blob: 50ea6cb0b5f4918f6f9f408090f9cc4896f9218e [file] [log] [blame]
Douglas Gregor2436e712009-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 McCall83024632010-08-25 22:03:47 +000013#include "clang/Sema/SemaInternal.h"
Douglas Gregorc3a6ade2010-08-12 20:07:10 +000014#include "clang/Sema/Lookup.h"
John McCall5c32be02010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregord720daf2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCallcc14d1f2010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCallaab3e412010-08-25 08:40:02 +000019#include "clang/Sema/ScopeInfo.h"
John McCallde6836a2010-08-24 07:21:54 +000020#include "clang/AST/DeclObjC.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000021#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000022#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000023#include "clang/Lex/MacroInfo.h"
24#include "clang/Lex/Preprocessor.h"
Douglas Gregor1154e272010-09-16 16:06:31 +000025#include "llvm/ADT/DenseSet.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000026#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000027#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000028#include "llvm/ADT/StringSwitch.h"
Douglas Gregor67c692c2010-08-26 15:07:07 +000029#include "llvm/ADT/Twine.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000030#include <list>
31#include <map>
32#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000033
34using namespace clang;
John McCallaab3e412010-08-25 08:40:02 +000035using namespace sema;
Douglas Gregor2436e712009-09-17 21:32:03 +000036
Douglas Gregor3545ff42009-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 McCall276321a2010-08-25 06:19:51 +000047 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-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 Gregor05e7ca32009-12-06 20:23:50 +0000115 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-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 Gregor6ae4c522010-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 Gregor7aa6b222010-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 Gregor3545ff42009-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 Gregor9be0ed42010-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 Gregorc2cb2e22010-08-27 15:29:55 +0000147 /// \brief The selector that we prefer.
148 Selector PreferredSelector;
149
Douglas Gregor05fcf842010-11-02 20:36:02 +0000150 /// \brief The completion context in which we are gathering results.
Douglas Gregor50832e02010-09-20 22:39:41 +0000151 CodeCompletionContext CompletionContext;
152
Douglas Gregor05fcf842010-11-02 20:36:02 +0000153 /// \brief If we are in an instance method definition, the @implementation
154 /// object.
155 ObjCImplementationDecl *ObjCImplementation;
156
Douglas Gregor50832e02010-09-20 22:39:41 +0000157 void AdjustResultPriorityForDecl(Result &R);
Douglas Gregor95887f92010-07-08 23:20:03 +0000158
Douglas Gregor0212fd72010-09-21 16:06:22 +0000159 void MaybeAddConstructorResults(Result R);
160
Douglas Gregor3545ff42009-09-21 16:56:56 +0000161 public:
Douglas Gregor0ac41382010-09-23 23:01:17 +0000162 explicit ResultBuilder(Sema &SemaRef,
163 const CodeCompletionContext &CompletionContext,
164 LookupFilter Filter = 0)
Douglas Gregor9be0ed42010-08-26 16:36:48 +0000165 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
Douglas Gregor50832e02010-09-20 22:39:41 +0000166 HasObjectTypeQualifiers(false),
Douglas Gregor05fcf842010-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 Gregor3545ff42009-09-21 16:56:56 +0000188
Douglas Gregorf64acca2010-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 Gregorac322ec2010-08-27 21:18:54 +0000193 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregorf64acca2010-05-25 21:41:55 +0000194 }
195
Douglas Gregor3545ff42009-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 Gregor3545ff42009-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 Gregor7aa6b222010-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 Gregor9be0ed42010-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 Gregorc2cb2e22010-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 Gregor05fcf842010-11-02 20:36:02 +0000230
Douglas Gregor50832e02010-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 Gregor6ae4c522010-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 Gregor74661272010-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 Gregor7c208612010-01-14 00:20:49 +0000246 /// \brief Determine whether the given declaration is at all interesting
247 /// as a code-completion result.
Douglas Gregor6ae4c522010-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 Gregore0717ab2010-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 Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000267 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000268 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-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 Gregor3545ff42009-09-21 16:56:56 +0000272
Douglas Gregorc580c522010-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 Gregor09bbc652010-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 Gregorc580c522010-01-14 01:09:38 +0000286
Douglas Gregor78a21012010-01-14 16:01:26 +0000287 /// \brief Add a new non-declaration result to this result set.
288 void AddResult(Result R);
289
Douglas Gregor3545ff42009-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 Gregorbaf69612009-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 Gregor3545ff42009-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 Gregor9d64c5e2009-09-21 20:51:25 +0000305 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor70febae2010-05-28 00:49:12 +0000306 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregor85b50632010-07-28 21:50:18 +0000307 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000308 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-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 Gregore412a5a2009-09-23 22:26:46 +0000316 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000317 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregora817a192010-05-27 23:06:34 +0000318 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor68762e72010-08-23 21:17:50 +0000319 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor0ac41382010-09-23 23:01:17 +0000320 bool IsImpossibleToSatisfy(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000321 //@}
322 };
323}
324
Douglas Gregor05e7ca32009-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 Lattner9795b392010-09-04 18:12:20 +0000367 /*iterator operator++(int) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000368 iterator tmp(*this);
369 ++(*this);
370 return tmp;
Chris Lattner9795b392010-09-04 18:12:20 +0000371 }*/
Douglas Gregor05e7ca32009-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 Gregor94bb5e82009-12-06 21:27:58 +0000377 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-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 Gregor94bb5e82009-12-06 21:27:58 +0000385 return X.DeclOrIterator.getOpaqueValue()
386 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000387 X.SingleDeclIndex == Y.SingleDeclIndex;
388 }
389
390 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000391 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000392 }
393};
394
Douglas Gregor05e7ca32009-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 Gregor2af2f672009-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 Gregor68762e72010-08-23 21:17:50 +0000448 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
449 if (!Namespace->getIdentifier())
450 continue;
451
Douglas Gregor2af2f672009-09-21 20:12:40 +0000452 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregor68762e72010-08-23 21:17:50 +0000453 }
Douglas Gregor2af2f672009-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 Gregor9eb77012009-11-07 00:00:49 +0000458 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000459 return Result;
460}
461
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000462bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
463 bool &AsNestedNameSpecifier) const {
464 AsNestedNameSpecifier = false;
465
Douglas Gregor7c208612010-01-14 00:20:49 +0000466 ND = ND->getUnderlyingDecl();
467 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000468
469 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000470 if (!ND->getDeclName())
471 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000472
473 // Friend declarations and declarations introduced due to friends are never
474 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000475 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000476 return false;
477
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000478 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000479 if (isa<ClassTemplateSpecializationDecl>(ND) ||
480 isa<ClassTemplatePartialSpecializationDecl>(ND))
481 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000482
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000483 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-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 Gregor3545ff42009-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 Gregor7c208612010-01-14 00:20:49 +0000491 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000492
Douglas Gregor58acf322009-10-09 22:16:47 +0000493 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor9f1570d2010-07-14 17:44:04 +0000494 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000495 //
496 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000497 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000498 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000499 if (Name[0] == '_' &&
Douglas Gregor9f1570d2010-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 Gregor7c208612010-01-14 00:20:49 +0000504 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000505 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000506 }
Douglas Gregor0212fd72010-09-21 16:06:22 +0000507
Douglas Gregor2927c0c2010-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 Gregor59cab552010-08-16 23:05:20 +0000516 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
517 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
518 Filter != &ResultBuilder::IsNamespace &&
Douglas Gregor0ac41382010-09-23 23:01:17 +0000519 Filter != &ResultBuilder::IsNamespaceOrAlias &&
520 Filter != 0))
Douglas Gregor59cab552010-08-16 23:05:20 +0000521 AsNestedNameSpecifier = true;
522
Douglas Gregor3545ff42009-09-21 16:56:56 +0000523 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-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 Gregor7c208612010-01-14 00:20:49 +0000535 return false;
Douglas Gregor59cab552010-08-16 23:05:20 +0000536 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000537 // ... then it must be interesting!
538 return true;
539}
540
Douglas Gregore0717ab2010-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 Redl50c68252010-08-31 00:36:30 +0000549 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregore0717ab2010-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 Redl50c68252010-08-31 00:36:30 +0000555 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregore0717ab2010-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 Gregor95887f92010-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 Gregor6e240332010-08-16 16:18:59 +0000571SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor95887f92010-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 Gregor6e240332010-08-16 16:18:59 +0000642QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor95887f92010-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 Gregor603d81b2010-07-13 08:18:22 +0000652 T = Function->getCallResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000653 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000654 T = Method->getSendResultType();
Douglas Gregor95887f92010-07-08 23:20:03 +0000655 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor603d81b2010-07-13 08:18:22 +0000656 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor95887f92010-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 Gregor50832e02010-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 Gregor5fb901d2010-09-20 23:11:55 +0000676
Douglas Gregor50832e02010-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 Gregor95887f92010-07-08 23:20:03 +0000688 == getSimplifiedTypeClass(TC)) &&
Douglas Gregor50832e02010-09-20 22:39:41 +0000689 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
690 R.Priority /= CCF_SimilarTypeMatch;
691 }
692 }
Douglas Gregor95887f92010-07-08 23:20:03 +0000693}
694
Douglas Gregor0212fd72010-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 Gregor7c208612010-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 Gregor6ae4c522010-01-14 03:21:49 +0000749 bool AsNestedNameSpecifier = false;
750 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000751 return;
752
Douglas Gregor0212fd72010-09-21 16:06:22 +0000753 // C++ constructors are never found by name lookup.
754 if (isa<CXXConstructorDecl>(R.Declaration))
755 return;
756
Douglas Gregor3545ff42009-09-21 16:56:56 +0000757 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000768 if (ND->getCanonicalDecl() == CanonDecl) {
769 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000770 Results[Index].Declaration = R.Declaration;
771
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000790 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000791 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-12-06 20:23:50 +0000797 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000798 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000799 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000800 continue;
801
802 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000803 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000804 return;
Douglas Gregor3545ff42009-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 Gregorc2cb2e22010-08-27 15:29:55 +0000813
Douglas Gregore412a5a2009-09-23 22:26:46 +0000814 // If the filter is for nested-name-specifiers, then this result starts a
815 // nested-name-specifier.
Douglas Gregora2db7932010-05-26 22:00:08 +0000816 if (AsNestedNameSpecifier) {
Douglas Gregore412a5a2009-09-23 22:26:46 +0000817 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000818 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor50832e02010-09-20 22:39:41 +0000819 } else
820 AdjustResultPriorityForDecl(R);
Douglas Gregorc2cb2e22010-08-27 15:29:55 +0000821
Douglas Gregor5bf52692009-09-22 23:15:58 +0000822 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000823 if (R.QualifierIsInformative && !R.Qualifier &&
824 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-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 Gregore412a5a2009-09-23 22:26:46 +0000834
Douglas Gregor3545ff42009-09-21 16:56:56 +0000835 // Insert this result into the set of results and into the current shadow
836 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000837 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000838 Results.push_back(R);
Douglas Gregor0212fd72010-09-21 16:06:22 +0000839
840 if (!AsNestedNameSpecifier)
841 MaybeAddConstructorResults(R);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000842}
843
Douglas Gregorc580c522010-01-14 01:09:38 +0000844void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000845 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-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 Gregorc580c522010-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 Gregor6ae4c522010-01-14 03:21:49 +0000858 bool AsNestedNameSpecifier = false;
859 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000860 return;
861
Douglas Gregor0212fd72010-09-21 16:06:22 +0000862 // C++ constructors are never found by name lookup.
863 if (isa<CXXConstructorDecl>(R.Declaration))
864 return;
865
Douglas Gregorc580c522010-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 Gregora2db7932010-05-26 22:00:08 +0000875 if (AsNestedNameSpecifier) {
Douglas Gregorc580c522010-01-14 01:09:38 +0000876 R.StartsNestedNameSpecifier = true;
Douglas Gregora2db7932010-05-26 22:00:08 +0000877 R.Priority = CCP_NestedNameSpecifier;
878 }
Douglas Gregor09bbc652010-01-14 15:47:35 +0000879 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
880 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl50c68252010-08-31 00:36:30 +0000881 ->getRedeclContext()))
Douglas Gregor09bbc652010-01-14 15:47:35 +0000882 R.QualifierIsInformative = true;
883
Douglas Gregorc580c522010-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 Gregor6ae4c522010-01-14 03:21:49 +0000892 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000893 else
894 R.QualifierIsInformative = false;
895 }
896
Douglas Gregora2db7932010-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 Gregor50832e02010-09-20 22:39:41 +0000901 AdjustResultPriorityForDecl(R);
Douglas Gregor7aa6b222010-05-30 01:49:25 +0000902
Douglas Gregor9be0ed42010-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 Gregorc580c522010-01-14 01:09:38 +0000917 // Insert this result into the set of results.
918 Results.push_back(R);
Douglas Gregor0212fd72010-09-21 16:06:22 +0000919
920 if (!AsNestedNameSpecifier)
921 MaybeAddConstructorResults(R);
Douglas Gregorc580c522010-01-14 01:09:38 +0000922}
923
Douglas Gregor78a21012010-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 Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000943 ShadowMaps.pop_back();
944}
945
Douglas Gregor9d64c5e2009-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 Gregor70febae2010-05-28 00:49:12 +0000949 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
950
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000951 unsigned IDNS = Decl::IDNS_Ordinary;
952 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9858ed52010-06-15 20:26:51 +0000953 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor05fcf842010-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 Gregor9d64c5e2009-09-21 20:51:25 +0000962 return ND->getIdentifierNamespace() & IDNS;
963}
964
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000965/// \brief Determines whether this given declaration will be found by
Douglas Gregor70febae2010-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 Gregor9858ed52010-06-15 20:26:51 +0000974 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor05fcf842010-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 Gregor70febae2010-05-28 00:49:12 +0000983 return ND->getIdentifierNamespace() & IDNS;
984}
985
Douglas Gregor85b50632010-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 Gregor70febae2010-05-28 00:49:12 +0000997/// \brief Determines whether this given declaration will be found by
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000998/// ordinary name lookup.
999bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor70febae2010-05-28 00:49:12 +00001000 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1001
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001002 unsigned IDNS = Decl::IDNS_Ordinary;
1003 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +00001004 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001005
1006 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor70febae2010-05-28 00:49:12 +00001007 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
1008 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001009}
1010
Douglas Gregor3545ff42009-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 Bagnara6150c882010-05-11 21:36:43 +00001033 return RD->getTagKind() == TTK_Class ||
1034 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-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 Bagnara6150c882010-05-11 21:36:43 +00001046 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-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 Gregor99fe2ad2009-12-11 17:31:05 +00001062/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +00001063bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregor99fa2642010-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 Gregor3545ff42009-09-21 16:56:56 +00001068}
1069
Douglas Gregor99fe2ad2009-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 Gregore412a5a2009-09-23 22:26:46 +00001073bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +00001074 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1075 ND = Using->getTargetDecl();
1076
Douglas Gregor70788392009-12-11 18:14:22 +00001077 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1078 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +00001079}
1080
Douglas Gregora817a192010-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 Gregor68762e72010-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 Gregora817a192010-05-27 23:06:34 +00001137
Douglas Gregor0ac41382010-09-23 23:01:17 +00001138bool ResultBuilder::IsImpossibleToSatisfy(NamedDecl *ND) const {
1139 return false;
1140}
1141
Douglas Gregor2b8162b2010-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 Gregorc580c522010-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 Gregor09bbc652010-01-14 15:47:35 +00001159 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1160 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +00001161 }
1162 };
1163}
1164
Douglas Gregor3545ff42009-09-21 16:56:56 +00001165/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001166static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +00001167 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001168 typedef CodeCompletionResult Result;
Douglas Gregora2db7932010-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 Gregor504a6ae2010-01-10 23:08:15 +00001183
Douglas Gregor3545ff42009-09-21 16:56:56 +00001184 if (LangOpts.C99) {
1185 // C99-specific
Douglas Gregora2db7932010-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 Gregor3545ff42009-09-21 16:56:56 +00001190 }
1191
1192 if (LangOpts.CPlusPlus) {
1193 // C++-specific
Douglas Gregor9dcf58a2010-09-20 21:11:48 +00001194 Results.AddResult(Result("bool", CCP_Type +
1195 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
Douglas Gregora2db7932010-05-26 22:00:08 +00001196 Results.AddResult(Result("class", CCP_Type));
1197 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001198
Douglas Gregorf4c33342010-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 Gregorf64acca2010-05-25 21:41:55 +00001207
Douglas Gregor3545ff42009-09-21 16:56:56 +00001208 if (LangOpts.CPlusPlus0x) {
Douglas Gregora2db7932010-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 Gregorf4c33342010-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 Gregor3545ff42009-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 Gregor78a21012010-01-14 16:01:26 +00001225 // Results.AddResult(Result("_Decimal32"));
1226 // Results.AddResult(Result("_Decimal64"));
1227 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001228
Douglas Gregorf4c33342010-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 Gregor3545ff42009-09-21 16:56:56 +00001241 }
1242}
1243
John McCallfaf5fb42010-08-26 23:41:50 +00001244static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001245 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001246 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001247 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +00001251 Results.AddResult(Result("extern"));
1252 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001253}
1254
John McCallfaf5fb42010-08-26 23:41:50 +00001255static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001256 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001257 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001258 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001259 switch (CCC) {
John McCallfaf5fb42010-08-26 23:41:50 +00001260 case Sema::PCC_Class:
1261 case Sema::PCC_MemberTemplate:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001262 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-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 Gregor504a6ae2010-01-10 23:08:15 +00001267 }
1268 // Fall through
1269
John McCallfaf5fb42010-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 Gregor504a6ae2010-01-10 23:08:15 +00001274 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +00001275 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001276 break;
1277
John McCallfaf5fb42010-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 Gregor5e35d592010-09-14 23:59:36 +00001285 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001286 break;
1287 }
1288}
1289
Douglas Gregorf98e6a22010-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 Gregor48d46252010-01-13 21:54:15 +00001293 ResultBuilder &Results,
1294 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001295static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001296 ResultBuilder &Results,
1297 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001298static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00001299 ResultBuilder &Results,
1300 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001301static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +00001302
Douglas Gregorf4c33342010-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 McCall276321a2010-08-25 06:19:51 +00001310 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorf4c33342010-05-28 00:22:41 +00001311}
1312
John McCallfaf5fb42010-08-26 23:41:50 +00001313static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor70febae2010-05-28 00:49:12 +00001314 const LangOptions &LangOpts) {
Douglas Gregor70febae2010-05-28 00:49:12 +00001315 switch (CCC) {
John McCallfaf5fb42010-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 Gregor5e35d592010-09-14 23:59:36 +00001324 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor70febae2010-05-28 00:49:12 +00001325 return true;
1326
John McCallfaf5fb42010-08-26 23:41:50 +00001327 case Sema::PCC_Expression:
1328 case Sema::PCC_Condition:
Douglas Gregor5e35d592010-09-14 23:59:36 +00001329 return LangOpts.CPlusPlus;
1330
1331 case Sema::PCC_ObjCInterface:
1332 case Sema::PCC_ObjCImplementation:
Douglas Gregor70febae2010-05-28 00:49:12 +00001333 return false;
1334
John McCallfaf5fb42010-08-26 23:41:50 +00001335 case Sema::PCC_ForInit:
Douglas Gregor5e35d592010-09-14 23:59:36 +00001336 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor70febae2010-05-28 00:49:12 +00001337 }
1338
1339 return false;
1340}
1341
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001342/// \brief Add language constructs that show up for "ordinary" names.
John McCallfaf5fb42010-08-26 23:41:50 +00001343static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001344 Scope *S,
1345 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001346 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00001347 typedef CodeCompletionResult Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001348 switch (CCC) {
John McCallfaf5fb42010-08-26 23:41:50 +00001349 case Sema::PCC_Namespace:
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001366 // namespace identifier = identifier ;
1367 Pattern = new CodeCompletionString;
1368 Pattern->AddTypedTextChunk("namespace");
1369 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001370 Pattern->AddPlaceholderChunk("name");
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001371 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001372 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregor78a21012010-01-14 16:01:26 +00001373 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +00001382 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +00001390 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001391
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001400 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001401
1402 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001403 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001404
Douglas Gregorf4c33342010-05-28 00:22:41 +00001405 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001406 // Fall through
1407
John McCallfaf5fb42010-08-26 23:41:50 +00001408 case Sema::PCC_Class:
Douglas Gregorf4c33342010-05-28 00:22:41 +00001409 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001410 // Using declaration
1411 CodeCompletionString *Pattern = new CodeCompletionString;
1412 Pattern->AddTypedTextChunk("using");
1413 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00001414 Pattern->AddPlaceholderChunk("qualifier");
1415 Pattern->AddTextChunk("::");
1416 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001417 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001418
Douglas Gregorf4c33342010-05-28 00:22:41 +00001419 // using typename qualifier::name (only in a dependent context)
Douglas Gregor504a6ae2010-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 Gregorf4c33342010-05-28 00:22:41 +00001426 Pattern->AddPlaceholderChunk("qualifier");
1427 Pattern->AddTextChunk("::");
1428 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00001429 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001430 }
1431
John McCallfaf5fb42010-08-26 23:41:50 +00001432 if (CCC == Sema::PCC_Class) {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001433 AddTypedefResult(Results);
1434
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001435 // public:
1436 Pattern = new CodeCompletionString;
1437 Pattern->AddTypedTextChunk("public");
1438 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001439 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001440
1441 // protected:
1442 Pattern = new CodeCompletionString;
1443 Pattern->AddTypedTextChunk("protected");
1444 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001445 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001446
1447 // private:
1448 Pattern = new CodeCompletionString;
1449 Pattern->AddTypedTextChunk("private");
1450 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001451 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001452 }
1453 }
1454 // Fall through
1455
John McCallfaf5fb42010-08-26 23:41:50 +00001456 case Sema::PCC_Template:
1457 case Sema::PCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +00001458 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +00001465 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001466 }
1467
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001468 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1469 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001470 break;
1471
John McCallfaf5fb42010-08-26 23:41:50 +00001472 case Sema::PCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001473 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1474 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1475 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001476 break;
1477
John McCallfaf5fb42010-08-26 23:41:50 +00001478 case Sema::PCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001479 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1480 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1481 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001482 break;
1483
John McCallfaf5fb42010-08-26 23:41:50 +00001484 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001485 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001486 break;
1487
John McCallfaf5fb42010-08-26 23:41:50 +00001488 case Sema::PCC_RecoveryInFunction:
1489 case Sema::PCC_Statement: {
Douglas Gregorf4c33342010-05-28 00:22:41 +00001490 AddTypedefResult(Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001491
1492 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001493 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +00001508 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001509 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001510 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001511 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001512
Douglas Gregorf64acca2010-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 Gregor504a6ae2010-01-10 23:08:15 +00001528
Douglas Gregorf64acca2010-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 Gregor504a6ae2010-01-10 23:08:15 +00001544 // Switch-specific statements.
John McCallaab3e412010-08-25 08:40:02 +00001545 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001546 // case expression:
1547 Pattern = new CodeCompletionString;
1548 Pattern->AddTypedTextChunk("case");
Douglas Gregorf4c33342010-05-28 00:22:41 +00001549 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001550 Pattern->AddPlaceholderChunk("expression");
1551 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001552 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001553
1554 // default:
1555 Pattern = new CodeCompletionString;
1556 Pattern->AddTypedTextChunk("default");
1557 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001558 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001559 }
1560
Douglas Gregorf64acca2010-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 Gregor504a6ae2010-01-10 23:08:15 +00001586 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001587 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1588 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001589
Douglas Gregorf64acca2010-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 Gregor8ed5b772010-10-08 20:39:29 +00001604 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
Douglas Gregorf64acca2010-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 Gregor504a6ae2010-01-10 23:08:15 +00001610
1611 if (S->getContinueParent()) {
1612 // continue ;
1613 Pattern = new CodeCompletionString;
1614 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001615 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001616 }
1617
1618 if (S->getBreakParent()) {
1619 // break ;
1620 Pattern = new CodeCompletionString;
1621 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001622 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-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 Gregor9a28e842010-03-01 23:15:13 +00001633 else if (SemaRef.getCurBlock() &&
1634 !SemaRef.getCurBlock()->ReturnType.isNull())
1635 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001636 Pattern = new CodeCompletionString;
1637 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001638 if (!isVoid) {
1639 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001640 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001641 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001642 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001643
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001650
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001659 }
1660
1661 // Fall through (for statement expressions).
John McCallfaf5fb42010-08-26 23:41:50 +00001662 case Sema::PCC_ForInit:
1663 case Sema::PCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001664 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001665 // Fall through: conditions and statements can have expressions.
1666
Douglas Gregor5e35d592010-09-14 23:59:36 +00001667 case Sema::PCC_ParenthesizedExpression:
John McCallfaf5fb42010-08-26 23:41:50 +00001668 case Sema::PCC_Expression: {
Douglas Gregor504a6ae2010-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 Gregor78a21012010-01-14 16:01:26 +00001674 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001675
1676 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001677 Results.AddResult(Result("true"));
1678 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001679
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001701
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001712
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001723
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001731
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001741
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001754
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001761
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001771
Douglas Gregorf4c33342010-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 Gregora2db7932010-05-26 22:00:08 +00001778
1779 // FIXME: Rethrow?
Douglas Gregor504a6ae2010-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 Kremenek305a0a72010-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 Gregorf98e6a22010-01-13 23:51:12 +00001791 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001792 }
1793
Douglas Gregorf4c33342010-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 Gregor504a6ae2010-01-10 23:08:15 +00001801 break;
1802 }
Douglas Gregor99fa2642010-08-24 01:06:58 +00001803
John McCallfaf5fb42010-08-26 23:41:50 +00001804 case Sema::PCC_Type:
Douglas Gregor99fa2642010-08-24 01:06:58 +00001805 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001806 }
1807
Douglas Gregor70febae2010-05-28 00:49:12 +00001808 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1809 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001810
John McCallfaf5fb42010-08-26 23:41:50 +00001811 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregor78a21012010-01-14 16:01:26 +00001812 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001813}
1814
Douglas Gregorb3fa9192009-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 Gregor0212fd72010-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 Gregorb3fa9192009-12-18 18:53:37 +00001828 // Determine the type of the declaration (if it has a type).
Douglas Gregor0212fd72010-09-21 16:06:22 +00001829 QualType T;
Douglas Gregorb3fa9192009-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 Gregorcf04b022010-04-05 21:25:31 +00001848 PrintingPolicy Policy(Context.PrintingPolicy);
1849 Policy.AnonymousTagLocations = false;
1850
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001851 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001852 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001853 Result->AddResultTypeChunk(TypeStr);
1854}
1855
Douglas Gregordbb71db2010-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 Gregore90dd002010-08-24 16:15:59 +00001870static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregor981a0c42010-08-29 19:47:46 +00001871 ParmVarDecl *Param,
1872 bool SuppressName = false) {
Douglas Gregore90dd002010-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 Gregor981a0c42010-08-29 19:47:46 +00001880 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregore90dd002010-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 Gregor981a0c42010-08-29 19:47:46 +00001889 if (Param->getIdentifier() && !SuppressName)
Douglas Gregore90dd002010-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)) {
Abramo Bagnara6d810632010-12-14 22:11:44 +00001921 TL = BlockPtr->getPointeeLoc().IgnoreParens();
Douglas Gregore90dd002010-08-24 16:15:59 +00001922 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1923 }
1924 break;
1925 }
1926 }
1927
1928 if (!Block) {
1929 // We were unable to find a FunctionProtoTypeLoc with parameter names
1930 // for the block; just use the parameter type as a placeholder.
1931 std::string Result;
1932 Param->getType().getUnqualifiedType().
1933 getAsStringInternal(Result, Context.PrintingPolicy);
1934
1935 if (ObjCMethodParam) {
1936 Result = "(" + Result;
1937 Result += ")";
1938 if (Param->getIdentifier())
1939 Result += Param->getIdentifier()->getName();
1940 }
1941
1942 return Result;
1943 }
1944
1945 // We have the function prototype behind the block pointer type, as it was
1946 // written in the source.
Douglas Gregor67da50e2010-09-08 22:47:51 +00001947 std::string Result;
1948 QualType ResultType = Block->getTypePtr()->getResultType();
1949 if (!ResultType->isVoidType())
1950 ResultType.getAsStringInternal(Result, Context.PrintingPolicy);
1951
1952 Result = '^' + Result;
1953 if (Block->getNumArgs() == 0) {
1954 if (Block->getTypePtr()->isVariadic())
1955 Result += "(...)";
Douglas Gregoraf25cfa2010-10-02 23:49:58 +00001956 else
1957 Result += "(void)";
Douglas Gregor67da50e2010-09-08 22:47:51 +00001958 } else {
1959 Result += "(";
1960 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1961 if (I)
1962 Result += ", ";
1963 Result += FormatFunctionParameter(Context, Block->getArg(I));
1964
1965 if (I == N - 1 && Block->getTypePtr()->isVariadic())
1966 Result += ", ...";
1967 }
1968 Result += ")";
Douglas Gregor400f5972010-08-31 05:13:43 +00001969 }
Douglas Gregor67da50e2010-09-08 22:47:51 +00001970
Douglas Gregoraf25cfa2010-10-02 23:49:58 +00001971 if (Param->getIdentifier())
1972 Result += Param->getIdentifier()->getName();
1973
Douglas Gregore90dd002010-08-24 16:15:59 +00001974 return Result;
1975}
1976
Douglas Gregor3545ff42009-09-21 16:56:56 +00001977/// \brief Add function parameter chunks to the given code completion string.
1978static void AddFunctionParameterChunks(ASTContext &Context,
1979 FunctionDecl *Function,
1980 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001981 typedef CodeCompletionString::Chunk Chunk;
1982
Douglas Gregor3545ff42009-09-21 16:56:56 +00001983 CodeCompletionString *CCStr = Result;
1984
1985 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1986 ParmVarDecl *Param = Function->getParamDecl(P);
1987
1988 if (Param->hasDefaultArg()) {
1989 // When we see an optional default argument, put that argument and
1990 // the remaining default arguments into a new, optional string.
1991 CodeCompletionString *Opt = new CodeCompletionString;
1992 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1993 CCStr = Opt;
1994 }
1995
1996 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001997 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001998
1999 // Format the placeholder string.
Douglas Gregore90dd002010-08-24 16:15:59 +00002000 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
2001
Douglas Gregor400f5972010-08-31 05:13:43 +00002002 if (Function->isVariadic() && P == N - 1)
2003 PlaceholderStr += ", ...";
2004
Douglas Gregor3545ff42009-09-21 16:56:56 +00002005 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002006 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002007 }
Douglas Gregorba449032009-09-22 21:42:17 +00002008
2009 if (const FunctionProtoType *Proto
2010 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregordbb71db2010-08-23 23:51:41 +00002011 if (Proto->isVariadic()) {
Douglas Gregor400f5972010-08-31 05:13:43 +00002012 if (Proto->getNumArgs() == 0)
2013 CCStr->AddPlaceholderChunk("...");
Douglas Gregordbb71db2010-08-23 23:51:41 +00002014
2015 MaybeAddSentinel(Context, Function, CCStr);
2016 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002017}
2018
2019/// \brief Add template parameter chunks to the given code completion string.
2020static void AddTemplateParameterChunks(ASTContext &Context,
2021 TemplateDecl *Template,
2022 CodeCompletionString *Result,
2023 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002024 typedef CodeCompletionString::Chunk Chunk;
2025
Douglas Gregor3545ff42009-09-21 16:56:56 +00002026 CodeCompletionString *CCStr = Result;
2027 bool FirstParameter = true;
2028
2029 TemplateParameterList *Params = Template->getTemplateParameters();
2030 TemplateParameterList::iterator PEnd = Params->end();
2031 if (MaxParameters)
2032 PEnd = Params->begin() + MaxParameters;
2033 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
2034 bool HasDefaultArg = false;
2035 std::string PlaceholderStr;
2036 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
2037 if (TTP->wasDeclaredWithTypename())
2038 PlaceholderStr = "typename";
2039 else
2040 PlaceholderStr = "class";
2041
2042 if (TTP->getIdentifier()) {
2043 PlaceholderStr += ' ';
2044 PlaceholderStr += TTP->getIdentifier()->getName();
2045 }
2046
2047 HasDefaultArg = TTP->hasDefaultArgument();
2048 } else if (NonTypeTemplateParmDecl *NTTP
2049 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
2050 if (NTTP->getIdentifier())
2051 PlaceholderStr = NTTP->getIdentifier()->getName();
2052 NTTP->getType().getAsStringInternal(PlaceholderStr,
2053 Context.PrintingPolicy);
2054 HasDefaultArg = NTTP->hasDefaultArgument();
2055 } else {
2056 assert(isa<TemplateTemplateParmDecl>(*P));
2057 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
2058
2059 // Since putting the template argument list into the placeholder would
2060 // be very, very long, we just use an abbreviation.
2061 PlaceholderStr = "template<...> class";
2062 if (TTP->getIdentifier()) {
2063 PlaceholderStr += ' ';
2064 PlaceholderStr += TTP->getIdentifier()->getName();
2065 }
2066
2067 HasDefaultArg = TTP->hasDefaultArgument();
2068 }
2069
2070 if (HasDefaultArg) {
2071 // When we see an optional default argument, put that argument and
2072 // the remaining default arguments into a new, optional string.
2073 CodeCompletionString *Opt = new CodeCompletionString;
2074 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
2075 CCStr = Opt;
2076 }
2077
2078 if (FirstParameter)
2079 FirstParameter = false;
2080 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002081 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002082
2083 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002084 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002085 }
2086}
2087
Douglas Gregorf2510672009-09-21 19:57:38 +00002088/// \brief Add a qualifier to the given code-completion string, if the
2089/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00002090static void
2091AddQualifierToCompletionString(CodeCompletionString *Result,
2092 NestedNameSpecifier *Qualifier,
2093 bool QualifierIsInformative,
2094 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00002095 if (!Qualifier)
2096 return;
2097
2098 std::string PrintedNNS;
2099 {
2100 llvm::raw_string_ostream OS(PrintedNNS);
2101 Qualifier->print(OS, Context.PrintingPolicy);
2102 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00002103 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002104 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00002105 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002106 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00002107}
2108
Douglas Gregor0f622362009-12-11 18:44:16 +00002109static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
2110 FunctionDecl *Function) {
2111 const FunctionProtoType *Proto
2112 = Function->getType()->getAs<FunctionProtoType>();
2113 if (!Proto || !Proto->getTypeQuals())
2114 return;
2115
2116 std::string QualsStr;
2117 if (Proto->getTypeQuals() & Qualifiers::Const)
2118 QualsStr += " const";
2119 if (Proto->getTypeQuals() & Qualifiers::Volatile)
2120 QualsStr += " volatile";
2121 if (Proto->getTypeQuals() & Qualifiers::Restrict)
2122 QualsStr += " restrict";
2123 Result->AddInformativeChunk(QualsStr);
2124}
2125
Douglas Gregor0212fd72010-09-21 16:06:22 +00002126/// \brief Add the name of the given declaration
2127static void AddTypedNameChunk(ASTContext &Context, NamedDecl *ND,
2128 CodeCompletionString *Result) {
2129 typedef CodeCompletionString::Chunk Chunk;
2130
2131 DeclarationName Name = ND->getDeclName();
2132 if (!Name)
2133 return;
2134
2135 switch (Name.getNameKind()) {
2136 case DeclarationName::Identifier:
2137 case DeclarationName::CXXConversionFunctionName:
2138 case DeclarationName::CXXOperatorName:
2139 case DeclarationName::CXXDestructorName:
2140 case DeclarationName::CXXLiteralOperatorName:
2141 Result->AddTypedTextChunk(ND->getNameAsString());
2142 break;
2143
2144 case DeclarationName::CXXUsingDirective:
2145 case DeclarationName::ObjCZeroArgSelector:
2146 case DeclarationName::ObjCOneArgSelector:
2147 case DeclarationName::ObjCMultiArgSelector:
2148 break;
2149
2150 case DeclarationName::CXXConstructorName: {
2151 CXXRecordDecl *Record = 0;
2152 QualType Ty = Name.getCXXNameType();
2153 if (const RecordType *RecordTy = Ty->getAs<RecordType>())
2154 Record = cast<CXXRecordDecl>(RecordTy->getDecl());
2155 else if (const InjectedClassNameType *InjectedTy
2156 = Ty->getAs<InjectedClassNameType>())
2157 Record = InjectedTy->getDecl();
2158 else {
2159 Result->AddTypedTextChunk(ND->getNameAsString());
2160 break;
2161 }
2162
2163 Result->AddTypedTextChunk(Record->getNameAsString());
2164 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
2165 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
2166 AddTemplateParameterChunks(Context, Template, Result);
2167 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
2168 }
2169 break;
2170 }
2171 }
2172}
2173
Douglas Gregor3545ff42009-09-21 16:56:56 +00002174/// \brief If possible, create a new code completion string for the given
2175/// result.
2176///
2177/// \returns Either a new, heap-allocated code completion string describing
2178/// how to use this result, or NULL to indicate that the string or name of the
2179/// result is all that is needed.
2180CodeCompletionString *
John McCall276321a2010-08-25 06:19:51 +00002181CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor0212fd72010-09-21 16:06:22 +00002182 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002183 typedef CodeCompletionString::Chunk Chunk;
2184
Douglas Gregorf09935f2009-12-01 05:55:20 +00002185 if (Kind == RK_Pattern)
Douglas Gregor8e984da2010-08-04 16:47:14 +00002186 return Pattern->Clone(Result);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002187
Douglas Gregor8e984da2010-08-04 16:47:14 +00002188 if (!Result)
2189 Result = new CodeCompletionString;
Douglas Gregorf09935f2009-12-01 05:55:20 +00002190
2191 if (Kind == RK_Keyword) {
2192 Result->AddTypedTextChunk(Keyword);
2193 return Result;
2194 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002195
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002196 if (Kind == RK_Macro) {
2197 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002198 assert(MI && "Not a macro?");
2199
2200 Result->AddTypedTextChunk(Macro->getName());
2201
2202 if (!MI->isFunctionLike())
2203 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002204
2205 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00002206 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002207 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2208 A != AEnd; ++A) {
2209 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00002210 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002211
2212 if (!MI->isVariadic() || A != AEnd - 1) {
2213 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002214 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002215 continue;
2216 }
2217
2218 // Variadic argument; cope with the different between GNU and C99
2219 // variadic macros, providing a single placeholder for the rest of the
2220 // arguments.
2221 if ((*A)->isStr("__VA_ARGS__"))
2222 Result->AddPlaceholderChunk("...");
2223 else {
2224 std::string Arg = (*A)->getName();
2225 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002226 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002227 }
2228 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002229 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002230 return Result;
2231 }
2232
Douglas Gregorf64acca2010-05-25 21:41:55 +00002233 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002234 NamedDecl *ND = Declaration;
2235
Douglas Gregor9eb77012009-11-07 00:00:49 +00002236 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002237 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002238 Result->AddTextChunk("::");
2239 return Result;
2240 }
2241
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002242 AddResultTypeChunk(S.Context, ND, Result);
2243
Douglas Gregor3545ff42009-09-21 16:56:56 +00002244 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002245 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2246 S.Context);
Douglas Gregor0212fd72010-09-21 16:06:22 +00002247 AddTypedNameChunk(S.Context, ND, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002248 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002249 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002250 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002251 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002252 return Result;
2253 }
2254
2255 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002256 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2257 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002258 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Douglas Gregor0212fd72010-09-21 16:06:22 +00002259 AddTypedNameChunk(S.Context, Function, Result);
2260
Douglas Gregor3545ff42009-09-21 16:56:56 +00002261 // Figure out which template parameters are deduced (or have default
2262 // arguments).
2263 llvm::SmallVector<bool, 16> Deduced;
2264 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2265 unsigned LastDeducibleArgument;
2266 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2267 --LastDeducibleArgument) {
2268 if (!Deduced[LastDeducibleArgument - 1]) {
2269 // C++0x: Figure out if the template argument has a default. If so,
2270 // the user doesn't need to type this argument.
2271 // FIXME: We need to abstract template parameters better!
2272 bool HasDefaultArg = false;
2273 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2274 LastDeducibleArgument - 1);
2275 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2276 HasDefaultArg = TTP->hasDefaultArgument();
2277 else if (NonTypeTemplateParmDecl *NTTP
2278 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2279 HasDefaultArg = NTTP->hasDefaultArgument();
2280 else {
2281 assert(isa<TemplateTemplateParmDecl>(Param));
2282 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00002283 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002284 }
2285
2286 if (!HasDefaultArg)
2287 break;
2288 }
2289 }
2290
2291 if (LastDeducibleArgument) {
2292 // Some of the function template arguments cannot be deduced from a
2293 // function call, so we introduce an explicit template argument list
2294 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00002295 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002296 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2297 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002298 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002299 }
2300
2301 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00002302 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002303 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002304 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00002305 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002306 return Result;
2307 }
2308
2309 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00002310 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2311 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002312 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00002313 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002314 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00002315 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002316 return Result;
2317 }
2318
Douglas Gregord3c5d792009-11-17 16:44:22 +00002319 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00002320 Selector Sel = Method->getSelector();
2321 if (Sel.isUnarySelector()) {
2322 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2323 return Result;
2324 }
2325
Douglas Gregor1b605f72009-11-19 01:08:35 +00002326 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2327 SelName += ':';
2328 if (StartParameter == 0)
2329 Result->AddTypedTextChunk(SelName);
2330 else {
2331 Result->AddInformativeChunk(SelName);
2332
2333 // If there is only one parameter, and we're past it, add an empty
2334 // typed-text chunk since there is nothing to type.
2335 if (Method->param_size() == 1)
2336 Result->AddTypedTextChunk("");
2337 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00002338 unsigned Idx = 0;
2339 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2340 PEnd = Method->param_end();
2341 P != PEnd; (void)++P, ++Idx) {
2342 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002343 std::string Keyword;
2344 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00002345 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002346 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2347 Keyword += II->getName().str();
2348 Keyword += ":";
Douglas Gregor95887f92010-07-08 23:20:03 +00002349 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregor1b605f72009-11-19 01:08:35 +00002350 Result->AddInformativeChunk(Keyword);
Douglas Gregor8e3e8742010-10-18 21:05:04 +00002351 else
Douglas Gregor1b605f72009-11-19 01:08:35 +00002352 Result->AddTypedTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002353 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00002354
2355 // If we're before the starting parameter, skip the placeholder.
2356 if (Idx < StartParameter)
2357 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00002358
2359 std::string Arg;
Douglas Gregore90dd002010-08-24 16:15:59 +00002360
2361 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregor981a0c42010-08-29 19:47:46 +00002362 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregore90dd002010-08-24 16:15:59 +00002363 else {
2364 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2365 Arg = "(" + Arg + ")";
2366 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregor981a0c42010-08-29 19:47:46 +00002367 if (DeclaringEntity || AllParametersAreInformative)
2368 Arg += II->getName().str();
Douglas Gregore90dd002010-08-24 16:15:59 +00002369 }
2370
Douglas Gregor400f5972010-08-31 05:13:43 +00002371 if (Method->isVariadic() && (P + 1) == PEnd)
2372 Arg += ", ...";
2373
Douglas Gregor95887f92010-07-08 23:20:03 +00002374 if (DeclaringEntity)
2375 Result->AddTextChunk(Arg);
2376 else if (AllParametersAreInformative)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002377 Result->AddInformativeChunk(Arg);
2378 else
2379 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00002380 }
2381
Douglas Gregor04c5f972009-12-23 00:21:46 +00002382 if (Method->isVariadic()) {
Douglas Gregor400f5972010-08-31 05:13:43 +00002383 if (Method->param_size() == 0) {
2384 if (DeclaringEntity)
2385 Result->AddTextChunk(", ...");
2386 else if (AllParametersAreInformative)
2387 Result->AddInformativeChunk(", ...");
2388 else
2389 Result->AddPlaceholderChunk(", ...");
2390 }
Douglas Gregordbb71db2010-08-23 23:51:41 +00002391
2392 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor04c5f972009-12-23 00:21:46 +00002393 }
2394
Douglas Gregord3c5d792009-11-17 16:44:22 +00002395 return Result;
2396 }
2397
Douglas Gregorf09935f2009-12-01 05:55:20 +00002398 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00002399 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2400 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00002401
2402 Result->AddTypedTextChunk(ND->getNameAsString());
2403 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002404}
2405
Douglas Gregorf0f51982009-09-23 00:34:09 +00002406CodeCompletionString *
2407CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2408 unsigned CurrentArg,
Douglas Gregor36e3b5c2010-10-11 21:37:58 +00002409 Sema &S,
2410 CodeCompletionString *Result) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002411 typedef CodeCompletionString::Chunk Chunk;
2412
Douglas Gregor36e3b5c2010-10-11 21:37:58 +00002413 if (!Result)
2414 Result = new CodeCompletionString;
Douglas Gregorf0f51982009-09-23 00:34:09 +00002415 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00002416 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002417 const FunctionProtoType *Proto
2418 = dyn_cast<FunctionProtoType>(getFunctionType());
2419 if (!FDecl && !Proto) {
2420 // Function without a prototype. Just give the return type and a
2421 // highlighted ellipsis.
2422 const FunctionType *FT = getFunctionType();
2423 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002424 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00002425 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2426 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2427 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002428 return Result;
2429 }
2430
2431 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002432 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00002433 else
2434 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002435 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002436
Douglas Gregor9eb77012009-11-07 00:00:49 +00002437 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002438 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2439 for (unsigned I = 0; I != NumParams; ++I) {
2440 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002441 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002442
2443 std::string ArgString;
2444 QualType ArgType;
2445
2446 if (FDecl) {
2447 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2448 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2449 } else {
2450 ArgType = Proto->getArgType(I);
2451 }
2452
2453 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2454
2455 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00002456 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002457 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002458 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00002459 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00002460 }
2461
2462 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00002463 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002464 if (CurrentArg < NumParams)
2465 Result->AddTextChunk("...");
2466 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00002467 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002468 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00002469 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00002470
2471 return Result;
2472}
2473
Douglas Gregor6e240332010-08-16 16:18:59 +00002474unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
Douglas Gregor9dcf58a2010-09-20 21:11:48 +00002475 const LangOptions &LangOpts,
Douglas Gregor6e240332010-08-16 16:18:59 +00002476 bool PreferredTypeIsPointer) {
2477 unsigned Priority = CCP_Macro;
2478
Douglas Gregor9dcf58a2010-09-20 21:11:48 +00002479 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2480 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2481 MacroName.equals("Nil")) {
Douglas Gregor6e240332010-08-16 16:18:59 +00002482 Priority = CCP_Constant;
2483 if (PreferredTypeIsPointer)
2484 Priority = Priority / CCF_SimilarTypeMatch;
Douglas Gregor9dcf58a2010-09-20 21:11:48 +00002485 }
2486 // Treat "YES", "NO", "true", and "false" as constants.
2487 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2488 MacroName.equals("true") || MacroName.equals("false"))
2489 Priority = CCP_Constant;
2490 // Treat "bool" as a type.
2491 else if (MacroName.equals("bool"))
2492 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2493
Douglas Gregor6e240332010-08-16 16:18:59 +00002494
2495 return Priority;
2496}
2497
Douglas Gregor09c0eb12010-09-03 23:30:36 +00002498CXCursorKind clang::getCursorKindForDecl(Decl *D) {
2499 if (!D)
2500 return CXCursor_UnexposedDecl;
2501
2502 switch (D->getKind()) {
2503 case Decl::Enum: return CXCursor_EnumDecl;
2504 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2505 case Decl::Field: return CXCursor_FieldDecl;
2506 case Decl::Function:
2507 return CXCursor_FunctionDecl;
2508 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2509 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2510 case Decl::ObjCClass:
2511 // FIXME
2512 return CXCursor_UnexposedDecl;
2513 case Decl::ObjCForwardProtocol:
2514 // FIXME
2515 return CXCursor_UnexposedDecl;
2516 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2517 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2518 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2519 case Decl::ObjCMethod:
2520 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2521 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2522 case Decl::CXXMethod: return CXCursor_CXXMethod;
2523 case Decl::CXXConstructor: return CXCursor_Constructor;
2524 case Decl::CXXDestructor: return CXCursor_Destructor;
2525 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2526 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2527 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2528 case Decl::ParmVar: return CXCursor_ParmDecl;
2529 case Decl::Typedef: return CXCursor_TypedefDecl;
2530 case Decl::Var: return CXCursor_VarDecl;
2531 case Decl::Namespace: return CXCursor_Namespace;
2532 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2533 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2534 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2535 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2536 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2537 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2538 case Decl::ClassTemplatePartialSpecialization:
2539 return CXCursor_ClassTemplatePartialSpecialization;
2540 case Decl::UsingDirective: return CXCursor_UsingDirective;
2541
2542 case Decl::Using:
2543 case Decl::UnresolvedUsingValue:
2544 case Decl::UnresolvedUsingTypename:
2545 return CXCursor_UsingDeclaration;
2546
2547 default:
2548 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
2549 switch (TD->getTagKind()) {
2550 case TTK_Struct: return CXCursor_StructDecl;
2551 case TTK_Class: return CXCursor_ClassDecl;
2552 case TTK_Union: return CXCursor_UnionDecl;
2553 case TTK_Enum: return CXCursor_EnumDecl;
2554 }
2555 }
2556 }
2557
2558 return CXCursor_UnexposedDecl;
2559}
2560
Douglas Gregor55b037b2010-07-08 20:55:51 +00002561static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2562 bool TargetTypeIsPointer = false) {
John McCall276321a2010-08-25 06:19:51 +00002563 typedef CodeCompletionResult Result;
Douglas Gregor55b037b2010-07-08 20:55:51 +00002564
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002565 Results.EnterNewScope();
Douglas Gregor8e3e8742010-10-18 21:05:04 +00002566
Douglas Gregor9eb77012009-11-07 00:00:49 +00002567 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2568 MEnd = PP.macro_end();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002569 M != MEnd; ++M) {
Douglas Gregor6e240332010-08-16 16:18:59 +00002570 Results.AddResult(Result(M->first,
2571 getMacroUsagePriority(M->first->getName(),
Douglas Gregor9dcf58a2010-09-20 21:11:48 +00002572 PP.getLangOptions(),
Douglas Gregor6e240332010-08-16 16:18:59 +00002573 TargetTypeIsPointer)));
Douglas Gregor55b037b2010-07-08 20:55:51 +00002574 }
Douglas Gregor8e3e8742010-10-18 21:05:04 +00002575
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002576 Results.ExitScope();
Douglas Gregor8e3e8742010-10-18 21:05:04 +00002577
Douglas Gregorf329c7c2009-10-30 16:50:04 +00002578}
2579
Douglas Gregorce0e8562010-08-23 21:54:33 +00002580static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2581 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00002582 typedef CodeCompletionResult Result;
Douglas Gregorce0e8562010-08-23 21:54:33 +00002583
2584 Results.EnterNewScope();
Douglas Gregor8e3e8742010-10-18 21:05:04 +00002585
Douglas Gregorce0e8562010-08-23 21:54:33 +00002586 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2587 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2588 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2589 Results.AddResult(Result("__func__", CCP_Constant));
2590 Results.ExitScope();
2591}
2592
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002593static void HandleCodeCompleteResults(Sema *S,
2594 CodeCompleteConsumer *CodeCompleter,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002595 CodeCompletionContext Context,
John McCall276321a2010-08-25 06:19:51 +00002596 CodeCompletionResult *Results,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002597 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00002598 if (CodeCompleter)
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002599 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002600
2601 for (unsigned I = 0; I != NumResults; ++I)
2602 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002603}
2604
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002605static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2606 Sema::ParserCompletionContext PCC) {
2607 switch (PCC) {
John McCallfaf5fb42010-08-26 23:41:50 +00002608 case Sema::PCC_Namespace:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002609 return CodeCompletionContext::CCC_TopLevel;
2610
John McCallfaf5fb42010-08-26 23:41:50 +00002611 case Sema::PCC_Class:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002612 return CodeCompletionContext::CCC_ClassStructUnion;
2613
John McCallfaf5fb42010-08-26 23:41:50 +00002614 case Sema::PCC_ObjCInterface:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002615 return CodeCompletionContext::CCC_ObjCInterface;
2616
John McCallfaf5fb42010-08-26 23:41:50 +00002617 case Sema::PCC_ObjCImplementation:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002618 return CodeCompletionContext::CCC_ObjCImplementation;
2619
John McCallfaf5fb42010-08-26 23:41:50 +00002620 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002621 return CodeCompletionContext::CCC_ObjCIvarList;
2622
John McCallfaf5fb42010-08-26 23:41:50 +00002623 case Sema::PCC_Template:
2624 case Sema::PCC_MemberTemplate:
Douglas Gregor0ac41382010-09-23 23:01:17 +00002625 if (S.CurContext->isFileContext())
2626 return CodeCompletionContext::CCC_TopLevel;
2627 else if (S.CurContext->isRecord())
2628 return CodeCompletionContext::CCC_ClassStructUnion;
2629 else
2630 return CodeCompletionContext::CCC_Other;
2631
John McCallfaf5fb42010-08-26 23:41:50 +00002632 case Sema::PCC_RecoveryInFunction:
Douglas Gregor0ac41382010-09-23 23:01:17 +00002633 return CodeCompletionContext::CCC_Recovery;
Douglas Gregorc769d6e2010-10-18 22:01:46 +00002634
John McCallfaf5fb42010-08-26 23:41:50 +00002635 case Sema::PCC_ForInit:
Douglas Gregorc769d6e2010-10-18 22:01:46 +00002636 if (S.getLangOptions().CPlusPlus || S.getLangOptions().C99 ||
2637 S.getLangOptions().ObjC1)
2638 return CodeCompletionContext::CCC_ParenthesizedExpression;
2639 else
2640 return CodeCompletionContext::CCC_Expression;
2641
2642 case Sema::PCC_Expression:
John McCallfaf5fb42010-08-26 23:41:50 +00002643 case Sema::PCC_Condition:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002644 return CodeCompletionContext::CCC_Expression;
2645
John McCallfaf5fb42010-08-26 23:41:50 +00002646 case Sema::PCC_Statement:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002647 return CodeCompletionContext::CCC_Statement;
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002648
John McCallfaf5fb42010-08-26 23:41:50 +00002649 case Sema::PCC_Type:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002650 return CodeCompletionContext::CCC_Type;
Douglas Gregor5e35d592010-09-14 23:59:36 +00002651
2652 case Sema::PCC_ParenthesizedExpression:
2653 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002654 }
2655
2656 return CodeCompletionContext::CCC_Other;
2657}
2658
Douglas Gregorac322ec2010-08-27 21:18:54 +00002659/// \brief If we're in a C++ virtual member function, add completion results
2660/// that invoke the functions we override, since it's common to invoke the
2661/// overridden function as well as adding new functionality.
2662///
2663/// \param S The semantic analysis object for which we are generating results.
2664///
2665/// \param InContext This context in which the nested-name-specifier preceding
2666/// the code-completion point
2667static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
2668 ResultBuilder &Results) {
2669 // Look through blocks.
2670 DeclContext *CurContext = S.CurContext;
2671 while (isa<BlockDecl>(CurContext))
2672 CurContext = CurContext->getParent();
2673
2674
2675 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
2676 if (!Method || !Method->isVirtual())
2677 return;
2678
2679 // We need to have names for all of the parameters, if we're going to
2680 // generate a forwarding call.
2681 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2682 PEnd = Method->param_end();
2683 P != PEnd;
2684 ++P) {
2685 if (!(*P)->getDeclName())
2686 return;
2687 }
2688
2689 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
2690 MEnd = Method->end_overridden_methods();
2691 M != MEnd; ++M) {
2692 CodeCompletionString *Pattern = new CodeCompletionString;
2693 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
2694 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
2695 continue;
2696
2697 // If we need a nested-name-specifier, add one now.
2698 if (!InContext) {
2699 NestedNameSpecifier *NNS
2700 = getRequiredQualification(S.Context, CurContext,
2701 Overridden->getDeclContext());
2702 if (NNS) {
2703 std::string Str;
2704 llvm::raw_string_ostream OS(Str);
2705 NNS->print(OS, S.Context.PrintingPolicy);
2706 Pattern->AddTextChunk(OS.str());
2707 }
2708 } else if (!InContext->Equals(Overridden->getDeclContext()))
2709 continue;
2710
2711 Pattern->AddTypedTextChunk(Overridden->getNameAsString());
2712 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2713 bool FirstParam = true;
2714 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
2715 PEnd = Method->param_end();
2716 P != PEnd; ++P) {
2717 if (FirstParam)
2718 FirstParam = false;
2719 else
2720 Pattern->AddChunk(CodeCompletionString::CK_Comma);
2721
2722 Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
2723 }
2724 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2725 Results.AddResult(CodeCompletionResult(Pattern,
2726 CCP_SuperCompletion,
2727 CXCursor_CXXMethod));
2728 Results.Ignore(Overridden);
2729 }
2730}
2731
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002732void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002733 ParserCompletionContext CompletionContext) {
John McCall276321a2010-08-25 06:19:51 +00002734 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00002735 ResultBuilder Results(*this,
2736 mapCodeCompletionContext(*this, CompletionContext));
Douglas Gregorac322ec2010-08-27 21:18:54 +00002737 Results.EnterNewScope();
Douglas Gregor50832e02010-09-20 22:39:41 +00002738
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002739 // Determine how to filter results, e.g., so that the names of
2740 // values (functions, enumerators, function templates, etc.) are
2741 // only allowed where we can have an expression.
2742 switch (CompletionContext) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002743 case PCC_Namespace:
2744 case PCC_Class:
2745 case PCC_ObjCInterface:
2746 case PCC_ObjCImplementation:
2747 case PCC_ObjCInstanceVariableList:
2748 case PCC_Template:
2749 case PCC_MemberTemplate:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002750 case PCC_Type:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002751 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2752 break;
2753
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002754 case PCC_Statement:
Douglas Gregor5e35d592010-09-14 23:59:36 +00002755 case PCC_ParenthesizedExpression:
Douglas Gregor4d755e82010-08-24 23:58:17 +00002756 case PCC_Expression:
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002757 case PCC_ForInit:
2758 case PCC_Condition:
Douglas Gregor70febae2010-05-28 00:49:12 +00002759 if (WantTypesInContext(CompletionContext, getLangOptions()))
2760 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2761 else
2762 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorac322ec2010-08-27 21:18:54 +00002763
2764 if (getLangOptions().CPlusPlus)
2765 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002766 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00002767
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002768 case PCC_RecoveryInFunction:
Douglas Gregor6da3db42010-05-25 05:58:43 +00002769 // Unfiltered
2770 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002771 }
2772
Douglas Gregor9be0ed42010-08-26 16:36:48 +00002773 // If we are in a C++ non-static member function, check the qualifiers on
2774 // the member function to filter/prioritize the results list.
2775 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
2776 if (CurMethod->isInstance())
2777 Results.setObjectTypeQualifiers(
2778 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
2779
Douglas Gregorc580c522010-01-14 01:09:38 +00002780 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002781 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2782 CodeCompleter->includeGlobals());
Douglas Gregor92253692009-12-07 09:54:55 +00002783
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002784 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00002785 Results.ExitScope();
2786
Douglas Gregorce0e8562010-08-23 21:54:33 +00002787 switch (CompletionContext) {
Douglas Gregor5e35d592010-09-14 23:59:36 +00002788 case PCC_ParenthesizedExpression:
Douglas Gregorf02e5f32010-08-24 01:11:00 +00002789 case PCC_Expression:
2790 case PCC_Statement:
2791 case PCC_RecoveryInFunction:
2792 if (S->getFnParent())
2793 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2794 break;
2795
2796 case PCC_Namespace:
2797 case PCC_Class:
2798 case PCC_ObjCInterface:
2799 case PCC_ObjCImplementation:
2800 case PCC_ObjCInstanceVariableList:
2801 case PCC_Template:
2802 case PCC_MemberTemplate:
2803 case PCC_ForInit:
2804 case PCC_Condition:
2805 case PCC_Type:
2806 break;
Douglas Gregorce0e8562010-08-23 21:54:33 +00002807 }
2808
Douglas Gregor9eb77012009-11-07 00:00:49 +00002809 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002810 AddMacroResults(PP, Results);
Douglas Gregorce0e8562010-08-23 21:54:33 +00002811
Douglas Gregor50832e02010-09-20 22:39:41 +00002812 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002813 Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00002814}
2815
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00002816static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2817 ParsedType Receiver,
2818 IdentifierInfo **SelIdents,
2819 unsigned NumSelIdents,
Douglas Gregorf86e4da2010-09-20 23:34:21 +00002820 bool AtArgumentExpression,
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00002821 bool IsSuper,
2822 ResultBuilder &Results);
2823
2824void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
2825 bool AllowNonIdentifiers,
2826 bool AllowNestedNameSpecifiers) {
John McCall276321a2010-08-25 06:19:51 +00002827 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00002828 ResultBuilder Results(*this,
2829 AllowNestedNameSpecifiers
2830 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2831 : CodeCompletionContext::CCC_Name);
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002832 Results.EnterNewScope();
2833
2834 // Type qualifiers can come after names.
2835 Results.AddResult(Result("const"));
2836 Results.AddResult(Result("volatile"));
2837 if (getLangOptions().C99)
2838 Results.AddResult(Result("restrict"));
2839
2840 if (getLangOptions().CPlusPlus) {
2841 if (AllowNonIdentifiers) {
2842 Results.AddResult(Result("operator"));
2843 }
2844
2845 // Add nested-name-specifiers.
2846 if (AllowNestedNameSpecifiers) {
2847 Results.allowNestedNameSpecifiers();
Douglas Gregor0ac41382010-09-23 23:01:17 +00002848 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002849 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2850 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2851 CodeCompleter->includeGlobals());
Douglas Gregor0ac41382010-09-23 23:01:17 +00002852 Results.setFilter(0);
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002853 }
2854 }
2855 Results.ExitScope();
2856
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00002857 // If we're in a context where we might have an expression (rather than a
2858 // declaration), and what we've seen so far is an Objective-C type that could
2859 // be a receiver of a class message, this may be a class message send with
2860 // the initial opening bracket '[' missing. Add appropriate completions.
2861 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
2862 DS.getTypeSpecType() == DeclSpec::TST_typename &&
2863 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
2864 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
2865 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
2866 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
2867 DS.getTypeQualifiers() == 0 &&
2868 S &&
2869 (S->getFlags() & Scope::DeclScope) != 0 &&
2870 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
2871 Scope::FunctionPrototypeScope |
2872 Scope::AtCatchScope)) == 0) {
2873 ParsedType T = DS.getRepAsType();
2874 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
Douglas Gregorf86e4da2010-09-20 23:34:21 +00002875 AddClassMessageCompletions(*this, S, T, 0, 0, false, false, Results);
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00002876 }
2877
Douglas Gregor56ccce02010-08-24 04:59:56 +00002878 // Note that we intentionally suppress macro results here, since we do not
2879 // encourage using macros to produce the names of entities.
2880
Douglas Gregor0ac41382010-09-23 23:01:17 +00002881 HandleCodeCompleteResults(this, CodeCompleter,
2882 Results.getCompletionContext(),
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002883 Results.data(), Results.size());
2884}
2885
Douglas Gregor68762e72010-08-23 21:17:50 +00002886struct Sema::CodeCompleteExpressionData {
2887 CodeCompleteExpressionData(QualType PreferredType = QualType())
2888 : PreferredType(PreferredType), IntegralConstantExpression(false),
2889 ObjCCollection(false) { }
2890
2891 QualType PreferredType;
2892 bool IntegralConstantExpression;
2893 bool ObjCCollection;
2894 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2895};
2896
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002897/// \brief Perform code-completion in an expression context when we know what
2898/// type we're looking for.
Douglas Gregor85b50632010-07-28 21:50:18 +00002899///
2900/// \param IntegralConstantExpression Only permit integral constant
2901/// expressions.
Douglas Gregor68762e72010-08-23 21:17:50 +00002902void Sema::CodeCompleteExpression(Scope *S,
2903 const CodeCompleteExpressionData &Data) {
John McCall276321a2010-08-25 06:19:51 +00002904 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00002905 ResultBuilder Results(*this, CodeCompletionContext::CCC_Expression);
Douglas Gregor68762e72010-08-23 21:17:50 +00002906 if (Data.ObjCCollection)
2907 Results.setFilter(&ResultBuilder::IsObjCCollection);
2908 else if (Data.IntegralConstantExpression)
Douglas Gregor85b50632010-07-28 21:50:18 +00002909 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002910 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002911 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2912 else
2913 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor68762e72010-08-23 21:17:50 +00002914
2915 if (!Data.PreferredType.isNull())
2916 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2917
2918 // Ignore any declarations that we were told that we don't care about.
2919 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2920 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002921
2922 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00002923 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2924 CodeCompleter->includeGlobals());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002925
2926 Results.EnterNewScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002927 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002928 Results.ExitScope();
2929
Douglas Gregor55b037b2010-07-08 20:55:51 +00002930 bool PreferredTypeIsPointer = false;
Douglas Gregor68762e72010-08-23 21:17:50 +00002931 if (!Data.PreferredType.isNull())
2932 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2933 || Data.PreferredType->isMemberPointerType()
2934 || Data.PreferredType->isBlockPointerType();
Douglas Gregor55b037b2010-07-08 20:55:51 +00002935
Douglas Gregorce0e8562010-08-23 21:54:33 +00002936 if (S->getFnParent() &&
2937 !Data.ObjCCollection &&
2938 !Data.IntegralConstantExpression)
2939 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2940
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002941 if (CodeCompleter->includeMacros())
Douglas Gregor55b037b2010-07-08 20:55:51 +00002942 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002943 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor68762e72010-08-23 21:17:50 +00002944 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2945 Data.PreferredType),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00002946 Results.data(),Results.size());
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002947}
2948
Douglas Gregoreda7e542010-09-18 01:28:11 +00002949void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
2950 if (E.isInvalid())
2951 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
2952 else if (getLangOptions().ObjC1)
2953 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
Douglas Gregored0b69d2010-09-15 16:23:04 +00002954}
Douglas Gregor7aa6b222010-05-30 01:49:25 +00002955
Douglas Gregorb888acf2010-12-09 23:01:55 +00002956/// \brief The set of properties that have already been added, referenced by
2957/// property name.
2958typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
2959
Douglas Gregor9291bad2009-11-18 01:29:26 +00002960static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00002961 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002962 DeclContext *CurContext,
Douglas Gregorb888acf2010-12-09 23:01:55 +00002963 AddedPropertiesSet &AddedProperties,
Douglas Gregor9291bad2009-11-18 01:29:26 +00002964 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00002965 typedef CodeCompletionResult Result;
Douglas Gregor9291bad2009-11-18 01:29:26 +00002966
2967 // Add properties in this container.
2968 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2969 PEnd = Container->prop_end();
2970 P != PEnd;
Douglas Gregorb888acf2010-12-09 23:01:55 +00002971 ++P) {
2972 if (AddedProperties.insert(P->getIdentifier()))
2973 Results.MaybeAddResult(Result(*P, 0), CurContext);
2974 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002975
2976 // Add properties in referenced protocols.
2977 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2978 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2979 PEnd = Protocol->protocol_end();
2980 P != PEnd; ++P)
Douglas Gregorb888acf2010-12-09 23:01:55 +00002981 AddObjCProperties(*P, AllowCategories, CurContext, AddedProperties,
2982 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002983 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00002984 if (AllowCategories) {
2985 // Look through categories.
2986 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2987 Category; Category = Category->getNextClassCategory())
Douglas Gregorb888acf2010-12-09 23:01:55 +00002988 AddObjCProperties(Category, AllowCategories, CurContext,
2989 AddedProperties, Results);
Douglas Gregor5d649882009-11-18 22:32:06 +00002990 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002991
2992 // Look through protocols.
Ted Kremenek0ef508d2010-09-01 01:21:15 +00002993 for (ObjCInterfaceDecl::all_protocol_iterator
2994 I = IFace->all_referenced_protocol_begin(),
2995 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregorb888acf2010-12-09 23:01:55 +00002996 AddObjCProperties(*I, AllowCategories, CurContext, AddedProperties,
2997 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002998
2999 // Look in the superclass.
3000 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00003001 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
Douglas Gregorb888acf2010-12-09 23:01:55 +00003002 AddedProperties, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00003003 } else if (const ObjCCategoryDecl *Category
3004 = dyn_cast<ObjCCategoryDecl>(Container)) {
3005 // Look through protocols.
Ted Kremenek0ef508d2010-09-01 01:21:15 +00003006 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
3007 PEnd = Category->protocol_end();
Douglas Gregor9291bad2009-11-18 01:29:26 +00003008 P != PEnd; ++P)
Douglas Gregorb888acf2010-12-09 23:01:55 +00003009 AddObjCProperties(*P, AllowCategories, CurContext, AddedProperties,
3010 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00003011 }
3012}
3013
Douglas Gregor2436e712009-09-17 21:32:03 +00003014void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
3015 SourceLocation OpLoc,
3016 bool IsArrow) {
3017 if (!BaseE || !CodeCompleter)
3018 return;
3019
John McCall276321a2010-08-25 06:19:51 +00003020 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003021
Douglas Gregor2436e712009-09-17 21:32:03 +00003022 Expr *Base = static_cast<Expr *>(BaseE);
3023 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003024
3025 if (IsArrow) {
3026 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
3027 BaseType = Ptr->getPointeeType();
3028 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor9be0ed42010-08-26 16:36:48 +00003029 /*Do nothing*/ ;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003030 else
3031 return;
3032 }
3033
Douglas Gregor0ac41382010-09-23 23:01:17 +00003034 ResultBuilder Results(*this,
3035 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
3036 BaseType),
3037 &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00003038 Results.EnterNewScope();
3039 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor9be0ed42010-08-26 16:36:48 +00003040 // Indicate that we are performing a member access, and the cv-qualifiers
3041 // for the base object type.
3042 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
3043
Douglas Gregor9291bad2009-11-18 01:29:26 +00003044 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00003045 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00003046 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003047 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
3048 CodeCompleter->includeGlobals());
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003049
Douglas Gregor9291bad2009-11-18 01:29:26 +00003050 if (getLangOptions().CPlusPlus) {
3051 if (!Results.empty()) {
3052 // The "template" keyword can follow "->" or "." in the grammar.
3053 // However, we only want to suggest the template keyword if something
3054 // is dependent.
3055 bool IsDependent = BaseType->isDependentType();
3056 if (!IsDependent) {
3057 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
3058 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
3059 IsDependent = Ctx->isDependentContext();
3060 break;
3061 }
3062 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003063
Douglas Gregor9291bad2009-11-18 01:29:26 +00003064 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00003065 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003066 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003067 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00003068 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
3069 // Objective-C property reference.
Douglas Gregorb888acf2010-12-09 23:01:55 +00003070 AddedPropertiesSet AddedProperties;
Douglas Gregor9291bad2009-11-18 01:29:26 +00003071
3072 // Add property results based on our interface.
3073 const ObjCObjectPointerType *ObjCPtr
3074 = BaseType->getAsObjCInterfacePointerType();
3075 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregorb888acf2010-12-09 23:01:55 +00003076 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext,
3077 AddedProperties, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00003078
3079 // Add properties from the protocols in a qualified interface.
3080 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
3081 E = ObjCPtr->qual_end();
3082 I != E; ++I)
Douglas Gregorb888acf2010-12-09 23:01:55 +00003083 AddObjCProperties(*I, true, CurContext, AddedProperties, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00003084 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00003085 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00003086 // Objective-C instance variable access.
3087 ObjCInterfaceDecl *Class = 0;
3088 if (const ObjCObjectPointerType *ObjCPtr
3089 = BaseType->getAs<ObjCObjectPointerType>())
3090 Class = ObjCPtr->getInterfaceDecl();
3091 else
John McCall8b07ec22010-05-15 11:32:37 +00003092 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00003093
3094 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00003095 if (Class) {
3096 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3097 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor39982192010-08-15 06:18:01 +00003098 LookupVisibleDecls(Class, LookupMemberName, Consumer,
3099 CodeCompleter->includeGlobals());
Douglas Gregor9291bad2009-11-18 01:29:26 +00003100 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00003101 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00003102
3103 // FIXME: How do we cope with isa?
3104
3105 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003106
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003107 // Hand off the results found for code completion.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003108 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0ac41382010-09-23 23:01:17 +00003109 Results.getCompletionContext(),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003110 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00003111}
3112
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00003113void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
3114 if (!CodeCompleter)
3115 return;
3116
John McCall276321a2010-08-25 06:19:51 +00003117 typedef CodeCompletionResult Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003118 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003119 enum CodeCompletionContext::Kind ContextKind
3120 = CodeCompletionContext::CCC_Other;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00003121 switch ((DeclSpec::TST)TagSpec) {
3122 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00003123 Filter = &ResultBuilder::IsEnum;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003124 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00003125 break;
3126
3127 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00003128 Filter = &ResultBuilder::IsUnion;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003129 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00003130 break;
3131
3132 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00003133 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00003134 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003135 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00003136 break;
3137
3138 default:
3139 assert(false && "Unknown type specifier kind in CodeCompleteTag");
3140 return;
3141 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00003142
Douglas Gregor0ac41382010-09-23 23:01:17 +00003143 ResultBuilder Results(*this, ContextKind);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003144 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00003145
3146 // First pass: look for tags.
3147 Results.setFilter(Filter);
Douglas Gregor39982192010-08-15 06:18:01 +00003148 LookupVisibleDecls(S, LookupTagName, Consumer,
3149 CodeCompleter->includeGlobals());
John McCalle87beb22010-04-23 18:46:30 +00003150
Douglas Gregor39982192010-08-15 06:18:01 +00003151 if (CodeCompleter->includeGlobals()) {
3152 // Second pass: look for nested name specifiers.
3153 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
3154 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
3155 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00003156
Douglas Gregor0ac41382010-09-23 23:01:17 +00003157 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003158 Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00003159}
3160
Douglas Gregor28c78432010-08-27 17:35:51 +00003161void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00003162 ResultBuilder Results(*this, CodeCompletionContext::CCC_TypeQualifiers);
Douglas Gregor28c78432010-08-27 17:35:51 +00003163 Results.EnterNewScope();
3164 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
3165 Results.AddResult("const");
3166 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
3167 Results.AddResult("volatile");
3168 if (getLangOptions().C99 &&
3169 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
3170 Results.AddResult("restrict");
3171 Results.ExitScope();
3172 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0ac41382010-09-23 23:01:17 +00003173 Results.getCompletionContext(),
Douglas Gregor28c78432010-08-27 17:35:51 +00003174 Results.data(), Results.size());
3175}
3176
Douglas Gregord328d572009-09-21 18:10:23 +00003177void Sema::CodeCompleteCase(Scope *S) {
John McCallaab3e412010-08-25 08:40:02 +00003178 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregord328d572009-09-21 18:10:23 +00003179 return;
3180
John McCallaab3e412010-08-25 08:40:02 +00003181 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregor85b50632010-07-28 21:50:18 +00003182 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregor68762e72010-08-23 21:17:50 +00003183 CodeCompleteExpressionData Data(Switch->getCond()->getType());
3184 Data.IntegralConstantExpression = true;
3185 CodeCompleteExpression(S, Data);
Douglas Gregord328d572009-09-21 18:10:23 +00003186 return;
Douglas Gregor85b50632010-07-28 21:50:18 +00003187 }
Douglas Gregord328d572009-09-21 18:10:23 +00003188
3189 // Code-complete the cases of a switch statement over an enumeration type
3190 // by providing the list of
3191 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
3192
3193 // Determine which enumerators we have already seen in the switch statement.
3194 // FIXME: Ideally, we would also be able to look *past* the code-completion
3195 // token, in case we are code-completing in the middle of the switch and not
3196 // at the end. However, we aren't able to do so at the moment.
3197 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00003198 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00003199 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3200 SC = SC->getNextSwitchCase()) {
3201 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3202 if (!Case)
3203 continue;
3204
3205 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3206 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3207 if (EnumConstantDecl *Enumerator
3208 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3209 // We look into the AST of the case statement to determine which
3210 // enumerator was named. Alternatively, we could compute the value of
3211 // the integral constant expression, then compare it against the
3212 // values of each enumerator. However, value-based approach would not
3213 // work as well with C++ templates where enumerators declared within a
3214 // template are type- and value-dependent.
3215 EnumeratorsSeen.insert(Enumerator);
3216
Douglas Gregorf2510672009-09-21 19:57:38 +00003217 // If this is a qualified-id, keep track of the nested-name-specifier
3218 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00003219 //
3220 // switch (TagD.getKind()) {
3221 // case TagDecl::TK_enum:
3222 // break;
3223 // case XXX
3224 //
Douglas Gregorf2510672009-09-21 19:57:38 +00003225 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00003226 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3227 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003228 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00003229 }
3230 }
3231
Douglas Gregorf2510672009-09-21 19:57:38 +00003232 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3233 // If there are no prior enumerators in C++, check whether we have to
3234 // qualify the names of the enumerators that we suggest, because they
3235 // may not be visible in this scope.
3236 Qualifier = getRequiredQualification(Context, CurContext,
3237 Enum->getDeclContext());
3238
3239 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3240 }
3241
Douglas Gregord328d572009-09-21 18:10:23 +00003242 // Add any enumerators that have not yet been mentioned.
Douglas Gregor0ac41382010-09-23 23:01:17 +00003243 ResultBuilder Results(*this, CodeCompletionContext::CCC_Expression);
Douglas Gregord328d572009-09-21 18:10:23 +00003244 Results.EnterNewScope();
3245 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3246 EEnd = Enum->enumerator_end();
3247 E != EEnd; ++E) {
3248 if (EnumeratorsSeen.count(*E))
3249 continue;
3250
John McCall276321a2010-08-25 06:19:51 +00003251 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003252 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00003253 }
3254 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00003255
Douglas Gregor9eb77012009-11-07 00:00:49 +00003256 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003257 AddMacroResults(PP, Results);
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003258 HandleCodeCompleteResults(this, CodeCompleter,
3259 CodeCompletionContext::CCC_Expression,
3260 Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00003261}
3262
Douglas Gregorcabea402009-09-22 15:41:20 +00003263namespace {
3264 struct IsBetterOverloadCandidate {
3265 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00003266 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00003267
3268 public:
John McCallbc077cf2010-02-08 23:07:23 +00003269 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3270 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00003271
3272 bool
3273 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5c32be02010-08-24 20:38:10 +00003274 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00003275 }
3276 };
3277}
3278
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00003279static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3280 if (NumArgs && !Args)
3281 return true;
3282
3283 for (unsigned I = 0; I != NumArgs; ++I)
3284 if (!Args[I])
3285 return true;
3286
3287 return false;
3288}
3289
Douglas Gregorcabea402009-09-22 15:41:20 +00003290void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3291 ExprTy **ArgsIn, unsigned NumArgs) {
3292 if (!CodeCompleter)
3293 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00003294
3295 // When we're code-completing for a call, we fall back to ordinary
3296 // name code-completion whenever we can't produce specific
3297 // results. We may want to revisit this strategy in the future,
3298 // e.g., by merging the two kinds of results.
3299
Douglas Gregorcabea402009-09-22 15:41:20 +00003300 Expr *Fn = (Expr *)FnIn;
3301 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00003302
Douglas Gregorcabea402009-09-22 15:41:20 +00003303 // Ignore type-dependent call expressions entirely.
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00003304 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00003305 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003306 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00003307 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00003308 }
Douglas Gregorcabea402009-09-22 15:41:20 +00003309
John McCall57500772009-12-16 12:17:52 +00003310 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00003311 SourceLocation Loc = Fn->getExprLoc();
3312 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00003313
Douglas Gregorcabea402009-09-22 15:41:20 +00003314 // FIXME: What if we're calling something that isn't a function declaration?
3315 // FIXME: What if we're calling a pseudo-destructor?
3316 // FIXME: What if we're calling a member function?
3317
Douglas Gregorff59f672010-01-21 15:46:19 +00003318 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3319 llvm::SmallVector<ResultCandidate, 8> Results;
3320
John McCall57500772009-12-16 12:17:52 +00003321 Expr *NakedFn = Fn->IgnoreParenCasts();
3322 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3323 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3324 /*PartialOverloading=*/ true);
3325 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3326 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00003327 if (FDecl) {
Douglas Gregor6ed3eb82010-05-30 06:10:08 +00003328 if (!getLangOptions().CPlusPlus ||
3329 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorff59f672010-01-21 15:46:19 +00003330 Results.push_back(ResultCandidate(FDecl));
3331 else
John McCallb89836b2010-01-26 01:37:31 +00003332 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00003333 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3334 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00003335 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00003336 }
John McCall57500772009-12-16 12:17:52 +00003337 }
Douglas Gregorcabea402009-09-22 15:41:20 +00003338
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003339 QualType ParamType;
3340
Douglas Gregorff59f672010-01-21 15:46:19 +00003341 if (!CandidateSet.empty()) {
3342 // Sort the overload candidate set by placing the best overloads first.
3343 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00003344 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00003345
Douglas Gregorff59f672010-01-21 15:46:19 +00003346 // Add the remaining viable overload candidates as code-completion reslults.
3347 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3348 CandEnd = CandidateSet.end();
3349 Cand != CandEnd; ++Cand) {
3350 if (Cand->Viable)
3351 Results.push_back(ResultCandidate(Cand->Function));
3352 }
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003353
3354 // From the viable candidates, try to determine the type of this parameter.
3355 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3356 if (const FunctionType *FType = Results[I].getFunctionType())
3357 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3358 if (NumArgs < Proto->getNumArgs()) {
3359 if (ParamType.isNull())
3360 ParamType = Proto->getArgType(NumArgs);
3361 else if (!Context.hasSameUnqualifiedType(
3362 ParamType.getNonReferenceType(),
3363 Proto->getArgType(NumArgs).getNonReferenceType())) {
3364 ParamType = QualType();
3365 break;
3366 }
3367 }
3368 }
3369 } else {
3370 // Try to determine the parameter type from the type of the expression
3371 // being called.
3372 QualType FunctionType = Fn->getType();
3373 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3374 FunctionType = Ptr->getPointeeType();
3375 else if (const BlockPointerType *BlockPtr
3376 = FunctionType->getAs<BlockPointerType>())
3377 FunctionType = BlockPtr->getPointeeType();
3378 else if (const MemberPointerType *MemPtr
3379 = FunctionType->getAs<MemberPointerType>())
3380 FunctionType = MemPtr->getPointeeType();
3381
3382 if (const FunctionProtoType *Proto
3383 = FunctionType->getAs<FunctionProtoType>()) {
3384 if (NumArgs < Proto->getNumArgs())
3385 ParamType = Proto->getArgType(NumArgs);
3386 }
Douglas Gregorcabea402009-09-22 15:41:20 +00003387 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00003388
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003389 if (ParamType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003390 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003391 else
3392 CodeCompleteExpression(S, ParamType);
3393
Douglas Gregorc01890e2010-04-06 20:19:47 +00003394 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00003395 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3396 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00003397}
3398
John McCall48871652010-08-21 09:40:31 +00003399void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3400 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003401 if (!VD) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003402 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003403 return;
3404 }
3405
3406 CodeCompleteExpression(S, VD->getType());
3407}
3408
3409void Sema::CodeCompleteReturn(Scope *S) {
3410 QualType ResultType;
3411 if (isa<BlockDecl>(CurContext)) {
3412 if (BlockScopeInfo *BSI = getCurBlock())
3413 ResultType = BSI->ReturnType;
3414 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3415 ResultType = Function->getResultType();
3416 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3417 ResultType = Method->getResultType();
3418
3419 if (ResultType.isNull())
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003420 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003421 else
3422 CodeCompleteExpression(S, ResultType);
3423}
3424
3425void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3426 if (LHS)
3427 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3428 else
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003429 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor7aa6b222010-05-30 01:49:25 +00003430}
3431
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00003432void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00003433 bool EnteringContext) {
3434 if (!SS.getScopeRep() || !CodeCompleter)
3435 return;
3436
Douglas Gregor3545ff42009-09-21 16:56:56 +00003437 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3438 if (!Ctx)
3439 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00003440
3441 // Try to instantiate any non-dependent declaration contexts before
3442 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00003443 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00003444 return;
3445
Douglas Gregor0ac41382010-09-23 23:01:17 +00003446 ResultBuilder Results(*this, CodeCompletionContext::CCC_Name);
Douglas Gregorac322ec2010-08-27 21:18:54 +00003447 Results.EnterNewScope();
Douglas Gregor0ac41382010-09-23 23:01:17 +00003448
Douglas Gregor3545ff42009-09-21 16:56:56 +00003449 // The "template" keyword can follow "::" in the grammar, but only
3450 // put it into the grammar if the nested-name-specifier is dependent.
3451 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3452 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00003453 Results.AddResult("template");
Douglas Gregorac322ec2010-08-27 21:18:54 +00003454
3455 // Add calls to overridden virtual functions, if there are any.
3456 //
3457 // FIXME: This isn't wonderful, because we don't know whether we're actually
3458 // in a context that permits expressions. This is a general issue with
3459 // qualified-id completions.
3460 if (!EnteringContext)
3461 MaybeAddOverrideCalls(*this, Ctx, Results);
3462 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003463
Douglas Gregorac322ec2010-08-27 21:18:54 +00003464 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3465 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3466
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003467 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorac322ec2010-08-27 21:18:54 +00003468 CodeCompletionContext::CCC_Name,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003469 Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00003470}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003471
3472void Sema::CodeCompleteUsing(Scope *S) {
3473 if (!CodeCompleter)
3474 return;
3475
Douglas Gregor0ac41382010-09-23 23:01:17 +00003476 ResultBuilder Results(*this,
3477 CodeCompletionContext::CCC_PotentiallyQualifiedName,
3478 &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003479 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003480
3481 // If we aren't in class scope, we could see the "namespace" keyword.
3482 if (!S->isClassScope())
John McCall276321a2010-08-25 06:19:51 +00003483 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003484
3485 // After "using", we can see anything that would start a
3486 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003487 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003488 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3489 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003490 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003491
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003492 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0ac41382010-09-23 23:01:17 +00003493 CodeCompletionContext::CCC_PotentiallyQualifiedName,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003494 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003495}
3496
3497void Sema::CodeCompleteUsingDirective(Scope *S) {
3498 if (!CodeCompleter)
3499 return;
3500
Douglas Gregor3545ff42009-09-21 16:56:56 +00003501 // After "using namespace", we expect to see a namespace name or namespace
3502 // alias.
Douglas Gregor0ac41382010-09-23 23:01:17 +00003503 ResultBuilder Results(*this, CodeCompletionContext::CCC_Namespace,
3504 &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003505 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003506 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003507 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3508 CodeCompleter->includeGlobals());
Douglas Gregor64b12b52009-09-22 23:31:26 +00003509 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003510 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003511 CodeCompletionContext::CCC_Namespace,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003512 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003513}
3514
3515void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3516 if (!CodeCompleter)
3517 return;
3518
Douglas Gregor3545ff42009-09-21 16:56:56 +00003519 DeclContext *Ctx = (DeclContext *)S->getEntity();
3520 if (!S->getParent())
3521 Ctx = Context.getTranslationUnitDecl();
3522
Douglas Gregor0ac41382010-09-23 23:01:17 +00003523 bool SuppressedGlobalResults
3524 = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
3525
3526 ResultBuilder Results(*this,
3527 SuppressedGlobalResults
3528 ? CodeCompletionContext::CCC_Namespace
3529 : CodeCompletionContext::CCC_Other,
3530 &ResultBuilder::IsNamespace);
3531
3532 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00003533 // We only want to see those namespaces that have already been defined
3534 // within this scope, because its likely that the user is creating an
3535 // extended namespace declaration. Keep track of the most recent
3536 // definition of each namespace.
3537 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3538 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3539 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3540 NS != NSEnd; ++NS)
3541 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3542
3543 // Add the most recent definition (or extended definition) of each
3544 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00003545 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003546 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3547 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3548 NS != NSEnd; ++NS)
John McCall276321a2010-08-25 06:19:51 +00003549 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003550 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003551 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003552 }
3553
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003554 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0ac41382010-09-23 23:01:17 +00003555 Results.getCompletionContext(),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003556 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003557}
3558
3559void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3560 if (!CodeCompleter)
3561 return;
3562
Douglas Gregor3545ff42009-09-21 16:56:56 +00003563 // After "namespace", we expect to see a namespace or alias.
Douglas Gregor0ac41382010-09-23 23:01:17 +00003564 ResultBuilder Results(*this, CodeCompletionContext::CCC_Namespace,
3565 &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003566 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003567 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3568 CodeCompleter->includeGlobals());
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003569 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0ac41382010-09-23 23:01:17 +00003570 Results.getCompletionContext(),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003571 Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003572}
3573
Douglas Gregorc811ede2009-09-18 20:05:18 +00003574void Sema::CodeCompleteOperatorName(Scope *S) {
3575 if (!CodeCompleter)
3576 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00003577
John McCall276321a2010-08-25 06:19:51 +00003578 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00003579 ResultBuilder Results(*this, CodeCompletionContext::CCC_Type,
3580 &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003581 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00003582
Douglas Gregor3545ff42009-09-21 16:56:56 +00003583 // Add the names of overloadable operators.
3584#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3585 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00003586 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00003587#include "clang/Basic/OperatorKinds.def"
3588
3589 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00003590 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00003591 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor39982192010-08-15 06:18:01 +00003592 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3593 CodeCompleter->includeGlobals());
Douglas Gregor3545ff42009-09-21 16:56:56 +00003594
3595 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003596 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00003597 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00003598
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003599 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor39982192010-08-15 06:18:01 +00003600 CodeCompletionContext::CCC_Type,
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003601 Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00003602}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00003603
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003604void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
Alexis Hunt1d792652011-01-08 20:30:50 +00003605 CXXCtorInitializer** Initializers,
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003606 unsigned NumInitializers) {
3607 CXXConstructorDecl *Constructor
3608 = static_cast<CXXConstructorDecl *>(ConstructorD);
3609 if (!Constructor)
3610 return;
3611
Douglas Gregor0ac41382010-09-23 23:01:17 +00003612 ResultBuilder Results(*this,
3613 CodeCompletionContext::CCC_PotentiallyQualifiedName);
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003614 Results.EnterNewScope();
3615
3616 // Fill in any already-initialized fields or base classes.
3617 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3618 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3619 for (unsigned I = 0; I != NumInitializers; ++I) {
3620 if (Initializers[I]->isBaseInitializer())
3621 InitializedBases.insert(
3622 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3623 else
Francois Pichetd583da02010-12-04 09:14:42 +00003624 InitializedFields.insert(cast<FieldDecl>(
3625 Initializers[I]->getAnyMember()));
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003626 }
3627
3628 // Add completions for base classes.
Douglas Gregor99129ef2010-08-29 19:27:27 +00003629 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003630 CXXRecordDecl *ClassDecl = Constructor->getParent();
3631 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3632 BaseEnd = ClassDecl->bases_end();
3633 Base != BaseEnd; ++Base) {
Douglas Gregor99129ef2010-08-29 19:27:27 +00003634 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3635 SawLastInitializer
3636 = NumInitializers > 0 &&
3637 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3638 Context.hasSameUnqualifiedType(Base->getType(),
3639 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003640 continue;
Douglas Gregor99129ef2010-08-29 19:27:27 +00003641 }
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003642
3643 CodeCompletionString *Pattern = new CodeCompletionString;
3644 Pattern->AddTypedTextChunk(
3645 Base->getType().getAsString(Context.PrintingPolicy));
3646 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3647 Pattern->AddPlaceholderChunk("args");
3648 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor99129ef2010-08-29 19:27:27 +00003649 Results.AddResult(CodeCompletionResult(Pattern,
3650 SawLastInitializer? CCP_NextInitializer
3651 : CCP_MemberDeclaration));
3652 SawLastInitializer = false;
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003653 }
3654
3655 // Add completions for virtual base classes.
3656 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3657 BaseEnd = ClassDecl->vbases_end();
3658 Base != BaseEnd; ++Base) {
Douglas Gregor99129ef2010-08-29 19:27:27 +00003659 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3660 SawLastInitializer
3661 = NumInitializers > 0 &&
3662 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3663 Context.hasSameUnqualifiedType(Base->getType(),
3664 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003665 continue;
Douglas Gregor99129ef2010-08-29 19:27:27 +00003666 }
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003667
3668 CodeCompletionString *Pattern = new CodeCompletionString;
3669 Pattern->AddTypedTextChunk(
3670 Base->getType().getAsString(Context.PrintingPolicy));
3671 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3672 Pattern->AddPlaceholderChunk("args");
3673 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor99129ef2010-08-29 19:27:27 +00003674 Results.AddResult(CodeCompletionResult(Pattern,
3675 SawLastInitializer? CCP_NextInitializer
3676 : CCP_MemberDeclaration));
3677 SawLastInitializer = false;
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003678 }
3679
3680 // Add completions for members.
3681 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3682 FieldEnd = ClassDecl->field_end();
3683 Field != FieldEnd; ++Field) {
Douglas Gregor99129ef2010-08-29 19:27:27 +00003684 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3685 SawLastInitializer
3686 = NumInitializers > 0 &&
Francois Pichetd583da02010-12-04 09:14:42 +00003687 Initializers[NumInitializers - 1]->isAnyMemberInitializer() &&
3688 Initializers[NumInitializers - 1]->getAnyMember() == *Field;
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003689 continue;
Douglas Gregor99129ef2010-08-29 19:27:27 +00003690 }
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003691
3692 if (!Field->getDeclName())
3693 continue;
3694
3695 CodeCompletionString *Pattern = new CodeCompletionString;
3696 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3697 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3698 Pattern->AddPlaceholderChunk("args");
3699 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor99129ef2010-08-29 19:27:27 +00003700 Results.AddResult(CodeCompletionResult(Pattern,
3701 SawLastInitializer? CCP_NextInitializer
Douglas Gregorf3af3112010-09-09 21:42:20 +00003702 : CCP_MemberDeclaration,
3703 CXCursor_MemberRef));
Douglas Gregor99129ef2010-08-29 19:27:27 +00003704 SawLastInitializer = false;
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003705 }
3706 Results.ExitScope();
3707
Douglas Gregor0ac41382010-09-23 23:01:17 +00003708 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregoreaeeca92010-08-28 00:00:50 +00003709 Results.data(), Results.size());
3710}
3711
Douglas Gregorf1934162010-01-13 21:24:21 +00003712// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3713// true or false.
3714#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003715static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003716 ResultBuilder &Results,
3717 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003718 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003719 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003720 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003721
3722 CodeCompletionString *Pattern = 0;
3723 if (LangOpts.ObjC2) {
3724 // @dynamic
3725 Pattern = new CodeCompletionString;
3726 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3727 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3728 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003729 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003730
3731 // @synthesize
3732 Pattern = new CodeCompletionString;
3733 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3734 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3735 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00003736 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003737 }
3738}
3739
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003740static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00003741 ResultBuilder &Results,
3742 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003743 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003744
3745 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00003746 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003747
3748 if (LangOpts.ObjC2) {
3749 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00003750 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003751
3752 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00003753 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003754
3755 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00003756 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00003757 }
3758}
3759
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003760static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003761 typedef CodeCompletionResult Result;
Douglas Gregorf1934162010-01-13 21:24:21 +00003762 CodeCompletionString *Pattern = 0;
3763
3764 // @class name ;
3765 Pattern = new CodeCompletionString;
3766 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3767 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorf4c33342010-05-28 00:22:41 +00003768 Pattern->AddPlaceholderChunk("name");
Douglas Gregor78a21012010-01-14 16:01:26 +00003769 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003770
Douglas Gregorf4c33342010-05-28 00:22:41 +00003771 if (Results.includeCodePatterns()) {
3772 // @interface name
3773 // FIXME: Could introduce the whole pattern, including superclasses and
3774 // such.
3775 Pattern = new CodeCompletionString;
3776 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3777 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3778 Pattern->AddPlaceholderChunk("class");
3779 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003780
Douglas Gregorf4c33342010-05-28 00:22:41 +00003781 // @protocol name
3782 Pattern = new CodeCompletionString;
3783 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3784 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3785 Pattern->AddPlaceholderChunk("protocol");
3786 Results.AddResult(Result(Pattern));
3787
3788 // @implementation name
3789 Pattern = new CodeCompletionString;
3790 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3791 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3792 Pattern->AddPlaceholderChunk("class");
3793 Results.AddResult(Result(Pattern));
3794 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003795
3796 // @compatibility_alias name
3797 Pattern = new CodeCompletionString;
3798 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3799 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3800 Pattern->AddPlaceholderChunk("alias");
3801 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3802 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00003803 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003804}
3805
John McCall48871652010-08-21 09:40:31 +00003806void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorf48706c2009-12-07 09:27:33 +00003807 bool InInterface) {
John McCall276321a2010-08-25 06:19:51 +00003808 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00003809 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorf48706c2009-12-07 09:27:33 +00003810 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00003811 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003812 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003813 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003814 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00003815 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003816 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00003817 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003818 HandleCodeCompleteResults(this, CodeCompleter,
3819 CodeCompletionContext::CCC_Other,
3820 Results.data(),Results.size());
Douglas Gregorf48706c2009-12-07 09:27:33 +00003821}
3822
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003823static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003824 typedef CodeCompletionResult Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003825 CodeCompletionString *Pattern = 0;
3826
3827 // @encode ( type-name )
3828 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003829 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003830 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3831 Pattern->AddPlaceholderChunk("type-name");
3832 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003833 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003834
3835 // @protocol ( protocol-name )
3836 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003837 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003838 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3839 Pattern->AddPlaceholderChunk("protocol-name");
3840 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003841 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003842
3843 // @selector ( selector )
3844 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003845 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003846 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3847 Pattern->AddPlaceholderChunk("selector");
3848 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00003849 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003850}
3851
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003852static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003853 typedef CodeCompletionResult Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003854 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00003855
Douglas Gregorf4c33342010-05-28 00:22:41 +00003856 if (Results.includeCodePatterns()) {
3857 // @try { statements } @catch ( declaration ) { statements } @finally
3858 // { statements }
3859 Pattern = new CodeCompletionString;
3860 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3861 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3862 Pattern->AddPlaceholderChunk("statements");
3863 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3864 Pattern->AddTextChunk("@catch");
3865 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3866 Pattern->AddPlaceholderChunk("parameter");
3867 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3868 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3869 Pattern->AddPlaceholderChunk("statements");
3870 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3871 Pattern->AddTextChunk("@finally");
3872 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3873 Pattern->AddPlaceholderChunk("statements");
3874 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3875 Results.AddResult(Result(Pattern));
3876 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003877
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003878 // @throw
3879 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00003880 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00003881 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003882 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00003883 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00003884
Douglas Gregorf4c33342010-05-28 00:22:41 +00003885 if (Results.includeCodePatterns()) {
3886 // @synchronized ( expression ) { statements }
3887 Pattern = new CodeCompletionString;
3888 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3889 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3890 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3891 Pattern->AddPlaceholderChunk("expression");
3892 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3893 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3894 Pattern->AddPlaceholderChunk("statements");
3895 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3896 Results.AddResult(Result(Pattern));
3897 }
Douglas Gregorf1934162010-01-13 21:24:21 +00003898}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003899
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003900static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00003901 ResultBuilder &Results,
3902 bool NeedAt) {
John McCall276321a2010-08-25 06:19:51 +00003903 typedef CodeCompletionResult Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00003904 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3905 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3906 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003907 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00003908 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00003909}
3910
3911void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00003912 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor48d46252010-01-13 21:54:15 +00003913 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003914 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00003915 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003916 HandleCodeCompleteResults(this, CodeCompleter,
3917 CodeCompletionContext::CCC_Other,
3918 Results.data(),Results.size());
Douglas Gregor48d46252010-01-13 21:54:15 +00003919}
3920
3921void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00003922 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorf1934162010-01-13 21:24:21 +00003923 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003924 AddObjCStatementResults(Results, false);
3925 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003926 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003927 HandleCodeCompleteResults(this, CodeCompleter,
3928 CodeCompletionContext::CCC_Other,
3929 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003930}
3931
3932void Sema::CodeCompleteObjCAtExpression(Scope *S) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00003933 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003934 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00003935 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003936 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00003937 HandleCodeCompleteResults(this, CodeCompleter,
3938 CodeCompletionContext::CCC_Other,
3939 Results.data(),Results.size());
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00003940}
3941
Douglas Gregore6078da2009-11-19 00:14:45 +00003942/// \brief Determine whether the addition of the given flag to an Objective-C
3943/// property's attributes will cause a conflict.
3944static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3945 // Check if we've already added this flag.
3946 if (Attributes & NewFlag)
3947 return true;
3948
3949 Attributes |= NewFlag;
3950
3951 // Check for collisions with "readonly".
3952 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3953 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3954 ObjCDeclSpec::DQ_PR_assign |
3955 ObjCDeclSpec::DQ_PR_copy |
3956 ObjCDeclSpec::DQ_PR_retain)))
3957 return true;
3958
3959 // Check for more than one of { assign, copy, retain }.
3960 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3961 ObjCDeclSpec::DQ_PR_copy |
3962 ObjCDeclSpec::DQ_PR_retain);
3963 if (AssignCopyRetMask &&
3964 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3965 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3966 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3967 return true;
3968
3969 return false;
3970}
3971
Douglas Gregor36029f42009-11-18 23:08:07 +00003972void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00003973 if (!CodeCompleter)
3974 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00003975
Steve Naroff936354c2009-10-08 21:55:05 +00003976 unsigned Attributes = ODS.getPropertyAttributes();
3977
John McCall276321a2010-08-25 06:19:51 +00003978 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00003979 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Steve Naroff936354c2009-10-08 21:55:05 +00003980 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00003981 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall276321a2010-08-25 06:19:51 +00003982 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003983 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall276321a2010-08-25 06:19:51 +00003984 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003985 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall276321a2010-08-25 06:19:51 +00003986 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003987 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall276321a2010-08-25 06:19:51 +00003988 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003989 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall276321a2010-08-25 06:19:51 +00003990 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003991 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall276321a2010-08-25 06:19:51 +00003992 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00003993 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003994 CodeCompletionString *Setter = new CodeCompletionString;
3995 Setter->AddTypedTextChunk("setter");
3996 Setter->AddTextChunk(" = ");
3997 Setter->AddPlaceholderChunk("method");
John McCall276321a2010-08-25 06:19:51 +00003998 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00003999 }
Douglas Gregore6078da2009-11-19 00:14:45 +00004000 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00004001 CodeCompletionString *Getter = new CodeCompletionString;
4002 Getter->AddTypedTextChunk("getter");
4003 Getter->AddTextChunk(" = ");
4004 Getter->AddPlaceholderChunk("method");
John McCall276321a2010-08-25 06:19:51 +00004005 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00004006 }
Steve Naroff936354c2009-10-08 21:55:05 +00004007 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004008 HandleCodeCompleteResults(this, CodeCompleter,
4009 CodeCompletionContext::CCC_Other,
4010 Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00004011}
Steve Naroffeae65032009-11-07 02:08:14 +00004012
Douglas Gregorc8537c52009-11-19 07:41:15 +00004013/// \brief Descripts the kind of Objective-C method that we want to find
4014/// via code completion.
4015enum ObjCMethodKind {
4016 MK_Any, //< Any kind of method, provided it means other specified criteria.
4017 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
4018 MK_OneArgSelector //< One-argument selector.
4019};
4020
Douglas Gregor67c692c2010-08-26 15:07:07 +00004021static bool isAcceptableObjCSelector(Selector Sel,
4022 ObjCMethodKind WantKind,
4023 IdentifierInfo **SelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004024 unsigned NumSelIdents,
4025 bool AllowSameLength = true) {
Douglas Gregor67c692c2010-08-26 15:07:07 +00004026 if (NumSelIdents > Sel.getNumArgs())
4027 return false;
4028
4029 switch (WantKind) {
4030 case MK_Any: break;
4031 case MK_ZeroArgSelector: return Sel.isUnarySelector();
4032 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
4033 }
4034
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004035 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
4036 return false;
4037
Douglas Gregor67c692c2010-08-26 15:07:07 +00004038 for (unsigned I = 0; I != NumSelIdents; ++I)
4039 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
4040 return false;
4041
4042 return true;
4043}
4044
Douglas Gregorc8537c52009-11-19 07:41:15 +00004045static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
4046 ObjCMethodKind WantKind,
4047 IdentifierInfo **SelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004048 unsigned NumSelIdents,
4049 bool AllowSameLength = true) {
Douglas Gregor67c692c2010-08-26 15:07:07 +00004050 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004051 NumSelIdents, AllowSameLength);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004052}
Douglas Gregor1154e272010-09-16 16:06:31 +00004053
4054namespace {
4055 /// \brief A set of selectors, which is used to avoid introducing multiple
4056 /// completions with the same selector into the result set.
4057 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
4058}
4059
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004060/// \brief Add all of the Objective-C methods in the given Objective-C
4061/// container to the set of results.
4062///
4063/// The container will be a class, protocol, category, or implementation of
4064/// any of the above. This mether will recurse to include methods from
4065/// the superclasses of classes along with their categories, protocols, and
4066/// implementations.
4067///
4068/// \param Container the container in which we'll look to find methods.
4069///
4070/// \param WantInstance whether to add instance methods (only); if false, this
4071/// routine will add factory methods (only).
4072///
4073/// \param CurContext the context in which we're performing the lookup that
4074/// finds methods.
4075///
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004076/// \param AllowSameLength Whether we allow a method to be added to the list
4077/// when it has the same number of parameters as we have selector identifiers.
4078///
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004079/// \param Results the structure into which we'll add results.
4080static void AddObjCMethods(ObjCContainerDecl *Container,
4081 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00004082 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00004083 IdentifierInfo **SelIdents,
4084 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004085 DeclContext *CurContext,
Douglas Gregor1154e272010-09-16 16:06:31 +00004086 VisitedSelectorSet &Selectors,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004087 bool AllowSameLength,
Douglas Gregor416b5752010-08-25 01:08:01 +00004088 ResultBuilder &Results,
4089 bool InOriginalClass = true) {
John McCall276321a2010-08-25 06:19:51 +00004090 typedef CodeCompletionResult Result;
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004091 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4092 MEnd = Container->meth_end();
4093 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00004094 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4095 // Check whether the selector identifiers we've been given are a
4096 // subset of the identifiers for this particular method.
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004097 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents,
4098 AllowSameLength))
Douglas Gregor1b605f72009-11-19 01:08:35 +00004099 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00004100
Douglas Gregor1154e272010-09-16 16:06:31 +00004101 if (!Selectors.insert((*M)->getSelector()))
4102 continue;
4103
Douglas Gregor1b605f72009-11-19 01:08:35 +00004104 Result R = Result(*M, 0);
4105 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00004106 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor416b5752010-08-25 01:08:01 +00004107 if (!InOriginalClass)
4108 R.Priority += CCD_InBaseClass;
Douglas Gregor1b605f72009-11-19 01:08:35 +00004109 Results.MaybeAddResult(R, CurContext);
4110 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004111 }
4112
Douglas Gregorf37c9492010-09-16 15:34:59 +00004113 // Visit the protocols of protocols.
4114 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4115 const ObjCList<ObjCProtocolDecl> &Protocols
4116 = Protocol->getReferencedProtocols();
4117 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4118 E = Protocols.end();
4119 I != E; ++I)
4120 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004121 CurContext, Selectors, AllowSameLength, Results, false);
Douglas Gregorf37c9492010-09-16 15:34:59 +00004122 }
4123
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004124 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
4125 if (!IFace)
4126 return;
4127
4128 // Add methods in protocols.
4129 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
4130 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4131 E = Protocols.end();
4132 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00004133 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004134 CurContext, Selectors, AllowSameLength, Results, false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004135
4136 // Add methods in categories.
4137 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
4138 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00004139 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004140 NumSelIdents, CurContext, Selectors, AllowSameLength,
4141 Results, InOriginalClass);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004142
4143 // Add a categories protocol methods.
4144 const ObjCList<ObjCProtocolDecl> &Protocols
4145 = CatDecl->getReferencedProtocols();
4146 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4147 E = Protocols.end();
4148 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00004149 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004150 NumSelIdents, CurContext, Selectors, AllowSameLength,
4151 Results, false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004152
4153 // Add methods in category implementations.
4154 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00004155 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004156 NumSelIdents, CurContext, Selectors, AllowSameLength,
4157 Results, InOriginalClass);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004158 }
4159
4160 // Add methods in superclass.
4161 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00004162 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004163 SelIdents, NumSelIdents, CurContext, Selectors,
4164 AllowSameLength, Results, false);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004165
4166 // Add methods in our implementation, if any.
4167 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00004168 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004169 NumSelIdents, CurContext, Selectors, AllowSameLength,
4170 Results, InOriginalClass);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004171}
4172
4173
Douglas Gregor87e92752010-12-21 17:34:17 +00004174void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl) {
John McCall276321a2010-08-25 06:19:51 +00004175 typedef CodeCompletionResult Result;
Douglas Gregorc8537c52009-11-19 07:41:15 +00004176
4177 // Try to find the interface where getters might live.
John McCall48871652010-08-21 09:40:31 +00004178 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004179 if (!Class) {
4180 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00004181 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00004182 Class = Category->getClassInterface();
4183
4184 if (!Class)
4185 return;
4186 }
4187
4188 // Find all of the potential getters.
Douglas Gregor0ac41382010-09-23 23:01:17 +00004189 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004190 Results.EnterNewScope();
4191
Douglas Gregor1154e272010-09-16 16:06:31 +00004192 VisitedSelectorSet Selectors;
4193 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004194 /*AllowSameLength=*/true, Results);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004195 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004196 HandleCodeCompleteResults(this, CodeCompleter,
4197 CodeCompletionContext::CCC_Other,
4198 Results.data(),Results.size());
Douglas Gregorc8537c52009-11-19 07:41:15 +00004199}
4200
Douglas Gregor87e92752010-12-21 17:34:17 +00004201void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl) {
John McCall276321a2010-08-25 06:19:51 +00004202 typedef CodeCompletionResult Result;
Douglas Gregorc8537c52009-11-19 07:41:15 +00004203
4204 // Try to find the interface where setters might live.
4205 ObjCInterfaceDecl *Class
John McCall48871652010-08-21 09:40:31 +00004206 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004207 if (!Class) {
4208 if (ObjCCategoryDecl *Category
John McCall48871652010-08-21 09:40:31 +00004209 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregorc8537c52009-11-19 07:41:15 +00004210 Class = Category->getClassInterface();
4211
4212 if (!Class)
4213 return;
4214 }
4215
4216 // Find all of the potential getters.
Douglas Gregor0ac41382010-09-23 23:01:17 +00004217 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004218 Results.EnterNewScope();
4219
Douglas Gregor1154e272010-09-16 16:06:31 +00004220 VisitedSelectorSet Selectors;
4221 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004222 Selectors, /*AllowSameLength=*/true, Results);
Douglas Gregorc8537c52009-11-19 07:41:15 +00004223
4224 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004225 HandleCodeCompleteResults(this, CodeCompleter,
4226 CodeCompletionContext::CCC_Other,
4227 Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004228}
4229
Douglas Gregor99fa2642010-08-24 01:06:58 +00004230void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall276321a2010-08-25 06:19:51 +00004231 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00004232 ResultBuilder Results(*this, CodeCompletionContext::CCC_Type);
Douglas Gregor99fa2642010-08-24 01:06:58 +00004233 Results.EnterNewScope();
4234
4235 // Add context-sensitive, Objective-C parameter-passing keywords.
4236 bool AddedInOut = false;
4237 if ((DS.getObjCDeclQualifier() &
4238 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4239 Results.AddResult("in");
4240 Results.AddResult("inout");
4241 AddedInOut = true;
4242 }
4243 if ((DS.getObjCDeclQualifier() &
4244 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4245 Results.AddResult("out");
4246 if (!AddedInOut)
4247 Results.AddResult("inout");
4248 }
4249 if ((DS.getObjCDeclQualifier() &
4250 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4251 ObjCDeclSpec::DQ_Oneway)) == 0) {
4252 Results.AddResult("bycopy");
4253 Results.AddResult("byref");
4254 Results.AddResult("oneway");
4255 }
4256
4257 // Add various builtin type names and specifiers.
4258 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4259 Results.ExitScope();
4260
4261 // Add the various type names
4262 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4263 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4264 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4265 CodeCompleter->includeGlobals());
4266
4267 if (CodeCompleter->includeMacros())
4268 AddMacroResults(PP, Results);
4269
4270 HandleCodeCompleteResults(this, CodeCompleter,
4271 CodeCompletionContext::CCC_Type,
4272 Results.data(), Results.size());
4273}
4274
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004275/// \brief When we have an expression with type "id", we may assume
4276/// that it has some more-specific class type based on knowledge of
4277/// common uses of Objective-C. This routine returns that class type,
4278/// or NULL if no better result could be determined.
4279static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregored0b69d2010-09-15 16:23:04 +00004280 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004281 if (!Msg)
4282 return 0;
4283
4284 Selector Sel = Msg->getSelector();
4285 if (Sel.isNull())
4286 return 0;
4287
4288 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4289 if (!Id)
4290 return 0;
4291
4292 ObjCMethodDecl *Method = Msg->getMethodDecl();
4293 if (!Method)
4294 return 0;
4295
4296 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00004297 ObjCInterfaceDecl *IFace = 0;
4298 switch (Msg->getReceiverKind()) {
4299 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00004300 if (const ObjCObjectType *ObjType
4301 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4302 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00004303 break;
4304
4305 case ObjCMessageExpr::Instance: {
4306 QualType T = Msg->getInstanceReceiver()->getType();
4307 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4308 IFace = Ptr->getInterfaceDecl();
4309 break;
4310 }
4311
4312 case ObjCMessageExpr::SuperInstance:
4313 case ObjCMessageExpr::SuperClass:
4314 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004315 }
4316
4317 if (!IFace)
4318 return 0;
4319
4320 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4321 if (Method->isInstanceMethod())
4322 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4323 .Case("retain", IFace)
4324 .Case("autorelease", IFace)
4325 .Case("copy", IFace)
4326 .Case("copyWithZone", IFace)
4327 .Case("mutableCopy", IFace)
4328 .Case("mutableCopyWithZone", IFace)
4329 .Case("awakeFromCoder", IFace)
4330 .Case("replacementObjectFromCoder", IFace)
4331 .Case("class", IFace)
4332 .Case("classForCoder", IFace)
4333 .Case("superclass", Super)
4334 .Default(0);
4335
4336 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4337 .Case("new", IFace)
4338 .Case("alloc", IFace)
4339 .Case("allocWithZone", IFace)
4340 .Case("class", IFace)
4341 .Case("superclass", Super)
4342 .Default(0);
4343}
4344
Douglas Gregor6fc04132010-08-27 15:10:57 +00004345// Add a special completion for a message send to "super", which fills in the
4346// most likely case of forwarding all of our arguments to the superclass
4347// function.
4348///
4349/// \param S The semantic analysis object.
4350///
4351/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4352/// the "super" keyword. Otherwise, we just need to provide the arguments.
4353///
4354/// \param SelIdents The identifiers in the selector that have already been
4355/// provided as arguments for a send to "super".
4356///
4357/// \param NumSelIdents The number of identifiers in \p SelIdents.
4358///
4359/// \param Results The set of results to augment.
4360///
4361/// \returns the Objective-C method declaration that would be invoked by
4362/// this "super" completion. If NULL, no completion was added.
4363static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4364 IdentifierInfo **SelIdents,
4365 unsigned NumSelIdents,
4366 ResultBuilder &Results) {
4367 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4368 if (!CurMethod)
4369 return 0;
4370
4371 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4372 if (!Class)
4373 return 0;
4374
4375 // Try to find a superclass method with the same selector.
4376 ObjCMethodDecl *SuperMethod = 0;
4377 while ((Class = Class->getSuperClass()) && !SuperMethod)
4378 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4379 CurMethod->isInstanceMethod());
4380
4381 if (!SuperMethod)
4382 return 0;
4383
4384 // Check whether the superclass method has the same signature.
4385 if (CurMethod->param_size() != SuperMethod->param_size() ||
4386 CurMethod->isVariadic() != SuperMethod->isVariadic())
4387 return 0;
4388
4389 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4390 CurPEnd = CurMethod->param_end(),
4391 SuperP = SuperMethod->param_begin();
4392 CurP != CurPEnd; ++CurP, ++SuperP) {
4393 // Make sure the parameter types are compatible.
4394 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4395 (*SuperP)->getType()))
4396 return 0;
4397
4398 // Make sure we have a parameter name to forward!
4399 if (!(*CurP)->getIdentifier())
4400 return 0;
4401 }
4402
4403 // We have a superclass method. Now, form the send-to-super completion.
4404 CodeCompletionString *Pattern = new CodeCompletionString;
4405
4406 // Give this completion a return type.
4407 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4408
4409 // If we need the "super" keyword, add it (plus some spacing).
4410 if (NeedSuperKeyword) {
4411 Pattern->AddTypedTextChunk("super");
4412 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4413 }
4414
4415 Selector Sel = CurMethod->getSelector();
4416 if (Sel.isUnarySelector()) {
4417 if (NeedSuperKeyword)
4418 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4419 else
4420 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4421 } else {
4422 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4423 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4424 if (I > NumSelIdents)
4425 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4426
4427 if (I < NumSelIdents)
4428 Pattern->AddInformativeChunk(
4429 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4430 else if (NeedSuperKeyword || I > NumSelIdents) {
4431 Pattern->AddTextChunk(
4432 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4433 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4434 } else {
4435 Pattern->AddTypedTextChunk(
4436 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4437 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4438 }
4439 }
4440 }
4441
4442 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4443 SuperMethod->isInstanceMethod()
4444 ? CXCursor_ObjCInstanceMethodDecl
4445 : CXCursor_ObjCClassMethodDecl));
4446 return SuperMethod;
4447}
4448
Douglas Gregora817a192010-05-27 23:06:34 +00004449void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall276321a2010-08-25 06:19:51 +00004450 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00004451 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCMessageReceiver,
4452 &ResultBuilder::IsObjCMessageReceiver);
Douglas Gregora817a192010-05-27 23:06:34 +00004453
Douglas Gregora817a192010-05-27 23:06:34 +00004454 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4455 Results.EnterNewScope();
Douglas Gregor39982192010-08-15 06:18:01 +00004456 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4457 CodeCompleter->includeGlobals());
Douglas Gregora817a192010-05-27 23:06:34 +00004458
4459 // If we are in an Objective-C method inside a class that has a superclass,
4460 // add "super" as an option.
4461 if (ObjCMethodDecl *Method = getCurMethodDecl())
4462 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor6fc04132010-08-27 15:10:57 +00004463 if (Iface->getSuperClass()) {
Douglas Gregora817a192010-05-27 23:06:34 +00004464 Results.AddResult(Result("super"));
Douglas Gregor6fc04132010-08-27 15:10:57 +00004465
4466 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4467 }
Douglas Gregora817a192010-05-27 23:06:34 +00004468
4469 Results.ExitScope();
4470
4471 if (CodeCompleter->includeMacros())
4472 AddMacroResults(PP, Results);
Douglas Gregor50832e02010-09-20 22:39:41 +00004473 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004474 Results.data(), Results.size());
Douglas Gregora817a192010-05-27 23:06:34 +00004475
4476}
4477
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004478void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4479 IdentifierInfo **SelIdents,
Douglas Gregorf86e4da2010-09-20 23:34:21 +00004480 unsigned NumSelIdents,
4481 bool AtArgumentExpression) {
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004482 ObjCInterfaceDecl *CDecl = 0;
4483 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4484 // Figure out which interface we're in.
4485 CDecl = CurMethod->getClassInterface();
4486 if (!CDecl)
4487 return;
4488
4489 // Find the superclass of this class.
4490 CDecl = CDecl->getSuperClass();
4491 if (!CDecl)
4492 return;
4493
4494 if (CurMethod->isInstanceMethod()) {
4495 // We are inside an instance method, which means that the message
4496 // send [super ...] is actually calling an instance method on the
Douglas Gregor392a84b2010-10-13 21:24:53 +00004497 // current object.
4498 return CodeCompleteObjCInstanceMessage(S, 0,
Douglas Gregor6fc04132010-08-27 15:10:57 +00004499 SelIdents, NumSelIdents,
Douglas Gregorf86e4da2010-09-20 23:34:21 +00004500 AtArgumentExpression,
Douglas Gregor392a84b2010-10-13 21:24:53 +00004501 CDecl);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004502 }
4503
4504 // Fall through to send to the superclass in CDecl.
4505 } else {
4506 // "super" may be the name of a type or variable. Figure out which
4507 // it is.
4508 IdentifierInfo *Super = &Context.Idents.get("super");
4509 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4510 LookupOrdinaryName);
4511 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4512 // "super" names an interface. Use it.
4513 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00004514 if (const ObjCObjectType *Iface
4515 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4516 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004517 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4518 // "super" names an unresolved type; we can't be more specific.
4519 } else {
4520 // Assume that "super" names some kind of value and parse that way.
4521 CXXScopeSpec SS;
4522 UnqualifiedId id;
4523 id.setIdentifier(Super, SuperLoc);
John McCalldadc5752010-08-24 06:29:42 +00004524 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004525 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
Douglas Gregorf86e4da2010-09-20 23:34:21 +00004526 SelIdents, NumSelIdents,
4527 AtArgumentExpression);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004528 }
4529
4530 // Fall through
4531 }
4532
John McCallba7bf592010-08-24 05:47:05 +00004533 ParsedType Receiver;
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004534 if (CDecl)
John McCallba7bf592010-08-24 05:47:05 +00004535 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004536 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregorf86e4da2010-09-20 23:34:21 +00004537 NumSelIdents, AtArgumentExpression,
4538 /*IsSuper=*/true);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004539}
4540
Douglas Gregor74661272010-09-21 00:03:25 +00004541/// \brief Given a set of code-completion results for the argument of a message
4542/// send, determine the preferred type (if any) for that argument expression.
4543static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
4544 unsigned NumSelIdents) {
4545 typedef CodeCompletionResult Result;
4546 ASTContext &Context = Results.getSema().Context;
4547
4548 QualType PreferredType;
4549 unsigned BestPriority = CCP_Unlikely * 2;
4550 Result *ResultsData = Results.data();
4551 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
4552 Result &R = ResultsData[I];
4553 if (R.Kind == Result::RK_Declaration &&
4554 isa<ObjCMethodDecl>(R.Declaration)) {
4555 if (R.Priority <= BestPriority) {
4556 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
4557 if (NumSelIdents <= Method->param_size()) {
4558 QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
4559 ->getType();
4560 if (R.Priority < BestPriority || PreferredType.isNull()) {
4561 BestPriority = R.Priority;
4562 PreferredType = MyPreferredType;
4563 } else if (!Context.hasSameUnqualifiedType(PreferredType,
4564 MyPreferredType)) {
4565 PreferredType = QualType();
4566 }
4567 }
4568 }
4569 }
4570 }
4571
4572 return PreferredType;
4573}
4574
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004575static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4576 ParsedType Receiver,
4577 IdentifierInfo **SelIdents,
4578 unsigned NumSelIdents,
Douglas Gregorf86e4da2010-09-20 23:34:21 +00004579 bool AtArgumentExpression,
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004580 bool IsSuper,
4581 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00004582 typedef CodeCompletionResult Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00004583 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004584
Douglas Gregor8ce33212009-11-17 17:59:40 +00004585 // If the given name refers to an interface type, retrieve the
4586 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004587 if (Receiver) {
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004588 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004589 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00004590 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4591 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00004592 }
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004593
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004594 // Add all of the factory methods in this Objective-C class, its protocols,
4595 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00004596 Results.EnterNewScope();
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004597
Douglas Gregor6fc04132010-08-27 15:10:57 +00004598 // If this is a send-to-super, try to add the special "super" send
4599 // completion.
4600 if (IsSuper) {
4601 if (ObjCMethodDecl *SuperMethod
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004602 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4603 Results))
Douglas Gregor6fc04132010-08-27 15:10:57 +00004604 Results.Ignore(SuperMethod);
4605 }
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004606
Douglas Gregorc2cb2e22010-08-27 15:29:55 +00004607 // If we're inside an Objective-C method definition, prefer its selector to
4608 // others.
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004609 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregorc2cb2e22010-08-27 15:29:55 +00004610 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004611
Douglas Gregor1154e272010-09-16 16:06:31 +00004612 VisitedSelectorSet Selectors;
Douglas Gregor6285f752010-04-06 16:40:00 +00004613 if (CDecl)
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004614 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004615 SemaRef.CurContext, Selectors, AtArgumentExpression,
4616 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00004617 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00004618 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004619
Douglas Gregord720daf2010-04-06 17:30:22 +00004620 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00004621 // pool from the AST file.
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004622 if (SemaRef.ExternalSource) {
4623 for (uint32_t I = 0,
4624 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall75b960e2010-06-01 09:23:16 +00004625 I != N; ++I) {
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004626 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4627 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00004628 continue;
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004629
4630 SemaRef.ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00004631 }
4632 }
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004633
4634 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4635 MEnd = SemaRef.MethodPool.end();
Sebastian Redl75d8a322010-08-02 23:18:59 +00004636 M != MEnd; ++M) {
4637 for (ObjCMethodList *MethList = &M->second.second;
4638 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00004639 MethList = MethList->Next) {
4640 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4641 NumSelIdents))
4642 continue;
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004643
Douglas Gregor6285f752010-04-06 16:40:00 +00004644 Result R(MethList->Method, 0);
4645 R.StartParameter = NumSelIdents;
4646 R.AllParametersAreInformative = false;
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004647 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor6285f752010-04-06 16:40:00 +00004648 }
4649 }
4650 }
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004651
4652 Results.ExitScope();
4653}
Douglas Gregor6285f752010-04-06 16:40:00 +00004654
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004655void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4656 IdentifierInfo **SelIdents,
4657 unsigned NumSelIdents,
Douglas Gregorf86e4da2010-09-20 23:34:21 +00004658 bool AtArgumentExpression,
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00004659 bool IsSuper) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00004660 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorf86e4da2010-09-20 23:34:21 +00004661 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
4662 AtArgumentExpression, IsSuper, Results);
Douglas Gregor74661272010-09-21 00:03:25 +00004663
4664 // If we're actually at the argument expression (rather than prior to the
4665 // selector), we're actually performing code completion for an expression.
4666 // Determine whether we have a single, best method. If so, we can
4667 // code-complete the expression using the corresponding parameter type as
4668 // our preferred type, improving completion results.
4669 if (AtArgumentExpression) {
4670 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
4671 NumSelIdents);
4672 if (PreferredType.isNull())
4673 CodeCompleteOrdinaryName(S, PCC_Expression);
4674 else
4675 CodeCompleteExpression(S, PreferredType);
4676 return;
4677 }
4678
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004679 HandleCodeCompleteResults(this, CodeCompleter,
4680 CodeCompletionContext::CCC_Other,
Douglas Gregor6fc04132010-08-27 15:10:57 +00004681 Results.data(), Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00004682}
4683
Douglas Gregor1b605f72009-11-19 01:08:35 +00004684void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4685 IdentifierInfo **SelIdents,
Douglas Gregor6fc04132010-08-27 15:10:57 +00004686 unsigned NumSelIdents,
Douglas Gregorf86e4da2010-09-20 23:34:21 +00004687 bool AtArgumentExpression,
Douglas Gregor392a84b2010-10-13 21:24:53 +00004688 ObjCInterfaceDecl *Super) {
John McCall276321a2010-08-25 06:19:51 +00004689 typedef CodeCompletionResult Result;
Steve Naroffeae65032009-11-07 02:08:14 +00004690
4691 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00004692
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004693 // If necessary, apply function/array conversion to the receiver.
4694 // C99 6.7.5.3p[7,8].
Douglas Gregored0b69d2010-09-15 16:23:04 +00004695 if (RecExpr)
4696 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor392a84b2010-10-13 21:24:53 +00004697 QualType ReceiverType = RecExpr? RecExpr->getType()
4698 : Super? Context.getObjCObjectPointerType(
4699 Context.getObjCInterfaceType(Super))
4700 : Context.getObjCIdType();
Steve Naroffeae65032009-11-07 02:08:14 +00004701
Douglas Gregordc520b02010-11-08 21:12:30 +00004702 // If we're messaging an expression with type "id" or "Class", check
4703 // whether we know something special about the receiver that allows
4704 // us to assume a more-specific receiver type.
4705 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4706 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
4707 if (ReceiverType->isObjCClassType())
4708 return CodeCompleteObjCClassMessage(S,
4709 ParsedType::make(Context.getObjCInterfaceType(IFace)),
4710 SelIdents, NumSelIdents,
4711 AtArgumentExpression, Super);
4712
4713 ReceiverType = Context.getObjCObjectPointerType(
4714 Context.getObjCInterfaceType(IFace));
4715 }
4716
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004717 // Build the set of methods we can see.
Douglas Gregor0ac41382010-09-23 23:01:17 +00004718 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004719 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00004720
Douglas Gregor6fc04132010-08-27 15:10:57 +00004721 // If this is a send-to-super, try to add the special "super" send
4722 // completion.
Douglas Gregor392a84b2010-10-13 21:24:53 +00004723 if (Super) {
Douglas Gregor6fc04132010-08-27 15:10:57 +00004724 if (ObjCMethodDecl *SuperMethod
4725 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4726 Results))
4727 Results.Ignore(SuperMethod);
4728 }
4729
Douglas Gregorc2cb2e22010-08-27 15:29:55 +00004730 // If we're inside an Objective-C method definition, prefer its selector to
4731 // others.
4732 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4733 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00004734
Douglas Gregor1154e272010-09-16 16:06:31 +00004735 // Keep track of the selectors we've already added.
4736 VisitedSelectorSet Selectors;
4737
Douglas Gregora3329fa2009-11-18 00:06:18 +00004738 // Handle messages to Class. This really isn't a message to an instance
4739 // method, so we treat it the same way we would treat a message send to a
4740 // class method.
4741 if (ReceiverType->isObjCClassType() ||
4742 ReceiverType->isObjCQualifiedClassType()) {
4743 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4744 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00004745 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004746 CurContext, Selectors, AtArgumentExpression, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00004747 }
4748 }
4749 // Handle messages to a qualified ID ("id<foo>").
4750 else if (const ObjCObjectPointerType *QualID
4751 = ReceiverType->getAsObjCQualifiedIdType()) {
4752 // Search protocols for instance methods.
4753 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4754 E = QualID->qual_end();
4755 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00004756 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004757 Selectors, AtArgumentExpression, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00004758 }
4759 // Handle messages to a pointer to interface type.
4760 else if (const ObjCObjectPointerType *IFacePtr
4761 = ReceiverType->getAsObjCInterfacePointerType()) {
4762 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00004763 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004764 NumSelIdents, CurContext, Selectors, AtArgumentExpression,
4765 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00004766
4767 // Search protocols for instance methods.
4768 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4769 E = IFacePtr->qual_end();
4770 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00004771 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregorb4a7c032010-11-17 21:36:08 +00004772 Selectors, AtArgumentExpression, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00004773 }
Douglas Gregor6285f752010-04-06 16:40:00 +00004774 // Handle messages to "id".
4775 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00004776 // We're messaging "id", so provide all instance methods we know
4777 // about as code-completion results.
4778
4779 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00004780 // pool from the AST file.
Douglas Gregord720daf2010-04-06 17:30:22 +00004781 if (ExternalSource) {
John McCall75b960e2010-06-01 09:23:16 +00004782 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4783 I != N; ++I) {
4784 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00004785 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregord720daf2010-04-06 17:30:22 +00004786 continue;
4787
Sebastian Redl75d8a322010-08-02 23:18:59 +00004788 ReadMethodPool(Sel);
Douglas Gregord720daf2010-04-06 17:30:22 +00004789 }
4790 }
4791
Sebastian Redl75d8a322010-08-02 23:18:59 +00004792 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4793 MEnd = MethodPool.end();
4794 M != MEnd; ++M) {
4795 for (ObjCMethodList *MethList = &M->second.first;
4796 MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00004797 MethList = MethList->Next) {
4798 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4799 NumSelIdents))
4800 continue;
Douglas Gregor1154e272010-09-16 16:06:31 +00004801
4802 if (!Selectors.insert(MethList->Method->getSelector()))
4803 continue;
4804
Douglas Gregor6285f752010-04-06 16:40:00 +00004805 Result R(MethList->Method, 0);
4806 R.StartParameter = NumSelIdents;
4807 R.AllParametersAreInformative = false;
4808 Results.MaybeAddResult(R, CurContext);
4809 }
4810 }
4811 }
Steve Naroffeae65032009-11-07 02:08:14 +00004812 Results.ExitScope();
Douglas Gregor74661272010-09-21 00:03:25 +00004813
4814
4815 // If we're actually at the argument expression (rather than prior to the
4816 // selector), we're actually performing code completion for an expression.
4817 // Determine whether we have a single, best method. If so, we can
4818 // code-complete the expression using the corresponding parameter type as
4819 // our preferred type, improving completion results.
4820 if (AtArgumentExpression) {
4821 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
4822 NumSelIdents);
4823 if (PreferredType.isNull())
4824 CodeCompleteOrdinaryName(S, PCC_Expression);
4825 else
4826 CodeCompleteExpression(S, PreferredType);
4827 return;
4828 }
4829
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004830 HandleCodeCompleteResults(this, CodeCompleter,
4831 CodeCompletionContext::CCC_Other,
4832 Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00004833}
Douglas Gregorbaf69612009-11-18 04:19:12 +00004834
Douglas Gregor68762e72010-08-23 21:17:50 +00004835void Sema::CodeCompleteObjCForCollection(Scope *S,
4836 DeclGroupPtrTy IterationVar) {
4837 CodeCompleteExpressionData Data;
4838 Data.ObjCCollection = true;
4839
4840 if (IterationVar.getAsOpaquePtr()) {
4841 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4842 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4843 if (*I)
4844 Data.IgnoreDecls.push_back(*I);
4845 }
4846 }
4847
4848 CodeCompleteExpression(S, Data);
4849}
4850
Douglas Gregor67c692c2010-08-26 15:07:07 +00004851void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4852 unsigned NumSelIdents) {
4853 // If we have an external source, load the entire class method
4854 // pool from the AST file.
4855 if (ExternalSource) {
4856 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4857 I != N; ++I) {
4858 Selector Sel = ExternalSource->GetExternalSelector(I);
4859 if (Sel.isNull() || MethodPool.count(Sel))
4860 continue;
4861
4862 ReadMethodPool(Sel);
4863 }
4864 }
4865
Douglas Gregor0ac41382010-09-23 23:01:17 +00004866 ResultBuilder Results(*this, CodeCompletionContext::CCC_SelectorName);
Douglas Gregor67c692c2010-08-26 15:07:07 +00004867 Results.EnterNewScope();
4868 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4869 MEnd = MethodPool.end();
4870 M != MEnd; ++M) {
4871
4872 Selector Sel = M->first;
4873 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4874 continue;
4875
4876 CodeCompletionString *Pattern = new CodeCompletionString;
4877 if (Sel.isUnarySelector()) {
4878 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4879 Results.AddResult(Pattern);
4880 continue;
4881 }
4882
Douglas Gregor9ac1ad12010-08-26 16:46:39 +00004883 std::string Accumulator;
Douglas Gregor67c692c2010-08-26 15:07:07 +00004884 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor9ac1ad12010-08-26 16:46:39 +00004885 if (I == NumSelIdents) {
4886 if (!Accumulator.empty()) {
4887 Pattern->AddInformativeChunk(Accumulator);
4888 Accumulator.clear();
4889 }
4890 }
4891
4892 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4893 Accumulator += ':';
Douglas Gregor67c692c2010-08-26 15:07:07 +00004894 }
Douglas Gregor9ac1ad12010-08-26 16:46:39 +00004895 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor67c692c2010-08-26 15:07:07 +00004896 Results.AddResult(Pattern);
4897 }
4898 Results.ExitScope();
4899
4900 HandleCodeCompleteResults(this, CodeCompleter,
4901 CodeCompletionContext::CCC_SelectorName,
4902 Results.data(), Results.size());
4903}
4904
Douglas Gregorbaf69612009-11-18 04:19:12 +00004905/// \brief Add all of the protocol declarations that we find in the given
4906/// (translation unit) context.
4907static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004908 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00004909 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00004910 typedef CodeCompletionResult Result;
Douglas Gregorbaf69612009-11-18 04:19:12 +00004911
4912 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4913 DEnd = Ctx->decls_end();
4914 D != DEnd; ++D) {
4915 // Record any protocols we find.
4916 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004917 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004918 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004919
4920 // Record any forward-declared protocols we find.
4921 if (ObjCForwardProtocolDecl *Forward
4922 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4923 for (ObjCForwardProtocolDecl::protocol_iterator
4924 P = Forward->protocol_begin(),
4925 PEnd = Forward->protocol_end();
4926 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004927 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00004928 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004929 }
4930 }
4931}
4932
4933void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4934 unsigned NumProtocols) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00004935 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCProtocolName);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004936
Douglas Gregora3b23b02010-12-09 21:44:02 +00004937 if (CodeCompleter && CodeCompleter->includeGlobals()) {
4938 Results.EnterNewScope();
4939
4940 // Tell the result set to ignore all of the protocols we have
4941 // already seen.
4942 // FIXME: This doesn't work when caching code-completion results.
4943 for (unsigned I = 0; I != NumProtocols; ++I)
4944 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4945 Protocols[I].second))
4946 Results.Ignore(Protocol);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004947
Douglas Gregora3b23b02010-12-09 21:44:02 +00004948 // Add all protocols.
4949 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4950 Results);
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004951
Douglas Gregora3b23b02010-12-09 21:44:02 +00004952 Results.ExitScope();
4953 }
4954
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004955 HandleCodeCompleteResults(this, CodeCompleter,
4956 CodeCompletionContext::CCC_ObjCProtocolName,
4957 Results.data(),Results.size());
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004958}
4959
4960void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00004961 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCProtocolName);
Douglas Gregor5b4671c2009-11-18 04:49:41 +00004962
Douglas Gregora3b23b02010-12-09 21:44:02 +00004963 if (CodeCompleter && CodeCompleter->includeGlobals()) {
4964 Results.EnterNewScope();
4965
4966 // Add all protocols.
4967 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4968 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00004969
Douglas Gregora3b23b02010-12-09 21:44:02 +00004970 Results.ExitScope();
4971 }
4972
Douglas Gregor00c37ef2010-08-11 21:23:17 +00004973 HandleCodeCompleteResults(this, CodeCompleter,
4974 CodeCompletionContext::CCC_ObjCProtocolName,
4975 Results.data(),Results.size());
Douglas Gregorbaf69612009-11-18 04:19:12 +00004976}
Douglas Gregor49c22a72009-11-18 16:26:39 +00004977
4978/// \brief Add all of the Objective-C interface declarations that we find in
4979/// the given (translation unit) context.
4980static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4981 bool OnlyForwardDeclarations,
4982 bool OnlyUnimplemented,
4983 ResultBuilder &Results) {
John McCall276321a2010-08-25 06:19:51 +00004984 typedef CodeCompletionResult Result;
Douglas Gregor49c22a72009-11-18 16:26:39 +00004985
4986 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4987 DEnd = Ctx->decls_end();
4988 D != DEnd; ++D) {
Douglas Gregor1c283312010-08-11 12:19:30 +00004989 // Record any interfaces we find.
4990 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4991 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4992 (!OnlyUnimplemented || !Class->getImplementation()))
4993 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00004994
4995 // Record any forward-declared interfaces we find.
4996 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4997 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregor1c283312010-08-11 12:19:30 +00004998 C != CEnd; ++C)
4999 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
5000 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
5001 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregorfc59ce12010-01-14 16:14:35 +00005002 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00005003 }
5004 }
5005}
5006
5007void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00005008 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor49c22a72009-11-18 16:26:39 +00005009 Results.EnterNewScope();
5010
5011 // Add all classes.
5012 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
5013 false, Results);
5014
5015 Results.ExitScope();
Douglas Gregor0ac41382010-09-23 23:01:17 +00005016 // FIXME: Add a special context for this, use cached global completion
5017 // results.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005018 HandleCodeCompleteResults(this, CodeCompleter,
5019 CodeCompletionContext::CCC_Other,
5020 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00005021}
5022
Douglas Gregorb2ccf012010-04-15 22:33:43 +00005023void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
5024 SourceLocation ClassNameLoc) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00005025 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor49c22a72009-11-18 16:26:39 +00005026 Results.EnterNewScope();
5027
5028 // Make sure that we ignore the class we're currently defining.
5029 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00005030 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005031 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00005032 Results.Ignore(CurClass);
5033
5034 // Add all classes.
5035 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5036 false, Results);
5037
5038 Results.ExitScope();
Douglas Gregor0ac41382010-09-23 23:01:17 +00005039 // FIXME: Add a special context for this, use cached global completion
5040 // results.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005041 HandleCodeCompleteResults(this, CodeCompleter,
5042 CodeCompletionContext::CCC_Other,
5043 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00005044}
5045
5046void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00005047 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor49c22a72009-11-18 16:26:39 +00005048 Results.EnterNewScope();
5049
5050 // Add all unimplemented classes.
5051 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5052 true, Results);
5053
5054 Results.ExitScope();
Douglas Gregor0ac41382010-09-23 23:01:17 +00005055 // FIXME: Add a special context for this, use cached global completion
5056 // results.
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005057 HandleCodeCompleteResults(this, CodeCompleter,
5058 CodeCompletionContext::CCC_Other,
5059 Results.data(),Results.size());
Douglas Gregor49c22a72009-11-18 16:26:39 +00005060}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005061
5062void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00005063 IdentifierInfo *ClassName,
5064 SourceLocation ClassNameLoc) {
John McCall276321a2010-08-25 06:19:51 +00005065 typedef CodeCompletionResult Result;
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005066
Douglas Gregor0ac41382010-09-23 23:01:17 +00005067 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005068
5069 // Ignore any categories we find that have already been implemented by this
5070 // interface.
5071 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5072 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00005073 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005074 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
5075 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
5076 Category = Category->getNextClassCategory())
5077 CategoryNames.insert(Category->getIdentifier());
5078
5079 // Add all of the categories we know about.
5080 Results.EnterNewScope();
5081 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
5082 for (DeclContext::decl_iterator D = TU->decls_begin(),
5083 DEnd = TU->decls_end();
5084 D != DEnd; ++D)
5085 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
5086 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00005087 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005088 Results.ExitScope();
5089
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005090 HandleCodeCompleteResults(this, CodeCompleter,
5091 CodeCompletionContext::CCC_Other,
5092 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005093}
5094
5095void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00005096 IdentifierInfo *ClassName,
5097 SourceLocation ClassNameLoc) {
John McCall276321a2010-08-25 06:19:51 +00005098 typedef CodeCompletionResult Result;
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005099
5100 // Find the corresponding interface. If we couldn't find the interface, the
5101 // program itself is ill-formed. However, we'll try to be helpful still by
5102 // providing the list of all of the categories we know about.
5103 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00005104 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005105 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
5106 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00005107 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005108
Douglas Gregor0ac41382010-09-23 23:01:17 +00005109 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005110
5111 // Add all of the categories that have have corresponding interface
5112 // declarations in this class and any of its superclasses, except for
5113 // already-implemented categories in the class itself.
5114 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5115 Results.EnterNewScope();
5116 bool IgnoreImplemented = true;
5117 while (Class) {
5118 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
5119 Category = Category->getNextClassCategory())
5120 if ((!IgnoreImplemented || !Category->getImplementation()) &&
5121 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00005122 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005123
5124 Class = Class->getSuperClass();
5125 IgnoreImplemented = false;
5126 }
5127 Results.ExitScope();
5128
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005129 HandleCodeCompleteResults(this, CodeCompleter,
5130 CodeCompletionContext::CCC_Other,
5131 Results.data(),Results.size());
Douglas Gregor5d34fd32009-11-18 19:08:43 +00005132}
Douglas Gregor5d649882009-11-18 22:32:06 +00005133
John McCall48871652010-08-21 09:40:31 +00005134void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall276321a2010-08-25 06:19:51 +00005135 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00005136 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor5d649882009-11-18 22:32:06 +00005137
5138 // Figure out where this @synthesize lives.
5139 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00005140 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00005141 if (!Container ||
5142 (!isa<ObjCImplementationDecl>(Container) &&
5143 !isa<ObjCCategoryImplDecl>(Container)))
5144 return;
5145
5146 // Ignore any properties that have already been implemented.
5147 for (DeclContext::decl_iterator D = Container->decls_begin(),
5148 DEnd = Container->decls_end();
5149 D != DEnd; ++D)
5150 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
5151 Results.Ignore(PropertyImpl->getPropertyDecl());
5152
5153 // Add any properties that we find.
Douglas Gregorb888acf2010-12-09 23:01:55 +00005154 AddedPropertiesSet AddedProperties;
Douglas Gregor5d649882009-11-18 22:32:06 +00005155 Results.EnterNewScope();
5156 if (ObjCImplementationDecl *ClassImpl
5157 = dyn_cast<ObjCImplementationDecl>(Container))
5158 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
Douglas Gregorb888acf2010-12-09 23:01:55 +00005159 AddedProperties, Results);
Douglas Gregor5d649882009-11-18 22:32:06 +00005160 else
5161 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
Douglas Gregorb888acf2010-12-09 23:01:55 +00005162 false, CurContext, AddedProperties, Results);
Douglas Gregor5d649882009-11-18 22:32:06 +00005163 Results.ExitScope();
5164
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005165 HandleCodeCompleteResults(this, CodeCompleter,
5166 CodeCompletionContext::CCC_Other,
5167 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00005168}
5169
5170void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
5171 IdentifierInfo *PropertyName,
John McCall48871652010-08-21 09:40:31 +00005172 Decl *ObjCImpDecl) {
John McCall276321a2010-08-25 06:19:51 +00005173 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00005174 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor5d649882009-11-18 22:32:06 +00005175
5176 // Figure out where this @synthesize lives.
5177 ObjCContainerDecl *Container
John McCall48871652010-08-21 09:40:31 +00005178 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor5d649882009-11-18 22:32:06 +00005179 if (!Container ||
5180 (!isa<ObjCImplementationDecl>(Container) &&
5181 !isa<ObjCCategoryImplDecl>(Container)))
5182 return;
5183
5184 // Figure out which interface we're looking into.
5185 ObjCInterfaceDecl *Class = 0;
5186 if (ObjCImplementationDecl *ClassImpl
5187 = dyn_cast<ObjCImplementationDecl>(Container))
5188 Class = ClassImpl->getClassInterface();
5189 else
5190 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
5191 ->getClassInterface();
5192
5193 // Add all of the instance variables in this class and its superclasses.
5194 Results.EnterNewScope();
5195 for(; Class; Class = Class->getSuperClass()) {
5196 // FIXME: We could screen the type of each ivar for compatibility with
5197 // the property, but is that being too paternal?
5198 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
5199 IVarEnd = Class->ivar_end();
5200 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00005201 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00005202 }
5203 Results.ExitScope();
5204
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005205 HandleCodeCompleteResults(this, CodeCompleter,
5206 CodeCompletionContext::CCC_Other,
5207 Results.data(),Results.size());
Douglas Gregor5d649882009-11-18 22:32:06 +00005208}
Douglas Gregor636a61e2010-04-07 00:21:17 +00005209
Douglas Gregor416b5752010-08-25 01:08:01 +00005210// Mapping from selectors to the methods that implement that selector, along
5211// with the "in original class" flag.
5212typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
5213 KnownMethodsMap;
Douglas Gregor636a61e2010-04-07 00:21:17 +00005214
5215/// \brief Find all of the methods that reside in the given container
5216/// (and its superclasses, protocols, etc.) that meet the given
5217/// criteria. Insert those methods into the map of known methods,
5218/// indexed by selector so they can be easily found.
5219static void FindImplementableMethods(ASTContext &Context,
5220 ObjCContainerDecl *Container,
5221 bool WantInstanceMethods,
5222 QualType ReturnType,
Douglas Gregor416b5752010-08-25 01:08:01 +00005223 KnownMethodsMap &KnownMethods,
5224 bool InOriginalClass = true) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00005225 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
5226 // Recurse into protocols.
5227 const ObjCList<ObjCProtocolDecl> &Protocols
5228 = IFace->getReferencedProtocols();
5229 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005230 E = Protocols.end();
Douglas Gregor636a61e2010-04-07 00:21:17 +00005231 I != E; ++I)
5232 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005233 KnownMethods, InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005234
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005235 // Add methods from any class extensions and categories.
5236 for (const ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
5237 Cat = Cat->getNextClassCategory())
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +00005238 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
5239 WantInstanceMethods, ReturnType,
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005240 KnownMethods, false);
5241
5242 // Visit the superclass.
5243 if (IFace->getSuperClass())
5244 FindImplementableMethods(Context, IFace->getSuperClass(),
5245 WantInstanceMethods, ReturnType,
5246 KnownMethods, false);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005247 }
5248
5249 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5250 // Recurse into protocols.
5251 const ObjCList<ObjCProtocolDecl> &Protocols
5252 = Category->getReferencedProtocols();
5253 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005254 E = Protocols.end();
Douglas Gregor636a61e2010-04-07 00:21:17 +00005255 I != E; ++I)
5256 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005257 KnownMethods, InOriginalClass);
5258
5259 // If this category is the original class, jump to the interface.
5260 if (InOriginalClass && Category->getClassInterface())
5261 FindImplementableMethods(Context, Category->getClassInterface(),
5262 WantInstanceMethods, ReturnType, KnownMethods,
5263 false);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005264 }
5265
5266 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5267 // Recurse into protocols.
5268 const ObjCList<ObjCProtocolDecl> &Protocols
5269 = Protocol->getReferencedProtocols();
5270 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5271 E = Protocols.end();
5272 I != E; ++I)
5273 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005274 KnownMethods, false);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005275 }
5276
5277 // Add methods in this container. This operation occurs last because
5278 // we want the methods from this container to override any methods
5279 // we've previously seen with the same selector.
5280 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
5281 MEnd = Container->meth_end();
5282 M != MEnd; ++M) {
5283 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
5284 if (!ReturnType.isNull() &&
5285 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
5286 continue;
5287
Douglas Gregor416b5752010-08-25 01:08:01 +00005288 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005289 }
5290 }
5291}
5292
5293void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5294 bool IsInstanceMethod,
John McCallba7bf592010-08-24 05:47:05 +00005295 ParsedType ReturnTy,
John McCall48871652010-08-21 09:40:31 +00005296 Decl *IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00005297 // Determine the return type of the method we're declaring, if
5298 // provided.
5299 QualType ReturnType = GetTypeFromParser(ReturnTy);
5300
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005301 // Determine where we should start searching for methods.
5302 ObjCContainerDecl *SearchDecl = 0;
Douglas Gregor636a61e2010-04-07 00:21:17 +00005303 bool IsInImplementation = false;
John McCall48871652010-08-21 09:40:31 +00005304 if (Decl *D = IDecl) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00005305 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5306 SearchDecl = Impl->getClassInterface();
Douglas Gregor636a61e2010-04-07 00:21:17 +00005307 IsInImplementation = true;
5308 } else if (ObjCCategoryImplDecl *CatImpl
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005309 = dyn_cast<ObjCCategoryImplDecl>(D)) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00005310 SearchDecl = CatImpl->getCategoryDecl();
Douglas Gregor636a61e2010-04-07 00:21:17 +00005311 IsInImplementation = true;
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005312 } else
Douglas Gregor636a61e2010-04-07 00:21:17 +00005313 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005314 }
5315
5316 if (!SearchDecl && S) {
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005317 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity()))
Douglas Gregor636a61e2010-04-07 00:21:17 +00005318 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005319 }
5320
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005321 if (!SearchDecl) {
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005322 HandleCodeCompleteResults(this, CodeCompleter,
5323 CodeCompletionContext::CCC_Other,
5324 0, 0);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005325 return;
5326 }
5327
5328 // Find all of the methods that we could declare/implement here.
5329 KnownMethodsMap KnownMethods;
5330 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
Douglas Gregor1b035bb2010-10-18 18:21:28 +00005331 ReturnType, KnownMethods);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005332
Douglas Gregor636a61e2010-04-07 00:21:17 +00005333 // Add declarations or definitions for each of the known methods.
John McCall276321a2010-08-25 06:19:51 +00005334 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00005335 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor636a61e2010-04-07 00:21:17 +00005336 Results.EnterNewScope();
5337 PrintingPolicy Policy(Context.PrintingPolicy);
5338 Policy.AnonymousTagLocations = false;
5339 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5340 MEnd = KnownMethods.end();
5341 M != MEnd; ++M) {
Douglas Gregor416b5752010-08-25 01:08:01 +00005342 ObjCMethodDecl *Method = M->second.first;
Douglas Gregor636a61e2010-04-07 00:21:17 +00005343 CodeCompletionString *Pattern = new CodeCompletionString;
5344
5345 // If the result type was not already provided, add it to the
5346 // pattern as (type).
5347 if (ReturnType.isNull()) {
5348 std::string TypeStr;
5349 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5350 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5351 Pattern->AddTextChunk(TypeStr);
5352 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5353 }
5354
5355 Selector Sel = Method->getSelector();
5356
5357 // Add the first part of the selector to the pattern.
5358 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5359
5360 // Add parameters to the pattern.
5361 unsigned I = 0;
5362 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5363 PEnd = Method->param_end();
5364 P != PEnd; (void)++P, ++I) {
5365 // Add the part of the selector name.
5366 if (I == 0)
Douglas Gregor8e3e8742010-10-18 21:05:04 +00005367 Pattern->AddTypedTextChunk(":");
Douglas Gregor636a61e2010-04-07 00:21:17 +00005368 else if (I < Sel.getNumArgs()) {
5369 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor8e3e8742010-10-18 21:05:04 +00005370 Pattern->AddTypedTextChunk((Sel.getIdentifierInfoForSlot(I)->getName()
5371 + ":").str());
Douglas Gregor636a61e2010-04-07 00:21:17 +00005372 } else
5373 break;
5374
5375 // Add the parameter type.
5376 std::string TypeStr;
5377 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5378 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5379 Pattern->AddTextChunk(TypeStr);
5380 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5381
5382 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregor400f5972010-08-31 05:13:43 +00005383 Pattern->AddTextChunk(Id->getName());
Douglas Gregor636a61e2010-04-07 00:21:17 +00005384 }
5385
5386 if (Method->isVariadic()) {
5387 if (Method->param_size() > 0)
5388 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5389 Pattern->AddTextChunk("...");
Douglas Gregor400f5972010-08-31 05:13:43 +00005390 }
Douglas Gregor636a61e2010-04-07 00:21:17 +00005391
Douglas Gregord37c59d2010-05-28 00:57:46 +00005392 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregor636a61e2010-04-07 00:21:17 +00005393 // We will be defining the method here, so add a compound statement.
5394 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5395 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5396 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5397 if (!Method->getResultType()->isVoidType()) {
5398 // If the result type is not void, add a return clause.
5399 Pattern->AddTextChunk("return");
5400 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5401 Pattern->AddPlaceholderChunk("expression");
5402 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5403 } else
5404 Pattern->AddPlaceholderChunk("statements");
5405
5406 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5407 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5408 }
5409
Douglas Gregor416b5752010-08-25 01:08:01 +00005410 unsigned Priority = CCP_CodePattern;
5411 if (!M->second.second)
5412 Priority += CCD_InBaseClass;
5413
5414 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor7116a8c2010-08-17 16:06:07 +00005415 Method->isInstanceMethod()
5416 ? CXCursor_ObjCInstanceMethodDecl
5417 : CXCursor_ObjCClassMethodDecl));
Douglas Gregor636a61e2010-04-07 00:21:17 +00005418 }
5419
5420 Results.ExitScope();
5421
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005422 HandleCodeCompleteResults(this, CodeCompleter,
5423 CodeCompletionContext::CCC_Other,
5424 Results.data(),Results.size());
Douglas Gregor636a61e2010-04-07 00:21:17 +00005425}
Douglas Gregor95887f92010-07-08 23:20:03 +00005426
5427void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5428 bool IsInstanceMethod,
Douglas Gregor45879692010-07-08 23:37:41 +00005429 bool AtParameterName,
John McCallba7bf592010-08-24 05:47:05 +00005430 ParsedType ReturnTy,
Douglas Gregor95887f92010-07-08 23:20:03 +00005431 IdentifierInfo **SelIdents,
5432 unsigned NumSelIdents) {
Douglas Gregor95887f92010-07-08 23:20:03 +00005433 // If we have an external source, load the entire class method
Sebastian Redld44cd6a2010-08-18 23:57:06 +00005434 // pool from the AST file.
Douglas Gregor95887f92010-07-08 23:20:03 +00005435 if (ExternalSource) {
5436 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5437 I != N; ++I) {
5438 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redl75d8a322010-08-02 23:18:59 +00005439 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor95887f92010-07-08 23:20:03 +00005440 continue;
Sebastian Redl75d8a322010-08-02 23:18:59 +00005441
5442 ReadMethodPool(Sel);
Douglas Gregor95887f92010-07-08 23:20:03 +00005443 }
5444 }
5445
5446 // Build the set of methods we can see.
John McCall276321a2010-08-25 06:19:51 +00005447 typedef CodeCompletionResult Result;
Douglas Gregor0ac41382010-09-23 23:01:17 +00005448 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor95887f92010-07-08 23:20:03 +00005449
5450 if (ReturnTy)
5451 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redl75d8a322010-08-02 23:18:59 +00005452
Douglas Gregor95887f92010-07-08 23:20:03 +00005453 Results.EnterNewScope();
Sebastian Redl75d8a322010-08-02 23:18:59 +00005454 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5455 MEnd = MethodPool.end();
5456 M != MEnd; ++M) {
5457 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5458 &M->second.second;
5459 MethList && MethList->Method;
Douglas Gregor95887f92010-07-08 23:20:03 +00005460 MethList = MethList->Next) {
5461 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5462 NumSelIdents))
5463 continue;
5464
Douglas Gregor45879692010-07-08 23:37:41 +00005465 if (AtParameterName) {
5466 // Suggest parameter names we've seen before.
5467 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5468 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5469 if (Param->getIdentifier()) {
5470 CodeCompletionString *Pattern = new CodeCompletionString;
5471 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5472 Results.AddResult(Pattern);
5473 }
5474 }
5475
5476 continue;
5477 }
5478
Douglas Gregor95887f92010-07-08 23:20:03 +00005479 Result R(MethList->Method, 0);
5480 R.StartParameter = NumSelIdents;
5481 R.AllParametersAreInformative = false;
5482 R.DeclaringEntity = true;
5483 Results.MaybeAddResult(R, CurContext);
5484 }
5485 }
5486
5487 Results.ExitScope();
Douglas Gregor00c37ef2010-08-11 21:23:17 +00005488 HandleCodeCompleteResults(this, CodeCompleter,
5489 CodeCompletionContext::CCC_Other,
5490 Results.data(),Results.size());
Douglas Gregor95887f92010-07-08 23:20:03 +00005491}
Douglas Gregorb14904c2010-08-13 22:48:40 +00005492
Douglas Gregorec00a262010-08-24 22:20:20 +00005493void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00005494 ResultBuilder Results(*this,
5495 CodeCompletionContext::CCC_PreprocessorDirective);
Douglas Gregor3a7ad252010-08-24 19:08:16 +00005496 Results.EnterNewScope();
5497
5498 // #if <condition>
5499 CodeCompletionString *Pattern = new CodeCompletionString;
5500 Pattern->AddTypedTextChunk("if");
5501 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5502 Pattern->AddPlaceholderChunk("condition");
5503 Results.AddResult(Pattern);
5504
5505 // #ifdef <macro>
5506 Pattern = new CodeCompletionString;
5507 Pattern->AddTypedTextChunk("ifdef");
5508 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5509 Pattern->AddPlaceholderChunk("macro");
5510 Results.AddResult(Pattern);
5511
5512 // #ifndef <macro>
5513 Pattern = new CodeCompletionString;
5514 Pattern->AddTypedTextChunk("ifndef");
5515 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5516 Pattern->AddPlaceholderChunk("macro");
5517 Results.AddResult(Pattern);
5518
5519 if (InConditional) {
5520 // #elif <condition>
5521 Pattern = new CodeCompletionString;
5522 Pattern->AddTypedTextChunk("elif");
5523 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5524 Pattern->AddPlaceholderChunk("condition");
5525 Results.AddResult(Pattern);
5526
5527 // #else
5528 Pattern = new CodeCompletionString;
5529 Pattern->AddTypedTextChunk("else");
5530 Results.AddResult(Pattern);
5531
5532 // #endif
5533 Pattern = new CodeCompletionString;
5534 Pattern->AddTypedTextChunk("endif");
5535 Results.AddResult(Pattern);
5536 }
5537
5538 // #include "header"
5539 Pattern = new CodeCompletionString;
5540 Pattern->AddTypedTextChunk("include");
5541 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5542 Pattern->AddTextChunk("\"");
5543 Pattern->AddPlaceholderChunk("header");
5544 Pattern->AddTextChunk("\"");
5545 Results.AddResult(Pattern);
5546
5547 // #include <header>
5548 Pattern = new CodeCompletionString;
5549 Pattern->AddTypedTextChunk("include");
5550 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5551 Pattern->AddTextChunk("<");
5552 Pattern->AddPlaceholderChunk("header");
5553 Pattern->AddTextChunk(">");
5554 Results.AddResult(Pattern);
5555
5556 // #define <macro>
5557 Pattern = new CodeCompletionString;
5558 Pattern->AddTypedTextChunk("define");
5559 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5560 Pattern->AddPlaceholderChunk("macro");
5561 Results.AddResult(Pattern);
5562
5563 // #define <macro>(<args>)
5564 Pattern = new CodeCompletionString;
5565 Pattern->AddTypedTextChunk("define");
5566 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5567 Pattern->AddPlaceholderChunk("macro");
5568 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5569 Pattern->AddPlaceholderChunk("args");
5570 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5571 Results.AddResult(Pattern);
5572
5573 // #undef <macro>
5574 Pattern = new CodeCompletionString;
5575 Pattern->AddTypedTextChunk("undef");
5576 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5577 Pattern->AddPlaceholderChunk("macro");
5578 Results.AddResult(Pattern);
5579
5580 // #line <number>
5581 Pattern = new CodeCompletionString;
5582 Pattern->AddTypedTextChunk("line");
5583 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5584 Pattern->AddPlaceholderChunk("number");
5585 Results.AddResult(Pattern);
5586
5587 // #line <number> "filename"
5588 Pattern = new CodeCompletionString;
5589 Pattern->AddTypedTextChunk("line");
5590 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5591 Pattern->AddPlaceholderChunk("number");
5592 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5593 Pattern->AddTextChunk("\"");
5594 Pattern->AddPlaceholderChunk("filename");
5595 Pattern->AddTextChunk("\"");
5596 Results.AddResult(Pattern);
5597
5598 // #error <message>
5599 Pattern = new CodeCompletionString;
5600 Pattern->AddTypedTextChunk("error");
5601 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5602 Pattern->AddPlaceholderChunk("message");
5603 Results.AddResult(Pattern);
5604
5605 // #pragma <arguments>
5606 Pattern = new CodeCompletionString;
5607 Pattern->AddTypedTextChunk("pragma");
5608 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5609 Pattern->AddPlaceholderChunk("arguments");
5610 Results.AddResult(Pattern);
5611
5612 if (getLangOptions().ObjC1) {
5613 // #import "header"
5614 Pattern = new CodeCompletionString;
5615 Pattern->AddTypedTextChunk("import");
5616 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5617 Pattern->AddTextChunk("\"");
5618 Pattern->AddPlaceholderChunk("header");
5619 Pattern->AddTextChunk("\"");
5620 Results.AddResult(Pattern);
5621
5622 // #import <header>
5623 Pattern = new CodeCompletionString;
5624 Pattern->AddTypedTextChunk("import");
5625 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5626 Pattern->AddTextChunk("<");
5627 Pattern->AddPlaceholderChunk("header");
5628 Pattern->AddTextChunk(">");
5629 Results.AddResult(Pattern);
5630 }
5631
5632 // #include_next "header"
5633 Pattern = new CodeCompletionString;
5634 Pattern->AddTypedTextChunk("include_next");
5635 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5636 Pattern->AddTextChunk("\"");
5637 Pattern->AddPlaceholderChunk("header");
5638 Pattern->AddTextChunk("\"");
5639 Results.AddResult(Pattern);
5640
5641 // #include_next <header>
5642 Pattern = new CodeCompletionString;
5643 Pattern->AddTypedTextChunk("include_next");
5644 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5645 Pattern->AddTextChunk("<");
5646 Pattern->AddPlaceholderChunk("header");
5647 Pattern->AddTextChunk(">");
5648 Results.AddResult(Pattern);
5649
5650 // #warning <message>
5651 Pattern = new CodeCompletionString;
5652 Pattern->AddTypedTextChunk("warning");
5653 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5654 Pattern->AddPlaceholderChunk("message");
5655 Results.AddResult(Pattern);
5656
5657 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5658 // completions for them. And __include_macros is a Clang-internal extension
5659 // that we don't want to encourage anyone to use.
5660
5661 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5662 Results.ExitScope();
5663
Douglas Gregor3a7ad252010-08-24 19:08:16 +00005664 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0de55ce2010-08-25 18:41:16 +00005665 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregor3a7ad252010-08-24 19:08:16 +00005666 Results.data(), Results.size());
5667}
5668
5669void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorec00a262010-08-24 22:20:20 +00005670 CodeCompleteOrdinaryName(S,
John McCallfaf5fb42010-08-26 23:41:50 +00005671 S->getFnParent()? Sema::PCC_RecoveryInFunction
5672 : Sema::PCC_Namespace);
Douglas Gregor3a7ad252010-08-24 19:08:16 +00005673}
5674
Douglas Gregorec00a262010-08-24 22:20:20 +00005675void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00005676 ResultBuilder Results(*this,
5677 IsDefinition? CodeCompletionContext::CCC_MacroName
5678 : CodeCompletionContext::CCC_MacroNameUse);
Douglas Gregor12785102010-08-24 20:21:13 +00005679 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5680 // Add just the names of macros, not their arguments.
5681 Results.EnterNewScope();
5682 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5683 MEnd = PP.macro_end();
5684 M != MEnd; ++M) {
5685 CodeCompletionString *Pattern = new CodeCompletionString;
5686 Pattern->AddTypedTextChunk(M->first->getName());
5687 Results.AddResult(Pattern);
5688 }
5689 Results.ExitScope();
5690 } else if (IsDefinition) {
5691 // FIXME: Can we detect when the user just wrote an include guard above?
5692 }
5693
Douglas Gregor0ac41382010-09-23 23:01:17 +00005694 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor12785102010-08-24 20:21:13 +00005695 Results.data(), Results.size());
5696}
5697
Douglas Gregorec00a262010-08-24 22:20:20 +00005698void Sema::CodeCompletePreprocessorExpression() {
Douglas Gregor0ac41382010-09-23 23:01:17 +00005699 ResultBuilder Results(*this,
5700 CodeCompletionContext::CCC_PreprocessorExpression);
Douglas Gregorec00a262010-08-24 22:20:20 +00005701
5702 if (!CodeCompleter || CodeCompleter->includeMacros())
5703 AddMacroResults(PP, Results);
5704
5705 // defined (<macro>)
5706 Results.EnterNewScope();
5707 CodeCompletionString *Pattern = new CodeCompletionString;
5708 Pattern->AddTypedTextChunk("defined");
5709 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5710 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5711 Pattern->AddPlaceholderChunk("macro");
5712 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5713 Results.AddResult(Pattern);
5714 Results.ExitScope();
5715
5716 HandleCodeCompleteResults(this, CodeCompleter,
5717 CodeCompletionContext::CCC_PreprocessorExpression,
5718 Results.data(), Results.size());
5719}
5720
5721void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5722 IdentifierInfo *Macro,
5723 MacroInfo *MacroInfo,
5724 unsigned Argument) {
5725 // FIXME: In the future, we could provide "overload" results, much like we
5726 // do for function calls.
5727
5728 CodeCompleteOrdinaryName(S,
John McCallfaf5fb42010-08-26 23:41:50 +00005729 S->getFnParent()? Sema::PCC_RecoveryInFunction
5730 : Sema::PCC_Namespace);
Douglas Gregorec00a262010-08-24 22:20:20 +00005731}
5732
Douglas Gregor11583702010-08-25 17:04:25 +00005733void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor11583702010-08-25 17:04:25 +00005734 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorea736372010-08-25 17:10:00 +00005735 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor11583702010-08-25 17:04:25 +00005736 0, 0);
5737}
5738
Douglas Gregorb14904c2010-08-13 22:48:40 +00005739void Sema::GatherGlobalCodeCompletions(
John McCall276321a2010-08-25 06:19:51 +00005740 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor0ac41382010-09-23 23:01:17 +00005741 ResultBuilder Builder(*this, CodeCompletionContext::CCC_Recovery);
Douglas Gregor39982192010-08-15 06:18:01 +00005742 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5743 CodeCompletionDeclConsumer Consumer(Builder,
5744 Context.getTranslationUnitDecl());
5745 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5746 Consumer);
5747 }
Douglas Gregorb14904c2010-08-13 22:48:40 +00005748
5749 if (!CodeCompleter || CodeCompleter->includeMacros())
5750 AddMacroResults(PP, Builder);
5751
5752 Results.clear();
5753 Results.insert(Results.end(),
5754 Builder.data(), Builder.data() + Builder.size());
5755}