blob: 727dd7929c0cd54ff76c3aa30894ff561ef77f60 [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
John McCall2d887082010-08-25 22:03:47 +000013#include "clang/Sema/SemaInternal.h"
Douglas Gregore737f502010-08-12 20:07:10 +000014#include "clang/Sema/Lookup.h"
John McCall120d63c2010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCall5f1e0942010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCall781472f2010-08-25 08:40:02 +000019#include "clang/Sema/ScopeInfo.h"
John McCall7cd088e2010-08-24 07:21:54 +000020#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000021#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000022#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000023#include "clang/Lex/MacroInfo.h"
24#include "clang/Lex/Preprocessor.h"
Douglas Gregord36adf52010-09-16 16:06:31 +000025#include "llvm/ADT/DenseSet.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000026#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000027#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000028#include "llvm/ADT/StringSwitch.h"
Douglas Gregor458433d2010-08-26 15:07:07 +000029#include "llvm/ADT/Twine.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000030#include <list>
31#include <map>
32#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000033
34using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000035using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000036
Douglas Gregor86d9a522009-09-21 16:56:56 +000037namespace {
38 /// \brief A container of code-completion results.
39 class ResultBuilder {
40 public:
41 /// \brief The type of a name-lookup filter, which can be provided to the
42 /// name-lookup routines to specify which declarations should be included in
43 /// the result set (when it returns true) and which declarations should be
44 /// filtered out (returns false).
45 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
46
John McCall0a2c5e22010-08-25 06:19:51 +000047 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000048
49 private:
50 /// \brief The actual results we have found.
51 std::vector<Result> Results;
52
53 /// \brief A record of all of the declarations we have found and placed
54 /// into the result set, used to ensure that no declaration ever gets into
55 /// the result set twice.
56 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
57
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000058 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
59
60 /// \brief An entry in the shadow map, which is optimized to store
61 /// a single (declaration, index) mapping (the common case) but
62 /// can also store a list of (declaration, index) mappings.
63 class ShadowMapEntry {
64 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
65
66 /// \brief Contains either the solitary NamedDecl * or a vector
67 /// of (declaration, index) pairs.
68 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
69
70 /// \brief When the entry contains a single declaration, this is
71 /// the index associated with that entry.
72 unsigned SingleDeclIndex;
73
74 public:
75 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
76
77 void Add(NamedDecl *ND, unsigned Index) {
78 if (DeclOrVector.isNull()) {
79 // 0 - > 1 elements: just set the single element information.
80 DeclOrVector = ND;
81 SingleDeclIndex = Index;
82 return;
83 }
84
85 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
86 // 1 -> 2 elements: create the vector of results and push in the
87 // existing declaration.
88 DeclIndexPairVector *Vec = new DeclIndexPairVector;
89 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
90 DeclOrVector = Vec;
91 }
92
93 // Add the new element to the end of the vector.
94 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
95 DeclIndexPair(ND, Index));
96 }
97
98 void Destroy() {
99 if (DeclIndexPairVector *Vec
100 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
101 delete Vec;
102 DeclOrVector = ((NamedDecl *)0);
103 }
104 }
105
106 // Iteration.
107 class iterator;
108 iterator begin() const;
109 iterator end() const;
110 };
111
Douglas Gregor86d9a522009-09-21 16:56:56 +0000112 /// \brief A mapping from declaration names to the declarations that have
113 /// this name within a particular scope and their index within the list of
114 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000115 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000116
117 /// \brief The semantic analysis object for which results are being
118 /// produced.
119 Sema &SemaRef;
120
121 /// \brief If non-NULL, a filter function used to remove any code-completion
122 /// results that are not desirable.
123 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000124
125 /// \brief Whether we should allow declarations as
126 /// nested-name-specifiers that would otherwise be filtered out.
127 bool AllowNestedNameSpecifiers;
128
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000129 /// \brief If set, the type that we would prefer our resulting value
130 /// declarations to have.
131 ///
132 /// Closely matching the preferred type gives a boost to a result's
133 /// priority.
134 CanQualType PreferredType;
135
Douglas Gregor86d9a522009-09-21 16:56:56 +0000136 /// \brief A list of shadow maps, which is used to model name hiding at
137 /// different levels of, e.g., the inheritance hierarchy.
138 std::list<ShadowMap> ShadowMaps;
139
Douglas Gregor3cdee122010-08-26 16:36:48 +0000140 /// \brief If we're potentially referring to a C++ member function, the set
141 /// of qualifiers applied to the object type.
142 Qualifiers ObjectTypeQualifiers;
143
144 /// \brief Whether the \p ObjectTypeQualifiers field is active.
145 bool HasObjectTypeQualifiers;
146
Douglas Gregor265f7492010-08-27 15:29:55 +0000147 /// \brief The selector that we prefer.
148 Selector PreferredSelector;
149
Douglas Gregorca45da02010-11-02 20:36:02 +0000150 /// \brief The completion context in which we are gathering results.
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000151 CodeCompletionContext CompletionContext;
152
Douglas Gregorca45da02010-11-02 20:36:02 +0000153 /// \brief If we are in an instance method definition, the @implementation
154 /// object.
155 ObjCImplementationDecl *ObjCImplementation;
156
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000157 void AdjustResultPriorityForDecl(Result &R);
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000158
Douglas Gregor6f942b22010-09-21 16:06:22 +0000159 void MaybeAddConstructorResults(Result R);
160
Douglas Gregor86d9a522009-09-21 16:56:56 +0000161 public:
Douglas Gregor52779fb2010-09-23 23:01:17 +0000162 explicit ResultBuilder(Sema &SemaRef,
163 const CodeCompletionContext &CompletionContext,
164 LookupFilter Filter = 0)
Douglas Gregor3cdee122010-08-26 16:36:48 +0000165 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000166 HasObjectTypeQualifiers(false),
Douglas Gregorca45da02010-11-02 20:36:02 +0000167 CompletionContext(CompletionContext),
168 ObjCImplementation(0)
169 {
170 // If this is an Objective-C instance method definition, dig out the
171 // corresponding implementation.
172 switch (CompletionContext.getKind()) {
173 case CodeCompletionContext::CCC_Expression:
174 case CodeCompletionContext::CCC_ObjCMessageReceiver:
175 case CodeCompletionContext::CCC_ParenthesizedExpression:
176 case CodeCompletionContext::CCC_Statement:
177 case CodeCompletionContext::CCC_Recovery:
178 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
179 if (Method->isInstanceMethod())
180 if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
181 ObjCImplementation = Interface->getImplementation();
182 break;
183
184 default:
185 break;
186 }
187 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000188
Douglas Gregord8e8a582010-05-25 21:41:55 +0000189 /// \brief Whether we should include code patterns in the completion
190 /// results.
191 bool includeCodePatterns() const {
192 return SemaRef.CodeCompleter &&
Douglas Gregorf6961522010-08-27 21:18:54 +0000193 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregord8e8a582010-05-25 21:41:55 +0000194 }
195
Douglas Gregor86d9a522009-09-21 16:56:56 +0000196 /// \brief Set the filter used for code-completion results.
197 void setFilter(LookupFilter Filter) {
198 this->Filter = Filter;
199 }
200
Douglas Gregor86d9a522009-09-21 16:56:56 +0000201 Result *data() { return Results.empty()? 0 : &Results.front(); }
202 unsigned size() const { return Results.size(); }
203 bool empty() const { return Results.empty(); }
204
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000205 /// \brief Specify the preferred type.
206 void setPreferredType(QualType T) {
207 PreferredType = SemaRef.Context.getCanonicalType(T);
208 }
209
Douglas Gregor3cdee122010-08-26 16:36:48 +0000210 /// \brief Set the cv-qualifiers on the object type, for us in filtering
211 /// calls to member functions.
212 ///
213 /// When there are qualifiers in this set, they will be used to filter
214 /// out member functions that aren't available (because there will be a
215 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
216 /// match.
217 void setObjectTypeQualifiers(Qualifiers Quals) {
218 ObjectTypeQualifiers = Quals;
219 HasObjectTypeQualifiers = true;
220 }
221
Douglas Gregor265f7492010-08-27 15:29:55 +0000222 /// \brief Set the preferred selector.
223 ///
224 /// When an Objective-C method declaration result is added, and that
225 /// method's selector matches this preferred selector, we give that method
226 /// a slight priority boost.
227 void setPreferredSelector(Selector Sel) {
228 PreferredSelector = Sel;
229 }
Douglas Gregorca45da02010-11-02 20:36:02 +0000230
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000231 /// \brief Retrieve the code-completion context for which results are
232 /// being collected.
233 const CodeCompletionContext &getCompletionContext() const {
234 return CompletionContext;
235 }
236
Douglas Gregor45bcd432010-01-14 03:21:49 +0000237 /// \brief Specify whether nested-name-specifiers are allowed.
238 void allowNestedNameSpecifiers(bool Allow = true) {
239 AllowNestedNameSpecifiers = Allow;
240 }
241
Douglas Gregorb9d77572010-09-21 00:03:25 +0000242 /// \brief Return the semantic analysis object for which we are collecting
243 /// code completion results.
244 Sema &getSema() const { return SemaRef; }
245
Douglas Gregore495b7f2010-01-14 00:20:49 +0000246 /// \brief Determine whether the given declaration is at all interesting
247 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000248 ///
249 /// \param ND the declaration that we are inspecting.
250 ///
251 /// \param AsNestedNameSpecifier will be set true if this declaration is
252 /// only interesting when it is a nested-name-specifier.
253 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000254
255 /// \brief Check whether the result is hidden by the Hiding declaration.
256 ///
257 /// \returns true if the result is hidden and cannot be found, false if
258 /// the hidden result could still be found. When false, \p R may be
259 /// modified to describe how the result can be found (e.g., via extra
260 /// qualification).
261 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
262 NamedDecl *Hiding);
263
Douglas Gregor86d9a522009-09-21 16:56:56 +0000264 /// \brief Add a new result to this result set (if it isn't already in one
265 /// of the shadow maps), or replace an existing result (for, e.g., a
266 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000267 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000268 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000269 ///
270 /// \param R the context in which this result will be named.
271 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000272
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000273 /// \brief Add a new result to this result set, where we already know
274 /// the hiding declation (if any).
275 ///
276 /// \param R the result to add (if it is unique).
277 ///
278 /// \param CurContext the context in which this result will be named.
279 ///
280 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000281 ///
282 /// \param InBaseClass whether the result was found in a base
283 /// class of the searched context.
284 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
285 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000286
Douglas Gregora4477812010-01-14 16:01:26 +0000287 /// \brief Add a new non-declaration result to this result set.
288 void AddResult(Result R);
289
Douglas Gregor86d9a522009-09-21 16:56:56 +0000290 /// \brief Enter into a new scope.
291 void EnterNewScope();
292
293 /// \brief Exit from the current scope.
294 void ExitScope();
295
Douglas Gregor55385fe2009-11-18 04:19:12 +0000296 /// \brief Ignore this declaration, if it is seen again.
297 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
298
Douglas Gregor86d9a522009-09-21 16:56:56 +0000299 /// \name Name lookup predicates
300 ///
301 /// These predicates can be passed to the name lookup functions to filter the
302 /// results of name lookup. All of the predicates have the same type, so that
303 ///
304 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000305 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000306 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000307 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000308 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000309 bool IsNestedNameSpecifier(NamedDecl *ND) const;
310 bool IsEnum(NamedDecl *ND) const;
311 bool IsClassOrStruct(NamedDecl *ND) const;
312 bool IsUnion(NamedDecl *ND) const;
313 bool IsNamespace(NamedDecl *ND) const;
314 bool IsNamespaceOrAlias(NamedDecl *ND) const;
315 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000316 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000317 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000318 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000319 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor52779fb2010-09-23 23:01:17 +0000320 bool IsImpossibleToSatisfy(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000321 //@}
322 };
323}
324
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000325class ResultBuilder::ShadowMapEntry::iterator {
326 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
327 unsigned SingleDeclIndex;
328
329public:
330 typedef DeclIndexPair value_type;
331 typedef value_type reference;
332 typedef std::ptrdiff_t difference_type;
333 typedef std::input_iterator_tag iterator_category;
334
335 class pointer {
336 DeclIndexPair Value;
337
338 public:
339 pointer(const DeclIndexPair &Value) : Value(Value) { }
340
341 const DeclIndexPair *operator->() const {
342 return &Value;
343 }
344 };
345
346 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
347
348 iterator(NamedDecl *SingleDecl, unsigned Index)
349 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
350
351 iterator(const DeclIndexPair *Iterator)
352 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
353
354 iterator &operator++() {
355 if (DeclOrIterator.is<NamedDecl *>()) {
356 DeclOrIterator = (NamedDecl *)0;
357 SingleDeclIndex = 0;
358 return *this;
359 }
360
361 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
362 ++I;
363 DeclOrIterator = I;
364 return *this;
365 }
366
Chris Lattner66392d42010-09-04 18:12:20 +0000367 /*iterator operator++(int) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000368 iterator tmp(*this);
369 ++(*this);
370 return tmp;
Chris Lattner66392d42010-09-04 18:12:20 +0000371 }*/
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000372
373 reference operator*() const {
374 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
375 return reference(ND, SingleDeclIndex);
376
Douglas Gregord490f952009-12-06 21:27:58 +0000377 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000378 }
379
380 pointer operator->() const {
381 return pointer(**this);
382 }
383
384 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000385 return X.DeclOrIterator.getOpaqueValue()
386 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000387 X.SingleDeclIndex == Y.SingleDeclIndex;
388 }
389
390 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000391 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000392 }
393};
394
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000395ResultBuilder::ShadowMapEntry::iterator
396ResultBuilder::ShadowMapEntry::begin() const {
397 if (DeclOrVector.isNull())
398 return iterator();
399
400 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
401 return iterator(ND, SingleDeclIndex);
402
403 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
404}
405
406ResultBuilder::ShadowMapEntry::iterator
407ResultBuilder::ShadowMapEntry::end() const {
408 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
409 return iterator();
410
411 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
412}
413
Douglas Gregor456c4a12009-09-21 20:12:40 +0000414/// \brief Compute the qualification required to get from the current context
415/// (\p CurContext) to the target context (\p TargetContext).
416///
417/// \param Context the AST context in which the qualification will be used.
418///
419/// \param CurContext the context where an entity is being named, which is
420/// typically based on the current scope.
421///
422/// \param TargetContext the context in which the named entity actually
423/// resides.
424///
425/// \returns a nested name specifier that refers into the target context, or
426/// NULL if no qualification is needed.
427static NestedNameSpecifier *
428getRequiredQualification(ASTContext &Context,
429 DeclContext *CurContext,
430 DeclContext *TargetContext) {
431 llvm::SmallVector<DeclContext *, 4> TargetParents;
432
433 for (DeclContext *CommonAncestor = TargetContext;
434 CommonAncestor && !CommonAncestor->Encloses(CurContext);
435 CommonAncestor = CommonAncestor->getLookupParent()) {
436 if (CommonAncestor->isTransparentContext() ||
437 CommonAncestor->isFunctionOrMethod())
438 continue;
439
440 TargetParents.push_back(CommonAncestor);
441 }
442
443 NestedNameSpecifier *Result = 0;
444 while (!TargetParents.empty()) {
445 DeclContext *Parent = TargetParents.back();
446 TargetParents.pop_back();
447
Douglas Gregorfb629412010-08-23 21:17:50 +0000448 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
449 if (!Namespace->getIdentifier())
450 continue;
451
Douglas Gregor456c4a12009-09-21 20:12:40 +0000452 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000453 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000454 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
455 Result = NestedNameSpecifier::Create(Context, Result,
456 false,
457 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000458 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000459 return Result;
460}
461
Douglas Gregor45bcd432010-01-14 03:21:49 +0000462bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
463 bool &AsNestedNameSpecifier) const {
464 AsNestedNameSpecifier = false;
465
Douglas Gregore495b7f2010-01-14 00:20:49 +0000466 ND = ND->getUnderlyingDecl();
467 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000468
469 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000470 if (!ND->getDeclName())
471 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000472
473 // Friend declarations and declarations introduced due to friends are never
474 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000475 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000476 return false;
477
Douglas Gregor76282942009-12-11 17:31:05 +0000478 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000479 if (isa<ClassTemplateSpecializationDecl>(ND) ||
480 isa<ClassTemplatePartialSpecializationDecl>(ND))
481 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000482
Douglas Gregor76282942009-12-11 17:31:05 +0000483 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000484 if (isa<UsingDecl>(ND))
485 return false;
486
487 // Some declarations have reserved names that we don't want to ever show.
488 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000489 // __va_list_tag is a freak of nature. Find it and skip it.
490 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000491 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000492
Douglas Gregorf52cede2009-10-09 22:16:47 +0000493 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000494 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000495 //
496 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000497 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000498 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000499 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000500 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
501 (ND->getLocation().isInvalid() ||
502 SemaRef.SourceMgr.isInSystemHeader(
503 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000504 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000505 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000506 }
Douglas Gregor6f942b22010-09-21 16:06:22 +0000507
Douglas Gregor9b0ba872010-11-09 03:59:40 +0000508 // Skip out-of-line declarations and definitions.
509 // NOTE: Unless it's an Objective-C property, method, or ivar, where
510 // the contexts can be messy.
511 if (!ND->getDeclContext()->Equals(ND->getLexicalDeclContext()) &&
512 !(isa<ObjCPropertyDecl>(ND) || isa<ObjCIvarDecl>(ND) ||
513 isa<ObjCMethodDecl>(ND)))
514 return false;
515
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000516 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
517 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
518 Filter != &ResultBuilder::IsNamespace &&
Douglas Gregor52779fb2010-09-23 23:01:17 +0000519 Filter != &ResultBuilder::IsNamespaceOrAlias &&
520 Filter != 0))
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000521 AsNestedNameSpecifier = true;
522
Douglas Gregor86d9a522009-09-21 16:56:56 +0000523 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000524 if (Filter && !(this->*Filter)(ND)) {
525 // Check whether it is interesting as a nested-name-specifier.
526 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
527 IsNestedNameSpecifier(ND) &&
528 (Filter != &ResultBuilder::IsMember ||
529 (isa<CXXRecordDecl>(ND) &&
530 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
531 AsNestedNameSpecifier = true;
532 return true;
533 }
534
Douglas Gregore495b7f2010-01-14 00:20:49 +0000535 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000536 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000537 // ... then it must be interesting!
538 return true;
539}
540
Douglas Gregor6660d842010-01-14 00:41:07 +0000541bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
542 NamedDecl *Hiding) {
543 // In C, there is no way to refer to a hidden name.
544 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
545 // name if we introduce the tag type.
546 if (!SemaRef.getLangOptions().CPlusPlus)
547 return true;
548
Sebastian Redl7a126a42010-08-31 00:36:30 +0000549 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregor6660d842010-01-14 00:41:07 +0000550
551 // There is no way to qualify a name declared in a function or method.
552 if (HiddenCtx->isFunctionOrMethod())
553 return true;
554
Sebastian Redl7a126a42010-08-31 00:36:30 +0000555 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregor6660d842010-01-14 00:41:07 +0000556 return true;
557
558 // We can refer to the result with the appropriate qualification. Do it.
559 R.Hidden = true;
560 R.QualifierIsInformative = false;
561
562 if (!R.Qualifier)
563 R.Qualifier = getRequiredQualification(SemaRef.Context,
564 CurContext,
565 R.Declaration->getDeclContext());
566 return false;
567}
568
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000569/// \brief A simplified classification of types used to determine whether two
570/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000571SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000572 switch (T->getTypeClass()) {
573 case Type::Builtin:
574 switch (cast<BuiltinType>(T)->getKind()) {
575 case BuiltinType::Void:
576 return STC_Void;
577
578 case BuiltinType::NullPtr:
579 return STC_Pointer;
580
581 case BuiltinType::Overload:
582 case BuiltinType::Dependent:
583 case BuiltinType::UndeducedAuto:
584 return STC_Other;
585
586 case BuiltinType::ObjCId:
587 case BuiltinType::ObjCClass:
588 case BuiltinType::ObjCSel:
589 return STC_ObjectiveC;
590
591 default:
592 return STC_Arithmetic;
593 }
594 return STC_Other;
595
596 case Type::Complex:
597 return STC_Arithmetic;
598
599 case Type::Pointer:
600 return STC_Pointer;
601
602 case Type::BlockPointer:
603 return STC_Block;
604
605 case Type::LValueReference:
606 case Type::RValueReference:
607 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
608
609 case Type::ConstantArray:
610 case Type::IncompleteArray:
611 case Type::VariableArray:
612 case Type::DependentSizedArray:
613 return STC_Array;
614
615 case Type::DependentSizedExtVector:
616 case Type::Vector:
617 case Type::ExtVector:
618 return STC_Arithmetic;
619
620 case Type::FunctionProto:
621 case Type::FunctionNoProto:
622 return STC_Function;
623
624 case Type::Record:
625 return STC_Record;
626
627 case Type::Enum:
628 return STC_Arithmetic;
629
630 case Type::ObjCObject:
631 case Type::ObjCInterface:
632 case Type::ObjCObjectPointer:
633 return STC_ObjectiveC;
634
635 default:
636 return STC_Other;
637 }
638}
639
640/// \brief Get the type that a given expression will have if this declaration
641/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000642QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000643 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
644
645 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
646 return C.getTypeDeclType(Type);
647 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
648 return C.getObjCInterfaceType(Iface);
649
650 QualType T;
651 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000652 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000653 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000654 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000655 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000656 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000657 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
658 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
659 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
660 T = Property->getType();
661 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
662 T = Value->getType();
663 else
664 return QualType();
665
666 return T.getNonReferenceType();
667}
668
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000669void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
670 // If this is an Objective-C method declaration whose selector matches our
671 // preferred selector, give it a priority boost.
672 if (!PreferredSelector.isNull())
673 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
674 if (PreferredSelector == Method->getSelector())
675 R.Priority += CCD_SelectorMatch;
Douglas Gregor08f43cd2010-09-20 23:11:55 +0000676
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000677 // If we have a preferred type, adjust the priority for results with exactly-
678 // matching or nearly-matching types.
679 if (!PreferredType.isNull()) {
680 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
681 if (!T.isNull()) {
682 CanQualType TC = SemaRef.Context.getCanonicalType(T);
683 // Check for exactly-matching types (modulo qualifiers).
684 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
685 R.Priority /= CCF_ExactTypeMatch;
686 // Check for nearly-matching types, based on classification of each.
687 else if ((getSimplifiedTypeClass(PreferredType)
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000688 == getSimplifiedTypeClass(TC)) &&
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000689 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
690 R.Priority /= CCF_SimilarTypeMatch;
691 }
692 }
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000693}
694
Douglas Gregor6f942b22010-09-21 16:06:22 +0000695void ResultBuilder::MaybeAddConstructorResults(Result R) {
696 if (!SemaRef.getLangOptions().CPlusPlus || !R.Declaration ||
697 !CompletionContext.wantConstructorResults())
698 return;
699
700 ASTContext &Context = SemaRef.Context;
701 NamedDecl *D = R.Declaration;
702 CXXRecordDecl *Record = 0;
703 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
704 Record = ClassTemplate->getTemplatedDecl();
705 else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
706 // Skip specializations and partial specializations.
707 if (isa<ClassTemplateSpecializationDecl>(Record))
708 return;
709 } else {
710 // There are no constructors here.
711 return;
712 }
713
714 Record = Record->getDefinition();
715 if (!Record)
716 return;
717
718
719 QualType RecordTy = Context.getTypeDeclType(Record);
720 DeclarationName ConstructorName
721 = Context.DeclarationNames.getCXXConstructorName(
722 Context.getCanonicalType(RecordTy));
723 for (DeclContext::lookup_result Ctors = Record->lookup(ConstructorName);
724 Ctors.first != Ctors.second; ++Ctors.first) {
725 R.Declaration = *Ctors.first;
726 R.CursorKind = getCursorKindForDecl(R.Declaration);
727 Results.push_back(R);
728 }
729}
730
Douglas Gregore495b7f2010-01-14 00:20:49 +0000731void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
732 assert(!ShadowMaps.empty() && "Must enter into a results scope");
733
734 if (R.Kind != Result::RK_Declaration) {
735 // For non-declaration results, just add the result.
736 Results.push_back(R);
737 return;
738 }
739
740 // Look through using declarations.
741 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
742 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
743 return;
744 }
745
746 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
747 unsigned IDNS = CanonDecl->getIdentifierNamespace();
748
Douglas Gregor45bcd432010-01-14 03:21:49 +0000749 bool AsNestedNameSpecifier = false;
750 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000751 return;
752
Douglas Gregor6f942b22010-09-21 16:06:22 +0000753 // C++ constructors are never found by name lookup.
754 if (isa<CXXConstructorDecl>(R.Declaration))
755 return;
756
Douglas Gregor86d9a522009-09-21 16:56:56 +0000757 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000758 ShadowMapEntry::iterator I, IEnd;
759 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
760 if (NamePos != SMap.end()) {
761 I = NamePos->second.begin();
762 IEnd = NamePos->second.end();
763 }
764
765 for (; I != IEnd; ++I) {
766 NamedDecl *ND = I->first;
767 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000768 if (ND->getCanonicalDecl() == CanonDecl) {
769 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000770 Results[Index].Declaration = R.Declaration;
771
Douglas Gregor86d9a522009-09-21 16:56:56 +0000772 // We're done.
773 return;
774 }
775 }
776
777 // This is a new declaration in this scope. However, check whether this
778 // declaration name is hidden by a similarly-named declaration in an outer
779 // scope.
780 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
781 --SMEnd;
782 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000783 ShadowMapEntry::iterator I, IEnd;
784 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
785 if (NamePos != SM->end()) {
786 I = NamePos->second.begin();
787 IEnd = NamePos->second.end();
788 }
789 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000790 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000791 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000792 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
793 Decl::IDNS_ObjCProtocol)))
794 continue;
795
796 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000797 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000798 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000799 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000800 continue;
801
802 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000803 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000804 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000805
806 break;
807 }
808 }
809
810 // Make sure that any given declaration only shows up in the result set once.
811 if (!AllDeclsFound.insert(CanonDecl))
812 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000813
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000814 // If the filter is for nested-name-specifiers, then this result starts a
815 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000816 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000817 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000818 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000819 } else
820 AdjustResultPriorityForDecl(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000821
Douglas Gregor0563c262009-09-22 23:15:58 +0000822 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000823 if (R.QualifierIsInformative && !R.Qualifier &&
824 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000825 DeclContext *Ctx = R.Declaration->getDeclContext();
826 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
827 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
828 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
829 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
830 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
831 else
832 R.QualifierIsInformative = false;
833 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000834
Douglas Gregor86d9a522009-09-21 16:56:56 +0000835 // Insert this result into the set of results and into the current shadow
836 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000837 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000838 Results.push_back(R);
Douglas Gregor6f942b22010-09-21 16:06:22 +0000839
840 if (!AsNestedNameSpecifier)
841 MaybeAddConstructorResults(R);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000842}
843
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000844void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000845 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000846 if (R.Kind != Result::RK_Declaration) {
847 // For non-declaration results, just add the result.
848 Results.push_back(R);
849 return;
850 }
851
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000852 // Look through using declarations.
853 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
854 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
855 return;
856 }
857
Douglas Gregor45bcd432010-01-14 03:21:49 +0000858 bool AsNestedNameSpecifier = false;
859 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000860 return;
861
Douglas Gregor6f942b22010-09-21 16:06:22 +0000862 // C++ constructors are never found by name lookup.
863 if (isa<CXXConstructorDecl>(R.Declaration))
864 return;
865
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000866 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
867 return;
868
869 // Make sure that any given declaration only shows up in the result set once.
870 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
871 return;
872
873 // If the filter is for nested-name-specifiers, then this result starts a
874 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000875 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000876 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000877 R.Priority = CCP_NestedNameSpecifier;
878 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000879 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
880 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000881 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000882 R.QualifierIsInformative = true;
883
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000884 // If this result is supposed to have an informative qualifier, add one.
885 if (R.QualifierIsInformative && !R.Qualifier &&
886 !R.StartsNestedNameSpecifier) {
887 DeclContext *Ctx = R.Declaration->getDeclContext();
888 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
889 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
890 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
891 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000892 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000893 else
894 R.QualifierIsInformative = false;
895 }
896
Douglas Gregor12e13132010-05-26 22:00:08 +0000897 // Adjust the priority if this result comes from a base class.
898 if (InBaseClass)
899 R.Priority += CCD_InBaseClass;
900
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000901 AdjustResultPriorityForDecl(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000902
Douglas Gregor3cdee122010-08-26 16:36:48 +0000903 if (HasObjectTypeQualifiers)
904 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
905 if (Method->isInstance()) {
906 Qualifiers MethodQuals
907 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
908 if (ObjectTypeQualifiers == MethodQuals)
909 R.Priority += CCD_ObjectQualifierMatch;
910 else if (ObjectTypeQualifiers - MethodQuals) {
911 // The method cannot be invoked, because doing so would drop
912 // qualifiers.
913 return;
914 }
915 }
916
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000917 // Insert this result into the set of results.
918 Results.push_back(R);
Douglas Gregor6f942b22010-09-21 16:06:22 +0000919
920 if (!AsNestedNameSpecifier)
921 MaybeAddConstructorResults(R);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000922}
923
Douglas Gregora4477812010-01-14 16:01:26 +0000924void ResultBuilder::AddResult(Result R) {
925 assert(R.Kind != Result::RK_Declaration &&
926 "Declaration results need more context");
927 Results.push_back(R);
928}
929
Douglas Gregor86d9a522009-09-21 16:56:56 +0000930/// \brief Enter into a new scope.
931void ResultBuilder::EnterNewScope() {
932 ShadowMaps.push_back(ShadowMap());
933}
934
935/// \brief Exit from the current scope.
936void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000937 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
938 EEnd = ShadowMaps.back().end();
939 E != EEnd;
940 ++E)
941 E->second.Destroy();
942
Douglas Gregor86d9a522009-09-21 16:56:56 +0000943 ShadowMaps.pop_back();
944}
945
Douglas Gregor791215b2009-09-21 20:51:25 +0000946/// \brief Determines whether this given declaration will be found by
947/// ordinary name lookup.
948bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000949 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
950
Douglas Gregor791215b2009-09-21 20:51:25 +0000951 unsigned IDNS = Decl::IDNS_Ordinary;
952 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000953 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorca45da02010-11-02 20:36:02 +0000954 else if (SemaRef.getLangOptions().ObjC1) {
955 if (isa<ObjCIvarDecl>(ND))
956 return true;
957 if (isa<ObjCPropertyDecl>(ND) &&
958 SemaRef.canSynthesizeProvisionalIvar(cast<ObjCPropertyDecl>(ND)))
959 return true;
960 }
961
Douglas Gregor791215b2009-09-21 20:51:25 +0000962 return ND->getIdentifierNamespace() & IDNS;
963}
964
Douglas Gregor01dfea02010-01-10 23:08:15 +0000965/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000966/// ordinary name lookup but is not a type name.
967bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
968 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
969 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
970 return false;
971
972 unsigned IDNS = Decl::IDNS_Ordinary;
973 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000974 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregorca45da02010-11-02 20:36:02 +0000975 else if (SemaRef.getLangOptions().ObjC1) {
976 if (isa<ObjCIvarDecl>(ND))
977 return true;
978 if (isa<ObjCPropertyDecl>(ND) &&
979 SemaRef.canSynthesizeProvisionalIvar(cast<ObjCPropertyDecl>(ND)))
980 return true;
981 }
982
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000983 return ND->getIdentifierNamespace() & IDNS;
984}
985
Douglas Gregorf9578432010-07-28 21:50:18 +0000986bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
987 if (!IsOrdinaryNonTypeName(ND))
988 return 0;
989
990 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
991 if (VD->getType()->isIntegralOrEnumerationType())
992 return true;
993
994 return false;
995}
996
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000997/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000998/// ordinary name lookup.
999bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001000 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1001
Douglas Gregor01dfea02010-01-10 23:08:15 +00001002 unsigned IDNS = Decl::IDNS_Ordinary;
1003 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +00001004 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001005
1006 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001007 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
1008 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001009}
1010
Douglas Gregor86d9a522009-09-21 16:56:56 +00001011/// \brief Determines whether the given declaration is suitable as the
1012/// start of a C++ nested-name-specifier, e.g., a class or namespace.
1013bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
1014 // Allow us to find class templates, too.
1015 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1016 ND = ClassTemplate->getTemplatedDecl();
1017
1018 return SemaRef.isAcceptableNestedNameSpecifier(ND);
1019}
1020
1021/// \brief Determines whether the given declaration is an enumeration.
1022bool ResultBuilder::IsEnum(NamedDecl *ND) const {
1023 return isa<EnumDecl>(ND);
1024}
1025
1026/// \brief Determines whether the given declaration is a class or struct.
1027bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
1028 // Allow us to find class templates, too.
1029 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1030 ND = ClassTemplate->getTemplatedDecl();
1031
1032 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +00001033 return RD->getTagKind() == TTK_Class ||
1034 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001035
1036 return false;
1037}
1038
1039/// \brief Determines whether the given declaration is a union.
1040bool ResultBuilder::IsUnion(NamedDecl *ND) const {
1041 // Allow us to find class templates, too.
1042 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1043 ND = ClassTemplate->getTemplatedDecl();
1044
1045 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +00001046 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001047
1048 return false;
1049}
1050
1051/// \brief Determines whether the given declaration is a namespace.
1052bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
1053 return isa<NamespaceDecl>(ND);
1054}
1055
1056/// \brief Determines whether the given declaration is a namespace or
1057/// namespace alias.
1058bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
1059 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
1060}
1061
Douglas Gregor76282942009-12-11 17:31:05 +00001062/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +00001063bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +00001064 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1065 ND = Using->getTargetDecl();
1066
1067 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001068}
1069
Douglas Gregor76282942009-12-11 17:31:05 +00001070/// \brief Determines which members of a class should be visible via
1071/// "." or "->". Only value declarations, nested name specifiers, and
1072/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001073bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +00001074 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1075 ND = Using->getTargetDecl();
1076
Douglas Gregorce821962009-12-11 18:14:22 +00001077 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1078 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001079}
1080
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001081static bool isObjCReceiverType(ASTContext &C, QualType T) {
1082 T = C.getCanonicalType(T);
1083 switch (T->getTypeClass()) {
1084 case Type::ObjCObject:
1085 case Type::ObjCInterface:
1086 case Type::ObjCObjectPointer:
1087 return true;
1088
1089 case Type::Builtin:
1090 switch (cast<BuiltinType>(T)->getKind()) {
1091 case BuiltinType::ObjCId:
1092 case BuiltinType::ObjCClass:
1093 case BuiltinType::ObjCSel:
1094 return true;
1095
1096 default:
1097 break;
1098 }
1099 return false;
1100
1101 default:
1102 break;
1103 }
1104
1105 if (!C.getLangOptions().CPlusPlus)
1106 return false;
1107
1108 // FIXME: We could perform more analysis here to determine whether a
1109 // particular class type has any conversions to Objective-C types. For now,
1110 // just accept all class types.
1111 return T->isDependentType() || T->isRecordType();
1112}
1113
1114bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
1115 QualType T = getDeclUsageType(SemaRef.Context, ND);
1116 if (T.isNull())
1117 return false;
1118
1119 T = SemaRef.Context.getBaseElementType(T);
1120 return isObjCReceiverType(SemaRef.Context, T);
1121}
1122
Douglas Gregorfb629412010-08-23 21:17:50 +00001123bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
1124 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
1125 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1126 return false;
1127
1128 QualType T = getDeclUsageType(SemaRef.Context, ND);
1129 if (T.isNull())
1130 return false;
1131
1132 T = SemaRef.Context.getBaseElementType(T);
1133 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1134 T->isObjCIdType() ||
1135 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
1136}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001137
Douglas Gregor52779fb2010-09-23 23:01:17 +00001138bool ResultBuilder::IsImpossibleToSatisfy(NamedDecl *ND) const {
1139 return false;
1140}
1141
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001142/// \rief Determines whether the given declaration is an Objective-C
1143/// instance variable.
1144bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
1145 return isa<ObjCIvarDecl>(ND);
1146}
1147
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001148namespace {
1149 /// \brief Visible declaration consumer that adds a code-completion result
1150 /// for each visible declaration.
1151 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1152 ResultBuilder &Results;
1153 DeclContext *CurContext;
1154
1155 public:
1156 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1157 : Results(Results), CurContext(CurContext) { }
1158
Douglas Gregor0cc84042010-01-14 15:47:35 +00001159 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
1160 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001161 }
1162 };
1163}
1164
Douglas Gregor86d9a522009-09-21 16:56:56 +00001165/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001166static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001167 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001168 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001169 Results.AddResult(Result("short", CCP_Type));
1170 Results.AddResult(Result("long", CCP_Type));
1171 Results.AddResult(Result("signed", CCP_Type));
1172 Results.AddResult(Result("unsigned", CCP_Type));
1173 Results.AddResult(Result("void", CCP_Type));
1174 Results.AddResult(Result("char", CCP_Type));
1175 Results.AddResult(Result("int", CCP_Type));
1176 Results.AddResult(Result("float", CCP_Type));
1177 Results.AddResult(Result("double", CCP_Type));
1178 Results.AddResult(Result("enum", CCP_Type));
1179 Results.AddResult(Result("struct", CCP_Type));
1180 Results.AddResult(Result("union", CCP_Type));
1181 Results.AddResult(Result("const", CCP_Type));
1182 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001183
Douglas Gregor86d9a522009-09-21 16:56:56 +00001184 if (LangOpts.C99) {
1185 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001186 Results.AddResult(Result("_Complex", CCP_Type));
1187 Results.AddResult(Result("_Imaginary", CCP_Type));
1188 Results.AddResult(Result("_Bool", CCP_Type));
1189 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001190 }
1191
1192 if (LangOpts.CPlusPlus) {
1193 // C++-specific
Douglas Gregorb05496d2010-09-20 21:11:48 +00001194 Results.AddResult(Result("bool", CCP_Type +
1195 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
Douglas Gregor12e13132010-05-26 22:00:08 +00001196 Results.AddResult(Result("class", CCP_Type));
1197 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001198
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001199 // typename qualified-id
1200 CodeCompletionString *Pattern = new CodeCompletionString;
1201 Pattern->AddTypedTextChunk("typename");
1202 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1203 Pattern->AddPlaceholderChunk("qualifier");
1204 Pattern->AddTextChunk("::");
1205 Pattern->AddPlaceholderChunk("name");
1206 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001207
Douglas Gregor86d9a522009-09-21 16:56:56 +00001208 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001209 Results.AddResult(Result("auto", CCP_Type));
1210 Results.AddResult(Result("char16_t", CCP_Type));
1211 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001212
1213 CodeCompletionString *Pattern = new CodeCompletionString;
1214 Pattern->AddTypedTextChunk("decltype");
1215 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1216 Pattern->AddPlaceholderChunk("expression");
1217 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1218 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001219 }
1220 }
1221
1222 // GNU extensions
1223 if (LangOpts.GNUMode) {
1224 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001225 // Results.AddResult(Result("_Decimal32"));
1226 // Results.AddResult(Result("_Decimal64"));
1227 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001228
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001229 CodeCompletionString *Pattern = new CodeCompletionString;
1230 Pattern->AddTypedTextChunk("typeof");
1231 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1232 Pattern->AddPlaceholderChunk("expression");
1233 Results.AddResult(Result(Pattern));
1234
1235 Pattern = new CodeCompletionString;
1236 Pattern->AddTypedTextChunk("typeof");
1237 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1238 Pattern->AddPlaceholderChunk("type");
1239 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1240 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001241 }
1242}
1243
John McCallf312b1e2010-08-26 23:41:50 +00001244static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001245 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001246 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001247 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001248 // Note: we don't suggest either "auto" or "register", because both
1249 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1250 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001251 Results.AddResult(Result("extern"));
1252 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001253}
1254
John McCallf312b1e2010-08-26 23:41:50 +00001255static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001256 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001257 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001258 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001259 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001260 case Sema::PCC_Class:
1261 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001262 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001263 Results.AddResult(Result("explicit"));
1264 Results.AddResult(Result("friend"));
1265 Results.AddResult(Result("mutable"));
1266 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001267 }
1268 // Fall through
1269
John McCallf312b1e2010-08-26 23:41:50 +00001270 case Sema::PCC_ObjCInterface:
1271 case Sema::PCC_ObjCImplementation:
1272 case Sema::PCC_Namespace:
1273 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001274 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001275 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001276 break;
1277
John McCallf312b1e2010-08-26 23:41:50 +00001278 case Sema::PCC_ObjCInstanceVariableList:
1279 case Sema::PCC_Expression:
1280 case Sema::PCC_Statement:
1281 case Sema::PCC_ForInit:
1282 case Sema::PCC_Condition:
1283 case Sema::PCC_RecoveryInFunction:
1284 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001285 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001286 break;
1287 }
1288}
1289
Douglas Gregorbca403c2010-01-13 23:51:12 +00001290static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1291static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1292static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001293 ResultBuilder &Results,
1294 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001295static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001296 ResultBuilder &Results,
1297 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001298static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001299 ResultBuilder &Results,
1300 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001301static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001302
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001303static void AddTypedefResult(ResultBuilder &Results) {
1304 CodeCompletionString *Pattern = new CodeCompletionString;
1305 Pattern->AddTypedTextChunk("typedef");
1306 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1307 Pattern->AddPlaceholderChunk("type");
1308 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1309 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001310 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001311}
1312
John McCallf312b1e2010-08-26 23:41:50 +00001313static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001314 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001315 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001316 case Sema::PCC_Namespace:
1317 case Sema::PCC_Class:
1318 case Sema::PCC_ObjCInstanceVariableList:
1319 case Sema::PCC_Template:
1320 case Sema::PCC_MemberTemplate:
1321 case Sema::PCC_Statement:
1322 case Sema::PCC_RecoveryInFunction:
1323 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001324 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001325 return true;
1326
John McCallf312b1e2010-08-26 23:41:50 +00001327 case Sema::PCC_Expression:
1328 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001329 return LangOpts.CPlusPlus;
1330
1331 case Sema::PCC_ObjCInterface:
1332 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001333 return false;
1334
John McCallf312b1e2010-08-26 23:41:50 +00001335 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001336 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001337 }
1338
1339 return false;
1340}
1341
Douglas Gregor01dfea02010-01-10 23:08:15 +00001342/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001343static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001344 Scope *S,
1345 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001346 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001347 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001348 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001349 case Sema::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001350 if (SemaRef.getLangOptions().CPlusPlus) {
1351 CodeCompletionString *Pattern = 0;
1352
1353 if (Results.includeCodePatterns()) {
1354 // namespace <identifier> { declarations }
1355 CodeCompletionString *Pattern = new CodeCompletionString;
1356 Pattern->AddTypedTextChunk("namespace");
1357 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1358 Pattern->AddPlaceholderChunk("identifier");
1359 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1360 Pattern->AddPlaceholderChunk("declarations");
1361 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1362 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1363 Results.AddResult(Result(Pattern));
1364 }
1365
Douglas Gregor01dfea02010-01-10 23:08:15 +00001366 // namespace identifier = identifier ;
1367 Pattern = new CodeCompletionString;
1368 Pattern->AddTypedTextChunk("namespace");
1369 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001370 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001371 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001372 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001373 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001374
1375 // Using directives
1376 Pattern = new CodeCompletionString;
1377 Pattern->AddTypedTextChunk("using");
1378 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1379 Pattern->AddTextChunk("namespace");
1380 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1381 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001382 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001383
1384 // asm(string-literal)
1385 Pattern = new CodeCompletionString;
1386 Pattern->AddTypedTextChunk("asm");
1387 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1388 Pattern->AddPlaceholderChunk("string-literal");
1389 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001390 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001391
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001392 if (Results.includeCodePatterns()) {
1393 // Explicit template instantiation
1394 Pattern = new CodeCompletionString;
1395 Pattern->AddTypedTextChunk("template");
1396 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1397 Pattern->AddPlaceholderChunk("declaration");
1398 Results.AddResult(Result(Pattern));
1399 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001400 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001401
1402 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001403 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001404
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001405 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001406 // Fall through
1407
John McCallf312b1e2010-08-26 23:41:50 +00001408 case Sema::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001409 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001410 // Using declaration
1411 CodeCompletionString *Pattern = new CodeCompletionString;
1412 Pattern->AddTypedTextChunk("using");
1413 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001414 Pattern->AddPlaceholderChunk("qualifier");
1415 Pattern->AddTextChunk("::");
1416 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001417 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001418
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001419 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001420 if (SemaRef.CurContext->isDependentContext()) {
1421 Pattern = new CodeCompletionString;
1422 Pattern->AddTypedTextChunk("using");
1423 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1424 Pattern->AddTextChunk("typename");
1425 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001426 Pattern->AddPlaceholderChunk("qualifier");
1427 Pattern->AddTextChunk("::");
1428 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001429 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001430 }
1431
John McCallf312b1e2010-08-26 23:41:50 +00001432 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001433 AddTypedefResult(Results);
1434
Douglas Gregor01dfea02010-01-10 23:08:15 +00001435 // public:
1436 Pattern = new CodeCompletionString;
1437 Pattern->AddTypedTextChunk("public");
1438 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001439 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001440
1441 // protected:
1442 Pattern = new CodeCompletionString;
1443 Pattern->AddTypedTextChunk("protected");
1444 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001445 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001446
1447 // private:
1448 Pattern = new CodeCompletionString;
1449 Pattern->AddTypedTextChunk("private");
1450 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001451 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001452 }
1453 }
1454 // Fall through
1455
John McCallf312b1e2010-08-26 23:41:50 +00001456 case Sema::PCC_Template:
1457 case Sema::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001458 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001459 // template < parameters >
1460 CodeCompletionString *Pattern = new CodeCompletionString;
1461 Pattern->AddTypedTextChunk("template");
1462 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1463 Pattern->AddPlaceholderChunk("parameters");
1464 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001465 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001466 }
1467
Douglas Gregorbca403c2010-01-13 23:51:12 +00001468 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1469 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001470 break;
1471
John McCallf312b1e2010-08-26 23:41:50 +00001472 case Sema::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001473 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1474 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1475 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001476 break;
1477
John McCallf312b1e2010-08-26 23:41:50 +00001478 case Sema::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001479 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1480 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1481 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001482 break;
1483
John McCallf312b1e2010-08-26 23:41:50 +00001484 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001485 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001486 break;
1487
John McCallf312b1e2010-08-26 23:41:50 +00001488 case Sema::PCC_RecoveryInFunction:
1489 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001490 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001491
1492 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001493 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001494 Pattern = new CodeCompletionString;
1495 Pattern->AddTypedTextChunk("try");
1496 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1497 Pattern->AddPlaceholderChunk("statements");
1498 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1499 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1500 Pattern->AddTextChunk("catch");
1501 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1502 Pattern->AddPlaceholderChunk("declaration");
1503 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1504 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1505 Pattern->AddPlaceholderChunk("statements");
1506 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1507 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001508 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001509 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001510 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001511 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001512
Douglas Gregord8e8a582010-05-25 21:41:55 +00001513 if (Results.includeCodePatterns()) {
1514 // if (condition) { statements }
1515 Pattern = new CodeCompletionString;
1516 Pattern->AddTypedTextChunk("if");
1517 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1518 if (SemaRef.getLangOptions().CPlusPlus)
1519 Pattern->AddPlaceholderChunk("condition");
1520 else
1521 Pattern->AddPlaceholderChunk("expression");
1522 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1523 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1524 Pattern->AddPlaceholderChunk("statements");
1525 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1526 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1527 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001528
Douglas Gregord8e8a582010-05-25 21:41:55 +00001529 // switch (condition) { }
1530 Pattern = new CodeCompletionString;
1531 Pattern->AddTypedTextChunk("switch");
1532 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1533 if (SemaRef.getLangOptions().CPlusPlus)
1534 Pattern->AddPlaceholderChunk("condition");
1535 else
1536 Pattern->AddPlaceholderChunk("expression");
1537 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1538 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1539 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1540 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1541 Results.AddResult(Result(Pattern));
1542 }
1543
Douglas Gregor01dfea02010-01-10 23:08:15 +00001544 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001545 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001546 // case expression:
1547 Pattern = new CodeCompletionString;
1548 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001549 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001550 Pattern->AddPlaceholderChunk("expression");
1551 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001552 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001553
1554 // default:
1555 Pattern = new CodeCompletionString;
1556 Pattern->AddTypedTextChunk("default");
1557 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001558 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001559 }
1560
Douglas Gregord8e8a582010-05-25 21:41:55 +00001561 if (Results.includeCodePatterns()) {
1562 /// while (condition) { statements }
1563 Pattern = new CodeCompletionString;
1564 Pattern->AddTypedTextChunk("while");
1565 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1566 if (SemaRef.getLangOptions().CPlusPlus)
1567 Pattern->AddPlaceholderChunk("condition");
1568 else
1569 Pattern->AddPlaceholderChunk("expression");
1570 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1571 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1572 Pattern->AddPlaceholderChunk("statements");
1573 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1574 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1575 Results.AddResult(Result(Pattern));
1576
1577 // do { statements } while ( expression );
1578 Pattern = new CodeCompletionString;
1579 Pattern->AddTypedTextChunk("do");
1580 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1581 Pattern->AddPlaceholderChunk("statements");
1582 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1583 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1584 Pattern->AddTextChunk("while");
1585 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001586 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001587 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1588 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001589
Douglas Gregord8e8a582010-05-25 21:41:55 +00001590 // for ( for-init-statement ; condition ; expression ) { statements }
1591 Pattern = new CodeCompletionString;
1592 Pattern->AddTypedTextChunk("for");
1593 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1594 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1595 Pattern->AddPlaceholderChunk("init-statement");
1596 else
1597 Pattern->AddPlaceholderChunk("init-expression");
1598 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1599 Pattern->AddPlaceholderChunk("condition");
1600 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1601 Pattern->AddPlaceholderChunk("inc-expression");
1602 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1603 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
Douglas Gregor5a9c0bc2010-10-08 20:39:29 +00001604 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
Douglas Gregord8e8a582010-05-25 21:41:55 +00001605 Pattern->AddPlaceholderChunk("statements");
1606 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1607 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1608 Results.AddResult(Result(Pattern));
1609 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001610
1611 if (S->getContinueParent()) {
1612 // continue ;
1613 Pattern = new CodeCompletionString;
1614 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001615 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001616 }
1617
1618 if (S->getBreakParent()) {
1619 // break ;
1620 Pattern = new CodeCompletionString;
1621 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001622 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001623 }
1624
1625 // "return expression ;" or "return ;", depending on whether we
1626 // know the function is void or not.
1627 bool isVoid = false;
1628 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1629 isVoid = Function->getResultType()->isVoidType();
1630 else if (ObjCMethodDecl *Method
1631 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1632 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001633 else if (SemaRef.getCurBlock() &&
1634 !SemaRef.getCurBlock()->ReturnType.isNull())
1635 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001636 Pattern = new CodeCompletionString;
1637 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001638 if (!isVoid) {
1639 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001640 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001641 }
Douglas Gregora4477812010-01-14 16:01:26 +00001642 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001643
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001644 // goto identifier ;
1645 Pattern = new CodeCompletionString;
1646 Pattern->AddTypedTextChunk("goto");
1647 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1648 Pattern->AddPlaceholderChunk("label");
1649 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001650
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001651 // Using directives
1652 Pattern = new CodeCompletionString;
1653 Pattern->AddTypedTextChunk("using");
1654 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1655 Pattern->AddTextChunk("namespace");
1656 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1657 Pattern->AddPlaceholderChunk("identifier");
1658 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001659 }
1660
1661 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001662 case Sema::PCC_ForInit:
1663 case Sema::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001664 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001665 // Fall through: conditions and statements can have expressions.
1666
Douglas Gregor02688102010-09-14 23:59:36 +00001667 case Sema::PCC_ParenthesizedExpression:
John McCallf312b1e2010-08-26 23:41:50 +00001668 case Sema::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001669 CodeCompletionString *Pattern = 0;
1670 if (SemaRef.getLangOptions().CPlusPlus) {
1671 // 'this', if we're in a non-static member function.
1672 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1673 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001674 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001675
1676 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001677 Results.AddResult(Result("true"));
1678 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001679
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001680 // dynamic_cast < type-id > ( expression )
1681 Pattern = new CodeCompletionString;
1682 Pattern->AddTypedTextChunk("dynamic_cast");
1683 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1684 Pattern->AddPlaceholderChunk("type");
1685 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1686 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1687 Pattern->AddPlaceholderChunk("expression");
1688 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1689 Results.AddResult(Result(Pattern));
1690
1691 // static_cast < type-id > ( expression )
1692 Pattern = new CodeCompletionString;
1693 Pattern->AddTypedTextChunk("static_cast");
1694 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1695 Pattern->AddPlaceholderChunk("type");
1696 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1697 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1698 Pattern->AddPlaceholderChunk("expression");
1699 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1700 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001701
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001702 // reinterpret_cast < type-id > ( expression )
1703 Pattern = new CodeCompletionString;
1704 Pattern->AddTypedTextChunk("reinterpret_cast");
1705 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1706 Pattern->AddPlaceholderChunk("type");
1707 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1708 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1709 Pattern->AddPlaceholderChunk("expression");
1710 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1711 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001712
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001713 // const_cast < type-id > ( expression )
1714 Pattern = new CodeCompletionString;
1715 Pattern->AddTypedTextChunk("const_cast");
1716 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1717 Pattern->AddPlaceholderChunk("type");
1718 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1719 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1720 Pattern->AddPlaceholderChunk("expression");
1721 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1722 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001723
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001724 // typeid ( expression-or-type )
1725 Pattern = new CodeCompletionString;
1726 Pattern->AddTypedTextChunk("typeid");
1727 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1728 Pattern->AddPlaceholderChunk("expression-or-type");
1729 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1730 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001731
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001732 // new T ( ... )
1733 Pattern = new CodeCompletionString;
1734 Pattern->AddTypedTextChunk("new");
1735 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1736 Pattern->AddPlaceholderChunk("type");
1737 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1738 Pattern->AddPlaceholderChunk("expressions");
1739 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1740 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001741
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001742 // new T [ ] ( ... )
1743 Pattern = new CodeCompletionString;
1744 Pattern->AddTypedTextChunk("new");
1745 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1746 Pattern->AddPlaceholderChunk("type");
1747 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1748 Pattern->AddPlaceholderChunk("size");
1749 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1750 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1751 Pattern->AddPlaceholderChunk("expressions");
1752 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1753 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001754
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001755 // delete expression
1756 Pattern = new CodeCompletionString;
1757 Pattern->AddTypedTextChunk("delete");
1758 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1759 Pattern->AddPlaceholderChunk("expression");
1760 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001761
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001762 // delete [] expression
1763 Pattern = new CodeCompletionString;
1764 Pattern->AddTypedTextChunk("delete");
1765 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1766 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1767 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1768 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1769 Pattern->AddPlaceholderChunk("expression");
1770 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001771
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001772 // throw expression
1773 Pattern = new CodeCompletionString;
1774 Pattern->AddTypedTextChunk("throw");
1775 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1776 Pattern->AddPlaceholderChunk("expression");
1777 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001778
1779 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001780 }
1781
1782 if (SemaRef.getLangOptions().ObjC1) {
1783 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001784 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1785 // The interface can be NULL.
1786 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1787 if (ID->getSuperClass())
1788 Results.AddResult(Result("super"));
1789 }
1790
Douglas Gregorbca403c2010-01-13 23:51:12 +00001791 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001792 }
1793
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001794 // sizeof expression
1795 Pattern = new CodeCompletionString;
1796 Pattern->AddTypedTextChunk("sizeof");
1797 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1798 Pattern->AddPlaceholderChunk("expression-or-type");
1799 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1800 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001801 break;
1802 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001803
John McCallf312b1e2010-08-26 23:41:50 +00001804 case Sema::PCC_Type:
Douglas Gregord32b0222010-08-24 01:06:58 +00001805 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001806 }
1807
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001808 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1809 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001810
John McCallf312b1e2010-08-26 23:41:50 +00001811 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001812 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001813}
1814
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001815/// \brief If the given declaration has an associated type, add it as a result
1816/// type chunk.
1817static void AddResultTypeChunk(ASTContext &Context,
1818 NamedDecl *ND,
1819 CodeCompletionString *Result) {
1820 if (!ND)
1821 return;
Douglas Gregor6f942b22010-09-21 16:06:22 +00001822
1823 // Skip constructors and conversion functions, which have their return types
1824 // built into their names.
1825 if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND))
1826 return;
1827
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001828 // Determine the type of the declaration (if it has a type).
Douglas Gregor6f942b22010-09-21 16:06:22 +00001829 QualType T;
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001830 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1831 T = Function->getResultType();
1832 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1833 T = Method->getResultType();
1834 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1835 T = FunTmpl->getTemplatedDecl()->getResultType();
1836 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1837 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1838 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1839 /* Do nothing: ignore unresolved using declarations*/
1840 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1841 T = Value->getType();
1842 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1843 T = Property->getType();
1844
1845 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1846 return;
1847
Douglas Gregor84139d62010-04-05 21:25:31 +00001848 PrintingPolicy Policy(Context.PrintingPolicy);
1849 Policy.AnonymousTagLocations = false;
1850
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001851 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001852 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001853 Result->AddResultTypeChunk(TypeStr);
1854}
1855
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001856static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1857 CodeCompletionString *Result) {
1858 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1859 if (Sentinel->getSentinel() == 0) {
1860 if (Context.getLangOptions().ObjC1 &&
1861 Context.Idents.get("nil").hasMacroDefinition())
1862 Result->AddTextChunk(", nil");
1863 else if (Context.Idents.get("NULL").hasMacroDefinition())
1864 Result->AddTextChunk(", NULL");
1865 else
1866 Result->AddTextChunk(", (void*)0");
1867 }
1868}
1869
Douglas Gregor83482d12010-08-24 16:15:59 +00001870static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregoraba48082010-08-29 19:47:46 +00001871 ParmVarDecl *Param,
1872 bool SuppressName = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00001873 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1874 if (Param->getType()->isDependentType() ||
1875 !Param->getType()->isBlockPointerType()) {
1876 // The argument for a dependent or non-block parameter is a placeholder
1877 // containing that parameter's type.
1878 std::string Result;
1879
Douglas Gregoraba48082010-08-29 19:47:46 +00001880 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001881 Result = Param->getIdentifier()->getName();
1882
1883 Param->getType().getAsStringInternal(Result,
1884 Context.PrintingPolicy);
1885
1886 if (ObjCMethodParam) {
1887 Result = "(" + Result;
1888 Result += ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00001889 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00001890 Result += Param->getIdentifier()->getName();
1891 }
1892 return Result;
1893 }
1894
1895 // The argument for a block pointer parameter is a block literal with
1896 // the appropriate type.
1897 FunctionProtoTypeLoc *Block = 0;
1898 TypeLoc TL;
1899 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1900 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1901 while (true) {
1902 // Look through typedefs.
1903 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1904 if (TypeSourceInfo *InnerTSInfo
1905 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1906 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1907 continue;
1908 }
1909 }
1910
1911 // Look through qualified types
1912 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1913 TL = QualifiedTL->getUnqualifiedLoc();
1914 continue;
1915 }
1916
1917 // Try to get the function prototype behind the block pointer type,
1918 // then we're done.
1919 if (BlockPointerTypeLoc *BlockPtr
1920 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1921 TL = BlockPtr->getPointeeLoc();
1922 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 Gregor38276252010-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 Gregorc2760bc2010-10-02 23:49:58 +00001956 else
1957 Result += "(void)";
Douglas Gregor38276252010-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 Gregore17794f2010-08-31 05:13:43 +00001969 }
Douglas Gregor38276252010-09-08 22:47:51 +00001970
Douglas Gregorc2760bc2010-10-02 23:49:58 +00001971 if (Param->getIdentifier())
1972 Result += Param->getIdentifier()->getName();
1973
Douglas Gregor83482d12010-08-24 16:15:59 +00001974 return Result;
1975}
1976
Douglas Gregor86d9a522009-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 Gregor0c8296d2009-11-07 00:00:49 +00001981 typedef CodeCompletionString::Chunk Chunk;
1982
Douglas Gregor86d9a522009-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 Gregor0c8296d2009-11-07 00:00:49 +00001997 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001998
1999 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00002000 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
2001
Douglas Gregore17794f2010-08-31 05:13:43 +00002002 if (Function->isVariadic() && P == N - 1)
2003 PlaceholderStr += ", ...";
2004
Douglas Gregor86d9a522009-09-21 16:56:56 +00002005 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002006 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002007 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00002008
2009 if (const FunctionProtoType *Proto
2010 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002011 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002012 if (Proto->getNumArgs() == 0)
2013 CCStr->AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002014
2015 MaybeAddSentinel(Context, Function, CCStr);
2016 }
Douglas Gregor86d9a522009-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 Gregor0c8296d2009-11-07 00:00:49 +00002024 typedef CodeCompletionString::Chunk Chunk;
2025
Douglas Gregor86d9a522009-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 Gregor0c8296d2009-11-07 00:00:49 +00002081 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002082
2083 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002084 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002085 }
2086}
2087
Douglas Gregorb9d0ef72009-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 Gregora61a8792009-12-11 18:44:16 +00002090static void
2091AddQualifierToCompletionString(CodeCompletionString *Result,
2092 NestedNameSpecifier *Qualifier,
2093 bool QualifierIsInformative,
2094 ASTContext &Context) {
Douglas Gregorb9d0ef72009-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 Gregor0563c262009-09-22 23:15:58 +00002103 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002104 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00002105 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002106 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002107}
2108
Douglas Gregora61a8792009-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 Gregor6f942b22010-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 Gregor86d9a522009-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 McCall0a2c5e22010-08-25 06:19:51 +00002181CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor6f942b22010-09-21 16:06:22 +00002182 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002183 typedef CodeCompletionString::Chunk Chunk;
2184
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002185 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002186 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002187
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002188 if (!Result)
2189 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002190
2191 if (Kind == RK_Keyword) {
2192 Result->AddTypedTextChunk(Keyword);
2193 return Result;
2194 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002195
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002196 if (Kind == RK_Macro) {
2197 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-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 Gregor3f7c7f42009-10-30 16:50:04 +00002204
2205 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002206 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-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 Gregor0c8296d2009-11-07 00:00:49 +00002210 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002211
2212 if (!MI->isVariadic() || A != AEnd - 1) {
2213 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00002214 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-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 Kramer660cc182009-11-29 20:18:50 +00002226 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002227 }
2228 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002229 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002230 return Result;
2231 }
2232
Douglas Gregord8e8a582010-05-25 21:41:55 +00002233 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002234 NamedDecl *ND = Declaration;
2235
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002236 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002237 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002238 Result->AddTextChunk("::");
2239 return Result;
2240 }
2241
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002242 AddResultTypeChunk(S.Context, ND, Result);
2243
Douglas Gregor86d9a522009-09-21 16:56:56 +00002244 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002245 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2246 S.Context);
Douglas Gregor6f942b22010-09-21 16:06:22 +00002247 AddTypedNameChunk(S.Context, ND, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002248 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002249 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002250 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002251 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002252 return Result;
2253 }
2254
2255 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002256 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2257 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002258 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Douglas Gregor6f942b22010-09-21 16:06:22 +00002259 AddTypedNameChunk(S.Context, Function, Result);
2260
Douglas Gregor86d9a522009-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 Gregor0c8296d2009-11-07 00:00:49 +00002283 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-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 Gregor0c8296d2009-11-07 00:00:49 +00002295 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002296 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2297 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002298 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002299 }
2300
2301 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002302 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002303 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002304 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002305 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002306 return Result;
2307 }
2308
2309 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002310 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2311 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002312 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002313 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002314 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002315 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002316 return Result;
2317 }
2318
Douglas Gregor9630eb62009-11-17 16:44:22 +00002319 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-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 Gregord3c68542009-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 Gregor9630eb62009-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 Gregord3c68542009-11-19 01:08:35 +00002343 std::string Keyword;
2344 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002345 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002346 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2347 Keyword += II->getName().str();
2348 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002349 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002350 Result->AddInformativeChunk(Keyword);
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002351 else
Douglas Gregord3c68542009-11-19 01:08:35 +00002352 Result->AddTypedTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002353 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002354
2355 // If we're before the starting parameter, skip the placeholder.
2356 if (Idx < StartParameter)
2357 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002358
2359 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002360
2361 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Douglas Gregoraba48082010-08-29 19:47:46 +00002362 Arg = FormatFunctionParameter(S.Context, *P, true);
Douglas Gregor83482d12010-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 Gregoraba48082010-08-29 19:47:46 +00002367 if (DeclaringEntity || AllParametersAreInformative)
2368 Arg += II->getName().str();
Douglas Gregor83482d12010-08-24 16:15:59 +00002369 }
2370
Douglas Gregore17794f2010-08-31 05:13:43 +00002371 if (Method->isVariadic() && (P + 1) == PEnd)
2372 Arg += ", ...";
2373
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002374 if (DeclaringEntity)
2375 Result->AddTextChunk(Arg);
2376 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002377 Result->AddInformativeChunk(Arg);
2378 else
2379 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002380 }
2381
Douglas Gregor2a17af02009-12-23 00:21:46 +00002382 if (Method->isVariadic()) {
Douglas Gregore17794f2010-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 Gregoraaa107a2010-08-23 23:51:41 +00002391
2392 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002393 }
2394
Douglas Gregor9630eb62009-11-17 16:44:22 +00002395 return Result;
2396 }
2397
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002398 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002399 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2400 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002401
2402 Result->AddTypedTextChunk(ND->getNameAsString());
2403 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002404}
2405
Douglas Gregor86d802e2009-09-23 00:34:09 +00002406CodeCompletionString *
2407CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2408 unsigned CurrentArg,
Douglas Gregor32be4a52010-10-11 21:37:58 +00002409 Sema &S,
2410 CodeCompletionString *Result) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002411 typedef CodeCompletionString::Chunk Chunk;
2412
Douglas Gregor32be4a52010-10-11 21:37:58 +00002413 if (!Result)
2414 Result = new CodeCompletionString;
Douglas Gregor86d802e2009-09-23 00:34:09 +00002415 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002416 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-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 Kramer660cc182009-11-29 20:18:50 +00002424 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-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 Gregor86d802e2009-09-23 00:34:09 +00002428 return Result;
2429 }
2430
2431 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002432 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002433 else
2434 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002435 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002436
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002437 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-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 Gregor0c8296d2009-11-07 00:00:49 +00002441 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-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 Gregor0c8296d2009-11-07 00:00:49 +00002456 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002457 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002458 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002459 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002460 }
2461
2462 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002463 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002464 if (CurrentArg < NumParams)
2465 Result->AddTextChunk("...");
2466 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002467 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002468 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002469 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002470
2471 return Result;
2472}
2473
Douglas Gregor1827e102010-08-16 16:18:59 +00002474unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
Douglas Gregorb05496d2010-09-20 21:11:48 +00002475 const LangOptions &LangOpts,
Douglas Gregor1827e102010-08-16 16:18:59 +00002476 bool PreferredTypeIsPointer) {
2477 unsigned Priority = CCP_Macro;
2478
Douglas Gregorb05496d2010-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 Gregor1827e102010-08-16 16:18:59 +00002482 Priority = CCP_Constant;
2483 if (PreferredTypeIsPointer)
2484 Priority = Priority / CCF_SimilarTypeMatch;
Douglas Gregorb05496d2010-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 Gregor1827e102010-08-16 16:18:59 +00002494
2495 return Priority;
2496}
2497
Douglas Gregore8d7beb2010-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 Gregor590c7d52010-07-08 20:55:51 +00002561static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2562 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002563 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002564
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002565 Results.EnterNewScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002566
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002567 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2568 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002569 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002570 Results.AddResult(Result(M->first,
2571 getMacroUsagePriority(M->first->getName(),
Douglas Gregorb05496d2010-09-20 21:11:48 +00002572 PP.getLangOptions(),
Douglas Gregor1827e102010-08-16 16:18:59 +00002573 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002574 }
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002575
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002576 Results.ExitScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002577
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002578}
2579
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002580static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2581 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002582 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002583
2584 Results.EnterNewScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002585
Douglas Gregoraa5f77b2010-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 Dunbar3a2838d2009-11-13 08:58:20 +00002593static void HandleCodeCompleteResults(Sema *S,
2594 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002595 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002596 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002597 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002598 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002599 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002600
2601 for (unsigned I = 0; I != NumResults; ++I)
2602 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002603}
2604
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002605static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2606 Sema::ParserCompletionContext PCC) {
2607 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002608 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002609 return CodeCompletionContext::CCC_TopLevel;
2610
John McCallf312b1e2010-08-26 23:41:50 +00002611 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002612 return CodeCompletionContext::CCC_ClassStructUnion;
2613
John McCallf312b1e2010-08-26 23:41:50 +00002614 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002615 return CodeCompletionContext::CCC_ObjCInterface;
2616
John McCallf312b1e2010-08-26 23:41:50 +00002617 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002618 return CodeCompletionContext::CCC_ObjCImplementation;
2619
John McCallf312b1e2010-08-26 23:41:50 +00002620 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002621 return CodeCompletionContext::CCC_ObjCIvarList;
2622
John McCallf312b1e2010-08-26 23:41:50 +00002623 case Sema::PCC_Template:
2624 case Sema::PCC_MemberTemplate:
Douglas Gregor52779fb2010-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 McCallf312b1e2010-08-26 23:41:50 +00002632 case Sema::PCC_RecoveryInFunction:
Douglas Gregor52779fb2010-09-23 23:01:17 +00002633 return CodeCompletionContext::CCC_Recovery;
Douglas Gregora5450a02010-10-18 22:01:46 +00002634
John McCallf312b1e2010-08-26 23:41:50 +00002635 case Sema::PCC_ForInit:
Douglas Gregora5450a02010-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 McCallf312b1e2010-08-26 23:41:50 +00002643 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002644 return CodeCompletionContext::CCC_Expression;
2645
John McCallf312b1e2010-08-26 23:41:50 +00002646 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002647 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002648
John McCallf312b1e2010-08-26 23:41:50 +00002649 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00002650 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00002651
2652 case Sema::PCC_ParenthesizedExpression:
2653 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002654 }
2655
2656 return CodeCompletionContext::CCC_Other;
2657}
2658
Douglas Gregorf6961522010-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 Gregor01dfea02010-01-10 23:08:15 +00002732void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002733 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002734 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00002735 ResultBuilder Results(*this,
2736 mapCodeCompletionContext(*this, CompletionContext));
Douglas Gregorf6961522010-08-27 21:18:54 +00002737 Results.EnterNewScope();
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002738
Douglas Gregor01dfea02010-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 Gregore6b1bb62010-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 Gregor72db1082010-08-24 01:11:00 +00002750 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002751 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2752 break;
2753
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002754 case PCC_Statement:
Douglas Gregor02688102010-09-14 23:59:36 +00002755 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002756 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002757 case PCC_ForInit:
2758 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002759 if (WantTypesInContext(CompletionContext, getLangOptions()))
2760 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2761 else
2762 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00002763
2764 if (getLangOptions().CPlusPlus)
2765 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002766 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002767
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002768 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002769 // Unfiltered
2770 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002771 }
2772
Douglas Gregor3cdee122010-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 Gregor1ca6ae82010-01-14 01:09:38 +00002780 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002781 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2782 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002783
Douglas Gregorbca403c2010-01-13 23:51:12 +00002784 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002785 Results.ExitScope();
2786
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002787 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00002788 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-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 Gregoraa5f77b2010-08-23 21:54:33 +00002807 }
2808
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002809 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002810 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002811
Douglas Gregorcee9ff12010-09-20 22:39:41 +00002812 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002813 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002814}
2815
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002816static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
2817 ParsedType Receiver,
2818 IdentifierInfo **SelIdents,
2819 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00002820 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-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 McCall0a2c5e22010-08-25 06:19:51 +00002827 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00002828 ResultBuilder Results(*this,
2829 AllowNestedNameSpecifiers
2830 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2831 : CodeCompletionContext::CCC_Name);
Douglas Gregor2ccccb32010-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 Gregor52779fb2010-09-23 23:01:17 +00002848 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002849 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2850 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2851 CodeCompleter->includeGlobals());
Douglas Gregor52779fb2010-09-23 23:01:17 +00002852 Results.setFilter(0);
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002853 }
2854 }
2855 Results.ExitScope();
2856
Douglas Gregorc7b6d882010-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 Gregor70c5ac72010-09-20 23:34:21 +00002875 AddClassMessageCompletions(*this, S, T, 0, 0, false, false, Results);
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002876 }
2877
Douglas Gregor4497dd42010-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 Gregor52779fb2010-09-23 23:01:17 +00002881 HandleCodeCompleteResults(this, CodeCompleter,
2882 Results.getCompletionContext(),
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002883 Results.data(), Results.size());
2884}
2885
Douglas Gregorfb629412010-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 Gregor5ac3bdb2010-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 Gregorf9578432010-07-28 21:50:18 +00002899///
2900/// \param IntegralConstantExpression Only permit integral constant
2901/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002902void Sema::CodeCompleteExpression(Scope *S,
2903 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002904 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00002905 ResultBuilder Results(*this, CodeCompletionContext::CCC_Expression);
Douglas Gregorfb629412010-08-23 21:17:50 +00002906 if (Data.ObjCCollection)
2907 Results.setFilter(&ResultBuilder::IsObjCCollection);
2908 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002909 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002910 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002911 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2912 else
2913 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-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 Gregor5ac3bdb2010-05-30 01:49:25 +00002921
2922 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002923 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2924 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002925
2926 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002927 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002928 Results.ExitScope();
2929
Douglas Gregor590c7d52010-07-08 20:55:51 +00002930 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002931 if (!Data.PreferredType.isNull())
2932 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2933 || Data.PreferredType->isMemberPointerType()
2934 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002935
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002936 if (S->getFnParent() &&
2937 !Data.ObjCCollection &&
2938 !Data.IntegralConstantExpression)
2939 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2940
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002941 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002942 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002943 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002944 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2945 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002946 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002947}
2948
Douglas Gregorac5fd842010-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 Gregor78edf512010-09-15 16:23:04 +00002954}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002955
Douglas Gregor95ac6552009-11-18 01:29:26 +00002956static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002957 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002958 DeclContext *CurContext,
2959 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002960 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002961
2962 // Add properties in this container.
2963 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2964 PEnd = Container->prop_end();
2965 P != PEnd;
2966 ++P)
2967 Results.MaybeAddResult(Result(*P, 0), CurContext);
2968
2969 // Add properties in referenced protocols.
2970 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2971 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2972 PEnd = Protocol->protocol_end();
2973 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002974 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002975 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002976 if (AllowCategories) {
2977 // Look through categories.
2978 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2979 Category; Category = Category->getNextClassCategory())
2980 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2981 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002982
2983 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002984 for (ObjCInterfaceDecl::all_protocol_iterator
2985 I = IFace->all_referenced_protocol_begin(),
2986 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002987 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002988
2989 // Look in the superclass.
2990 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002991 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2992 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002993 } else if (const ObjCCategoryDecl *Category
2994 = dyn_cast<ObjCCategoryDecl>(Container)) {
2995 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00002996 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
2997 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002998 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002999 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003000 }
3001}
3002
Douglas Gregor81b747b2009-09-17 21:32:03 +00003003void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
3004 SourceLocation OpLoc,
3005 bool IsArrow) {
3006 if (!BaseE || !CodeCompleter)
3007 return;
3008
John McCall0a2c5e22010-08-25 06:19:51 +00003009 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003010
Douglas Gregor81b747b2009-09-17 21:32:03 +00003011 Expr *Base = static_cast<Expr *>(BaseE);
3012 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003013
3014 if (IsArrow) {
3015 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
3016 BaseType = Ptr->getPointeeType();
3017 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00003018 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003019 else
3020 return;
3021 }
3022
Douglas Gregor52779fb2010-09-23 23:01:17 +00003023 ResultBuilder Results(*this,
3024 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
3025 BaseType),
3026 &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003027 Results.EnterNewScope();
3028 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00003029 // Indicate that we are performing a member access, and the cv-qualifiers
3030 // for the base object type.
3031 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
3032
Douglas Gregor95ac6552009-11-18 01:29:26 +00003033 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00003034 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00003035 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003036 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
3037 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003038
Douglas Gregor95ac6552009-11-18 01:29:26 +00003039 if (getLangOptions().CPlusPlus) {
3040 if (!Results.empty()) {
3041 // The "template" keyword can follow "->" or "." in the grammar.
3042 // However, we only want to suggest the template keyword if something
3043 // is dependent.
3044 bool IsDependent = BaseType->isDependentType();
3045 if (!IsDependent) {
3046 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
3047 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
3048 IsDependent = Ctx->isDependentContext();
3049 break;
3050 }
3051 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003052
Douglas Gregor95ac6552009-11-18 01:29:26 +00003053 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00003054 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003055 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003056 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003057 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
3058 // Objective-C property reference.
3059
3060 // Add property results based on our interface.
3061 const ObjCObjectPointerType *ObjCPtr
3062 = BaseType->getAsObjCInterfacePointerType();
3063 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00003064 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003065
3066 // Add properties from the protocols in a qualified interface.
3067 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
3068 E = ObjCPtr->qual_end();
3069 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00003070 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003071 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00003072 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00003073 // Objective-C instance variable access.
3074 ObjCInterfaceDecl *Class = 0;
3075 if (const ObjCObjectPointerType *ObjCPtr
3076 = BaseType->getAs<ObjCObjectPointerType>())
3077 Class = ObjCPtr->getInterfaceDecl();
3078 else
John McCallc12c5bb2010-05-15 11:32:37 +00003079 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00003080
3081 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00003082 if (Class) {
3083 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3084 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00003085 LookupVisibleDecls(Class, LookupMemberName, Consumer,
3086 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00003087 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003088 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003089
3090 // FIXME: How do we cope with isa?
3091
3092 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003093
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003094 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003095 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003096 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003097 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003098}
3099
Douglas Gregor374929f2009-09-18 15:37:17 +00003100void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
3101 if (!CodeCompleter)
3102 return;
3103
John McCall0a2c5e22010-08-25 06:19:51 +00003104 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003105 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003106 enum CodeCompletionContext::Kind ContextKind
3107 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00003108 switch ((DeclSpec::TST)TagSpec) {
3109 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003110 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003111 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003112 break;
3113
3114 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003115 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003116 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003117 break;
3118
3119 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00003120 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003121 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003122 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003123 break;
3124
3125 default:
3126 assert(false && "Unknown type specifier kind in CodeCompleteTag");
3127 return;
3128 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003129
Douglas Gregor52779fb2010-09-23 23:01:17 +00003130 ResultBuilder Results(*this, ContextKind);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003131 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00003132
3133 // First pass: look for tags.
3134 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00003135 LookupVisibleDecls(S, LookupTagName, Consumer,
3136 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00003137
Douglas Gregor8071e422010-08-15 06:18:01 +00003138 if (CodeCompleter->includeGlobals()) {
3139 // Second pass: look for nested name specifiers.
3140 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
3141 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
3142 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003143
Douglas Gregor52779fb2010-09-23 23:01:17 +00003144 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003145 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00003146}
3147
Douglas Gregor1a480c42010-08-27 17:35:51 +00003148void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00003149 ResultBuilder Results(*this, CodeCompletionContext::CCC_TypeQualifiers);
Douglas Gregor1a480c42010-08-27 17:35:51 +00003150 Results.EnterNewScope();
3151 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
3152 Results.AddResult("const");
3153 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
3154 Results.AddResult("volatile");
3155 if (getLangOptions().C99 &&
3156 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
3157 Results.AddResult("restrict");
3158 Results.ExitScope();
3159 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003160 Results.getCompletionContext(),
Douglas Gregor1a480c42010-08-27 17:35:51 +00003161 Results.data(), Results.size());
3162}
3163
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003164void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00003165 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003166 return;
3167
John McCall781472f2010-08-25 08:40:02 +00003168 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00003169 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00003170 CodeCompleteExpressionData Data(Switch->getCond()->getType());
3171 Data.IntegralConstantExpression = true;
3172 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003173 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00003174 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003175
3176 // Code-complete the cases of a switch statement over an enumeration type
3177 // by providing the list of
3178 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
3179
3180 // Determine which enumerators we have already seen in the switch statement.
3181 // FIXME: Ideally, we would also be able to look *past* the code-completion
3182 // token, in case we are code-completing in the middle of the switch and not
3183 // at the end. However, we aren't able to do so at the moment.
3184 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003185 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003186 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3187 SC = SC->getNextSwitchCase()) {
3188 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3189 if (!Case)
3190 continue;
3191
3192 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3193 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3194 if (EnumConstantDecl *Enumerator
3195 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3196 // We look into the AST of the case statement to determine which
3197 // enumerator was named. Alternatively, we could compute the value of
3198 // the integral constant expression, then compare it against the
3199 // values of each enumerator. However, value-based approach would not
3200 // work as well with C++ templates where enumerators declared within a
3201 // template are type- and value-dependent.
3202 EnumeratorsSeen.insert(Enumerator);
3203
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003204 // If this is a qualified-id, keep track of the nested-name-specifier
3205 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003206 //
3207 // switch (TagD.getKind()) {
3208 // case TagDecl::TK_enum:
3209 // break;
3210 // case XXX
3211 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003212 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003213 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3214 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003215 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003216 }
3217 }
3218
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003219 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3220 // If there are no prior enumerators in C++, check whether we have to
3221 // qualify the names of the enumerators that we suggest, because they
3222 // may not be visible in this scope.
3223 Qualifier = getRequiredQualification(Context, CurContext,
3224 Enum->getDeclContext());
3225
3226 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
3227 }
3228
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003229 // Add any enumerators that have not yet been mentioned.
Douglas Gregor52779fb2010-09-23 23:01:17 +00003230 ResultBuilder Results(*this, CodeCompletionContext::CCC_Expression);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003231 Results.EnterNewScope();
3232 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3233 EEnd = Enum->enumerator_end();
3234 E != EEnd; ++E) {
3235 if (EnumeratorsSeen.count(*E))
3236 continue;
3237
John McCall0a2c5e22010-08-25 06:19:51 +00003238 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00003239 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003240 }
3241 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003242
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003243 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00003244 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003245 HandleCodeCompleteResults(this, CodeCompleter,
3246 CodeCompletionContext::CCC_Expression,
3247 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003248}
3249
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003250namespace {
3251 struct IsBetterOverloadCandidate {
3252 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003253 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003254
3255 public:
John McCall5769d612010-02-08 23:07:23 +00003256 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3257 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003258
3259 bool
3260 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003261 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003262 }
3263 };
3264}
3265
Douglas Gregord28dcd72010-05-30 06:10:08 +00003266static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
3267 if (NumArgs && !Args)
3268 return true;
3269
3270 for (unsigned I = 0; I != NumArgs; ++I)
3271 if (!Args[I])
3272 return true;
3273
3274 return false;
3275}
3276
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003277void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
3278 ExprTy **ArgsIn, unsigned NumArgs) {
3279 if (!CodeCompleter)
3280 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003281
3282 // When we're code-completing for a call, we fall back to ordinary
3283 // name code-completion whenever we can't produce specific
3284 // results. We may want to revisit this strategy in the future,
3285 // e.g., by merging the two kinds of results.
3286
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003287 Expr *Fn = (Expr *)FnIn;
3288 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003289
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003290 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00003291 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00003292 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003293 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003294 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003295 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003296
John McCall3b4294e2009-12-16 12:17:52 +00003297 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003298 SourceLocation Loc = Fn->getExprLoc();
3299 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003300
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003301 // FIXME: What if we're calling something that isn't a function declaration?
3302 // FIXME: What if we're calling a pseudo-destructor?
3303 // FIXME: What if we're calling a member function?
3304
Douglas Gregorc0265402010-01-21 15:46:19 +00003305 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3306 llvm::SmallVector<ResultCandidate, 8> Results;
3307
John McCall3b4294e2009-12-16 12:17:52 +00003308 Expr *NakedFn = Fn->IgnoreParenCasts();
3309 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3310 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
3311 /*PartialOverloading=*/ true);
3312 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3313 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003314 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00003315 if (!getLangOptions().CPlusPlus ||
3316 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003317 Results.push_back(ResultCandidate(FDecl));
3318 else
John McCall86820f52010-01-26 01:37:31 +00003319 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00003320 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
3321 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00003322 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003323 }
John McCall3b4294e2009-12-16 12:17:52 +00003324 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003325
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003326 QualType ParamType;
3327
Douglas Gregorc0265402010-01-21 15:46:19 +00003328 if (!CandidateSet.empty()) {
3329 // Sort the overload candidate set by placing the best overloads first.
3330 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003331 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003332
Douglas Gregorc0265402010-01-21 15:46:19 +00003333 // Add the remaining viable overload candidates as code-completion reslults.
3334 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3335 CandEnd = CandidateSet.end();
3336 Cand != CandEnd; ++Cand) {
3337 if (Cand->Viable)
3338 Results.push_back(ResultCandidate(Cand->Function));
3339 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003340
3341 // From the viable candidates, try to determine the type of this parameter.
3342 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3343 if (const FunctionType *FType = Results[I].getFunctionType())
3344 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3345 if (NumArgs < Proto->getNumArgs()) {
3346 if (ParamType.isNull())
3347 ParamType = Proto->getArgType(NumArgs);
3348 else if (!Context.hasSameUnqualifiedType(
3349 ParamType.getNonReferenceType(),
3350 Proto->getArgType(NumArgs).getNonReferenceType())) {
3351 ParamType = QualType();
3352 break;
3353 }
3354 }
3355 }
3356 } else {
3357 // Try to determine the parameter type from the type of the expression
3358 // being called.
3359 QualType FunctionType = Fn->getType();
3360 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3361 FunctionType = Ptr->getPointeeType();
3362 else if (const BlockPointerType *BlockPtr
3363 = FunctionType->getAs<BlockPointerType>())
3364 FunctionType = BlockPtr->getPointeeType();
3365 else if (const MemberPointerType *MemPtr
3366 = FunctionType->getAs<MemberPointerType>())
3367 FunctionType = MemPtr->getPointeeType();
3368
3369 if (const FunctionProtoType *Proto
3370 = FunctionType->getAs<FunctionProtoType>()) {
3371 if (NumArgs < Proto->getNumArgs())
3372 ParamType = Proto->getArgType(NumArgs);
3373 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003374 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003375
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003376 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003377 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003378 else
3379 CodeCompleteExpression(S, ParamType);
3380
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003381 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00003382 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
3383 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003384}
3385
John McCalld226f652010-08-21 09:40:31 +00003386void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3387 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003388 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003389 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003390 return;
3391 }
3392
3393 CodeCompleteExpression(S, VD->getType());
3394}
3395
3396void Sema::CodeCompleteReturn(Scope *S) {
3397 QualType ResultType;
3398 if (isa<BlockDecl>(CurContext)) {
3399 if (BlockScopeInfo *BSI = getCurBlock())
3400 ResultType = BSI->ReturnType;
3401 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3402 ResultType = Function->getResultType();
3403 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3404 ResultType = Method->getResultType();
3405
3406 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003407 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003408 else
3409 CodeCompleteExpression(S, ResultType);
3410}
3411
3412void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3413 if (LHS)
3414 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3415 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003416 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003417}
3418
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003419void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003420 bool EnteringContext) {
3421 if (!SS.getScopeRep() || !CodeCompleter)
3422 return;
3423
Douglas Gregor86d9a522009-09-21 16:56:56 +00003424 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3425 if (!Ctx)
3426 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003427
3428 // Try to instantiate any non-dependent declaration contexts before
3429 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003430 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003431 return;
3432
Douglas Gregor52779fb2010-09-23 23:01:17 +00003433 ResultBuilder Results(*this, CodeCompletionContext::CCC_Name);
Douglas Gregorf6961522010-08-27 21:18:54 +00003434 Results.EnterNewScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00003435
Douglas Gregor86d9a522009-09-21 16:56:56 +00003436 // The "template" keyword can follow "::" in the grammar, but only
3437 // put it into the grammar if the nested-name-specifier is dependent.
3438 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3439 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003440 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00003441
3442 // Add calls to overridden virtual functions, if there are any.
3443 //
3444 // FIXME: This isn't wonderful, because we don't know whether we're actually
3445 // in a context that permits expressions. This is a general issue with
3446 // qualified-id completions.
3447 if (!EnteringContext)
3448 MaybeAddOverrideCalls(*this, Ctx, Results);
3449 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003450
Douglas Gregorf6961522010-08-27 21:18:54 +00003451 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3452 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
3453
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003454 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorf6961522010-08-27 21:18:54 +00003455 CodeCompletionContext::CCC_Name,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003456 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003457}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003458
3459void Sema::CodeCompleteUsing(Scope *S) {
3460 if (!CodeCompleter)
3461 return;
3462
Douglas Gregor52779fb2010-09-23 23:01:17 +00003463 ResultBuilder Results(*this,
3464 CodeCompletionContext::CCC_PotentiallyQualifiedName,
3465 &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003466 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003467
3468 // If we aren't in class scope, we could see the "namespace" keyword.
3469 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003470 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003471
3472 // After "using", we can see anything that would start a
3473 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003474 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003475 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3476 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003477 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003478
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003479 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003480 CodeCompletionContext::CCC_PotentiallyQualifiedName,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003481 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003482}
3483
3484void Sema::CodeCompleteUsingDirective(Scope *S) {
3485 if (!CodeCompleter)
3486 return;
3487
Douglas Gregor86d9a522009-09-21 16:56:56 +00003488 // After "using namespace", we expect to see a namespace name or namespace
3489 // alias.
Douglas Gregor52779fb2010-09-23 23:01:17 +00003490 ResultBuilder Results(*this, CodeCompletionContext::CCC_Namespace,
3491 &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003492 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003493 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003494 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3495 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003496 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003497 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003498 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003499 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003500}
3501
3502void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3503 if (!CodeCompleter)
3504 return;
3505
Douglas Gregor86d9a522009-09-21 16:56:56 +00003506 DeclContext *Ctx = (DeclContext *)S->getEntity();
3507 if (!S->getParent())
3508 Ctx = Context.getTranslationUnitDecl();
3509
Douglas Gregor52779fb2010-09-23 23:01:17 +00003510 bool SuppressedGlobalResults
3511 = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
3512
3513 ResultBuilder Results(*this,
3514 SuppressedGlobalResults
3515 ? CodeCompletionContext::CCC_Namespace
3516 : CodeCompletionContext::CCC_Other,
3517 &ResultBuilder::IsNamespace);
3518
3519 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00003520 // We only want to see those namespaces that have already been defined
3521 // within this scope, because its likely that the user is creating an
3522 // extended namespace declaration. Keep track of the most recent
3523 // definition of each namespace.
3524 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3525 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3526 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3527 NS != NSEnd; ++NS)
3528 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3529
3530 // Add the most recent definition (or extended definition) of each
3531 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003532 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003533 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3534 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3535 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003536 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003537 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003538 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003539 }
3540
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003541 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003542 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003543 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003544}
3545
3546void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3547 if (!CodeCompleter)
3548 return;
3549
Douglas Gregor86d9a522009-09-21 16:56:56 +00003550 // After "namespace", we expect to see a namespace or alias.
Douglas Gregor52779fb2010-09-23 23:01:17 +00003551 ResultBuilder Results(*this, CodeCompletionContext::CCC_Namespace,
3552 &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003553 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003554 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3555 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003556 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003557 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003558 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003559}
3560
Douglas Gregored8d3222009-09-18 20:05:18 +00003561void Sema::CodeCompleteOperatorName(Scope *S) {
3562 if (!CodeCompleter)
3563 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003564
John McCall0a2c5e22010-08-25 06:19:51 +00003565 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00003566 ResultBuilder Results(*this, CodeCompletionContext::CCC_Type,
3567 &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003568 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003569
Douglas Gregor86d9a522009-09-21 16:56:56 +00003570 // Add the names of overloadable operators.
3571#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3572 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003573 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003574#include "clang/Basic/OperatorKinds.def"
3575
3576 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003577 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003578 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003579 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3580 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003581
3582 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003583 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003584 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003585
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003586 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003587 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003588 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003589}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003590
Douglas Gregor0133f522010-08-28 00:00:50 +00003591void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
3592 CXXBaseOrMemberInitializer** Initializers,
3593 unsigned NumInitializers) {
3594 CXXConstructorDecl *Constructor
3595 = static_cast<CXXConstructorDecl *>(ConstructorD);
3596 if (!Constructor)
3597 return;
3598
Douglas Gregor52779fb2010-09-23 23:01:17 +00003599 ResultBuilder Results(*this,
3600 CodeCompletionContext::CCC_PotentiallyQualifiedName);
Douglas Gregor0133f522010-08-28 00:00:50 +00003601 Results.EnterNewScope();
3602
3603 // Fill in any already-initialized fields or base classes.
3604 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
3605 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
3606 for (unsigned I = 0; I != NumInitializers; ++I) {
3607 if (Initializers[I]->isBaseInitializer())
3608 InitializedBases.insert(
3609 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
3610 else
Francois Pichet00eb3f92010-12-04 09:14:42 +00003611 InitializedFields.insert(cast<FieldDecl>(
3612 Initializers[I]->getAnyMember()));
Douglas Gregor0133f522010-08-28 00:00:50 +00003613 }
3614
3615 // Add completions for base classes.
Douglas Gregor0c431c82010-08-29 19:27:27 +00003616 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00003617 CXXRecordDecl *ClassDecl = Constructor->getParent();
3618 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
3619 BaseEnd = ClassDecl->bases_end();
3620 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003621 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3622 SawLastInitializer
3623 = NumInitializers > 0 &&
3624 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3625 Context.hasSameUnqualifiedType(Base->getType(),
3626 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003627 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003628 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003629
3630 CodeCompletionString *Pattern = new CodeCompletionString;
3631 Pattern->AddTypedTextChunk(
3632 Base->getType().getAsString(Context.PrintingPolicy));
3633 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3634 Pattern->AddPlaceholderChunk("args");
3635 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003636 Results.AddResult(CodeCompletionResult(Pattern,
3637 SawLastInitializer? CCP_NextInitializer
3638 : CCP_MemberDeclaration));
3639 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003640 }
3641
3642 // Add completions for virtual base classes.
3643 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
3644 BaseEnd = ClassDecl->vbases_end();
3645 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003646 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
3647 SawLastInitializer
3648 = NumInitializers > 0 &&
3649 Initializers[NumInitializers - 1]->isBaseInitializer() &&
3650 Context.hasSameUnqualifiedType(Base->getType(),
3651 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00003652 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003653 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003654
3655 CodeCompletionString *Pattern = new CodeCompletionString;
3656 Pattern->AddTypedTextChunk(
3657 Base->getType().getAsString(Context.PrintingPolicy));
3658 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3659 Pattern->AddPlaceholderChunk("args");
3660 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003661 Results.AddResult(CodeCompletionResult(Pattern,
3662 SawLastInitializer? CCP_NextInitializer
3663 : CCP_MemberDeclaration));
3664 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003665 }
3666
3667 // Add completions for members.
3668 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
3669 FieldEnd = ClassDecl->field_end();
3670 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00003671 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
3672 SawLastInitializer
3673 = NumInitializers > 0 &&
Francois Pichet00eb3f92010-12-04 09:14:42 +00003674 Initializers[NumInitializers - 1]->isAnyMemberInitializer() &&
3675 Initializers[NumInitializers - 1]->getAnyMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00003676 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00003677 }
Douglas Gregor0133f522010-08-28 00:00:50 +00003678
3679 if (!Field->getDeclName())
3680 continue;
3681
3682 CodeCompletionString *Pattern = new CodeCompletionString;
3683 Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
3684 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3685 Pattern->AddPlaceholderChunk("args");
3686 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor0c431c82010-08-29 19:27:27 +00003687 Results.AddResult(CodeCompletionResult(Pattern,
3688 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00003689 : CCP_MemberDeclaration,
3690 CXCursor_MemberRef));
Douglas Gregor0c431c82010-08-29 19:27:27 +00003691 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00003692 }
3693 Results.ExitScope();
3694
Douglas Gregor52779fb2010-09-23 23:01:17 +00003695 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor0133f522010-08-28 00:00:50 +00003696 Results.data(), Results.size());
3697}
3698
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003699// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3700// true or false.
3701#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003702static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003703 ResultBuilder &Results,
3704 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003705 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003706 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003707 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003708
3709 CodeCompletionString *Pattern = 0;
3710 if (LangOpts.ObjC2) {
3711 // @dynamic
3712 Pattern = new CodeCompletionString;
3713 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3714 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3715 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003716 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003717
3718 // @synthesize
3719 Pattern = new CodeCompletionString;
3720 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3721 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3722 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003723 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003724 }
3725}
3726
Douglas Gregorbca403c2010-01-13 23:51:12 +00003727static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003728 ResultBuilder &Results,
3729 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003730 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003731
3732 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003733 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003734
3735 if (LangOpts.ObjC2) {
3736 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003737 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003738
3739 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003740 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003741
3742 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003743 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003744 }
3745}
3746
Douglas Gregorbca403c2010-01-13 23:51:12 +00003747static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003748 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003749 CodeCompletionString *Pattern = 0;
3750
3751 // @class name ;
3752 Pattern = new CodeCompletionString;
3753 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3754 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003755 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003756 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003757
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003758 if (Results.includeCodePatterns()) {
3759 // @interface name
3760 // FIXME: Could introduce the whole pattern, including superclasses and
3761 // such.
3762 Pattern = new CodeCompletionString;
3763 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3764 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3765 Pattern->AddPlaceholderChunk("class");
3766 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003767
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003768 // @protocol name
3769 Pattern = new CodeCompletionString;
3770 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3771 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3772 Pattern->AddPlaceholderChunk("protocol");
3773 Results.AddResult(Result(Pattern));
3774
3775 // @implementation name
3776 Pattern = new CodeCompletionString;
3777 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3778 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3779 Pattern->AddPlaceholderChunk("class");
3780 Results.AddResult(Result(Pattern));
3781 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003782
3783 // @compatibility_alias name
3784 Pattern = new CodeCompletionString;
3785 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3786 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3787 Pattern->AddPlaceholderChunk("alias");
3788 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3789 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003790 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003791}
3792
John McCalld226f652010-08-21 09:40:31 +00003793void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003794 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003795 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00003796 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003797 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003798 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003799 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003800 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003801 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003802 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003803 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003804 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003805 HandleCodeCompleteResults(this, CodeCompleter,
3806 CodeCompletionContext::CCC_Other,
3807 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003808}
3809
Douglas Gregorbca403c2010-01-13 23:51:12 +00003810static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003811 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003812 CodeCompletionString *Pattern = 0;
3813
3814 // @encode ( type-name )
3815 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003816 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003817 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3818 Pattern->AddPlaceholderChunk("type-name");
3819 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003820 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003821
3822 // @protocol ( protocol-name )
3823 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003824 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003825 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3826 Pattern->AddPlaceholderChunk("protocol-name");
3827 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003828 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003829
3830 // @selector ( selector )
3831 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003832 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003833 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3834 Pattern->AddPlaceholderChunk("selector");
3835 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003836 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003837}
3838
Douglas Gregorbca403c2010-01-13 23:51:12 +00003839static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003840 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003841 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003842
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003843 if (Results.includeCodePatterns()) {
3844 // @try { statements } @catch ( declaration ) { statements } @finally
3845 // { statements }
3846 Pattern = new CodeCompletionString;
3847 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3848 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3849 Pattern->AddPlaceholderChunk("statements");
3850 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3851 Pattern->AddTextChunk("@catch");
3852 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3853 Pattern->AddPlaceholderChunk("parameter");
3854 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3855 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3856 Pattern->AddPlaceholderChunk("statements");
3857 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3858 Pattern->AddTextChunk("@finally");
3859 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3860 Pattern->AddPlaceholderChunk("statements");
3861 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3862 Results.AddResult(Result(Pattern));
3863 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003864
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003865 // @throw
3866 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003867 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003868 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003869 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003870 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003871
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003872 if (Results.includeCodePatterns()) {
3873 // @synchronized ( expression ) { statements }
3874 Pattern = new CodeCompletionString;
3875 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3876 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3877 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3878 Pattern->AddPlaceholderChunk("expression");
3879 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3880 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3881 Pattern->AddPlaceholderChunk("statements");
3882 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3883 Results.AddResult(Result(Pattern));
3884 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003885}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003886
Douglas Gregorbca403c2010-01-13 23:51:12 +00003887static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003888 ResultBuilder &Results,
3889 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003890 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003891 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3892 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3893 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003894 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003895 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003896}
3897
3898void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00003899 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003900 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003901 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003902 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003903 HandleCodeCompleteResults(this, CodeCompleter,
3904 CodeCompletionContext::CCC_Other,
3905 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003906}
3907
3908void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00003909 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003910 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003911 AddObjCStatementResults(Results, false);
3912 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003913 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003914 HandleCodeCompleteResults(this, CodeCompleter,
3915 CodeCompletionContext::CCC_Other,
3916 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003917}
3918
3919void Sema::CodeCompleteObjCAtExpression(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00003920 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003921 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003922 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003923 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003924 HandleCodeCompleteResults(this, CodeCompleter,
3925 CodeCompletionContext::CCC_Other,
3926 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003927}
3928
Douglas Gregor988358f2009-11-19 00:14:45 +00003929/// \brief Determine whether the addition of the given flag to an Objective-C
3930/// property's attributes will cause a conflict.
3931static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3932 // Check if we've already added this flag.
3933 if (Attributes & NewFlag)
3934 return true;
3935
3936 Attributes |= NewFlag;
3937
3938 // Check for collisions with "readonly".
3939 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3940 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3941 ObjCDeclSpec::DQ_PR_assign |
3942 ObjCDeclSpec::DQ_PR_copy |
3943 ObjCDeclSpec::DQ_PR_retain)))
3944 return true;
3945
3946 // Check for more than one of { assign, copy, retain }.
3947 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3948 ObjCDeclSpec::DQ_PR_copy |
3949 ObjCDeclSpec::DQ_PR_retain);
3950 if (AssignCopyRetMask &&
3951 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3952 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3953 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3954 return true;
3955
3956 return false;
3957}
3958
Douglas Gregora93b1082009-11-18 23:08:07 +00003959void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003960 if (!CodeCompleter)
3961 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003962
Steve Naroffece8e712009-10-08 21:55:05 +00003963 unsigned Attributes = ODS.getPropertyAttributes();
3964
John McCall0a2c5e22010-08-25 06:19:51 +00003965 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00003966 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Steve Naroffece8e712009-10-08 21:55:05 +00003967 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003968 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003969 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003970 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003971 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003972 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003973 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003974 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003975 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003976 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003977 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003978 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003979 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003980 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003981 CodeCompletionString *Setter = new CodeCompletionString;
3982 Setter->AddTypedTextChunk("setter");
3983 Setter->AddTextChunk(" = ");
3984 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003985 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003986 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003987 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003988 CodeCompletionString *Getter = new CodeCompletionString;
3989 Getter->AddTypedTextChunk("getter");
3990 Getter->AddTextChunk(" = ");
3991 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003992 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003993 }
Steve Naroffece8e712009-10-08 21:55:05 +00003994 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003995 HandleCodeCompleteResults(this, CodeCompleter,
3996 CodeCompletionContext::CCC_Other,
3997 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003998}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003999
Douglas Gregor4ad96852009-11-19 07:41:15 +00004000/// \brief Descripts the kind of Objective-C method that we want to find
4001/// via code completion.
4002enum ObjCMethodKind {
4003 MK_Any, //< Any kind of method, provided it means other specified criteria.
4004 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
4005 MK_OneArgSelector //< One-argument selector.
4006};
4007
Douglas Gregor458433d2010-08-26 15:07:07 +00004008static bool isAcceptableObjCSelector(Selector Sel,
4009 ObjCMethodKind WantKind,
4010 IdentifierInfo **SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004011 unsigned NumSelIdents,
4012 bool AllowSameLength = true) {
Douglas Gregor458433d2010-08-26 15:07:07 +00004013 if (NumSelIdents > Sel.getNumArgs())
4014 return false;
4015
4016 switch (WantKind) {
4017 case MK_Any: break;
4018 case MK_ZeroArgSelector: return Sel.isUnarySelector();
4019 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
4020 }
4021
Douglas Gregorcf544262010-11-17 21:36:08 +00004022 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
4023 return false;
4024
Douglas Gregor458433d2010-08-26 15:07:07 +00004025 for (unsigned I = 0; I != NumSelIdents; ++I)
4026 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
4027 return false;
4028
4029 return true;
4030}
4031
Douglas Gregor4ad96852009-11-19 07:41:15 +00004032static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
4033 ObjCMethodKind WantKind,
4034 IdentifierInfo **SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004035 unsigned NumSelIdents,
4036 bool AllowSameLength = true) {
Douglas Gregor458433d2010-08-26 15:07:07 +00004037 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004038 NumSelIdents, AllowSameLength);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004039}
Douglas Gregord36adf52010-09-16 16:06:31 +00004040
4041namespace {
4042 /// \brief A set of selectors, which is used to avoid introducing multiple
4043 /// completions with the same selector into the result set.
4044 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
4045}
4046
Douglas Gregor36ecb042009-11-17 23:22:23 +00004047/// \brief Add all of the Objective-C methods in the given Objective-C
4048/// container to the set of results.
4049///
4050/// The container will be a class, protocol, category, or implementation of
4051/// any of the above. This mether will recurse to include methods from
4052/// the superclasses of classes along with their categories, protocols, and
4053/// implementations.
4054///
4055/// \param Container the container in which we'll look to find methods.
4056///
4057/// \param WantInstance whether to add instance methods (only); if false, this
4058/// routine will add factory methods (only).
4059///
4060/// \param CurContext the context in which we're performing the lookup that
4061/// finds methods.
4062///
Douglas Gregorcf544262010-11-17 21:36:08 +00004063/// \param AllowSameLength Whether we allow a method to be added to the list
4064/// when it has the same number of parameters as we have selector identifiers.
4065///
Douglas Gregor36ecb042009-11-17 23:22:23 +00004066/// \param Results the structure into which we'll add results.
4067static void AddObjCMethods(ObjCContainerDecl *Container,
4068 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004069 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00004070 IdentifierInfo **SelIdents,
4071 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00004072 DeclContext *CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004073 VisitedSelectorSet &Selectors,
Douglas Gregorcf544262010-11-17 21:36:08 +00004074 bool AllowSameLength,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004075 ResultBuilder &Results,
4076 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00004077 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00004078 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4079 MEnd = Container->meth_end();
4080 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00004081 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4082 // Check whether the selector identifiers we've been given are a
4083 // subset of the identifiers for this particular method.
Douglas Gregorcf544262010-11-17 21:36:08 +00004084 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents,
4085 AllowSameLength))
Douglas Gregord3c68542009-11-19 01:08:35 +00004086 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004087
Douglas Gregord36adf52010-09-16 16:06:31 +00004088 if (!Selectors.insert((*M)->getSelector()))
4089 continue;
4090
Douglas Gregord3c68542009-11-19 01:08:35 +00004091 Result R = Result(*M, 0);
4092 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004093 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00004094 if (!InOriginalClass)
4095 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00004096 Results.MaybeAddResult(R, CurContext);
4097 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00004098 }
4099
Douglas Gregore396c7b2010-09-16 15:34:59 +00004100 // Visit the protocols of protocols.
4101 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4102 const ObjCList<ObjCProtocolDecl> &Protocols
4103 = Protocol->getReferencedProtocols();
4104 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4105 E = Protocols.end();
4106 I != E; ++I)
4107 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004108 CurContext, Selectors, AllowSameLength, Results, false);
Douglas Gregore396c7b2010-09-16 15:34:59 +00004109 }
4110
Douglas Gregor36ecb042009-11-17 23:22:23 +00004111 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
4112 if (!IFace)
4113 return;
4114
4115 // Add methods in protocols.
4116 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
4117 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4118 E = Protocols.end();
4119 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004120 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004121 CurContext, Selectors, AllowSameLength, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004122
4123 // Add methods in categories.
4124 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
4125 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00004126 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004127 NumSelIdents, CurContext, Selectors, AllowSameLength,
4128 Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004129
4130 // Add a categories protocol methods.
4131 const ObjCList<ObjCProtocolDecl> &Protocols
4132 = CatDecl->getReferencedProtocols();
4133 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4134 E = Protocols.end();
4135 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004136 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004137 NumSelIdents, CurContext, Selectors, AllowSameLength,
4138 Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004139
4140 // Add methods in category implementations.
4141 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004142 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004143 NumSelIdents, CurContext, Selectors, AllowSameLength,
4144 Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004145 }
4146
4147 // Add methods in superclass.
4148 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004149 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregorcf544262010-11-17 21:36:08 +00004150 SelIdents, NumSelIdents, CurContext, Selectors,
4151 AllowSameLength, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004152
4153 // Add methods in our implementation, if any.
4154 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004155 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004156 NumSelIdents, CurContext, Selectors, AllowSameLength,
4157 Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004158}
4159
4160
John McCalld226f652010-08-21 09:40:31 +00004161void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
4162 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004163 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00004164 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004165
4166 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00004167 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004168 if (!Class) {
4169 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004170 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004171 Class = Category->getClassInterface();
4172
4173 if (!Class)
4174 return;
4175 }
4176
4177 // Find all of the potential getters.
Douglas Gregor52779fb2010-09-23 23:01:17 +00004178 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004179 Results.EnterNewScope();
4180
4181 // FIXME: We need to do this because Objective-C methods don't get
4182 // pushed into DeclContexts early enough. Argh!
4183 for (unsigned I = 0; I != NumMethods; ++I) {
4184 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004185 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004186 if (Method->isInstanceMethod() &&
4187 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
4188 Result R = Result(Method, 0);
4189 R.AllParametersAreInformative = true;
4190 Results.MaybeAddResult(R, CurContext);
4191 }
4192 }
4193
Douglas Gregord36adf52010-09-16 16:06:31 +00004194 VisitedSelectorSet Selectors;
4195 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
Douglas Gregorcf544262010-11-17 21:36:08 +00004196 /*AllowSameLength=*/true, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004197 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004198 HandleCodeCompleteResults(this, CodeCompleter,
4199 CodeCompletionContext::CCC_Other,
4200 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00004201}
4202
John McCalld226f652010-08-21 09:40:31 +00004203void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
4204 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004205 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00004206 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004207
4208 // Try to find the interface where setters might live.
4209 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00004210 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004211 if (!Class) {
4212 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00004213 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004214 Class = Category->getClassInterface();
4215
4216 if (!Class)
4217 return;
4218 }
4219
4220 // Find all of the potential getters.
Douglas Gregor52779fb2010-09-23 23:01:17 +00004221 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004222 Results.EnterNewScope();
4223
4224 // FIXME: We need to do this because Objective-C methods don't get
4225 // pushed into DeclContexts early enough. Argh!
4226 for (unsigned I = 0; I != NumMethods; ++I) {
4227 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00004228 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004229 if (Method->isInstanceMethod() &&
4230 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
4231 Result R = Result(Method, 0);
4232 R.AllParametersAreInformative = true;
4233 Results.MaybeAddResult(R, CurContext);
4234 }
4235 }
4236
Douglas Gregord36adf52010-09-16 16:06:31 +00004237 VisitedSelectorSet Selectors;
4238 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00004239 Selectors, /*AllowSameLength=*/true, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004240
4241 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004242 HandleCodeCompleteResults(this, CodeCompleter,
4243 CodeCompletionContext::CCC_Other,
4244 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004245}
4246
Douglas Gregord32b0222010-08-24 01:06:58 +00004247void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00004248 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00004249 ResultBuilder Results(*this, CodeCompletionContext::CCC_Type);
Douglas Gregord32b0222010-08-24 01:06:58 +00004250 Results.EnterNewScope();
4251
4252 // Add context-sensitive, Objective-C parameter-passing keywords.
4253 bool AddedInOut = false;
4254 if ((DS.getObjCDeclQualifier() &
4255 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4256 Results.AddResult("in");
4257 Results.AddResult("inout");
4258 AddedInOut = true;
4259 }
4260 if ((DS.getObjCDeclQualifier() &
4261 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4262 Results.AddResult("out");
4263 if (!AddedInOut)
4264 Results.AddResult("inout");
4265 }
4266 if ((DS.getObjCDeclQualifier() &
4267 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4268 ObjCDeclSpec::DQ_Oneway)) == 0) {
4269 Results.AddResult("bycopy");
4270 Results.AddResult("byref");
4271 Results.AddResult("oneway");
4272 }
4273
4274 // Add various builtin type names and specifiers.
4275 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
4276 Results.ExitScope();
4277
4278 // Add the various type names
4279 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4280 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4281 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4282 CodeCompleter->includeGlobals());
4283
4284 if (CodeCompleter->includeMacros())
4285 AddMacroResults(PP, Results);
4286
4287 HandleCodeCompleteResults(this, CodeCompleter,
4288 CodeCompletionContext::CCC_Type,
4289 Results.data(), Results.size());
4290}
4291
Douglas Gregor22f56992010-04-06 19:22:33 +00004292/// \brief When we have an expression with type "id", we may assume
4293/// that it has some more-specific class type based on knowledge of
4294/// common uses of Objective-C. This routine returns that class type,
4295/// or NULL if no better result could be determined.
4296static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00004297 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00004298 if (!Msg)
4299 return 0;
4300
4301 Selector Sel = Msg->getSelector();
4302 if (Sel.isNull())
4303 return 0;
4304
4305 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
4306 if (!Id)
4307 return 0;
4308
4309 ObjCMethodDecl *Method = Msg->getMethodDecl();
4310 if (!Method)
4311 return 0;
4312
4313 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00004314 ObjCInterfaceDecl *IFace = 0;
4315 switch (Msg->getReceiverKind()) {
4316 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00004317 if (const ObjCObjectType *ObjType
4318 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
4319 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00004320 break;
4321
4322 case ObjCMessageExpr::Instance: {
4323 QualType T = Msg->getInstanceReceiver()->getType();
4324 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
4325 IFace = Ptr->getInterfaceDecl();
4326 break;
4327 }
4328
4329 case ObjCMessageExpr::SuperInstance:
4330 case ObjCMessageExpr::SuperClass:
4331 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00004332 }
4333
4334 if (!IFace)
4335 return 0;
4336
4337 ObjCInterfaceDecl *Super = IFace->getSuperClass();
4338 if (Method->isInstanceMethod())
4339 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4340 .Case("retain", IFace)
4341 .Case("autorelease", IFace)
4342 .Case("copy", IFace)
4343 .Case("copyWithZone", IFace)
4344 .Case("mutableCopy", IFace)
4345 .Case("mutableCopyWithZone", IFace)
4346 .Case("awakeFromCoder", IFace)
4347 .Case("replacementObjectFromCoder", IFace)
4348 .Case("class", IFace)
4349 .Case("classForCoder", IFace)
4350 .Case("superclass", Super)
4351 .Default(0);
4352
4353 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
4354 .Case("new", IFace)
4355 .Case("alloc", IFace)
4356 .Case("allocWithZone", IFace)
4357 .Case("class", IFace)
4358 .Case("superclass", Super)
4359 .Default(0);
4360}
4361
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004362// Add a special completion for a message send to "super", which fills in the
4363// most likely case of forwarding all of our arguments to the superclass
4364// function.
4365///
4366/// \param S The semantic analysis object.
4367///
4368/// \param S NeedSuperKeyword Whether we need to prefix this completion with
4369/// the "super" keyword. Otherwise, we just need to provide the arguments.
4370///
4371/// \param SelIdents The identifiers in the selector that have already been
4372/// provided as arguments for a send to "super".
4373///
4374/// \param NumSelIdents The number of identifiers in \p SelIdents.
4375///
4376/// \param Results The set of results to augment.
4377///
4378/// \returns the Objective-C method declaration that would be invoked by
4379/// this "super" completion. If NULL, no completion was added.
4380static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
4381 IdentifierInfo **SelIdents,
4382 unsigned NumSelIdents,
4383 ResultBuilder &Results) {
4384 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
4385 if (!CurMethod)
4386 return 0;
4387
4388 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
4389 if (!Class)
4390 return 0;
4391
4392 // Try to find a superclass method with the same selector.
4393 ObjCMethodDecl *SuperMethod = 0;
4394 while ((Class = Class->getSuperClass()) && !SuperMethod)
4395 SuperMethod = Class->getMethod(CurMethod->getSelector(),
4396 CurMethod->isInstanceMethod());
4397
4398 if (!SuperMethod)
4399 return 0;
4400
4401 // Check whether the superclass method has the same signature.
4402 if (CurMethod->param_size() != SuperMethod->param_size() ||
4403 CurMethod->isVariadic() != SuperMethod->isVariadic())
4404 return 0;
4405
4406 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
4407 CurPEnd = CurMethod->param_end(),
4408 SuperP = SuperMethod->param_begin();
4409 CurP != CurPEnd; ++CurP, ++SuperP) {
4410 // Make sure the parameter types are compatible.
4411 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
4412 (*SuperP)->getType()))
4413 return 0;
4414
4415 // Make sure we have a parameter name to forward!
4416 if (!(*CurP)->getIdentifier())
4417 return 0;
4418 }
4419
4420 // We have a superclass method. Now, form the send-to-super completion.
4421 CodeCompletionString *Pattern = new CodeCompletionString;
4422
4423 // Give this completion a return type.
4424 AddResultTypeChunk(S.Context, SuperMethod, Pattern);
4425
4426 // If we need the "super" keyword, add it (plus some spacing).
4427 if (NeedSuperKeyword) {
4428 Pattern->AddTypedTextChunk("super");
4429 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4430 }
4431
4432 Selector Sel = CurMethod->getSelector();
4433 if (Sel.isUnarySelector()) {
4434 if (NeedSuperKeyword)
4435 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4436 else
4437 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4438 } else {
4439 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
4440 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
4441 if (I > NumSelIdents)
4442 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4443
4444 if (I < NumSelIdents)
4445 Pattern->AddInformativeChunk(
4446 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4447 else if (NeedSuperKeyword || I > NumSelIdents) {
4448 Pattern->AddTextChunk(
4449 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4450 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4451 } else {
4452 Pattern->AddTypedTextChunk(
4453 Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
4454 Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
4455 }
4456 }
4457 }
4458
4459 Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
4460 SuperMethod->isInstanceMethod()
4461 ? CXCursor_ObjCInstanceMethodDecl
4462 : CXCursor_ObjCClassMethodDecl));
4463 return SuperMethod;
4464}
4465
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004466void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00004467 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00004468 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCMessageReceiver,
4469 &ResultBuilder::IsObjCMessageReceiver);
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004470
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004471 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4472 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00004473 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4474 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004475
4476 // If we are in an Objective-C method inside a class that has a superclass,
4477 // add "super" as an option.
4478 if (ObjCMethodDecl *Method = getCurMethodDecl())
4479 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004480 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004481 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004482
4483 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
4484 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004485
4486 Results.ExitScope();
4487
4488 if (CodeCompleter->includeMacros())
4489 AddMacroResults(PP, Results);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00004490 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004491 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00004492
4493}
4494
Douglas Gregor2725ca82010-04-21 19:57:20 +00004495void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
4496 IdentifierInfo **SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004497 unsigned NumSelIdents,
4498 bool AtArgumentExpression) {
Douglas Gregor2725ca82010-04-21 19:57:20 +00004499 ObjCInterfaceDecl *CDecl = 0;
4500 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4501 // Figure out which interface we're in.
4502 CDecl = CurMethod->getClassInterface();
4503 if (!CDecl)
4504 return;
4505
4506 // Find the superclass of this class.
4507 CDecl = CDecl->getSuperClass();
4508 if (!CDecl)
4509 return;
4510
4511 if (CurMethod->isInstanceMethod()) {
4512 // We are inside an instance method, which means that the message
4513 // send [super ...] is actually calling an instance method on the
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004514 // current object.
4515 return CodeCompleteObjCInstanceMessage(S, 0,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004516 SelIdents, NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004517 AtArgumentExpression,
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004518 CDecl);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004519 }
4520
4521 // Fall through to send to the superclass in CDecl.
4522 } else {
4523 // "super" may be the name of a type or variable. Figure out which
4524 // it is.
4525 IdentifierInfo *Super = &Context.Idents.get("super");
4526 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
4527 LookupOrdinaryName);
4528 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
4529 // "super" names an interface. Use it.
4530 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00004531 if (const ObjCObjectType *Iface
4532 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
4533 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00004534 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
4535 // "super" names an unresolved type; we can't be more specific.
4536 } else {
4537 // Assume that "super" names some kind of value and parse that way.
4538 CXXScopeSpec SS;
4539 UnqualifiedId id;
4540 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00004541 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004542 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004543 SelIdents, NumSelIdents,
4544 AtArgumentExpression);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004545 }
4546
4547 // Fall through
4548 }
4549
John McCallb3d87482010-08-24 05:47:05 +00004550 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00004551 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00004552 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00004553 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004554 NumSelIdents, AtArgumentExpression,
4555 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004556}
4557
Douglas Gregorb9d77572010-09-21 00:03:25 +00004558/// \brief Given a set of code-completion results for the argument of a message
4559/// send, determine the preferred type (if any) for that argument expression.
4560static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
4561 unsigned NumSelIdents) {
4562 typedef CodeCompletionResult Result;
4563 ASTContext &Context = Results.getSema().Context;
4564
4565 QualType PreferredType;
4566 unsigned BestPriority = CCP_Unlikely * 2;
4567 Result *ResultsData = Results.data();
4568 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
4569 Result &R = ResultsData[I];
4570 if (R.Kind == Result::RK_Declaration &&
4571 isa<ObjCMethodDecl>(R.Declaration)) {
4572 if (R.Priority <= BestPriority) {
4573 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
4574 if (NumSelIdents <= Method->param_size()) {
4575 QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
4576 ->getType();
4577 if (R.Priority < BestPriority || PreferredType.isNull()) {
4578 BestPriority = R.Priority;
4579 PreferredType = MyPreferredType;
4580 } else if (!Context.hasSameUnqualifiedType(PreferredType,
4581 MyPreferredType)) {
4582 PreferredType = QualType();
4583 }
4584 }
4585 }
4586 }
4587 }
4588
4589 return PreferredType;
4590}
4591
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004592static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4593 ParsedType Receiver,
4594 IdentifierInfo **SelIdents,
4595 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004596 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004597 bool IsSuper,
4598 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004599 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00004600 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004601
Douglas Gregor24a069f2009-11-17 17:59:40 +00004602 // If the given name refers to an interface type, retrieve the
4603 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00004604 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004605 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004606 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00004607 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
4608 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00004609 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004610
Douglas Gregor36ecb042009-11-17 23:22:23 +00004611 // Add all of the factory methods in this Objective-C class, its protocols,
4612 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00004613 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004614
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004615 // If this is a send-to-super, try to add the special "super" send
4616 // completion.
4617 if (IsSuper) {
4618 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004619 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
4620 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004621 Results.Ignore(SuperMethod);
4622 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004623
Douglas Gregor265f7492010-08-27 15:29:55 +00004624 // If we're inside an Objective-C method definition, prefer its selector to
4625 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004626 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00004627 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004628
Douglas Gregord36adf52010-09-16 16:06:31 +00004629 VisitedSelectorSet Selectors;
Douglas Gregor13438f92010-04-06 16:40:00 +00004630 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004631 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004632 SemaRef.CurContext, Selectors, AtArgumentExpression,
4633 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00004634 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00004635 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004636
Douglas Gregor719770d2010-04-06 17:30:22 +00004637 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004638 // pool from the AST file.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004639 if (SemaRef.ExternalSource) {
4640 for (uint32_t I = 0,
4641 N = SemaRef.ExternalSource->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00004642 I != N; ++I) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004643 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
4644 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004645 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004646
4647 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004648 }
4649 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004650
4651 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
4652 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004653 M != MEnd; ++M) {
4654 for (ObjCMethodList *MethList = &M->second.second;
4655 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004656 MethList = MethList->Next) {
4657 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4658 NumSelIdents))
4659 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004660
Douglas Gregor13438f92010-04-06 16:40:00 +00004661 Result R(MethList->Method, 0);
4662 R.StartParameter = NumSelIdents;
4663 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004664 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00004665 }
4666 }
4667 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004668
4669 Results.ExitScope();
4670}
Douglas Gregor13438f92010-04-06 16:40:00 +00004671
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004672void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
4673 IdentifierInfo **SelIdents,
4674 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004675 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00004676 bool IsSuper) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00004677 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004678 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
4679 AtArgumentExpression, IsSuper, Results);
Douglas Gregorb9d77572010-09-21 00:03:25 +00004680
4681 // If we're actually at the argument expression (rather than prior to the
4682 // selector), we're actually performing code completion for an expression.
4683 // Determine whether we have a single, best method. If so, we can
4684 // code-complete the expression using the corresponding parameter type as
4685 // our preferred type, improving completion results.
4686 if (AtArgumentExpression) {
4687 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
4688 NumSelIdents);
4689 if (PreferredType.isNull())
4690 CodeCompleteOrdinaryName(S, PCC_Expression);
4691 else
4692 CodeCompleteExpression(S, PreferredType);
4693 return;
4694 }
4695
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004696 HandleCodeCompleteResults(this, CodeCompleter,
4697 CodeCompletionContext::CCC_Other,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004698 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004699}
4700
Douglas Gregord3c68542009-11-19 01:08:35 +00004701void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
4702 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004703 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00004704 bool AtArgumentExpression,
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004705 ObjCInterfaceDecl *Super) {
John McCall0a2c5e22010-08-25 06:19:51 +00004706 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00004707
4708 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00004709
Douglas Gregor36ecb042009-11-17 23:22:23 +00004710 // If necessary, apply function/array conversion to the receiver.
4711 // C99 6.7.5.3p[7,8].
Douglas Gregor78edf512010-09-15 16:23:04 +00004712 if (RecExpr)
4713 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004714 QualType ReceiverType = RecExpr? RecExpr->getType()
4715 : Super? Context.getObjCObjectPointerType(
4716 Context.getObjCInterfaceType(Super))
4717 : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00004718
Douglas Gregorda892642010-11-08 21:12:30 +00004719 // If we're messaging an expression with type "id" or "Class", check
4720 // whether we know something special about the receiver that allows
4721 // us to assume a more-specific receiver type.
4722 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
4723 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
4724 if (ReceiverType->isObjCClassType())
4725 return CodeCompleteObjCClassMessage(S,
4726 ParsedType::make(Context.getObjCInterfaceType(IFace)),
4727 SelIdents, NumSelIdents,
4728 AtArgumentExpression, Super);
4729
4730 ReceiverType = Context.getObjCObjectPointerType(
4731 Context.getObjCInterfaceType(IFace));
4732 }
4733
Douglas Gregor36ecb042009-11-17 23:22:23 +00004734 // Build the set of methods we can see.
Douglas Gregor52779fb2010-09-23 23:01:17 +00004735 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004736 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00004737
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004738 // If this is a send-to-super, try to add the special "super" send
4739 // completion.
Douglas Gregor6b0656a2010-10-13 21:24:53 +00004740 if (Super) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00004741 if (ObjCMethodDecl *SuperMethod
4742 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
4743 Results))
4744 Results.Ignore(SuperMethod);
4745 }
4746
Douglas Gregor265f7492010-08-27 15:29:55 +00004747 // If we're inside an Objective-C method definition, prefer its selector to
4748 // others.
4749 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
4750 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004751
Douglas Gregord36adf52010-09-16 16:06:31 +00004752 // Keep track of the selectors we've already added.
4753 VisitedSelectorSet Selectors;
4754
Douglas Gregorf74a4192009-11-18 00:06:18 +00004755 // Handle messages to Class. This really isn't a message to an instance
4756 // method, so we treat it the same way we would treat a message send to a
4757 // class method.
4758 if (ReceiverType->isObjCClassType() ||
4759 ReceiverType->isObjCQualifiedClassType()) {
4760 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
4761 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004762 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004763 CurContext, Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004764 }
4765 }
4766 // Handle messages to a qualified ID ("id<foo>").
4767 else if (const ObjCObjectPointerType *QualID
4768 = ReceiverType->getAsObjCQualifiedIdType()) {
4769 // Search protocols for instance methods.
4770 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
4771 E = QualID->qual_end();
4772 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004773 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00004774 Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004775 }
4776 // Handle messages to a pointer to interface type.
4777 else if (const ObjCObjectPointerType *IFacePtr
4778 = ReceiverType->getAsObjCInterfacePointerType()) {
4779 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004780 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004781 NumSelIdents, CurContext, Selectors, AtArgumentExpression,
4782 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004783
4784 // Search protocols for instance methods.
4785 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
4786 E = IFacePtr->qual_end();
4787 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004788 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00004789 Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00004790 }
Douglas Gregor13438f92010-04-06 16:40:00 +00004791 // Handle messages to "id".
4792 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00004793 // We're messaging "id", so provide all instance methods we know
4794 // about as code-completion results.
4795
4796 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004797 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00004798 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00004799 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4800 I != N; ++I) {
4801 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004802 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00004803 continue;
4804
Sebastian Redldb9d2142010-08-02 23:18:59 +00004805 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004806 }
4807 }
4808
Sebastian Redldb9d2142010-08-02 23:18:59 +00004809 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4810 MEnd = MethodPool.end();
4811 M != MEnd; ++M) {
4812 for (ObjCMethodList *MethList = &M->second.first;
4813 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004814 MethList = MethList->Next) {
4815 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4816 NumSelIdents))
4817 continue;
Douglas Gregord36adf52010-09-16 16:06:31 +00004818
4819 if (!Selectors.insert(MethList->Method->getSelector()))
4820 continue;
4821
Douglas Gregor13438f92010-04-06 16:40:00 +00004822 Result R(MethList->Method, 0);
4823 R.StartParameter = NumSelIdents;
4824 R.AllParametersAreInformative = false;
4825 Results.MaybeAddResult(R, CurContext);
4826 }
4827 }
4828 }
Steve Naroffc4df6d22009-11-07 02:08:14 +00004829 Results.ExitScope();
Douglas Gregorb9d77572010-09-21 00:03:25 +00004830
4831
4832 // If we're actually at the argument expression (rather than prior to the
4833 // selector), we're actually performing code completion for an expression.
4834 // Determine whether we have a single, best method. If so, we can
4835 // code-complete the expression using the corresponding parameter type as
4836 // our preferred type, improving completion results.
4837 if (AtArgumentExpression) {
4838 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
4839 NumSelIdents);
4840 if (PreferredType.isNull())
4841 CodeCompleteOrdinaryName(S, PCC_Expression);
4842 else
4843 CodeCompleteExpression(S, PreferredType);
4844 return;
4845 }
4846
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004847 HandleCodeCompleteResults(this, CodeCompleter,
4848 CodeCompletionContext::CCC_Other,
4849 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004850}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004851
Douglas Gregorfb629412010-08-23 21:17:50 +00004852void Sema::CodeCompleteObjCForCollection(Scope *S,
4853 DeclGroupPtrTy IterationVar) {
4854 CodeCompleteExpressionData Data;
4855 Data.ObjCCollection = true;
4856
4857 if (IterationVar.getAsOpaquePtr()) {
4858 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4859 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4860 if (*I)
4861 Data.IgnoreDecls.push_back(*I);
4862 }
4863 }
4864
4865 CodeCompleteExpression(S, Data);
4866}
4867
Douglas Gregor458433d2010-08-26 15:07:07 +00004868void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
4869 unsigned NumSelIdents) {
4870 // If we have an external source, load the entire class method
4871 // pool from the AST file.
4872 if (ExternalSource) {
4873 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4874 I != N; ++I) {
4875 Selector Sel = ExternalSource->GetExternalSelector(I);
4876 if (Sel.isNull() || MethodPool.count(Sel))
4877 continue;
4878
4879 ReadMethodPool(Sel);
4880 }
4881 }
4882
Douglas Gregor52779fb2010-09-23 23:01:17 +00004883 ResultBuilder Results(*this, CodeCompletionContext::CCC_SelectorName);
Douglas Gregor458433d2010-08-26 15:07:07 +00004884 Results.EnterNewScope();
4885 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4886 MEnd = MethodPool.end();
4887 M != MEnd; ++M) {
4888
4889 Selector Sel = M->first;
4890 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
4891 continue;
4892
4893 CodeCompletionString *Pattern = new CodeCompletionString;
4894 if (Sel.isUnarySelector()) {
4895 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4896 Results.AddResult(Pattern);
4897 continue;
4898 }
4899
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004900 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00004901 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004902 if (I == NumSelIdents) {
4903 if (!Accumulator.empty()) {
4904 Pattern->AddInformativeChunk(Accumulator);
4905 Accumulator.clear();
4906 }
4907 }
4908
4909 Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
4910 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00004911 }
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00004912 Pattern->AddTypedTextChunk(Accumulator);
Douglas Gregor458433d2010-08-26 15:07:07 +00004913 Results.AddResult(Pattern);
4914 }
4915 Results.ExitScope();
4916
4917 HandleCodeCompleteResults(this, CodeCompleter,
4918 CodeCompletionContext::CCC_SelectorName,
4919 Results.data(), Results.size());
4920}
4921
Douglas Gregor55385fe2009-11-18 04:19:12 +00004922/// \brief Add all of the protocol declarations that we find in the given
4923/// (translation unit) context.
4924static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004925 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004926 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004927 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004928
4929 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4930 DEnd = Ctx->decls_end();
4931 D != DEnd; ++D) {
4932 // Record any protocols we find.
4933 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004934 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004935 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004936
4937 // Record any forward-declared protocols we find.
4938 if (ObjCForwardProtocolDecl *Forward
4939 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4940 for (ObjCForwardProtocolDecl::protocol_iterator
4941 P = Forward->protocol_begin(),
4942 PEnd = Forward->protocol_end();
4943 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004944 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004945 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004946 }
4947 }
4948}
4949
4950void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4951 unsigned NumProtocols) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00004952 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCProtocolName);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004953
Douglas Gregor70c23352010-12-09 21:44:02 +00004954 if (CodeCompleter && CodeCompleter->includeGlobals()) {
4955 Results.EnterNewScope();
4956
4957 // Tell the result set to ignore all of the protocols we have
4958 // already seen.
4959 // FIXME: This doesn't work when caching code-completion results.
4960 for (unsigned I = 0; I != NumProtocols; ++I)
4961 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4962 Protocols[I].second))
4963 Results.Ignore(Protocol);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004964
Douglas Gregor70c23352010-12-09 21:44:02 +00004965 // Add all protocols.
4966 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4967 Results);
Douglas Gregor083128f2009-11-18 04:49:41 +00004968
Douglas Gregor70c23352010-12-09 21:44:02 +00004969 Results.ExitScope();
4970 }
4971
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004972 HandleCodeCompleteResults(this, CodeCompleter,
4973 CodeCompletionContext::CCC_ObjCProtocolName,
4974 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004975}
4976
4977void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00004978 ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCProtocolName);
Douglas Gregor083128f2009-11-18 04:49:41 +00004979
Douglas Gregor70c23352010-12-09 21:44:02 +00004980 if (CodeCompleter && CodeCompleter->includeGlobals()) {
4981 Results.EnterNewScope();
4982
4983 // Add all protocols.
4984 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4985 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004986
Douglas Gregor70c23352010-12-09 21:44:02 +00004987 Results.ExitScope();
4988 }
4989
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004990 HandleCodeCompleteResults(this, CodeCompleter,
4991 CodeCompletionContext::CCC_ObjCProtocolName,
4992 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004993}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004994
4995/// \brief Add all of the Objective-C interface declarations that we find in
4996/// the given (translation unit) context.
4997static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4998 bool OnlyForwardDeclarations,
4999 bool OnlyUnimplemented,
5000 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00005001 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005002
5003 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
5004 DEnd = Ctx->decls_end();
5005 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00005006 // Record any interfaces we find.
5007 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
5008 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
5009 (!OnlyUnimplemented || !Class->getImplementation()))
5010 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005011
5012 // Record any forward-declared interfaces we find.
5013 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
5014 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00005015 C != CEnd; ++C)
5016 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
5017 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
5018 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00005019 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005020 }
5021 }
5022}
5023
5024void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005025 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005026 Results.EnterNewScope();
5027
5028 // Add all classes.
5029 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
5030 false, Results);
5031
5032 Results.ExitScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00005033 // FIXME: Add a special context for this, use cached global completion
5034 // results.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005035 HandleCodeCompleteResults(this, CodeCompleter,
5036 CodeCompletionContext::CCC_Other,
5037 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005038}
5039
Douglas Gregorc83c6872010-04-15 22:33:43 +00005040void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
5041 SourceLocation ClassNameLoc) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005042 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005043 Results.EnterNewScope();
5044
5045 // Make sure that we ignore the class we're currently defining.
5046 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005047 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005048 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005049 Results.Ignore(CurClass);
5050
5051 // Add all classes.
5052 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5053 false, Results);
5054
5055 Results.ExitScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00005056 // FIXME: Add a special context for this, use cached global completion
5057 // results.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005058 HandleCodeCompleteResults(this, CodeCompleter,
5059 CodeCompletionContext::CCC_Other,
5060 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005061}
5062
5063void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005064 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005065 Results.EnterNewScope();
5066
5067 // Add all unimplemented classes.
5068 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5069 true, Results);
5070
5071 Results.ExitScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00005072 // FIXME: Add a special context for this, use cached global completion
5073 // results.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005074 HandleCodeCompleteResults(this, CodeCompleter,
5075 CodeCompletionContext::CCC_Other,
5076 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005077}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005078
5079void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00005080 IdentifierInfo *ClassName,
5081 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00005082 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005083
Douglas Gregor52779fb2010-09-23 23:01:17 +00005084 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005085
5086 // Ignore any categories we find that have already been implemented by this
5087 // interface.
5088 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5089 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005090 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005091 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
5092 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
5093 Category = Category->getNextClassCategory())
5094 CategoryNames.insert(Category->getIdentifier());
5095
5096 // Add all of the categories we know about.
5097 Results.EnterNewScope();
5098 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
5099 for (DeclContext::decl_iterator D = TU->decls_begin(),
5100 DEnd = TU->decls_end();
5101 D != DEnd; ++D)
5102 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
5103 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00005104 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005105 Results.ExitScope();
5106
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005107 HandleCodeCompleteResults(this, CodeCompleter,
5108 CodeCompletionContext::CCC_Other,
5109 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005110}
5111
5112void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00005113 IdentifierInfo *ClassName,
5114 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00005115 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005116
5117 // Find the corresponding interface. If we couldn't find the interface, the
5118 // program itself is ill-formed. However, we'll try to be helpful still by
5119 // providing the list of all of the categories we know about.
5120 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005121 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005122 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
5123 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00005124 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005125
Douglas Gregor52779fb2010-09-23 23:01:17 +00005126 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005127
5128 // Add all of the categories that have have corresponding interface
5129 // declarations in this class and any of its superclasses, except for
5130 // already-implemented categories in the class itself.
5131 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5132 Results.EnterNewScope();
5133 bool IgnoreImplemented = true;
5134 while (Class) {
5135 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
5136 Category = Category->getNextClassCategory())
5137 if ((!IgnoreImplemented || !Category->getImplementation()) &&
5138 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00005139 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005140
5141 Class = Class->getSuperClass();
5142 IgnoreImplemented = false;
5143 }
5144 Results.ExitScope();
5145
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005146 HandleCodeCompleteResults(this, CodeCompleter,
5147 CodeCompletionContext::CCC_Other,
5148 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005149}
Douglas Gregor322328b2009-11-18 22:32:06 +00005150
John McCalld226f652010-08-21 09:40:31 +00005151void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00005152 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00005153 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor322328b2009-11-18 22:32:06 +00005154
5155 // Figure out where this @synthesize lives.
5156 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00005157 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00005158 if (!Container ||
5159 (!isa<ObjCImplementationDecl>(Container) &&
5160 !isa<ObjCCategoryImplDecl>(Container)))
5161 return;
5162
5163 // Ignore any properties that have already been implemented.
5164 for (DeclContext::decl_iterator D = Container->decls_begin(),
5165 DEnd = Container->decls_end();
5166 D != DEnd; ++D)
5167 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
5168 Results.Ignore(PropertyImpl->getPropertyDecl());
5169
5170 // Add any properties that we find.
5171 Results.EnterNewScope();
5172 if (ObjCImplementationDecl *ClassImpl
5173 = dyn_cast<ObjCImplementationDecl>(Container))
5174 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
5175 Results);
5176 else
5177 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
5178 false, CurContext, Results);
5179 Results.ExitScope();
5180
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005181 HandleCodeCompleteResults(this, CodeCompleter,
5182 CodeCompletionContext::CCC_Other,
5183 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00005184}
5185
5186void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
5187 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00005188 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00005189 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00005190 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor322328b2009-11-18 22:32:06 +00005191
5192 // Figure out where this @synthesize lives.
5193 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00005194 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00005195 if (!Container ||
5196 (!isa<ObjCImplementationDecl>(Container) &&
5197 !isa<ObjCCategoryImplDecl>(Container)))
5198 return;
5199
5200 // Figure out which interface we're looking into.
5201 ObjCInterfaceDecl *Class = 0;
5202 if (ObjCImplementationDecl *ClassImpl
5203 = dyn_cast<ObjCImplementationDecl>(Container))
5204 Class = ClassImpl->getClassInterface();
5205 else
5206 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
5207 ->getClassInterface();
5208
5209 // Add all of the instance variables in this class and its superclasses.
5210 Results.EnterNewScope();
5211 for(; Class; Class = Class->getSuperClass()) {
5212 // FIXME: We could screen the type of each ivar for compatibility with
5213 // the property, but is that being too paternal?
5214 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
5215 IVarEnd = Class->ivar_end();
5216 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00005217 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00005218 }
5219 Results.ExitScope();
5220
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005221 HandleCodeCompleteResults(this, CodeCompleter,
5222 CodeCompletionContext::CCC_Other,
5223 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00005224}
Douglas Gregore8f5a172010-04-07 00:21:17 +00005225
Douglas Gregor408be5a2010-08-25 01:08:01 +00005226// Mapping from selectors to the methods that implement that selector, along
5227// with the "in original class" flag.
5228typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
5229 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005230
5231/// \brief Find all of the methods that reside in the given container
5232/// (and its superclasses, protocols, etc.) that meet the given
5233/// criteria. Insert those methods into the map of known methods,
5234/// indexed by selector so they can be easily found.
5235static void FindImplementableMethods(ASTContext &Context,
5236 ObjCContainerDecl *Container,
5237 bool WantInstanceMethods,
5238 QualType ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00005239 KnownMethodsMap &KnownMethods,
5240 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005241 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
5242 // Recurse into protocols.
5243 const ObjCList<ObjCProtocolDecl> &Protocols
5244 = IFace->getReferencedProtocols();
5245 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
Douglas Gregorea766182010-10-18 18:21:28 +00005246 E = Protocols.end();
Douglas Gregore8f5a172010-04-07 00:21:17 +00005247 I != E; ++I)
5248 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00005249 KnownMethods, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005250
Douglas Gregorea766182010-10-18 18:21:28 +00005251 // Add methods from any class extensions and categories.
5252 for (const ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
5253 Cat = Cat->getNextClassCategory())
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00005254 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
5255 WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00005256 KnownMethods, false);
5257
5258 // Visit the superclass.
5259 if (IFace->getSuperClass())
5260 FindImplementableMethods(Context, IFace->getSuperClass(),
5261 WantInstanceMethods, ReturnType,
5262 KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005263 }
5264
5265 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5266 // Recurse into protocols.
5267 const ObjCList<ObjCProtocolDecl> &Protocols
5268 = Category->getReferencedProtocols();
5269 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
Douglas Gregorea766182010-10-18 18:21:28 +00005270 E = Protocols.end();
Douglas Gregore8f5a172010-04-07 00:21:17 +00005271 I != E; ++I)
5272 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00005273 KnownMethods, InOriginalClass);
5274
5275 // If this category is the original class, jump to the interface.
5276 if (InOriginalClass && Category->getClassInterface())
5277 FindImplementableMethods(Context, Category->getClassInterface(),
5278 WantInstanceMethods, ReturnType, KnownMethods,
5279 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005280 }
5281
5282 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5283 // Recurse into protocols.
5284 const ObjCList<ObjCProtocolDecl> &Protocols
5285 = Protocol->getReferencedProtocols();
5286 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5287 E = Protocols.end();
5288 I != E; ++I)
5289 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00005290 KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005291 }
5292
5293 // Add methods in this container. This operation occurs last because
5294 // we want the methods from this container to override any methods
5295 // we've previously seen with the same selector.
5296 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
5297 MEnd = Container->meth_end();
5298 M != MEnd; ++M) {
5299 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
5300 if (!ReturnType.isNull() &&
5301 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
5302 continue;
5303
Douglas Gregor408be5a2010-08-25 01:08:01 +00005304 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005305 }
5306 }
5307}
5308
5309void Sema::CodeCompleteObjCMethodDecl(Scope *S,
5310 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00005311 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00005312 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005313 // Determine the return type of the method we're declaring, if
5314 // provided.
5315 QualType ReturnType = GetTypeFromParser(ReturnTy);
5316
Douglas Gregorea766182010-10-18 18:21:28 +00005317 // Determine where we should start searching for methods.
5318 ObjCContainerDecl *SearchDecl = 0;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005319 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00005320 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005321 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
5322 SearchDecl = Impl->getClassInterface();
Douglas Gregore8f5a172010-04-07 00:21:17 +00005323 IsInImplementation = true;
5324 } else if (ObjCCategoryImplDecl *CatImpl
Douglas Gregorea766182010-10-18 18:21:28 +00005325 = dyn_cast<ObjCCategoryImplDecl>(D)) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005326 SearchDecl = CatImpl->getCategoryDecl();
Douglas Gregore8f5a172010-04-07 00:21:17 +00005327 IsInImplementation = true;
Douglas Gregorea766182010-10-18 18:21:28 +00005328 } else
Douglas Gregore8f5a172010-04-07 00:21:17 +00005329 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005330 }
5331
5332 if (!SearchDecl && S) {
Douglas Gregorea766182010-10-18 18:21:28 +00005333 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity()))
Douglas Gregore8f5a172010-04-07 00:21:17 +00005334 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005335 }
5336
Douglas Gregorea766182010-10-18 18:21:28 +00005337 if (!SearchDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005338 HandleCodeCompleteResults(this, CodeCompleter,
5339 CodeCompletionContext::CCC_Other,
5340 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005341 return;
5342 }
5343
5344 // Find all of the methods that we could declare/implement here.
5345 KnownMethodsMap KnownMethods;
5346 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
Douglas Gregorea766182010-10-18 18:21:28 +00005347 ReturnType, KnownMethods);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005348
Douglas Gregore8f5a172010-04-07 00:21:17 +00005349 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00005350 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00005351 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregore8f5a172010-04-07 00:21:17 +00005352 Results.EnterNewScope();
5353 PrintingPolicy Policy(Context.PrintingPolicy);
5354 Policy.AnonymousTagLocations = false;
5355 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
5356 MEnd = KnownMethods.end();
5357 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00005358 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00005359 CodeCompletionString *Pattern = new CodeCompletionString;
5360
5361 // If the result type was not already provided, add it to the
5362 // pattern as (type).
5363 if (ReturnType.isNull()) {
5364 std::string TypeStr;
5365 Method->getResultType().getAsStringInternal(TypeStr, Policy);
5366 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5367 Pattern->AddTextChunk(TypeStr);
5368 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5369 }
5370
5371 Selector Sel = Method->getSelector();
5372
5373 // Add the first part of the selector to the pattern.
5374 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
5375
5376 // Add parameters to the pattern.
5377 unsigned I = 0;
5378 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
5379 PEnd = Method->param_end();
5380 P != PEnd; (void)++P, ++I) {
5381 // Add the part of the selector name.
5382 if (I == 0)
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00005383 Pattern->AddTypedTextChunk(":");
Douglas Gregore8f5a172010-04-07 00:21:17 +00005384 else if (I < Sel.getNumArgs()) {
5385 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00005386 Pattern->AddTypedTextChunk((Sel.getIdentifierInfoForSlot(I)->getName()
5387 + ":").str());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005388 } else
5389 break;
5390
5391 // Add the parameter type.
5392 std::string TypeStr;
5393 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
5394 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5395 Pattern->AddTextChunk(TypeStr);
5396 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5397
5398 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregore17794f2010-08-31 05:13:43 +00005399 Pattern->AddTextChunk(Id->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005400 }
5401
5402 if (Method->isVariadic()) {
5403 if (Method->param_size() > 0)
5404 Pattern->AddChunk(CodeCompletionString::CK_Comma);
5405 Pattern->AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00005406 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00005407
Douglas Gregor447107d2010-05-28 00:57:46 +00005408 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00005409 // We will be defining the method here, so add a compound statement.
5410 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5411 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
5412 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5413 if (!Method->getResultType()->isVoidType()) {
5414 // If the result type is not void, add a return clause.
5415 Pattern->AddTextChunk("return");
5416 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5417 Pattern->AddPlaceholderChunk("expression");
5418 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
5419 } else
5420 Pattern->AddPlaceholderChunk("statements");
5421
5422 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
5423 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
5424 }
5425
Douglas Gregor408be5a2010-08-25 01:08:01 +00005426 unsigned Priority = CCP_CodePattern;
5427 if (!M->second.second)
5428 Priority += CCD_InBaseClass;
5429
5430 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00005431 Method->isInstanceMethod()
5432 ? CXCursor_ObjCInstanceMethodDecl
5433 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00005434 }
5435
5436 Results.ExitScope();
5437
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005438 HandleCodeCompleteResults(this, CodeCompleter,
5439 CodeCompletionContext::CCC_Other,
5440 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00005441}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005442
5443void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
5444 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005445 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00005446 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005447 IdentifierInfo **SelIdents,
5448 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005449 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005450 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005451 if (ExternalSource) {
5452 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5453 I != N; ++I) {
5454 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005455 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005456 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00005457
5458 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005459 }
5460 }
5461
5462 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00005463 typedef CodeCompletionResult Result;
Douglas Gregor52779fb2010-09-23 23:01:17 +00005464 ResultBuilder Results(*this, CodeCompletionContext::CCC_Other);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005465
5466 if (ReturnTy)
5467 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00005468
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005469 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005470 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5471 MEnd = MethodPool.end();
5472 M != MEnd; ++M) {
5473 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
5474 &M->second.second;
5475 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005476 MethList = MethList->Next) {
5477 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5478 NumSelIdents))
5479 continue;
5480
Douglas Gregor40ed9a12010-07-08 23:37:41 +00005481 if (AtParameterName) {
5482 // Suggest parameter names we've seen before.
5483 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
5484 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
5485 if (Param->getIdentifier()) {
5486 CodeCompletionString *Pattern = new CodeCompletionString;
5487 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
5488 Results.AddResult(Pattern);
5489 }
5490 }
5491
5492 continue;
5493 }
5494
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005495 Result R(MethList->Method, 0);
5496 R.StartParameter = NumSelIdents;
5497 R.AllParametersAreInformative = false;
5498 R.DeclaringEntity = true;
5499 Results.MaybeAddResult(R, CurContext);
5500 }
5501 }
5502
5503 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005504 HandleCodeCompleteResults(this, CodeCompleter,
5505 CodeCompletionContext::CCC_Other,
5506 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00005507}
Douglas Gregor87c08a52010-08-13 22:48:40 +00005508
Douglas Gregorf29c5232010-08-24 22:20:20 +00005509void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005510 ResultBuilder Results(*this,
5511 CodeCompletionContext::CCC_PreprocessorDirective);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005512 Results.EnterNewScope();
5513
5514 // #if <condition>
5515 CodeCompletionString *Pattern = new CodeCompletionString;
5516 Pattern->AddTypedTextChunk("if");
5517 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5518 Pattern->AddPlaceholderChunk("condition");
5519 Results.AddResult(Pattern);
5520
5521 // #ifdef <macro>
5522 Pattern = new CodeCompletionString;
5523 Pattern->AddTypedTextChunk("ifdef");
5524 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5525 Pattern->AddPlaceholderChunk("macro");
5526 Results.AddResult(Pattern);
5527
5528 // #ifndef <macro>
5529 Pattern = new CodeCompletionString;
5530 Pattern->AddTypedTextChunk("ifndef");
5531 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5532 Pattern->AddPlaceholderChunk("macro");
5533 Results.AddResult(Pattern);
5534
5535 if (InConditional) {
5536 // #elif <condition>
5537 Pattern = new CodeCompletionString;
5538 Pattern->AddTypedTextChunk("elif");
5539 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5540 Pattern->AddPlaceholderChunk("condition");
5541 Results.AddResult(Pattern);
5542
5543 // #else
5544 Pattern = new CodeCompletionString;
5545 Pattern->AddTypedTextChunk("else");
5546 Results.AddResult(Pattern);
5547
5548 // #endif
5549 Pattern = new CodeCompletionString;
5550 Pattern->AddTypedTextChunk("endif");
5551 Results.AddResult(Pattern);
5552 }
5553
5554 // #include "header"
5555 Pattern = new CodeCompletionString;
5556 Pattern->AddTypedTextChunk("include");
5557 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5558 Pattern->AddTextChunk("\"");
5559 Pattern->AddPlaceholderChunk("header");
5560 Pattern->AddTextChunk("\"");
5561 Results.AddResult(Pattern);
5562
5563 // #include <header>
5564 Pattern = new CodeCompletionString;
5565 Pattern->AddTypedTextChunk("include");
5566 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5567 Pattern->AddTextChunk("<");
5568 Pattern->AddPlaceholderChunk("header");
5569 Pattern->AddTextChunk(">");
5570 Results.AddResult(Pattern);
5571
5572 // #define <macro>
5573 Pattern = new CodeCompletionString;
5574 Pattern->AddTypedTextChunk("define");
5575 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5576 Pattern->AddPlaceholderChunk("macro");
5577 Results.AddResult(Pattern);
5578
5579 // #define <macro>(<args>)
5580 Pattern = new CodeCompletionString;
5581 Pattern->AddTypedTextChunk("define");
5582 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5583 Pattern->AddPlaceholderChunk("macro");
5584 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5585 Pattern->AddPlaceholderChunk("args");
5586 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5587 Results.AddResult(Pattern);
5588
5589 // #undef <macro>
5590 Pattern = new CodeCompletionString;
5591 Pattern->AddTypedTextChunk("undef");
5592 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5593 Pattern->AddPlaceholderChunk("macro");
5594 Results.AddResult(Pattern);
5595
5596 // #line <number>
5597 Pattern = new CodeCompletionString;
5598 Pattern->AddTypedTextChunk("line");
5599 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5600 Pattern->AddPlaceholderChunk("number");
5601 Results.AddResult(Pattern);
5602
5603 // #line <number> "filename"
5604 Pattern = new CodeCompletionString;
5605 Pattern->AddTypedTextChunk("line");
5606 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5607 Pattern->AddPlaceholderChunk("number");
5608 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5609 Pattern->AddTextChunk("\"");
5610 Pattern->AddPlaceholderChunk("filename");
5611 Pattern->AddTextChunk("\"");
5612 Results.AddResult(Pattern);
5613
5614 // #error <message>
5615 Pattern = new CodeCompletionString;
5616 Pattern->AddTypedTextChunk("error");
5617 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5618 Pattern->AddPlaceholderChunk("message");
5619 Results.AddResult(Pattern);
5620
5621 // #pragma <arguments>
5622 Pattern = new CodeCompletionString;
5623 Pattern->AddTypedTextChunk("pragma");
5624 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5625 Pattern->AddPlaceholderChunk("arguments");
5626 Results.AddResult(Pattern);
5627
5628 if (getLangOptions().ObjC1) {
5629 // #import "header"
5630 Pattern = new CodeCompletionString;
5631 Pattern->AddTypedTextChunk("import");
5632 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5633 Pattern->AddTextChunk("\"");
5634 Pattern->AddPlaceholderChunk("header");
5635 Pattern->AddTextChunk("\"");
5636 Results.AddResult(Pattern);
5637
5638 // #import <header>
5639 Pattern = new CodeCompletionString;
5640 Pattern->AddTypedTextChunk("import");
5641 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5642 Pattern->AddTextChunk("<");
5643 Pattern->AddPlaceholderChunk("header");
5644 Pattern->AddTextChunk(">");
5645 Results.AddResult(Pattern);
5646 }
5647
5648 // #include_next "header"
5649 Pattern = new CodeCompletionString;
5650 Pattern->AddTypedTextChunk("include_next");
5651 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5652 Pattern->AddTextChunk("\"");
5653 Pattern->AddPlaceholderChunk("header");
5654 Pattern->AddTextChunk("\"");
5655 Results.AddResult(Pattern);
5656
5657 // #include_next <header>
5658 Pattern = new CodeCompletionString;
5659 Pattern->AddTypedTextChunk("include_next");
5660 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5661 Pattern->AddTextChunk("<");
5662 Pattern->AddPlaceholderChunk("header");
5663 Pattern->AddTextChunk(">");
5664 Results.AddResult(Pattern);
5665
5666 // #warning <message>
5667 Pattern = new CodeCompletionString;
5668 Pattern->AddTypedTextChunk("warning");
5669 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5670 Pattern->AddPlaceholderChunk("message");
5671 Results.AddResult(Pattern);
5672
5673 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
5674 // completions for them. And __include_macros is a Clang-internal extension
5675 // that we don't want to encourage anyone to use.
5676
5677 // FIXME: we don't support #assert or #unassert, so don't suggest them.
5678 Results.ExitScope();
5679
Douglas Gregorf44e8542010-08-24 19:08:16 +00005680 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00005681 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00005682 Results.data(), Results.size());
5683}
5684
5685void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00005686 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005687 S->getFnParent()? Sema::PCC_RecoveryInFunction
5688 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00005689}
5690
Douglas Gregorf29c5232010-08-24 22:20:20 +00005691void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005692 ResultBuilder Results(*this,
5693 IsDefinition? CodeCompletionContext::CCC_MacroName
5694 : CodeCompletionContext::CCC_MacroNameUse);
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005695 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
5696 // Add just the names of macros, not their arguments.
5697 Results.EnterNewScope();
5698 for (Preprocessor::macro_iterator M = PP.macro_begin(),
5699 MEnd = PP.macro_end();
5700 M != MEnd; ++M) {
5701 CodeCompletionString *Pattern = new CodeCompletionString;
5702 Pattern->AddTypedTextChunk(M->first->getName());
5703 Results.AddResult(Pattern);
5704 }
5705 Results.ExitScope();
5706 } else if (IsDefinition) {
5707 // FIXME: Can we detect when the user just wrote an include guard above?
5708 }
5709
Douglas Gregor52779fb2010-09-23 23:01:17 +00005710 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor1fbb4472010-08-24 20:21:13 +00005711 Results.data(), Results.size());
5712}
5713
Douglas Gregorf29c5232010-08-24 22:20:20 +00005714void Sema::CodeCompletePreprocessorExpression() {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005715 ResultBuilder Results(*this,
5716 CodeCompletionContext::CCC_PreprocessorExpression);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005717
5718 if (!CodeCompleter || CodeCompleter->includeMacros())
5719 AddMacroResults(PP, Results);
5720
5721 // defined (<macro>)
5722 Results.EnterNewScope();
5723 CodeCompletionString *Pattern = new CodeCompletionString;
5724 Pattern->AddTypedTextChunk("defined");
5725 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
5726 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
5727 Pattern->AddPlaceholderChunk("macro");
5728 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
5729 Results.AddResult(Pattern);
5730 Results.ExitScope();
5731
5732 HandleCodeCompleteResults(this, CodeCompleter,
5733 CodeCompletionContext::CCC_PreprocessorExpression,
5734 Results.data(), Results.size());
5735}
5736
5737void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
5738 IdentifierInfo *Macro,
5739 MacroInfo *MacroInfo,
5740 unsigned Argument) {
5741 // FIXME: In the future, we could provide "overload" results, much like we
5742 // do for function calls.
5743
5744 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00005745 S->getFnParent()? Sema::PCC_RecoveryInFunction
5746 : Sema::PCC_Namespace);
Douglas Gregorf29c5232010-08-24 22:20:20 +00005747}
5748
Douglas Gregor55817af2010-08-25 17:04:25 +00005749void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00005750 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00005751 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00005752 0, 0);
5753}
5754
Douglas Gregor87c08a52010-08-13 22:48:40 +00005755void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00005756 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor52779fb2010-09-23 23:01:17 +00005757 ResultBuilder Builder(*this, CodeCompletionContext::CCC_Recovery);
Douglas Gregor8071e422010-08-15 06:18:01 +00005758 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
5759 CodeCompletionDeclConsumer Consumer(Builder,
5760 Context.getTranslationUnitDecl());
5761 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
5762 Consumer);
5763 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00005764
5765 if (!CodeCompleter || CodeCompleter->includeMacros())
5766 AddMacroResults(PP, Builder);
5767
5768 Results.clear();
5769 Results.insert(Results.end(),
5770 Builder.data(), Builder.data() + Builder.size());
5771}