blob: 2394629be59b66afecab9e2c7dccaacaeef05729 [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 Gregord36adf52010-09-16 16:06:31 +000025#include "llvm/ADT/DenseSet.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000026#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000027#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000028#include "llvm/ADT/StringSwitch.h"
Douglas Gregor458433d2010-08-26 15:07:07 +000029#include "llvm/ADT/Twine.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000030#include <list>
31#include <map>
32#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000033
34using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000035using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000036
Douglas Gregor86d9a522009-09-21 16:56:56 +000037namespace {
38 /// \brief A container of code-completion results.
39 class ResultBuilder {
40 public:
41 /// \brief The type of a name-lookup filter, which can be provided to the
42 /// name-lookup routines to specify which declarations should be included in
43 /// the result set (when it returns true) and which declarations should be
44 /// filtered out (returns false).
45 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
46
John McCall0a2c5e22010-08-25 06:19:51 +000047 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000048
49 private:
50 /// \brief The actual results we have found.
51 std::vector<Result> Results;
52
53 /// \brief A record of all of the declarations we have found and placed
54 /// into the result set, used to ensure that no declaration ever gets into
55 /// the result set twice.
56 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
57
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000058 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
59
60 /// \brief An entry in the shadow map, which is optimized to store
61 /// a single (declaration, index) mapping (the common case) but
62 /// can also store a list of (declaration, index) mappings.
63 class ShadowMapEntry {
64 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
65
66 /// \brief Contains either the solitary NamedDecl * or a vector
67 /// of (declaration, index) pairs.
68 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
69
70 /// \brief When the entry contains a single declaration, this is
71 /// the index associated with that entry.
72 unsigned SingleDeclIndex;
73
74 public:
75 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
76
77 void Add(NamedDecl *ND, unsigned Index) {
78 if (DeclOrVector.isNull()) {
79 // 0 - > 1 elements: just set the single element information.
80 DeclOrVector = ND;
81 SingleDeclIndex = Index;
82 return;
83 }
84
85 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
86 // 1 -> 2 elements: create the vector of results and push in the
87 // existing declaration.
88 DeclIndexPairVector *Vec = new DeclIndexPairVector;
89 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
90 DeclOrVector = Vec;
91 }
92
93 // Add the new element to the end of the vector.
94 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
95 DeclIndexPair(ND, Index));
96 }
97
98 void Destroy() {
99 if (DeclIndexPairVector *Vec
100 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
101 delete Vec;
102 DeclOrVector = ((NamedDecl *)0);
103 }
104 }
105
106 // Iteration.
107 class iterator;
108 iterator begin() const;
109 iterator end() const;
110 };
111
Douglas Gregor86d9a522009-09-21 16:56:56 +0000112 /// \brief A mapping from declaration names to the declarations that have
113 /// this name within a particular scope and their index within the list of
114 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000115 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000116
117 /// \brief The semantic analysis object for which results are being
118 /// produced.
119 Sema &SemaRef;
120
121 /// \brief If non-NULL, a filter function used to remove any code-completion
122 /// results that are not desirable.
123 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000124
125 /// \brief Whether we should allow declarations as
126 /// nested-name-specifiers that would otherwise be filtered out.
127 bool AllowNestedNameSpecifiers;
128
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000129 /// \brief If set, the type that we would prefer our resulting value
130 /// declarations to have.
131 ///
132 /// Closely matching the preferred type gives a boost to a result's
133 /// priority.
134 CanQualType PreferredType;
135
Douglas Gregor86d9a522009-09-21 16:56:56 +0000136 /// \brief A list of shadow maps, which is used to model name hiding at
137 /// different levels of, e.g., the inheritance hierarchy.
138 std::list<ShadowMap> ShadowMaps;
139
Douglas Gregor3cdee122010-08-26 16:36:48 +0000140 /// \brief If we're potentially referring to a C++ member function, the set
141 /// of qualifiers applied to the object type.
142 Qualifiers ObjectTypeQualifiers;
143
144 /// \brief Whether the \p ObjectTypeQualifiers field is active.
145 bool HasObjectTypeQualifiers;
146
Douglas Gregor265f7492010-08-27 15:29:55 +0000147 /// \brief The selector that we prefer.
148 Selector PreferredSelector;
149
Douglas Gregorca45da02010-11-02 20:36:02 +0000150 /// \brief The completion context in which we are gathering results.
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000151 CodeCompletionContext CompletionContext;
152
Douglas Gregorca45da02010-11-02 20:36:02 +0000153 /// \brief If we are in an instance method definition, the @implementation
154 /// object.
155 ObjCImplementationDecl *ObjCImplementation;
156
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000157 void AdjustResultPriorityForDecl(Result &R);
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000158
Douglas Gregor6f942b22010-09-21 16:06:22 +0000159 void MaybeAddConstructorResults(Result R);
160
Douglas Gregor86d9a522009-09-21 16:56:56 +0000161 public:
Douglas Gregor52779fb2010-09-23 23:01:17 +0000162 explicit ResultBuilder(Sema &SemaRef,
163 const CodeCompletionContext &CompletionContext,
164 LookupFilter Filter = 0)
Douglas Gregor3cdee122010-08-26 16:36:48 +0000165 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000166 HasObjectTypeQualifiers(false),
Douglas Gregorca45da02010-11-02 20:36:02 +0000167 CompletionContext(CompletionContext),
168 ObjCImplementation(0)
169 {
170 // If this is an Objective-C instance method definition, dig out the
171 // corresponding implementation.
172 switch (CompletionContext.getKind()) {
173 case CodeCompletionContext::CCC_Expression:
174 case CodeCompletionContext::CCC_ObjCMessageReceiver:
175 case CodeCompletionContext::CCC_ParenthesizedExpression:
176 case CodeCompletionContext::CCC_Statement:
177 case CodeCompletionContext::CCC_Recovery:
178 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
179 if (Method->isInstanceMethod())
180 if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
181 ObjCImplementation = Interface->getImplementation();
182 break;
183
184 default:
185 break;
186 }
187 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000188
Douglas Gregord8e8a582010-05-25 21:41:55 +0000189 /// \brief Whether we should include code patterns in the completion
190 /// results.
191 bool includeCodePatterns() const {
192 return SemaRef.CodeCompleter &&
Douglas Gregorf6961522010-08-27 21:18:54 +0000193 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregord8e8a582010-05-25 21:41:55 +0000194 }
195
Douglas Gregor86d9a522009-09-21 16:56:56 +0000196 /// \brief Set the filter used for code-completion results.
197 void setFilter(LookupFilter Filter) {
198 this->Filter = Filter;
199 }
200
Douglas Gregor86d9a522009-09-21 16:56:56 +0000201 Result *data() { return Results.empty()? 0 : &Results.front(); }
202 unsigned size() const { return Results.size(); }
203 bool empty() const { return Results.empty(); }
204
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000205 /// \brief Specify the preferred type.
206 void setPreferredType(QualType T) {
207 PreferredType = SemaRef.Context.getCanonicalType(T);
208 }
209
Douglas Gregor3cdee122010-08-26 16:36:48 +0000210 /// \brief Set the cv-qualifiers on the object type, for us in filtering
211 /// calls to member functions.
212 ///
213 /// When there are qualifiers in this set, they will be used to filter
214 /// out member functions that aren't available (because there will be a
215 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
216 /// match.
217 void setObjectTypeQualifiers(Qualifiers Quals) {
218 ObjectTypeQualifiers = Quals;
219 HasObjectTypeQualifiers = true;
220 }
221
Douglas Gregor265f7492010-08-27 15:29:55 +0000222 /// \brief Set the preferred selector.
223 ///
224 /// When an Objective-C method declaration result is added, and that
225 /// method's selector matches this preferred selector, we give that method
226 /// a slight priority boost.
227 void setPreferredSelector(Selector Sel) {
228 PreferredSelector = Sel;
229 }
Douglas Gregorca45da02010-11-02 20:36:02 +0000230
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000231 /// \brief Retrieve the code-completion context for which results are
232 /// being collected.
233 const CodeCompletionContext &getCompletionContext() const {
234 return CompletionContext;
235 }
236
Douglas Gregor45bcd432010-01-14 03:21:49 +0000237 /// \brief Specify whether nested-name-specifiers are allowed.
238 void allowNestedNameSpecifiers(bool Allow = true) {
239 AllowNestedNameSpecifiers = Allow;
240 }
241
Douglas Gregorb9d77572010-09-21 00:03:25 +0000242 /// \brief Return the semantic analysis object for which we are collecting
243 /// code completion results.
244 Sema &getSema() const { return SemaRef; }
245
Douglas Gregore495b7f2010-01-14 00:20:49 +0000246 /// \brief Determine whether the given declaration is at all interesting
247 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000248 ///
249 /// \param ND the declaration that we are inspecting.
250 ///
251 /// \param AsNestedNameSpecifier will be set true if this declaration is
252 /// only interesting when it is a nested-name-specifier.
253 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000254
255 /// \brief Check whether the result is hidden by the Hiding declaration.
256 ///
257 /// \returns true if the result is hidden and cannot be found, false if
258 /// the hidden result could still be found. When false, \p R may be
259 /// modified to describe how the result can be found (e.g., via extra
260 /// qualification).
261 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
262 NamedDecl *Hiding);
263
Douglas Gregor86d9a522009-09-21 16:56:56 +0000264 /// \brief Add a new result to this result set (if it isn't already in one
265 /// of the shadow maps), or replace an existing result (for, e.g., a
266 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000267 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000268 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000269 ///
270 /// \param R the context in which this result will be named.
271 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000272
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000273 /// \brief Add a new result to this result set, where we already know
274 /// the hiding declation (if any).
275 ///
276 /// \param R the result to add (if it is unique).
277 ///
278 /// \param CurContext the context in which this result will be named.
279 ///
280 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000281 ///
282 /// \param InBaseClass whether the result was found in a base
283 /// class of the searched context.
284 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
285 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000286
Douglas Gregora4477812010-01-14 16:01:26 +0000287 /// \brief Add a new non-declaration result to this result set.
288 void AddResult(Result R);
289
Douglas Gregor86d9a522009-09-21 16:56:56 +0000290 /// \brief Enter into a new scope.
291 void EnterNewScope();
292
293 /// \brief Exit from the current scope.
294 void ExitScope();
295
Douglas Gregor55385fe2009-11-18 04:19:12 +0000296 /// \brief Ignore this declaration, if it is seen again.
297 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
298
Douglas Gregor86d9a522009-09-21 16:56:56 +0000299 /// \name Name lookup predicates
300 ///
301 /// These predicates can be passed to the name lookup functions to filter the
302 /// results of name lookup. All of the predicates have the same type, so that
303 ///
304 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000305 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000306 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000307 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000308 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000309 bool IsNestedNameSpecifier(NamedDecl *ND) const;
310 bool IsEnum(NamedDecl *ND) const;
311 bool IsClassOrStruct(NamedDecl *ND) const;
312 bool IsUnion(NamedDecl *ND) const;
313 bool IsNamespace(NamedDecl *ND) const;
314 bool IsNamespaceOrAlias(NamedDecl *ND) const;
315 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000316 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000317 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000318 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000319 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor52779fb2010-09-23 23:01:17 +0000320 bool IsImpossibleToSatisfy(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000321 //@}
322 };
323}
324
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000325class ResultBuilder::ShadowMapEntry::iterator {
326 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
327 unsigned SingleDeclIndex;
328
329public:
330 typedef DeclIndexPair value_type;
331 typedef value_type reference;
332 typedef std::ptrdiff_t difference_type;
333 typedef std::input_iterator_tag iterator_category;
334
335 class pointer {
336 DeclIndexPair Value;
337
338 public:
339 pointer(const DeclIndexPair &Value) : Value(Value) { }
340
341 const DeclIndexPair *operator->() const {
342 return &Value;
343 }
344 };
345
346 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
347
348 iterator(NamedDecl *SingleDecl, unsigned Index)
349 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
350
351 iterator(const DeclIndexPair *Iterator)
352 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
353
354 iterator &operator++() {
355 if (DeclOrIterator.is<NamedDecl *>()) {
356 DeclOrIterator = (NamedDecl *)0;
357 SingleDeclIndex = 0;
358 return *this;
359 }
360
361 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
362 ++I;
363 DeclOrIterator = I;
364 return *this;
365 }
366
Chris Lattner66392d42010-09-04 18:12:20 +0000367 /*iterator operator++(int) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000368 iterator tmp(*this);
369 ++(*this);
370 return tmp;
Chris Lattner66392d42010-09-04 18:12:20 +0000371 }*/
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000372
373 reference operator*() const {
374 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
375 return reference(ND, SingleDeclIndex);
376
Douglas Gregord490f952009-12-06 21:27:58 +0000377 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000378 }
379
380 pointer operator->() const {
381 return pointer(**this);
382 }
383
384 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000385 return X.DeclOrIterator.getOpaqueValue()
386 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000387 X.SingleDeclIndex == Y.SingleDeclIndex;
388 }
389
390 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000391 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000392 }
393};
394
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000395ResultBuilder::ShadowMapEntry::iterator
396ResultBuilder::ShadowMapEntry::begin() const {
397 if (DeclOrVector.isNull())
398 return iterator();
399
400 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
401 return iterator(ND, SingleDeclIndex);
402
403 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
404}
405
406ResultBuilder::ShadowMapEntry::iterator
407ResultBuilder::ShadowMapEntry::end() const {
408 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
409 return iterator();
410
411 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
412}
413
Douglas Gregor456c4a12009-09-21 20:12:40 +0000414/// \brief Compute the qualification required to get from the current context
415/// (\p CurContext) to the target context (\p TargetContext).
416///
417/// \param Context the AST context in which the qualification will be used.
418///
419/// \param CurContext the context where an entity is being named, which is
420/// typically based on the current scope.
421///
422/// \param TargetContext the context in which the named entity actually
423/// resides.
424///
425/// \returns a nested name specifier that refers into the target context, or
426/// NULL if no qualification is needed.
427static NestedNameSpecifier *
428getRequiredQualification(ASTContext &Context,
429 DeclContext *CurContext,
430 DeclContext *TargetContext) {
431 llvm::SmallVector<DeclContext *, 4> TargetParents;
432
433 for (DeclContext *CommonAncestor = TargetContext;
434 CommonAncestor && !CommonAncestor->Encloses(CurContext);
435 CommonAncestor = CommonAncestor->getLookupParent()) {
436 if (CommonAncestor->isTransparentContext() ||
437 CommonAncestor->isFunctionOrMethod())
438 continue;
439
440 TargetParents.push_back(CommonAncestor);
441 }
442
443 NestedNameSpecifier *Result = 0;
444 while (!TargetParents.empty()) {
445 DeclContext *Parent = TargetParents.back();
446 TargetParents.pop_back();
447
Douglas Gregorfb629412010-08-23 21:17:50 +0000448 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
449 if (!Namespace->getIdentifier())
450 continue;
451
Douglas Gregor456c4a12009-09-21 20:12:40 +0000452 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000453 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000454 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
455 Result = NestedNameSpecifier::Create(Context, Result,
456 false,
457 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000458 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000459 return Result;
460}
461
Douglas Gregor45bcd432010-01-14 03:21:49 +0000462bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
463 bool &AsNestedNameSpecifier) const {
464 AsNestedNameSpecifier = false;
465
Douglas Gregore495b7f2010-01-14 00:20:49 +0000466 ND = ND->getUnderlyingDecl();
467 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000468
469 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000470 if (!ND->getDeclName())
471 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000472
473 // Friend declarations and declarations introduced due to friends are never
474 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000475 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000476 return false;
477
Douglas Gregor76282942009-12-11 17:31:05 +0000478 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000479 if (isa<ClassTemplateSpecializationDecl>(ND) ||
480 isa<ClassTemplatePartialSpecializationDecl>(ND))
481 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000482
Douglas Gregor76282942009-12-11 17:31:05 +0000483 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000484 if (isa<UsingDecl>(ND))
485 return false;
486
487 // Some declarations have reserved names that we don't want to ever show.
488 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000489 // __va_list_tag is a freak of nature. Find it and skip it.
490 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000491 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000492
Douglas Gregorf52cede2009-10-09 22:16:47 +0000493 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000494 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000495 //
496 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000497 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000498 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000499 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000500 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
501 (ND->getLocation().isInvalid() ||
502 SemaRef.SourceMgr.isInSystemHeader(
503 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000504 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000505 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000506 }
Douglas Gregor6f942b22010-09-21 16:06:22 +0000507
Douglas Gregor9b0ba872010-11-09 03:59:40 +0000508 // Skip out-of-line declarations and definitions.
509 // NOTE: Unless it's an Objective-C property, method, or ivar, where
510 // the contexts can be messy.
511 if (!ND->getDeclContext()->Equals(ND->getLexicalDeclContext()) &&
512 !(isa<ObjCPropertyDecl>(ND) || isa<ObjCIvarDecl>(ND) ||
513 isa<ObjCMethodDecl>(ND)))
514 return false;
515
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000516 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
517 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
518 Filter != &ResultBuilder::IsNamespace &&
Douglas Gregor52779fb2010-09-23 23:01:17 +0000519 Filter != &ResultBuilder::IsNamespaceOrAlias &&
520 Filter != 0))
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000521 AsNestedNameSpecifier = true;
522
Douglas Gregor86d9a522009-09-21 16:56:56 +0000523 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000524 if (Filter && !(this->*Filter)(ND)) {
525 // Check whether it is interesting as a nested-name-specifier.
526 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
527 IsNestedNameSpecifier(ND) &&
528 (Filter != &ResultBuilder::IsMember ||
529 (isa<CXXRecordDecl>(ND) &&
530 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
531 AsNestedNameSpecifier = true;
532 return true;
533 }
534
Douglas Gregore495b7f2010-01-14 00:20:49 +0000535 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000536 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000537 // ... then it must be interesting!
538 return true;
539}
540
Douglas Gregor6660d842010-01-14 00:41:07 +0000541bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
542 NamedDecl *Hiding) {
543 // In C, there is no way to refer to a hidden name.
544 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
545 // name if we introduce the tag type.
546 if (!SemaRef.getLangOptions().CPlusPlus)
547 return true;
548
Sebastian Redl7a126a42010-08-31 00:36:30 +0000549 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregor6660d842010-01-14 00:41:07 +0000550
551 // There is no way to qualify a name declared in a function or method.
552 if (HiddenCtx->isFunctionOrMethod())
553 return true;
554
Sebastian Redl7a126a42010-08-31 00:36:30 +0000555 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregor6660d842010-01-14 00:41:07 +0000556 return true;
557
558 // We can refer to the result with the appropriate qualification. Do it.
559 R.Hidden = true;
560 R.QualifierIsInformative = false;
561
562 if (!R.Qualifier)
563 R.Qualifier = getRequiredQualification(SemaRef.Context,
564 CurContext,
565 R.Declaration->getDeclContext());
566 return false;
567}
568
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000569/// \brief A simplified classification of types used to determine whether two
570/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000571SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000572 switch (T->getTypeClass()) {
573 case Type::Builtin:
574 switch (cast<BuiltinType>(T)->getKind()) {
575 case BuiltinType::Void:
576 return STC_Void;
577
578 case BuiltinType::NullPtr:
579 return STC_Pointer;
580
581 case BuiltinType::Overload:
582 case BuiltinType::Dependent:
583 case BuiltinType::UndeducedAuto:
584 return STC_Other;
585
586 case BuiltinType::ObjCId:
587 case BuiltinType::ObjCClass:
588 case BuiltinType::ObjCSel:
589 return STC_ObjectiveC;
590
591 default:
592 return STC_Arithmetic;
593 }
594 return STC_Other;
595
596 case Type::Complex:
597 return STC_Arithmetic;
598
599 case Type::Pointer:
600 return STC_Pointer;
601
602 case Type::BlockPointer:
603 return STC_Block;
604
605 case Type::LValueReference:
606 case Type::RValueReference:
607 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
608
609 case Type::ConstantArray:
610 case Type::IncompleteArray:
611 case Type::VariableArray:
612 case Type::DependentSizedArray:
613 return STC_Array;
614
615 case Type::DependentSizedExtVector:
616 case Type::Vector:
617 case Type::ExtVector:
618 return STC_Arithmetic;
619
620 case Type::FunctionProto:
621 case Type::FunctionNoProto:
622 return STC_Function;
623
624 case Type::Record:
625 return STC_Record;
626
627 case Type::Enum:
628 return STC_Arithmetic;
629
630 case Type::ObjCObject:
631 case Type::ObjCInterface:
632 case Type::ObjCObjectPointer:
633 return STC_ObjectiveC;
634
635 default:
636 return STC_Other;
637 }
638}
639
640/// \brief Get the type that a given expression will have if this declaration
641/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000642QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000643 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
644
645 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
646 return C.getTypeDeclType(Type);
647 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
648 return C.getObjCInterfaceType(Iface);
649
650 QualType T;
651 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000652 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000653 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000654 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000655 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000656 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000657 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
658 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
659 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
660 T = Property->getType();
661 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
662 T = Value->getType();
663 else
664 return QualType();
665
666 return T.getNonReferenceType();
667}
668
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000669void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
670 // If this is an Objective-C method declaration whose selector matches our
671 // preferred selector, give it a priority boost.
672 if (!PreferredSelector.isNull())
673 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
674 if (PreferredSelector == Method->getSelector())
675 R.Priority += CCD_SelectorMatch;
Douglas Gregor08f43cd2010-09-20 23:11:55 +0000676
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000677 // If we have a preferred type, adjust the priority for results with exactly-
678 // matching or nearly-matching types.
679 if (!PreferredType.isNull()) {
680 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
681 if (!T.isNull()) {
682 CanQualType TC = SemaRef.Context.getCanonicalType(T);
683 // Check for exactly-matching types (modulo qualifiers).
684 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
685 R.Priority /= CCF_ExactTypeMatch;
686 // Check for nearly-matching types, based on classification of each.
687 else if ((getSimplifiedTypeClass(PreferredType)
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000688 == getSimplifiedTypeClass(TC)) &&
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000689 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
690 R.Priority /= CCF_SimilarTypeMatch;
691 }
692 }
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000693}
694
Douglas Gregor6f942b22010-09-21 16:06:22 +0000695void ResultBuilder::MaybeAddConstructorResults(Result R) {
696 if (!SemaRef.getLangOptions().CPlusPlus || !R.Declaration ||
697 !CompletionContext.wantConstructorResults())
698 return;
699
700 ASTContext &Context = SemaRef.Context;
701 NamedDecl *D = R.Declaration;
702 CXXRecordDecl *Record = 0;
703 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
704 Record = ClassTemplate->getTemplatedDecl();
705 else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
706 // Skip specializations and partial specializations.
707 if (isa<ClassTemplateSpecializationDecl>(Record))
708 return;
709 } else {
710 // There are no constructors here.
711 return;
712 }
713
714 Record = Record->getDefinition();
715 if (!Record)
716 return;
717
718
719 QualType RecordTy = Context.getTypeDeclType(Record);
720 DeclarationName ConstructorName
721 = Context.DeclarationNames.getCXXConstructorName(
722 Context.getCanonicalType(RecordTy));
723 for (DeclContext::lookup_result Ctors = Record->lookup(ConstructorName);
724 Ctors.first != Ctors.second; ++Ctors.first) {
725 R.Declaration = *Ctors.first;
726 R.CursorKind = getCursorKindForDecl(R.Declaration);
727 Results.push_back(R);
728 }
729}
730
Douglas Gregore495b7f2010-01-14 00:20:49 +0000731void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
732 assert(!ShadowMaps.empty() && "Must enter into a results scope");
733
734 if (R.Kind != Result::RK_Declaration) {
735 // For non-declaration results, just add the result.
736 Results.push_back(R);
737 return;
738 }
739
740 // Look through using declarations.
741 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
742 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
743 return;
744 }
745
746 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
747 unsigned IDNS = CanonDecl->getIdentifierNamespace();
748
Douglas Gregor45bcd432010-01-14 03:21:49 +0000749 bool AsNestedNameSpecifier = false;
750 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000751 return;
752
Douglas Gregor6f942b22010-09-21 16:06:22 +0000753 // C++ constructors are never found by name lookup.
754 if (isa<CXXConstructorDecl>(R.Declaration))
755 return;
756
Douglas Gregor86d9a522009-09-21 16:56:56 +0000757 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000758 ShadowMapEntry::iterator I, IEnd;
759 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
760 if (NamePos != SMap.end()) {
761 I = NamePos->second.begin();
762 IEnd = NamePos->second.end();
763 }
764
765 for (; I != IEnd; ++I) {
766 NamedDecl *ND = I->first;
767 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000768 if (ND->getCanonicalDecl() == CanonDecl) {
769 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000770 Results[Index].Declaration = R.Declaration;
771
Douglas Gregor86d9a522009-09-21 16:56:56 +0000772 // We're done.
773 return;
774 }
775 }
776
777 // This is a new declaration in this scope. However, check whether this
778 // declaration name is hidden by a similarly-named declaration in an outer
779 // scope.
780 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
781 --SMEnd;
782 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000783 ShadowMapEntry::iterator I, IEnd;
784 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
785 if (NamePos != SM->end()) {
786 I = NamePos->second.begin();
787 IEnd = NamePos->second.end();
788 }
789 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000790 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000791 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000792 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
793 Decl::IDNS_ObjCProtocol)))
794 continue;
795
796 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000797 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000798 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000799 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000800 continue;
801
802 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000803 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000804 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000805
806 break;
807 }
808 }
809
810 // Make sure that any given declaration only shows up in the result set once.
811 if (!AllDeclsFound.insert(CanonDecl))
812 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000813
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000814 // If the filter is for nested-name-specifiers, then this result starts a
815 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000816 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000817 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000818 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000819 } else
820 AdjustResultPriorityForDecl(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000821
Douglas Gregor0563c262009-09-22 23:15:58 +0000822 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000823 if (R.QualifierIsInformative && !R.Qualifier &&
824 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000825 DeclContext *Ctx = R.Declaration->getDeclContext();
826 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
827 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
828 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
829 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
830 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
831 else
832 R.QualifierIsInformative = false;
833 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000834
Douglas Gregor86d9a522009-09-21 16:56:56 +0000835 // Insert this result into the set of results and into the current shadow
836 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000837 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000838 Results.push_back(R);
Douglas Gregor6f942b22010-09-21 16:06:22 +0000839
840 if (!AsNestedNameSpecifier)
841 MaybeAddConstructorResults(R);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000842}
843
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000844void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000845 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000846 if (R.Kind != Result::RK_Declaration) {
847 // For non-declaration results, just add the result.
848 Results.push_back(R);
849 return;
850 }
851
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000852 // Look through using declarations.
853 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
854 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
855 return;
856 }
857
Douglas Gregor45bcd432010-01-14 03:21:49 +0000858 bool AsNestedNameSpecifier = false;
859 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000860 return;
861
Douglas Gregor6f942b22010-09-21 16:06:22 +0000862 // C++ constructors are never found by name lookup.
863 if (isa<CXXConstructorDecl>(R.Declaration))
864 return;
865
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000866 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
867 return;
868
869 // Make sure that any given declaration only shows up in the result set once.
870 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
871 return;
872
873 // If the filter is for nested-name-specifiers, then this result starts a
874 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000875 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000876 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000877 R.Priority = CCP_NestedNameSpecifier;
878 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000879 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
880 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000881 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000882 R.QualifierIsInformative = true;
883
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000884 // If this result is supposed to have an informative qualifier, add one.
885 if (R.QualifierIsInformative && !R.Qualifier &&
886 !R.StartsNestedNameSpecifier) {
887 DeclContext *Ctx = R.Declaration->getDeclContext();
888 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
889 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
890 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
891 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000892 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000893 else
894 R.QualifierIsInformative = false;
895 }
896
Douglas Gregor12e13132010-05-26 22:00:08 +0000897 // Adjust the priority if this result comes from a base class.
898 if (InBaseClass)
899 R.Priority += CCD_InBaseClass;
900
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000901 AdjustResultPriorityForDecl(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000902
Douglas Gregor3cdee122010-08-26 16:36:48 +0000903 if (HasObjectTypeQualifiers)
904 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
905 if (Method->isInstance()) {
906 Qualifiers MethodQuals
907 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
908 if (ObjectTypeQualifiers == MethodQuals)
909 R.Priority += CCD_ObjectQualifierMatch;
910 else if (ObjectTypeQualifiers - MethodQuals) {
911 // The method cannot be invoked, because doing so would drop
912 // qualifiers.
913 return;
914 }
915 }
916
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000917 // Insert this result into the set of results.
918 Results.push_back(R);
Douglas Gregor6f942b22010-09-21 16:06:22 +0000919
920 if (!AsNestedNameSpecifier)
921 MaybeAddConstructorResults(R);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000922}
923
Douglas Gregora4477812010-01-14 16:01:26 +0000924void ResultBuilder::AddResult(Result R) {
925 assert(R.Kind != Result::RK_Declaration &&
926 "Declaration results need more context");
927 Results.push_back(R);
928}
929
Douglas Gregor86d9a522009-09-21 16:56:56 +0000930/// \brief Enter into a new scope.
931void ResultBuilder::EnterNewScope() {
932 ShadowMaps.push_back(ShadowMap());
933}
934
935/// \brief Exit from the current scope.
936void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000937 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
938 EEnd = ShadowMaps.back().end();
939 E != EEnd;
940 ++E)
941 E->second.Destroy();
942
Douglas Gregor86d9a522009-09-21 16:56:56 +0000943 ShadowMaps.pop_back();
944}
945
Douglas Gregor791215b2009-09-21 20:51:25 +0000946/// \brief Determines whether this given declaration will be found by
947/// ordinary name lookup.
948bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000949 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
950
Douglas Gregor791215b2009-09-21 20:51:25 +0000951 unsigned IDNS = Decl::IDNS_Ordinary;
952 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000953 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorca45da02010-11-02 20:36:02 +0000954 else if (SemaRef.getLangOptions().ObjC1) {
955 if (isa<ObjCIvarDecl>(ND))
956 return true;
957 if (isa<ObjCPropertyDecl>(ND) &&
958 SemaRef.canSynthesizeProvisionalIvar(cast<ObjCPropertyDecl>(ND)))
959 return true;
960 }
961
Douglas Gregor791215b2009-09-21 20:51:25 +0000962 return ND->getIdentifierNamespace() & IDNS;
963}
964
Douglas Gregor01dfea02010-01-10 23:08:15 +0000965/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000966/// ordinary name lookup but is not a type name.
967bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
968 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
969 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
970 return false;
971
972 unsigned IDNS = Decl::IDNS_Ordinary;
973 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000974 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorca45da02010-11-02 20:36:02 +0000975 else if (SemaRef.getLangOptions().ObjC1) {
976 if (isa<ObjCIvarDecl>(ND))
977 return true;
978 if (isa<ObjCPropertyDecl>(ND) &&
979 SemaRef.canSynthesizeProvisionalIvar(cast<ObjCPropertyDecl>(ND)))
980 return true;
981 }
982
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000983 return ND->getIdentifierNamespace() & IDNS;
984}
985
Douglas Gregorf9578432010-07-28 21:50:18 +0000986bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
987 if (!IsOrdinaryNonTypeName(ND))
988 return 0;
989
990 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
991 if (VD->getType()->isIntegralOrEnumerationType())
992 return true;
993
994 return false;
995}
996
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000997/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000998/// ordinary name lookup.
999bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001000 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1001
Douglas Gregor01dfea02010-01-10 23:08:15 +00001002 unsigned IDNS = Decl::IDNS_Ordinary;
1003 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +00001004 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001005
1006 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001007 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
1008 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001009}
1010
Douglas Gregor86d9a522009-09-21 16:56:56 +00001011/// \brief Determines whether the given declaration is suitable as the
1012/// start of a C++ nested-name-specifier, e.g., a class or namespace.
1013bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
1014 // Allow us to find class templates, too.
1015 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1016 ND = ClassTemplate->getTemplatedDecl();
1017
1018 return SemaRef.isAcceptableNestedNameSpecifier(ND);
1019}
1020
1021/// \brief Determines whether the given declaration is an enumeration.
1022bool ResultBuilder::IsEnum(NamedDecl *ND) const {
1023 return isa<EnumDecl>(ND);
1024}
1025
1026/// \brief Determines whether the given declaration is a class or struct.
1027bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
1028 // Allow us to find class templates, too.
1029 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1030 ND = ClassTemplate->getTemplatedDecl();
1031
1032 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +00001033 return RD->getTagKind() == TTK_Class ||
1034 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001035
1036 return false;
1037}
1038
1039/// \brief Determines whether the given declaration is a union.
1040bool ResultBuilder::IsUnion(NamedDecl *ND) const {
1041 // Allow us to find class templates, too.
1042 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1043 ND = ClassTemplate->getTemplatedDecl();
1044
1045 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +00001046 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001047
1048 return false;
1049}
1050
1051/// \brief Determines whether the given declaration is a namespace.
1052bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
1053 return isa<NamespaceDecl>(ND);
1054}
1055
1056/// \brief Determines whether the given declaration is a namespace or
1057/// namespace alias.
1058bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
1059 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
1060}
1061
Douglas Gregor76282942009-12-11 17:31:05 +00001062/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +00001063bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +00001064 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1065 ND = Using->getTargetDecl();
1066
1067 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001068}
1069
Douglas Gregor76282942009-12-11 17:31:05 +00001070/// \brief Determines which members of a class should be visible via
1071/// "." or "->". Only value declarations, nested name specifiers, and
1072/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001073bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +00001074 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1075 ND = Using->getTargetDecl();
1076
Douglas Gregorce821962009-12-11 18:14:22 +00001077 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1078 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001079}
1080
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001081static bool isObjCReceiverType(ASTContext &C, QualType T) {
1082 T = C.getCanonicalType(T);
1083 switch (T->getTypeClass()) {
1084 case Type::ObjCObject:
1085 case Type::ObjCInterface:
1086 case Type::ObjCObjectPointer:
1087 return true;
1088
1089 case Type::Builtin:
1090 switch (cast<BuiltinType>(T)->getKind()) {
1091 case BuiltinType::ObjCId:
1092 case BuiltinType::ObjCClass:
1093 case BuiltinType::ObjCSel:
1094 return true;
1095
1096 default:
1097 break;
1098 }
1099 return false;
1100
1101 default:
1102 break;
1103 }
1104
1105 if (!C.getLangOptions().CPlusPlus)
1106 return false;
1107
1108 // FIXME: We could perform more analysis here to determine whether a
1109 // particular class type has any conversions to Objective-C types. For now,
1110 // just accept all class types.
1111 return T->isDependentType() || T->isRecordType();
1112}
1113
1114bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1115 QualType T = getDeclUsageType(SemaRef.Context, ND);
1116 if (T.isNull())
1117 return false;
1118
1119 T = SemaRef.Context.getBaseElementType(T);
1120 return isObjCReceiverType(SemaRef.Context, T);
1121}
1122
Douglas Gregorfb629412010-08-23 21:17:50 +00001123bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1124 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1125 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1126 return false;
1127
1128 QualType T = getDeclUsageType(SemaRef.Context, ND);
1129 if (T.isNull())
1130 return false;
1131
1132 T = SemaRef.Context.getBaseElementType(T);
1133 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1134 T->isObjCIdType() ||
1135 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1136}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001137
Douglas Gregor52779fb2010-09-23 23:01:17 +00001138bool ResultBuilder::IsImpossibleToSatisfy(NamedDecl *ND) const {
1139 return false;
1140}
1141
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001142/// \rief Determines whether the given declaration is an Objective-C
1143/// instance variable.
1144bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1145 return isa<ObjCIvarDecl>(ND);
1146}
1147
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001148namespace {
1149 /// \brief Visible declaration consumer that adds a code-completion result
1150 /// for each visible declaration.
1151 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1152 ResultBuilder &Results;
1153 DeclContext *CurContext;
1154
1155 public:
1156 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1157 : Results(Results), CurContext(CurContext) { }
1158
Douglas Gregor0cc84042010-01-14 15:47:35 +00001159 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1160 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001161 }
1162 };
1163}
1164
Douglas Gregor86d9a522009-09-21 16:56:56 +00001165/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001166static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001167 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001168 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001169 Results.AddResult(Result("short", CCP_Type));
1170 Results.AddResult(Result("long", CCP_Type));
1171 Results.AddResult(Result("signed", CCP_Type));
1172 Results.AddResult(Result("unsigned", CCP_Type));
1173 Results.AddResult(Result("void", CCP_Type));
1174 Results.AddResult(Result("char", CCP_Type));
1175 Results.AddResult(Result("int", CCP_Type));
1176 Results.AddResult(Result("float", CCP_Type));
1177 Results.AddResult(Result("double", CCP_Type));
1178 Results.AddResult(Result("enum", CCP_Type));
1179 Results.AddResult(Result("struct", CCP_Type));
1180 Results.AddResult(Result("union", CCP_Type));
1181 Results.AddResult(Result("const", CCP_Type));
1182 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001183
Douglas Gregor86d9a522009-09-21 16:56:56 +00001184 if (LangOpts.C99) {
1185 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001186 Results.AddResult(Result("_Complex", CCP_Type));
1187 Results.AddResult(Result("_Imaginary", CCP_Type));
1188 Results.AddResult(Result("_Bool", CCP_Type));
1189 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001190 }
1191
1192 if (LangOpts.CPlusPlus) {
1193 // C++-specific
Douglas Gregorb05496d2010-09-20 21:11:48 +00001194 Results.AddResult(Result("bool", CCP_Type +
1195 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
Douglas Gregor12e13132010-05-26 22:00:08 +00001196 Results.AddResult(Result("class", CCP_Type));
1197 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001198
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001199 // typename qualified-id
1200 CodeCompletionString *Pattern = new CodeCompletionString;
1201 Pattern->AddTypedTextChunk("typename");
1202 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1203 Pattern->AddPlaceholderChunk("qualifier");
1204 Pattern->AddTextChunk("::");
1205 Pattern->AddPlaceholderChunk("name");
1206 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001207
Douglas Gregor86d9a522009-09-21 16:56:56 +00001208 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001209 Results.AddResult(Result("auto", CCP_Type));
1210 Results.AddResult(Result("char16_t", CCP_Type));
1211 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001212
1213 CodeCompletionString *Pattern = new CodeCompletionString;
1214 Pattern->AddTypedTextChunk("decltype");
1215 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1216 Pattern->AddPlaceholderChunk("expression");
1217 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1218 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001219 }
1220 }
1221
1222 // GNU extensions
1223 if (LangOpts.GNUMode) {
1224 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001225 // Results.AddResult(Result("_Decimal32"));
1226 // Results.AddResult(Result("_Decimal64"));
1227 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001228
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001229 CodeCompletionString *Pattern = new CodeCompletionString;
1230 Pattern->AddTypedTextChunk("typeof");
1231 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1232 Pattern->AddPlaceholderChunk("expression");
1233 Results.AddResult(Result(Pattern));
1234
1235 Pattern = new CodeCompletionString;
1236 Pattern->AddTypedTextChunk("typeof");
1237 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1238 Pattern->AddPlaceholderChunk("type");
1239 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1240 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001241 }
1242}
1243
John McCallf312b1e2010-08-26 23:41:50 +00001244static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001245 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001246 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001247 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001248 // Note: we don't suggest either "auto" or "register", because both
1249 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1250 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001251 Results.AddResult(Result("extern"));
1252 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001253}
1254
John McCallf312b1e2010-08-26 23:41:50 +00001255static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001256 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001257 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001258 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001259 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001260 case Sema::PCC_Class:
1261 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001262 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001263 Results.AddResult(Result("explicit"));
1264 Results.AddResult(Result("friend"));
1265 Results.AddResult(Result("mutable"));
1266 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001267 }
1268 // Fall through
1269
John McCallf312b1e2010-08-26 23:41:50 +00001270 case Sema::PCC_ObjCInterface:
1271 case Sema::PCC_ObjCImplementation:
1272 case Sema::PCC_Namespace:
1273 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001274 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001275 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001276 break;
1277
John McCallf312b1e2010-08-26 23:41:50 +00001278 case Sema::PCC_ObjCInstanceVariableList:
1279 case Sema::PCC_Expression:
1280 case Sema::PCC_Statement:
1281 case Sema::PCC_ForInit:
1282 case Sema::PCC_Condition:
1283 case Sema::PCC_RecoveryInFunction:
1284 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001285 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001286 break;
1287 }
1288}
1289
Douglas Gregorbca403c2010-01-13 23:51:12 +00001290static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1291static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1292static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001293 ResultBuilder &Results,
1294 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001295static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001296 ResultBuilder &Results,
1297 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001298static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001299 ResultBuilder &Results,
1300 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001301static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001302
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001303static void AddTypedefResult(ResultBuilder &Results) {
1304 CodeCompletionString *Pattern = new CodeCompletionString;
1305 Pattern->AddTypedTextChunk("typedef");
1306 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1307 Pattern->AddPlaceholderChunk("type");
1308 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1309 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001310 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001311}
1312
John McCallf312b1e2010-08-26 23:41:50 +00001313static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001314 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001315 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001316 case Sema::PCC_Namespace:
1317 case Sema::PCC_Class:
1318 case Sema::PCC_ObjCInstanceVariableList:
1319 case Sema::PCC_Template:
1320 case Sema::PCC_MemberTemplate:
1321 case Sema::PCC_Statement:
1322 case Sema::PCC_RecoveryInFunction:
1323 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001324 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001325 return true;
1326
John McCallf312b1e2010-08-26 23:41:50 +00001327 case Sema::PCC_Expression:
1328 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001329 return LangOpts.CPlusPlus;
1330
1331 case Sema::PCC_ObjCInterface:
1332 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001333 return false;
1334
John McCallf312b1e2010-08-26 23:41:50 +00001335 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001336 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001337 }
1338
1339 return false;
1340}
1341
Douglas Gregor01dfea02010-01-10 23:08:15 +00001342/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001343static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001344 Scope *S,
1345 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001346 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001347 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001348 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001349 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001350 if (SemaRef.getLangOptions().CPlusPlus) {
1351 CodeCompletionString *Pattern = 0;
1352
1353 if (Results.includeCodePatterns()) {
1354 // namespace <identifier> { declarations }
1355 CodeCompletionString *Pattern = new CodeCompletionString;
1356 Pattern->AddTypedTextChunk("namespace");
1357 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1358 Pattern->AddPlaceholderChunk("identifier");
1359 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1360 Pattern->AddPlaceholderChunk("declarations");
1361 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1362 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1363 Results.AddResult(Result(Pattern));
1364 }
1365
Douglas Gregor01dfea02010-01-10 23:08:15 +00001366 // namespace identifier = identifier ;
1367 Pattern = new CodeCompletionString;
1368 Pattern->AddTypedTextChunk("namespace");
1369 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001370 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001371 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001372 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001373 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001374
1375 // Using directives
1376 Pattern = new CodeCompletionString;
1377 Pattern->AddTypedTextChunk("using");
1378 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1379 Pattern->AddTextChunk("namespace");
1380 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1381 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001382 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001383
1384 // asm(string-literal)
1385 Pattern = new CodeCompletionString;
1386 Pattern->AddTypedTextChunk("asm");
1387 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1388 Pattern->AddPlaceholderChunk("string-literal");
1389 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001390 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001391
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001392 if (Results.includeCodePatterns()) {
1393 // Explicit template instantiation
1394 Pattern = new CodeCompletionString;
1395 Pattern->AddTypedTextChunk("template");
1396 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1397 Pattern->AddPlaceholderChunk("declaration");
1398 Results.AddResult(Result(Pattern));
1399 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001400 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001401
1402 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001403 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001404
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001405 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001406 // Fall through
1407
John McCallf312b1e2010-08-26 23:41:50 +00001408 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001409 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001410 // Using declaration
1411 CodeCompletionString *Pattern = new CodeCompletionString;
1412 Pattern->AddTypedTextChunk("using");
1413 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001414 Pattern->AddPlaceholderChunk("qualifier");
1415 Pattern->AddTextChunk("::");
1416 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001417 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001418
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001419 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001420 if (SemaRef.CurContext->isDependentContext()) {
1421 Pattern = new CodeCompletionString;
1422 Pattern->AddTypedTextChunk("using");
1423 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1424 Pattern->AddTextChunk("typename");
1425 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001426 Pattern->AddPlaceholderChunk("qualifier");
1427 Pattern->AddTextChunk("::");
1428 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001429 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001430 }
1431
John McCallf312b1e2010-08-26 23:41:50 +00001432 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001433 AddTypedefResult(Results);
1434
Douglas Gregor01dfea02010-01-10 23:08:15 +00001435 // public:
1436 Pattern = new CodeCompletionString;
1437 Pattern->AddTypedTextChunk("public");
1438 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001439 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001440
1441 // protected:
1442 Pattern = new CodeCompletionString;
1443 Pattern->AddTypedTextChunk("protected");
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 // private:
1448 Pattern = new CodeCompletionString;
1449 Pattern->AddTypedTextChunk("private");
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 }
1454 // Fall through
1455
John McCallf312b1e2010-08-26 23:41:50 +00001456 case Sema::PCC_Template:
1457 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001458 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001459 // template < parameters >
1460 CodeCompletionString *Pattern = new CodeCompletionString;
1461 Pattern->AddTypedTextChunk("template");
1462 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1463 Pattern->AddPlaceholderChunk("parameters");
1464 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001465 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001466 }
1467
Douglas Gregorbca403c2010-01-13 23:51:12 +00001468 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1469 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001470 break;
1471
John McCallf312b1e2010-08-26 23:41:50 +00001472 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001473 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1474 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1475 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001476 break;
1477
John McCallf312b1e2010-08-26 23:41:50 +00001478 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001479 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1480 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1481 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001482 break;
1483
John McCallf312b1e2010-08-26 23:41:50 +00001484 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001485 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001486 break;
1487
John McCallf312b1e2010-08-26 23:41:50 +00001488 case Sema::PCC_RecoveryInFunction:
1489 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001490 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001491
1492 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001493 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001494 Pattern = new CodeCompletionString;
1495 Pattern->AddTypedTextChunk("try");
1496 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1497 Pattern->AddPlaceholderChunk("statements");
1498 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1499 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1500 Pattern->AddTextChunk("catch");
1501 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1502 Pattern->AddPlaceholderChunk("declaration");
1503 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1504 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1505 Pattern->AddPlaceholderChunk("statements");
1506 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1507 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001508 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001509 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001510 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001511 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001512
Douglas Gregord8e8a582010-05-25 21:41:55 +00001513 if (Results.includeCodePatterns()) {
1514 // if (condition) { statements }
1515 Pattern = new CodeCompletionString;
1516 Pattern->AddTypedTextChunk("if");
1517 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1518 if (SemaRef.getLangOptions().CPlusPlus)
1519 Pattern->AddPlaceholderChunk("condition");
1520 else
1521 Pattern->AddPlaceholderChunk("expression");
1522 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1523 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1524 Pattern->AddPlaceholderChunk("statements");
1525 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1526 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1527 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001528
Douglas Gregord8e8a582010-05-25 21:41:55 +00001529 // switch (condition) { }
1530 Pattern = new CodeCompletionString;
1531 Pattern->AddTypedTextChunk("switch");
1532 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1533 if (SemaRef.getLangOptions().CPlusPlus)
1534 Pattern->AddPlaceholderChunk("condition");
1535 else
1536 Pattern->AddPlaceholderChunk("expression");
1537 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1538 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1539 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1540 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1541 Results.AddResult(Result(Pattern));
1542 }
1543
Douglas Gregor01dfea02010-01-10 23:08:15 +00001544 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001545 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001546 // case expression:
1547 Pattern = new CodeCompletionString;
1548 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001549 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001550 Pattern->AddPlaceholderChunk("expression");
1551 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001552 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001553
1554 // default:
1555 Pattern = new CodeCompletionString;
1556 Pattern->AddTypedTextChunk("default");
1557 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001558 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001559 }
1560
Douglas Gregord8e8a582010-05-25 21:41:55 +00001561 if (Results.includeCodePatterns()) {
1562 /// while (condition) { statements }
1563 Pattern = new CodeCompletionString;
1564 Pattern->AddTypedTextChunk("while");
1565 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1566 if (SemaRef.getLangOptions().CPlusPlus)
1567 Pattern->AddPlaceholderChunk("condition");
1568 else
1569 Pattern->AddPlaceholderChunk("expression");
1570 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1571 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1572 Pattern->AddPlaceholderChunk("statements");
1573 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1574 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1575 Results.AddResult(Result(Pattern));
1576
1577 // do { statements } while ( expression );
1578 Pattern = new CodeCompletionString;
1579 Pattern->AddTypedTextChunk("do");
1580 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1581 Pattern->AddPlaceholderChunk("statements");
1582 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1583 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1584 Pattern->AddTextChunk("while");
1585 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001586 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001587 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1588 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001589
Douglas Gregord8e8a582010-05-25 21:41:55 +00001590 // for ( for-init-statement ; condition ; expression ) { statements }
1591 Pattern = new CodeCompletionString;
1592 Pattern->AddTypedTextChunk("for");
1593 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1594 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1595 Pattern->AddPlaceholderChunk("init-statement");
1596 else
1597 Pattern->AddPlaceholderChunk("init-expression");
1598 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1599 Pattern->AddPlaceholderChunk("condition");
1600 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1601 Pattern->AddPlaceholderChunk("inc-expression");
1602 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1603 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
Douglas Gregor5a9c0bc2010-10-08 20:39:29 +00001604 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
Douglas Gregord8e8a582010-05-25 21:41:55 +00001605 Pattern->AddPlaceholderChunk("statements");
1606 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1607 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1608 Results.AddResult(Result(Pattern));
1609 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001610
1611 if (S->getContinueParent()) {
1612 // continue ;
1613 Pattern = new CodeCompletionString;
1614 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001615 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001616 }
1617
1618 if (S->getBreakParent()) {
1619 // break ;
1620 Pattern = new CodeCompletionString;
1621 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001622 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001623 }
1624
1625 // "return expression ;" or "return ;", depending on whether we
1626 // know the function is void or not.
1627 bool isVoid = false;
1628 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1629 isVoid = Function->getResultType()->isVoidType();
1630 else if (ObjCMethodDecl *Method
1631 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1632 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001633 else if (SemaRef.getCurBlock() &&
1634 !SemaRef.getCurBlock()->ReturnType.isNull())
1635 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001636 Pattern = new CodeCompletionString;
1637 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001638 if (!isVoid) {
1639 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001640 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001641 }
Douglas Gregora4477812010-01-14 16:01:26 +00001642 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001643
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001644 // goto identifier ;
1645 Pattern = new CodeCompletionString;
1646 Pattern->AddTypedTextChunk("goto");
1647 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1648 Pattern->AddPlaceholderChunk("label");
1649 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001650
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001651 // Using directives
1652 Pattern = new CodeCompletionString;
1653 Pattern->AddTypedTextChunk("using");
1654 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1655 Pattern->AddTextChunk("namespace");
1656 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1657 Pattern->AddPlaceholderChunk("identifier");
1658 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001659 }
1660
1661 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001662 case Sema::PCC_ForInit:
1663 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001664 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001665 // Fall through: conditions and statements can have expressions.
1666
Douglas Gregor02688102010-09-14 23:59:36 +00001667 case Sema::PCC_ParenthesizedExpression:
John McCallf312b1e2010-08-26 23:41:50 +00001668 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001669 CodeCompletionString *Pattern = 0;
1670 if (SemaRef.getLangOptions().CPlusPlus) {
1671 // 'this', if we're in a non-static member function.
1672 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1673 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001674 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001675
1676 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001677 Results.AddResult(Result("true"));
1678 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001679
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001680 // dynamic_cast < type-id > ( expression )
1681 Pattern = new CodeCompletionString;
1682 Pattern->AddTypedTextChunk("dynamic_cast");
1683 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1684 Pattern->AddPlaceholderChunk("type");
1685 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1686 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1687 Pattern->AddPlaceholderChunk("expression");
1688 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1689 Results.AddResult(Result(Pattern));
1690
1691 // static_cast < type-id > ( expression )
1692 Pattern = new CodeCompletionString;
1693 Pattern->AddTypedTextChunk("static_cast");
1694 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1695 Pattern->AddPlaceholderChunk("type");
1696 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1697 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1698 Pattern->AddPlaceholderChunk("expression");
1699 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1700 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001701
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001702 // reinterpret_cast < type-id > ( expression )
1703 Pattern = new CodeCompletionString;
1704 Pattern->AddTypedTextChunk("reinterpret_cast");
1705 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1706 Pattern->AddPlaceholderChunk("type");
1707 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1708 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1709 Pattern->AddPlaceholderChunk("expression");
1710 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1711 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001712
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001713 // const_cast < type-id > ( expression )
1714 Pattern = new CodeCompletionString;
1715 Pattern->AddTypedTextChunk("const_cast");
1716 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1717 Pattern->AddPlaceholderChunk("type");
1718 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1719 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1720 Pattern->AddPlaceholderChunk("expression");
1721 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1722 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001723
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001724 // typeid ( expression-or-type )
1725 Pattern = new CodeCompletionString;
1726 Pattern->AddTypedTextChunk("typeid");
1727 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1728 Pattern->AddPlaceholderChunk("expression-or-type");
1729 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1730 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001731
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001732 // new T ( ... )
1733 Pattern = new CodeCompletionString;
1734 Pattern->AddTypedTextChunk("new");
1735 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1736 Pattern->AddPlaceholderChunk("type");
1737 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1738 Pattern->AddPlaceholderChunk("expressions");
1739 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1740 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001741
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001742 // new T [ ] ( ... )
1743 Pattern = new CodeCompletionString;
1744 Pattern->AddTypedTextChunk("new");
1745 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1746 Pattern->AddPlaceholderChunk("type");
1747 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1748 Pattern->AddPlaceholderChunk("size");
1749 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1750 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1751 Pattern->AddPlaceholderChunk("expressions");
1752 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1753 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001754
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001755 // delete expression
1756 Pattern = new CodeCompletionString;
1757 Pattern->AddTypedTextChunk("delete");
1758 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1759 Pattern->AddPlaceholderChunk("expression");
1760 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001761
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001762 // delete [] expression
1763 Pattern = new CodeCompletionString;
1764 Pattern->AddTypedTextChunk("delete");
1765 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1766 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1767 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1768 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1769 Pattern->AddPlaceholderChunk("expression");
1770 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001771
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001772 // throw expression
1773 Pattern = new CodeCompletionString;
1774 Pattern->AddTypedTextChunk("throw");
1775 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1776 Pattern->AddPlaceholderChunk("expression");
1777 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001778
1779 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001780 }
1781
1782 if (SemaRef.getLangOptions().ObjC1) {
1783 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001784 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1785 // The interface can be NULL.
1786 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1787 if (ID->getSuperClass())
1788 Results.AddResult(Result("super"));
1789 }
1790
Douglas Gregorbca403c2010-01-13 23:51:12 +00001791 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001792 }
1793
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001794 // sizeof expression
1795 Pattern = new CodeCompletionString;
1796 Pattern->AddTypedTextChunk("sizeof");
1797 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1798 Pattern->AddPlaceholderChunk("expression-or-type");
1799 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1800 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001801 break;
1802 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001803
John McCallf312b1e2010-08-26 23:41:50 +00001804 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001805 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001806 }
1807
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001808 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1809 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001810
John McCallf312b1e2010-08-26 23:41:50 +00001811 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001812 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001813}
1814
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001815/// \brief If the given declaration has an associated type, add it as a result
1816/// type chunk.
1817static void AddResultTypeChunk(ASTContext &Context,
1818 NamedDecl *ND,
1819 CodeCompletionString *Result) {
1820 if (!ND)
1821 return;
Douglas Gregor6f942b22010-09-21 16:06:22 +00001822
1823 // Skip constructors and conversion functions, which have their return types
1824 // built into their names.
1825 if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND))
1826 return;
1827
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001828 // Determine the type of the declaration (if it has a type).
Douglas Gregor6f942b22010-09-21 16:06:22 +00001829 QualType T;
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001830 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1831 T = Function->getResultType();
1832 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1833 T = Method->getResultType();
1834 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1835 T = FunTmpl->getTemplatedDecl()->getResultType();
1836 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1837 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1838 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1839 /* Do nothing: ignore unresolved using declarations*/
1840 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1841 T = Value->getType();
1842 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1843 T = Property->getType();
1844
1845 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1846 return;
1847
Douglas Gregor84139d62010-04-05 21:25:31 +00001848 PrintingPolicy Policy(Context.PrintingPolicy);
1849 Policy.AnonymousTagLocations = false;
1850
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001851 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001852 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001853 Result->AddResultTypeChunk(TypeStr);
1854}
1855
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001856static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1857 CodeCompletionString *Result) {
1858 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1859 if (Sentinel->getSentinel() == 0) {
1860 if (Context.getLangOptions().ObjC1 &&
1861 Context.Idents.get("nil").hasMacroDefinition())
1862 Result->AddTextChunk(", nil");
1863 else if (Context.Idents.get("NULL").hasMacroDefinition())
1864 Result->AddTextChunk(", NULL");
1865 else
1866 Result->AddTextChunk(", (void*)0");
1867 }
1868}
1869
Douglas Gregor83482d12010-08-24 16:15:59 +00001870static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001871 ParmVarDecl *Param,
1872 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001873 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1874 if (Param->getType()->isDependentType() ||
1875 !Param->getType()->isBlockPointerType()) {
1876 // The argument for a dependent or non-block parameter is a placeholder
1877 // containing that parameter's type.
1878 std::string Result;
1879
Douglas Gregoraba48082010-08-29 19:47:46 +00001880 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001881 Result = Param->getIdentifier()->getName();
1882
1883 Param->getType().getAsStringInternal(Result,
1884 Context.PrintingPolicy);
1885
1886 if (ObjCMethodParam) {
1887 Result = "(" + Result;
1888 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001889 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001890 Result += Param->getIdentifier()->getName();
1891 }
1892 return Result;
1893 }
1894
1895 // The argument for a block pointer parameter is a block literal with
1896 // the appropriate type.
1897 FunctionProtoTypeLoc *Block = 0;
1898 TypeLoc TL;
1899 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1900 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1901 while (true) {
1902 // Look through typedefs.
1903 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1904 if (TypeSourceInfo *InnerTSInfo
1905 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1906 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1907 continue;
1908 }
1909 }
1910
1911 // Look through qualified types
1912 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1913 TL = QualifiedTL->getUnqualifiedLoc();
1914 continue;
1915 }
1916
1917 // Try to get the function prototype behind the block pointer type,
1918 // then we're done.
1919 if (BlockPointerTypeLoc *BlockPtr
1920 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1921 TL = BlockPtr->getPointeeLoc();
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001922 // Skip any paren typeloc.
1923 while (ParenTypeLoc *ParenPtr = dyn_cast<ParenTypeLoc>(&TL))
1924 TL = ParenPtr->getInnerLoc();
Douglas Gregor83482d12010-08-24 16:15:59 +00001925 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1926 }
1927 break;
1928 }
1929 }
1930
1931 if (!Block) {
1932 // We were unable to find a FunctionProtoTypeLoc with parameter names
1933 // for the block; just use the parameter type as a placeholder.
1934 std::string Result;
1935 Param->getType().getUnqualifiedType().
1936 getAsStringInternal(Result, Context.PrintingPolicy);
1937
1938 if (ObjCMethodParam) {
1939 Result = "(" + Result;
1940 Result += ")";
1941 if (Param->getIdentifier())
1942 Result += Param->getIdentifier()->getName();
1943 }
1944
1945 return Result;
1946 }
1947
1948 // We have the function prototype behind the block pointer type, as it was
1949 // written in the source.
Douglas Gregor38276252010-09-08 22:47:51 +00001950 std::string Result;
1951 QualType ResultType = Block->getTypePtr()->getResultType();
1952 if (!ResultType->isVoidType())
1953 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1954
1955 Result = '^' + Result;
1956 if (Block->getNumArgs() == 0) {
1957 if (Block->getTypePtr()->isVariadic())
1958 Result += "(...)";
Douglas Gregorc2760bc2010-10-02 23:49:58 +00001959 else
1960 Result += "(void)";
Douglas Gregor38276252010-09-08 22:47:51 +00001961 } else {
1962 Result += "(";
1963 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1964 if (I)
1965 Result += ", ";
1966 Result += FormatFunctionParameter(Context, Block->getArg(I));
1967
1968 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1969 Result += ", ...";
1970 }
1971 Result += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00001972 }
Douglas Gregor38276252010-09-08 22:47:51 +00001973
Douglas Gregorc2760bc2010-10-02 23:49:58 +00001974 if (Param->getIdentifier())
1975 Result += Param->getIdentifier()->getName();
1976
Douglas Gregor83482d12010-08-24 16:15:59 +00001977 return Result;
1978}
1979
Douglas Gregor86d9a522009-09-21 16:56:56 +00001980/// \brief Add function parameter chunks to the given code completion string.
1981static void AddFunctionParameterChunks(ASTContext &Context,
1982 FunctionDecl *Function,
1983 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001984 typedef CodeCompletionString::Chunk Chunk;
1985
Douglas Gregor86d9a522009-09-21 16:56:56 +00001986 CodeCompletionString *CCStr = Result;
1987
1988 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1989 ParmVarDecl *Param = Function->getParamDecl(P);
1990
1991 if (Param->hasDefaultArg()) {
1992 // When we see an optional default argument, put that argument and
1993 // the remaining default arguments into a new, optional string.
1994 CodeCompletionString *Opt = new CodeCompletionString;
1995 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1996 CCStr = Opt;
1997 }
1998
1999 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002000 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002001
2002 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00002003 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
2004
Douglas Gregore17794f2010-08-31 05:13:43 +00002005 if (Function->isVariadic() && P == N - 1)
2006 PlaceholderStr += ", ...";
2007
Douglas Gregor86d9a522009-09-21 16:56:56 +00002008 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002009 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002010 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00002011
2012 if (const FunctionProtoType *Proto
2013 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002014 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002015 if (Proto->getNumArgs() == 0)
2016 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002017
2018 MaybeAddSentinel(Context, Function, CCStr);
2019 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002020}
2021
2022/// \brief Add template parameter chunks to the given code completion string.
2023static void AddTemplateParameterChunks(ASTContext &Context,
2024 TemplateDecl *Template,
2025 CodeCompletionString *Result,
2026 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002027 typedef CodeCompletionString::Chunk Chunk;
2028
Douglas Gregor86d9a522009-09-21 16:56:56 +00002029 CodeCompletionString *CCStr = Result;
2030 bool FirstParameter = true;
2031
2032 TemplateParameterList *Params = Template->getTemplateParameters();
2033 TemplateParameterList::iterator PEnd = Params->end();
2034 if (MaxParameters)
2035 PEnd = Params->begin() + MaxParameters;
2036 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
2037 bool HasDefaultArg = false;
2038 std::string PlaceholderStr;
2039 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
2040 if (TTP->wasDeclaredWithTypename())
2041 PlaceholderStr = "typename";
2042 else
2043 PlaceholderStr = "class";
2044
2045 if (TTP->getIdentifier()) {
2046 PlaceholderStr += ' ';
2047 PlaceholderStr += TTP->getIdentifier()->getName();
2048 }
2049
2050 HasDefaultArg = TTP->hasDefaultArgument();
2051 } else if (NonTypeTemplateParmDecl *NTTP
2052 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
2053 if (NTTP->getIdentifier())
2054 PlaceholderStr = NTTP->getIdentifier()->getName();
2055 NTTP->getType().getAsStringInternal(PlaceholderStr,
2056 Context.PrintingPolicy);
2057 HasDefaultArg = NTTP->hasDefaultArgument();
2058 } else {
2059 assert(isa<TemplateTemplateParmDecl>(*P));
2060 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
2061
2062 // Since putting the template argument list into the placeholder would
2063 // be very, very long, we just use an abbreviation.
2064 PlaceholderStr = "template<...> class";
2065 if (TTP->getIdentifier()) {
2066 PlaceholderStr += ' ';
2067 PlaceholderStr += TTP->getIdentifier()->getName();
2068 }
2069
2070 HasDefaultArg = TTP->hasDefaultArgument();
2071 }
2072
2073 if (HasDefaultArg) {
2074 // When we see an optional default argument, put that argument and
2075 // the remaining default arguments into a new, optional string.
2076 CodeCompletionString *Opt = new CodeCompletionString;
2077 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
2078 CCStr = Opt;
2079 }
2080
2081 if (FirstParameter)
2082 FirstParameter = false;
2083 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002084 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002085
2086 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002087 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002088 }
2089}
2090
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002091/// \brief Add a qualifier to the given code-completion string, if the
2092/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00002093static void
2094AddQualifierToCompletionString(CodeCompletionString *Result,
2095 NestedNameSpecifier *Qualifier,
2096 bool QualifierIsInformative,
2097 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002098 if (!Qualifier)
2099 return;
2100
2101 std::string PrintedNNS;
2102 {
2103 llvm::raw_string_ostream OS(PrintedNNS);
2104 Qualifier->print(OS, Context.PrintingPolicy);
2105 }
Douglas Gregor0563c262009-09-22 23:15:58 +00002106 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002107 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00002108 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002109 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002110}
2111
Douglas Gregora61a8792009-12-11 18:44:16 +00002112static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
2113 FunctionDecl *Function) {
2114 const FunctionProtoType *Proto
2115 = Function->getType()->getAs<FunctionProtoType>();
2116 if (!Proto || !Proto->getTypeQuals())
2117 return;
2118
2119 std::string QualsStr;
2120 if (Proto->getTypeQuals() & Qualifiers::Const)
2121 QualsStr += " const";
2122 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2123 QualsStr += " volatile";
2124 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2125 QualsStr += " restrict";
2126 Result->AddInformativeChunk(QualsStr);
2127}
2128
Douglas Gregor6f942b22010-09-21 16:06:22 +00002129/// \brief Add the name of the given declaration
2130static void AddTypedNameChunk(ASTContext &Context, NamedDecl *ND,
2131 CodeCompletionString *Result) {
2132 typedef CodeCompletionString::Chunk Chunk;
2133
2134 DeclarationName Name = ND->getDeclName();
2135 if (!Name)
2136 return;
2137
2138 switch (Name.getNameKind()) {
2139 case DeclarationName::Identifier:
2140 case DeclarationName::CXXConversionFunctionName:
2141 case DeclarationName::CXXOperatorName:
2142 case DeclarationName::CXXDestructorName:
2143 case DeclarationName::CXXLiteralOperatorName:
2144 Result->AddTypedTextChunk(ND->getNameAsString());
2145 break;
2146
2147 case DeclarationName::CXXUsingDirective:
2148 case DeclarationName::ObjCZeroArgSelector:
2149 case DeclarationName::ObjCOneArgSelector:
2150 case DeclarationName::ObjCMultiArgSelector:
2151 break;
2152
2153 case DeclarationName::CXXConstructorName: {
2154 CXXRecordDecl *Record = 0;
2155 QualType Ty = Name.getCXXNameType();
2156 if (const RecordType *RecordTy = Ty->getAs<RecordType>())
2157 Record = cast<CXXRecordDecl>(RecordTy->getDecl());
2158 else if (const InjectedClassNameType *InjectedTy
2159 = Ty->getAs<InjectedClassNameType>())
2160 Record = InjectedTy->getDecl();
2161 else {
2162 Result->AddTypedTextChunk(ND->getNameAsString());
2163 break;
2164 }
2165
2166 Result->AddTypedTextChunk(Record->getNameAsString());
2167 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
2168 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
2169 AddTemplateParameterChunks(Context, Template, Result);
2170 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
2171 }
2172 break;
2173 }
2174 }
2175}
2176
Douglas Gregor86d9a522009-09-21 16:56:56 +00002177/// \brief If possible, create a new code completion string for the given
2178/// result.
2179///
2180/// \returns Either a new, heap-allocated code completion string describing
2181/// how to use this result, or NULL to indicate that the string or name of the
2182/// result is all that is needed.
2183CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00002184CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor6f942b22010-09-21 16:06:22 +00002185 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002186 typedef CodeCompletionString::Chunk Chunk;
2187
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002188 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002189 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002190
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002191 if (!Result)
2192 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002193
2194 if (Kind == RK_Keyword) {
2195 Result->AddTypedTextChunk(Keyword);
2196 return Result;
2197 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002198
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002199 if (Kind == RK_Macro) {
2200 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002201 assert(MI && "Not a macro?");
2202
2203 Result->AddTypedTextChunk(Macro->getName());
2204
2205 if (!MI->isFunctionLike())
2206 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002207
2208 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002209 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002210 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2211 A != AEnd; ++A) {
2212 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002213 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002214
2215 if (!MI->isVariadic() || A != AEnd - 1) {
2216 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002217 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002218 continue;
2219 }
2220
2221 // Variadic argument; cope with the different between GNU and C99
2222 // variadic macros, providing a single placeholder for the rest of the
2223 // arguments.
2224 if ((*A)->isStr("__VA_ARGS__"))
2225 Result->AddPlaceholderChunk("...");
2226 else {
2227 std::string Arg = (*A)->getName();
2228 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00002229 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002230 }
2231 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002232 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002233 return Result;
2234 }
2235
Douglas Gregord8e8a582010-05-25 21:41:55 +00002236 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002237 NamedDecl *ND = Declaration;
2238
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002239 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002240 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002241 Result->AddTextChunk("::");
2242 return Result;
2243 }
2244
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002245 AddResultTypeChunk(S.Context, ND, Result);
2246
Douglas Gregor86d9a522009-09-21 16:56:56 +00002247 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002248 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2249 S.Context);
Douglas Gregor6f942b22010-09-21 16:06:22 +00002250 AddTypedNameChunk(S.Context, ND, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002251 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002252 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002253 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002254 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002255 return Result;
2256 }
2257
2258 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002259 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2260 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002261 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Douglas Gregor6f942b22010-09-21 16:06:22 +00002262 AddTypedNameChunk(S.Context, Function, Result);
2263
Douglas Gregor86d9a522009-09-21 16:56:56 +00002264 // Figure out which template parameters are deduced (or have default
2265 // arguments).
2266 llvm::SmallVector<bool, 16> Deduced;
2267 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2268 unsigned LastDeducibleArgument;
2269 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2270 --LastDeducibleArgument) {
2271 if (!Deduced[LastDeducibleArgument - 1]) {
2272 // C++0x: Figure out if the template argument has a default. If so,
2273 // the user doesn't need to type this argument.
2274 // FIXME: We need to abstract template parameters better!
2275 bool HasDefaultArg = false;
2276 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2277 LastDeducibleArgument - 1);
2278 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2279 HasDefaultArg = TTP->hasDefaultArgument();
2280 else if (NonTypeTemplateParmDecl *NTTP
2281 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2282 HasDefaultArg = NTTP->hasDefaultArgument();
2283 else {
2284 assert(isa<TemplateTemplateParmDecl>(Param));
2285 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002286 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002287 }
2288
2289 if (!HasDefaultArg)
2290 break;
2291 }
2292 }
2293
2294 if (LastDeducibleArgument) {
2295 // Some of the function template arguments cannot be deduced from a
2296 // function call, so we introduce an explicit template argument list
2297 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002298 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002299 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2300 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002301 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002302 }
2303
2304 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002305 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002306 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002307 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002308 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002309 return Result;
2310 }
2311
2312 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002313 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2314 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002315 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002316 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002317 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002318 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002319 return Result;
2320 }
2321
Douglas Gregor9630eb62009-11-17 16:44:22 +00002322 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002323 Selector Sel = Method->getSelector();
2324 if (Sel.isUnarySelector()) {
2325 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2326 return Result;
2327 }
2328
Douglas Gregord3c68542009-11-19 01:08:35 +00002329 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2330 SelName += ':';
2331 if (StartParameter == 0)
2332 Result->AddTypedTextChunk(SelName);
2333 else {
2334 Result->AddInformativeChunk(SelName);
2335
2336 // If there is only one parameter, and we're past it, add an empty
2337 // typed-text chunk since there is nothing to type.
2338 if (Method->param_size() == 1)
2339 Result->AddTypedTextChunk("");
2340 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002341 unsigned Idx = 0;
2342 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2343 PEnd = Method->param_end();
2344 P != PEnd; (void)++P, ++Idx) {
2345 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002346 std::string Keyword;
2347 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002348 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002349 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2350 Keyword += II->getName().str();
2351 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002352 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002353 Result->AddInformativeChunk(Keyword);
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002354 else
Douglas Gregord3c68542009-11-19 01:08:35 +00002355 Result->AddTypedTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002356 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002357
2358 // If we're before the starting parameter, skip the placeholder.
2359 if (Idx < StartParameter)
2360 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002361
2362 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002363
2364 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002365 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002366 else {
2367 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2368 Arg = "(" + Arg + ")";
2369 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002370 if (DeclaringEntity || AllParametersAreInformative)
2371 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002372 }
2373
Douglas Gregore17794f2010-08-31 05:13:43 +00002374 if (Method->isVariadic() && (P + 1) == PEnd)
2375 Arg += ", ...";
2376
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002377 if (DeclaringEntity)
2378 Result->AddTextChunk(Arg);
2379 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002380 Result->AddInformativeChunk(Arg);
2381 else
2382 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002383 }
2384
Douglas Gregor2a17af02009-12-23 00:21:46 +00002385 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002386 if (Method->param_size() == 0) {
2387 if (DeclaringEntity)
2388 Result->AddTextChunk(", ...");
2389 else if (AllParametersAreInformative)
2390 Result->AddInformativeChunk(", ...");
2391 else
2392 Result->AddPlaceholderChunk(", ...");
2393 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002394
2395 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002396 }
2397
Douglas Gregor9630eb62009-11-17 16:44:22 +00002398 return Result;
2399 }
2400
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002401 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002402 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2403 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002404
2405 Result->AddTypedTextChunk(ND->getNameAsString());
2406 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002407}
2408
Douglas Gregor86d802e2009-09-23 00:34:09 +00002409CodeCompletionString *
2410CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2411 unsigned CurrentArg,
Douglas Gregor32be4a52010-10-11 21:37:58 +00002412 Sema &S,
2413 CodeCompletionString *Result) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002414 typedef CodeCompletionString::Chunk Chunk;
2415
Douglas Gregor32be4a52010-10-11 21:37:58 +00002416 if (!Result)
2417 Result = new CodeCompletionString;
Douglas Gregor86d802e2009-09-23 00:34:09 +00002418 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002419 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002420 const FunctionProtoType *Proto
2421 = dyn_cast<FunctionProtoType>(getFunctionType());
2422 if (!FDecl && !Proto) {
2423 // Function without a prototype. Just give the return type and a
2424 // highlighted ellipsis.
2425 const FunctionType *FT = getFunctionType();
2426 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002427 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002428 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2429 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2430 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002431 return Result;
2432 }
2433
2434 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002435 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002436 else
2437 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002438 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002439
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002440 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002441 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2442 for (unsigned I = 0; I != NumParams; ++I) {
2443 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002444 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002445
2446 std::string ArgString;
2447 QualType ArgType;
2448
2449 if (FDecl) {
2450 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2451 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2452 } else {
2453 ArgType = Proto->getArgType(I);
2454 }
2455
2456 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2457
2458 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002459 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002460 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002461 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002462 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002463 }
2464
2465 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002466 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002467 if (CurrentArg < NumParams)
2468 Result->AddTextChunk("...");
2469 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002470 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002471 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002472 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002473
2474 return Result;
2475}
2476
Douglas Gregor1827e102010-08-16 16:18:59 +00002477unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
Douglas Gregorb05496d2010-09-20 21:11:48 +00002478 const LangOptions &LangOpts,
Douglas Gregor1827e102010-08-16 16:18:59 +00002479 bool PreferredTypeIsPointer) {
2480 unsigned Priority = CCP_Macro;
2481
Douglas Gregorb05496d2010-09-20 21:11:48 +00002482 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2483 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2484 MacroName.equals("Nil")) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002485 Priority = CCP_Constant;
2486 if (PreferredTypeIsPointer)
2487 Priority = Priority / CCF_SimilarTypeMatch;
Douglas Gregorb05496d2010-09-20 21:11:48 +00002488 }
2489 // Treat "YES", "NO", "true", and "false" as constants.
2490 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2491 MacroName.equals("true") || MacroName.equals("false"))
2492 Priority = CCP_Constant;
2493 // Treat "bool" as a type.
2494 else if (MacroName.equals("bool"))
2495 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2496
Douglas Gregor1827e102010-08-16 16:18:59 +00002497
2498 return Priority;
2499}
2500
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002501CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2502 if (!D)
2503 return CXCursor_UnexposedDecl;
2504
2505 switch (D->getKind()) {
2506 case Decl::Enum: return CXCursor_EnumDecl;
2507 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2508 case Decl::Field: return CXCursor_FieldDecl;
2509 case Decl::Function:
2510 return CXCursor_FunctionDecl;
2511 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2512 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2513 case Decl::ObjCClass:
2514 // FIXME
2515 return CXCursor_UnexposedDecl;
2516 case Decl::ObjCForwardProtocol:
2517 // FIXME
2518 return CXCursor_UnexposedDecl;
2519 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2520 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2521 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2522 case Decl::ObjCMethod:
2523 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2524 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2525 case Decl::CXXMethod: return CXCursor_CXXMethod;
2526 case Decl::CXXConstructor: return CXCursor_Constructor;
2527 case Decl::CXXDestructor: return CXCursor_Destructor;
2528 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2529 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2530 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2531 case Decl::ParmVar: return CXCursor_ParmDecl;
2532 case Decl::Typedef: return CXCursor_TypedefDecl;
2533 case Decl::Var: return CXCursor_VarDecl;
2534 case Decl::Namespace: return CXCursor_Namespace;
2535 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2536 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2537 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2538 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2539 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2540 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2541 case Decl::ClassTemplatePartialSpecialization:
2542 return CXCursor_ClassTemplatePartialSpecialization;
2543 case Decl::UsingDirective: return CXCursor_UsingDirective;
2544
2545 case Decl::Using:
2546 case Decl::UnresolvedUsingValue:
2547 case Decl::UnresolvedUsingTypename:
2548 return CXCursor_UsingDeclaration;
2549
2550 default:
2551 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2552 switch (TD->getTagKind()) {
2553 case TTK_Struct: return CXCursor_StructDecl;
2554 case TTK_Class: return CXCursor_ClassDecl;
2555 case TTK_Union: return CXCursor_UnionDecl;
2556 case TTK_Enum: return CXCursor_EnumDecl;
2557 }
2558 }
2559 }
2560
2561 return CXCursor_UnexposedDecl;
2562}
2563
Douglas Gregor590c7d52010-07-08 20:55:51 +00002564static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2565 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002566 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002567
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002568 Results.EnterNewScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002569
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002570 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2571 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002572 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002573 Results.AddResult(Result(M->first,
2574 getMacroUsagePriority(M->first->getName(),
Douglas Gregorb05496d2010-09-20 21:11:48 +00002575 PP.getLangOptions(),
Douglas Gregor1827e102010-08-16 16:18:59 +00002576 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002577 }
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002578
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002579 Results.ExitScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002580
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002581}
2582
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002583static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2584 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002585 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002586
2587 Results.EnterNewScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002588
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002589 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2590 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2591 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2592 Results.AddResult(Result("__func__", CCP_Constant));
2593 Results.ExitScope();
2594}
2595
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002596static void HandleCodeCompleteResults(Sema *S,
2597 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002598 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002599 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002600 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002601 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002602 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002603
2604 for (unsigned I = 0; I != NumResults; ++I)
2605 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002606}
2607
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002608static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2609 Sema::ParserCompletionContext PCC) {
2610 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002611 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002612 return CodeCompletionContext::CCC_TopLevel;
2613
John McCallf312b1e2010-08-26 23:41:50 +00002614 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002615 return CodeCompletionContext::CCC_ClassStructUnion;
2616
John McCallf312b1e2010-08-26 23:41:50 +00002617 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002618 return CodeCompletionContext::CCC_ObjCInterface;
2619
John McCallf312b1e2010-08-26 23:41:50 +00002620 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002621 return CodeCompletionContext::CCC_ObjCImplementation;
2622
John McCallf312b1e2010-08-26 23:41:50 +00002623 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002624 return CodeCompletionContext::CCC_ObjCIvarList;
2625
John McCallf312b1e2010-08-26 23:41:50 +00002626 case Sema::PCC_Template:
2627 case Sema::PCC_MemberTemplate:
Douglas Gregor52779fb2010-09-23 23:01:17 +00002628 if (S.CurContext->isFileContext())
2629 return CodeCompletionContext::CCC_TopLevel;
2630 else if (S.CurContext->isRecord())
2631 return CodeCompletionContext::CCC_ClassStructUnion;
2632 else
2633 return CodeCompletionContext::CCC_Other;
2634
John McCallf312b1e2010-08-26 23:41:50 +00002635 case Sema::PCC_RecoveryInFunction:
Douglas Gregor52779fb2010-09-23 23:01:17 +00002636 return CodeCompletionContext::CCC_Recovery;
Douglas Gregora5450a02010-10-18 22:01:46 +00002637
John McCallf312b1e2010-08-26 23:41:50 +00002638 case Sema::PCC_ForInit:
Douglas Gregora5450a02010-10-18 22:01:46 +00002639 if (S.getLangOptions().CPlusPlus || S.getLangOptions().C99 ||
2640 S.getLangOptions().ObjC1)
2641 return CodeCompletionContext::CCC_ParenthesizedExpression;
2642 else
2643 return CodeCompletionContext::CCC_Expression;
2644
2645 case Sema::PCC_Expression:
John McCallf312b1e2010-08-26 23:41:50 +00002646 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002647 return CodeCompletionContext::CCC_Expression;
2648
John McCallf312b1e2010-08-26 23:41:50 +00002649 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002650 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002651
John McCallf312b1e2010-08-26 23:41:50 +00002652 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002653 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00002654
2655 case Sema::PCC_ParenthesizedExpression:
2656 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002657 }
2658
2659 return CodeCompletionContext::CCC_Other;
2660}
2661
Douglas Gregorf6961522010-08-27 21:18:54 +00002662/// \brief If we're in a C++ virtual member function, add completion results
2663/// that invoke the functions we override, since it's common to invoke the
2664/// overridden function as well as adding new functionality.
2665///
2666/// \param S The semantic analysis object for which we are generating results.
2667///
2668/// \param InContext This context in which the nested-name-specifier preceding
2669/// the code-completion point
2670static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2671 ResultBuilder &Results) {
2672 // Look through blocks.
2673 DeclContext *CurContext = S.CurContext;
2674 while (isa<BlockDecl>(CurContext))
2675 CurContext = CurContext->getParent();
2676
2677
2678 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2679 if (!Method || !Method->isVirtual())
2680 return;
2681
2682 // We need to have names for all of the parameters, if we're going to
2683 // generate a forwarding call.
2684 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2685 PEnd = Method->param_end();
2686 P != PEnd;
2687 ++P) {
2688 if (!(*P)->getDeclName())
2689 return;
2690 }
2691
2692 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2693 MEnd = Method->end_overridden_methods();
2694 M != MEnd; ++M) {
2695 CodeCompletionString *Pattern = new CodeCompletionString;
2696 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2697 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2698 continue;
2699
2700 // If we need a nested-name-specifier, add one now.
2701 if (!InContext) {
2702 NestedNameSpecifier *NNS
2703 = getRequiredQualification(S.Context, CurContext,
2704 Overridden->getDeclContext());
2705 if (NNS) {
2706 std::string Str;
2707 llvm::raw_string_ostream OS(Str);
2708 NNS->print(OS, S.Context.PrintingPolicy);
2709 Pattern->AddTextChunk(OS.str());
2710 }
2711 } else if (!InContext->Equals(Overridden->getDeclContext()))
2712 continue;
2713
2714 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2715 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2716 bool FirstParam = true;
2717 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2718 PEnd = Method->param_end();
2719 P != PEnd; ++P) {
2720 if (FirstParam)
2721 FirstParam = false;
2722 else
2723 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2724
2725 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2726 }
2727 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2728 Results.AddResult(CodeCompletionResult(Pattern,
2729 CCP_SuperCompletion,
2730 CXCursor_CXXMethod));
2731 Results.Ignore(Overridden);
2732 }
2733}
2734
Douglas Gregor01dfea02010-01-10 23:08:15 +00002735void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002736 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002737 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00002738 ResultBuilder Results(*this,
2739 mapCodeCompletionContext(*this, CompletionContext));
Douglas Gregorf6961522010-08-27 21:18:54 +00002740 Results.EnterNewScope();
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002741
Douglas Gregor01dfea02010-01-10 23:08:15 +00002742 // Determine how to filter results, e.g., so that the names of
2743 // values (functions, enumerators, function templates, etc.) are
2744 // only allowed where we can have an expression.
2745 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002746 case PCC_Namespace:
2747 case PCC_Class:
2748 case PCC_ObjCInterface:
2749 case PCC_ObjCImplementation:
2750 case PCC_ObjCInstanceVariableList:
2751 case PCC_Template:
2752 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002753 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002754 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2755 break;
2756
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002757 case PCC_Statement:
Douglas Gregor02688102010-09-14 23:59:36 +00002758 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002759 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002760 case PCC_ForInit:
2761 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002762 if (WantTypesInContext(CompletionContext, getLangOptions()))
2763 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2764 else
2765 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002766
2767 if (getLangOptions().CPlusPlus)
2768 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002769 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002770
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002771 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002772 // Unfiltered
2773 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002774 }
2775
Douglas Gregor3cdee122010-08-26 16:36:48 +00002776 // If we are in a C++ non-static member function, check the qualifiers on
2777 // the member function to filter/prioritize the results list.
2778 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2779 if (CurMethod->isInstance())
2780 Results.setObjectTypeQualifiers(
2781 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2782
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002783 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002784 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2785 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002786
Douglas Gregorbca403c2010-01-13 23:51:12 +00002787 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002788 Results.ExitScope();
2789
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002790 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00002791 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-08-24 01:11:00 +00002792 case PCC_Expression:
2793 case PCC_Statement:
2794 case PCC_RecoveryInFunction:
2795 if (S->getFnParent())
2796 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2797 break;
2798
2799 case PCC_Namespace:
2800 case PCC_Class:
2801 case PCC_ObjCInterface:
2802 case PCC_ObjCImplementation:
2803 case PCC_ObjCInstanceVariableList:
2804 case PCC_Template:
2805 case PCC_MemberTemplate:
2806 case PCC_ForInit:
2807 case PCC_Condition:
2808 case PCC_Type:
2809 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002810 }
2811
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002812 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002813 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002814
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002815 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002816 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002817}
2818
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002819static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2820 ParsedType Receiver,
2821 IdentifierInfo **SelIdents,
2822 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00002823 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002824 bool IsSuper,
2825 ResultBuilder &Results);
2826
2827void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2828 bool AllowNonIdentifiers,
2829 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002830 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00002831 ResultBuilder Results(*this,
2832 AllowNestedNameSpecifiers
2833 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2834 : CodeCompletionContext::CCC_Name);
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002835 Results.EnterNewScope();
2836
2837 // Type qualifiers can come after names.
2838 Results.AddResult(Result("const"));
2839 Results.AddResult(Result("volatile"));
2840 if (getLangOptions().C99)
2841 Results.AddResult(Result("restrict"));
2842
2843 if (getLangOptions().CPlusPlus) {
2844 if (AllowNonIdentifiers) {
2845 Results.AddResult(Result("operator"));
2846 }
2847
2848 // Add nested-name-specifiers.
2849 if (AllowNestedNameSpecifiers) {
2850 Results.allowNestedNameSpecifiers();
Douglas Gregor52779fb2010-09-23 23:01:17 +00002851 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002852 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2853 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2854 CodeCompleter->includeGlobals());
Douglas Gregor52779fb2010-09-23 23:01:17 +00002855 Results.setFilter(0);
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002856 }
2857 }
2858 Results.ExitScope();
2859
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002860 // If we're in a context where we might have an expression (rather than a
2861 // declaration), and what we've seen so far is an Objective-C type that could
2862 // be a receiver of a class message, this may be a class message send with
2863 // the initial opening bracket '[' missing. Add appropriate completions.
2864 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2865 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2866 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2867 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2868 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2869 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2870 DS.getTypeQualifiers() == 0 &&
2871 S &&
2872 (S->getFlags() & Scope::DeclScope) != 0 &&
2873 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2874 Scope::FunctionPrototypeScope |
2875 Scope::AtCatchScope)) == 0) {
2876 ParsedType T = DS.getRepAsType();
2877 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
Douglas Gregor70c5ac72010-09-20 23:34:21 +00002878 AddClassMessageCompletions(*this, S, T, 0, 0, false, false, Results);
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002879 }
2880
Douglas Gregor4497dd42010-08-24 04:59:56 +00002881 // Note that we intentionally suppress macro results here, since we do not
2882 // encourage using macros to produce the names of entities.
2883
Douglas Gregor52779fb2010-09-23 23:01:17 +00002884 HandleCodeCompleteResults(this, CodeCompleter,
2885 Results.getCompletionContext(),
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002886 Results.data(), Results.size());
2887}
2888
Douglas Gregorfb629412010-08-23 21:17:50 +00002889struct Sema::CodeCompleteExpressionData {
2890 CodeCompleteExpressionData(QualType PreferredType = QualType())
2891 : PreferredType(PreferredType), IntegralConstantExpression(false),
2892 ObjCCollection(false) { }
2893
2894 QualType PreferredType;
2895 bool IntegralConstantExpression;
2896 bool ObjCCollection;
2897 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2898};
2899
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002900/// \brief Perform code-completion in an expression context when we know what
2901/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002902///
2903/// \param IntegralConstantExpression Only permit integral constant
2904/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002905void Sema::CodeCompleteExpression(Scope *S,
2906 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002907 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00002908 ResultBuilder Results(*this, CodeCompletionContext::CCC_Expression);
Douglas Gregorfb629412010-08-23 21:17:50 +00002909 if (Data.ObjCCollection)
2910 Results.setFilter(&ResultBuilder::IsObjCCollection);
2911 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002912 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002913 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002914 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2915 else
2916 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002917
2918 if (!Data.PreferredType.isNull())
2919 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2920
2921 // Ignore any declarations that we were told that we don't care about.
2922 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2923 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002924
2925 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002926 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2927 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002928
2929 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002930 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002931 Results.ExitScope();
2932
Douglas Gregor590c7d52010-07-08 20:55:51 +00002933 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002934 if (!Data.PreferredType.isNull())
2935 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2936 || Data.PreferredType->isMemberPointerType()
2937 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002938
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002939 if (S->getFnParent() &&
2940 !Data.ObjCCollection &&
2941 !Data.IntegralConstantExpression)
2942 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2943
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002944 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002945 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002946 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002947 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2948 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002949 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002950}
2951
Douglas Gregorac5fd842010-09-18 01:28:11 +00002952void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
2953 if (E.isInvalid())
2954 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
2955 else if (getLangOptions().ObjC1)
2956 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
Douglas Gregor78edf512010-09-15 16:23:04 +00002957}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002958
Douglas Gregor73449212010-12-09 23:01:55 +00002959/// \brief The set of properties that have already been added, referenced by
2960/// property name.
2961typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
2962
Douglas Gregor95ac6552009-11-18 01:29:26 +00002963static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002964 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002965 DeclContext *CurContext,
Douglas Gregor73449212010-12-09 23:01:55 +00002966 AddedPropertiesSet &AddedProperties,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002967 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002968 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002969
2970 // Add properties in this container.
2971 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2972 PEnd = Container->prop_end();
2973 P != PEnd;
Douglas Gregor73449212010-12-09 23:01:55 +00002974 ++P) {
2975 if (AddedProperties.insert(P->getIdentifier()))
2976 Results.MaybeAddResult(Result(*P, 0), CurContext);
2977 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002978
2979 // Add properties in referenced protocols.
2980 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2981 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2982 PEnd = Protocol->protocol_end();
2983 P != PEnd; ++P)
Douglas Gregor73449212010-12-09 23:01:55 +00002984 AddObjCProperties(*P, AllowCategories, CurContext, AddedProperties,
2985 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002986 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002987 if (AllowCategories) {
2988 // Look through categories.
2989 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2990 Category; Category = Category->getNextClassCategory())
Douglas Gregor73449212010-12-09 23:01:55 +00002991 AddObjCProperties(Category, AllowCategories, CurContext,
2992 AddedProperties, Results);
Douglas Gregor322328b2009-11-18 22:32:06 +00002993 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002994
2995 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002996 for (ObjCInterfaceDecl::all_protocol_iterator
2997 I = IFace->all_referenced_protocol_begin(),
2998 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor73449212010-12-09 23:01:55 +00002999 AddObjCProperties(*I, AllowCategories, CurContext, AddedProperties,
3000 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003001
3002 // Look in the superclass.
3003 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00003004 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
Douglas Gregor73449212010-12-09 23:01:55 +00003005 AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003006 } else if (const ObjCCategoryDecl *Category
3007 = dyn_cast<ObjCCategoryDecl>(Container)) {
3008 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00003009 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
3010 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00003011 P != PEnd; ++P)
Douglas Gregor73449212010-12-09 23:01:55 +00003012 AddObjCProperties(*P, AllowCategories, CurContext, AddedProperties,
3013 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003014 }
3015}
3016
Douglas Gregor81b747b2009-09-17 21:32:03 +00003017void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
3018 SourceLocation OpLoc,
3019 bool IsArrow) {
3020 if (!BaseE || !CodeCompleter)
3021 return;
3022
John McCall0a2c5e22010-08-25 06:19:51 +00003023 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003024
Douglas Gregor81b747b2009-09-17 21:32:03 +00003025 Expr *Base = static_cast<Expr *>(BaseE);
3026 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003027
3028 if (IsArrow) {
3029 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
3030 BaseType = Ptr->getPointeeType();
3031 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00003032 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003033 else
3034 return;
3035 }
3036
Douglas Gregor52779fb2010-09-23 23:01:17 +00003037 ResultBuilder Results(*this,
3038 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
3039 BaseType),
3040 &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003041 Results.EnterNewScope();
3042 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00003043 // Indicate that we are performing a member access, and the cv-qualifiers
3044 // for the base object type.
3045 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
3046
Douglas Gregor95ac6552009-11-18 01:29:26 +00003047 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00003048 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00003049 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003050 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
3051 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003052
Douglas Gregor95ac6552009-11-18 01:29:26 +00003053 if (getLangOptions().CPlusPlus) {
3054 if (!Results.empty()) {
3055 // The "template" keyword can follow "->" or "." in the grammar.
3056 // However, we only want to suggest the template keyword if something
3057 // is dependent.
3058 bool IsDependent = BaseType->isDependentType();
3059 if (!IsDependent) {
3060 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
3061 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
3062 IsDependent = Ctx->isDependentContext();
3063 break;
3064 }
3065 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003066
Douglas Gregor95ac6552009-11-18 01:29:26 +00003067 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00003068 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003069 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003070 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003071 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
3072 // Objective-C property reference.
Douglas Gregor73449212010-12-09 23:01:55 +00003073 AddedPropertiesSet AddedProperties;
Douglas Gregor95ac6552009-11-18 01:29:26 +00003074
3075 // Add property results based on our interface.
3076 const ObjCObjectPointerType *ObjCPtr
3077 = BaseType->getAsObjCInterfacePointerType();
3078 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor73449212010-12-09 23:01:55 +00003079 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext,
3080 AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003081
3082 // Add properties from the protocols in a qualified interface.
3083 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
3084 E = ObjCPtr->qual_end();
3085 I != E; ++I)
Douglas Gregor73449212010-12-09 23:01:55 +00003086 AddObjCProperties(*I, true, CurContext, AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003087 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00003088 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00003089 // Objective-C instance variable access.
3090 ObjCInterfaceDecl *Class = 0;
3091 if (const ObjCObjectPointerType *ObjCPtr
3092 = BaseType->getAs<ObjCObjectPointerType>())
3093 Class = ObjCPtr->getInterfaceDecl();
3094 else
John McCallc12c5bb2010-05-15 11:32:37 +00003095 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00003096
3097 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00003098 if (Class) {
3099 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3100 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00003101 LookupVisibleDecls(Class, LookupMemberName, Consumer,
3102 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00003103 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003104 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003105
3106 // FIXME: How do we cope with isa?
3107
3108 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003109
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003110 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003111 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003112 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003113 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003114}
3115
Douglas Gregor374929f2009-09-18 15:37:17 +00003116void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
3117 if (!CodeCompleter)
3118 return;
3119
John McCall0a2c5e22010-08-25 06:19:51 +00003120 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003121 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003122 enum CodeCompletionContext::Kind ContextKind
3123 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00003124 switch ((DeclSpec::TST)TagSpec) {
3125 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003126 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003127 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003128 break;
3129
3130 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003131 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003132 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003133 break;
3134
3135 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00003136 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003137 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003138 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003139 break;
3140
3141 default:
3142 assert(false && "Unknown type specifier kind in CodeCompleteTag");
3143 return;
3144 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003145
Douglas Gregor52779fb2010-09-23 23:01:17 +00003146 ResultBuilder Results(*this, ContextKind);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003147 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00003148
3149 // First pass: look for tags.
3150 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00003151 LookupVisibleDecls(S, LookupTagName, Consumer,
3152 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00003153
Douglas Gregor8071e422010-08-15 06:18:01 +00003154 if (CodeCompleter->includeGlobals()) {
3155 // Second pass: look for nested name specifiers.
3156 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
3157 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
3158 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003159
Douglas Gregor52779fb2010-09-23 23:01:17 +00003160 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003161 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00003162}
3163
Douglas Gregor1a480c42010-08-27 17:35:51 +00003164void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00003165 ResultBuilder Results(*this, CodeCompletionContext::CCC_TypeQualifiers);
Douglas Gregor1a480c42010-08-27 17:35:51 +00003166 Results.EnterNewScope();
3167 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
3168 Results.AddResult("const");
3169 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
3170 Results.AddResult("volatile");
3171 if (getLangOptions().C99 &&
3172 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
3173 Results.AddResult("restrict");
3174 Results.ExitScope();
3175 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003176 Results.getCompletionContext(),
Douglas Gregor1a480c42010-08-27 17:35:51 +00003177 Results.data(), Results.size());
3178}
3179
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003180void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00003181 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003182 return;
3183
John McCall781472f2010-08-25 08:40:02 +00003184 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00003185 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00003186 CodeCompleteExpressionData Data(Switch->getCond()->getType());
3187 Data.IntegralConstantExpression = true;
3188 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003189 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00003190 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003191
3192 // Code-complete the cases of a switch statement over an enumeration type
3193 // by providing the list of
3194 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
3195
3196 // Determine which enumerators we have already seen in the switch statement.
3197 // FIXME: Ideally, we would also be able to look *past* the code-completion
3198 // token, in case we are code-completing in the middle of the switch and not
3199 // at the end. However, we aren't able to do so at the moment.
3200 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003201 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003202 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3203 SC = SC->getNextSwitchCase()) {
3204 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3205 if (!Case)
3206 continue;
3207
3208 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3209 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3210 if (EnumConstantDecl *Enumerator
3211 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3212 // We look into the AST of the case statement to determine which
3213 // enumerator was named. Alternatively, we could compute the value of
3214 // the integral constant expression, then compare it against the
3215 // values of each enumerator. However, value-based approach would not
3216 // work as well with C++ templates where enumerators declared within a
3217 // template are type- and value-dependent.
3218 EnumeratorsSeen.insert(Enumerator);
3219
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003220 // If this is a qualified-id, keep track of the nested-name-specifier
3221 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003222 //
3223 // switch (TagD.getKind()) {
3224 // case TagDecl::TK_enum:
3225 // break;
3226 // case XXX
3227 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003228 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003229 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3230 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003231 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003232 }
3233 }
3234
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003235 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3236 // If there are no prior enumerators in C++, check whether we have to
3237 // qualify the names of the enumerators that we suggest, because they
3238 // may not be visible in this scope.
3239 Qualifier = getRequiredQualification(Context, CurContext,
3240 Enum->getDeclContext());
3241
3242 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3243 }
3244
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003245 // Add any enumerators that have not yet been mentioned.
Douglas Gregor52779fb2010-09-23 23:01:17 +00003246 ResultBuilder Results(*this, CodeCompletionContext::CCC_Expression);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003247 Results.EnterNewScope();
3248 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3249 EEnd = Enum->enumerator_end();
3250 E != EEnd; ++E) {
3251 if (EnumeratorsSeen.count(*E))
3252 continue;
3253
John McCall0a2c5e22010-08-25 06:19:51 +00003254 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003255 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003256 }
3257 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003258
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003259 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003260 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003261 HandleCodeCompleteResults(this, CodeCompleter,
3262 CodeCompletionContext::CCC_Expression,
3263 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003264}
3265
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003266namespace {
3267 struct IsBetterOverloadCandidate {
3268 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003269 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003270
3271 public:
John McCall5769d612010-02-08 23:07:23 +00003272 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3273 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003274
3275 bool
3276 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003277 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003278 }
3279 };
3280}
3281
Douglas Gregord28dcd72010-05-30 06:10:08 +00003282static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3283 if (NumArgs && !Args)
3284 return true;
3285
3286 for (unsigned I = 0; I != NumArgs; ++I)
3287 if (!Args[I])
3288 return true;
3289
3290 return false;
3291}
3292
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003293void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3294 ExprTy **ArgsIn, unsigned NumArgs) {
3295 if (!CodeCompleter)
3296 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003297
3298 // When we're code-completing for a call, we fall back to ordinary
3299 // name code-completion whenever we can't produce specific
3300 // results. We may want to revisit this strategy in the future,
3301 // e.g., by merging the two kinds of results.
3302
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003303 Expr *Fn = (Expr *)FnIn;
3304 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003305
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003306 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003307 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003308 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003309 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003310 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003311 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003312
John McCall3b4294e2009-12-16 12:17:52 +00003313 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003314 SourceLocation Loc = Fn->getExprLoc();
3315 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003316
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003317 // FIXME: What if we're calling something that isn't a function declaration?
3318 // FIXME: What if we're calling a pseudo-destructor?
3319 // FIXME: What if we're calling a member function?
3320
Douglas Gregorc0265402010-01-21 15:46:19 +00003321 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3322 llvm::SmallVector<ResultCandidate, 8> Results;
3323
John McCall3b4294e2009-12-16 12:17:52 +00003324 Expr *NakedFn = Fn->IgnoreParenCasts();
3325 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3326 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3327 /*PartialOverloading=*/ true);
3328 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3329 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003330 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003331 if (!getLangOptions().CPlusPlus ||
3332 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003333 Results.push_back(ResultCandidate(FDecl));
3334 else
John McCall86820f52010-01-26 01:37:31 +00003335 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003336 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3337 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003338 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003339 }
John McCall3b4294e2009-12-16 12:17:52 +00003340 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003341
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003342 QualType ParamType;
3343
Douglas Gregorc0265402010-01-21 15:46:19 +00003344 if (!CandidateSet.empty()) {
3345 // Sort the overload candidate set by placing the best overloads first.
3346 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003347 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003348
Douglas Gregorc0265402010-01-21 15:46:19 +00003349 // Add the remaining viable overload candidates as code-completion reslults.
3350 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3351 CandEnd = CandidateSet.end();
3352 Cand != CandEnd; ++Cand) {
3353 if (Cand->Viable)
3354 Results.push_back(ResultCandidate(Cand->Function));
3355 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003356
3357 // From the viable candidates, try to determine the type of this parameter.
3358 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3359 if (const FunctionType *FType = Results[I].getFunctionType())
3360 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3361 if (NumArgs < Proto->getNumArgs()) {
3362 if (ParamType.isNull())
3363 ParamType = Proto->getArgType(NumArgs);
3364 else if (!Context.hasSameUnqualifiedType(
3365 ParamType.getNonReferenceType(),
3366 Proto->getArgType(NumArgs).getNonReferenceType())) {
3367 ParamType = QualType();
3368 break;
3369 }
3370 }
3371 }
3372 } else {
3373 // Try to determine the parameter type from the type of the expression
3374 // being called.
3375 QualType FunctionType = Fn->getType();
3376 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3377 FunctionType = Ptr->getPointeeType();
3378 else if (const BlockPointerType *BlockPtr
3379 = FunctionType->getAs<BlockPointerType>())
3380 FunctionType = BlockPtr->getPointeeType();
3381 else if (const MemberPointerType *MemPtr
3382 = FunctionType->getAs<MemberPointerType>())
3383 FunctionType = MemPtr->getPointeeType();
3384
3385 if (const FunctionProtoType *Proto
3386 = FunctionType->getAs<FunctionProtoType>()) {
3387 if (NumArgs < Proto->getNumArgs())
3388 ParamType = Proto->getArgType(NumArgs);
3389 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003390 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003391
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003392 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003393 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003394 else
3395 CodeCompleteExpression(S, ParamType);
3396
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003397 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003398 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3399 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003400}
3401
John McCalld226f652010-08-21 09:40:31 +00003402void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3403 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003404 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003405 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003406 return;
3407 }
3408
3409 CodeCompleteExpression(S, VD->getType());
3410}
3411
3412void Sema::CodeCompleteReturn(Scope *S) {
3413 QualType ResultType;
3414 if (isa<BlockDecl>(CurContext)) {
3415 if (BlockScopeInfo *BSI = getCurBlock())
3416 ResultType = BSI->ReturnType;
3417 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3418 ResultType = Function->getResultType();
3419 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3420 ResultType = Method->getResultType();
3421
3422 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003423 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003424 else
3425 CodeCompleteExpression(S, ResultType);
3426}
3427
3428void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3429 if (LHS)
3430 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3431 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003432 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003433}
3434
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003435void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003436 bool EnteringContext) {
3437 if (!SS.getScopeRep() || !CodeCompleter)
3438 return;
3439
Douglas Gregor86d9a522009-09-21 16:56:56 +00003440 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3441 if (!Ctx)
3442 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003443
3444 // Try to instantiate any non-dependent declaration contexts before
3445 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003446 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003447 return;
3448
Douglas Gregor52779fb2010-09-23 23:01:17 +00003449 ResultBuilder Results(*this, CodeCompletionContext::CCC_Name);
Douglas Gregorf6961522010-08-27 21:18:54 +00003450 Results.EnterNewScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00003451
Douglas Gregor86d9a522009-09-21 16:56:56 +00003452 // The "template" keyword can follow "::" in the grammar, but only
3453 // put it into the grammar if the nested-name-specifier is dependent.
3454 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3455 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003456 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003457
3458 // Add calls to overridden virtual functions, if there are any.
3459 //
3460 // FIXME: This isn't wonderful, because we don't know whether we're actually
3461 // in a context that permits expressions. This is a general issue with
3462 // qualified-id completions.
3463 if (!EnteringContext)
3464 MaybeAddOverrideCalls(*this, Ctx, Results);
3465 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003466
Douglas Gregorf6961522010-08-27 21:18:54 +00003467 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3468 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3469
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003470 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003471 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003472 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003473}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003474
3475void Sema::CodeCompleteUsing(Scope *S) {
3476 if (!CodeCompleter)
3477 return;
3478
Douglas Gregor52779fb2010-09-23 23:01:17 +00003479 ResultBuilder Results(*this,
3480 CodeCompletionContext::CCC_PotentiallyQualifiedName,
3481 &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003482 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003483
3484 // If we aren't in class scope, we could see the "namespace" keyword.
3485 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003486 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003487
3488 // After "using", we can see anything that would start a
3489 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003490 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003491 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3492 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003493 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003494
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003495 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003496 CodeCompletionContext::CCC_PotentiallyQualifiedName,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003497 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003498}
3499
3500void Sema::CodeCompleteUsingDirective(Scope *S) {
3501 if (!CodeCompleter)
3502 return;
3503
Douglas Gregor86d9a522009-09-21 16:56:56 +00003504 // After "using namespace", we expect to see a namespace name or namespace
3505 // alias.
Douglas Gregor52779fb2010-09-23 23:01:17 +00003506 ResultBuilder Results(*this, CodeCompletionContext::CCC_Namespace,
3507 &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003508 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003509 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003510 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3511 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003512 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003513 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003514 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003515 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003516}
3517
3518void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3519 if (!CodeCompleter)
3520 return;
3521
Douglas Gregor86d9a522009-09-21 16:56:56 +00003522 DeclContext *Ctx = (DeclContext *)S->getEntity();
3523 if (!S->getParent())
3524 Ctx = Context.getTranslationUnitDecl();
3525
Douglas Gregor52779fb2010-09-23 23:01:17 +00003526 bool SuppressedGlobalResults
3527 = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
3528
3529 ResultBuilder Results(*this,
3530 SuppressedGlobalResults
3531 ? CodeCompletionContext::CCC_Namespace
3532 : CodeCompletionContext::CCC_Other,
3533 &ResultBuilder::IsNamespace);
3534
3535 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00003536 // We only want to see those namespaces that have already been defined
3537 // within this scope, because its likely that the user is creating an
3538 // extended namespace declaration. Keep track of the most recent
3539 // definition of each namespace.
3540 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3541 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3542 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3543 NS != NSEnd; ++NS)
3544 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3545
3546 // Add the most recent definition (or extended definition) of each
3547 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003548 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003549 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3550 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3551 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003552 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003553 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003554 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003555 }
3556
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003557 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003558 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003559 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003560}
3561
3562void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3563 if (!CodeCompleter)
3564 return;
3565
Douglas Gregor86d9a522009-09-21 16:56:56 +00003566 // After "namespace", we expect to see a namespace or alias.
Douglas Gregor52779fb2010-09-23 23:01:17 +00003567 ResultBuilder Results(*this, CodeCompletionContext::CCC_Namespace,
3568 &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003569 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003570 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3571 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003572 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003573 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003574 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003575}
3576
Douglas Gregored8d3222009-09-18 20:05:18 +00003577void Sema::CodeCompleteOperatorName(Scope *S) {
3578 if (!CodeCompleter)
3579 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003580
John McCall0a2c5e22010-08-25 06:19:51 +00003581 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00003582 ResultBuilder Results(*this, CodeCompletionContext::CCC_Type,
3583 &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003584 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003585
Douglas Gregor86d9a522009-09-21 16:56:56 +00003586 // Add the names of overloadable operators.
3587#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3588 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003589 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003590#include "clang/Basic/OperatorKinds.def"
3591
3592 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003593 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003594 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003595 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3596 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003597
3598 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003599 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003600 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003601
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003602 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003603 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003604 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003605}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003606
Douglas Gregor0133f522010-08-28 00:00:50 +00003607void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3608 CXXBaseOrMemberInitializer** Initializers,
3609 unsigned NumInitializers) {
3610 CXXConstructorDecl *Constructor
3611 = static_cast<CXXConstructorDecl *>(ConstructorD);
3612 if (!Constructor)
3613 return;
3614
Douglas Gregor52779fb2010-09-23 23:01:17 +00003615 ResultBuilder Results(*this,
3616 CodeCompletionContext::CCC_PotentiallyQualifiedName);
Douglas Gregor0133f522010-08-28 00:00:50 +00003617 Results.EnterNewScope();
3618
3619 // Fill in any already-initialized fields or base classes.
3620 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3621 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3622 for (unsigned I = 0; I != NumInitializers; ++I) {
3623 if (Initializers[I]->isBaseInitializer())
3624 InitializedBases.insert(
3625 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3626 else
Francois Pichet00eb3f92010-12-04 09:14:42 +00003627 InitializedFields.insert(cast<FieldDecl>(
3628 Initializers[I]->getAnyMember()));
Douglas Gregor0133f522010-08-28 00:00:50 +00003629 }
3630
3631 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003632 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003633 CXXRecordDecl *ClassDecl = Constructor->getParent();
3634 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3635 BaseEnd = ClassDecl->bases_end();
3636 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003637 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3638 SawLastInitializer
3639 = NumInitializers > 0 &&
3640 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3641 Context.hasSameUnqualifiedType(Base->getType(),
3642 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003643 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003644 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003645
3646 CodeCompletionString *Pattern = new CodeCompletionString;
3647 Pattern->AddTypedTextChunk(
3648 Base->getType().getAsString(Context.PrintingPolicy));
3649 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3650 Pattern->AddPlaceholderChunk("args");
3651 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003652 Results.AddResult(CodeCompletionResult(Pattern,
3653 SawLastInitializer? CCP_NextInitializer
3654 : CCP_MemberDeclaration));
3655 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003656 }
3657
3658 // Add completions for virtual base classes.
3659 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3660 BaseEnd = ClassDecl->vbases_end();
3661 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003662 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3663 SawLastInitializer
3664 = NumInitializers > 0 &&
3665 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3666 Context.hasSameUnqualifiedType(Base->getType(),
3667 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003668 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003669 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003670
3671 CodeCompletionString *Pattern = new CodeCompletionString;
3672 Pattern->AddTypedTextChunk(
3673 Base->getType().getAsString(Context.PrintingPolicy));
3674 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3675 Pattern->AddPlaceholderChunk("args");
3676 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003677 Results.AddResult(CodeCompletionResult(Pattern,
3678 SawLastInitializer? CCP_NextInitializer
3679 : CCP_MemberDeclaration));
3680 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003681 }
3682
3683 // Add completions for members.
3684 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3685 FieldEnd = ClassDecl->field_end();
3686 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003687 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3688 SawLastInitializer
3689 = NumInitializers > 0 &&
Francois Pichet00eb3f92010-12-04 09:14:42 +00003690 Initializers[NumInitializers - 1]->isAnyMemberInitializer() &&
3691 Initializers[NumInitializers - 1]->getAnyMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003692 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003693 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003694
3695 if (!Field->getDeclName())
3696 continue;
3697
3698 CodeCompletionString *Pattern = new CodeCompletionString;
3699 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3700 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3701 Pattern->AddPlaceholderChunk("args");
3702 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003703 Results.AddResult(CodeCompletionResult(Pattern,
3704 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003705 : CCP_MemberDeclaration,
3706 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003707 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003708 }
3709 Results.ExitScope();
3710
Douglas Gregor52779fb2010-09-23 23:01:17 +00003711 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor0133f522010-08-28 00:00:50 +00003712 Results.data(), Results.size());
3713}
3714
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003715// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3716// true or false.
3717#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003718static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003719 ResultBuilder &Results,
3720 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003721 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003722 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003723 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003724
3725 CodeCompletionString *Pattern = 0;
3726 if (LangOpts.ObjC2) {
3727 // @dynamic
3728 Pattern = new CodeCompletionString;
3729 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3730 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3731 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003732 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003733
3734 // @synthesize
3735 Pattern = new CodeCompletionString;
3736 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3737 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3738 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003739 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003740 }
3741}
3742
Douglas Gregorbca403c2010-01-13 23:51:12 +00003743static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003744 ResultBuilder &Results,
3745 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003746 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003747
3748 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003749 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003750
3751 if (LangOpts.ObjC2) {
3752 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003753 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003754
3755 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003756 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003757
3758 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003759 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003760 }
3761}
3762
Douglas Gregorbca403c2010-01-13 23:51:12 +00003763static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003764 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003765 CodeCompletionString *Pattern = 0;
3766
3767 // @class name ;
3768 Pattern = new CodeCompletionString;
3769 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3770 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003771 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003772 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003773
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003774 if (Results.includeCodePatterns()) {
3775 // @interface name
3776 // FIXME: Could introduce the whole pattern, including superclasses and
3777 // such.
3778 Pattern = new CodeCompletionString;
3779 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3780 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3781 Pattern->AddPlaceholderChunk("class");
3782 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003783
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003784 // @protocol name
3785 Pattern = new CodeCompletionString;
3786 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3787 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3788 Pattern->AddPlaceholderChunk("protocol");
3789 Results.AddResult(Result(Pattern));
3790
3791 // @implementation name
3792 Pattern = new CodeCompletionString;
3793 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3794 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3795 Pattern->AddPlaceholderChunk("class");
3796 Results.AddResult(Result(Pattern));
3797 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003798
3799 // @compatibility_alias name
3800 Pattern = new CodeCompletionString;
3801 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3802 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3803 Pattern->AddPlaceholderChunk("alias");
3804 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3805 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003806 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003807}
3808
John McCalld226f652010-08-21 09:40:31 +00003809void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003810 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003811 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00003812 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003813 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003814 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003815 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003816 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003817 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003818 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003819 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003820 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003821 HandleCodeCompleteResults(this, CodeCompleter,
3822 CodeCompletionContext::CCC_Other,
3823 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003824}
3825
Douglas Gregorbca403c2010-01-13 23:51:12 +00003826static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003827 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003828 CodeCompletionString *Pattern = 0;
3829
3830 // @encode ( type-name )
3831 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003832 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003833 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3834 Pattern->AddPlaceholderChunk("type-name");
3835 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003836 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003837
3838 // @protocol ( protocol-name )
3839 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003840 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003841 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3842 Pattern->AddPlaceholderChunk("protocol-name");
3843 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003844 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003845
3846 // @selector ( selector )
3847 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003848 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003849 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3850 Pattern->AddPlaceholderChunk("selector");
3851 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003852 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003853}
3854
Douglas Gregorbca403c2010-01-13 23:51:12 +00003855static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003856 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003857 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003858
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003859 if (Results.includeCodePatterns()) {
3860 // @try { statements } @catch ( declaration ) { statements } @finally
3861 // { statements }
3862 Pattern = new CodeCompletionString;
3863 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3864 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3865 Pattern->AddPlaceholderChunk("statements");
3866 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3867 Pattern->AddTextChunk("@catch");
3868 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3869 Pattern->AddPlaceholderChunk("parameter");
3870 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3871 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3872 Pattern->AddPlaceholderChunk("statements");
3873 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3874 Pattern->AddTextChunk("@finally");
3875 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3876 Pattern->AddPlaceholderChunk("statements");
3877 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3878 Results.AddResult(Result(Pattern));
3879 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003880
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003881 // @throw
3882 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003883 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003884 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003885 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003886 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003887
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003888 if (Results.includeCodePatterns()) {
3889 // @synchronized ( expression ) { statements }
3890 Pattern = new CodeCompletionString;
3891 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3892 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3893 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3894 Pattern->AddPlaceholderChunk("expression");
3895 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3896 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3897 Pattern->AddPlaceholderChunk("statements");
3898 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3899 Results.AddResult(Result(Pattern));
3900 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003901}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003902
Douglas Gregorbca403c2010-01-13 23:51:12 +00003903static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003904 ResultBuilder &Results,
3905 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003906 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003907 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3908 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3909 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003910 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003911 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003912}
3913
3914void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00003915 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003916 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003917 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003918 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003919 HandleCodeCompleteResults(this, CodeCompleter,
3920 CodeCompletionContext::CCC_Other,
3921 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003922}
3923
3924void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00003925 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003926 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003927 AddObjCStatementResults(Results, false);
3928 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003929 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003930 HandleCodeCompleteResults(this, CodeCompleter,
3931 CodeCompletionContext::CCC_Other,
3932 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003933}
3934
3935void Sema::CodeCompleteObjCAtExpression(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00003936 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003937 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003938 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003939 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003940 HandleCodeCompleteResults(this, CodeCompleter,
3941 CodeCompletionContext::CCC_Other,
3942 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003943}
3944
Douglas Gregor988358f2009-11-19 00:14:45 +00003945/// \brief Determine whether the addition of the given flag to an Objective-C
3946/// property's attributes will cause a conflict.
3947static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3948 // Check if we've already added this flag.
3949 if (Attributes & NewFlag)
3950 return true;
3951
3952 Attributes |= NewFlag;
3953
3954 // Check for collisions with "readonly".
3955 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3956 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3957 ObjCDeclSpec::DQ_PR_assign |
3958 ObjCDeclSpec::DQ_PR_copy |
3959 ObjCDeclSpec::DQ_PR_retain)))
3960 return true;
3961
3962 // Check for more than one of { assign, copy, retain }.
3963 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3964 ObjCDeclSpec::DQ_PR_copy |
3965 ObjCDeclSpec::DQ_PR_retain);
3966 if (AssignCopyRetMask &&
3967 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3968 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3969 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3970 return true;
3971
3972 return false;
3973}
3974
Douglas Gregora93b1082009-11-18 23:08:07 +00003975void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003976 if (!CodeCompleter)
3977 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003978
Steve Naroffece8e712009-10-08 21:55:05 +00003979 unsigned Attributes = ODS.getPropertyAttributes();
3980
John McCall0a2c5e22010-08-25 06:19:51 +00003981 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00003982 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Steve Naroffece8e712009-10-08 21:55:05 +00003983 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003984 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003985 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003986 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003987 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003988 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003989 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003990 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003991 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003992 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003993 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003994 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003995 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003996 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003997 CodeCompletionString *Setter = new CodeCompletionString;
3998 Setter->AddTypedTextChunk("setter");
3999 Setter->AddTextChunk(" = ");
4000 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00004001 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00004002 }
Douglas Gregor988358f2009-11-19 00:14:45 +00004003 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00004004 CodeCompletionString *Getter = new CodeCompletionString;
4005 Getter->AddTypedTextChunk("getter");
4006 Getter->AddTextChunk(" = ");
4007 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00004008 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00004009 }
Steve Naroffece8e712009-10-08 21:55:05 +00004010 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004011 HandleCodeCompleteResults(this, CodeCompleter,
4012 CodeCompletionContext::CCC_Other,
4013 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00004014}
Steve Naroffc4df6d22009-11-07 02:08:14 +00004015
Douglas Gregor4ad96852009-11-19 07:41:15 +00004016/// \brief Descripts the kind of Objective-C method that we want to find
4017/// via code completion.
4018enum ObjCMethodKind {
4019 MK_Any, //< Any kind of method, provided it means other specified criteria.
4020 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
4021 MK_OneArgSelector //< One-argument selector.
4022};
4023
Douglas Gregor458433d2010-08-26 15:07:07 +00004024static bool isAcceptableObjCSelector(Selector Sel,
4025 ObjCMethodKind WantKind,
4026 IdentifierInfo **SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004027 unsigned NumSelIdents,
4028 bool AllowSameLength = true) {
Douglas Gregor458433d2010-08-26 15:07:07 +00004029 if (NumSelIdents > Sel.getNumArgs())
4030 return false;
4031
4032 switch (WantKind) {
4033 case MK_Any: break;
4034 case MK_ZeroArgSelector: return Sel.isUnarySelector();
4035 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
4036 }
4037
Douglas Gregorcf544262010-11-17 21:36:08 +00004038 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
4039 return false;
4040
Douglas Gregor458433d2010-08-26 15:07:07 +00004041 for (unsigned I = 0; I != NumSelIdents; ++I)
4042 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
4043 return false;
4044
4045 return true;
4046}
4047
Douglas Gregor4ad96852009-11-19 07:41:15 +00004048static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
4049 ObjCMethodKind WantKind,
4050 IdentifierInfo **SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004051 unsigned NumSelIdents,
4052 bool AllowSameLength = true) {
Douglas Gregor458433d2010-08-26 15:07:07 +00004053 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004054 NumSelIdents, AllowSameLength);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004055}
Douglas Gregord36adf52010-09-16 16:06:31 +00004056
4057namespace {
4058 /// \brief A set of selectors, which is used to avoid introducing multiple
4059 /// completions with the same selector into the result set.
4060 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
4061}
4062
Douglas Gregor36ecb042009-11-17 23:22:23 +00004063/// \brief Add all of the Objective-C methods in the given Objective-C
4064/// container to the set of results.
4065///
4066/// The container will be a class, protocol, category, or implementation of
4067/// any of the above. This mether will recurse to include methods from
4068/// the superclasses of classes along with their categories, protocols, and
4069/// implementations.
4070///
4071/// \param Container the container in which we'll look to find methods.
4072///
4073/// \param WantInstance whether to add instance methods (only); if false, this
4074/// routine will add factory methods (only).
4075///
4076/// \param CurContext the context in which we're performing the lookup that
4077/// finds methods.
4078///
Douglas Gregorcf544262010-11-17 21:36:08 +00004079/// \param AllowSameLength Whether we allow a method to be added to the list
4080/// when it has the same number of parameters as we have selector identifiers.
4081///
Douglas Gregor36ecb042009-11-17 23:22:23 +00004082/// \param Results the structure into which we'll add results.
4083static void AddObjCMethods(ObjCContainerDecl *Container,
4084 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004085 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00004086 IdentifierInfo **SelIdents,
4087 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00004088 DeclContext *CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004089 VisitedSelectorSet &Selectors,
Douglas Gregorcf544262010-11-17 21:36:08 +00004090 bool AllowSameLength,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004091 ResultBuilder &Results,
4092 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00004093 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00004094 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4095 MEnd = Container->meth_end();
4096 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00004097 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4098 // Check whether the selector identifiers we've been given are a
4099 // subset of the identifiers for this particular method.
Douglas Gregorcf544262010-11-17 21:36:08 +00004100 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents,
4101 AllowSameLength))
Douglas Gregord3c68542009-11-19 01:08:35 +00004102 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004103
Douglas Gregord36adf52010-09-16 16:06:31 +00004104 if (!Selectors.insert((*M)->getSelector()))
4105 continue;
4106
Douglas Gregord3c68542009-11-19 01:08:35 +00004107 Result R = Result(*M, 0);
4108 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004109 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00004110 if (!InOriginalClass)
4111 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00004112 Results.MaybeAddResult(R, CurContext);
4113 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00004114 }
4115
Douglas Gregore396c7b2010-09-16 15:34:59 +00004116 // Visit the protocols of protocols.
4117 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4118 const ObjCList<ObjCProtocolDecl> &Protocols
4119 = Protocol->getReferencedProtocols();
4120 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4121 E = Protocols.end();
4122 I != E; ++I)
4123 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004124 CurContext, Selectors, AllowSameLength, Results, false);
Douglas Gregore396c7b2010-09-16 15:34:59 +00004125 }
4126
Douglas Gregor36ecb042009-11-17 23:22:23 +00004127 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
4128 if (!IFace)
4129 return;
4130
4131 // Add methods in protocols.
4132 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
4133 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4134 E = Protocols.end();
4135 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004136 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004137 CurContext, Selectors, AllowSameLength, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004138
4139 // Add methods in categories.
4140 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
4141 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00004142 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004143 NumSelIdents, CurContext, Selectors, AllowSameLength,
4144 Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004145
4146 // Add a categories protocol methods.
4147 const ObjCList<ObjCProtocolDecl> &Protocols
4148 = CatDecl->getReferencedProtocols();
4149 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4150 E = Protocols.end();
4151 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004152 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004153 NumSelIdents, CurContext, Selectors, AllowSameLength,
4154 Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004155
4156 // Add methods in category implementations.
4157 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004158 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004159 NumSelIdents, CurContext, Selectors, AllowSameLength,
4160 Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004161 }
4162
4163 // Add methods in superclass.
4164 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004165 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregorcf544262010-11-17 21:36:08 +00004166 SelIdents, NumSelIdents, CurContext, Selectors,
4167 AllowSameLength, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004168
4169 // Add methods in our implementation, if any.
4170 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004171 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004172 NumSelIdents, CurContext, Selectors, AllowSameLength,
4173 Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004174}
4175
4176
John McCalld226f652010-08-21 09:40:31 +00004177void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
4178 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004179 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00004180 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004181
4182 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00004183 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004184 if (!Class) {
4185 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004186 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004187 Class = Category->getClassInterface();
4188
4189 if (!Class)
4190 return;
4191 }
4192
4193 // Find all of the potential getters.
Douglas Gregor52779fb2010-09-23 23:01:17 +00004194 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004195 Results.EnterNewScope();
4196
4197 // FIXME: We need to do this because Objective-C methods don't get
4198 // pushed into DeclContexts early enough. Argh!
4199 for (unsigned I = 0; I != NumMethods; ++I) {
4200 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004201 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004202 if (Method->isInstanceMethod() &&
4203 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
4204 Result R = Result(Method, 0);
4205 R.AllParametersAreInformative = true;
4206 Results.MaybeAddResult(R, CurContext);
4207 }
4208 }
4209
Douglas Gregord36adf52010-09-16 16:06:31 +00004210 VisitedSelectorSet Selectors;
4211 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
Douglas Gregorcf544262010-11-17 21:36:08 +00004212 /*AllowSameLength=*/true, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004213 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004214 HandleCodeCompleteResults(this, CodeCompleter,
4215 CodeCompletionContext::CCC_Other,
4216 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00004217}
4218
John McCalld226f652010-08-21 09:40:31 +00004219void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
4220 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004221 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00004222 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004223
4224 // Try to find the interface where setters might live.
4225 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00004226 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004227 if (!Class) {
4228 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004229 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004230 Class = Category->getClassInterface();
4231
4232 if (!Class)
4233 return;
4234 }
4235
4236 // Find all of the potential getters.
Douglas Gregor52779fb2010-09-23 23:01:17 +00004237 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004238 Results.EnterNewScope();
4239
4240 // FIXME: We need to do this because Objective-C methods don't get
4241 // pushed into DeclContexts early enough. Argh!
4242 for (unsigned I = 0; I != NumMethods; ++I) {
4243 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004244 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004245 if (Method->isInstanceMethod() &&
4246 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
4247 Result R = Result(Method, 0);
4248 R.AllParametersAreInformative = true;
4249 Results.MaybeAddResult(R, CurContext);
4250 }
4251 }
4252
Douglas Gregord36adf52010-09-16 16:06:31 +00004253 VisitedSelectorSet Selectors;
4254 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00004255 Selectors, /*AllowSameLength=*/true, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004256
4257 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004258 HandleCodeCompleteResults(this, CodeCompleter,
4259 CodeCompletionContext::CCC_Other,
4260 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004261}
4262
Douglas Gregord32b0222010-08-24 01:06:58 +00004263void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00004264 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00004265 ResultBuilder Results(*this, CodeCompletionContext::CCC_Type);
Douglas Gregord32b0222010-08-24 01:06:58 +00004266 Results.EnterNewScope();
4267
4268 // Add context-sensitive, Objective-C parameter-passing keywords.
4269 bool AddedInOut = false;
4270 if ((DS.getObjCDeclQualifier() &
4271 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4272 Results.AddResult("in");
4273 Results.AddResult("inout");
4274 AddedInOut = true;
4275 }
4276 if ((DS.getObjCDeclQualifier() &
4277 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4278 Results.AddResult("out");
4279 if (!AddedInOut)
4280 Results.AddResult("inout");
4281 }
4282 if ((DS.getObjCDeclQualifier() &
4283 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4284 ObjCDeclSpec::DQ_Oneway)) == 0) {
4285 Results.AddResult("bycopy");
4286 Results.AddResult("byref");
4287 Results.AddResult("oneway");
4288 }
4289
4290 // Add various builtin type names and specifiers.
4291 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4292 Results.ExitScope();
4293
4294 // Add the various type names
4295 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4296 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4297 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4298 CodeCompleter->includeGlobals());
4299
4300 if (CodeCompleter->includeMacros())
4301 AddMacroResults(PP, Results);
4302
4303 HandleCodeCompleteResults(this, CodeCompleter,
4304 CodeCompletionContext::CCC_Type,
4305 Results.data(), Results.size());
4306}
4307
Douglas Gregor22f56992010-04-06 19:22:33 +00004308/// \brief When we have an expression with type "id", we may assume
4309/// that it has some more-specific class type based on knowledge of
4310/// common uses of Objective-C. This routine returns that class type,
4311/// or NULL if no better result could be determined.
4312static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004313 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004314 if (!Msg)
4315 return 0;
4316
4317 Selector Sel = Msg->getSelector();
4318 if (Sel.isNull())
4319 return 0;
4320
4321 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4322 if (!Id)
4323 return 0;
4324
4325 ObjCMethodDecl *Method = Msg->getMethodDecl();
4326 if (!Method)
4327 return 0;
4328
4329 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004330 ObjCInterfaceDecl *IFace = 0;
4331 switch (Msg->getReceiverKind()) {
4332 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004333 if (const ObjCObjectType *ObjType
4334 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4335 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004336 break;
4337
4338 case ObjCMessageExpr::Instance: {
4339 QualType T = Msg->getInstanceReceiver()->getType();
4340 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4341 IFace = Ptr->getInterfaceDecl();
4342 break;
4343 }
4344
4345 case ObjCMessageExpr::SuperInstance:
4346 case ObjCMessageExpr::SuperClass:
4347 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004348 }
4349
4350 if (!IFace)
4351 return 0;
4352
4353 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4354 if (Method->isInstanceMethod())
4355 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4356 .Case("retain", IFace)
4357 .Case("autorelease", IFace)
4358 .Case("copy", IFace)
4359 .Case("copyWithZone", IFace)
4360 .Case("mutableCopy", IFace)
4361 .Case("mutableCopyWithZone", IFace)
4362 .Case("awakeFromCoder", IFace)
4363 .Case("replacementObjectFromCoder", IFace)
4364 .Case("class", IFace)
4365 .Case("classForCoder", IFace)
4366 .Case("superclass", Super)
4367 .Default(0);
4368
4369 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4370 .Case("new", IFace)
4371 .Case("alloc", IFace)
4372 .Case("allocWithZone", IFace)
4373 .Case("class", IFace)
4374 .Case("superclass", Super)
4375 .Default(0);
4376}
4377
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004378// Add a special completion for a message send to "super", which fills in the
4379// most likely case of forwarding all of our arguments to the superclass
4380// function.
4381///
4382/// \param S The semantic analysis object.
4383///
4384/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4385/// the "super" keyword. Otherwise, we just need to provide the arguments.
4386///
4387/// \param SelIdents The identifiers in the selector that have already been
4388/// provided as arguments for a send to "super".
4389///
4390/// \param NumSelIdents The number of identifiers in \p SelIdents.
4391///
4392/// \param Results The set of results to augment.
4393///
4394/// \returns the Objective-C method declaration that would be invoked by
4395/// this "super" completion. If NULL, no completion was added.
4396static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4397 IdentifierInfo **SelIdents,
4398 unsigned NumSelIdents,
4399 ResultBuilder &Results) {
4400 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4401 if (!CurMethod)
4402 return 0;
4403
4404 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4405 if (!Class)
4406 return 0;
4407
4408 // Try to find a superclass method with the same selector.
4409 ObjCMethodDecl *SuperMethod = 0;
4410 while ((Class = Class->getSuperClass()) && !SuperMethod)
4411 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4412 CurMethod->isInstanceMethod());
4413
4414 if (!SuperMethod)
4415 return 0;
4416
4417 // Check whether the superclass method has the same signature.
4418 if (CurMethod->param_size() != SuperMethod->param_size() ||
4419 CurMethod->isVariadic() != SuperMethod->isVariadic())
4420 return 0;
4421
4422 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4423 CurPEnd = CurMethod->param_end(),
4424 SuperP = SuperMethod->param_begin();
4425 CurP != CurPEnd; ++CurP, ++SuperP) {
4426 // Make sure the parameter types are compatible.
4427 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4428 (*SuperP)->getType()))
4429 return 0;
4430
4431 // Make sure we have a parameter name to forward!
4432 if (!(*CurP)->getIdentifier())
4433 return 0;
4434 }
4435
4436 // We have a superclass method. Now, form the send-to-super completion.
4437 CodeCompletionString *Pattern = new CodeCompletionString;
4438
4439 // Give this completion a return type.
4440 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4441
4442 // If we need the "super" keyword, add it (plus some spacing).
4443 if (NeedSuperKeyword) {
4444 Pattern->AddTypedTextChunk("super");
4445 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4446 }
4447
4448 Selector Sel = CurMethod->getSelector();
4449 if (Sel.isUnarySelector()) {
4450 if (NeedSuperKeyword)
4451 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4452 else
4453 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4454 } else {
4455 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4456 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4457 if (I > NumSelIdents)
4458 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4459
4460 if (I < NumSelIdents)
4461 Pattern->AddInformativeChunk(
4462 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4463 else if (NeedSuperKeyword || I > NumSelIdents) {
4464 Pattern->AddTextChunk(
4465 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4466 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4467 } else {
4468 Pattern->AddTypedTextChunk(
4469 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4470 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4471 }
4472 }
4473 }
4474
4475 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4476 SuperMethod->isInstanceMethod()
4477 ? CXCursor_ObjCInstanceMethodDecl
4478 : CXCursor_ObjCClassMethodDecl));
4479 return SuperMethod;
4480}
4481
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004482void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004483 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00004484 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCMessageReceiver,
4485 &ResultBuilder::IsObjCMessageReceiver);
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004486
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004487 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4488 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004489 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4490 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004491
4492 // If we are in an Objective-C method inside a class that has a superclass,
4493 // add "super" as an option.
4494 if (ObjCMethodDecl *Method = getCurMethodDecl())
4495 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004496 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004497 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004498
4499 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4500 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004501
4502 Results.ExitScope();
4503
4504 if (CodeCompleter->includeMacros())
4505 AddMacroResults(PP, Results);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00004506 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004507 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004508
4509}
4510
Douglas Gregor2725ca82010-04-21 19:57:20 +00004511void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4512 IdentifierInfo **SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004513 unsigned NumSelIdents,
4514 bool AtArgumentExpression) {
Douglas Gregor2725ca82010-04-21 19:57:20 +00004515 ObjCInterfaceDecl *CDecl = 0;
4516 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4517 // Figure out which interface we're in.
4518 CDecl = CurMethod->getClassInterface();
4519 if (!CDecl)
4520 return;
4521
4522 // Find the superclass of this class.
4523 CDecl = CDecl->getSuperClass();
4524 if (!CDecl)
4525 return;
4526
4527 if (CurMethod->isInstanceMethod()) {
4528 // We are inside an instance method, which means that the message
4529 // send [super ...] is actually calling an instance method on the
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004530 // current object.
4531 return CodeCompleteObjCInstanceMessage(S, 0,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004532 SelIdents, NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004533 AtArgumentExpression,
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004534 CDecl);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004535 }
4536
4537 // Fall through to send to the superclass in CDecl.
4538 } else {
4539 // "super" may be the name of a type or variable. Figure out which
4540 // it is.
4541 IdentifierInfo *Super = &Context.Idents.get("super");
4542 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4543 LookupOrdinaryName);
4544 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4545 // "super" names an interface. Use it.
4546 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004547 if (const ObjCObjectType *Iface
4548 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4549 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004550 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4551 // "super" names an unresolved type; we can't be more specific.
4552 } else {
4553 // Assume that "super" names some kind of value and parse that way.
4554 CXXScopeSpec SS;
4555 UnqualifiedId id;
4556 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004557 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004558 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004559 SelIdents, NumSelIdents,
4560 AtArgumentExpression);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004561 }
4562
4563 // Fall through
4564 }
4565
John McCallb3d87482010-08-24 05:47:05 +00004566 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004567 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004568 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004569 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004570 NumSelIdents, AtArgumentExpression,
4571 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004572}
4573
Douglas Gregorb9d77572010-09-21 00:03:25 +00004574/// \brief Given a set of code-completion results for the argument of a message
4575/// send, determine the preferred type (if any) for that argument expression.
4576static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
4577 unsigned NumSelIdents) {
4578 typedef CodeCompletionResult Result;
4579 ASTContext &Context = Results.getSema().Context;
4580
4581 QualType PreferredType;
4582 unsigned BestPriority = CCP_Unlikely * 2;
4583 Result *ResultsData = Results.data();
4584 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
4585 Result &R = ResultsData[I];
4586 if (R.Kind == Result::RK_Declaration &&
4587 isa<ObjCMethodDecl>(R.Declaration)) {
4588 if (R.Priority <= BestPriority) {
4589 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
4590 if (NumSelIdents <= Method->param_size()) {
4591 QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
4592 ->getType();
4593 if (R.Priority < BestPriority || PreferredType.isNull()) {
4594 BestPriority = R.Priority;
4595 PreferredType = MyPreferredType;
4596 } else if (!Context.hasSameUnqualifiedType(PreferredType,
4597 MyPreferredType)) {
4598 PreferredType = QualType();
4599 }
4600 }
4601 }
4602 }
4603 }
4604
4605 return PreferredType;
4606}
4607
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004608static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4609 ParsedType Receiver,
4610 IdentifierInfo **SelIdents,
4611 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004612 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004613 bool IsSuper,
4614 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004615 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004616 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004617
Douglas Gregor24a069f2009-11-17 17:59:40 +00004618 // If the given name refers to an interface type, retrieve the
4619 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004620 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004621 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004622 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004623 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4624 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004625 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004626
Douglas Gregor36ecb042009-11-17 23:22:23 +00004627 // Add all of the factory methods in this Objective-C class, its protocols,
4628 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004629 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004630
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004631 // If this is a send-to-super, try to add the special "super" send
4632 // completion.
4633 if (IsSuper) {
4634 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004635 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4636 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004637 Results.Ignore(SuperMethod);
4638 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004639
Douglas Gregor265f7492010-08-27 15:29:55 +00004640 // If we're inside an Objective-C method definition, prefer its selector to
4641 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004642 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00004643 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004644
Douglas Gregord36adf52010-09-16 16:06:31 +00004645 VisitedSelectorSet Selectors;
Douglas Gregor13438f92010-04-06 16:40:00 +00004646 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004647 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004648 SemaRef.CurContext, Selectors, AtArgumentExpression,
4649 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004650 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004651 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004652
Douglas Gregor719770d2010-04-06 17:30:22 +00004653 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004654 // pool from the AST file.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004655 if (SemaRef.ExternalSource) {
4656 for (uint32_t I = 0,
4657 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00004658 I != N; ++I) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004659 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4660 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004661 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004662
4663 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004664 }
4665 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004666
4667 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4668 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004669 M != MEnd; ++M) {
4670 for (ObjCMethodList *MethList = &M->second.second;
4671 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004672 MethList = MethList->Next) {
4673 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4674 NumSelIdents))
4675 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004676
Douglas Gregor13438f92010-04-06 16:40:00 +00004677 Result R(MethList->Method, 0);
4678 R.StartParameter = NumSelIdents;
4679 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004680 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00004681 }
4682 }
4683 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004684
4685 Results.ExitScope();
4686}
Douglas Gregor13438f92010-04-06 16:40:00 +00004687
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004688void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4689 IdentifierInfo **SelIdents,
4690 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004691 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004692 bool IsSuper) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00004693 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004694 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
4695 AtArgumentExpression, IsSuper, Results);
Douglas Gregorb9d77572010-09-21 00:03:25 +00004696
4697 // If we're actually at the argument expression (rather than prior to the
4698 // selector), we're actually performing code completion for an expression.
4699 // Determine whether we have a single, best method. If so, we can
4700 // code-complete the expression using the corresponding parameter type as
4701 // our preferred type, improving completion results.
4702 if (AtArgumentExpression) {
4703 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
4704 NumSelIdents);
4705 if (PreferredType.isNull())
4706 CodeCompleteOrdinaryName(S, PCC_Expression);
4707 else
4708 CodeCompleteExpression(S, PreferredType);
4709 return;
4710 }
4711
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004712 HandleCodeCompleteResults(this, CodeCompleter,
4713 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004714 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004715}
4716
Douglas Gregord3c68542009-11-19 01:08:35 +00004717void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4718 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004719 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004720 bool AtArgumentExpression,
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004721 ObjCInterfaceDecl *Super) {
John McCall0a2c5e22010-08-25 06:19:51 +00004722 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004723
4724 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004725
Douglas Gregor36ecb042009-11-17 23:22:23 +00004726 // If necessary, apply function/array conversion to the receiver.
4727 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004728 if (RecExpr)
4729 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004730 QualType ReceiverType = RecExpr? RecExpr->getType()
4731 : Super? Context.getObjCObjectPointerType(
4732 Context.getObjCInterfaceType(Super))
4733 : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004734
Douglas Gregorda892642010-11-08 21:12:30 +00004735 // If we're messaging an expression with type "id" or "Class", check
4736 // whether we know something special about the receiver that allows
4737 // us to assume a more-specific receiver type.
4738 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4739 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
4740 if (ReceiverType->isObjCClassType())
4741 return CodeCompleteObjCClassMessage(S,
4742 ParsedType::make(Context.getObjCInterfaceType(IFace)),
4743 SelIdents, NumSelIdents,
4744 AtArgumentExpression, Super);
4745
4746 ReceiverType = Context.getObjCObjectPointerType(
4747 Context.getObjCInterfaceType(IFace));
4748 }
4749
Douglas Gregor36ecb042009-11-17 23:22:23 +00004750 // Build the set of methods we can see.
Douglas Gregor52779fb2010-09-23 23:01:17 +00004751 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004752 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004753
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004754 // If this is a send-to-super, try to add the special "super" send
4755 // completion.
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004756 if (Super) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004757 if (ObjCMethodDecl *SuperMethod
4758 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4759 Results))
4760 Results.Ignore(SuperMethod);
4761 }
4762
Douglas Gregor265f7492010-08-27 15:29:55 +00004763 // If we're inside an Objective-C method definition, prefer its selector to
4764 // others.
4765 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4766 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004767
Douglas Gregord36adf52010-09-16 16:06:31 +00004768 // Keep track of the selectors we've already added.
4769 VisitedSelectorSet Selectors;
4770
Douglas Gregorf74a4192009-11-18 00:06:18 +00004771 // Handle messages to Class. This really isn't a message to an instance
4772 // method, so we treat it the same way we would treat a message send to a
4773 // class method.
4774 if (ReceiverType->isObjCClassType() ||
4775 ReceiverType->isObjCQualifiedClassType()) {
4776 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4777 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004778 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004779 CurContext, Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004780 }
4781 }
4782 // Handle messages to a qualified ID ("id<foo>").
4783 else if (const ObjCObjectPointerType *QualID
4784 = ReceiverType->getAsObjCQualifiedIdType()) {
4785 // Search protocols for instance methods.
4786 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4787 E = QualID->qual_end();
4788 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004789 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00004790 Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004791 }
4792 // Handle messages to a pointer to interface type.
4793 else if (const ObjCObjectPointerType *IFacePtr
4794 = ReceiverType->getAsObjCInterfacePointerType()) {
4795 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004796 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004797 NumSelIdents, CurContext, Selectors, AtArgumentExpression,
4798 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004799
4800 // Search protocols for instance methods.
4801 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4802 E = IFacePtr->qual_end();
4803 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004804 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00004805 Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004806 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004807 // Handle messages to "id".
4808 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004809 // We're messaging "id", so provide all instance methods we know
4810 // about as code-completion results.
4811
4812 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004813 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004814 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004815 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4816 I != N; ++I) {
4817 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004818 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004819 continue;
4820
Sebastian Redldb9d2142010-08-02 23:18:59 +00004821 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004822 }
4823 }
4824
Sebastian Redldb9d2142010-08-02 23:18:59 +00004825 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4826 MEnd = MethodPool.end();
4827 M != MEnd; ++M) {
4828 for (ObjCMethodList *MethList = &M->second.first;
4829 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004830 MethList = MethList->Next) {
4831 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4832 NumSelIdents))
4833 continue;
Douglas Gregord36adf52010-09-16 16:06:31 +00004834
4835 if (!Selectors.insert(MethList->Method->getSelector()))
4836 continue;
4837
Douglas Gregor13438f92010-04-06 16:40:00 +00004838 Result R(MethList->Method, 0);
4839 R.StartParameter = NumSelIdents;
4840 R.AllParametersAreInformative = false;
4841 Results.MaybeAddResult(R, CurContext);
4842 }
4843 }
4844 }
Steve Naroffc4df6d22009-11-07 02:08:14 +00004845 Results.ExitScope();
Douglas Gregorb9d77572010-09-21 00:03:25 +00004846
4847
4848 // If we're actually at the argument expression (rather than prior to the
4849 // selector), we're actually performing code completion for an expression.
4850 // Determine whether we have a single, best method. If so, we can
4851 // code-complete the expression using the corresponding parameter type as
4852 // our preferred type, improving completion results.
4853 if (AtArgumentExpression) {
4854 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
4855 NumSelIdents);
4856 if (PreferredType.isNull())
4857 CodeCompleteOrdinaryName(S, PCC_Expression);
4858 else
4859 CodeCompleteExpression(S, PreferredType);
4860 return;
4861 }
4862
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004863 HandleCodeCompleteResults(this, CodeCompleter,
4864 CodeCompletionContext::CCC_Other,
4865 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004866}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004867
Douglas Gregorfb629412010-08-23 21:17:50 +00004868void Sema::CodeCompleteObjCForCollection(Scope *S,
4869 DeclGroupPtrTy IterationVar) {
4870 CodeCompleteExpressionData Data;
4871 Data.ObjCCollection = true;
4872
4873 if (IterationVar.getAsOpaquePtr()) {
4874 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4875 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4876 if (*I)
4877 Data.IgnoreDecls.push_back(*I);
4878 }
4879 }
4880
4881 CodeCompleteExpression(S, Data);
4882}
4883
Douglas Gregor458433d2010-08-26 15:07:07 +00004884void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4885 unsigned NumSelIdents) {
4886 // If we have an external source, load the entire class method
4887 // pool from the AST file.
4888 if (ExternalSource) {
4889 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4890 I != N; ++I) {
4891 Selector Sel = ExternalSource->GetExternalSelector(I);
4892 if (Sel.isNull() || MethodPool.count(Sel))
4893 continue;
4894
4895 ReadMethodPool(Sel);
4896 }
4897 }
4898
Douglas Gregor52779fb2010-09-23 23:01:17 +00004899 ResultBuilder Results(*this, CodeCompletionContext::CCC_SelectorName);
Douglas Gregor458433d2010-08-26 15:07:07 +00004900 Results.EnterNewScope();
4901 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4902 MEnd = MethodPool.end();
4903 M != MEnd; ++M) {
4904
4905 Selector Sel = M->first;
4906 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4907 continue;
4908
4909 CodeCompletionString *Pattern = new CodeCompletionString;
4910 if (Sel.isUnarySelector()) {
4911 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4912 Results.AddResult(Pattern);
4913 continue;
4914 }
4915
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004916 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004917 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004918 if (I == NumSelIdents) {
4919 if (!Accumulator.empty()) {
4920 Pattern->AddInformativeChunk(Accumulator);
4921 Accumulator.clear();
4922 }
4923 }
4924
4925 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4926 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004927 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004928 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004929 Results.AddResult(Pattern);
4930 }
4931 Results.ExitScope();
4932
4933 HandleCodeCompleteResults(this, CodeCompleter,
4934 CodeCompletionContext::CCC_SelectorName,
4935 Results.data(), Results.size());
4936}
4937
Douglas Gregor55385fe2009-11-18 04:19:12 +00004938/// \brief Add all of the protocol declarations that we find in the given
4939/// (translation unit) context.
4940static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004941 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004942 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004943 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004944
4945 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4946 DEnd = Ctx->decls_end();
4947 D != DEnd; ++D) {
4948 // Record any protocols we find.
4949 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004950 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004951 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004952
4953 // Record any forward-declared protocols we find.
4954 if (ObjCForwardProtocolDecl *Forward
4955 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4956 for (ObjCForwardProtocolDecl::protocol_iterator
4957 P = Forward->protocol_begin(),
4958 PEnd = Forward->protocol_end();
4959 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004960 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004961 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004962 }
4963 }
4964}
4965
4966void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4967 unsigned NumProtocols) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00004968 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCProtocolName);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004969
Douglas Gregor70c23352010-12-09 21:44:02 +00004970 if (CodeCompleter && CodeCompleter->includeGlobals()) {
4971 Results.EnterNewScope();
4972
4973 // Tell the result set to ignore all of the protocols we have
4974 // already seen.
4975 // FIXME: This doesn't work when caching code-completion results.
4976 for (unsigned I = 0; I != NumProtocols; ++I)
4977 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4978 Protocols[I].second))
4979 Results.Ignore(Protocol);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004980
Douglas Gregor70c23352010-12-09 21:44:02 +00004981 // Add all protocols.
4982 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4983 Results);
Douglas Gregor083128f2009-11-18 04:49:41 +00004984
Douglas Gregor70c23352010-12-09 21:44:02 +00004985 Results.ExitScope();
4986 }
4987
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004988 HandleCodeCompleteResults(this, CodeCompleter,
4989 CodeCompletionContext::CCC_ObjCProtocolName,
4990 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004991}
4992
4993void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00004994 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCProtocolName);
Douglas Gregor083128f2009-11-18 04:49:41 +00004995
Douglas Gregor70c23352010-12-09 21:44:02 +00004996 if (CodeCompleter && CodeCompleter->includeGlobals()) {
4997 Results.EnterNewScope();
4998
4999 // Add all protocols.
5000 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
5001 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00005002
Douglas Gregor70c23352010-12-09 21:44:02 +00005003 Results.ExitScope();
5004 }
5005
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005006 HandleCodeCompleteResults(this, CodeCompleter,
5007 CodeCompletionContext::CCC_ObjCProtocolName,
5008 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00005009}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005010
5011/// \brief Add all of the Objective-C interface declarations that we find in
5012/// the given (translation unit) context.
5013static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
5014 bool OnlyForwardDeclarations,
5015 bool OnlyUnimplemented,
5016 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00005017 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005018
5019 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
5020 DEnd = Ctx->decls_end();
5021 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00005022 // Record any interfaces we find.
5023 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
5024 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
5025 (!OnlyUnimplemented || !Class->getImplementation()))
5026 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005027
5028 // Record any forward-declared interfaces we find.
5029 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
5030 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00005031 C != CEnd; ++C)
5032 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
5033 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
5034 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00005035 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005036 }
5037 }
5038}
5039
5040void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005041 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005042 Results.EnterNewScope();
5043
5044 // Add all classes.
5045 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
5046 false, Results);
5047
5048 Results.ExitScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00005049 // FIXME: Add a special context for this, use cached global completion
5050 // results.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005051 HandleCodeCompleteResults(this, CodeCompleter,
5052 CodeCompletionContext::CCC_Other,
5053 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005054}
5055
Douglas Gregorc83c6872010-04-15 22:33:43 +00005056void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
5057 SourceLocation ClassNameLoc) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005058 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005059 Results.EnterNewScope();
5060
5061 // Make sure that we ignore the class we're currently defining.
5062 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005063 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005064 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005065 Results.Ignore(CurClass);
5066
5067 // Add all classes.
5068 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5069 false, Results);
5070
5071 Results.ExitScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00005072 // FIXME: Add a special context for this, use cached global completion
5073 // results.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005074 HandleCodeCompleteResults(this, CodeCompleter,
5075 CodeCompletionContext::CCC_Other,
5076 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005077}
5078
5079void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005080 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005081 Results.EnterNewScope();
5082
5083 // Add all unimplemented classes.
5084 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5085 true, Results);
5086
5087 Results.ExitScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00005088 // FIXME: Add a special context for this, use cached global completion
5089 // results.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005090 HandleCodeCompleteResults(this, CodeCompleter,
5091 CodeCompletionContext::CCC_Other,
5092 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005093}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005094
5095void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00005096 IdentifierInfo *ClassName,
5097 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00005098 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005099
Douglas Gregor52779fb2010-09-23 23:01:17 +00005100 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005101
5102 // Ignore any categories we find that have already been implemented by this
5103 // interface.
5104 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5105 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005106 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005107 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
5108 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
5109 Category = Category->getNextClassCategory())
5110 CategoryNames.insert(Category->getIdentifier());
5111
5112 // Add all of the categories we know about.
5113 Results.EnterNewScope();
5114 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
5115 for (DeclContext::decl_iterator D = TU->decls_begin(),
5116 DEnd = TU->decls_end();
5117 D != DEnd; ++D)
5118 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
5119 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00005120 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005121 Results.ExitScope();
5122
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005123 HandleCodeCompleteResults(this, CodeCompleter,
5124 CodeCompletionContext::CCC_Other,
5125 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005126}
5127
5128void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00005129 IdentifierInfo *ClassName,
5130 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00005131 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005132
5133 // Find the corresponding interface. If we couldn't find the interface, the
5134 // program itself is ill-formed. However, we'll try to be helpful still by
5135 // providing the list of all of the categories we know about.
5136 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005137 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005138 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
5139 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00005140 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005141
Douglas Gregor52779fb2010-09-23 23:01:17 +00005142 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005143
5144 // Add all of the categories that have have corresponding interface
5145 // declarations in this class and any of its superclasses, except for
5146 // already-implemented categories in the class itself.
5147 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5148 Results.EnterNewScope();
5149 bool IgnoreImplemented = true;
5150 while (Class) {
5151 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
5152 Category = Category->getNextClassCategory())
5153 if ((!IgnoreImplemented || !Category->getImplementation()) &&
5154 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00005155 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005156
5157 Class = Class->getSuperClass();
5158 IgnoreImplemented = false;
5159 }
5160 Results.ExitScope();
5161
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005162 HandleCodeCompleteResults(this, CodeCompleter,
5163 CodeCompletionContext::CCC_Other,
5164 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005165}
Douglas Gregor322328b2009-11-18 22:32:06 +00005166
John McCalld226f652010-08-21 09:40:31 +00005167void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00005168 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00005169 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor322328b2009-11-18 22:32:06 +00005170
5171 // Figure out where this @synthesize lives.
5172 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00005173 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00005174 if (!Container ||
5175 (!isa<ObjCImplementationDecl>(Container) &&
5176 !isa<ObjCCategoryImplDecl>(Container)))
5177 return;
5178
5179 // Ignore any properties that have already been implemented.
5180 for (DeclContext::decl_iterator D = Container->decls_begin(),
5181 DEnd = Container->decls_end();
5182 D != DEnd; ++D)
5183 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
5184 Results.Ignore(PropertyImpl->getPropertyDecl());
5185
5186 // Add any properties that we find.
Douglas Gregor73449212010-12-09 23:01:55 +00005187 AddedPropertiesSet AddedProperties;
Douglas Gregor322328b2009-11-18 22:32:06 +00005188 Results.EnterNewScope();
5189 if (ObjCImplementationDecl *ClassImpl
5190 = dyn_cast<ObjCImplementationDecl>(Container))
5191 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
Douglas Gregor73449212010-12-09 23:01:55 +00005192 AddedProperties, Results);
Douglas Gregor322328b2009-11-18 22:32:06 +00005193 else
5194 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
Douglas Gregor73449212010-12-09 23:01:55 +00005195 false, CurContext, AddedProperties, Results);
Douglas Gregor322328b2009-11-18 22:32:06 +00005196 Results.ExitScope();
5197
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005198 HandleCodeCompleteResults(this, CodeCompleter,
5199 CodeCompletionContext::CCC_Other,
5200 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00005201}
5202
5203void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
5204 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00005205 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00005206 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00005207 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor322328b2009-11-18 22:32:06 +00005208
5209 // Figure out where this @synthesize lives.
5210 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00005211 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00005212 if (!Container ||
5213 (!isa<ObjCImplementationDecl>(Container) &&
5214 !isa<ObjCCategoryImplDecl>(Container)))
5215 return;
5216
5217 // Figure out which interface we're looking into.
5218 ObjCInterfaceDecl *Class = 0;
5219 if (ObjCImplementationDecl *ClassImpl
5220 = dyn_cast<ObjCImplementationDecl>(Container))
5221 Class = ClassImpl->getClassInterface();
5222 else
5223 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
5224 ->getClassInterface();
5225
5226 // Add all of the instance variables in this class and its superclasses.
5227 Results.EnterNewScope();
5228 for(; Class; Class = Class->getSuperClass()) {
5229 // FIXME: We could screen the type of each ivar for compatibility with
5230 // the property, but is that being too paternal?
5231 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
5232 IVarEnd = Class->ivar_end();
5233 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00005234 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00005235 }
5236 Results.ExitScope();
5237
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005238 HandleCodeCompleteResults(this, CodeCompleter,
5239 CodeCompletionContext::CCC_Other,
5240 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00005241}
Douglas Gregore8f5a172010-04-07 00:21:17 +00005242
Douglas Gregor408be5a2010-08-25 01:08:01 +00005243// Mapping from selectors to the methods that implement that selector, along
5244// with the "in original class" flag.
5245typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
5246 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005247
5248/// \brief Find all of the methods that reside in the given container
5249/// (and its superclasses, protocols, etc.) that meet the given
5250/// criteria. Insert those methods into the map of known methods,
5251/// indexed by selector so they can be easily found.
5252static void FindImplementableMethods(ASTContext &Context,
5253 ObjCContainerDecl *Container,
5254 bool WantInstanceMethods,
5255 QualType ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005256 KnownMethodsMap &KnownMethods,
5257 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005258 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
5259 // Recurse into protocols.
5260 const ObjCList<ObjCProtocolDecl> &Protocols
5261 = IFace->getReferencedProtocols();
5262 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
Douglas Gregorea766182010-10-18 18:21:28 +00005263 E = Protocols.end();
Douglas Gregore8f5a172010-04-07 00:21:17 +00005264 I != E; ++I)
5265 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00005266 KnownMethods, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005267
Douglas Gregorea766182010-10-18 18:21:28 +00005268 // Add methods from any class extensions and categories.
5269 for (const ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
5270 Cat = Cat->getNextClassCategory())
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00005271 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
5272 WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00005273 KnownMethods, false);
5274
5275 // Visit the superclass.
5276 if (IFace->getSuperClass())
5277 FindImplementableMethods(Context, IFace->getSuperClass(),
5278 WantInstanceMethods, ReturnType,
5279 KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005280 }
5281
5282 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5283 // Recurse into protocols.
5284 const ObjCList<ObjCProtocolDecl> &Protocols
5285 = Category->getReferencedProtocols();
5286 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
Douglas Gregorea766182010-10-18 18:21:28 +00005287 E = Protocols.end();
Douglas Gregore8f5a172010-04-07 00:21:17 +00005288 I != E; ++I)
5289 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00005290 KnownMethods, InOriginalClass);
5291
5292 // If this category is the original class, jump to the interface.
5293 if (InOriginalClass && Category->getClassInterface())
5294 FindImplementableMethods(Context, Category->getClassInterface(),
5295 WantInstanceMethods, ReturnType, KnownMethods,
5296 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005297 }
5298
5299 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5300 // Recurse into protocols.
5301 const ObjCList<ObjCProtocolDecl> &Protocols
5302 = Protocol->getReferencedProtocols();
5303 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5304 E = Protocols.end();
5305 I != E; ++I)
5306 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00005307 KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005308 }
5309
5310 // Add methods in this container. This operation occurs last because
5311 // we want the methods from this container to override any methods
5312 // we've previously seen with the same selector.
5313 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
5314 MEnd = Container->meth_end();
5315 M != MEnd; ++M) {
5316 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
5317 if (!ReturnType.isNull() &&
5318 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
5319 continue;
5320
Douglas Gregor408be5a2010-08-25 01:08:01 +00005321 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005322 }
5323 }
5324}
5325
5326void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5327 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00005328 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00005329 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005330 // Determine the return type of the method we're declaring, if
5331 // provided.
5332 QualType ReturnType = GetTypeFromParser(ReturnTy);
5333
Douglas Gregorea766182010-10-18 18:21:28 +00005334 // Determine where we should start searching for methods.
5335 ObjCContainerDecl *SearchDecl = 0;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005336 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00005337 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005338 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5339 SearchDecl = Impl->getClassInterface();
Douglas Gregore8f5a172010-04-07 00:21:17 +00005340 IsInImplementation = true;
5341 } else if (ObjCCategoryImplDecl *CatImpl
Douglas Gregorea766182010-10-18 18:21:28 +00005342 = dyn_cast<ObjCCategoryImplDecl>(D)) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005343 SearchDecl = CatImpl->getCategoryDecl();
Douglas Gregore8f5a172010-04-07 00:21:17 +00005344 IsInImplementation = true;
Douglas Gregorea766182010-10-18 18:21:28 +00005345 } else
Douglas Gregore8f5a172010-04-07 00:21:17 +00005346 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005347 }
5348
5349 if (!SearchDecl && S) {
Douglas Gregorea766182010-10-18 18:21:28 +00005350 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity()))
Douglas Gregore8f5a172010-04-07 00:21:17 +00005351 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005352 }
5353
Douglas Gregorea766182010-10-18 18:21:28 +00005354 if (!SearchDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005355 HandleCodeCompleteResults(this, CodeCompleter,
5356 CodeCompletionContext::CCC_Other,
5357 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005358 return;
5359 }
5360
5361 // Find all of the methods that we could declare/implement here.
5362 KnownMethodsMap KnownMethods;
5363 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
Douglas Gregorea766182010-10-18 18:21:28 +00005364 ReturnType, KnownMethods);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005365
Douglas Gregore8f5a172010-04-07 00:21:17 +00005366 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00005367 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00005368 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005369 Results.EnterNewScope();
5370 PrintingPolicy Policy(Context.PrintingPolicy);
5371 Policy.AnonymousTagLocations = false;
5372 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5373 MEnd = KnownMethods.end();
5374 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00005375 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005376 CodeCompletionString *Pattern = new CodeCompletionString;
5377
5378 // If the result type was not already provided, add it to the
5379 // pattern as (type).
5380 if (ReturnType.isNull()) {
5381 std::string TypeStr;
5382 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5383 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5384 Pattern->AddTextChunk(TypeStr);
5385 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5386 }
5387
5388 Selector Sel = Method->getSelector();
5389
5390 // Add the first part of the selector to the pattern.
5391 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5392
5393 // Add parameters to the pattern.
5394 unsigned I = 0;
5395 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5396 PEnd = Method->param_end();
5397 P != PEnd; (void)++P, ++I) {
5398 // Add the part of the selector name.
5399 if (I == 0)
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00005400 Pattern->AddTypedTextChunk(":");
Douglas Gregore8f5a172010-04-07 00:21:17 +00005401 else if (I < Sel.getNumArgs()) {
5402 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00005403 Pattern->AddTypedTextChunk((Sel.getIdentifierInfoForSlot(I)->getName()
5404 + ":").str());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005405 } else
5406 break;
5407
5408 // Add the parameter type.
5409 std::string TypeStr;
5410 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5411 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5412 Pattern->AddTextChunk(TypeStr);
5413 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5414
5415 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005416 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005417 }
5418
5419 if (Method->isVariadic()) {
5420 if (Method->param_size() > 0)
5421 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5422 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005423 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005424
Douglas Gregor447107d2010-05-28 00:57:46 +00005425 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005426 // We will be defining the method here, so add a compound statement.
5427 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5428 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5429 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5430 if (!Method->getResultType()->isVoidType()) {
5431 // If the result type is not void, add a return clause.
5432 Pattern->AddTextChunk("return");
5433 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5434 Pattern->AddPlaceholderChunk("expression");
5435 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5436 } else
5437 Pattern->AddPlaceholderChunk("statements");
5438
5439 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5440 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5441 }
5442
Douglas Gregor408be5a2010-08-25 01:08:01 +00005443 unsigned Priority = CCP_CodePattern;
5444 if (!M->second.second)
5445 Priority += CCD_InBaseClass;
5446
5447 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005448 Method->isInstanceMethod()
5449 ? CXCursor_ObjCInstanceMethodDecl
5450 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005451 }
5452
5453 Results.ExitScope();
5454
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005455 HandleCodeCompleteResults(this, CodeCompleter,
5456 CodeCompletionContext::CCC_Other,
5457 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005458}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005459
5460void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5461 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005462 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005463 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005464 IdentifierInfo **SelIdents,
5465 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005466 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005467 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005468 if (ExternalSource) {
5469 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5470 I != N; ++I) {
5471 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005472 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005473 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005474
5475 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005476 }
5477 }
5478
5479 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005480 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00005481 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005482
5483 if (ReturnTy)
5484 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005485
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005486 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005487 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5488 MEnd = MethodPool.end();
5489 M != MEnd; ++M) {
5490 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5491 &M->second.second;
5492 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005493 MethList = MethList->Next) {
5494 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5495 NumSelIdents))
5496 continue;
5497
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005498 if (AtParameterName) {
5499 // Suggest parameter names we've seen before.
5500 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5501 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5502 if (Param->getIdentifier()) {
5503 CodeCompletionString *Pattern = new CodeCompletionString;
5504 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5505 Results.AddResult(Pattern);
5506 }
5507 }
5508
5509 continue;
5510 }
5511
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005512 Result R(MethList->Method, 0);
5513 R.StartParameter = NumSelIdents;
5514 R.AllParametersAreInformative = false;
5515 R.DeclaringEntity = true;
5516 Results.MaybeAddResult(R, CurContext);
5517 }
5518 }
5519
5520 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005521 HandleCodeCompleteResults(this, CodeCompleter,
5522 CodeCompletionContext::CCC_Other,
5523 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005524}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005525
Douglas Gregorf29c5232010-08-24 22:20:20 +00005526void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005527 ResultBuilder Results(*this,
5528 CodeCompletionContext::CCC_PreprocessorDirective);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005529 Results.EnterNewScope();
5530
5531 // #if <condition>
5532 CodeCompletionString *Pattern = new CodeCompletionString;
5533 Pattern->AddTypedTextChunk("if");
5534 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5535 Pattern->AddPlaceholderChunk("condition");
5536 Results.AddResult(Pattern);
5537
5538 // #ifdef <macro>
5539 Pattern = new CodeCompletionString;
5540 Pattern->AddTypedTextChunk("ifdef");
5541 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5542 Pattern->AddPlaceholderChunk("macro");
5543 Results.AddResult(Pattern);
5544
5545 // #ifndef <macro>
5546 Pattern = new CodeCompletionString;
5547 Pattern->AddTypedTextChunk("ifndef");
5548 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5549 Pattern->AddPlaceholderChunk("macro");
5550 Results.AddResult(Pattern);
5551
5552 if (InConditional) {
5553 // #elif <condition>
5554 Pattern = new CodeCompletionString;
5555 Pattern->AddTypedTextChunk("elif");
5556 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5557 Pattern->AddPlaceholderChunk("condition");
5558 Results.AddResult(Pattern);
5559
5560 // #else
5561 Pattern = new CodeCompletionString;
5562 Pattern->AddTypedTextChunk("else");
5563 Results.AddResult(Pattern);
5564
5565 // #endif
5566 Pattern = new CodeCompletionString;
5567 Pattern->AddTypedTextChunk("endif");
5568 Results.AddResult(Pattern);
5569 }
5570
5571 // #include "header"
5572 Pattern = new CodeCompletionString;
5573 Pattern->AddTypedTextChunk("include");
5574 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5575 Pattern->AddTextChunk("\"");
5576 Pattern->AddPlaceholderChunk("header");
5577 Pattern->AddTextChunk("\"");
5578 Results.AddResult(Pattern);
5579
5580 // #include <header>
5581 Pattern = new CodeCompletionString;
5582 Pattern->AddTypedTextChunk("include");
5583 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5584 Pattern->AddTextChunk("<");
5585 Pattern->AddPlaceholderChunk("header");
5586 Pattern->AddTextChunk(">");
5587 Results.AddResult(Pattern);
5588
5589 // #define <macro>
5590 Pattern = new CodeCompletionString;
5591 Pattern->AddTypedTextChunk("define");
5592 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5593 Pattern->AddPlaceholderChunk("macro");
5594 Results.AddResult(Pattern);
5595
5596 // #define <macro>(<args>)
5597 Pattern = new CodeCompletionString;
5598 Pattern->AddTypedTextChunk("define");
5599 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5600 Pattern->AddPlaceholderChunk("macro");
5601 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5602 Pattern->AddPlaceholderChunk("args");
5603 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5604 Results.AddResult(Pattern);
5605
5606 // #undef <macro>
5607 Pattern = new CodeCompletionString;
5608 Pattern->AddTypedTextChunk("undef");
5609 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5610 Pattern->AddPlaceholderChunk("macro");
5611 Results.AddResult(Pattern);
5612
5613 // #line <number>
5614 Pattern = new CodeCompletionString;
5615 Pattern->AddTypedTextChunk("line");
5616 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5617 Pattern->AddPlaceholderChunk("number");
5618 Results.AddResult(Pattern);
5619
5620 // #line <number> "filename"
5621 Pattern = new CodeCompletionString;
5622 Pattern->AddTypedTextChunk("line");
5623 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5624 Pattern->AddPlaceholderChunk("number");
5625 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5626 Pattern->AddTextChunk("\"");
5627 Pattern->AddPlaceholderChunk("filename");
5628 Pattern->AddTextChunk("\"");
5629 Results.AddResult(Pattern);
5630
5631 // #error <message>
5632 Pattern = new CodeCompletionString;
5633 Pattern->AddTypedTextChunk("error");
5634 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5635 Pattern->AddPlaceholderChunk("message");
5636 Results.AddResult(Pattern);
5637
5638 // #pragma <arguments>
5639 Pattern = new CodeCompletionString;
5640 Pattern->AddTypedTextChunk("pragma");
5641 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5642 Pattern->AddPlaceholderChunk("arguments");
5643 Results.AddResult(Pattern);
5644
5645 if (getLangOptions().ObjC1) {
5646 // #import "header"
5647 Pattern = new CodeCompletionString;
5648 Pattern->AddTypedTextChunk("import");
5649 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5650 Pattern->AddTextChunk("\"");
5651 Pattern->AddPlaceholderChunk("header");
5652 Pattern->AddTextChunk("\"");
5653 Results.AddResult(Pattern);
5654
5655 // #import <header>
5656 Pattern = new CodeCompletionString;
5657 Pattern->AddTypedTextChunk("import");
5658 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5659 Pattern->AddTextChunk("<");
5660 Pattern->AddPlaceholderChunk("header");
5661 Pattern->AddTextChunk(">");
5662 Results.AddResult(Pattern);
5663 }
5664
5665 // #include_next "header"
5666 Pattern = new CodeCompletionString;
5667 Pattern->AddTypedTextChunk("include_next");
5668 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5669 Pattern->AddTextChunk("\"");
5670 Pattern->AddPlaceholderChunk("header");
5671 Pattern->AddTextChunk("\"");
5672 Results.AddResult(Pattern);
5673
5674 // #include_next <header>
5675 Pattern = new CodeCompletionString;
5676 Pattern->AddTypedTextChunk("include_next");
5677 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5678 Pattern->AddTextChunk("<");
5679 Pattern->AddPlaceholderChunk("header");
5680 Pattern->AddTextChunk(">");
5681 Results.AddResult(Pattern);
5682
5683 // #warning <message>
5684 Pattern = new CodeCompletionString;
5685 Pattern->AddTypedTextChunk("warning");
5686 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5687 Pattern->AddPlaceholderChunk("message");
5688 Results.AddResult(Pattern);
5689
5690 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5691 // completions for them. And __include_macros is a Clang-internal extension
5692 // that we don't want to encourage anyone to use.
5693
5694 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5695 Results.ExitScope();
5696
Douglas Gregorf44e8542010-08-24 19:08:16 +00005697 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005698 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005699 Results.data(), Results.size());
5700}
5701
5702void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005703 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005704 S->getFnParent()? Sema::PCC_RecoveryInFunction
5705 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005706}
5707
Douglas Gregorf29c5232010-08-24 22:20:20 +00005708void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005709 ResultBuilder Results(*this,
5710 IsDefinition? CodeCompletionContext::CCC_MacroName
5711 : CodeCompletionContext::CCC_MacroNameUse);
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005712 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5713 // Add just the names of macros, not their arguments.
5714 Results.EnterNewScope();
5715 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5716 MEnd = PP.macro_end();
5717 M != MEnd; ++M) {
5718 CodeCompletionString *Pattern = new CodeCompletionString;
5719 Pattern->AddTypedTextChunk(M->first->getName());
5720 Results.AddResult(Pattern);
5721 }
5722 Results.ExitScope();
5723 } else if (IsDefinition) {
5724 // FIXME: Can we detect when the user just wrote an include guard above?
5725 }
5726
Douglas Gregor52779fb2010-09-23 23:01:17 +00005727 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005728 Results.data(), Results.size());
5729}
5730
Douglas Gregorf29c5232010-08-24 22:20:20 +00005731void Sema::CodeCompletePreprocessorExpression() {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005732 ResultBuilder Results(*this,
5733 CodeCompletionContext::CCC_PreprocessorExpression);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005734
5735 if (!CodeCompleter || CodeCompleter->includeMacros())
5736 AddMacroResults(PP, Results);
5737
5738 // defined (<macro>)
5739 Results.EnterNewScope();
5740 CodeCompletionString *Pattern = new CodeCompletionString;
5741 Pattern->AddTypedTextChunk("defined");
5742 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5743 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5744 Pattern->AddPlaceholderChunk("macro");
5745 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5746 Results.AddResult(Pattern);
5747 Results.ExitScope();
5748
5749 HandleCodeCompleteResults(this, CodeCompleter,
5750 CodeCompletionContext::CCC_PreprocessorExpression,
5751 Results.data(), Results.size());
5752}
5753
5754void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5755 IdentifierInfo *Macro,
5756 MacroInfo *MacroInfo,
5757 unsigned Argument) {
5758 // FIXME: In the future, we could provide "overload" results, much like we
5759 // do for function calls.
5760
5761 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005762 S->getFnParent()? Sema::PCC_RecoveryInFunction
5763 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005764}
5765
Douglas Gregor55817af2010-08-25 17:04:25 +00005766void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005767 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005768 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005769 0, 0);
5770}
5771
Douglas Gregor87c08a52010-08-13 22:48:40 +00005772void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005773 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005774 ResultBuilder Builder(*this, CodeCompletionContext::CCC_Recovery);
Douglas Gregor8071e422010-08-15 06:18:01 +00005775 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5776 CodeCompletionDeclConsumer Consumer(Builder,
5777 Context.getTranslationUnitDecl());
5778 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5779 Consumer);
5780 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005781
5782 if (!CodeCompleter || CodeCompleter->includeMacros())
5783 AddMacroResults(PP, Builder);
5784
5785 Results.clear();
5786 Results.insert(Results.end(),
5787 Builder.data(), Builder.data() + Builder.size());
5788}