1 //===---------------- 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 //===----------------------------------------------------------------------===//
13 #include "clang/Sema/SemaInternal.h"
14 #include "clang/AST/DeclObjC.h"
15 #include "clang/AST/ExprCXX.h"
16 #include "clang/AST/ExprObjC.h"
17 #include "clang/Basic/CharInfo.h"
18 #include "clang/Lex/HeaderSearch.h"
19 #include "clang/Lex/MacroInfo.h"
20 #include "clang/Lex/Preprocessor.h"
21 #include "clang/Sema/CodeCompleteConsumer.h"
22 #include "clang/Sema/ExternalSemaSource.h"
23 #include "clang/Sema/Lookup.h"
24 #include "clang/Sema/Overload.h"
25 #include "clang/Sema/Scope.h"
26 #include "clang/Sema/ScopeInfo.h"
27 #include "llvm/ADT/DenseSet.h"
28 #include "llvm/ADT/SmallBitVector.h"
29 #include "llvm/ADT/SmallPtrSet.h"
30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/ADT/StringExtras.h"
32 #include "llvm/ADT/StringSwitch.h"
33 #include "llvm/ADT/Twine.h"
34 #include <list>
35 #include <map>
36 #include <vector>
37
38 using namespace clang;
39 using namespace sema;
40
41 namespace {
42 /// \brief A container of code-completion results.
43 class ResultBuilder {
44 public:
45 /// \brief The type of a name-lookup filter, which can be provided to the
46 /// name-lookup routines to specify which declarations should be included in
47 /// the result set (when it returns true) and which declarations should be
48 /// filtered out (returns false).
49 typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const;
50
51 typedef CodeCompletionResult Result;
52
53 private:
54 /// \brief The actual results we have found.
55 std::vector<Result> Results;
56
57 /// \brief A record of all of the declarations we have found and placed
58 /// into the result set, used to ensure that no declaration ever gets into
59 /// the result set twice.
60 llvm::SmallPtrSet<const Decl*, 16> AllDeclsFound;
61
62 typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair;
63
64 /// \brief An entry in the shadow map, which is optimized to store
65 /// a single (declaration, index) mapping (the common case) but
66 /// can also store a list of (declaration, index) mappings.
67 class ShadowMapEntry {
68 typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
69
70 /// \brief Contains either the solitary NamedDecl * or a vector
71 /// of (declaration, index) pairs.
72 llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector*> DeclOrVector;
73
74 /// \brief When the entry contains a single declaration, this is
75 /// the index associated with that entry.
76 unsigned SingleDeclIndex;
77
78 public:
ShadowMapEntry()79 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
80
Add(const NamedDecl * ND,unsigned Index)81 void Add(const NamedDecl *ND, unsigned Index) {
82 if (DeclOrVector.isNull()) {
83 // 0 - > 1 elements: just set the single element information.
84 DeclOrVector = ND;
85 SingleDeclIndex = Index;
86 return;
87 }
88
89 if (const NamedDecl *PrevND =
90 DeclOrVector.dyn_cast<const NamedDecl *>()) {
91 // 1 -> 2 elements: create the vector of results and push in the
92 // existing declaration.
93 DeclIndexPairVector *Vec = new DeclIndexPairVector;
94 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
95 DeclOrVector = Vec;
96 }
97
98 // Add the new element to the end of the vector.
99 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
100 DeclIndexPair(ND, Index));
101 }
102
Destroy()103 void Destroy() {
104 if (DeclIndexPairVector *Vec
105 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
106 delete Vec;
107 DeclOrVector = ((NamedDecl *)0);
108 }
109 }
110
111 // Iteration.
112 class iterator;
113 iterator begin() const;
114 iterator end() const;
115 };
116
117 /// \brief A mapping from declaration names to the declarations that have
118 /// this name within a particular scope and their index within the list of
119 /// results.
120 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
121
122 /// \brief The semantic analysis object for which results are being
123 /// produced.
124 Sema &SemaRef;
125
126 /// \brief The allocator used to allocate new code-completion strings.
127 CodeCompletionAllocator &Allocator;
128
129 CodeCompletionTUInfo &CCTUInfo;
130
131 /// \brief If non-NULL, a filter function used to remove any code-completion
132 /// results that are not desirable.
133 LookupFilter Filter;
134
135 /// \brief Whether we should allow declarations as
136 /// nested-name-specifiers that would otherwise be filtered out.
137 bool AllowNestedNameSpecifiers;
138
139 /// \brief If set, the type that we would prefer our resulting value
140 /// declarations to have.
141 ///
142 /// Closely matching the preferred type gives a boost to a result's
143 /// priority.
144 CanQualType PreferredType;
145
146 /// \brief A list of shadow maps, which is used to model name hiding at
147 /// different levels of, e.g., the inheritance hierarchy.
148 std::list<ShadowMap> ShadowMaps;
149
150 /// \brief If we're potentially referring to a C++ member function, the set
151 /// of qualifiers applied to the object type.
152 Qualifiers ObjectTypeQualifiers;
153
154 /// \brief Whether the \p ObjectTypeQualifiers field is active.
155 bool HasObjectTypeQualifiers;
156
157 /// \brief The selector that we prefer.
158 Selector PreferredSelector;
159
160 /// \brief The completion context in which we are gathering results.
161 CodeCompletionContext CompletionContext;
162
163 /// \brief If we are in an instance method definition, the \@implementation
164 /// object.
165 ObjCImplementationDecl *ObjCImplementation;
166
167 void AdjustResultPriorityForDecl(Result &R);
168
169 void MaybeAddConstructorResults(Result R);
170
171 public:
ResultBuilder(Sema & SemaRef,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,const CodeCompletionContext & CompletionContext,LookupFilter Filter=0)172 explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
173 CodeCompletionTUInfo &CCTUInfo,
174 const CodeCompletionContext &CompletionContext,
175 LookupFilter Filter = 0)
176 : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
177 Filter(Filter),
178 AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false),
179 CompletionContext(CompletionContext),
180 ObjCImplementation(0)
181 {
182 // If this is an Objective-C instance method definition, dig out the
183 // corresponding implementation.
184 switch (CompletionContext.getKind()) {
185 case CodeCompletionContext::CCC_Expression:
186 case CodeCompletionContext::CCC_ObjCMessageReceiver:
187 case CodeCompletionContext::CCC_ParenthesizedExpression:
188 case CodeCompletionContext::CCC_Statement:
189 case CodeCompletionContext::CCC_Recovery:
190 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
191 if (Method->isInstanceMethod())
192 if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
193 ObjCImplementation = Interface->getImplementation();
194 break;
195
196 default:
197 break;
198 }
199 }
200
201 /// \brief Determine the priority for a reference to the given declaration.
202 unsigned getBasePriority(const NamedDecl *D);
203
204 /// \brief Whether we should include code patterns in the completion
205 /// results.
includeCodePatterns() const206 bool includeCodePatterns() const {
207 return SemaRef.CodeCompleter &&
208 SemaRef.CodeCompleter->includeCodePatterns();
209 }
210
211 /// \brief Set the filter used for code-completion results.
setFilter(LookupFilter Filter)212 void setFilter(LookupFilter Filter) {
213 this->Filter = Filter;
214 }
215
data()216 Result *data() { return Results.empty()? 0 : &Results.front(); }
size() const217 unsigned size() const { return Results.size(); }
empty() const218 bool empty() const { return Results.empty(); }
219
220 /// \brief Specify the preferred type.
setPreferredType(QualType T)221 void setPreferredType(QualType T) {
222 PreferredType = SemaRef.Context.getCanonicalType(T);
223 }
224
225 /// \brief Set the cv-qualifiers on the object type, for us in filtering
226 /// calls to member functions.
227 ///
228 /// When there are qualifiers in this set, they will be used to filter
229 /// out member functions that aren't available (because there will be a
230 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
231 /// match.
setObjectTypeQualifiers(Qualifiers Quals)232 void setObjectTypeQualifiers(Qualifiers Quals) {
233 ObjectTypeQualifiers = Quals;
234 HasObjectTypeQualifiers = true;
235 }
236
237 /// \brief Set the preferred selector.
238 ///
239 /// When an Objective-C method declaration result is added, and that
240 /// method's selector matches this preferred selector, we give that method
241 /// a slight priority boost.
setPreferredSelector(Selector Sel)242 void setPreferredSelector(Selector Sel) {
243 PreferredSelector = Sel;
244 }
245
246 /// \brief Retrieve the code-completion context for which results are
247 /// being collected.
getCompletionContext() const248 const CodeCompletionContext &getCompletionContext() const {
249 return CompletionContext;
250 }
251
252 /// \brief Specify whether nested-name-specifiers are allowed.
allowNestedNameSpecifiers(bool Allow=true)253 void allowNestedNameSpecifiers(bool Allow = true) {
254 AllowNestedNameSpecifiers = Allow;
255 }
256
257 /// \brief Return the semantic analysis object for which we are collecting
258 /// code completion results.
getSema() const259 Sema &getSema() const { return SemaRef; }
260
261 /// \brief Retrieve the allocator used to allocate code completion strings.
getAllocator() const262 CodeCompletionAllocator &getAllocator() const { return Allocator; }
263
getCodeCompletionTUInfo() const264 CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
265
266 /// \brief Determine whether the given declaration is at all interesting
267 /// as a code-completion result.
268 ///
269 /// \param ND the declaration that we are inspecting.
270 ///
271 /// \param AsNestedNameSpecifier will be set true if this declaration is
272 /// only interesting when it is a nested-name-specifier.
273 bool isInterestingDecl(const NamedDecl *ND,
274 bool &AsNestedNameSpecifier) const;
275
276 /// \brief Check whether the result is hidden by the Hiding declaration.
277 ///
278 /// \returns true if the result is hidden and cannot be found, false if
279 /// the hidden result could still be found. When false, \p R may be
280 /// modified to describe how the result can be found (e.g., via extra
281 /// qualification).
282 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
283 const NamedDecl *Hiding);
284
285 /// \brief Add a new result to this result set (if it isn't already in one
286 /// of the shadow maps), or replace an existing result (for, e.g., a
287 /// redeclaration).
288 ///
289 /// \param R the result to add (if it is unique).
290 ///
291 /// \param CurContext the context in which this result will be named.
292 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
293
294 /// \brief Add a new result to this result set, where we already know
295 /// the hiding declation (if any).
296 ///
297 /// \param R the result to add (if it is unique).
298 ///
299 /// \param CurContext the context in which this result will be named.
300 ///
301 /// \param Hiding the declaration that hides the result.
302 ///
303 /// \param InBaseClass whether the result was found in a base
304 /// class of the searched context.
305 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
306 bool InBaseClass);
307
308 /// \brief Add a new non-declaration result to this result set.
309 void AddResult(Result R);
310
311 /// \brief Enter into a new scope.
312 void EnterNewScope();
313
314 /// \brief Exit from the current scope.
315 void ExitScope();
316
317 /// \brief Ignore this declaration, if it is seen again.
Ignore(const Decl * D)318 void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
319
320 /// \name Name lookup predicates
321 ///
322 /// These predicates can be passed to the name lookup functions to filter the
323 /// results of name lookup. All of the predicates have the same type, so that
324 ///
325 //@{
326 bool IsOrdinaryName(const NamedDecl *ND) const;
327 bool IsOrdinaryNonTypeName(const NamedDecl *ND) const;
328 bool IsIntegralConstantValue(const NamedDecl *ND) const;
329 bool IsOrdinaryNonValueName(const NamedDecl *ND) const;
330 bool IsNestedNameSpecifier(const NamedDecl *ND) const;
331 bool IsEnum(const NamedDecl *ND) const;
332 bool IsClassOrStruct(const NamedDecl *ND) const;
333 bool IsUnion(const NamedDecl *ND) const;
334 bool IsNamespace(const NamedDecl *ND) const;
335 bool IsNamespaceOrAlias(const NamedDecl *ND) const;
336 bool IsType(const NamedDecl *ND) const;
337 bool IsMember(const NamedDecl *ND) const;
338 bool IsObjCIvar(const NamedDecl *ND) const;
339 bool IsObjCMessageReceiver(const NamedDecl *ND) const;
340 bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const;
341 bool IsObjCCollection(const NamedDecl *ND) const;
342 bool IsImpossibleToSatisfy(const NamedDecl *ND) const;
343 //@}
344 };
345 }
346
347 class ResultBuilder::ShadowMapEntry::iterator {
348 llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
349 unsigned SingleDeclIndex;
350
351 public:
352 typedef DeclIndexPair value_type;
353 typedef value_type reference;
354 typedef std::ptrdiff_t difference_type;
355 typedef std::input_iterator_tag iterator_category;
356
357 class pointer {
358 DeclIndexPair Value;
359
360 public:
pointer(const DeclIndexPair & Value)361 pointer(const DeclIndexPair &Value) : Value(Value) { }
362
operator ->() const363 const DeclIndexPair *operator->() const {
364 return &Value;
365 }
366 };
367
iterator()368 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
369
iterator(const NamedDecl * SingleDecl,unsigned Index)370 iterator(const NamedDecl *SingleDecl, unsigned Index)
371 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
372
iterator(const DeclIndexPair * Iterator)373 iterator(const DeclIndexPair *Iterator)
374 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
375
operator ++()376 iterator &operator++() {
377 if (DeclOrIterator.is<const NamedDecl *>()) {
378 DeclOrIterator = (NamedDecl *)0;
379 SingleDeclIndex = 0;
380 return *this;
381 }
382
383 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
384 ++I;
385 DeclOrIterator = I;
386 return *this;
387 }
388
389 /*iterator operator++(int) {
390 iterator tmp(*this);
391 ++(*this);
392 return tmp;
393 }*/
394
operator *() const395 reference operator*() const {
396 if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>())
397 return reference(ND, SingleDeclIndex);
398
399 return *DeclOrIterator.get<const DeclIndexPair*>();
400 }
401
operator ->() const402 pointer operator->() const {
403 return pointer(**this);
404 }
405
operator ==(const iterator & X,const iterator & Y)406 friend bool operator==(const iterator &X, const iterator &Y) {
407 return X.DeclOrIterator.getOpaqueValue()
408 == Y.DeclOrIterator.getOpaqueValue() &&
409 X.SingleDeclIndex == Y.SingleDeclIndex;
410 }
411
operator !=(const iterator & X,const iterator & Y)412 friend bool operator!=(const iterator &X, const iterator &Y) {
413 return !(X == Y);
414 }
415 };
416
417 ResultBuilder::ShadowMapEntry::iterator
begin() const418 ResultBuilder::ShadowMapEntry::begin() const {
419 if (DeclOrVector.isNull())
420 return iterator();
421
422 if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>())
423 return iterator(ND, SingleDeclIndex);
424
425 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
426 }
427
428 ResultBuilder::ShadowMapEntry::iterator
end() const429 ResultBuilder::ShadowMapEntry::end() const {
430 if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull())
431 return iterator();
432
433 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
434 }
435
436 /// \brief Compute the qualification required to get from the current context
437 /// (\p CurContext) to the target context (\p TargetContext).
438 ///
439 /// \param Context the AST context in which the qualification will be used.
440 ///
441 /// \param CurContext the context where an entity is being named, which is
442 /// typically based on the current scope.
443 ///
444 /// \param TargetContext the context in which the named entity actually
445 /// resides.
446 ///
447 /// \returns a nested name specifier that refers into the target context, or
448 /// NULL if no qualification is needed.
449 static NestedNameSpecifier *
getRequiredQualification(ASTContext & Context,const DeclContext * CurContext,const DeclContext * TargetContext)450 getRequiredQualification(ASTContext &Context,
451 const DeclContext *CurContext,
452 const DeclContext *TargetContext) {
453 SmallVector<const DeclContext *, 4> TargetParents;
454
455 for (const DeclContext *CommonAncestor = TargetContext;
456 CommonAncestor && !CommonAncestor->Encloses(CurContext);
457 CommonAncestor = CommonAncestor->getLookupParent()) {
458 if (CommonAncestor->isTransparentContext() ||
459 CommonAncestor->isFunctionOrMethod())
460 continue;
461
462 TargetParents.push_back(CommonAncestor);
463 }
464
465 NestedNameSpecifier *Result = 0;
466 while (!TargetParents.empty()) {
467 const DeclContext *Parent = TargetParents.pop_back_val();
468
469 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
470 if (!Namespace->getIdentifier())
471 continue;
472
473 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
474 }
475 else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent))
476 Result = NestedNameSpecifier::Create(Context, Result,
477 false,
478 Context.getTypeDeclType(TD).getTypePtr());
479 }
480 return Result;
481 }
482
isInterestingDecl(const NamedDecl * ND,bool & AsNestedNameSpecifier) const483 bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
484 bool &AsNestedNameSpecifier) const {
485 AsNestedNameSpecifier = false;
486
487 ND = ND->getUnderlyingDecl();
488 unsigned IDNS = ND->getIdentifierNamespace();
489
490 // Skip unnamed entities.
491 if (!ND->getDeclName())
492 return false;
493
494 // Friend declarations and declarations introduced due to friends are never
495 // added as results.
496 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
497 return false;
498
499 // Class template (partial) specializations are never added as results.
500 if (isa<ClassTemplateSpecializationDecl>(ND) ||
501 isa<ClassTemplatePartialSpecializationDecl>(ND))
502 return false;
503
504 // Using declarations themselves are never added as results.
505 if (isa<UsingDecl>(ND))
506 return false;
507
508 // Some declarations have reserved names that we don't want to ever show.
509 if (const IdentifierInfo *Id = ND->getIdentifier()) {
510 // __va_list_tag is a freak of nature. Find it and skip it.
511 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
512 return false;
513
514 // Filter out names reserved for the implementation (C99 7.1.3,
515 // C++ [lib.global.names]) if they come from a system header.
516 //
517 // FIXME: Add predicate for this.
518 if (Id->getLength() >= 2) {
519 const char *Name = Id->getNameStart();
520 if (Name[0] == '_' &&
521 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
522 (ND->getLocation().isInvalid() ||
523 SemaRef.SourceMgr.isInSystemHeader(
524 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
525 return false;
526 }
527 }
528
529 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
530 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
531 Filter != &ResultBuilder::IsNamespace &&
532 Filter != &ResultBuilder::IsNamespaceOrAlias &&
533 Filter != 0))
534 AsNestedNameSpecifier = true;
535
536 // Filter out any unwanted results.
537 if (Filter && !(this->*Filter)(ND)) {
538 // Check whether it is interesting as a nested-name-specifier.
539 if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus &&
540 IsNestedNameSpecifier(ND) &&
541 (Filter != &ResultBuilder::IsMember ||
542 (isa<CXXRecordDecl>(ND) &&
543 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
544 AsNestedNameSpecifier = true;
545 return true;
546 }
547
548 return false;
549 }
550 // ... then it must be interesting!
551 return true;
552 }
553
CheckHiddenResult(Result & R,DeclContext * CurContext,const NamedDecl * Hiding)554 bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
555 const NamedDecl *Hiding) {
556 // In C, there is no way to refer to a hidden name.
557 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
558 // name if we introduce the tag type.
559 if (!SemaRef.getLangOpts().CPlusPlus)
560 return true;
561
562 const DeclContext *HiddenCtx =
563 R.Declaration->getDeclContext()->getRedeclContext();
564
565 // There is no way to qualify a name declared in a function or method.
566 if (HiddenCtx->isFunctionOrMethod())
567 return true;
568
569 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
570 return true;
571
572 // We can refer to the result with the appropriate qualification. Do it.
573 R.Hidden = true;
574 R.QualifierIsInformative = false;
575
576 if (!R.Qualifier)
577 R.Qualifier = getRequiredQualification(SemaRef.Context,
578 CurContext,
579 R.Declaration->getDeclContext());
580 return false;
581 }
582
583 /// \brief A simplified classification of types used to determine whether two
584 /// types are "similar enough" when adjusting priorities.
getSimplifiedTypeClass(CanQualType T)585 SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
586 switch (T->getTypeClass()) {
587 case Type::Builtin:
588 switch (cast<BuiltinType>(T)->getKind()) {
589 case BuiltinType::Void:
590 return STC_Void;
591
592 case BuiltinType::NullPtr:
593 return STC_Pointer;
594
595 case BuiltinType::Overload:
596 case BuiltinType::Dependent:
597 return STC_Other;
598
599 case BuiltinType::ObjCId:
600 case BuiltinType::ObjCClass:
601 case BuiltinType::ObjCSel:
602 return STC_ObjectiveC;
603
604 default:
605 return STC_Arithmetic;
606 }
607
608 case Type::Complex:
609 return STC_Arithmetic;
610
611 case Type::Pointer:
612 return STC_Pointer;
613
614 case Type::BlockPointer:
615 return STC_Block;
616
617 case Type::LValueReference:
618 case Type::RValueReference:
619 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
620
621 case Type::ConstantArray:
622 case Type::IncompleteArray:
623 case Type::VariableArray:
624 case Type::DependentSizedArray:
625 return STC_Array;
626
627 case Type::DependentSizedExtVector:
628 case Type::Vector:
629 case Type::ExtVector:
630 return STC_Arithmetic;
631
632 case Type::FunctionProto:
633 case Type::FunctionNoProto:
634 return STC_Function;
635
636 case Type::Record:
637 return STC_Record;
638
639 case Type::Enum:
640 return STC_Arithmetic;
641
642 case Type::ObjCObject:
643 case Type::ObjCInterface:
644 case Type::ObjCObjectPointer:
645 return STC_ObjectiveC;
646
647 default:
648 return STC_Other;
649 }
650 }
651
652 /// \brief Get the type that a given expression will have if this declaration
653 /// is used as an expression in its "typical" code-completion form.
getDeclUsageType(ASTContext & C,const NamedDecl * ND)654 QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
655 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
656
657 if (const TypeDecl *Type = dyn_cast<TypeDecl>(ND))
658 return C.getTypeDeclType(Type);
659 if (const ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
660 return C.getObjCInterfaceType(Iface);
661
662 QualType T;
663 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
664 T = Function->getCallResultType();
665 else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
666 T = Method->getSendResultType();
667 else if (const FunctionTemplateDecl *FunTmpl =
668 dyn_cast<FunctionTemplateDecl>(ND))
669 T = FunTmpl->getTemplatedDecl()->getCallResultType();
670 else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
671 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
672 else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
673 T = Property->getType();
674 else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND))
675 T = Value->getType();
676 else
677 return QualType();
678
679 // Dig through references, function pointers, and block pointers to
680 // get down to the likely type of an expression when the entity is
681 // used.
682 do {
683 if (const ReferenceType *Ref = T->getAs<ReferenceType>()) {
684 T = Ref->getPointeeType();
685 continue;
686 }
687
688 if (const PointerType *Pointer = T->getAs<PointerType>()) {
689 if (Pointer->getPointeeType()->isFunctionType()) {
690 T = Pointer->getPointeeType();
691 continue;
692 }
693
694 break;
695 }
696
697 if (const BlockPointerType *Block = T->getAs<BlockPointerType>()) {
698 T = Block->getPointeeType();
699 continue;
700 }
701
702 if (const FunctionType *Function = T->getAs<FunctionType>()) {
703 T = Function->getResultType();
704 continue;
705 }
706
707 break;
708 } while (true);
709
710 return T;
711 }
712
getBasePriority(const NamedDecl * ND)713 unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) {
714 if (!ND)
715 return CCP_Unlikely;
716
717 // Context-based decisions.
718 const DeclContext *LexicalDC = ND->getLexicalDeclContext();
719 if (LexicalDC->isFunctionOrMethod()) {
720 // _cmd is relatively rare
721 if (const ImplicitParamDecl *ImplicitParam =
722 dyn_cast<ImplicitParamDecl>(ND))
723 if (ImplicitParam->getIdentifier() &&
724 ImplicitParam->getIdentifier()->isStr("_cmd"))
725 return CCP_ObjC_cmd;
726
727 return CCP_LocalDeclaration;
728 }
729
730 const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
731 if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
732 return CCP_MemberDeclaration;
733
734 // Content-based decisions.
735 if (isa<EnumConstantDecl>(ND))
736 return CCP_Constant;
737
738 // Use CCP_Type for type declarations unless we're in a statement, Objective-C
739 // message receiver, or parenthesized expression context. There, it's as
740 // likely that the user will want to write a type as other declarations.
741 if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
742 !(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement ||
743 CompletionContext.getKind()
744 == CodeCompletionContext::CCC_ObjCMessageReceiver ||
745 CompletionContext.getKind()
746 == CodeCompletionContext::CCC_ParenthesizedExpression))
747 return CCP_Type;
748
749 return CCP_Declaration;
750 }
751
AdjustResultPriorityForDecl(Result & R)752 void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
753 // If this is an Objective-C method declaration whose selector matches our
754 // preferred selector, give it a priority boost.
755 if (!PreferredSelector.isNull())
756 if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
757 if (PreferredSelector == Method->getSelector())
758 R.Priority += CCD_SelectorMatch;
759
760 // If we have a preferred type, adjust the priority for results with exactly-
761 // matching or nearly-matching types.
762 if (!PreferredType.isNull()) {
763 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
764 if (!T.isNull()) {
765 CanQualType TC = SemaRef.Context.getCanonicalType(T);
766 // Check for exactly-matching types (modulo qualifiers).
767 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
768 R.Priority /= CCF_ExactTypeMatch;
769 // Check for nearly-matching types, based on classification of each.
770 else if ((getSimplifiedTypeClass(PreferredType)
771 == getSimplifiedTypeClass(TC)) &&
772 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
773 R.Priority /= CCF_SimilarTypeMatch;
774 }
775 }
776 }
777
MaybeAddConstructorResults(Result R)778 void ResultBuilder::MaybeAddConstructorResults(Result R) {
779 if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration ||
780 !CompletionContext.wantConstructorResults())
781 return;
782
783 ASTContext &Context = SemaRef.Context;
784 const NamedDecl *D = R.Declaration;
785 const CXXRecordDecl *Record = 0;
786 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
787 Record = ClassTemplate->getTemplatedDecl();
788 else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
789 // Skip specializations and partial specializations.
790 if (isa<ClassTemplateSpecializationDecl>(Record))
791 return;
792 } else {
793 // There are no constructors here.
794 return;
795 }
796
797 Record = Record->getDefinition();
798 if (!Record)
799 return;
800
801
802 QualType RecordTy = Context.getTypeDeclType(Record);
803 DeclarationName ConstructorName
804 = Context.DeclarationNames.getCXXConstructorName(
805 Context.getCanonicalType(RecordTy));
806 DeclContext::lookup_const_result Ctors = Record->lookup(ConstructorName);
807 for (DeclContext::lookup_const_iterator I = Ctors.begin(),
808 E = Ctors.end();
809 I != E; ++I) {
810 R.Declaration = *I;
811 R.CursorKind = getCursorKindForDecl(R.Declaration);
812 Results.push_back(R);
813 }
814 }
815
MaybeAddResult(Result R,DeclContext * CurContext)816 void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
817 assert(!ShadowMaps.empty() && "Must enter into a results scope");
818
819 if (R.Kind != Result::RK_Declaration) {
820 // For non-declaration results, just add the result.
821 Results.push_back(R);
822 return;
823 }
824
825 // Look through using declarations.
826 if (const UsingShadowDecl *Using =
827 dyn_cast<UsingShadowDecl>(R.Declaration)) {
828 MaybeAddResult(Result(Using->getTargetDecl(),
829 getBasePriority(Using->getTargetDecl()),
830 R.Qualifier),
831 CurContext);
832 return;
833 }
834
835 const Decl *CanonDecl = R.Declaration->getCanonicalDecl();
836 unsigned IDNS = CanonDecl->getIdentifierNamespace();
837
838 bool AsNestedNameSpecifier = false;
839 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
840 return;
841
842 // C++ constructors are never found by name lookup.
843 if (isa<CXXConstructorDecl>(R.Declaration))
844 return;
845
846 ShadowMap &SMap = ShadowMaps.back();
847 ShadowMapEntry::iterator I, IEnd;
848 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
849 if (NamePos != SMap.end()) {
850 I = NamePos->second.begin();
851 IEnd = NamePos->second.end();
852 }
853
854 for (; I != IEnd; ++I) {
855 const NamedDecl *ND = I->first;
856 unsigned Index = I->second;
857 if (ND->getCanonicalDecl() == CanonDecl) {
858 // This is a redeclaration. Always pick the newer declaration.
859 Results[Index].Declaration = R.Declaration;
860
861 // We're done.
862 return;
863 }
864 }
865
866 // This is a new declaration in this scope. However, check whether this
867 // declaration name is hidden by a similarly-named declaration in an outer
868 // scope.
869 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
870 --SMEnd;
871 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
872 ShadowMapEntry::iterator I, IEnd;
873 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
874 if (NamePos != SM->end()) {
875 I = NamePos->second.begin();
876 IEnd = NamePos->second.end();
877 }
878 for (; I != IEnd; ++I) {
879 // A tag declaration does not hide a non-tag declaration.
880 if (I->first->hasTagIdentifierNamespace() &&
881 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
882 Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol)))
883 continue;
884
885 // Protocols are in distinct namespaces from everything else.
886 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
887 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
888 I->first->getIdentifierNamespace() != IDNS)
889 continue;
890
891 // The newly-added result is hidden by an entry in the shadow map.
892 if (CheckHiddenResult(R, CurContext, I->first))
893 return;
894
895 break;
896 }
897 }
898
899 // Make sure that any given declaration only shows up in the result set once.
900 if (!AllDeclsFound.insert(CanonDecl))
901 return;
902
903 // If the filter is for nested-name-specifiers, then this result starts a
904 // nested-name-specifier.
905 if (AsNestedNameSpecifier) {
906 R.StartsNestedNameSpecifier = true;
907 R.Priority = CCP_NestedNameSpecifier;
908 } else
909 AdjustResultPriorityForDecl(R);
910
911 // If this result is supposed to have an informative qualifier, add one.
912 if (R.QualifierIsInformative && !R.Qualifier &&
913 !R.StartsNestedNameSpecifier) {
914 const DeclContext *Ctx = R.Declaration->getDeclContext();
915 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
916 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
917 else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
918 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
919 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
920 else
921 R.QualifierIsInformative = false;
922 }
923
924 // Insert this result into the set of results and into the current shadow
925 // map.
926 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
927 Results.push_back(R);
928
929 if (!AsNestedNameSpecifier)
930 MaybeAddConstructorResults(R);
931 }
932
AddResult(Result R,DeclContext * CurContext,NamedDecl * Hiding,bool InBaseClass=false)933 void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
934 NamedDecl *Hiding, bool InBaseClass = false) {
935 if (R.Kind != Result::RK_Declaration) {
936 // For non-declaration results, just add the result.
937 Results.push_back(R);
938 return;
939 }
940
941 // Look through using declarations.
942 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
943 AddResult(Result(Using->getTargetDecl(),
944 getBasePriority(Using->getTargetDecl()),
945 R.Qualifier),
946 CurContext, Hiding);
947 return;
948 }
949
950 bool AsNestedNameSpecifier = false;
951 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
952 return;
953
954 // C++ constructors are never found by name lookup.
955 if (isa<CXXConstructorDecl>(R.Declaration))
956 return;
957
958 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
959 return;
960
961 // Make sure that any given declaration only shows up in the result set once.
962 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
963 return;
964
965 // If the filter is for nested-name-specifiers, then this result starts a
966 // nested-name-specifier.
967 if (AsNestedNameSpecifier) {
968 R.StartsNestedNameSpecifier = true;
969 R.Priority = CCP_NestedNameSpecifier;
970 }
971 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
972 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
973 ->getRedeclContext()))
974 R.QualifierIsInformative = true;
975
976 // If this result is supposed to have an informative qualifier, add one.
977 if (R.QualifierIsInformative && !R.Qualifier &&
978 !R.StartsNestedNameSpecifier) {
979 const DeclContext *Ctx = R.Declaration->getDeclContext();
980 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
981 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
982 else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
983 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
984 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
985 else
986 R.QualifierIsInformative = false;
987 }
988
989 // Adjust the priority if this result comes from a base class.
990 if (InBaseClass)
991 R.Priority += CCD_InBaseClass;
992
993 AdjustResultPriorityForDecl(R);
994
995 if (HasObjectTypeQualifiers)
996 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
997 if (Method->isInstance()) {
998 Qualifiers MethodQuals
999 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
1000 if (ObjectTypeQualifiers == MethodQuals)
1001 R.Priority += CCD_ObjectQualifierMatch;
1002 else if (ObjectTypeQualifiers - MethodQuals) {
1003 // The method cannot be invoked, because doing so would drop
1004 // qualifiers.
1005 return;
1006 }
1007 }
1008
1009 // Insert this result into the set of results.
1010 Results.push_back(R);
1011
1012 if (!AsNestedNameSpecifier)
1013 MaybeAddConstructorResults(R);
1014 }
1015
AddResult(Result R)1016 void ResultBuilder::AddResult(Result R) {
1017 assert(R.Kind != Result::RK_Declaration &&
1018 "Declaration results need more context");
1019 Results.push_back(R);
1020 }
1021
1022 /// \brief Enter into a new scope.
EnterNewScope()1023 void ResultBuilder::EnterNewScope() {
1024 ShadowMaps.push_back(ShadowMap());
1025 }
1026
1027 /// \brief Exit from the current scope.
ExitScope()1028 void ResultBuilder::ExitScope() {
1029 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
1030 EEnd = ShadowMaps.back().end();
1031 E != EEnd;
1032 ++E)
1033 E->second.Destroy();
1034
1035 ShadowMaps.pop_back();
1036 }
1037
1038 /// \brief Determines whether this given declaration will be found by
1039 /// ordinary name lookup.
IsOrdinaryName(const NamedDecl * ND) const1040 bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
1041 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1042
1043 // If name lookup finds a local extern declaration, then we are in a
1044 // context where it behaves like an ordinary name.
1045 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1046 if (SemaRef.getLangOpts().CPlusPlus)
1047 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1048 else if (SemaRef.getLangOpts().ObjC1) {
1049 if (isa<ObjCIvarDecl>(ND))
1050 return true;
1051 }
1052
1053 return ND->getIdentifierNamespace() & IDNS;
1054 }
1055
1056 /// \brief Determines whether this given declaration will be found by
1057 /// ordinary name lookup but is not a type name.
IsOrdinaryNonTypeName(const NamedDecl * ND) const1058 bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
1059 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1060 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
1061 return false;
1062
1063 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1064 if (SemaRef.getLangOpts().CPlusPlus)
1065 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1066 else if (SemaRef.getLangOpts().ObjC1) {
1067 if (isa<ObjCIvarDecl>(ND))
1068 return true;
1069 }
1070
1071 return ND->getIdentifierNamespace() & IDNS;
1072 }
1073
IsIntegralConstantValue(const NamedDecl * ND) const1074 bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {
1075 if (!IsOrdinaryNonTypeName(ND))
1076 return 0;
1077
1078 if (const ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
1079 if (VD->getType()->isIntegralOrEnumerationType())
1080 return true;
1081
1082 return false;
1083 }
1084
1085 /// \brief Determines whether this given declaration will be found by
1086 /// ordinary name lookup.
IsOrdinaryNonValueName(const NamedDecl * ND) const1087 bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
1088 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1089
1090 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1091 if (SemaRef.getLangOpts().CPlusPlus)
1092 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
1093
1094 return (ND->getIdentifierNamespace() & IDNS) &&
1095 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
1096 !isa<ObjCPropertyDecl>(ND);
1097 }
1098
1099 /// \brief Determines whether the given declaration is suitable as the
1100 /// start of a C++ nested-name-specifier, e.g., a class or namespace.
IsNestedNameSpecifier(const NamedDecl * ND) const1101 bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {
1102 // Allow us to find class templates, too.
1103 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1104 ND = ClassTemplate->getTemplatedDecl();
1105
1106 return SemaRef.isAcceptableNestedNameSpecifier(ND);
1107 }
1108
1109 /// \brief Determines whether the given declaration is an enumeration.
IsEnum(const NamedDecl * ND) const1110 bool ResultBuilder::IsEnum(const NamedDecl *ND) const {
1111 return isa<EnumDecl>(ND);
1112 }
1113
1114 /// \brief Determines whether the given declaration is a class or struct.
IsClassOrStruct(const NamedDecl * ND) const1115 bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {
1116 // Allow us to find class templates, too.
1117 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1118 ND = ClassTemplate->getTemplatedDecl();
1119
1120 // For purposes of this check, interfaces match too.
1121 if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
1122 return RD->getTagKind() == TTK_Class ||
1123 RD->getTagKind() == TTK_Struct ||
1124 RD->getTagKind() == TTK_Interface;
1125
1126 return false;
1127 }
1128
1129 /// \brief Determines whether the given declaration is a union.
IsUnion(const NamedDecl * ND) const1130 bool ResultBuilder::IsUnion(const NamedDecl *ND) const {
1131 // Allow us to find class templates, too.
1132 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1133 ND = ClassTemplate->getTemplatedDecl();
1134
1135 if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
1136 return RD->getTagKind() == TTK_Union;
1137
1138 return false;
1139 }
1140
1141 /// \brief Determines whether the given declaration is a namespace.
IsNamespace(const NamedDecl * ND) const1142 bool ResultBuilder::IsNamespace(const NamedDecl *ND) const {
1143 return isa<NamespaceDecl>(ND);
1144 }
1145
1146 /// \brief Determines whether the given declaration is a namespace or
1147 /// namespace alias.
IsNamespaceOrAlias(const NamedDecl * ND) const1148 bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {
1149 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
1150 }
1151
1152 /// \brief Determines whether the given declaration is a type.
IsType(const NamedDecl * ND) const1153 bool ResultBuilder::IsType(const NamedDecl *ND) const {
1154 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1155 ND = Using->getTargetDecl();
1156
1157 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
1158 }
1159
1160 /// \brief Determines which members of a class should be visible via
1161 /// "." or "->". Only value declarations, nested name specifiers, and
1162 /// using declarations thereof should show up.
IsMember(const NamedDecl * ND) const1163 bool ResultBuilder::IsMember(const NamedDecl *ND) const {
1164 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1165 ND = Using->getTargetDecl();
1166
1167 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1168 isa<ObjCPropertyDecl>(ND);
1169 }
1170
isObjCReceiverType(ASTContext & C,QualType T)1171 static bool isObjCReceiverType(ASTContext &C, QualType T) {
1172 T = C.getCanonicalType(T);
1173 switch (T->getTypeClass()) {
1174 case Type::ObjCObject:
1175 case Type::ObjCInterface:
1176 case Type::ObjCObjectPointer:
1177 return true;
1178
1179 case Type::Builtin:
1180 switch (cast<BuiltinType>(T)->getKind()) {
1181 case BuiltinType::ObjCId:
1182 case BuiltinType::ObjCClass:
1183 case BuiltinType::ObjCSel:
1184 return true;
1185
1186 default:
1187 break;
1188 }
1189 return false;
1190
1191 default:
1192 break;
1193 }
1194
1195 if (!C.getLangOpts().CPlusPlus)
1196 return false;
1197
1198 // FIXME: We could perform more analysis here to determine whether a
1199 // particular class type has any conversions to Objective-C types. For now,
1200 // just accept all class types.
1201 return T->isDependentType() || T->isRecordType();
1202 }
1203
IsObjCMessageReceiver(const NamedDecl * ND) const1204 bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
1205 QualType T = getDeclUsageType(SemaRef.Context, ND);
1206 if (T.isNull())
1207 return false;
1208
1209 T = SemaRef.Context.getBaseElementType(T);
1210 return isObjCReceiverType(SemaRef.Context, T);
1211 }
1212
IsObjCMessageReceiverOrLambdaCapture(const NamedDecl * ND) const1213 bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const {
1214 if (IsObjCMessageReceiver(ND))
1215 return true;
1216
1217 const VarDecl *Var = dyn_cast<VarDecl>(ND);
1218 if (!Var)
1219 return false;
1220
1221 return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
1222 }
1223
IsObjCCollection(const NamedDecl * ND) const1224 bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
1225 if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
1226 (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1227 return false;
1228
1229 QualType T = getDeclUsageType(SemaRef.Context, ND);
1230 if (T.isNull())
1231 return false;
1232
1233 T = SemaRef.Context.getBaseElementType(T);
1234 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1235 T->isObjCIdType() ||
1236 (SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
1237 }
1238
IsImpossibleToSatisfy(const NamedDecl * ND) const1239 bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {
1240 return false;
1241 }
1242
1243 /// \brief Determines whether the given declaration is an Objective-C
1244 /// instance variable.
IsObjCIvar(const NamedDecl * ND) const1245 bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {
1246 return isa<ObjCIvarDecl>(ND);
1247 }
1248
1249 namespace {
1250 /// \brief Visible declaration consumer that adds a code-completion result
1251 /// for each visible declaration.
1252 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1253 ResultBuilder &Results;
1254 DeclContext *CurContext;
1255
1256 public:
CodeCompletionDeclConsumer(ResultBuilder & Results,DeclContext * CurContext)1257 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1258 : Results(Results), CurContext(CurContext) { }
1259
FoundDecl(NamedDecl * ND,NamedDecl * Hiding,DeclContext * Ctx,bool InBaseClass)1260 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
1261 bool InBaseClass) {
1262 bool Accessible = true;
1263 if (Ctx)
1264 Accessible = Results.getSema().IsSimplyAccessible(ND, Ctx);
1265
1266 ResultBuilder::Result Result(ND, Results.getBasePriority(ND), 0, false,
1267 Accessible);
1268 Results.AddResult(Result, CurContext, Hiding, InBaseClass);
1269 }
1270 };
1271 }
1272
1273 /// \brief Add type specifiers for the current language as keyword results.
AddTypeSpecifierResults(const LangOptions & LangOpts,ResultBuilder & Results)1274 static void AddTypeSpecifierResults(const LangOptions &LangOpts,
1275 ResultBuilder &Results) {
1276 typedef CodeCompletionResult Result;
1277 Results.AddResult(Result("short", CCP_Type));
1278 Results.AddResult(Result("long", CCP_Type));
1279 Results.AddResult(Result("signed", CCP_Type));
1280 Results.AddResult(Result("unsigned", CCP_Type));
1281 Results.AddResult(Result("void", CCP_Type));
1282 Results.AddResult(Result("char", CCP_Type));
1283 Results.AddResult(Result("int", CCP_Type));
1284 Results.AddResult(Result("float", CCP_Type));
1285 Results.AddResult(Result("double", CCP_Type));
1286 Results.AddResult(Result("enum", CCP_Type));
1287 Results.AddResult(Result("struct", CCP_Type));
1288 Results.AddResult(Result("union", CCP_Type));
1289 Results.AddResult(Result("const", CCP_Type));
1290 Results.AddResult(Result("volatile", CCP_Type));
1291
1292 if (LangOpts.C99) {
1293 // C99-specific
1294 Results.AddResult(Result("_Complex", CCP_Type));
1295 Results.AddResult(Result("_Imaginary", CCP_Type));
1296 Results.AddResult(Result("_Bool", CCP_Type));
1297 Results.AddResult(Result("restrict", CCP_Type));
1298 }
1299
1300 CodeCompletionBuilder Builder(Results.getAllocator(),
1301 Results.getCodeCompletionTUInfo());
1302 if (LangOpts.CPlusPlus) {
1303 // C++-specific
1304 Results.AddResult(Result("bool", CCP_Type +
1305 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
1306 Results.AddResult(Result("class", CCP_Type));
1307 Results.AddResult(Result("wchar_t", CCP_Type));
1308
1309 // typename qualified-id
1310 Builder.AddTypedTextChunk("typename");
1311 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1312 Builder.AddPlaceholderChunk("qualifier");
1313 Builder.AddTextChunk("::");
1314 Builder.AddPlaceholderChunk("name");
1315 Results.AddResult(Result(Builder.TakeString()));
1316
1317 if (LangOpts.CPlusPlus11) {
1318 Results.AddResult(Result("auto", CCP_Type));
1319 Results.AddResult(Result("char16_t", CCP_Type));
1320 Results.AddResult(Result("char32_t", CCP_Type));
1321
1322 Builder.AddTypedTextChunk("decltype");
1323 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1324 Builder.AddPlaceholderChunk("expression");
1325 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1326 Results.AddResult(Result(Builder.TakeString()));
1327 }
1328 }
1329
1330 // GNU extensions
1331 if (LangOpts.GNUMode) {
1332 // FIXME: Enable when we actually support decimal floating point.
1333 // Results.AddResult(Result("_Decimal32"));
1334 // Results.AddResult(Result("_Decimal64"));
1335 // Results.AddResult(Result("_Decimal128"));
1336
1337 Builder.AddTypedTextChunk("typeof");
1338 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1339 Builder.AddPlaceholderChunk("expression");
1340 Results.AddResult(Result(Builder.TakeString()));
1341
1342 Builder.AddTypedTextChunk("typeof");
1343 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1344 Builder.AddPlaceholderChunk("type");
1345 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1346 Results.AddResult(Result(Builder.TakeString()));
1347 }
1348 }
1349
AddStorageSpecifiers(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts,ResultBuilder & Results)1350 static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
1351 const LangOptions &LangOpts,
1352 ResultBuilder &Results) {
1353 typedef CodeCompletionResult Result;
1354 // Note: we don't suggest either "auto" or "register", because both
1355 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1356 // in C++0x as a type specifier.
1357 Results.AddResult(Result("extern"));
1358 Results.AddResult(Result("static"));
1359 }
1360
AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts,ResultBuilder & Results)1361 static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
1362 const LangOptions &LangOpts,
1363 ResultBuilder &Results) {
1364 typedef CodeCompletionResult Result;
1365 switch (CCC) {
1366 case Sema::PCC_Class:
1367 case Sema::PCC_MemberTemplate:
1368 if (LangOpts.CPlusPlus) {
1369 Results.AddResult(Result("explicit"));
1370 Results.AddResult(Result("friend"));
1371 Results.AddResult(Result("mutable"));
1372 Results.AddResult(Result("virtual"));
1373 }
1374 // Fall through
1375
1376 case Sema::PCC_ObjCInterface:
1377 case Sema::PCC_ObjCImplementation:
1378 case Sema::PCC_Namespace:
1379 case Sema::PCC_Template:
1380 if (LangOpts.CPlusPlus || LangOpts.C99)
1381 Results.AddResult(Result("inline"));
1382 break;
1383
1384 case Sema::PCC_ObjCInstanceVariableList:
1385 case Sema::PCC_Expression:
1386 case Sema::PCC_Statement:
1387 case Sema::PCC_ForInit:
1388 case Sema::PCC_Condition:
1389 case Sema::PCC_RecoveryInFunction:
1390 case Sema::PCC_Type:
1391 case Sema::PCC_ParenthesizedExpression:
1392 case Sema::PCC_LocalDeclarationSpecifiers:
1393 break;
1394 }
1395 }
1396
1397 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1398 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1399 static void AddObjCVisibilityResults(const LangOptions &LangOpts,
1400 ResultBuilder &Results,
1401 bool NeedAt);
1402 static void AddObjCImplementationResults(const LangOptions &LangOpts,
1403 ResultBuilder &Results,
1404 bool NeedAt);
1405 static void AddObjCInterfaceResults(const LangOptions &LangOpts,
1406 ResultBuilder &Results,
1407 bool NeedAt);
1408 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
1409
AddTypedefResult(ResultBuilder & Results)1410 static void AddTypedefResult(ResultBuilder &Results) {
1411 CodeCompletionBuilder Builder(Results.getAllocator(),
1412 Results.getCodeCompletionTUInfo());
1413 Builder.AddTypedTextChunk("typedef");
1414 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1415 Builder.AddPlaceholderChunk("type");
1416 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1417 Builder.AddPlaceholderChunk("name");
1418 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1419 }
1420
WantTypesInContext(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts)1421 static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
1422 const LangOptions &LangOpts) {
1423 switch (CCC) {
1424 case Sema::PCC_Namespace:
1425 case Sema::PCC_Class:
1426 case Sema::PCC_ObjCInstanceVariableList:
1427 case Sema::PCC_Template:
1428 case Sema::PCC_MemberTemplate:
1429 case Sema::PCC_Statement:
1430 case Sema::PCC_RecoveryInFunction:
1431 case Sema::PCC_Type:
1432 case Sema::PCC_ParenthesizedExpression:
1433 case Sema::PCC_LocalDeclarationSpecifiers:
1434 return true;
1435
1436 case Sema::PCC_Expression:
1437 case Sema::PCC_Condition:
1438 return LangOpts.CPlusPlus;
1439
1440 case Sema::PCC_ObjCInterface:
1441 case Sema::PCC_ObjCImplementation:
1442 return false;
1443
1444 case Sema::PCC_ForInit:
1445 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
1446 }
1447
1448 llvm_unreachable("Invalid ParserCompletionContext!");
1449 }
1450
getCompletionPrintingPolicy(const ASTContext & Context,const Preprocessor & PP)1451 static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
1452 const Preprocessor &PP) {
1453 PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP);
1454 Policy.AnonymousTagLocations = false;
1455 Policy.SuppressStrongLifetime = true;
1456 Policy.SuppressUnwrittenScope = true;
1457 return Policy;
1458 }
1459
1460 /// \brief Retrieve a printing policy suitable for code completion.
getCompletionPrintingPolicy(Sema & S)1461 static PrintingPolicy getCompletionPrintingPolicy(Sema &S) {
1462 return getCompletionPrintingPolicy(S.Context, S.PP);
1463 }
1464
1465 /// \brief Retrieve the string representation of the given type as a string
1466 /// that has the appropriate lifetime for code completion.
1467 ///
1468 /// This routine provides a fast path where we provide constant strings for
1469 /// common type names.
GetCompletionTypeString(QualType T,ASTContext & Context,const PrintingPolicy & Policy,CodeCompletionAllocator & Allocator)1470 static const char *GetCompletionTypeString(QualType T,
1471 ASTContext &Context,
1472 const PrintingPolicy &Policy,
1473 CodeCompletionAllocator &Allocator) {
1474 if (!T.getLocalQualifiers()) {
1475 // Built-in type names are constant strings.
1476 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T))
1477 return BT->getNameAsCString(Policy);
1478
1479 // Anonymous tag types are constant strings.
1480 if (const TagType *TagT = dyn_cast<TagType>(T))
1481 if (TagDecl *Tag = TagT->getDecl())
1482 if (!Tag->hasNameForLinkage()) {
1483 switch (Tag->getTagKind()) {
1484 case TTK_Struct: return "struct <anonymous>";
1485 case TTK_Interface: return "__interface <anonymous>";
1486 case TTK_Class: return "class <anonymous>";
1487 case TTK_Union: return "union <anonymous>";
1488 case TTK_Enum: return "enum <anonymous>";
1489 }
1490 }
1491 }
1492
1493 // Slow path: format the type as a string.
1494 std::string Result;
1495 T.getAsStringInternal(Result, Policy);
1496 return Allocator.CopyString(Result);
1497 }
1498
1499 /// \brief Add a completion for "this", if we're in a member function.
addThisCompletion(Sema & S,ResultBuilder & Results)1500 static void addThisCompletion(Sema &S, ResultBuilder &Results) {
1501 QualType ThisTy = S.getCurrentThisType();
1502 if (ThisTy.isNull())
1503 return;
1504
1505 CodeCompletionAllocator &Allocator = Results.getAllocator();
1506 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1507 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
1508 Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy,
1509 S.Context,
1510 Policy,
1511 Allocator));
1512 Builder.AddTypedTextChunk("this");
1513 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1514 }
1515
1516 /// \brief Add language constructs that show up for "ordinary" names.
AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,Scope * S,Sema & SemaRef,ResultBuilder & Results)1517 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
1518 Scope *S,
1519 Sema &SemaRef,
1520 ResultBuilder &Results) {
1521 CodeCompletionAllocator &Allocator = Results.getAllocator();
1522 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1523 PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);
1524
1525 typedef CodeCompletionResult Result;
1526 switch (CCC) {
1527 case Sema::PCC_Namespace:
1528 if (SemaRef.getLangOpts().CPlusPlus) {
1529 if (Results.includeCodePatterns()) {
1530 // namespace <identifier> { declarations }
1531 Builder.AddTypedTextChunk("namespace");
1532 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1533 Builder.AddPlaceholderChunk("identifier");
1534 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1535 Builder.AddPlaceholderChunk("declarations");
1536 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1537 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1538 Results.AddResult(Result(Builder.TakeString()));
1539 }
1540
1541 // namespace identifier = identifier ;
1542 Builder.AddTypedTextChunk("namespace");
1543 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1544 Builder.AddPlaceholderChunk("name");
1545 Builder.AddChunk(CodeCompletionString::CK_Equal);
1546 Builder.AddPlaceholderChunk("namespace");
1547 Results.AddResult(Result(Builder.TakeString()));
1548
1549 // Using directives
1550 Builder.AddTypedTextChunk("using");
1551 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1552 Builder.AddTextChunk("namespace");
1553 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1554 Builder.AddPlaceholderChunk("identifier");
1555 Results.AddResult(Result(Builder.TakeString()));
1556
1557 // asm(string-literal)
1558 Builder.AddTypedTextChunk("asm");
1559 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1560 Builder.AddPlaceholderChunk("string-literal");
1561 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1562 Results.AddResult(Result(Builder.TakeString()));
1563
1564 if (Results.includeCodePatterns()) {
1565 // Explicit template instantiation
1566 Builder.AddTypedTextChunk("template");
1567 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1568 Builder.AddPlaceholderChunk("declaration");
1569 Results.AddResult(Result(Builder.TakeString()));
1570 }
1571 }
1572
1573 if (SemaRef.getLangOpts().ObjC1)
1574 AddObjCTopLevelResults(Results, true);
1575
1576 AddTypedefResult(Results);
1577 // Fall through
1578
1579 case Sema::PCC_Class:
1580 if (SemaRef.getLangOpts().CPlusPlus) {
1581 // Using declaration
1582 Builder.AddTypedTextChunk("using");
1583 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1584 Builder.AddPlaceholderChunk("qualifier");
1585 Builder.AddTextChunk("::");
1586 Builder.AddPlaceholderChunk("name");
1587 Results.AddResult(Result(Builder.TakeString()));
1588
1589 // using typename qualifier::name (only in a dependent context)
1590 if (SemaRef.CurContext->isDependentContext()) {
1591 Builder.AddTypedTextChunk("using");
1592 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1593 Builder.AddTextChunk("typename");
1594 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1595 Builder.AddPlaceholderChunk("qualifier");
1596 Builder.AddTextChunk("::");
1597 Builder.AddPlaceholderChunk("name");
1598 Results.AddResult(Result(Builder.TakeString()));
1599 }
1600
1601 if (CCC == Sema::PCC_Class) {
1602 AddTypedefResult(Results);
1603
1604 // public:
1605 Builder.AddTypedTextChunk("public");
1606 if (Results.includeCodePatterns())
1607 Builder.AddChunk(CodeCompletionString::CK_Colon);
1608 Results.AddResult(Result(Builder.TakeString()));
1609
1610 // protected:
1611 Builder.AddTypedTextChunk("protected");
1612 if (Results.includeCodePatterns())
1613 Builder.AddChunk(CodeCompletionString::CK_Colon);
1614 Results.AddResult(Result(Builder.TakeString()));
1615
1616 // private:
1617 Builder.AddTypedTextChunk("private");
1618 if (Results.includeCodePatterns())
1619 Builder.AddChunk(CodeCompletionString::CK_Colon);
1620 Results.AddResult(Result(Builder.TakeString()));
1621 }
1622 }
1623 // Fall through
1624
1625 case Sema::PCC_Template:
1626 case Sema::PCC_MemberTemplate:
1627 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
1628 // template < parameters >
1629 Builder.AddTypedTextChunk("template");
1630 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1631 Builder.AddPlaceholderChunk("parameters");
1632 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1633 Results.AddResult(Result(Builder.TakeString()));
1634 }
1635
1636 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1637 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1638 break;
1639
1640 case Sema::PCC_ObjCInterface:
1641 AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true);
1642 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1643 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1644 break;
1645
1646 case Sema::PCC_ObjCImplementation:
1647 AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true);
1648 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1649 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1650 break;
1651
1652 case Sema::PCC_ObjCInstanceVariableList:
1653 AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true);
1654 break;
1655
1656 case Sema::PCC_RecoveryInFunction:
1657 case Sema::PCC_Statement: {
1658 AddTypedefResult(Results);
1659
1660 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() &&
1661 SemaRef.getLangOpts().CXXExceptions) {
1662 Builder.AddTypedTextChunk("try");
1663 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1664 Builder.AddPlaceholderChunk("statements");
1665 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1666 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1667 Builder.AddTextChunk("catch");
1668 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1669 Builder.AddPlaceholderChunk("declaration");
1670 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1671 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1672 Builder.AddPlaceholderChunk("statements");
1673 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1674 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1675 Results.AddResult(Result(Builder.TakeString()));
1676 }
1677 if (SemaRef.getLangOpts().ObjC1)
1678 AddObjCStatementResults(Results, true);
1679
1680 if (Results.includeCodePatterns()) {
1681 // if (condition) { statements }
1682 Builder.AddTypedTextChunk("if");
1683 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1684 if (SemaRef.getLangOpts().CPlusPlus)
1685 Builder.AddPlaceholderChunk("condition");
1686 else
1687 Builder.AddPlaceholderChunk("expression");
1688 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1689 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1690 Builder.AddPlaceholderChunk("statements");
1691 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1692 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1693 Results.AddResult(Result(Builder.TakeString()));
1694
1695 // switch (condition) { }
1696 Builder.AddTypedTextChunk("switch");
1697 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1698 if (SemaRef.getLangOpts().CPlusPlus)
1699 Builder.AddPlaceholderChunk("condition");
1700 else
1701 Builder.AddPlaceholderChunk("expression");
1702 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1703 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1704 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1705 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1706 Results.AddResult(Result(Builder.TakeString()));
1707 }
1708
1709 // Switch-specific statements.
1710 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
1711 // case expression:
1712 Builder.AddTypedTextChunk("case");
1713 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1714 Builder.AddPlaceholderChunk("expression");
1715 Builder.AddChunk(CodeCompletionString::CK_Colon);
1716 Results.AddResult(Result(Builder.TakeString()));
1717
1718 // default:
1719 Builder.AddTypedTextChunk("default");
1720 Builder.AddChunk(CodeCompletionString::CK_Colon);
1721 Results.AddResult(Result(Builder.TakeString()));
1722 }
1723
1724 if (Results.includeCodePatterns()) {
1725 /// while (condition) { statements }
1726 Builder.AddTypedTextChunk("while");
1727 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1728 if (SemaRef.getLangOpts().CPlusPlus)
1729 Builder.AddPlaceholderChunk("condition");
1730 else
1731 Builder.AddPlaceholderChunk("expression");
1732 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1733 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1734 Builder.AddPlaceholderChunk("statements");
1735 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1736 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1737 Results.AddResult(Result(Builder.TakeString()));
1738
1739 // do { statements } while ( expression );
1740 Builder.AddTypedTextChunk("do");
1741 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1742 Builder.AddPlaceholderChunk("statements");
1743 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1744 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1745 Builder.AddTextChunk("while");
1746 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1747 Builder.AddPlaceholderChunk("expression");
1748 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1749 Results.AddResult(Result(Builder.TakeString()));
1750
1751 // for ( for-init-statement ; condition ; expression ) { statements }
1752 Builder.AddTypedTextChunk("for");
1753 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1754 if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99)
1755 Builder.AddPlaceholderChunk("init-statement");
1756 else
1757 Builder.AddPlaceholderChunk("init-expression");
1758 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1759 Builder.AddPlaceholderChunk("condition");
1760 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1761 Builder.AddPlaceholderChunk("inc-expression");
1762 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1763 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1764 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1765 Builder.AddPlaceholderChunk("statements");
1766 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1767 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1768 Results.AddResult(Result(Builder.TakeString()));
1769 }
1770
1771 if (S->getContinueParent()) {
1772 // continue ;
1773 Builder.AddTypedTextChunk("continue");
1774 Results.AddResult(Result(Builder.TakeString()));
1775 }
1776
1777 if (S->getBreakParent()) {
1778 // break ;
1779 Builder.AddTypedTextChunk("break");
1780 Results.AddResult(Result(Builder.TakeString()));
1781 }
1782
1783 // "return expression ;" or "return ;", depending on whether we
1784 // know the function is void or not.
1785 bool isVoid = false;
1786 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1787 isVoid = Function->getResultType()->isVoidType();
1788 else if (ObjCMethodDecl *Method
1789 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1790 isVoid = Method->getResultType()->isVoidType();
1791 else if (SemaRef.getCurBlock() &&
1792 !SemaRef.getCurBlock()->ReturnType.isNull())
1793 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
1794 Builder.AddTypedTextChunk("return");
1795 if (!isVoid) {
1796 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1797 Builder.AddPlaceholderChunk("expression");
1798 }
1799 Results.AddResult(Result(Builder.TakeString()));
1800
1801 // goto identifier ;
1802 Builder.AddTypedTextChunk("goto");
1803 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1804 Builder.AddPlaceholderChunk("label");
1805 Results.AddResult(Result(Builder.TakeString()));
1806
1807 // Using directives
1808 Builder.AddTypedTextChunk("using");
1809 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1810 Builder.AddTextChunk("namespace");
1811 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1812 Builder.AddPlaceholderChunk("identifier");
1813 Results.AddResult(Result(Builder.TakeString()));
1814 }
1815
1816 // Fall through (for statement expressions).
1817 case Sema::PCC_ForInit:
1818 case Sema::PCC_Condition:
1819 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1820 // Fall through: conditions and statements can have expressions.
1821
1822 case Sema::PCC_ParenthesizedExpression:
1823 if (SemaRef.getLangOpts().ObjCAutoRefCount &&
1824 CCC == Sema::PCC_ParenthesizedExpression) {
1825 // (__bridge <type>)<expression>
1826 Builder.AddTypedTextChunk("__bridge");
1827 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1828 Builder.AddPlaceholderChunk("type");
1829 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1830 Builder.AddPlaceholderChunk("expression");
1831 Results.AddResult(Result(Builder.TakeString()));
1832
1833 // (__bridge_transfer <Objective-C type>)<expression>
1834 Builder.AddTypedTextChunk("__bridge_transfer");
1835 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1836 Builder.AddPlaceholderChunk("Objective-C type");
1837 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1838 Builder.AddPlaceholderChunk("expression");
1839 Results.AddResult(Result(Builder.TakeString()));
1840
1841 // (__bridge_retained <CF type>)<expression>
1842 Builder.AddTypedTextChunk("__bridge_retained");
1843 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1844 Builder.AddPlaceholderChunk("CF type");
1845 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1846 Builder.AddPlaceholderChunk("expression");
1847 Results.AddResult(Result(Builder.TakeString()));
1848 }
1849 // Fall through
1850
1851 case Sema::PCC_Expression: {
1852 if (SemaRef.getLangOpts().CPlusPlus) {
1853 // 'this', if we're in a non-static member function.
1854 addThisCompletion(SemaRef, Results);
1855
1856 // true
1857 Builder.AddResultTypeChunk("bool");
1858 Builder.AddTypedTextChunk("true");
1859 Results.AddResult(Result(Builder.TakeString()));
1860
1861 // false
1862 Builder.AddResultTypeChunk("bool");
1863 Builder.AddTypedTextChunk("false");
1864 Results.AddResult(Result(Builder.TakeString()));
1865
1866 if (SemaRef.getLangOpts().RTTI) {
1867 // dynamic_cast < type-id > ( expression )
1868 Builder.AddTypedTextChunk("dynamic_cast");
1869 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1870 Builder.AddPlaceholderChunk("type");
1871 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1872 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1873 Builder.AddPlaceholderChunk("expression");
1874 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1875 Results.AddResult(Result(Builder.TakeString()));
1876 }
1877
1878 // static_cast < type-id > ( expression )
1879 Builder.AddTypedTextChunk("static_cast");
1880 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1881 Builder.AddPlaceholderChunk("type");
1882 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1883 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1884 Builder.AddPlaceholderChunk("expression");
1885 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1886 Results.AddResult(Result(Builder.TakeString()));
1887
1888 // reinterpret_cast < type-id > ( expression )
1889 Builder.AddTypedTextChunk("reinterpret_cast");
1890 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1891 Builder.AddPlaceholderChunk("type");
1892 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1893 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1894 Builder.AddPlaceholderChunk("expression");
1895 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1896 Results.AddResult(Result(Builder.TakeString()));
1897
1898 // const_cast < type-id > ( expression )
1899 Builder.AddTypedTextChunk("const_cast");
1900 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1901 Builder.AddPlaceholderChunk("type");
1902 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1903 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1904 Builder.AddPlaceholderChunk("expression");
1905 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1906 Results.AddResult(Result(Builder.TakeString()));
1907
1908 if (SemaRef.getLangOpts().RTTI) {
1909 // typeid ( expression-or-type )
1910 Builder.AddResultTypeChunk("std::type_info");
1911 Builder.AddTypedTextChunk("typeid");
1912 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1913 Builder.AddPlaceholderChunk("expression-or-type");
1914 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1915 Results.AddResult(Result(Builder.TakeString()));
1916 }
1917
1918 // new T ( ... )
1919 Builder.AddTypedTextChunk("new");
1920 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1921 Builder.AddPlaceholderChunk("type");
1922 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1923 Builder.AddPlaceholderChunk("expressions");
1924 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1925 Results.AddResult(Result(Builder.TakeString()));
1926
1927 // new T [ ] ( ... )
1928 Builder.AddTypedTextChunk("new");
1929 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1930 Builder.AddPlaceholderChunk("type");
1931 Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
1932 Builder.AddPlaceholderChunk("size");
1933 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
1934 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1935 Builder.AddPlaceholderChunk("expressions");
1936 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1937 Results.AddResult(Result(Builder.TakeString()));
1938
1939 // delete expression
1940 Builder.AddResultTypeChunk("void");
1941 Builder.AddTypedTextChunk("delete");
1942 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1943 Builder.AddPlaceholderChunk("expression");
1944 Results.AddResult(Result(Builder.TakeString()));
1945
1946 // delete [] expression
1947 Builder.AddResultTypeChunk("void");
1948 Builder.AddTypedTextChunk("delete");
1949 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1950 Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
1951 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
1952 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1953 Builder.AddPlaceholderChunk("expression");
1954 Results.AddResult(Result(Builder.TakeString()));
1955
1956 if (SemaRef.getLangOpts().CXXExceptions) {
1957 // throw expression
1958 Builder.AddResultTypeChunk("void");
1959 Builder.AddTypedTextChunk("throw");
1960 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1961 Builder.AddPlaceholderChunk("expression");
1962 Results.AddResult(Result(Builder.TakeString()));
1963 }
1964
1965 // FIXME: Rethrow?
1966
1967 if (SemaRef.getLangOpts().CPlusPlus11) {
1968 // nullptr
1969 Builder.AddResultTypeChunk("std::nullptr_t");
1970 Builder.AddTypedTextChunk("nullptr");
1971 Results.AddResult(Result(Builder.TakeString()));
1972
1973 // alignof
1974 Builder.AddResultTypeChunk("size_t");
1975 Builder.AddTypedTextChunk("alignof");
1976 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1977 Builder.AddPlaceholderChunk("type");
1978 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1979 Results.AddResult(Result(Builder.TakeString()));
1980
1981 // noexcept
1982 Builder.AddResultTypeChunk("bool");
1983 Builder.AddTypedTextChunk("noexcept");
1984 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1985 Builder.AddPlaceholderChunk("expression");
1986 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1987 Results.AddResult(Result(Builder.TakeString()));
1988
1989 // sizeof... expression
1990 Builder.AddResultTypeChunk("size_t");
1991 Builder.AddTypedTextChunk("sizeof...");
1992 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1993 Builder.AddPlaceholderChunk("parameter-pack");
1994 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1995 Results.AddResult(Result(Builder.TakeString()));
1996 }
1997 }
1998
1999 if (SemaRef.getLangOpts().ObjC1) {
2000 // Add "super", if we're in an Objective-C class with a superclass.
2001 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
2002 // The interface can be NULL.
2003 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
2004 if (ID->getSuperClass()) {
2005 std::string SuperType;
2006 SuperType = ID->getSuperClass()->getNameAsString();
2007 if (Method->isInstanceMethod())
2008 SuperType += " *";
2009
2010 Builder.AddResultTypeChunk(Allocator.CopyString(SuperType));
2011 Builder.AddTypedTextChunk("super");
2012 Results.AddResult(Result(Builder.TakeString()));
2013 }
2014 }
2015
2016 AddObjCExpressionResults(Results, true);
2017 }
2018
2019 if (SemaRef.getLangOpts().C11) {
2020 // _Alignof
2021 Builder.AddResultTypeChunk("size_t");
2022 if (SemaRef.getASTContext().Idents.get("alignof").hasMacroDefinition())
2023 Builder.AddTypedTextChunk("alignof");
2024 else
2025 Builder.AddTypedTextChunk("_Alignof");
2026 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2027 Builder.AddPlaceholderChunk("type");
2028 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2029 Results.AddResult(Result(Builder.TakeString()));
2030 }
2031
2032 // sizeof expression
2033 Builder.AddResultTypeChunk("size_t");
2034 Builder.AddTypedTextChunk("sizeof");
2035 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2036 Builder.AddPlaceholderChunk("expression-or-type");
2037 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2038 Results.AddResult(Result(Builder.TakeString()));
2039 break;
2040 }
2041
2042 case Sema::PCC_Type:
2043 case Sema::PCC_LocalDeclarationSpecifiers:
2044 break;
2045 }
2046
2047 if (WantTypesInContext(CCC, SemaRef.getLangOpts()))
2048 AddTypeSpecifierResults(SemaRef.getLangOpts(), Results);
2049
2050 if (SemaRef.getLangOpts().CPlusPlus && CCC != Sema::PCC_Type)
2051 Results.AddResult(Result("operator"));
2052 }
2053
2054 /// \brief If the given declaration has an associated type, add it as a result
2055 /// type chunk.
AddResultTypeChunk(ASTContext & Context,const PrintingPolicy & Policy,const NamedDecl * ND,CodeCompletionBuilder & Result)2056 static void AddResultTypeChunk(ASTContext &Context,
2057 const PrintingPolicy &Policy,
2058 const NamedDecl *ND,
2059 CodeCompletionBuilder &Result) {
2060 if (!ND)
2061 return;
2062
2063 // Skip constructors and conversion functions, which have their return types
2064 // built into their names.
2065 if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND))
2066 return;
2067
2068 // Determine the type of the declaration (if it has a type).
2069 QualType T;
2070 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
2071 T = Function->getResultType();
2072 else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
2073 T = Method->getResultType();
2074 else if (const FunctionTemplateDecl *FunTmpl =
2075 dyn_cast<FunctionTemplateDecl>(ND))
2076 T = FunTmpl->getTemplatedDecl()->getResultType();
2077 else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
2078 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
2079 else if (isa<UnresolvedUsingValueDecl>(ND)) {
2080 /* Do nothing: ignore unresolved using declarations*/
2081 } else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) {
2082 T = Value->getType();
2083 } else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
2084 T = Property->getType();
2085
2086 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
2087 return;
2088
2089 Result.AddResultTypeChunk(GetCompletionTypeString(T, Context, Policy,
2090 Result.getAllocator()));
2091 }
2092
MaybeAddSentinel(ASTContext & Context,const NamedDecl * FunctionOrMethod,CodeCompletionBuilder & Result)2093 static void MaybeAddSentinel(ASTContext &Context,
2094 const NamedDecl *FunctionOrMethod,
2095 CodeCompletionBuilder &Result) {
2096 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
2097 if (Sentinel->getSentinel() == 0) {
2098 if (Context.getLangOpts().ObjC1 &&
2099 Context.Idents.get("nil").hasMacroDefinition())
2100 Result.AddTextChunk(", nil");
2101 else if (Context.Idents.get("NULL").hasMacroDefinition())
2102 Result.AddTextChunk(", NULL");
2103 else
2104 Result.AddTextChunk(", (void*)0");
2105 }
2106 }
2107
formatObjCParamQualifiers(unsigned ObjCQuals)2108 static std::string formatObjCParamQualifiers(unsigned ObjCQuals) {
2109 std::string Result;
2110 if (ObjCQuals & Decl::OBJC_TQ_In)
2111 Result += "in ";
2112 else if (ObjCQuals & Decl::OBJC_TQ_Inout)
2113 Result += "inout ";
2114 else if (ObjCQuals & Decl::OBJC_TQ_Out)
2115 Result += "out ";
2116 if (ObjCQuals & Decl::OBJC_TQ_Bycopy)
2117 Result += "bycopy ";
2118 else if (ObjCQuals & Decl::OBJC_TQ_Byref)
2119 Result += "byref ";
2120 if (ObjCQuals & Decl::OBJC_TQ_Oneway)
2121 Result += "oneway ";
2122 return Result;
2123 }
2124
FormatFunctionParameter(ASTContext & Context,const PrintingPolicy & Policy,const ParmVarDecl * Param,bool SuppressName=false,bool SuppressBlock=false)2125 static std::string FormatFunctionParameter(ASTContext &Context,
2126 const PrintingPolicy &Policy,
2127 const ParmVarDecl *Param,
2128 bool SuppressName = false,
2129 bool SuppressBlock = false) {
2130 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
2131 if (Param->getType()->isDependentType() ||
2132 !Param->getType()->isBlockPointerType()) {
2133 // The argument for a dependent or non-block parameter is a placeholder
2134 // containing that parameter's type.
2135 std::string Result;
2136
2137 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
2138 Result = Param->getIdentifier()->getName();
2139
2140 Param->getType().getAsStringInternal(Result, Policy);
2141
2142 if (ObjCMethodParam) {
2143 Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier())
2144 + Result + ")";
2145 if (Param->getIdentifier() && !SuppressName)
2146 Result += Param->getIdentifier()->getName();
2147 }
2148 return Result;
2149 }
2150
2151 // The argument for a block pointer parameter is a block literal with
2152 // the appropriate type.
2153 FunctionTypeLoc Block;
2154 FunctionProtoTypeLoc BlockProto;
2155 TypeLoc TL;
2156 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
2157 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
2158 while (true) {
2159 // Look through typedefs.
2160 if (!SuppressBlock) {
2161 if (TypedefTypeLoc TypedefTL = TL.getAs<TypedefTypeLoc>()) {
2162 if (TypeSourceInfo *InnerTSInfo =
2163 TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) {
2164 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
2165 continue;
2166 }
2167 }
2168
2169 // Look through qualified types
2170 if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) {
2171 TL = QualifiedTL.getUnqualifiedLoc();
2172 continue;
2173 }
2174 }
2175
2176 // Try to get the function prototype behind the block pointer type,
2177 // then we're done.
2178 if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) {
2179 TL = BlockPtr.getPointeeLoc().IgnoreParens();
2180 Block = TL.getAs<FunctionTypeLoc>();
2181 BlockProto = TL.getAs<FunctionProtoTypeLoc>();
2182 }
2183 break;
2184 }
2185 }
2186
2187 if (!Block) {
2188 // We were unable to find a FunctionProtoTypeLoc with parameter names
2189 // for the block; just use the parameter type as a placeholder.
2190 std::string Result;
2191 if (!ObjCMethodParam && Param->getIdentifier())
2192 Result = Param->getIdentifier()->getName();
2193
2194 Param->getType().getUnqualifiedType().getAsStringInternal(Result, Policy);
2195
2196 if (ObjCMethodParam) {
2197 Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier())
2198 + Result + ")";
2199 if (Param->getIdentifier())
2200 Result += Param->getIdentifier()->getName();
2201 }
2202
2203 return Result;
2204 }
2205
2206 // We have the function prototype behind the block pointer type, as it was
2207 // written in the source.
2208 std::string Result;
2209 QualType ResultType = Block.getTypePtr()->getResultType();
2210 if (!ResultType->isVoidType() || SuppressBlock)
2211 ResultType.getAsStringInternal(Result, Policy);
2212
2213 // Format the parameter list.
2214 std::string Params;
2215 if (!BlockProto || Block.getNumArgs() == 0) {
2216 if (BlockProto && BlockProto.getTypePtr()->isVariadic())
2217 Params = "(...)";
2218 else
2219 Params = "(void)";
2220 } else {
2221 Params += "(";
2222 for (unsigned I = 0, N = Block.getNumArgs(); I != N; ++I) {
2223 if (I)
2224 Params += ", ";
2225 Params += FormatFunctionParameter(Context, Policy, Block.getArg(I),
2226 /*SuppressName=*/false,
2227 /*SuppressBlock=*/true);
2228
2229 if (I == N - 1 && BlockProto.getTypePtr()->isVariadic())
2230 Params += ", ...";
2231 }
2232 Params += ")";
2233 }
2234
2235 if (SuppressBlock) {
2236 // Format as a parameter.
2237 Result = Result + " (^";
2238 if (Param->getIdentifier())
2239 Result += Param->getIdentifier()->getName();
2240 Result += ")";
2241 Result += Params;
2242 } else {
2243 // Format as a block literal argument.
2244 Result = '^' + Result;
2245 Result += Params;
2246
2247 if (Param->getIdentifier())
2248 Result += Param->getIdentifier()->getName();
2249 }
2250
2251 return Result;
2252 }
2253
2254 /// \brief Add function parameter chunks to the given code completion string.
AddFunctionParameterChunks(ASTContext & Context,const PrintingPolicy & Policy,const FunctionDecl * Function,CodeCompletionBuilder & Result,unsigned Start=0,bool InOptional=false)2255 static void AddFunctionParameterChunks(ASTContext &Context,
2256 const PrintingPolicy &Policy,
2257 const FunctionDecl *Function,
2258 CodeCompletionBuilder &Result,
2259 unsigned Start = 0,
2260 bool InOptional = false) {
2261 bool FirstParameter = true;
2262
2263 for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) {
2264 const ParmVarDecl *Param = Function->getParamDecl(P);
2265
2266 if (Param->hasDefaultArg() && !InOptional) {
2267 // When we see an optional default argument, put that argument and
2268 // the remaining default arguments into a new, optional string.
2269 CodeCompletionBuilder Opt(Result.getAllocator(),
2270 Result.getCodeCompletionTUInfo());
2271 if (!FirstParameter)
2272 Opt.AddChunk(CodeCompletionString::CK_Comma);
2273 AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true);
2274 Result.AddOptionalChunk(Opt.TakeString());
2275 break;
2276 }
2277
2278 if (FirstParameter)
2279 FirstParameter = false;
2280 else
2281 Result.AddChunk(CodeCompletionString::CK_Comma);
2282
2283 InOptional = false;
2284
2285 // Format the placeholder string.
2286 std::string PlaceholderStr = FormatFunctionParameter(Context, Policy,
2287 Param);
2288
2289 if (Function->isVariadic() && P == N - 1)
2290 PlaceholderStr += ", ...";
2291
2292 // Add the placeholder string.
2293 Result.AddPlaceholderChunk(
2294 Result.getAllocator().CopyString(PlaceholderStr));
2295 }
2296
2297 if (const FunctionProtoType *Proto
2298 = Function->getType()->getAs<FunctionProtoType>())
2299 if (Proto->isVariadic()) {
2300 if (Proto->getNumArgs() == 0)
2301 Result.AddPlaceholderChunk("...");
2302
2303 MaybeAddSentinel(Context, Function, Result);
2304 }
2305 }
2306
2307 /// \brief Add template parameter chunks to the given code completion string.
AddTemplateParameterChunks(ASTContext & Context,const PrintingPolicy & Policy,const TemplateDecl * Template,CodeCompletionBuilder & Result,unsigned MaxParameters=0,unsigned Start=0,bool InDefaultArg=false)2308 static void AddTemplateParameterChunks(ASTContext &Context,
2309 const PrintingPolicy &Policy,
2310 const TemplateDecl *Template,
2311 CodeCompletionBuilder &Result,
2312 unsigned MaxParameters = 0,
2313 unsigned Start = 0,
2314 bool InDefaultArg = false) {
2315 bool FirstParameter = true;
2316
2317 TemplateParameterList *Params = Template->getTemplateParameters();
2318 TemplateParameterList::iterator PEnd = Params->end();
2319 if (MaxParameters)
2320 PEnd = Params->begin() + MaxParameters;
2321 for (TemplateParameterList::iterator P = Params->begin() + Start;
2322 P != PEnd; ++P) {
2323 bool HasDefaultArg = false;
2324 std::string PlaceholderStr;
2325 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
2326 if (TTP->wasDeclaredWithTypename())
2327 PlaceholderStr = "typename";
2328 else
2329 PlaceholderStr = "class";
2330
2331 if (TTP->getIdentifier()) {
2332 PlaceholderStr += ' ';
2333 PlaceholderStr += TTP->getIdentifier()->getName();
2334 }
2335
2336 HasDefaultArg = TTP->hasDefaultArgument();
2337 } else if (NonTypeTemplateParmDecl *NTTP
2338 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
2339 if (NTTP->getIdentifier())
2340 PlaceholderStr = NTTP->getIdentifier()->getName();
2341 NTTP->getType().getAsStringInternal(PlaceholderStr, Policy);
2342 HasDefaultArg = NTTP->hasDefaultArgument();
2343 } else {
2344 assert(isa<TemplateTemplateParmDecl>(*P));
2345 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
2346
2347 // Since putting the template argument list into the placeholder would
2348 // be very, very long, we just use an abbreviation.
2349 PlaceholderStr = "template<...> class";
2350 if (TTP->getIdentifier()) {
2351 PlaceholderStr += ' ';
2352 PlaceholderStr += TTP->getIdentifier()->getName();
2353 }
2354
2355 HasDefaultArg = TTP->hasDefaultArgument();
2356 }
2357
2358 if (HasDefaultArg && !InDefaultArg) {
2359 // When we see an optional default argument, put that argument and
2360 // the remaining default arguments into a new, optional string.
2361 CodeCompletionBuilder Opt(Result.getAllocator(),
2362 Result.getCodeCompletionTUInfo());
2363 if (!FirstParameter)
2364 Opt.AddChunk(CodeCompletionString::CK_Comma);
2365 AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
2366 P - Params->begin(), true);
2367 Result.AddOptionalChunk(Opt.TakeString());
2368 break;
2369 }
2370
2371 InDefaultArg = false;
2372
2373 if (FirstParameter)
2374 FirstParameter = false;
2375 else
2376 Result.AddChunk(CodeCompletionString::CK_Comma);
2377
2378 // Add the placeholder string.
2379 Result.AddPlaceholderChunk(
2380 Result.getAllocator().CopyString(PlaceholderStr));
2381 }
2382 }
2383
2384 /// \brief Add a qualifier to the given code-completion string, if the
2385 /// provided nested-name-specifier is non-NULL.
2386 static void
AddQualifierToCompletionString(CodeCompletionBuilder & Result,NestedNameSpecifier * Qualifier,bool QualifierIsInformative,ASTContext & Context,const PrintingPolicy & Policy)2387 AddQualifierToCompletionString(CodeCompletionBuilder &Result,
2388 NestedNameSpecifier *Qualifier,
2389 bool QualifierIsInformative,
2390 ASTContext &Context,
2391 const PrintingPolicy &Policy) {
2392 if (!Qualifier)
2393 return;
2394
2395 std::string PrintedNNS;
2396 {
2397 llvm::raw_string_ostream OS(PrintedNNS);
2398 Qualifier->print(OS, Policy);
2399 }
2400 if (QualifierIsInformative)
2401 Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS));
2402 else
2403 Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS));
2404 }
2405
2406 static void
AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder & Result,const FunctionDecl * Function)2407 AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
2408 const FunctionDecl *Function) {
2409 const FunctionProtoType *Proto
2410 = Function->getType()->getAs<FunctionProtoType>();
2411 if (!Proto || !Proto->getTypeQuals())
2412 return;
2413
2414 // FIXME: Add ref-qualifier!
2415
2416 // Handle single qualifiers without copying
2417 if (Proto->getTypeQuals() == Qualifiers::Const) {
2418 Result.AddInformativeChunk(" const");
2419 return;
2420 }
2421
2422 if (Proto->getTypeQuals() == Qualifiers::Volatile) {
2423 Result.AddInformativeChunk(" volatile");
2424 return;
2425 }
2426
2427 if (Proto->getTypeQuals() == Qualifiers::Restrict) {
2428 Result.AddInformativeChunk(" restrict");
2429 return;
2430 }
2431
2432 // Handle multiple qualifiers.
2433 std::string QualsStr;
2434 if (Proto->isConst())
2435 QualsStr += " const";
2436 if (Proto->isVolatile())
2437 QualsStr += " volatile";
2438 if (Proto->isRestrict())
2439 QualsStr += " restrict";
2440 Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
2441 }
2442
2443 /// \brief Add the name of the given declaration
AddTypedNameChunk(ASTContext & Context,const PrintingPolicy & Policy,const NamedDecl * ND,CodeCompletionBuilder & Result)2444 static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
2445 const NamedDecl *ND,
2446 CodeCompletionBuilder &Result) {
2447 DeclarationName Name = ND->getDeclName();
2448 if (!Name)
2449 return;
2450
2451 switch (Name.getNameKind()) {
2452 case DeclarationName::CXXOperatorName: {
2453 const char *OperatorName = 0;
2454 switch (Name.getCXXOverloadedOperator()) {
2455 case OO_None:
2456 case OO_Conditional:
2457 case NUM_OVERLOADED_OPERATORS:
2458 OperatorName = "operator";
2459 break;
2460
2461 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2462 case OO_##Name: OperatorName = "operator" Spelling; break;
2463 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
2464 #include "clang/Basic/OperatorKinds.def"
2465
2466 case OO_New: OperatorName = "operator new"; break;
2467 case OO_Delete: OperatorName = "operator delete"; break;
2468 case OO_Array_New: OperatorName = "operator new[]"; break;
2469 case OO_Array_Delete: OperatorName = "operator delete[]"; break;
2470 case OO_Call: OperatorName = "operator()"; break;
2471 case OO_Subscript: OperatorName = "operator[]"; break;
2472 }
2473 Result.AddTypedTextChunk(OperatorName);
2474 break;
2475 }
2476
2477 case DeclarationName::Identifier:
2478 case DeclarationName::CXXConversionFunctionName:
2479 case DeclarationName::CXXDestructorName:
2480 case DeclarationName::CXXLiteralOperatorName:
2481 Result.AddTypedTextChunk(
2482 Result.getAllocator().CopyString(ND->getNameAsString()));
2483 break;
2484
2485 case DeclarationName::CXXUsingDirective:
2486 case DeclarationName::ObjCZeroArgSelector:
2487 case DeclarationName::ObjCOneArgSelector:
2488 case DeclarationName::ObjCMultiArgSelector:
2489 break;
2490
2491 case DeclarationName::CXXConstructorName: {
2492 CXXRecordDecl *Record = 0;
2493 QualType Ty = Name.getCXXNameType();
2494 if (const RecordType *RecordTy = Ty->getAs<RecordType>())
2495 Record = cast<CXXRecordDecl>(RecordTy->getDecl());
2496 else if (const InjectedClassNameType *InjectedTy
2497 = Ty->getAs<InjectedClassNameType>())
2498 Record = InjectedTy->getDecl();
2499 else {
2500 Result.AddTypedTextChunk(
2501 Result.getAllocator().CopyString(ND->getNameAsString()));
2502 break;
2503 }
2504
2505 Result.AddTypedTextChunk(
2506 Result.getAllocator().CopyString(Record->getNameAsString()));
2507 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
2508 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2509 AddTemplateParameterChunks(Context, Policy, Template, Result);
2510 Result.AddChunk(CodeCompletionString::CK_RightAngle);
2511 }
2512 break;
2513 }
2514 }
2515 }
2516
CreateCodeCompletionString(Sema & S,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,bool IncludeBriefComments)2517 CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
2518 CodeCompletionAllocator &Allocator,
2519 CodeCompletionTUInfo &CCTUInfo,
2520 bool IncludeBriefComments) {
2521 return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo,
2522 IncludeBriefComments);
2523 }
2524
2525 /// \brief If possible, create a new code completion string for the given
2526 /// result.
2527 ///
2528 /// \returns Either a new, heap-allocated code completion string describing
2529 /// how to use this result, or NULL to indicate that the string or name of the
2530 /// result is all that is needed.
2531 CodeCompletionString *
CreateCodeCompletionString(ASTContext & Ctx,Preprocessor & PP,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,bool IncludeBriefComments)2532 CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
2533 Preprocessor &PP,
2534 CodeCompletionAllocator &Allocator,
2535 CodeCompletionTUInfo &CCTUInfo,
2536 bool IncludeBriefComments) {
2537 CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
2538
2539 PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
2540 if (Kind == RK_Pattern) {
2541 Pattern->Priority = Priority;
2542 Pattern->Availability = Availability;
2543
2544 if (Declaration) {
2545 Result.addParentContext(Declaration->getDeclContext());
2546 Pattern->ParentName = Result.getParentName();
2547 // Provide code completion comment for self.GetterName where
2548 // GetterName is the getter method for a property with name
2549 // different from the property name (declared via a property
2550 // getter attribute.
2551 const NamedDecl *ND = Declaration;
2552 if (const ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(ND))
2553 if (M->isPropertyAccessor())
2554 if (const ObjCPropertyDecl *PDecl = M->findPropertyDecl())
2555 if (PDecl->getGetterName() == M->getSelector() &&
2556 PDecl->getIdentifier() != M->getIdentifier()) {
2557 if (const RawComment *RC =
2558 Ctx.getRawCommentForAnyRedecl(M)) {
2559 Result.addBriefComment(RC->getBriefText(Ctx));
2560 Pattern->BriefComment = Result.getBriefComment();
2561 }
2562 else if (const RawComment *RC =
2563 Ctx.getRawCommentForAnyRedecl(PDecl)) {
2564 Result.addBriefComment(RC->getBriefText(Ctx));
2565 Pattern->BriefComment = Result.getBriefComment();
2566 }
2567 }
2568 }
2569
2570 return Pattern;
2571 }
2572
2573 if (Kind == RK_Keyword) {
2574 Result.AddTypedTextChunk(Keyword);
2575 return Result.TakeString();
2576 }
2577
2578 if (Kind == RK_Macro) {
2579 const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro);
2580 assert(MD && "Not a macro?");
2581 const MacroInfo *MI = MD->getMacroInfo();
2582
2583 Result.AddTypedTextChunk(
2584 Result.getAllocator().CopyString(Macro->getName()));
2585
2586 if (!MI->isFunctionLike())
2587 return Result.TakeString();
2588
2589 // Format a function-like macro with placeholders for the arguments.
2590 Result.AddChunk(CodeCompletionString::CK_LeftParen);
2591 MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2592
2593 // C99 variadic macros add __VA_ARGS__ at the end. Skip it.
2594 if (MI->isC99Varargs()) {
2595 --AEnd;
2596
2597 if (A == AEnd) {
2598 Result.AddPlaceholderChunk("...");
2599 }
2600 }
2601
2602 for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) {
2603 if (A != MI->arg_begin())
2604 Result.AddChunk(CodeCompletionString::CK_Comma);
2605
2606 if (MI->isVariadic() && (A+1) == AEnd) {
2607 SmallString<32> Arg = (*A)->getName();
2608 if (MI->isC99Varargs())
2609 Arg += ", ...";
2610 else
2611 Arg += "...";
2612 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
2613 break;
2614 }
2615
2616 // Non-variadic macros are simple.
2617 Result.AddPlaceholderChunk(
2618 Result.getAllocator().CopyString((*A)->getName()));
2619 }
2620 Result.AddChunk(CodeCompletionString::CK_RightParen);
2621 return Result.TakeString();
2622 }
2623
2624 assert(Kind == RK_Declaration && "Missed a result kind?");
2625 const NamedDecl *ND = Declaration;
2626 Result.addParentContext(ND->getDeclContext());
2627
2628 if (IncludeBriefComments) {
2629 // Add documentation comment, if it exists.
2630 if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(ND)) {
2631 Result.addBriefComment(RC->getBriefText(Ctx));
2632 }
2633 else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
2634 if (OMD->isPropertyAccessor())
2635 if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl())
2636 if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(PDecl))
2637 Result.addBriefComment(RC->getBriefText(Ctx));
2638 }
2639
2640 if (StartsNestedNameSpecifier) {
2641 Result.AddTypedTextChunk(
2642 Result.getAllocator().CopyString(ND->getNameAsString()));
2643 Result.AddTextChunk("::");
2644 return Result.TakeString();
2645 }
2646
2647 for (Decl::attr_iterator i = ND->attr_begin(); i != ND->attr_end(); ++i) {
2648 if (AnnotateAttr *Attr = dyn_cast_or_null<AnnotateAttr>(*i)) {
2649 Result.AddAnnotation(Result.getAllocator().CopyString(Attr->getAnnotation()));
2650 }
2651 }
2652
2653 AddResultTypeChunk(Ctx, Policy, ND, Result);
2654
2655 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
2656 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2657 Ctx, Policy);
2658 AddTypedNameChunk(Ctx, Policy, ND, Result);
2659 Result.AddChunk(CodeCompletionString::CK_LeftParen);
2660 AddFunctionParameterChunks(Ctx, Policy, Function, Result);
2661 Result.AddChunk(CodeCompletionString::CK_RightParen);
2662 AddFunctionTypeQualsToCompletionString(Result, Function);
2663 return Result.TakeString();
2664 }
2665
2666 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
2667 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2668 Ctx, Policy);
2669 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
2670 AddTypedNameChunk(Ctx, Policy, Function, Result);
2671
2672 // Figure out which template parameters are deduced (or have default
2673 // arguments).
2674 llvm::SmallBitVector Deduced;
2675 Sema::MarkDeducedTemplateParameters(Ctx, FunTmpl, Deduced);
2676 unsigned LastDeducibleArgument;
2677 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2678 --LastDeducibleArgument) {
2679 if (!Deduced[LastDeducibleArgument - 1]) {
2680 // C++0x: Figure out if the template argument has a default. If so,
2681 // the user doesn't need to type this argument.
2682 // FIXME: We need to abstract template parameters better!
2683 bool HasDefaultArg = false;
2684 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2685 LastDeducibleArgument - 1);
2686 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2687 HasDefaultArg = TTP->hasDefaultArgument();
2688 else if (NonTypeTemplateParmDecl *NTTP
2689 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2690 HasDefaultArg = NTTP->hasDefaultArgument();
2691 else {
2692 assert(isa<TemplateTemplateParmDecl>(Param));
2693 HasDefaultArg
2694 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
2695 }
2696
2697 if (!HasDefaultArg)
2698 break;
2699 }
2700 }
2701
2702 if (LastDeducibleArgument) {
2703 // Some of the function template arguments cannot be deduced from a
2704 // function call, so we introduce an explicit template argument list
2705 // containing all of the arguments up to the first deducible argument.
2706 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2707 AddTemplateParameterChunks(Ctx, Policy, FunTmpl, Result,
2708 LastDeducibleArgument);
2709 Result.AddChunk(CodeCompletionString::CK_RightAngle);
2710 }
2711
2712 // Add the function parameters
2713 Result.AddChunk(CodeCompletionString::CK_LeftParen);
2714 AddFunctionParameterChunks(Ctx, Policy, Function, Result);
2715 Result.AddChunk(CodeCompletionString::CK_RightParen);
2716 AddFunctionTypeQualsToCompletionString(Result, Function);
2717 return Result.TakeString();
2718 }
2719
2720 if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
2721 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2722 Ctx, Policy);
2723 Result.AddTypedTextChunk(
2724 Result.getAllocator().CopyString(Template->getNameAsString()));
2725 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2726 AddTemplateParameterChunks(Ctx, Policy, Template, Result);
2727 Result.AddChunk(CodeCompletionString::CK_RightAngle);
2728 return Result.TakeString();
2729 }
2730
2731 if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
2732 Selector Sel = Method->getSelector();
2733 if (Sel.isUnarySelector()) {
2734 Result.AddTypedTextChunk(Result.getAllocator().CopyString(
2735 Sel.getNameForSlot(0)));
2736 return Result.TakeString();
2737 }
2738
2739 std::string SelName = Sel.getNameForSlot(0).str();
2740 SelName += ':';
2741 if (StartParameter == 0)
2742 Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName));
2743 else {
2744 Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName));
2745
2746 // If there is only one parameter, and we're past it, add an empty
2747 // typed-text chunk since there is nothing to type.
2748 if (Method->param_size() == 1)
2749 Result.AddTypedTextChunk("");
2750 }
2751 unsigned Idx = 0;
2752 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
2753 PEnd = Method->param_end();
2754 P != PEnd; (void)++P, ++Idx) {
2755 if (Idx > 0) {
2756 std::string Keyword;
2757 if (Idx > StartParameter)
2758 Result.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2759 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2760 Keyword += II->getName();
2761 Keyword += ":";
2762 if (Idx < StartParameter || AllParametersAreInformative)
2763 Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword));
2764 else
2765 Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword));
2766 }
2767
2768 // If we're before the starting parameter, skip the placeholder.
2769 if (Idx < StartParameter)
2770 continue;
2771
2772 std::string Arg;
2773
2774 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
2775 Arg = FormatFunctionParameter(Ctx, Policy, *P, true);
2776 else {
2777 (*P)->getType().getAsStringInternal(Arg, Policy);
2778 Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier())
2779 + Arg + ")";
2780 if (IdentifierInfo *II = (*P)->getIdentifier())
2781 if (DeclaringEntity || AllParametersAreInformative)
2782 Arg += II->getName();
2783 }
2784
2785 if (Method->isVariadic() && (P + 1) == PEnd)
2786 Arg += ", ...";
2787
2788 if (DeclaringEntity)
2789 Result.AddTextChunk(Result.getAllocator().CopyString(Arg));
2790 else if (AllParametersAreInformative)
2791 Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg));
2792 else
2793 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
2794 }
2795
2796 if (Method->isVariadic()) {
2797 if (Method->param_size() == 0) {
2798 if (DeclaringEntity)
2799 Result.AddTextChunk(", ...");
2800 else if (AllParametersAreInformative)
2801 Result.AddInformativeChunk(", ...");
2802 else
2803 Result.AddPlaceholderChunk(", ...");
2804 }
2805
2806 MaybeAddSentinel(Ctx, Method, Result);
2807 }
2808
2809 return Result.TakeString();
2810 }
2811
2812 if (Qualifier)
2813 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2814 Ctx, Policy);
2815
2816 Result.AddTypedTextChunk(
2817 Result.getAllocator().CopyString(ND->getNameAsString()));
2818 return Result.TakeString();
2819 }
2820
2821 CodeCompletionString *
CreateSignatureString(unsigned CurrentArg,Sema & S,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo) const2822 CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2823 unsigned CurrentArg,
2824 Sema &S,
2825 CodeCompletionAllocator &Allocator,
2826 CodeCompletionTUInfo &CCTUInfo) const {
2827 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
2828
2829 // FIXME: Set priority, availability appropriately.
2830 CodeCompletionBuilder Result(Allocator,CCTUInfo, 1, CXAvailability_Available);
2831 FunctionDecl *FDecl = getFunction();
2832 AddResultTypeChunk(S.Context, Policy, FDecl, Result);
2833 const FunctionProtoType *Proto
2834 = dyn_cast<FunctionProtoType>(getFunctionType());
2835 if (!FDecl && !Proto) {
2836 // Function without a prototype. Just give the return type and a
2837 // highlighted ellipsis.
2838 const FunctionType *FT = getFunctionType();
2839 Result.AddTextChunk(GetCompletionTypeString(FT->getResultType(),
2840 S.Context, Policy,
2841 Result.getAllocator()));
2842 Result.AddChunk(CodeCompletionString::CK_LeftParen);
2843 Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
2844 Result.AddChunk(CodeCompletionString::CK_RightParen);
2845 return Result.TakeString();
2846 }
2847
2848 if (FDecl)
2849 Result.AddTextChunk(
2850 Result.getAllocator().CopyString(FDecl->getNameAsString()));
2851 else
2852 Result.AddTextChunk(
2853 Result.getAllocator().CopyString(
2854 Proto->getResultType().getAsString(Policy)));
2855
2856 Result.AddChunk(CodeCompletionString::CK_LeftParen);
2857 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2858 for (unsigned I = 0; I != NumParams; ++I) {
2859 if (I)
2860 Result.AddChunk(CodeCompletionString::CK_Comma);
2861
2862 std::string ArgString;
2863 QualType ArgType;
2864
2865 if (FDecl) {
2866 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2867 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2868 } else {
2869 ArgType = Proto->getArgType(I);
2870 }
2871
2872 ArgType.getAsStringInternal(ArgString, Policy);
2873
2874 if (I == CurrentArg)
2875 Result.AddChunk(CodeCompletionString::CK_CurrentParameter,
2876 Result.getAllocator().CopyString(ArgString));
2877 else
2878 Result.AddTextChunk(Result.getAllocator().CopyString(ArgString));
2879 }
2880
2881 if (Proto && Proto->isVariadic()) {
2882 Result.AddChunk(CodeCompletionString::CK_Comma);
2883 if (CurrentArg < NumParams)
2884 Result.AddTextChunk("...");
2885 else
2886 Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
2887 }
2888 Result.AddChunk(CodeCompletionString::CK_RightParen);
2889
2890 return Result.TakeString();
2891 }
2892
getMacroUsagePriority(StringRef MacroName,const LangOptions & LangOpts,bool PreferredTypeIsPointer)2893 unsigned clang::getMacroUsagePriority(StringRef MacroName,
2894 const LangOptions &LangOpts,
2895 bool PreferredTypeIsPointer) {
2896 unsigned Priority = CCP_Macro;
2897
2898 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2899 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2900 MacroName.equals("Nil")) {
2901 Priority = CCP_Constant;
2902 if (PreferredTypeIsPointer)
2903 Priority = Priority / CCF_SimilarTypeMatch;
2904 }
2905 // Treat "YES", "NO", "true", and "false" as constants.
2906 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2907 MacroName.equals("true") || MacroName.equals("false"))
2908 Priority = CCP_Constant;
2909 // Treat "bool" as a type.
2910 else if (MacroName.equals("bool"))
2911 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2912
2913
2914 return Priority;
2915 }
2916
getCursorKindForDecl(const Decl * D)2917 CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
2918 if (!D)
2919 return CXCursor_UnexposedDecl;
2920
2921 switch (D->getKind()) {
2922 case Decl::Enum: return CXCursor_EnumDecl;
2923 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2924 case Decl::Field: return CXCursor_FieldDecl;
2925 case Decl::Function:
2926 return CXCursor_FunctionDecl;
2927 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2928 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
2929 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2930
2931 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
2932 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2933 case Decl::ObjCMethod:
2934 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2935 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2936 case Decl::CXXMethod: return CXCursor_CXXMethod;
2937 case Decl::CXXConstructor: return CXCursor_Constructor;
2938 case Decl::CXXDestructor: return CXCursor_Destructor;
2939 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2940 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
2941 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
2942 case Decl::ParmVar: return CXCursor_ParmDecl;
2943 case Decl::Typedef: return CXCursor_TypedefDecl;
2944 case Decl::TypeAlias: return CXCursor_TypeAliasDecl;
2945 case Decl::Var: return CXCursor_VarDecl;
2946 case Decl::Namespace: return CXCursor_Namespace;
2947 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2948 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2949 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2950 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2951 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2952 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
2953 case Decl::AccessSpec: return CXCursor_CXXAccessSpecifier;
2954 case Decl::ClassTemplatePartialSpecialization:
2955 return CXCursor_ClassTemplatePartialSpecialization;
2956 case Decl::UsingDirective: return CXCursor_UsingDirective;
2957 case Decl::TranslationUnit: return CXCursor_TranslationUnit;
2958
2959 case Decl::Using:
2960 case Decl::UnresolvedUsingValue:
2961 case Decl::UnresolvedUsingTypename:
2962 return CXCursor_UsingDeclaration;
2963
2964 case Decl::ObjCPropertyImpl:
2965 switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) {
2966 case ObjCPropertyImplDecl::Dynamic:
2967 return CXCursor_ObjCDynamicDecl;
2968
2969 case ObjCPropertyImplDecl::Synthesize:
2970 return CXCursor_ObjCSynthesizeDecl;
2971 }
2972
2973 case Decl::Import:
2974 return CXCursor_ModuleImportDecl;
2975
2976 default:
2977 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
2978 switch (TD->getTagKind()) {
2979 case TTK_Interface: // fall through
2980 case TTK_Struct: return CXCursor_StructDecl;
2981 case TTK_Class: return CXCursor_ClassDecl;
2982 case TTK_Union: return CXCursor_UnionDecl;
2983 case TTK_Enum: return CXCursor_EnumDecl;
2984 }
2985 }
2986 }
2987
2988 return CXCursor_UnexposedDecl;
2989 }
2990
AddMacroResults(Preprocessor & PP,ResultBuilder & Results,bool IncludeUndefined,bool TargetTypeIsPointer=false)2991 static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2992 bool IncludeUndefined,
2993 bool TargetTypeIsPointer = false) {
2994 typedef CodeCompletionResult Result;
2995
2996 Results.EnterNewScope();
2997
2998 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2999 MEnd = PP.macro_end();
3000 M != MEnd; ++M) {
3001 if (IncludeUndefined || M->first->hasMacroDefinition())
3002 Results.AddResult(Result(M->first,
3003 getMacroUsagePriority(M->first->getName(),
3004 PP.getLangOpts(),
3005 TargetTypeIsPointer)));
3006 }
3007
3008 Results.ExitScope();
3009
3010 }
3011
AddPrettyFunctionResults(const LangOptions & LangOpts,ResultBuilder & Results)3012 static void AddPrettyFunctionResults(const LangOptions &LangOpts,
3013 ResultBuilder &Results) {
3014 typedef CodeCompletionResult Result;
3015
3016 Results.EnterNewScope();
3017
3018 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
3019 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
3020 if (LangOpts.C99 || LangOpts.CPlusPlus11)
3021 Results.AddResult(Result("__func__", CCP_Constant));
3022 Results.ExitScope();
3023 }
3024
HandleCodeCompleteResults(Sema * S,CodeCompleteConsumer * CodeCompleter,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)3025 static void HandleCodeCompleteResults(Sema *S,
3026 CodeCompleteConsumer *CodeCompleter,
3027 CodeCompletionContext Context,
3028 CodeCompletionResult *Results,
3029 unsigned NumResults) {
3030 if (CodeCompleter)
3031 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
3032 }
3033
mapCodeCompletionContext(Sema & S,Sema::ParserCompletionContext PCC)3034 static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
3035 Sema::ParserCompletionContext PCC) {
3036 switch (PCC) {
3037 case Sema::PCC_Namespace:
3038 return CodeCompletionContext::CCC_TopLevel;
3039
3040 case Sema::PCC_Class:
3041 return CodeCompletionContext::CCC_ClassStructUnion;
3042
3043 case Sema::PCC_ObjCInterface:
3044 return CodeCompletionContext::CCC_ObjCInterface;
3045
3046 case Sema::PCC_ObjCImplementation:
3047 return CodeCompletionContext::CCC_ObjCImplementation;
3048
3049 case Sema::PCC_ObjCInstanceVariableList:
3050 return CodeCompletionContext::CCC_ObjCIvarList;
3051
3052 case Sema::PCC_Template:
3053 case Sema::PCC_MemberTemplate:
3054 if (S.CurContext->isFileContext())
3055 return CodeCompletionContext::CCC_TopLevel;
3056 if (S.CurContext->isRecord())
3057 return CodeCompletionContext::CCC_ClassStructUnion;
3058 return CodeCompletionContext::CCC_Other;
3059
3060 case Sema::PCC_RecoveryInFunction:
3061 return CodeCompletionContext::CCC_Recovery;
3062
3063 case Sema::PCC_ForInit:
3064 if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 ||
3065 S.getLangOpts().ObjC1)
3066 return CodeCompletionContext::CCC_ParenthesizedExpression;
3067 else
3068 return CodeCompletionContext::CCC_Expression;
3069
3070 case Sema::PCC_Expression:
3071 case Sema::PCC_Condition:
3072 return CodeCompletionContext::CCC_Expression;
3073
3074 case Sema::PCC_Statement:
3075 return CodeCompletionContext::CCC_Statement;
3076
3077 case Sema::PCC_Type:
3078 return CodeCompletionContext::CCC_Type;
3079
3080 case Sema::PCC_ParenthesizedExpression:
3081 return CodeCompletionContext::CCC_ParenthesizedExpression;
3082
3083 case Sema::PCC_LocalDeclarationSpecifiers:
3084 return CodeCompletionContext::CCC_Type;
3085 }
3086
3087 llvm_unreachable("Invalid ParserCompletionContext!");
3088 }
3089
3090 /// \brief If we're in a C++ virtual member function, add completion results
3091 /// that invoke the functions we override, since it's common to invoke the
3092 /// overridden function as well as adding new functionality.
3093 ///
3094 /// \param S The semantic analysis object for which we are generating results.
3095 ///
3096 /// \param InContext This context in which the nested-name-specifier preceding
3097 /// the code-completion point
MaybeAddOverrideCalls(Sema & S,DeclContext * InContext,ResultBuilder & Results)3098 static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
3099 ResultBuilder &Results) {
3100 // Look through blocks.
3101 DeclContext *CurContext = S.CurContext;
3102 while (isa<BlockDecl>(CurContext))
3103 CurContext = CurContext->getParent();
3104
3105
3106 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
3107 if (!Method || !Method->isVirtual())
3108 return;
3109
3110 // We need to have names for all of the parameters, if we're going to
3111 // generate a forwarding call.
3112 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
3113 PEnd = Method->param_end();
3114 P != PEnd;
3115 ++P) {
3116 if (!(*P)->getDeclName())
3117 return;
3118 }
3119
3120 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
3121 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
3122 MEnd = Method->end_overridden_methods();
3123 M != MEnd; ++M) {
3124 CodeCompletionBuilder Builder(Results.getAllocator(),
3125 Results.getCodeCompletionTUInfo());
3126 const CXXMethodDecl *Overridden = *M;
3127 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
3128 continue;
3129
3130 // If we need a nested-name-specifier, add one now.
3131 if (!InContext) {
3132 NestedNameSpecifier *NNS
3133 = getRequiredQualification(S.Context, CurContext,
3134 Overridden->getDeclContext());
3135 if (NNS) {
3136 std::string Str;
3137 llvm::raw_string_ostream OS(Str);
3138 NNS->print(OS, Policy);
3139 Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str()));
3140 }
3141 } else if (!InContext->Equals(Overridden->getDeclContext()))
3142 continue;
3143
3144 Builder.AddTypedTextChunk(Results.getAllocator().CopyString(
3145 Overridden->getNameAsString()));
3146 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
3147 bool FirstParam = true;
3148 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
3149 PEnd = Method->param_end();
3150 P != PEnd; ++P) {
3151 if (FirstParam)
3152 FirstParam = false;
3153 else
3154 Builder.AddChunk(CodeCompletionString::CK_Comma);
3155
3156 Builder.AddPlaceholderChunk(Results.getAllocator().CopyString(
3157 (*P)->getIdentifier()->getName()));
3158 }
3159 Builder.AddChunk(CodeCompletionString::CK_RightParen);
3160 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
3161 CCP_SuperCompletion,
3162 CXCursor_CXXMethod,
3163 CXAvailability_Available,
3164 Overridden));
3165 Results.Ignore(Overridden);
3166 }
3167 }
3168
CodeCompleteModuleImport(SourceLocation ImportLoc,ModuleIdPath Path)3169 void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc,
3170 ModuleIdPath Path) {
3171 typedef CodeCompletionResult Result;
3172 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3173 CodeCompleter->getCodeCompletionTUInfo(),
3174 CodeCompletionContext::CCC_Other);
3175 Results.EnterNewScope();
3176
3177 CodeCompletionAllocator &Allocator = Results.getAllocator();
3178 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
3179 typedef CodeCompletionResult Result;
3180 if (Path.empty()) {
3181 // Enumerate all top-level modules.
3182 SmallVector<Module *, 8> Modules;
3183 PP.getHeaderSearchInfo().collectAllModules(Modules);
3184 for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
3185 Builder.AddTypedTextChunk(
3186 Builder.getAllocator().CopyString(Modules[I]->Name));
3187 Results.AddResult(Result(Builder.TakeString(),
3188 CCP_Declaration,
3189 CXCursor_ModuleImportDecl,
3190 Modules[I]->isAvailable()
3191 ? CXAvailability_Available
3192 : CXAvailability_NotAvailable));
3193 }
3194 } else if (getLangOpts().Modules) {
3195 // Load the named module.
3196 Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path,
3197 Module::AllVisible,
3198 /*IsInclusionDirective=*/false);
3199 // Enumerate submodules.
3200 if (Mod) {
3201 for (Module::submodule_iterator Sub = Mod->submodule_begin(),
3202 SubEnd = Mod->submodule_end();
3203 Sub != SubEnd; ++Sub) {
3204
3205 Builder.AddTypedTextChunk(
3206 Builder.getAllocator().CopyString((*Sub)->Name));
3207 Results.AddResult(Result(Builder.TakeString(),
3208 CCP_Declaration,
3209 CXCursor_ModuleImportDecl,
3210 (*Sub)->isAvailable()
3211 ? CXAvailability_Available
3212 : CXAvailability_NotAvailable));
3213 }
3214 }
3215 }
3216 Results.ExitScope();
3217 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3218 Results.data(),Results.size());
3219 }
3220
CodeCompleteOrdinaryName(Scope * S,ParserCompletionContext CompletionContext)3221 void Sema::CodeCompleteOrdinaryName(Scope *S,
3222 ParserCompletionContext CompletionContext) {
3223 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3224 CodeCompleter->getCodeCompletionTUInfo(),
3225 mapCodeCompletionContext(*this, CompletionContext));
3226 Results.EnterNewScope();
3227
3228 // Determine how to filter results, e.g., so that the names of
3229 // values (functions, enumerators, function templates, etc.) are
3230 // only allowed where we can have an expression.
3231 switch (CompletionContext) {
3232 case PCC_Namespace:
3233 case PCC_Class:
3234 case PCC_ObjCInterface:
3235 case PCC_ObjCImplementation:
3236 case PCC_ObjCInstanceVariableList:
3237 case PCC_Template:
3238 case PCC_MemberTemplate:
3239 case PCC_Type:
3240 case PCC_LocalDeclarationSpecifiers:
3241 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3242 break;
3243
3244 case PCC_Statement:
3245 case PCC_ParenthesizedExpression:
3246 case PCC_Expression:
3247 case PCC_ForInit:
3248 case PCC_Condition:
3249 if (WantTypesInContext(CompletionContext, getLangOpts()))
3250 Results.setFilter(&ResultBuilder::IsOrdinaryName);
3251 else
3252 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
3253
3254 if (getLangOpts().CPlusPlus)
3255 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
3256 break;
3257
3258 case PCC_RecoveryInFunction:
3259 // Unfiltered
3260 break;
3261 }
3262
3263 // If we are in a C++ non-static member function, check the qualifiers on
3264 // the member function to filter/prioritize the results list.
3265 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
3266 if (CurMethod->isInstance())
3267 Results.setObjectTypeQualifiers(
3268 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
3269
3270 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3271 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3272 CodeCompleter->includeGlobals());
3273
3274 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
3275 Results.ExitScope();
3276
3277 switch (CompletionContext) {
3278 case PCC_ParenthesizedExpression:
3279 case PCC_Expression:
3280 case PCC_Statement:
3281 case PCC_RecoveryInFunction:
3282 if (S->getFnParent())
3283 AddPrettyFunctionResults(PP.getLangOpts(), Results);
3284 break;
3285
3286 case PCC_Namespace:
3287 case PCC_Class:
3288 case PCC_ObjCInterface:
3289 case PCC_ObjCImplementation:
3290 case PCC_ObjCInstanceVariableList:
3291 case PCC_Template:
3292 case PCC_MemberTemplate:
3293 case PCC_ForInit:
3294 case PCC_Condition:
3295 case PCC_Type:
3296 case PCC_LocalDeclarationSpecifiers:
3297 break;
3298 }
3299
3300 if (CodeCompleter->includeMacros())
3301 AddMacroResults(PP, Results, false);
3302
3303 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3304 Results.data(),Results.size());
3305 }
3306
3307 static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
3308 ParsedType Receiver,
3309 ArrayRef<IdentifierInfo *> SelIdents,
3310 bool AtArgumentExpression,
3311 bool IsSuper,
3312 ResultBuilder &Results);
3313
CodeCompleteDeclSpec(Scope * S,DeclSpec & DS,bool AllowNonIdentifiers,bool AllowNestedNameSpecifiers)3314 void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
3315 bool AllowNonIdentifiers,
3316 bool AllowNestedNameSpecifiers) {
3317 typedef CodeCompletionResult Result;
3318 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3319 CodeCompleter->getCodeCompletionTUInfo(),
3320 AllowNestedNameSpecifiers
3321 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
3322 : CodeCompletionContext::CCC_Name);
3323 Results.EnterNewScope();
3324
3325 // Type qualifiers can come after names.
3326 Results.AddResult(Result("const"));
3327 Results.AddResult(Result("volatile"));
3328 if (getLangOpts().C99)
3329 Results.AddResult(Result("restrict"));
3330
3331 if (getLangOpts().CPlusPlus) {
3332 if (AllowNonIdentifiers) {
3333 Results.AddResult(Result("operator"));
3334 }
3335
3336 // Add nested-name-specifiers.
3337 if (AllowNestedNameSpecifiers) {
3338 Results.allowNestedNameSpecifiers();
3339 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
3340 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3341 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
3342 CodeCompleter->includeGlobals());
3343 Results.setFilter(0);
3344 }
3345 }
3346 Results.ExitScope();
3347
3348 // If we're in a context where we might have an expression (rather than a
3349 // declaration), and what we've seen so far is an Objective-C type that could
3350 // be a receiver of a class message, this may be a class message send with
3351 // the initial opening bracket '[' missing. Add appropriate completions.
3352 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
3353 DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier &&
3354 DS.getTypeSpecType() == DeclSpec::TST_typename &&
3355 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
3356 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
3357 !DS.isTypeAltiVecVector() &&
3358 S &&
3359 (S->getFlags() & Scope::DeclScope) != 0 &&
3360 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
3361 Scope::FunctionPrototypeScope |
3362 Scope::AtCatchScope)) == 0) {
3363 ParsedType T = DS.getRepAsType();
3364 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
3365 AddClassMessageCompletions(*this, S, T, None, false, false, Results);
3366 }
3367
3368 // Note that we intentionally suppress macro results here, since we do not
3369 // encourage using macros to produce the names of entities.
3370
3371 HandleCodeCompleteResults(this, CodeCompleter,
3372 Results.getCompletionContext(),
3373 Results.data(), Results.size());
3374 }
3375
3376 struct Sema::CodeCompleteExpressionData {
CodeCompleteExpressionDataSema::CodeCompleteExpressionData3377 CodeCompleteExpressionData(QualType PreferredType = QualType())
3378 : PreferredType(PreferredType), IntegralConstantExpression(false),
3379 ObjCCollection(false) { }
3380
3381 QualType PreferredType;
3382 bool IntegralConstantExpression;
3383 bool ObjCCollection;
3384 SmallVector<Decl *, 4> IgnoreDecls;
3385 };
3386
3387 /// \brief Perform code-completion in an expression context when we know what
3388 /// type we're looking for.
CodeCompleteExpression(Scope * S,const CodeCompleteExpressionData & Data)3389 void Sema::CodeCompleteExpression(Scope *S,
3390 const CodeCompleteExpressionData &Data) {
3391 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3392 CodeCompleter->getCodeCompletionTUInfo(),
3393 CodeCompletionContext::CCC_Expression);
3394 if (Data.ObjCCollection)
3395 Results.setFilter(&ResultBuilder::IsObjCCollection);
3396 else if (Data.IntegralConstantExpression)
3397 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
3398 else if (WantTypesInContext(PCC_Expression, getLangOpts()))
3399 Results.setFilter(&ResultBuilder::IsOrdinaryName);
3400 else
3401 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
3402
3403 if (!Data.PreferredType.isNull())
3404 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
3405
3406 // Ignore any declarations that we were told that we don't care about.
3407 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
3408 Results.Ignore(Data.IgnoreDecls[I]);
3409
3410 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3411 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3412 CodeCompleter->includeGlobals());
3413
3414 Results.EnterNewScope();
3415 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
3416 Results.ExitScope();
3417
3418 bool PreferredTypeIsPointer = false;
3419 if (!Data.PreferredType.isNull())
3420 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
3421 || Data.PreferredType->isMemberPointerType()
3422 || Data.PreferredType->isBlockPointerType();
3423
3424 if (S->getFnParent() &&
3425 !Data.ObjCCollection &&
3426 !Data.IntegralConstantExpression)
3427 AddPrettyFunctionResults(PP.getLangOpts(), Results);
3428
3429 if (CodeCompleter->includeMacros())
3430 AddMacroResults(PP, Results, false, PreferredTypeIsPointer);
3431 HandleCodeCompleteResults(this, CodeCompleter,
3432 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
3433 Data.PreferredType),
3434 Results.data(),Results.size());
3435 }
3436
CodeCompletePostfixExpression(Scope * S,ExprResult E)3437 void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
3438 if (E.isInvalid())
3439 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
3440 else if (getLangOpts().ObjC1)
3441 CodeCompleteObjCInstanceMessage(S, E.take(), None, false);
3442 }
3443
3444 /// \brief The set of properties that have already been added, referenced by
3445 /// property name.
3446 typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
3447
3448 /// \brief Retrieve the container definition, if any?
getContainerDef(ObjCContainerDecl * Container)3449 static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {
3450 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
3451 if (Interface->hasDefinition())
3452 return Interface->getDefinition();
3453
3454 return Interface;
3455 }
3456
3457 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3458 if (Protocol->hasDefinition())
3459 return Protocol->getDefinition();
3460
3461 return Protocol;
3462 }
3463 return Container;
3464 }
3465
AddObjCProperties(ObjCContainerDecl * Container,bool AllowCategories,bool AllowNullaryMethods,DeclContext * CurContext,AddedPropertiesSet & AddedProperties,ResultBuilder & Results)3466 static void AddObjCProperties(ObjCContainerDecl *Container,
3467 bool AllowCategories,
3468 bool AllowNullaryMethods,
3469 DeclContext *CurContext,
3470 AddedPropertiesSet &AddedProperties,
3471 ResultBuilder &Results) {
3472 typedef CodeCompletionResult Result;
3473
3474 // Retrieve the definition.
3475 Container = getContainerDef(Container);
3476
3477 // Add properties in this container.
3478 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
3479 PEnd = Container->prop_end();
3480 P != PEnd;
3481 ++P) {
3482 if (AddedProperties.insert(P->getIdentifier()))
3483 Results.MaybeAddResult(Result(*P, Results.getBasePriority(*P), 0),
3484 CurContext);
3485 }
3486
3487 // Add nullary methods
3488 if (AllowNullaryMethods) {
3489 ASTContext &Context = Container->getASTContext();
3490 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
3491 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3492 MEnd = Container->meth_end();
3493 M != MEnd; ++M) {
3494 if (M->getSelector().isUnarySelector())
3495 if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
3496 if (AddedProperties.insert(Name)) {
3497 CodeCompletionBuilder Builder(Results.getAllocator(),
3498 Results.getCodeCompletionTUInfo());
3499 AddResultTypeChunk(Context, Policy, *M, Builder);
3500 Builder.AddTypedTextChunk(
3501 Results.getAllocator().CopyString(Name->getName()));
3502
3503 Results.MaybeAddResult(Result(Builder.TakeString(), *M,
3504 CCP_MemberDeclaration + CCD_MethodAsProperty),
3505 CurContext);
3506 }
3507 }
3508 }
3509
3510
3511 // Add properties in referenced protocols.
3512 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3513 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
3514 PEnd = Protocol->protocol_end();
3515 P != PEnd; ++P)
3516 AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
3517 AddedProperties, Results);
3518 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
3519 if (AllowCategories) {
3520 // Look through categories.
3521 for (ObjCInterfaceDecl::known_categories_iterator
3522 Cat = IFace->known_categories_begin(),
3523 CatEnd = IFace->known_categories_end();
3524 Cat != CatEnd; ++Cat)
3525 AddObjCProperties(*Cat, AllowCategories, AllowNullaryMethods,
3526 CurContext, AddedProperties, Results);
3527 }
3528
3529 // Look through protocols.
3530 for (ObjCInterfaceDecl::all_protocol_iterator
3531 I = IFace->all_referenced_protocol_begin(),
3532 E = IFace->all_referenced_protocol_end(); I != E; ++I)
3533 AddObjCProperties(*I, AllowCategories, AllowNullaryMethods, CurContext,
3534 AddedProperties, Results);
3535
3536 // Look in the superclass.
3537 if (IFace->getSuperClass())
3538 AddObjCProperties(IFace->getSuperClass(), AllowCategories,
3539 AllowNullaryMethods, CurContext,
3540 AddedProperties, Results);
3541 } else if (const ObjCCategoryDecl *Category
3542 = dyn_cast<ObjCCategoryDecl>(Container)) {
3543 // Look through protocols.
3544 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
3545 PEnd = Category->protocol_end();
3546 P != PEnd; ++P)
3547 AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
3548 AddedProperties, Results);
3549 }
3550 }
3551
CodeCompleteMemberReferenceExpr(Scope * S,Expr * Base,SourceLocation OpLoc,bool IsArrow)3552 void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
3553 SourceLocation OpLoc,
3554 bool IsArrow) {
3555 if (!Base || !CodeCompleter)
3556 return;
3557
3558 ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
3559 if (ConvertedBase.isInvalid())
3560 return;
3561 Base = ConvertedBase.get();
3562
3563 typedef CodeCompletionResult Result;
3564
3565 QualType BaseType = Base->getType();
3566
3567 if (IsArrow) {
3568 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
3569 BaseType = Ptr->getPointeeType();
3570 else if (BaseType->isObjCObjectPointerType())
3571 /*Do nothing*/ ;
3572 else
3573 return;
3574 }
3575
3576 enum CodeCompletionContext::Kind contextKind;
3577
3578 if (IsArrow) {
3579 contextKind = CodeCompletionContext::CCC_ArrowMemberAccess;
3580 }
3581 else {
3582 if (BaseType->isObjCObjectPointerType() ||
3583 BaseType->isObjCObjectOrInterfaceType()) {
3584 contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess;
3585 }
3586 else {
3587 contextKind = CodeCompletionContext::CCC_DotMemberAccess;
3588 }
3589 }
3590
3591 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3592 CodeCompleter->getCodeCompletionTUInfo(),
3593 CodeCompletionContext(contextKind,
3594 BaseType),
3595 &ResultBuilder::IsMember);
3596 Results.EnterNewScope();
3597 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
3598 // Indicate that we are performing a member access, and the cv-qualifiers
3599 // for the base object type.
3600 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
3601
3602 // Access to a C/C++ class, struct, or union.
3603 Results.allowNestedNameSpecifiers();
3604 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3605 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
3606 CodeCompleter->includeGlobals());
3607
3608 if (getLangOpts().CPlusPlus) {
3609 if (!Results.empty()) {
3610 // The "template" keyword can follow "->" or "." in the grammar.
3611 // However, we only want to suggest the template keyword if something
3612 // is dependent.
3613 bool IsDependent = BaseType->isDependentType();
3614 if (!IsDependent) {
3615 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
3616 if (DeclContext *Ctx = DepScope->getEntity()) {
3617 IsDependent = Ctx->isDependentContext();
3618 break;
3619 }
3620 }
3621
3622 if (IsDependent)
3623 Results.AddResult(Result("template"));
3624 }
3625 }
3626 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
3627 // Objective-C property reference.
3628 AddedPropertiesSet AddedProperties;
3629
3630 // Add property results based on our interface.
3631 const ObjCObjectPointerType *ObjCPtr
3632 = BaseType->getAsObjCInterfacePointerType();
3633 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
3634 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true,
3635 /*AllowNullaryMethods=*/true, CurContext,
3636 AddedProperties, Results);
3637
3638 // Add properties from the protocols in a qualified interface.
3639 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
3640 E = ObjCPtr->qual_end();
3641 I != E; ++I)
3642 AddObjCProperties(*I, true, /*AllowNullaryMethods=*/true, CurContext,
3643 AddedProperties, Results);
3644 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
3645 (!IsArrow && BaseType->isObjCObjectType())) {
3646 // Objective-C instance variable access.
3647 ObjCInterfaceDecl *Class = 0;
3648 if (const ObjCObjectPointerType *ObjCPtr
3649 = BaseType->getAs<ObjCObjectPointerType>())
3650 Class = ObjCPtr->getInterfaceDecl();
3651 else
3652 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
3653
3654 // Add all ivars from this class and its superclasses.
3655 if (Class) {
3656 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3657 Results.setFilter(&ResultBuilder::IsObjCIvar);
3658 LookupVisibleDecls(Class, LookupMemberName, Consumer,
3659 CodeCompleter->includeGlobals());
3660 }
3661 }
3662
3663 // FIXME: How do we cope with isa?
3664
3665 Results.ExitScope();
3666
3667 // Hand off the results found for code completion.
3668 HandleCodeCompleteResults(this, CodeCompleter,
3669 Results.getCompletionContext(),
3670 Results.data(),Results.size());
3671 }
3672
CodeCompleteTag(Scope * S,unsigned TagSpec)3673 void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
3674 if (!CodeCompleter)
3675 return;
3676
3677 ResultBuilder::LookupFilter Filter = 0;
3678 enum CodeCompletionContext::Kind ContextKind
3679 = CodeCompletionContext::CCC_Other;
3680 switch ((DeclSpec::TST)TagSpec) {
3681 case DeclSpec::TST_enum:
3682 Filter = &ResultBuilder::IsEnum;
3683 ContextKind = CodeCompletionContext::CCC_EnumTag;
3684 break;
3685
3686 case DeclSpec::TST_union:
3687 Filter = &ResultBuilder::IsUnion;
3688 ContextKind = CodeCompletionContext::CCC_UnionTag;
3689 break;
3690
3691 case DeclSpec::TST_struct:
3692 case DeclSpec::TST_class:
3693 case DeclSpec::TST_interface:
3694 Filter = &ResultBuilder::IsClassOrStruct;
3695 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
3696 break;
3697
3698 default:
3699 llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
3700 }
3701
3702 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3703 CodeCompleter->getCodeCompletionTUInfo(), ContextKind);
3704 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3705
3706 // First pass: look for tags.
3707 Results.setFilter(Filter);
3708 LookupVisibleDecls(S, LookupTagName, Consumer,
3709 CodeCompleter->includeGlobals());
3710
3711 if (CodeCompleter->includeGlobals()) {
3712 // Second pass: look for nested name specifiers.
3713 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
3714 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
3715 }
3716
3717 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3718 Results.data(),Results.size());
3719 }
3720
CodeCompleteTypeQualifiers(DeclSpec & DS)3721 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
3722 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3723 CodeCompleter->getCodeCompletionTUInfo(),
3724 CodeCompletionContext::CCC_TypeQualifiers);
3725 Results.EnterNewScope();
3726 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
3727 Results.AddResult("const");
3728 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
3729 Results.AddResult("volatile");
3730 if (getLangOpts().C99 &&
3731 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
3732 Results.AddResult("restrict");
3733 if (getLangOpts().C11 &&
3734 !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
3735 Results.AddResult("_Atomic");
3736 Results.ExitScope();
3737 HandleCodeCompleteResults(this, CodeCompleter,
3738 Results.getCompletionContext(),
3739 Results.data(), Results.size());
3740 }
3741
CodeCompleteCase(Scope * S)3742 void Sema::CodeCompleteCase(Scope *S) {
3743 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
3744 return;
3745
3746 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
3747 QualType type = Switch->getCond()->IgnoreImplicit()->getType();
3748 if (!type->isEnumeralType()) {
3749 CodeCompleteExpressionData Data(type);
3750 Data.IntegralConstantExpression = true;
3751 CodeCompleteExpression(S, Data);
3752 return;
3753 }
3754
3755 // Code-complete the cases of a switch statement over an enumeration type
3756 // by providing the list of
3757 EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
3758 if (EnumDecl *Def = Enum->getDefinition())
3759 Enum = Def;
3760
3761 // Determine which enumerators we have already seen in the switch statement.
3762 // FIXME: Ideally, we would also be able to look *past* the code-completion
3763 // token, in case we are code-completing in the middle of the switch and not
3764 // at the end. However, we aren't able to do so at the moment.
3765 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
3766 NestedNameSpecifier *Qualifier = 0;
3767 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3768 SC = SC->getNextSwitchCase()) {
3769 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3770 if (!Case)
3771 continue;
3772
3773 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3774 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3775 if (EnumConstantDecl *Enumerator
3776 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3777 // We look into the AST of the case statement to determine which
3778 // enumerator was named. Alternatively, we could compute the value of
3779 // the integral constant expression, then compare it against the
3780 // values of each enumerator. However, value-based approach would not
3781 // work as well with C++ templates where enumerators declared within a
3782 // template are type- and value-dependent.
3783 EnumeratorsSeen.insert(Enumerator);
3784
3785 // If this is a qualified-id, keep track of the nested-name-specifier
3786 // so that we can reproduce it as part of code completion, e.g.,
3787 //
3788 // switch (TagD.getKind()) {
3789 // case TagDecl::TK_enum:
3790 // break;
3791 // case XXX
3792 //
3793 // At the XXX, our completions are TagDecl::TK_union,
3794 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3795 // TK_struct, and TK_class.
3796 Qualifier = DRE->getQualifier();
3797 }
3798 }
3799
3800 if (getLangOpts().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3801 // If there are no prior enumerators in C++, check whether we have to
3802 // qualify the names of the enumerators that we suggest, because they
3803 // may not be visible in this scope.
3804 Qualifier = getRequiredQualification(Context, CurContext, Enum);
3805 }
3806
3807 // Add any enumerators that have not yet been mentioned.
3808 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3809 CodeCompleter->getCodeCompletionTUInfo(),
3810 CodeCompletionContext::CCC_Expression);
3811 Results.EnterNewScope();
3812 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3813 EEnd = Enum->enumerator_end();
3814 E != EEnd; ++E) {
3815 if (EnumeratorsSeen.count(*E))
3816 continue;
3817
3818 CodeCompletionResult R(*E, CCP_EnumInCase, Qualifier);
3819 Results.AddResult(R, CurContext, 0, false);
3820 }
3821 Results.ExitScope();
3822
3823 //We need to make sure we're setting the right context,
3824 //so only say we include macros if the code completer says we do
3825 enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other;
3826 if (CodeCompleter->includeMacros()) {
3827 AddMacroResults(PP, Results, false);
3828 kind = CodeCompletionContext::CCC_OtherWithMacros;
3829 }
3830
3831 HandleCodeCompleteResults(this, CodeCompleter,
3832 kind,
3833 Results.data(),Results.size());
3834 }
3835
3836 namespace {
3837 struct IsBetterOverloadCandidate {
3838 Sema &S;
3839 SourceLocation Loc;
3840
3841 public:
IsBetterOverloadCandidate__anon973cf00c0311::IsBetterOverloadCandidate3842 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3843 : S(S), Loc(Loc) { }
3844
3845 bool
operator ()__anon973cf00c0311::IsBetterOverloadCandidate3846 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
3847 return isBetterOverloadCandidate(S, X, Y, Loc);
3848 }
3849 };
3850 }
3851
anyNullArguments(ArrayRef<Expr * > Args)3852 static bool anyNullArguments(ArrayRef<Expr *> Args) {
3853 if (Args.size() && !Args.data())
3854 return true;
3855
3856 for (unsigned I = 0; I != Args.size(); ++I)
3857 if (!Args[I])
3858 return true;
3859
3860 return false;
3861 }
3862
CodeCompleteCall(Scope * S,Expr * FnIn,ArrayRef<Expr * > Args)3863 void Sema::CodeCompleteCall(Scope *S, Expr *FnIn, ArrayRef<Expr *> Args) {
3864 if (!CodeCompleter)
3865 return;
3866
3867 // When we're code-completing for a call, we fall back to ordinary
3868 // name code-completion whenever we can't produce specific
3869 // results. We may want to revisit this strategy in the future,
3870 // e.g., by merging the two kinds of results.
3871
3872 Expr *Fn = (Expr *)FnIn;
3873
3874 // Ignore type-dependent call expressions entirely.
3875 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
3876 Expr::hasAnyTypeDependentArguments(Args)) {
3877 CodeCompleteOrdinaryName(S, PCC_Expression);
3878 return;
3879 }
3880
3881 // Build an overload candidate set based on the functions we find.
3882 SourceLocation Loc = Fn->getExprLoc();
3883 OverloadCandidateSet CandidateSet(Loc);
3884
3885 // FIXME: What if we're calling something that isn't a function declaration?
3886 // FIXME: What if we're calling a pseudo-destructor?
3887 // FIXME: What if we're calling a member function?
3888
3889 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3890 SmallVector<ResultCandidate, 8> Results;
3891
3892 Expr *NakedFn = Fn->IgnoreParenCasts();
3893 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3894 AddOverloadedCallCandidates(ULE, Args, CandidateSet,
3895 /*PartialOverloading=*/ true);
3896 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3897 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
3898 if (FDecl) {
3899 if (!getLangOpts().CPlusPlus ||
3900 !FDecl->getType()->getAs<FunctionProtoType>())
3901 Results.push_back(ResultCandidate(FDecl));
3902 else
3903 // FIXME: access?
3904 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none), Args,
3905 CandidateSet, false, /*PartialOverloading*/true);
3906 }
3907 }
3908
3909 QualType ParamType;
3910
3911 if (!CandidateSet.empty()) {
3912 // Sort the overload candidate set by placing the best overloads first.
3913 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
3914 IsBetterOverloadCandidate(*this, Loc));
3915
3916 // Add the remaining viable overload candidates as code-completion reslults.
3917 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3918 CandEnd = CandidateSet.end();
3919 Cand != CandEnd; ++Cand) {
3920 if (Cand->Viable)
3921 Results.push_back(ResultCandidate(Cand->Function));
3922 }
3923
3924 // From the viable candidates, try to determine the type of this parameter.
3925 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3926 if (const FunctionType *FType = Results[I].getFunctionType())
3927 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3928 if (Args.size() < Proto->getNumArgs()) {
3929 if (ParamType.isNull())
3930 ParamType = Proto->getArgType(Args.size());
3931 else if (!Context.hasSameUnqualifiedType(
3932 ParamType.getNonReferenceType(),
3933 Proto->getArgType(Args.size()).getNonReferenceType())) {
3934 ParamType = QualType();
3935 break;
3936 }
3937 }
3938 }
3939 } else {
3940 // Try to determine the parameter type from the type of the expression
3941 // being called.
3942 QualType FunctionType = Fn->getType();
3943 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3944 FunctionType = Ptr->getPointeeType();
3945 else if (const BlockPointerType *BlockPtr
3946 = FunctionType->getAs<BlockPointerType>())
3947 FunctionType = BlockPtr->getPointeeType();
3948 else if (const MemberPointerType *MemPtr
3949 = FunctionType->getAs<MemberPointerType>())
3950 FunctionType = MemPtr->getPointeeType();
3951
3952 if (const FunctionProtoType *Proto
3953 = FunctionType->getAs<FunctionProtoType>()) {
3954 if (Args.size() < Proto->getNumArgs())
3955 ParamType = Proto->getArgType(Args.size());
3956 }
3957 }
3958
3959 if (ParamType.isNull())
3960 CodeCompleteOrdinaryName(S, PCC_Expression);
3961 else
3962 CodeCompleteExpression(S, ParamType);
3963
3964 if (!Results.empty())
3965 CodeCompleter->ProcessOverloadCandidates(*this, Args.size(), Results.data(),
3966 Results.size());
3967 }
3968
CodeCompleteInitializer(Scope * S,Decl * D)3969 void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3970 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
3971 if (!VD) {
3972 CodeCompleteOrdinaryName(S, PCC_Expression);
3973 return;
3974 }
3975
3976 CodeCompleteExpression(S, VD->getType());
3977 }
3978
CodeCompleteReturn(Scope * S)3979 void Sema::CodeCompleteReturn(Scope *S) {
3980 QualType ResultType;
3981 if (isa<BlockDecl>(CurContext)) {
3982 if (BlockScopeInfo *BSI = getCurBlock())
3983 ResultType = BSI->ReturnType;
3984 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3985 ResultType = Function->getResultType();
3986 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3987 ResultType = Method->getResultType();
3988
3989 if (ResultType.isNull())
3990 CodeCompleteOrdinaryName(S, PCC_Expression);
3991 else
3992 CodeCompleteExpression(S, ResultType);
3993 }
3994
CodeCompleteAfterIf(Scope * S)3995 void Sema::CodeCompleteAfterIf(Scope *S) {
3996 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3997 CodeCompleter->getCodeCompletionTUInfo(),
3998 mapCodeCompletionContext(*this, PCC_Statement));
3999 Results.setFilter(&ResultBuilder::IsOrdinaryName);
4000 Results.EnterNewScope();
4001
4002 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4003 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4004 CodeCompleter->includeGlobals());
4005
4006 AddOrdinaryNameResults(PCC_Statement, S, *this, Results);
4007
4008 // "else" block
4009 CodeCompletionBuilder Builder(Results.getAllocator(),
4010 Results.getCodeCompletionTUInfo());
4011 Builder.AddTypedTextChunk("else");
4012 if (Results.includeCodePatterns()) {
4013 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4014 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4015 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4016 Builder.AddPlaceholderChunk("statements");
4017 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4018 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4019 }
4020 Results.AddResult(Builder.TakeString());
4021
4022 // "else if" block
4023 Builder.AddTypedTextChunk("else");
4024 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4025 Builder.AddTextChunk("if");
4026 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4027 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4028 if (getLangOpts().CPlusPlus)
4029 Builder.AddPlaceholderChunk("condition");
4030 else
4031 Builder.AddPlaceholderChunk("expression");
4032 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4033 if (Results.includeCodePatterns()) {
4034 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4035 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4036 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4037 Builder.AddPlaceholderChunk("statements");
4038 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4039 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4040 }
4041 Results.AddResult(Builder.TakeString());
4042
4043 Results.ExitScope();
4044
4045 if (S->getFnParent())
4046 AddPrettyFunctionResults(PP.getLangOpts(), Results);
4047
4048 if (CodeCompleter->includeMacros())
4049 AddMacroResults(PP, Results, false);
4050
4051 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4052 Results.data(),Results.size());
4053 }
4054
CodeCompleteAssignmentRHS(Scope * S,Expr * LHS)4055 void Sema::CodeCompleteAssignmentRHS(Scope *S, Expr *LHS) {
4056 if (LHS)
4057 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
4058 else
4059 CodeCompleteOrdinaryName(S, PCC_Expression);
4060 }
4061
CodeCompleteQualifiedId(Scope * S,CXXScopeSpec & SS,bool EnteringContext)4062 void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
4063 bool EnteringContext) {
4064 if (!SS.getScopeRep() || !CodeCompleter)
4065 return;
4066
4067 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
4068 if (!Ctx)
4069 return;
4070
4071 // Try to instantiate any non-dependent declaration contexts before
4072 // we look in them.
4073 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
4074 return;
4075
4076 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4077 CodeCompleter->getCodeCompletionTUInfo(),
4078 CodeCompletionContext::CCC_Name);
4079 Results.EnterNewScope();
4080
4081 // The "template" keyword can follow "::" in the grammar, but only
4082 // put it into the grammar if the nested-name-specifier is dependent.
4083 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
4084 if (!Results.empty() && NNS->isDependent())
4085 Results.AddResult("template");
4086
4087 // Add calls to overridden virtual functions, if there are any.
4088 //
4089 // FIXME: This isn't wonderful, because we don't know whether we're actually
4090 // in a context that permits expressions. This is a general issue with
4091 // qualified-id completions.
4092 if (!EnteringContext)
4093 MaybeAddOverrideCalls(*this, Ctx, Results);
4094 Results.ExitScope();
4095
4096 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4097 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
4098
4099 HandleCodeCompleteResults(this, CodeCompleter,
4100 Results.getCompletionContext(),
4101 Results.data(),Results.size());
4102 }
4103
CodeCompleteUsing(Scope * S)4104 void Sema::CodeCompleteUsing(Scope *S) {
4105 if (!CodeCompleter)
4106 return;
4107
4108 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4109 CodeCompleter->getCodeCompletionTUInfo(),
4110 CodeCompletionContext::CCC_PotentiallyQualifiedName,
4111 &ResultBuilder::IsNestedNameSpecifier);
4112 Results.EnterNewScope();
4113
4114 // If we aren't in class scope, we could see the "namespace" keyword.
4115 if (!S->isClassScope())
4116 Results.AddResult(CodeCompletionResult("namespace"));
4117
4118 // After "using", we can see anything that would start a
4119 // nested-name-specifier.
4120 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4121 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4122 CodeCompleter->includeGlobals());
4123 Results.ExitScope();
4124
4125 HandleCodeCompleteResults(this, CodeCompleter,
4126 CodeCompletionContext::CCC_PotentiallyQualifiedName,
4127 Results.data(),Results.size());
4128 }
4129
CodeCompleteUsingDirective(Scope * S)4130 void Sema::CodeCompleteUsingDirective(Scope *S) {
4131 if (!CodeCompleter)
4132 return;
4133
4134 // After "using namespace", we expect to see a namespace name or namespace
4135 // alias.
4136 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4137 CodeCompleter->getCodeCompletionTUInfo(),
4138 CodeCompletionContext::CCC_Namespace,
4139 &ResultBuilder::IsNamespaceOrAlias);
4140 Results.EnterNewScope();
4141 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4142 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4143 CodeCompleter->includeGlobals());
4144 Results.ExitScope();
4145 HandleCodeCompleteResults(this, CodeCompleter,
4146 CodeCompletionContext::CCC_Namespace,
4147 Results.data(),Results.size());
4148 }
4149
CodeCompleteNamespaceDecl(Scope * S)4150 void Sema::CodeCompleteNamespaceDecl(Scope *S) {
4151 if (!CodeCompleter)
4152 return;
4153
4154 DeclContext *Ctx = S->getEntity();
4155 if (!S->getParent())
4156 Ctx = Context.getTranslationUnitDecl();
4157
4158 bool SuppressedGlobalResults
4159 = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
4160
4161 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4162 CodeCompleter->getCodeCompletionTUInfo(),
4163 SuppressedGlobalResults
4164 ? CodeCompletionContext::CCC_Namespace
4165 : CodeCompletionContext::CCC_Other,
4166 &ResultBuilder::IsNamespace);
4167
4168 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
4169 // We only want to see those namespaces that have already been defined
4170 // within this scope, because its likely that the user is creating an
4171 // extended namespace declaration. Keep track of the most recent
4172 // definition of each namespace.
4173 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
4174 for (DeclContext::specific_decl_iterator<NamespaceDecl>
4175 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
4176 NS != NSEnd; ++NS)
4177 OrigToLatest[NS->getOriginalNamespace()] = *NS;
4178
4179 // Add the most recent definition (or extended definition) of each
4180 // namespace to the list of results.
4181 Results.EnterNewScope();
4182 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
4183 NS = OrigToLatest.begin(),
4184 NSEnd = OrigToLatest.end();
4185 NS != NSEnd; ++NS)
4186 Results.AddResult(CodeCompletionResult(
4187 NS->second, Results.getBasePriority(NS->second), 0),
4188 CurContext, 0, false);
4189 Results.ExitScope();
4190 }
4191
4192 HandleCodeCompleteResults(this, CodeCompleter,
4193 Results.getCompletionContext(),
4194 Results.data(),Results.size());
4195 }
4196
CodeCompleteNamespaceAliasDecl(Scope * S)4197 void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
4198 if (!CodeCompleter)
4199 return;
4200
4201 // After "namespace", we expect to see a namespace or alias.
4202 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4203 CodeCompleter->getCodeCompletionTUInfo(),
4204 CodeCompletionContext::CCC_Namespace,
4205 &ResultBuilder::IsNamespaceOrAlias);
4206 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4207 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4208 CodeCompleter->includeGlobals());
4209 HandleCodeCompleteResults(this, CodeCompleter,
4210 Results.getCompletionContext(),
4211 Results.data(),Results.size());
4212 }
4213
CodeCompleteOperatorName(Scope * S)4214 void Sema::CodeCompleteOperatorName(Scope *S) {
4215 if (!CodeCompleter)
4216 return;
4217
4218 typedef CodeCompletionResult Result;
4219 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4220 CodeCompleter->getCodeCompletionTUInfo(),
4221 CodeCompletionContext::CCC_Type,
4222 &ResultBuilder::IsType);
4223 Results.EnterNewScope();
4224
4225 // Add the names of overloadable operators.
4226 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
4227 if (std::strcmp(Spelling, "?")) \
4228 Results.AddResult(Result(Spelling));
4229 #include "clang/Basic/OperatorKinds.def"
4230
4231 // Add any type names visible from the current scope
4232 Results.allowNestedNameSpecifiers();
4233 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4234 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4235 CodeCompleter->includeGlobals());
4236
4237 // Add any type specifiers
4238 AddTypeSpecifierResults(getLangOpts(), Results);
4239 Results.ExitScope();
4240
4241 HandleCodeCompleteResults(this, CodeCompleter,
4242 CodeCompletionContext::CCC_Type,
4243 Results.data(),Results.size());
4244 }
4245
CodeCompleteConstructorInitializer(Decl * ConstructorD,ArrayRef<CXXCtorInitializer * > Initializers)4246 void Sema::CodeCompleteConstructorInitializer(
4247 Decl *ConstructorD,
4248 ArrayRef <CXXCtorInitializer *> Initializers) {
4249 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
4250 CXXConstructorDecl *Constructor
4251 = static_cast<CXXConstructorDecl *>(ConstructorD);
4252 if (!Constructor)
4253 return;
4254
4255 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4256 CodeCompleter->getCodeCompletionTUInfo(),
4257 CodeCompletionContext::CCC_PotentiallyQualifiedName);
4258 Results.EnterNewScope();
4259
4260 // Fill in any already-initialized fields or base classes.
4261 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
4262 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
4263 for (unsigned I = 0, E = Initializers.size(); I != E; ++I) {
4264 if (Initializers[I]->isBaseInitializer())
4265 InitializedBases.insert(
4266 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
4267 else
4268 InitializedFields.insert(cast<FieldDecl>(
4269 Initializers[I]->getAnyMember()));
4270 }
4271
4272 // Add completions for base classes.
4273 CodeCompletionBuilder Builder(Results.getAllocator(),
4274 Results.getCodeCompletionTUInfo());
4275 bool SawLastInitializer = Initializers.empty();
4276 CXXRecordDecl *ClassDecl = Constructor->getParent();
4277 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
4278 BaseEnd = ClassDecl->bases_end();
4279 Base != BaseEnd; ++Base) {
4280 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
4281 SawLastInitializer
4282 = !Initializers.empty() &&
4283 Initializers.back()->isBaseInitializer() &&
4284 Context.hasSameUnqualifiedType(Base->getType(),
4285 QualType(Initializers.back()->getBaseClass(), 0));
4286 continue;
4287 }
4288
4289 Builder.AddTypedTextChunk(
4290 Results.getAllocator().CopyString(
4291 Base->getType().getAsString(Policy)));
4292 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4293 Builder.AddPlaceholderChunk("args");
4294 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4295 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4296 SawLastInitializer? CCP_NextInitializer
4297 : CCP_MemberDeclaration));
4298 SawLastInitializer = false;
4299 }
4300
4301 // Add completions for virtual base classes.
4302 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
4303 BaseEnd = ClassDecl->vbases_end();
4304 Base != BaseEnd; ++Base) {
4305 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
4306 SawLastInitializer
4307 = !Initializers.empty() &&
4308 Initializers.back()->isBaseInitializer() &&
4309 Context.hasSameUnqualifiedType(Base->getType(),
4310 QualType(Initializers.back()->getBaseClass(), 0));
4311 continue;
4312 }
4313
4314 Builder.AddTypedTextChunk(
4315 Builder.getAllocator().CopyString(
4316 Base->getType().getAsString(Policy)));
4317 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4318 Builder.AddPlaceholderChunk("args");
4319 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4320 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4321 SawLastInitializer? CCP_NextInitializer
4322 : CCP_MemberDeclaration));
4323 SawLastInitializer = false;
4324 }
4325
4326 // Add completions for members.
4327 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
4328 FieldEnd = ClassDecl->field_end();
4329 Field != FieldEnd; ++Field) {
4330 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
4331 SawLastInitializer
4332 = !Initializers.empty() &&
4333 Initializers.back()->isAnyMemberInitializer() &&
4334 Initializers.back()->getAnyMember() == *Field;
4335 continue;
4336 }
4337
4338 if (!Field->getDeclName())
4339 continue;
4340
4341 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
4342 Field->getIdentifier()->getName()));
4343 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4344 Builder.AddPlaceholderChunk("args");
4345 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4346 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4347 SawLastInitializer? CCP_NextInitializer
4348 : CCP_MemberDeclaration,
4349 CXCursor_MemberRef,
4350 CXAvailability_Available,
4351 *Field));
4352 SawLastInitializer = false;
4353 }
4354 Results.ExitScope();
4355
4356 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4357 Results.data(), Results.size());
4358 }
4359
4360 /// \brief Determine whether this scope denotes a namespace.
isNamespaceScope(Scope * S)4361 static bool isNamespaceScope(Scope *S) {
4362 DeclContext *DC = S->getEntity();
4363 if (!DC)
4364 return false;
4365
4366 return DC->isFileContext();
4367 }
4368
CodeCompleteLambdaIntroducer(Scope * S,LambdaIntroducer & Intro,bool AfterAmpersand)4369 void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
4370 bool AfterAmpersand) {
4371 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4372 CodeCompleter->getCodeCompletionTUInfo(),
4373 CodeCompletionContext::CCC_Other);
4374 Results.EnterNewScope();
4375
4376 // Note what has already been captured.
4377 llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
4378 bool IncludedThis = false;
4379 for (SmallVectorImpl<LambdaCapture>::iterator C = Intro.Captures.begin(),
4380 CEnd = Intro.Captures.end();
4381 C != CEnd; ++C) {
4382 if (C->Kind == LCK_This) {
4383 IncludedThis = true;
4384 continue;
4385 }
4386
4387 Known.insert(C->Id);
4388 }
4389
4390 // Look for other capturable variables.
4391 for (; S && !isNamespaceScope(S); S = S->getParent()) {
4392 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
4393 D != DEnd; ++D) {
4394 VarDecl *Var = dyn_cast<VarDecl>(*D);
4395 if (!Var ||
4396 !Var->hasLocalStorage() ||
4397 Var->hasAttr<BlocksAttr>())
4398 continue;
4399
4400 if (Known.insert(Var->getIdentifier()))
4401 Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),
4402 CurContext, 0, false);
4403 }
4404 }
4405
4406 // Add 'this', if it would be valid.
4407 if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
4408 addThisCompletion(*this, Results);
4409
4410 Results.ExitScope();
4411
4412 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4413 Results.data(), Results.size());
4414 }
4415
4416 /// Macro that optionally prepends an "@" to the string literal passed in via
4417 /// Keyword, depending on whether NeedAt is true or false.
4418 #define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) ((NeedAt)? "@" Keyword : Keyword)
4419
AddObjCImplementationResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)4420 static void AddObjCImplementationResults(const LangOptions &LangOpts,
4421 ResultBuilder &Results,
4422 bool NeedAt) {
4423 typedef CodeCompletionResult Result;
4424 // Since we have an implementation, we can end it.
4425 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end")));
4426
4427 CodeCompletionBuilder Builder(Results.getAllocator(),
4428 Results.getCodeCompletionTUInfo());
4429 if (LangOpts.ObjC2) {
4430 // @dynamic
4431 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"dynamic"));
4432 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4433 Builder.AddPlaceholderChunk("property");
4434 Results.AddResult(Result(Builder.TakeString()));
4435
4436 // @synthesize
4437 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synthesize"));
4438 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4439 Builder.AddPlaceholderChunk("property");
4440 Results.AddResult(Result(Builder.TakeString()));
4441 }
4442 }
4443
AddObjCInterfaceResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)4444 static void AddObjCInterfaceResults(const LangOptions &LangOpts,
4445 ResultBuilder &Results,
4446 bool NeedAt) {
4447 typedef CodeCompletionResult Result;
4448
4449 // Since we have an interface or protocol, we can end it.
4450 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end")));
4451
4452 if (LangOpts.ObjC2) {
4453 // @property
4454 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"property")));
4455
4456 // @required
4457 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"required")));
4458
4459 // @optional
4460 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"optional")));
4461 }
4462 }
4463
AddObjCTopLevelResults(ResultBuilder & Results,bool NeedAt)4464 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
4465 typedef CodeCompletionResult Result;
4466 CodeCompletionBuilder Builder(Results.getAllocator(),
4467 Results.getCodeCompletionTUInfo());
4468
4469 // @class name ;
4470 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"class"));
4471 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4472 Builder.AddPlaceholderChunk("name");
4473 Results.AddResult(Result(Builder.TakeString()));
4474
4475 if (Results.includeCodePatterns()) {
4476 // @interface name
4477 // FIXME: Could introduce the whole pattern, including superclasses and
4478 // such.
4479 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"interface"));
4480 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4481 Builder.AddPlaceholderChunk("class");
4482 Results.AddResult(Result(Builder.TakeString()));
4483
4484 // @protocol name
4485 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol"));
4486 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4487 Builder.AddPlaceholderChunk("protocol");
4488 Results.AddResult(Result(Builder.TakeString()));
4489
4490 // @implementation name
4491 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"implementation"));
4492 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4493 Builder.AddPlaceholderChunk("class");
4494 Results.AddResult(Result(Builder.TakeString()));
4495 }
4496
4497 // @compatibility_alias name
4498 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"compatibility_alias"));
4499 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4500 Builder.AddPlaceholderChunk("alias");
4501 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4502 Builder.AddPlaceholderChunk("class");
4503 Results.AddResult(Result(Builder.TakeString()));
4504
4505 if (Results.getSema().getLangOpts().Modules) {
4506 // @import name
4507 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "import"));
4508 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4509 Builder.AddPlaceholderChunk("module");
4510 Results.AddResult(Result(Builder.TakeString()));
4511 }
4512 }
4513
CodeCompleteObjCAtDirective(Scope * S)4514 void Sema::CodeCompleteObjCAtDirective(Scope *S) {
4515 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4516 CodeCompleter->getCodeCompletionTUInfo(),
4517 CodeCompletionContext::CCC_Other);
4518 Results.EnterNewScope();
4519 if (isa<ObjCImplDecl>(CurContext))
4520 AddObjCImplementationResults(getLangOpts(), Results, false);
4521 else if (CurContext->isObjCContainer())
4522 AddObjCInterfaceResults(getLangOpts(), Results, false);
4523 else
4524 AddObjCTopLevelResults(Results, false);
4525 Results.ExitScope();
4526 HandleCodeCompleteResults(this, CodeCompleter,
4527 CodeCompletionContext::CCC_Other,
4528 Results.data(),Results.size());
4529 }
4530
AddObjCExpressionResults(ResultBuilder & Results,bool NeedAt)4531 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
4532 typedef CodeCompletionResult Result;
4533 CodeCompletionBuilder Builder(Results.getAllocator(),
4534 Results.getCodeCompletionTUInfo());
4535
4536 // @encode ( type-name )
4537 const char *EncodeType = "char[]";
4538 if (Results.getSema().getLangOpts().CPlusPlus ||
4539 Results.getSema().getLangOpts().ConstStrings)
4540 EncodeType = "const char[]";
4541 Builder.AddResultTypeChunk(EncodeType);
4542 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"encode"));
4543 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4544 Builder.AddPlaceholderChunk("type-name");
4545 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4546 Results.AddResult(Result(Builder.TakeString()));
4547
4548 // @protocol ( protocol-name )
4549 Builder.AddResultTypeChunk("Protocol *");
4550 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol"));
4551 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4552 Builder.AddPlaceholderChunk("protocol-name");
4553 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4554 Results.AddResult(Result(Builder.TakeString()));
4555
4556 // @selector ( selector )
4557 Builder.AddResultTypeChunk("SEL");
4558 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"selector"));
4559 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4560 Builder.AddPlaceholderChunk("selector");
4561 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4562 Results.AddResult(Result(Builder.TakeString()));
4563
4564 // @"string"
4565 Builder.AddResultTypeChunk("NSString *");
4566 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"\""));
4567 Builder.AddPlaceholderChunk("string");
4568 Builder.AddTextChunk("\"");
4569 Results.AddResult(Result(Builder.TakeString()));
4570
4571 // @[objects, ...]
4572 Builder.AddResultTypeChunk("NSArray *");
4573 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"["));
4574 Builder.AddPlaceholderChunk("objects, ...");
4575 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
4576 Results.AddResult(Result(Builder.TakeString()));
4577
4578 // @{key : object, ...}
4579 Builder.AddResultTypeChunk("NSDictionary *");
4580 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"{"));
4581 Builder.AddPlaceholderChunk("key");
4582 Builder.AddChunk(CodeCompletionString::CK_Colon);
4583 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4584 Builder.AddPlaceholderChunk("object, ...");
4585 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4586 Results.AddResult(Result(Builder.TakeString()));
4587
4588 // @(expression)
4589 Builder.AddResultTypeChunk("id");
4590 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "("));
4591 Builder.AddPlaceholderChunk("expression");
4592 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4593 Results.AddResult(Result(Builder.TakeString()));
4594 }
4595
AddObjCStatementResults(ResultBuilder & Results,bool NeedAt)4596 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
4597 typedef CodeCompletionResult Result;
4598 CodeCompletionBuilder Builder(Results.getAllocator(),
4599 Results.getCodeCompletionTUInfo());
4600
4601 if (Results.includeCodePatterns()) {
4602 // @try { statements } @catch ( declaration ) { statements } @finally
4603 // { statements }
4604 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"try"));
4605 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4606 Builder.AddPlaceholderChunk("statements");
4607 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4608 Builder.AddTextChunk("@catch");
4609 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4610 Builder.AddPlaceholderChunk("parameter");
4611 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4612 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4613 Builder.AddPlaceholderChunk("statements");
4614 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4615 Builder.AddTextChunk("@finally");
4616 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4617 Builder.AddPlaceholderChunk("statements");
4618 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4619 Results.AddResult(Result(Builder.TakeString()));
4620 }
4621
4622 // @throw
4623 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"throw"));
4624 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4625 Builder.AddPlaceholderChunk("expression");
4626 Results.AddResult(Result(Builder.TakeString()));
4627
4628 if (Results.includeCodePatterns()) {
4629 // @synchronized ( expression ) { statements }
4630 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synchronized"));
4631 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4632 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4633 Builder.AddPlaceholderChunk("expression");
4634 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4635 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4636 Builder.AddPlaceholderChunk("statements");
4637 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4638 Results.AddResult(Result(Builder.TakeString()));
4639 }
4640 }
4641
AddObjCVisibilityResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)4642 static void AddObjCVisibilityResults(const LangOptions &LangOpts,
4643 ResultBuilder &Results,
4644 bool NeedAt) {
4645 typedef CodeCompletionResult Result;
4646 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"private")));
4647 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"protected")));
4648 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"public")));
4649 if (LangOpts.ObjC2)
4650 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"package")));
4651 }
4652
CodeCompleteObjCAtVisibility(Scope * S)4653 void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
4654 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4655 CodeCompleter->getCodeCompletionTUInfo(),
4656 CodeCompletionContext::CCC_Other);
4657 Results.EnterNewScope();
4658 AddObjCVisibilityResults(getLangOpts(), Results, false);
4659 Results.ExitScope();
4660 HandleCodeCompleteResults(this, CodeCompleter,
4661 CodeCompletionContext::CCC_Other,
4662 Results.data(),Results.size());
4663 }
4664
CodeCompleteObjCAtStatement(Scope * S)4665 void Sema::CodeCompleteObjCAtStatement(Scope *S) {
4666 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4667 CodeCompleter->getCodeCompletionTUInfo(),
4668 CodeCompletionContext::CCC_Other);
4669 Results.EnterNewScope();
4670 AddObjCStatementResults(Results, false);
4671 AddObjCExpressionResults(Results, false);
4672 Results.ExitScope();
4673 HandleCodeCompleteResults(this, CodeCompleter,
4674 CodeCompletionContext::CCC_Other,
4675 Results.data(),Results.size());
4676 }
4677
CodeCompleteObjCAtExpression(Scope * S)4678 void Sema::CodeCompleteObjCAtExpression(Scope *S) {
4679 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4680 CodeCompleter->getCodeCompletionTUInfo(),
4681 CodeCompletionContext::CCC_Other);
4682 Results.EnterNewScope();
4683 AddObjCExpressionResults(Results, false);
4684 Results.ExitScope();
4685 HandleCodeCompleteResults(this, CodeCompleter,
4686 CodeCompletionContext::CCC_Other,
4687 Results.data(),Results.size());
4688 }
4689
4690 /// \brief Determine whether the addition of the given flag to an Objective-C
4691 /// property's attributes will cause a conflict.
ObjCPropertyFlagConflicts(unsigned Attributes,unsigned NewFlag)4692 static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
4693 // Check if we've already added this flag.
4694 if (Attributes & NewFlag)
4695 return true;
4696
4697 Attributes |= NewFlag;
4698
4699 // Check for collisions with "readonly".
4700 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
4701 (Attributes & ObjCDeclSpec::DQ_PR_readwrite))
4702 return true;
4703
4704 // Check for more than one of { assign, copy, retain, strong, weak }.
4705 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
4706 ObjCDeclSpec::DQ_PR_unsafe_unretained |
4707 ObjCDeclSpec::DQ_PR_copy |
4708 ObjCDeclSpec::DQ_PR_retain |
4709 ObjCDeclSpec::DQ_PR_strong |
4710 ObjCDeclSpec::DQ_PR_weak);
4711 if (AssignCopyRetMask &&
4712 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
4713 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained &&
4714 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
4715 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain &&
4716 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong &&
4717 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_weak)
4718 return true;
4719
4720 return false;
4721 }
4722
CodeCompleteObjCPropertyFlags(Scope * S,ObjCDeclSpec & ODS)4723 void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
4724 if (!CodeCompleter)
4725 return;
4726
4727 unsigned Attributes = ODS.getPropertyAttributes();
4728
4729 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4730 CodeCompleter->getCodeCompletionTUInfo(),
4731 CodeCompletionContext::CCC_Other);
4732 Results.EnterNewScope();
4733 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
4734 Results.AddResult(CodeCompletionResult("readonly"));
4735 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
4736 Results.AddResult(CodeCompletionResult("assign"));
4737 if (!ObjCPropertyFlagConflicts(Attributes,
4738 ObjCDeclSpec::DQ_PR_unsafe_unretained))
4739 Results.AddResult(CodeCompletionResult("unsafe_unretained"));
4740 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
4741 Results.AddResult(CodeCompletionResult("readwrite"));
4742 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
4743 Results.AddResult(CodeCompletionResult("retain"));
4744 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_strong))
4745 Results.AddResult(CodeCompletionResult("strong"));
4746 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
4747 Results.AddResult(CodeCompletionResult("copy"));
4748 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
4749 Results.AddResult(CodeCompletionResult("nonatomic"));
4750 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
4751 Results.AddResult(CodeCompletionResult("atomic"));
4752
4753 // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
4754 if (getLangOpts().ObjCARCWeak || getLangOpts().getGC() != LangOptions::NonGC)
4755 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak))
4756 Results.AddResult(CodeCompletionResult("weak"));
4757
4758 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
4759 CodeCompletionBuilder Setter(Results.getAllocator(),
4760 Results.getCodeCompletionTUInfo());
4761 Setter.AddTypedTextChunk("setter");
4762 Setter.AddTextChunk(" = ");
4763 Setter.AddPlaceholderChunk("method");
4764 Results.AddResult(CodeCompletionResult(Setter.TakeString()));
4765 }
4766 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
4767 CodeCompletionBuilder Getter(Results.getAllocator(),
4768 Results.getCodeCompletionTUInfo());
4769 Getter.AddTypedTextChunk("getter");
4770 Getter.AddTextChunk(" = ");
4771 Getter.AddPlaceholderChunk("method");
4772 Results.AddResult(CodeCompletionResult(Getter.TakeString()));
4773 }
4774 Results.ExitScope();
4775 HandleCodeCompleteResults(this, CodeCompleter,
4776 CodeCompletionContext::CCC_Other,
4777 Results.data(),Results.size());
4778 }
4779
4780 /// \brief Describes the kind of Objective-C method that we want to find
4781 /// via code completion.
4782 enum ObjCMethodKind {
4783 MK_Any, ///< Any kind of method, provided it means other specified criteria.
4784 MK_ZeroArgSelector, ///< Zero-argument (unary) selector.
4785 MK_OneArgSelector ///< One-argument selector.
4786 };
4787
isAcceptableObjCSelector(Selector Sel,ObjCMethodKind WantKind,ArrayRef<IdentifierInfo * > SelIdents,bool AllowSameLength=true)4788 static bool isAcceptableObjCSelector(Selector Sel,
4789 ObjCMethodKind WantKind,
4790 ArrayRef<IdentifierInfo *> SelIdents,
4791 bool AllowSameLength = true) {
4792 unsigned NumSelIdents = SelIdents.size();
4793 if (NumSelIdents > Sel.getNumArgs())
4794 return false;
4795
4796 switch (WantKind) {
4797 case MK_Any: break;
4798 case MK_ZeroArgSelector: return Sel.isUnarySelector();
4799 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
4800 }
4801
4802 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
4803 return false;
4804
4805 for (unsigned I = 0; I != NumSelIdents; ++I)
4806 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
4807 return false;
4808
4809 return true;
4810 }
4811
isAcceptableObjCMethod(ObjCMethodDecl * Method,ObjCMethodKind WantKind,ArrayRef<IdentifierInfo * > SelIdents,bool AllowSameLength=true)4812 static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
4813 ObjCMethodKind WantKind,
4814 ArrayRef<IdentifierInfo *> SelIdents,
4815 bool AllowSameLength = true) {
4816 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
4817 AllowSameLength);
4818 }
4819
4820 namespace {
4821 /// \brief A set of selectors, which is used to avoid introducing multiple
4822 /// completions with the same selector into the result set.
4823 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
4824 }
4825
4826 /// \brief Add all of the Objective-C methods in the given Objective-C
4827 /// container to the set of results.
4828 ///
4829 /// The container will be a class, protocol, category, or implementation of
4830 /// any of the above. This mether will recurse to include methods from
4831 /// the superclasses of classes along with their categories, protocols, and
4832 /// implementations.
4833 ///
4834 /// \param Container the container in which we'll look to find methods.
4835 ///
4836 /// \param WantInstanceMethods Whether to add instance methods (only); if
4837 /// false, this routine will add factory methods (only).
4838 ///
4839 /// \param CurContext the context in which we're performing the lookup that
4840 /// finds methods.
4841 ///
4842 /// \param AllowSameLength Whether we allow a method to be added to the list
4843 /// when it has the same number of parameters as we have selector identifiers.
4844 ///
4845 /// \param Results the structure into which we'll add results.
AddObjCMethods(ObjCContainerDecl * Container,bool WantInstanceMethods,ObjCMethodKind WantKind,ArrayRef<IdentifierInfo * > SelIdents,DeclContext * CurContext,VisitedSelectorSet & Selectors,bool AllowSameLength,ResultBuilder & Results,bool InOriginalClass=true)4846 static void AddObjCMethods(ObjCContainerDecl *Container,
4847 bool WantInstanceMethods,
4848 ObjCMethodKind WantKind,
4849 ArrayRef<IdentifierInfo *> SelIdents,
4850 DeclContext *CurContext,
4851 VisitedSelectorSet &Selectors,
4852 bool AllowSameLength,
4853 ResultBuilder &Results,
4854 bool InOriginalClass = true) {
4855 typedef CodeCompletionResult Result;
4856 Container = getContainerDef(Container);
4857 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
4858 bool isRootClass = IFace && !IFace->getSuperClass();
4859 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4860 MEnd = Container->meth_end();
4861 M != MEnd; ++M) {
4862 // The instance methods on the root class can be messaged via the
4863 // metaclass.
4864 if (M->isInstanceMethod() == WantInstanceMethods ||
4865 (isRootClass && !WantInstanceMethods)) {
4866 // Check whether the selector identifiers we've been given are a
4867 // subset of the identifiers for this particular method.
4868 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, AllowSameLength))
4869 continue;
4870
4871 if (!Selectors.insert(M->getSelector()))
4872 continue;
4873
4874 Result R = Result(*M, Results.getBasePriority(*M), 0);
4875 R.StartParameter = SelIdents.size();
4876 R.AllParametersAreInformative = (WantKind != MK_Any);
4877 if (!InOriginalClass)
4878 R.Priority += CCD_InBaseClass;
4879 Results.MaybeAddResult(R, CurContext);
4880 }
4881 }
4882
4883 // Visit the protocols of protocols.
4884 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4885 if (Protocol->hasDefinition()) {
4886 const ObjCList<ObjCProtocolDecl> &Protocols
4887 = Protocol->getReferencedProtocols();
4888 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4889 E = Protocols.end();
4890 I != E; ++I)
4891 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
4892 CurContext, Selectors, AllowSameLength, Results, false);
4893 }
4894 }
4895
4896 if (!IFace || !IFace->hasDefinition())
4897 return;
4898
4899 // Add methods in protocols.
4900 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
4901 E = IFace->protocol_end();
4902 I != E; ++I)
4903 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
4904 CurContext, Selectors, AllowSameLength, Results, false);
4905
4906 // Add methods in categories.
4907 for (ObjCInterfaceDecl::known_categories_iterator
4908 Cat = IFace->known_categories_begin(),
4909 CatEnd = IFace->known_categories_end();
4910 Cat != CatEnd; ++Cat) {
4911 ObjCCategoryDecl *CatDecl = *Cat;
4912
4913 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
4914 CurContext, Selectors, AllowSameLength,
4915 Results, InOriginalClass);
4916
4917 // Add a categories protocol methods.
4918 const ObjCList<ObjCProtocolDecl> &Protocols
4919 = CatDecl->getReferencedProtocols();
4920 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4921 E = Protocols.end();
4922 I != E; ++I)
4923 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
4924 CurContext, Selectors, AllowSameLength,
4925 Results, false);
4926
4927 // Add methods in category implementations.
4928 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
4929 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
4930 CurContext, Selectors, AllowSameLength,
4931 Results, InOriginalClass);
4932 }
4933
4934 // Add methods in superclass.
4935 if (IFace->getSuperClass())
4936 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
4937 SelIdents, CurContext, Selectors,
4938 AllowSameLength, Results, false);
4939
4940 // Add methods in our implementation, if any.
4941 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4942 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
4943 CurContext, Selectors, AllowSameLength,
4944 Results, InOriginalClass);
4945 }
4946
4947
CodeCompleteObjCPropertyGetter(Scope * S)4948 void Sema::CodeCompleteObjCPropertyGetter(Scope *S) {
4949 // Try to find the interface where getters might live.
4950 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
4951 if (!Class) {
4952 if (ObjCCategoryDecl *Category
4953 = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
4954 Class = Category->getClassInterface();
4955
4956 if (!Class)
4957 return;
4958 }
4959
4960 // Find all of the potential getters.
4961 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4962 CodeCompleter->getCodeCompletionTUInfo(),
4963 CodeCompletionContext::CCC_Other);
4964 Results.EnterNewScope();
4965
4966 VisitedSelectorSet Selectors;
4967 AddObjCMethods(Class, true, MK_ZeroArgSelector, None, CurContext, Selectors,
4968 /*AllowSameLength=*/true, Results);
4969 Results.ExitScope();
4970 HandleCodeCompleteResults(this, CodeCompleter,
4971 CodeCompletionContext::CCC_Other,
4972 Results.data(),Results.size());
4973 }
4974
CodeCompleteObjCPropertySetter(Scope * S)4975 void Sema::CodeCompleteObjCPropertySetter(Scope *S) {
4976 // Try to find the interface where setters might live.
4977 ObjCInterfaceDecl *Class
4978 = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
4979 if (!Class) {
4980 if (ObjCCategoryDecl *Category
4981 = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
4982 Class = Category->getClassInterface();
4983
4984 if (!Class)
4985 return;
4986 }
4987
4988 // Find all of the potential getters.
4989 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4990 CodeCompleter->getCodeCompletionTUInfo(),
4991 CodeCompletionContext::CCC_Other);
4992 Results.EnterNewScope();
4993
4994 VisitedSelectorSet Selectors;
4995 AddObjCMethods(Class, true, MK_OneArgSelector, None, CurContext,
4996 Selectors, /*AllowSameLength=*/true, Results);
4997
4998 Results.ExitScope();
4999 HandleCodeCompleteResults(this, CodeCompleter,
5000 CodeCompletionContext::CCC_Other,
5001 Results.data(),Results.size());
5002 }
5003
CodeCompleteObjCPassingType(Scope * S,ObjCDeclSpec & DS,bool IsParameter)5004 void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
5005 bool IsParameter) {
5006 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5007 CodeCompleter->getCodeCompletionTUInfo(),
5008 CodeCompletionContext::CCC_Type);
5009 Results.EnterNewScope();
5010
5011 // Add context-sensitive, Objective-C parameter-passing keywords.
5012 bool AddedInOut = false;
5013 if ((DS.getObjCDeclQualifier() &
5014 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
5015 Results.AddResult("in");
5016 Results.AddResult("inout");
5017 AddedInOut = true;
5018 }
5019 if ((DS.getObjCDeclQualifier() &
5020 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
5021 Results.AddResult("out");
5022 if (!AddedInOut)
5023 Results.AddResult("inout");
5024 }
5025 if ((DS.getObjCDeclQualifier() &
5026 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
5027 ObjCDeclSpec::DQ_Oneway)) == 0) {
5028 Results.AddResult("bycopy");
5029 Results.AddResult("byref");
5030 Results.AddResult("oneway");
5031 }
5032
5033 // If we're completing the return type of an Objective-C method and the
5034 // identifier IBAction refers to a macro, provide a completion item for
5035 // an action, e.g.,
5036 // IBAction)<#selector#>:(id)sender
5037 if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
5038 Context.Idents.get("IBAction").hasMacroDefinition()) {
5039 CodeCompletionBuilder Builder(Results.getAllocator(),
5040 Results.getCodeCompletionTUInfo(),
5041 CCP_CodePattern, CXAvailability_Available);
5042 Builder.AddTypedTextChunk("IBAction");
5043 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5044 Builder.AddPlaceholderChunk("selector");
5045 Builder.AddChunk(CodeCompletionString::CK_Colon);
5046 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5047 Builder.AddTextChunk("id");
5048 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5049 Builder.AddTextChunk("sender");
5050 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
5051 }
5052
5053 // If we're completing the return type, provide 'instancetype'.
5054 if (!IsParameter) {
5055 Results.AddResult(CodeCompletionResult("instancetype"));
5056 }
5057
5058 // Add various builtin type names and specifiers.
5059 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
5060 Results.ExitScope();
5061
5062 // Add the various type names
5063 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
5064 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5065 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5066 CodeCompleter->includeGlobals());
5067
5068 if (CodeCompleter->includeMacros())
5069 AddMacroResults(PP, Results, false);
5070
5071 HandleCodeCompleteResults(this, CodeCompleter,
5072 CodeCompletionContext::CCC_Type,
5073 Results.data(), Results.size());
5074 }
5075
5076 /// \brief When we have an expression with type "id", we may assume
5077 /// that it has some more-specific class type based on knowledge of
5078 /// common uses of Objective-C. This routine returns that class type,
5079 /// or NULL if no better result could be determined.
GetAssumedMessageSendExprType(Expr * E)5080 static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
5081 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
5082 if (!Msg)
5083 return 0;
5084
5085 Selector Sel = Msg->getSelector();
5086 if (Sel.isNull())
5087 return 0;
5088
5089 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
5090 if (!Id)
5091 return 0;
5092
5093 ObjCMethodDecl *Method = Msg->getMethodDecl();
5094 if (!Method)
5095 return 0;
5096
5097 // Determine the class that we're sending the message to.
5098 ObjCInterfaceDecl *IFace = 0;
5099 switch (Msg->getReceiverKind()) {
5100 case ObjCMessageExpr::Class:
5101 if (const ObjCObjectType *ObjType
5102 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
5103 IFace = ObjType->getInterface();
5104 break;
5105
5106 case ObjCMessageExpr::Instance: {
5107 QualType T = Msg->getInstanceReceiver()->getType();
5108 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
5109 IFace = Ptr->getInterfaceDecl();
5110 break;
5111 }
5112
5113 case ObjCMessageExpr::SuperInstance:
5114 case ObjCMessageExpr::SuperClass:
5115 break;
5116 }
5117
5118 if (!IFace)
5119 return 0;
5120
5121 ObjCInterfaceDecl *Super = IFace->getSuperClass();
5122 if (Method->isInstanceMethod())
5123 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
5124 .Case("retain", IFace)
5125 .Case("strong", IFace)
5126 .Case("autorelease", IFace)
5127 .Case("copy", IFace)
5128 .Case("copyWithZone", IFace)
5129 .Case("mutableCopy", IFace)
5130 .Case("mutableCopyWithZone", IFace)
5131 .Case("awakeFromCoder", IFace)
5132 .Case("replacementObjectFromCoder", IFace)
5133 .Case("class", IFace)
5134 .Case("classForCoder", IFace)
5135 .Case("superclass", Super)
5136 .Default(0);
5137
5138 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
5139 .Case("new", IFace)
5140 .Case("alloc", IFace)
5141 .Case("allocWithZone", IFace)
5142 .Case("class", IFace)
5143 .Case("superclass", Super)
5144 .Default(0);
5145 }
5146
5147 // Add a special completion for a message send to "super", which fills in the
5148 // most likely case of forwarding all of our arguments to the superclass
5149 // function.
5150 ///
5151 /// \param S The semantic analysis object.
5152 ///
5153 /// \param NeedSuperKeyword Whether we need to prefix this completion with
5154 /// the "super" keyword. Otherwise, we just need to provide the arguments.
5155 ///
5156 /// \param SelIdents The identifiers in the selector that have already been
5157 /// provided as arguments for a send to "super".
5158 ///
5159 /// \param Results The set of results to augment.
5160 ///
5161 /// \returns the Objective-C method declaration that would be invoked by
5162 /// this "super" completion. If NULL, no completion was added.
AddSuperSendCompletion(Sema & S,bool NeedSuperKeyword,ArrayRef<IdentifierInfo * > SelIdents,ResultBuilder & Results)5163 static ObjCMethodDecl *AddSuperSendCompletion(
5164 Sema &S, bool NeedSuperKeyword,
5165 ArrayRef<IdentifierInfo *> SelIdents,
5166 ResultBuilder &Results) {
5167 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
5168 if (!CurMethod)
5169 return 0;
5170
5171 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
5172 if (!Class)
5173 return 0;
5174
5175 // Try to find a superclass method with the same selector.
5176 ObjCMethodDecl *SuperMethod = 0;
5177 while ((Class = Class->getSuperClass()) && !SuperMethod) {
5178 // Check in the class
5179 SuperMethod = Class->getMethod(CurMethod->getSelector(),
5180 CurMethod->isInstanceMethod());
5181
5182 // Check in categories or class extensions.
5183 if (!SuperMethod) {
5184 for (ObjCInterfaceDecl::known_categories_iterator
5185 Cat = Class->known_categories_begin(),
5186 CatEnd = Class->known_categories_end();
5187 Cat != CatEnd; ++Cat) {
5188 if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(),
5189 CurMethod->isInstanceMethod())))
5190 break;
5191 }
5192 }
5193 }
5194
5195 if (!SuperMethod)
5196 return 0;
5197
5198 // Check whether the superclass method has the same signature.
5199 if (CurMethod->param_size() != SuperMethod->param_size() ||
5200 CurMethod->isVariadic() != SuperMethod->isVariadic())
5201 return 0;
5202
5203 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
5204 CurPEnd = CurMethod->param_end(),
5205 SuperP = SuperMethod->param_begin();
5206 CurP != CurPEnd; ++CurP, ++SuperP) {
5207 // Make sure the parameter types are compatible.
5208 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
5209 (*SuperP)->getType()))
5210 return 0;
5211
5212 // Make sure we have a parameter name to forward!
5213 if (!(*CurP)->getIdentifier())
5214 return 0;
5215 }
5216
5217 // We have a superclass method. Now, form the send-to-super completion.
5218 CodeCompletionBuilder Builder(Results.getAllocator(),
5219 Results.getCodeCompletionTUInfo());
5220
5221 // Give this completion a return type.
5222 AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod,
5223 Builder);
5224
5225 // If we need the "super" keyword, add it (plus some spacing).
5226 if (NeedSuperKeyword) {
5227 Builder.AddTypedTextChunk("super");
5228 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5229 }
5230
5231 Selector Sel = CurMethod->getSelector();
5232 if (Sel.isUnarySelector()) {
5233 if (NeedSuperKeyword)
5234 Builder.AddTextChunk(Builder.getAllocator().CopyString(
5235 Sel.getNameForSlot(0)));
5236 else
5237 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
5238 Sel.getNameForSlot(0)));
5239 } else {
5240 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
5241 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
5242 if (I > SelIdents.size())
5243 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5244
5245 if (I < SelIdents.size())
5246 Builder.AddInformativeChunk(
5247 Builder.getAllocator().CopyString(
5248 Sel.getNameForSlot(I) + ":"));
5249 else if (NeedSuperKeyword || I > SelIdents.size()) {
5250 Builder.AddTextChunk(
5251 Builder.getAllocator().CopyString(
5252 Sel.getNameForSlot(I) + ":"));
5253 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
5254 (*CurP)->getIdentifier()->getName()));
5255 } else {
5256 Builder.AddTypedTextChunk(
5257 Builder.getAllocator().CopyString(
5258 Sel.getNameForSlot(I) + ":"));
5259 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
5260 (*CurP)->getIdentifier()->getName()));
5261 }
5262 }
5263 }
5264
5265 Results.AddResult(CodeCompletionResult(Builder.TakeString(), SuperMethod,
5266 CCP_SuperCompletion));
5267 return SuperMethod;
5268 }
5269
CodeCompleteObjCMessageReceiver(Scope * S)5270 void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
5271 typedef CodeCompletionResult Result;
5272 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5273 CodeCompleter->getCodeCompletionTUInfo(),
5274 CodeCompletionContext::CCC_ObjCMessageReceiver,
5275 getLangOpts().CPlusPlus11
5276 ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
5277 : &ResultBuilder::IsObjCMessageReceiver);
5278
5279 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5280 Results.EnterNewScope();
5281 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5282 CodeCompleter->includeGlobals());
5283
5284 // If we are in an Objective-C method inside a class that has a superclass,
5285 // add "super" as an option.
5286 if (ObjCMethodDecl *Method = getCurMethodDecl())
5287 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
5288 if (Iface->getSuperClass()) {
5289 Results.AddResult(Result("super"));
5290
5291 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, None, Results);
5292 }
5293
5294 if (getLangOpts().CPlusPlus11)
5295 addThisCompletion(*this, Results);
5296
5297 Results.ExitScope();
5298
5299 if (CodeCompleter->includeMacros())
5300 AddMacroResults(PP, Results, false);
5301 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5302 Results.data(), Results.size());
5303
5304 }
5305
CodeCompleteObjCSuperMessage(Scope * S,SourceLocation SuperLoc,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression)5306 void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
5307 ArrayRef<IdentifierInfo *> SelIdents,
5308 bool AtArgumentExpression) {
5309 ObjCInterfaceDecl *CDecl = 0;
5310 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
5311 // Figure out which interface we're in.
5312 CDecl = CurMethod->getClassInterface();
5313 if (!CDecl)
5314 return;
5315
5316 // Find the superclass of this class.
5317 CDecl = CDecl->getSuperClass();
5318 if (!CDecl)
5319 return;
5320
5321 if (CurMethod->isInstanceMethod()) {
5322 // We are inside an instance method, which means that the message
5323 // send [super ...] is actually calling an instance method on the
5324 // current object.
5325 return CodeCompleteObjCInstanceMessage(S, 0, SelIdents,
5326 AtArgumentExpression,
5327 CDecl);
5328 }
5329
5330 // Fall through to send to the superclass in CDecl.
5331 } else {
5332 // "super" may be the name of a type or variable. Figure out which
5333 // it is.
5334 IdentifierInfo *Super = getSuperIdentifier();
5335 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
5336 LookupOrdinaryName);
5337 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
5338 // "super" names an interface. Use it.
5339 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
5340 if (const ObjCObjectType *Iface
5341 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
5342 CDecl = Iface->getInterface();
5343 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
5344 // "super" names an unresolved type; we can't be more specific.
5345 } else {
5346 // Assume that "super" names some kind of value and parse that way.
5347 CXXScopeSpec SS;
5348 SourceLocation TemplateKWLoc;
5349 UnqualifiedId id;
5350 id.setIdentifier(Super, SuperLoc);
5351 ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id,
5352 false, false);
5353 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
5354 SelIdents,
5355 AtArgumentExpression);
5356 }
5357
5358 // Fall through
5359 }
5360
5361 ParsedType Receiver;
5362 if (CDecl)
5363 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
5364 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
5365 AtArgumentExpression,
5366 /*IsSuper=*/true);
5367 }
5368
5369 /// \brief Given a set of code-completion results for the argument of a message
5370 /// send, determine the preferred type (if any) for that argument expression.
getPreferredArgumentTypeForMessageSend(ResultBuilder & Results,unsigned NumSelIdents)5371 static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
5372 unsigned NumSelIdents) {
5373 typedef CodeCompletionResult Result;
5374 ASTContext &Context = Results.getSema().Context;
5375
5376 QualType PreferredType;
5377 unsigned BestPriority = CCP_Unlikely * 2;
5378 Result *ResultsData = Results.data();
5379 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
5380 Result &R = ResultsData[I];
5381 if (R.Kind == Result::RK_Declaration &&
5382 isa<ObjCMethodDecl>(R.Declaration)) {
5383 if (R.Priority <= BestPriority) {
5384 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
5385 if (NumSelIdents <= Method->param_size()) {
5386 QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
5387 ->getType();
5388 if (R.Priority < BestPriority || PreferredType.isNull()) {
5389 BestPriority = R.Priority;
5390 PreferredType = MyPreferredType;
5391 } else if (!Context.hasSameUnqualifiedType(PreferredType,
5392 MyPreferredType)) {
5393 PreferredType = QualType();
5394 }
5395 }
5396 }
5397 }
5398 }
5399
5400 return PreferredType;
5401 }
5402
AddClassMessageCompletions(Sema & SemaRef,Scope * S,ParsedType Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,bool IsSuper,ResultBuilder & Results)5403 static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
5404 ParsedType Receiver,
5405 ArrayRef<IdentifierInfo *> SelIdents,
5406 bool AtArgumentExpression,
5407 bool IsSuper,
5408 ResultBuilder &Results) {
5409 typedef CodeCompletionResult Result;
5410 ObjCInterfaceDecl *CDecl = 0;
5411
5412 // If the given name refers to an interface type, retrieve the
5413 // corresponding declaration.
5414 if (Receiver) {
5415 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
5416 if (!T.isNull())
5417 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
5418 CDecl = Interface->getInterface();
5419 }
5420
5421 // Add all of the factory methods in this Objective-C class, its protocols,
5422 // superclasses, categories, implementation, etc.
5423 Results.EnterNewScope();
5424
5425 // If this is a send-to-super, try to add the special "super" send
5426 // completion.
5427 if (IsSuper) {
5428 if (ObjCMethodDecl *SuperMethod
5429 = AddSuperSendCompletion(SemaRef, false, SelIdents, Results))
5430 Results.Ignore(SuperMethod);
5431 }
5432
5433 // If we're inside an Objective-C method definition, prefer its selector to
5434 // others.
5435 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
5436 Results.setPreferredSelector(CurMethod->getSelector());
5437
5438 VisitedSelectorSet Selectors;
5439 if (CDecl)
5440 AddObjCMethods(CDecl, false, MK_Any, SelIdents,
5441 SemaRef.CurContext, Selectors, AtArgumentExpression,
5442 Results);
5443 else {
5444 // We're messaging "id" as a type; provide all class/factory methods.
5445
5446 // If we have an external source, load the entire class method
5447 // pool from the AST file.
5448 if (SemaRef.getExternalSource()) {
5449 for (uint32_t I = 0,
5450 N = SemaRef.getExternalSource()->GetNumExternalSelectors();
5451 I != N; ++I) {
5452 Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I);
5453 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
5454 continue;
5455
5456 SemaRef.ReadMethodPool(Sel);
5457 }
5458 }
5459
5460 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
5461 MEnd = SemaRef.MethodPool.end();
5462 M != MEnd; ++M) {
5463 for (ObjCMethodList *MethList = &M->second.second;
5464 MethList && MethList->Method;
5465 MethList = MethList->getNext()) {
5466 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents))
5467 continue;
5468
5469 Result R(MethList->Method, Results.getBasePriority(MethList->Method),0);
5470 R.StartParameter = SelIdents.size();
5471 R.AllParametersAreInformative = false;
5472 Results.MaybeAddResult(R, SemaRef.CurContext);
5473 }
5474 }
5475 }
5476
5477 Results.ExitScope();
5478 }
5479
CodeCompleteObjCClassMessage(Scope * S,ParsedType Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,bool IsSuper)5480 void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
5481 ArrayRef<IdentifierInfo *> SelIdents,
5482 bool AtArgumentExpression,
5483 bool IsSuper) {
5484
5485 QualType T = this->GetTypeFromParser(Receiver);
5486
5487 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5488 CodeCompleter->getCodeCompletionTUInfo(),
5489 CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage,
5490 T, SelIdents));
5491
5492 AddClassMessageCompletions(*this, S, Receiver, SelIdents,
5493 AtArgumentExpression, IsSuper, Results);
5494
5495 // If we're actually at the argument expression (rather than prior to the
5496 // selector), we're actually performing code completion for an expression.
5497 // Determine whether we have a single, best method. If so, we can
5498 // code-complete the expression using the corresponding parameter type as
5499 // our preferred type, improving completion results.
5500 if (AtArgumentExpression) {
5501 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
5502 SelIdents.size());
5503 if (PreferredType.isNull())
5504 CodeCompleteOrdinaryName(S, PCC_Expression);
5505 else
5506 CodeCompleteExpression(S, PreferredType);
5507 return;
5508 }
5509
5510 HandleCodeCompleteResults(this, CodeCompleter,
5511 Results.getCompletionContext(),
5512 Results.data(), Results.size());
5513 }
5514
CodeCompleteObjCInstanceMessage(Scope * S,Expr * Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,ObjCInterfaceDecl * Super)5515 void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
5516 ArrayRef<IdentifierInfo *> SelIdents,
5517 bool AtArgumentExpression,
5518 ObjCInterfaceDecl *Super) {
5519 typedef CodeCompletionResult Result;
5520
5521 Expr *RecExpr = static_cast<Expr *>(Receiver);
5522
5523 // If necessary, apply function/array conversion to the receiver.
5524 // C99 6.7.5.3p[7,8].
5525 if (RecExpr) {
5526 ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
5527 if (Conv.isInvalid()) // conversion failed. bail.
5528 return;
5529 RecExpr = Conv.take();
5530 }
5531 QualType ReceiverType = RecExpr? RecExpr->getType()
5532 : Super? Context.getObjCObjectPointerType(
5533 Context.getObjCInterfaceType(Super))
5534 : Context.getObjCIdType();
5535
5536 // If we're messaging an expression with type "id" or "Class", check
5537 // whether we know something special about the receiver that allows
5538 // us to assume a more-specific receiver type.
5539 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
5540 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
5541 if (ReceiverType->isObjCClassType())
5542 return CodeCompleteObjCClassMessage(S,
5543 ParsedType::make(Context.getObjCInterfaceType(IFace)),
5544 SelIdents,
5545 AtArgumentExpression, Super);
5546
5547 ReceiverType = Context.getObjCObjectPointerType(
5548 Context.getObjCInterfaceType(IFace));
5549 }
5550
5551 // Build the set of methods we can see.
5552 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5553 CodeCompleter->getCodeCompletionTUInfo(),
5554 CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
5555 ReceiverType, SelIdents));
5556
5557 Results.EnterNewScope();
5558
5559 // If this is a send-to-super, try to add the special "super" send
5560 // completion.
5561 if (Super) {
5562 if (ObjCMethodDecl *SuperMethod
5563 = AddSuperSendCompletion(*this, false, SelIdents, Results))
5564 Results.Ignore(SuperMethod);
5565 }
5566
5567 // If we're inside an Objective-C method definition, prefer its selector to
5568 // others.
5569 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
5570 Results.setPreferredSelector(CurMethod->getSelector());
5571
5572 // Keep track of the selectors we've already added.
5573 VisitedSelectorSet Selectors;
5574
5575 // Handle messages to Class. This really isn't a message to an instance
5576 // method, so we treat it the same way we would treat a message send to a
5577 // class method.
5578 if (ReceiverType->isObjCClassType() ||
5579 ReceiverType->isObjCQualifiedClassType()) {
5580 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
5581 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
5582 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents,
5583 CurContext, Selectors, AtArgumentExpression, Results);
5584 }
5585 }
5586 // Handle messages to a qualified ID ("id<foo>").
5587 else if (const ObjCObjectPointerType *QualID
5588 = ReceiverType->getAsObjCQualifiedIdType()) {
5589 // Search protocols for instance methods.
5590 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
5591 E = QualID->qual_end();
5592 I != E; ++I)
5593 AddObjCMethods(*I, true, MK_Any, SelIdents, CurContext,
5594 Selectors, AtArgumentExpression, Results);
5595 }
5596 // Handle messages to a pointer to interface type.
5597 else if (const ObjCObjectPointerType *IFacePtr
5598 = ReceiverType->getAsObjCInterfacePointerType()) {
5599 // Search the class, its superclasses, etc., for instance methods.
5600 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
5601 CurContext, Selectors, AtArgumentExpression,
5602 Results);
5603
5604 // Search protocols for instance methods.
5605 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
5606 E = IFacePtr->qual_end();
5607 I != E; ++I)
5608 AddObjCMethods(*I, true, MK_Any, SelIdents, CurContext,
5609 Selectors, AtArgumentExpression, Results);
5610 }
5611 // Handle messages to "id".
5612 else if (ReceiverType->isObjCIdType()) {
5613 // We're messaging "id", so provide all instance methods we know
5614 // about as code-completion results.
5615
5616 // If we have an external source, load the entire class method
5617 // pool from the AST file.
5618 if (ExternalSource) {
5619 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5620 I != N; ++I) {
5621 Selector Sel = ExternalSource->GetExternalSelector(I);
5622 if (Sel.isNull() || MethodPool.count(Sel))
5623 continue;
5624
5625 ReadMethodPool(Sel);
5626 }
5627 }
5628
5629 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5630 MEnd = MethodPool.end();
5631 M != MEnd; ++M) {
5632 for (ObjCMethodList *MethList = &M->second.first;
5633 MethList && MethList->Method;
5634 MethList = MethList->getNext()) {
5635 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents))
5636 continue;
5637
5638 if (!Selectors.insert(MethList->Method->getSelector()))
5639 continue;
5640
5641 Result R(MethList->Method, Results.getBasePriority(MethList->Method),0);
5642 R.StartParameter = SelIdents.size();
5643 R.AllParametersAreInformative = false;
5644 Results.MaybeAddResult(R, CurContext);
5645 }
5646 }
5647 }
5648 Results.ExitScope();
5649
5650
5651 // If we're actually at the argument expression (rather than prior to the
5652 // selector), we're actually performing code completion for an expression.
5653 // Determine whether we have a single, best method. If so, we can
5654 // code-complete the expression using the corresponding parameter type as
5655 // our preferred type, improving completion results.
5656 if (AtArgumentExpression) {
5657 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
5658 SelIdents.size());
5659 if (PreferredType.isNull())
5660 CodeCompleteOrdinaryName(S, PCC_Expression);
5661 else
5662 CodeCompleteExpression(S, PreferredType);
5663 return;
5664 }
5665
5666 HandleCodeCompleteResults(this, CodeCompleter,
5667 Results.getCompletionContext(),
5668 Results.data(),Results.size());
5669 }
5670
CodeCompleteObjCForCollection(Scope * S,DeclGroupPtrTy IterationVar)5671 void Sema::CodeCompleteObjCForCollection(Scope *S,
5672 DeclGroupPtrTy IterationVar) {
5673 CodeCompleteExpressionData Data;
5674 Data.ObjCCollection = true;
5675
5676 if (IterationVar.getAsOpaquePtr()) {
5677 DeclGroupRef DG = IterationVar.get();
5678 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
5679 if (*I)
5680 Data.IgnoreDecls.push_back(*I);
5681 }
5682 }
5683
5684 CodeCompleteExpression(S, Data);
5685 }
5686
CodeCompleteObjCSelector(Scope * S,ArrayRef<IdentifierInfo * > SelIdents)5687 void Sema::CodeCompleteObjCSelector(Scope *S,
5688 ArrayRef<IdentifierInfo *> SelIdents) {
5689 // If we have an external source, load the entire class method
5690 // pool from the AST file.
5691 if (ExternalSource) {
5692 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5693 I != N; ++I) {
5694 Selector Sel = ExternalSource->GetExternalSelector(I);
5695 if (Sel.isNull() || MethodPool.count(Sel))
5696 continue;
5697
5698 ReadMethodPool(Sel);
5699 }
5700 }
5701
5702 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5703 CodeCompleter->getCodeCompletionTUInfo(),
5704 CodeCompletionContext::CCC_SelectorName);
5705 Results.EnterNewScope();
5706 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5707 MEnd = MethodPool.end();
5708 M != MEnd; ++M) {
5709
5710 Selector Sel = M->first;
5711 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents))
5712 continue;
5713
5714 CodeCompletionBuilder Builder(Results.getAllocator(),
5715 Results.getCodeCompletionTUInfo());
5716 if (Sel.isUnarySelector()) {
5717 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
5718 Sel.getNameForSlot(0)));
5719 Results.AddResult(Builder.TakeString());
5720 continue;
5721 }
5722
5723 std::string Accumulator;
5724 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
5725 if (I == SelIdents.size()) {
5726 if (!Accumulator.empty()) {
5727 Builder.AddInformativeChunk(Builder.getAllocator().CopyString(
5728 Accumulator));
5729 Accumulator.clear();
5730 }
5731 }
5732
5733 Accumulator += Sel.getNameForSlot(I);
5734 Accumulator += ':';
5735 }
5736 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( Accumulator));
5737 Results.AddResult(Builder.TakeString());
5738 }
5739 Results.ExitScope();
5740
5741 HandleCodeCompleteResults(this, CodeCompleter,
5742 CodeCompletionContext::CCC_SelectorName,
5743 Results.data(), Results.size());
5744 }
5745
5746 /// \brief Add all of the protocol declarations that we find in the given
5747 /// (translation unit) context.
AddProtocolResults(DeclContext * Ctx,DeclContext * CurContext,bool OnlyForwardDeclarations,ResultBuilder & Results)5748 static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
5749 bool OnlyForwardDeclarations,
5750 ResultBuilder &Results) {
5751 typedef CodeCompletionResult Result;
5752
5753 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
5754 DEnd = Ctx->decls_end();
5755 D != DEnd; ++D) {
5756 // Record any protocols we find.
5757 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
5758 if (!OnlyForwardDeclarations || !Proto->hasDefinition())
5759 Results.AddResult(Result(Proto, Results.getBasePriority(Proto), 0),
5760 CurContext, 0, false);
5761 }
5762 }
5763
CodeCompleteObjCProtocolReferences(IdentifierLocPair * Protocols,unsigned NumProtocols)5764 void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
5765 unsigned NumProtocols) {
5766 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5767 CodeCompleter->getCodeCompletionTUInfo(),
5768 CodeCompletionContext::CCC_ObjCProtocolName);
5769
5770 if (CodeCompleter && CodeCompleter->includeGlobals()) {
5771 Results.EnterNewScope();
5772
5773 // Tell the result set to ignore all of the protocols we have
5774 // already seen.
5775 // FIXME: This doesn't work when caching code-completion results.
5776 for (unsigned I = 0; I != NumProtocols; ++I)
5777 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
5778 Protocols[I].second))
5779 Results.Ignore(Protocol);
5780
5781 // Add all protocols.
5782 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
5783 Results);
5784
5785 Results.ExitScope();
5786 }
5787
5788 HandleCodeCompleteResults(this, CodeCompleter,
5789 CodeCompletionContext::CCC_ObjCProtocolName,
5790 Results.data(),Results.size());
5791 }
5792
CodeCompleteObjCProtocolDecl(Scope *)5793 void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
5794 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5795 CodeCompleter->getCodeCompletionTUInfo(),
5796 CodeCompletionContext::CCC_ObjCProtocolName);
5797
5798 if (CodeCompleter && CodeCompleter->includeGlobals()) {
5799 Results.EnterNewScope();
5800
5801 // Add all protocols.
5802 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
5803 Results);
5804
5805 Results.ExitScope();
5806 }
5807
5808 HandleCodeCompleteResults(this, CodeCompleter,
5809 CodeCompletionContext::CCC_ObjCProtocolName,
5810 Results.data(),Results.size());
5811 }
5812
5813 /// \brief Add all of the Objective-C interface declarations that we find in
5814 /// the given (translation unit) context.
AddInterfaceResults(DeclContext * Ctx,DeclContext * CurContext,bool OnlyForwardDeclarations,bool OnlyUnimplemented,ResultBuilder & Results)5815 static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
5816 bool OnlyForwardDeclarations,
5817 bool OnlyUnimplemented,
5818 ResultBuilder &Results) {
5819 typedef CodeCompletionResult Result;
5820
5821 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
5822 DEnd = Ctx->decls_end();
5823 D != DEnd; ++D) {
5824 // Record any interfaces we find.
5825 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
5826 if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
5827 (!OnlyUnimplemented || !Class->getImplementation()))
5828 Results.AddResult(Result(Class, Results.getBasePriority(Class), 0),
5829 CurContext, 0, false);
5830 }
5831 }
5832
CodeCompleteObjCInterfaceDecl(Scope * S)5833 void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
5834 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5835 CodeCompleter->getCodeCompletionTUInfo(),
5836 CodeCompletionContext::CCC_Other);
5837 Results.EnterNewScope();
5838
5839 if (CodeCompleter->includeGlobals()) {
5840 // Add all classes.
5841 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5842 false, Results);
5843 }
5844
5845 Results.ExitScope();
5846
5847 HandleCodeCompleteResults(this, CodeCompleter,
5848 CodeCompletionContext::CCC_ObjCInterfaceName,
5849 Results.data(),Results.size());
5850 }
5851
CodeCompleteObjCSuperclass(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)5852 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
5853 SourceLocation ClassNameLoc) {
5854 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5855 CodeCompleter->getCodeCompletionTUInfo(),
5856 CodeCompletionContext::CCC_ObjCInterfaceName);
5857 Results.EnterNewScope();
5858
5859 // Make sure that we ignore the class we're currently defining.
5860 NamedDecl *CurClass
5861 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
5862 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
5863 Results.Ignore(CurClass);
5864
5865 if (CodeCompleter->includeGlobals()) {
5866 // Add all classes.
5867 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5868 false, Results);
5869 }
5870
5871 Results.ExitScope();
5872
5873 HandleCodeCompleteResults(this, CodeCompleter,
5874 CodeCompletionContext::CCC_ObjCInterfaceName,
5875 Results.data(),Results.size());
5876 }
5877
CodeCompleteObjCImplementationDecl(Scope * S)5878 void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
5879 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5880 CodeCompleter->getCodeCompletionTUInfo(),
5881 CodeCompletionContext::CCC_Other);
5882 Results.EnterNewScope();
5883
5884 if (CodeCompleter->includeGlobals()) {
5885 // Add all unimplemented classes.
5886 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5887 true, Results);
5888 }
5889
5890 Results.ExitScope();
5891
5892 HandleCodeCompleteResults(this, CodeCompleter,
5893 CodeCompletionContext::CCC_ObjCInterfaceName,
5894 Results.data(),Results.size());
5895 }
5896
CodeCompleteObjCInterfaceCategory(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)5897 void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
5898 IdentifierInfo *ClassName,
5899 SourceLocation ClassNameLoc) {
5900 typedef CodeCompletionResult Result;
5901
5902 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5903 CodeCompleter->getCodeCompletionTUInfo(),
5904 CodeCompletionContext::CCC_ObjCCategoryName);
5905
5906 // Ignore any categories we find that have already been implemented by this
5907 // interface.
5908 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5909 NamedDecl *CurClass
5910 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
5911 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)){
5912 for (ObjCInterfaceDecl::visible_categories_iterator
5913 Cat = Class->visible_categories_begin(),
5914 CatEnd = Class->visible_categories_end();
5915 Cat != CatEnd; ++Cat) {
5916 CategoryNames.insert(Cat->getIdentifier());
5917 }
5918 }
5919
5920 // Add all of the categories we know about.
5921 Results.EnterNewScope();
5922 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
5923 for (DeclContext::decl_iterator D = TU->decls_begin(),
5924 DEnd = TU->decls_end();
5925 D != DEnd; ++D)
5926 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
5927 if (CategoryNames.insert(Category->getIdentifier()))
5928 Results.AddResult(Result(Category, Results.getBasePriority(Category),0),
5929 CurContext, 0, false);
5930 Results.ExitScope();
5931
5932 HandleCodeCompleteResults(this, CodeCompleter,
5933 CodeCompletionContext::CCC_ObjCCategoryName,
5934 Results.data(),Results.size());
5935 }
5936
CodeCompleteObjCImplementationCategory(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)5937 void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
5938 IdentifierInfo *ClassName,
5939 SourceLocation ClassNameLoc) {
5940 typedef CodeCompletionResult Result;
5941
5942 // Find the corresponding interface. If we couldn't find the interface, the
5943 // program itself is ill-formed. However, we'll try to be helpful still by
5944 // providing the list of all of the categories we know about.
5945 NamedDecl *CurClass
5946 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
5947 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
5948 if (!Class)
5949 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
5950
5951 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5952 CodeCompleter->getCodeCompletionTUInfo(),
5953 CodeCompletionContext::CCC_ObjCCategoryName);
5954
5955 // Add all of the categories that have have corresponding interface
5956 // declarations in this class and any of its superclasses, except for
5957 // already-implemented categories in the class itself.
5958 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5959 Results.EnterNewScope();
5960 bool IgnoreImplemented = true;
5961 while (Class) {
5962 for (ObjCInterfaceDecl::visible_categories_iterator
5963 Cat = Class->visible_categories_begin(),
5964 CatEnd = Class->visible_categories_end();
5965 Cat != CatEnd; ++Cat) {
5966 if ((!IgnoreImplemented || !Cat->getImplementation()) &&
5967 CategoryNames.insert(Cat->getIdentifier()))
5968 Results.AddResult(Result(*Cat, Results.getBasePriority(*Cat), 0),
5969 CurContext, 0, false);
5970 }
5971
5972 Class = Class->getSuperClass();
5973 IgnoreImplemented = false;
5974 }
5975 Results.ExitScope();
5976
5977 HandleCodeCompleteResults(this, CodeCompleter,
5978 CodeCompletionContext::CCC_ObjCCategoryName,
5979 Results.data(),Results.size());
5980 }
5981
CodeCompleteObjCPropertyDefinition(Scope * S)5982 void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
5983 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5984 CodeCompleter->getCodeCompletionTUInfo(),
5985 CodeCompletionContext::CCC_Other);
5986
5987 // Figure out where this @synthesize lives.
5988 ObjCContainerDecl *Container
5989 = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
5990 if (!Container ||
5991 (!isa<ObjCImplementationDecl>(Container) &&
5992 !isa<ObjCCategoryImplDecl>(Container)))
5993 return;
5994
5995 // Ignore any properties that have already been implemented.
5996 Container = getContainerDef(Container);
5997 for (DeclContext::decl_iterator D = Container->decls_begin(),
5998 DEnd = Container->decls_end();
5999 D != DEnd; ++D)
6000 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
6001 Results.Ignore(PropertyImpl->getPropertyDecl());
6002
6003 // Add any properties that we find.
6004 AddedPropertiesSet AddedProperties;
6005 Results.EnterNewScope();
6006 if (ObjCImplementationDecl *ClassImpl
6007 = dyn_cast<ObjCImplementationDecl>(Container))
6008 AddObjCProperties(ClassImpl->getClassInterface(), false,
6009 /*AllowNullaryMethods=*/false, CurContext,
6010 AddedProperties, Results);
6011 else
6012 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
6013 false, /*AllowNullaryMethods=*/false, CurContext,
6014 AddedProperties, Results);
6015 Results.ExitScope();
6016
6017 HandleCodeCompleteResults(this, CodeCompleter,
6018 CodeCompletionContext::CCC_Other,
6019 Results.data(),Results.size());
6020 }
6021
CodeCompleteObjCPropertySynthesizeIvar(Scope * S,IdentifierInfo * PropertyName)6022 void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
6023 IdentifierInfo *PropertyName) {
6024 typedef CodeCompletionResult Result;
6025 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6026 CodeCompleter->getCodeCompletionTUInfo(),
6027 CodeCompletionContext::CCC_Other);
6028
6029 // Figure out where this @synthesize lives.
6030 ObjCContainerDecl *Container
6031 = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
6032 if (!Container ||
6033 (!isa<ObjCImplementationDecl>(Container) &&
6034 !isa<ObjCCategoryImplDecl>(Container)))
6035 return;
6036
6037 // Figure out which interface we're looking into.
6038 ObjCInterfaceDecl *Class = 0;
6039 if (ObjCImplementationDecl *ClassImpl
6040 = dyn_cast<ObjCImplementationDecl>(Container))
6041 Class = ClassImpl->getClassInterface();
6042 else
6043 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
6044 ->getClassInterface();
6045
6046 // Determine the type of the property we're synthesizing.
6047 QualType PropertyType = Context.getObjCIdType();
6048 if (Class) {
6049 if (ObjCPropertyDecl *Property
6050 = Class->FindPropertyDeclaration(PropertyName)) {
6051 PropertyType
6052 = Property->getType().getNonReferenceType().getUnqualifiedType();
6053
6054 // Give preference to ivars
6055 Results.setPreferredType(PropertyType);
6056 }
6057 }
6058
6059 // Add all of the instance variables in this class and its superclasses.
6060 Results.EnterNewScope();
6061 bool SawSimilarlyNamedIvar = false;
6062 std::string NameWithPrefix;
6063 NameWithPrefix += '_';
6064 NameWithPrefix += PropertyName->getName();
6065 std::string NameWithSuffix = PropertyName->getName().str();
6066 NameWithSuffix += '_';
6067 for(; Class; Class = Class->getSuperClass()) {
6068 for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
6069 Ivar = Ivar->getNextIvar()) {
6070 Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), 0),
6071 CurContext, 0, false);
6072
6073 // Determine whether we've seen an ivar with a name similar to the
6074 // property.
6075 if ((PropertyName == Ivar->getIdentifier() ||
6076 NameWithPrefix == Ivar->getName() ||
6077 NameWithSuffix == Ivar->getName())) {
6078 SawSimilarlyNamedIvar = true;
6079
6080 // Reduce the priority of this result by one, to give it a slight
6081 // advantage over other results whose names don't match so closely.
6082 if (Results.size() &&
6083 Results.data()[Results.size() - 1].Kind
6084 == CodeCompletionResult::RK_Declaration &&
6085 Results.data()[Results.size() - 1].Declaration == Ivar)
6086 Results.data()[Results.size() - 1].Priority--;
6087 }
6088 }
6089 }
6090
6091 if (!SawSimilarlyNamedIvar) {
6092 // Create ivar result _propName, that the user can use to synthesize
6093 // an ivar of the appropriate type.
6094 unsigned Priority = CCP_MemberDeclaration + 1;
6095 typedef CodeCompletionResult Result;
6096 CodeCompletionAllocator &Allocator = Results.getAllocator();
6097 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
6098 Priority,CXAvailability_Available);
6099
6100 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
6101 Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context,
6102 Policy, Allocator));
6103 Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix));
6104 Results.AddResult(Result(Builder.TakeString(), Priority,
6105 CXCursor_ObjCIvarDecl));
6106 }
6107
6108 Results.ExitScope();
6109
6110 HandleCodeCompleteResults(this, CodeCompleter,
6111 CodeCompletionContext::CCC_Other,
6112 Results.data(),Results.size());
6113 }
6114
6115 // Mapping from selectors to the methods that implement that selector, along
6116 // with the "in original class" flag.
6117 typedef llvm::DenseMap<
6118 Selector, llvm::PointerIntPair<ObjCMethodDecl *, 1, bool> > KnownMethodsMap;
6119
6120 /// \brief Find all of the methods that reside in the given container
6121 /// (and its superclasses, protocols, etc.) that meet the given
6122 /// criteria. Insert those methods into the map of known methods,
6123 /// indexed by selector so they can be easily found.
FindImplementableMethods(ASTContext & Context,ObjCContainerDecl * Container,bool WantInstanceMethods,QualType ReturnType,KnownMethodsMap & KnownMethods,bool InOriginalClass=true)6124 static void FindImplementableMethods(ASTContext &Context,
6125 ObjCContainerDecl *Container,
6126 bool WantInstanceMethods,
6127 QualType ReturnType,
6128 KnownMethodsMap &KnownMethods,
6129 bool InOriginalClass = true) {
6130 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
6131 // Make sure we have a definition; that's what we'll walk.
6132 if (!IFace->hasDefinition())
6133 return;
6134
6135 IFace = IFace->getDefinition();
6136 Container = IFace;
6137
6138 const ObjCList<ObjCProtocolDecl> &Protocols
6139 = IFace->getReferencedProtocols();
6140 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6141 E = Protocols.end();
6142 I != E; ++I)
6143 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6144 KnownMethods, InOriginalClass);
6145
6146 // Add methods from any class extensions and categories.
6147 for (ObjCInterfaceDecl::visible_categories_iterator
6148 Cat = IFace->visible_categories_begin(),
6149 CatEnd = IFace->visible_categories_end();
6150 Cat != CatEnd; ++Cat) {
6151 FindImplementableMethods(Context, *Cat, WantInstanceMethods, ReturnType,
6152 KnownMethods, false);
6153 }
6154
6155 // Visit the superclass.
6156 if (IFace->getSuperClass())
6157 FindImplementableMethods(Context, IFace->getSuperClass(),
6158 WantInstanceMethods, ReturnType,
6159 KnownMethods, false);
6160 }
6161
6162 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
6163 // Recurse into protocols.
6164 const ObjCList<ObjCProtocolDecl> &Protocols
6165 = Category->getReferencedProtocols();
6166 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6167 E = Protocols.end();
6168 I != E; ++I)
6169 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6170 KnownMethods, InOriginalClass);
6171
6172 // If this category is the original class, jump to the interface.
6173 if (InOriginalClass && Category->getClassInterface())
6174 FindImplementableMethods(Context, Category->getClassInterface(),
6175 WantInstanceMethods, ReturnType, KnownMethods,
6176 false);
6177 }
6178
6179 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
6180 // Make sure we have a definition; that's what we'll walk.
6181 if (!Protocol->hasDefinition())
6182 return;
6183 Protocol = Protocol->getDefinition();
6184 Container = Protocol;
6185
6186 // Recurse into protocols.
6187 const ObjCList<ObjCProtocolDecl> &Protocols
6188 = Protocol->getReferencedProtocols();
6189 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6190 E = Protocols.end();
6191 I != E; ++I)
6192 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6193 KnownMethods, false);
6194 }
6195
6196 // Add methods in this container. This operation occurs last because
6197 // we want the methods from this container to override any methods
6198 // we've previously seen with the same selector.
6199 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
6200 MEnd = Container->meth_end();
6201 M != MEnd; ++M) {
6202 if (M->isInstanceMethod() == WantInstanceMethods) {
6203 if (!ReturnType.isNull() &&
6204 !Context.hasSameUnqualifiedType(ReturnType, M->getResultType()))
6205 continue;
6206
6207 KnownMethods[M->getSelector()] =
6208 KnownMethodsMap::mapped_type(*M, InOriginalClass);
6209 }
6210 }
6211 }
6212
6213 /// \brief Add the parenthesized return or parameter type chunk to a code
6214 /// completion string.
AddObjCPassingTypeChunk(QualType Type,unsigned ObjCDeclQuals,ASTContext & Context,const PrintingPolicy & Policy,CodeCompletionBuilder & Builder)6215 static void AddObjCPassingTypeChunk(QualType Type,
6216 unsigned ObjCDeclQuals,
6217 ASTContext &Context,
6218 const PrintingPolicy &Policy,
6219 CodeCompletionBuilder &Builder) {
6220 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6221 std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals);
6222 if (!Quals.empty())
6223 Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals));
6224 Builder.AddTextChunk(GetCompletionTypeString(Type, Context, Policy,
6225 Builder.getAllocator()));
6226 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6227 }
6228
6229 /// \brief Determine whether the given class is or inherits from a class by
6230 /// the given name.
InheritsFromClassNamed(ObjCInterfaceDecl * Class,StringRef Name)6231 static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class,
6232 StringRef Name) {
6233 if (!Class)
6234 return false;
6235
6236 if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name)
6237 return true;
6238
6239 return InheritsFromClassNamed(Class->getSuperClass(), Name);
6240 }
6241
6242 /// \brief Add code completions for Objective-C Key-Value Coding (KVC) and
6243 /// Key-Value Observing (KVO).
AddObjCKeyValueCompletions(ObjCPropertyDecl * Property,bool IsInstanceMethod,QualType ReturnType,ASTContext & Context,VisitedSelectorSet & KnownSelectors,ResultBuilder & Results)6244 static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
6245 bool IsInstanceMethod,
6246 QualType ReturnType,
6247 ASTContext &Context,
6248 VisitedSelectorSet &KnownSelectors,
6249 ResultBuilder &Results) {
6250 IdentifierInfo *PropName = Property->getIdentifier();
6251 if (!PropName || PropName->getLength() == 0)
6252 return;
6253
6254 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
6255
6256 // Builder that will create each code completion.
6257 typedef CodeCompletionResult Result;
6258 CodeCompletionAllocator &Allocator = Results.getAllocator();
6259 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
6260
6261 // The selector table.
6262 SelectorTable &Selectors = Context.Selectors;
6263
6264 // The property name, copied into the code completion allocation region
6265 // on demand.
6266 struct KeyHolder {
6267 CodeCompletionAllocator &Allocator;
6268 StringRef Key;
6269 const char *CopiedKey;
6270
6271 KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
6272 : Allocator(Allocator), Key(Key), CopiedKey(0) { }
6273
6274 operator const char *() {
6275 if (CopiedKey)
6276 return CopiedKey;
6277
6278 return CopiedKey = Allocator.CopyString(Key);
6279 }
6280 } Key(Allocator, PropName->getName());
6281
6282 // The uppercased name of the property name.
6283 std::string UpperKey = PropName->getName();
6284 if (!UpperKey.empty())
6285 UpperKey[0] = toUppercase(UpperKey[0]);
6286
6287 bool ReturnTypeMatchesProperty = ReturnType.isNull() ||
6288 Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(),
6289 Property->getType());
6290 bool ReturnTypeMatchesVoid
6291 = ReturnType.isNull() || ReturnType->isVoidType();
6292
6293 // Add the normal accessor -(type)key.
6294 if (IsInstanceMethod &&
6295 KnownSelectors.insert(Selectors.getNullarySelector(PropName)) &&
6296 ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {
6297 if (ReturnType.isNull())
6298 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0,
6299 Context, Policy, Builder);
6300
6301 Builder.AddTypedTextChunk(Key);
6302 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6303 CXCursor_ObjCInstanceMethodDecl));
6304 }
6305
6306 // If we have an integral or boolean property (or the user has provided
6307 // an integral or boolean return type), add the accessor -(type)isKey.
6308 if (IsInstanceMethod &&
6309 ((!ReturnType.isNull() &&
6310 (ReturnType->isIntegerType() || ReturnType->isBooleanType())) ||
6311 (ReturnType.isNull() &&
6312 (Property->getType()->isIntegerType() ||
6313 Property->getType()->isBooleanType())))) {
6314 std::string SelectorName = (Twine("is") + UpperKey).str();
6315 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6316 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6317 if (ReturnType.isNull()) {
6318 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6319 Builder.AddTextChunk("BOOL");
6320 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6321 }
6322
6323 Builder.AddTypedTextChunk(
6324 Allocator.CopyString(SelectorId->getName()));
6325 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6326 CXCursor_ObjCInstanceMethodDecl));
6327 }
6328 }
6329
6330 // Add the normal mutator.
6331 if (IsInstanceMethod && ReturnTypeMatchesVoid &&
6332 !Property->getSetterMethodDecl()) {
6333 std::string SelectorName = (Twine("set") + UpperKey).str();
6334 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6335 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6336 if (ReturnType.isNull()) {
6337 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6338 Builder.AddTextChunk("void");
6339 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6340 }
6341
6342 Builder.AddTypedTextChunk(
6343 Allocator.CopyString(SelectorId->getName()));
6344 Builder.AddTypedTextChunk(":");
6345 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0,
6346 Context, Policy, Builder);
6347 Builder.AddTextChunk(Key);
6348 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6349 CXCursor_ObjCInstanceMethodDecl));
6350 }
6351 }
6352
6353 // Indexed and unordered accessors
6354 unsigned IndexedGetterPriority = CCP_CodePattern;
6355 unsigned IndexedSetterPriority = CCP_CodePattern;
6356 unsigned UnorderedGetterPriority = CCP_CodePattern;
6357 unsigned UnorderedSetterPriority = CCP_CodePattern;
6358 if (const ObjCObjectPointerType *ObjCPointer
6359 = Property->getType()->getAs<ObjCObjectPointerType>()) {
6360 if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) {
6361 // If this interface type is not provably derived from a known
6362 // collection, penalize the corresponding completions.
6363 if (!InheritsFromClassNamed(IFace, "NSMutableArray")) {
6364 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
6365 if (!InheritsFromClassNamed(IFace, "NSArray"))
6366 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
6367 }
6368
6369 if (!InheritsFromClassNamed(IFace, "NSMutableSet")) {
6370 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
6371 if (!InheritsFromClassNamed(IFace, "NSSet"))
6372 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
6373 }
6374 }
6375 } else {
6376 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
6377 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
6378 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
6379 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
6380 }
6381
6382 // Add -(NSUInteger)countOf<key>
6383 if (IsInstanceMethod &&
6384 (ReturnType.isNull() || ReturnType->isIntegerType())) {
6385 std::string SelectorName = (Twine("countOf") + UpperKey).str();
6386 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6387 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6388 if (ReturnType.isNull()) {
6389 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6390 Builder.AddTextChunk("NSUInteger");
6391 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6392 }
6393
6394 Builder.AddTypedTextChunk(
6395 Allocator.CopyString(SelectorId->getName()));
6396 Results.AddResult(Result(Builder.TakeString(),
6397 std::min(IndexedGetterPriority,
6398 UnorderedGetterPriority),
6399 CXCursor_ObjCInstanceMethodDecl));
6400 }
6401 }
6402
6403 // Indexed getters
6404 // Add -(id)objectInKeyAtIndex:(NSUInteger)index
6405 if (IsInstanceMethod &&
6406 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
6407 std::string SelectorName
6408 = (Twine("objectIn") + UpperKey + "AtIndex").str();
6409 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6410 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6411 if (ReturnType.isNull()) {
6412 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6413 Builder.AddTextChunk("id");
6414 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6415 }
6416
6417 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6418 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6419 Builder.AddTextChunk("NSUInteger");
6420 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6421 Builder.AddTextChunk("index");
6422 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6423 CXCursor_ObjCInstanceMethodDecl));
6424 }
6425 }
6426
6427 // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes
6428 if (IsInstanceMethod &&
6429 (ReturnType.isNull() ||
6430 (ReturnType->isObjCObjectPointerType() &&
6431 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6432 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6433 ->getName() == "NSArray"))) {
6434 std::string SelectorName
6435 = (Twine(Property->getName()) + "AtIndexes").str();
6436 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6437 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6438 if (ReturnType.isNull()) {
6439 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6440 Builder.AddTextChunk("NSArray *");
6441 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6442 }
6443
6444 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6445 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6446 Builder.AddTextChunk("NSIndexSet *");
6447 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6448 Builder.AddTextChunk("indexes");
6449 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6450 CXCursor_ObjCInstanceMethodDecl));
6451 }
6452 }
6453
6454 // Add -(void)getKey:(type **)buffer range:(NSRange)inRange
6455 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6456 std::string SelectorName = (Twine("get") + UpperKey).str();
6457 IdentifierInfo *SelectorIds[2] = {
6458 &Context.Idents.get(SelectorName),
6459 &Context.Idents.get("range")
6460 };
6461
6462 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6463 if (ReturnType.isNull()) {
6464 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6465 Builder.AddTextChunk("void");
6466 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6467 }
6468
6469 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6470 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6471 Builder.AddPlaceholderChunk("object-type");
6472 Builder.AddTextChunk(" **");
6473 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6474 Builder.AddTextChunk("buffer");
6475 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6476 Builder.AddTypedTextChunk("range:");
6477 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6478 Builder.AddTextChunk("NSRange");
6479 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6480 Builder.AddTextChunk("inRange");
6481 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6482 CXCursor_ObjCInstanceMethodDecl));
6483 }
6484 }
6485
6486 // Mutable indexed accessors
6487
6488 // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index
6489 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6490 std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str();
6491 IdentifierInfo *SelectorIds[2] = {
6492 &Context.Idents.get("insertObject"),
6493 &Context.Idents.get(SelectorName)
6494 };
6495
6496 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6497 if (ReturnType.isNull()) {
6498 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6499 Builder.AddTextChunk("void");
6500 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6501 }
6502
6503 Builder.AddTypedTextChunk("insertObject:");
6504 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6505 Builder.AddPlaceholderChunk("object-type");
6506 Builder.AddTextChunk(" *");
6507 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6508 Builder.AddTextChunk("object");
6509 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6510 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6511 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6512 Builder.AddPlaceholderChunk("NSUInteger");
6513 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6514 Builder.AddTextChunk("index");
6515 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6516 CXCursor_ObjCInstanceMethodDecl));
6517 }
6518 }
6519
6520 // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes
6521 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6522 std::string SelectorName = (Twine("insert") + UpperKey).str();
6523 IdentifierInfo *SelectorIds[2] = {
6524 &Context.Idents.get(SelectorName),
6525 &Context.Idents.get("atIndexes")
6526 };
6527
6528 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6529 if (ReturnType.isNull()) {
6530 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6531 Builder.AddTextChunk("void");
6532 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6533 }
6534
6535 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6536 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6537 Builder.AddTextChunk("NSArray *");
6538 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6539 Builder.AddTextChunk("array");
6540 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6541 Builder.AddTypedTextChunk("atIndexes:");
6542 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6543 Builder.AddPlaceholderChunk("NSIndexSet *");
6544 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6545 Builder.AddTextChunk("indexes");
6546 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6547 CXCursor_ObjCInstanceMethodDecl));
6548 }
6549 }
6550
6551 // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index
6552 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6553 std::string SelectorName
6554 = (Twine("removeObjectFrom") + UpperKey + "AtIndex").str();
6555 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6556 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6557 if (ReturnType.isNull()) {
6558 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6559 Builder.AddTextChunk("void");
6560 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6561 }
6562
6563 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6564 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6565 Builder.AddTextChunk("NSUInteger");
6566 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6567 Builder.AddTextChunk("index");
6568 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6569 CXCursor_ObjCInstanceMethodDecl));
6570 }
6571 }
6572
6573 // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes
6574 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6575 std::string SelectorName
6576 = (Twine("remove") + UpperKey + "AtIndexes").str();
6577 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6578 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6579 if (ReturnType.isNull()) {
6580 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6581 Builder.AddTextChunk("void");
6582 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6583 }
6584
6585 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6586 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6587 Builder.AddTextChunk("NSIndexSet *");
6588 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6589 Builder.AddTextChunk("indexes");
6590 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6591 CXCursor_ObjCInstanceMethodDecl));
6592 }
6593 }
6594
6595 // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object
6596 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6597 std::string SelectorName
6598 = (Twine("replaceObjectIn") + UpperKey + "AtIndex").str();
6599 IdentifierInfo *SelectorIds[2] = {
6600 &Context.Idents.get(SelectorName),
6601 &Context.Idents.get("withObject")
6602 };
6603
6604 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6605 if (ReturnType.isNull()) {
6606 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6607 Builder.AddTextChunk("void");
6608 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6609 }
6610
6611 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6612 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6613 Builder.AddPlaceholderChunk("NSUInteger");
6614 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6615 Builder.AddTextChunk("index");
6616 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6617 Builder.AddTypedTextChunk("withObject:");
6618 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6619 Builder.AddTextChunk("id");
6620 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6621 Builder.AddTextChunk("object");
6622 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6623 CXCursor_ObjCInstanceMethodDecl));
6624 }
6625 }
6626
6627 // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array
6628 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6629 std::string SelectorName1
6630 = (Twine("replace") + UpperKey + "AtIndexes").str();
6631 std::string SelectorName2 = (Twine("with") + UpperKey).str();
6632 IdentifierInfo *SelectorIds[2] = {
6633 &Context.Idents.get(SelectorName1),
6634 &Context.Idents.get(SelectorName2)
6635 };
6636
6637 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6638 if (ReturnType.isNull()) {
6639 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6640 Builder.AddTextChunk("void");
6641 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6642 }
6643
6644 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":"));
6645 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6646 Builder.AddPlaceholderChunk("NSIndexSet *");
6647 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6648 Builder.AddTextChunk("indexes");
6649 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6650 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":"));
6651 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6652 Builder.AddTextChunk("NSArray *");
6653 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6654 Builder.AddTextChunk("array");
6655 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6656 CXCursor_ObjCInstanceMethodDecl));
6657 }
6658 }
6659
6660 // Unordered getters
6661 // - (NSEnumerator *)enumeratorOfKey
6662 if (IsInstanceMethod &&
6663 (ReturnType.isNull() ||
6664 (ReturnType->isObjCObjectPointerType() &&
6665 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6666 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6667 ->getName() == "NSEnumerator"))) {
6668 std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();
6669 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6670 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6671 if (ReturnType.isNull()) {
6672 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6673 Builder.AddTextChunk("NSEnumerator *");
6674 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6675 }
6676
6677 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6678 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
6679 CXCursor_ObjCInstanceMethodDecl));
6680 }
6681 }
6682
6683 // - (type *)memberOfKey:(type *)object
6684 if (IsInstanceMethod &&
6685 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
6686 std::string SelectorName = (Twine("memberOf") + UpperKey).str();
6687 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6688 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6689 if (ReturnType.isNull()) {
6690 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6691 Builder.AddPlaceholderChunk("object-type");
6692 Builder.AddTextChunk(" *");
6693 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6694 }
6695
6696 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6697 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6698 if (ReturnType.isNull()) {
6699 Builder.AddPlaceholderChunk("object-type");
6700 Builder.AddTextChunk(" *");
6701 } else {
6702 Builder.AddTextChunk(GetCompletionTypeString(ReturnType, Context,
6703 Policy,
6704 Builder.getAllocator()));
6705 }
6706 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6707 Builder.AddTextChunk("object");
6708 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
6709 CXCursor_ObjCInstanceMethodDecl));
6710 }
6711 }
6712
6713 // Mutable unordered accessors
6714 // - (void)addKeyObject:(type *)object
6715 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6716 std::string SelectorName
6717 = (Twine("add") + UpperKey + Twine("Object")).str();
6718 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6719 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6720 if (ReturnType.isNull()) {
6721 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6722 Builder.AddTextChunk("void");
6723 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6724 }
6725
6726 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6727 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6728 Builder.AddPlaceholderChunk("object-type");
6729 Builder.AddTextChunk(" *");
6730 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6731 Builder.AddTextChunk("object");
6732 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6733 CXCursor_ObjCInstanceMethodDecl));
6734 }
6735 }
6736
6737 // - (void)addKey:(NSSet *)objects
6738 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6739 std::string SelectorName = (Twine("add") + UpperKey).str();
6740 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6741 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6742 if (ReturnType.isNull()) {
6743 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6744 Builder.AddTextChunk("void");
6745 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6746 }
6747
6748 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6749 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6750 Builder.AddTextChunk("NSSet *");
6751 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6752 Builder.AddTextChunk("objects");
6753 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6754 CXCursor_ObjCInstanceMethodDecl));
6755 }
6756 }
6757
6758 // - (void)removeKeyObject:(type *)object
6759 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6760 std::string SelectorName
6761 = (Twine("remove") + UpperKey + Twine("Object")).str();
6762 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6763 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6764 if (ReturnType.isNull()) {
6765 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6766 Builder.AddTextChunk("void");
6767 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6768 }
6769
6770 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6771 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6772 Builder.AddPlaceholderChunk("object-type");
6773 Builder.AddTextChunk(" *");
6774 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6775 Builder.AddTextChunk("object");
6776 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6777 CXCursor_ObjCInstanceMethodDecl));
6778 }
6779 }
6780
6781 // - (void)removeKey:(NSSet *)objects
6782 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6783 std::string SelectorName = (Twine("remove") + UpperKey).str();
6784 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6785 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6786 if (ReturnType.isNull()) {
6787 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6788 Builder.AddTextChunk("void");
6789 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6790 }
6791
6792 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6793 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6794 Builder.AddTextChunk("NSSet *");
6795 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6796 Builder.AddTextChunk("objects");
6797 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6798 CXCursor_ObjCInstanceMethodDecl));
6799 }
6800 }
6801
6802 // - (void)intersectKey:(NSSet *)objects
6803 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6804 std::string SelectorName = (Twine("intersect") + UpperKey).str();
6805 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6806 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6807 if (ReturnType.isNull()) {
6808 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6809 Builder.AddTextChunk("void");
6810 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6811 }
6812
6813 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6814 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6815 Builder.AddTextChunk("NSSet *");
6816 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6817 Builder.AddTextChunk("objects");
6818 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6819 CXCursor_ObjCInstanceMethodDecl));
6820 }
6821 }
6822
6823 // Key-Value Observing
6824 // + (NSSet *)keyPathsForValuesAffectingKey
6825 if (!IsInstanceMethod &&
6826 (ReturnType.isNull() ||
6827 (ReturnType->isObjCObjectPointerType() &&
6828 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6829 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6830 ->getName() == "NSSet"))) {
6831 std::string SelectorName
6832 = (Twine("keyPathsForValuesAffecting") + UpperKey).str();
6833 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6834 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6835 if (ReturnType.isNull()) {
6836 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6837 Builder.AddTextChunk("NSSet *");
6838 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6839 }
6840
6841 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6842 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6843 CXCursor_ObjCClassMethodDecl));
6844 }
6845 }
6846
6847 // + (BOOL)automaticallyNotifiesObserversForKey
6848 if (!IsInstanceMethod &&
6849 (ReturnType.isNull() ||
6850 ReturnType->isIntegerType() ||
6851 ReturnType->isBooleanType())) {
6852 std::string SelectorName
6853 = (Twine("automaticallyNotifiesObserversOf") + UpperKey).str();
6854 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6855 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6856 if (ReturnType.isNull()) {
6857 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6858 Builder.AddTextChunk("BOOL");
6859 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6860 }
6861
6862 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6863 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6864 CXCursor_ObjCClassMethodDecl));
6865 }
6866 }
6867 }
6868
CodeCompleteObjCMethodDecl(Scope * S,bool IsInstanceMethod,ParsedType ReturnTy)6869 void Sema::CodeCompleteObjCMethodDecl(Scope *S,
6870 bool IsInstanceMethod,
6871 ParsedType ReturnTy) {
6872 // Determine the return type of the method we're declaring, if
6873 // provided.
6874 QualType ReturnType = GetTypeFromParser(ReturnTy);
6875 Decl *IDecl = 0;
6876 if (CurContext->isObjCContainer()) {
6877 ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
6878 IDecl = cast<Decl>(OCD);
6879 }
6880 // Determine where we should start searching for methods.
6881 ObjCContainerDecl *SearchDecl = 0;
6882 bool IsInImplementation = false;
6883 if (Decl *D = IDecl) {
6884 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
6885 SearchDecl = Impl->getClassInterface();
6886 IsInImplementation = true;
6887 } else if (ObjCCategoryImplDecl *CatImpl
6888 = dyn_cast<ObjCCategoryImplDecl>(D)) {
6889 SearchDecl = CatImpl->getCategoryDecl();
6890 IsInImplementation = true;
6891 } else
6892 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
6893 }
6894
6895 if (!SearchDecl && S) {
6896 if (DeclContext *DC = S->getEntity())
6897 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
6898 }
6899
6900 if (!SearchDecl) {
6901 HandleCodeCompleteResults(this, CodeCompleter,
6902 CodeCompletionContext::CCC_Other,
6903 0, 0);
6904 return;
6905 }
6906
6907 // Find all of the methods that we could declare/implement here.
6908 KnownMethodsMap KnownMethods;
6909 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
6910 ReturnType, KnownMethods);
6911
6912 // Add declarations or definitions for each of the known methods.
6913 typedef CodeCompletionResult Result;
6914 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6915 CodeCompleter->getCodeCompletionTUInfo(),
6916 CodeCompletionContext::CCC_Other);
6917 Results.EnterNewScope();
6918 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
6919 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
6920 MEnd = KnownMethods.end();
6921 M != MEnd; ++M) {
6922 ObjCMethodDecl *Method = M->second.getPointer();
6923 CodeCompletionBuilder Builder(Results.getAllocator(),
6924 Results.getCodeCompletionTUInfo());
6925
6926 // If the result type was not already provided, add it to the
6927 // pattern as (type).
6928 if (ReturnType.isNull())
6929 AddObjCPassingTypeChunk(Method->getResultType(),
6930 Method->getObjCDeclQualifier(),
6931 Context, Policy,
6932 Builder);
6933
6934 Selector Sel = Method->getSelector();
6935
6936 // Add the first part of the selector to the pattern.
6937 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
6938 Sel.getNameForSlot(0)));
6939
6940 // Add parameters to the pattern.
6941 unsigned I = 0;
6942 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
6943 PEnd = Method->param_end();
6944 P != PEnd; (void)++P, ++I) {
6945 // Add the part of the selector name.
6946 if (I == 0)
6947 Builder.AddTypedTextChunk(":");
6948 else if (I < Sel.getNumArgs()) {
6949 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6950 Builder.AddTypedTextChunk(
6951 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
6952 } else
6953 break;
6954
6955 // Add the parameter type.
6956 AddObjCPassingTypeChunk((*P)->getOriginalType(),
6957 (*P)->getObjCDeclQualifier(),
6958 Context, Policy,
6959 Builder);
6960
6961 if (IdentifierInfo *Id = (*P)->getIdentifier())
6962 Builder.AddTextChunk(Builder.getAllocator().CopyString( Id->getName()));
6963 }
6964
6965 if (Method->isVariadic()) {
6966 if (Method->param_size() > 0)
6967 Builder.AddChunk(CodeCompletionString::CK_Comma);
6968 Builder.AddTextChunk("...");
6969 }
6970
6971 if (IsInImplementation && Results.includeCodePatterns()) {
6972 // We will be defining the method here, so add a compound statement.
6973 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6974 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
6975 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6976 if (!Method->getResultType()->isVoidType()) {
6977 // If the result type is not void, add a return clause.
6978 Builder.AddTextChunk("return");
6979 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6980 Builder.AddPlaceholderChunk("expression");
6981 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
6982 } else
6983 Builder.AddPlaceholderChunk("statements");
6984
6985 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6986 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
6987 }
6988
6989 unsigned Priority = CCP_CodePattern;
6990 if (!M->second.getInt())
6991 Priority += CCD_InBaseClass;
6992
6993 Results.AddResult(Result(Builder.TakeString(), Method, Priority));
6994 }
6995
6996 // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
6997 // the properties in this class and its categories.
6998 if (Context.getLangOpts().ObjC2) {
6999 SmallVector<ObjCContainerDecl *, 4> Containers;
7000 Containers.push_back(SearchDecl);
7001
7002 VisitedSelectorSet KnownSelectors;
7003 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
7004 MEnd = KnownMethods.end();
7005 M != MEnd; ++M)
7006 KnownSelectors.insert(M->first);
7007
7008
7009 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl);
7010 if (!IFace)
7011 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl))
7012 IFace = Category->getClassInterface();
7013
7014 if (IFace) {
7015 for (ObjCInterfaceDecl::visible_categories_iterator
7016 Cat = IFace->visible_categories_begin(),
7017 CatEnd = IFace->visible_categories_end();
7018 Cat != CatEnd; ++Cat) {
7019 Containers.push_back(*Cat);
7020 }
7021 }
7022
7023 for (unsigned I = 0, N = Containers.size(); I != N; ++I) {
7024 for (ObjCContainerDecl::prop_iterator P = Containers[I]->prop_begin(),
7025 PEnd = Containers[I]->prop_end();
7026 P != PEnd; ++P) {
7027 AddObjCKeyValueCompletions(*P, IsInstanceMethod, ReturnType, Context,
7028 KnownSelectors, Results);
7029 }
7030 }
7031 }
7032
7033 Results.ExitScope();
7034
7035 HandleCodeCompleteResults(this, CodeCompleter,
7036 CodeCompletionContext::CCC_Other,
7037 Results.data(),Results.size());
7038 }
7039
CodeCompleteObjCMethodDeclSelector(Scope * S,bool IsInstanceMethod,bool AtParameterName,ParsedType ReturnTy,ArrayRef<IdentifierInfo * > SelIdents)7040 void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
7041 bool IsInstanceMethod,
7042 bool AtParameterName,
7043 ParsedType ReturnTy,
7044 ArrayRef<IdentifierInfo *> SelIdents) {
7045 // If we have an external source, load the entire class method
7046 // pool from the AST file.
7047 if (ExternalSource) {
7048 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
7049 I != N; ++I) {
7050 Selector Sel = ExternalSource->GetExternalSelector(I);
7051 if (Sel.isNull() || MethodPool.count(Sel))
7052 continue;
7053
7054 ReadMethodPool(Sel);
7055 }
7056 }
7057
7058 // Build the set of methods we can see.
7059 typedef CodeCompletionResult Result;
7060 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7061 CodeCompleter->getCodeCompletionTUInfo(),
7062 CodeCompletionContext::CCC_Other);
7063
7064 if (ReturnTy)
7065 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
7066
7067 Results.EnterNewScope();
7068 for (GlobalMethodPool::iterator M = MethodPool.begin(),
7069 MEnd = MethodPool.end();
7070 M != MEnd; ++M) {
7071 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
7072 &M->second.second;
7073 MethList && MethList->Method;
7074 MethList = MethList->getNext()) {
7075 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents))
7076 continue;
7077
7078 if (AtParameterName) {
7079 // Suggest parameter names we've seen before.
7080 unsigned NumSelIdents = SelIdents.size();
7081 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
7082 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
7083 if (Param->getIdentifier()) {
7084 CodeCompletionBuilder Builder(Results.getAllocator(),
7085 Results.getCodeCompletionTUInfo());
7086 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
7087 Param->getIdentifier()->getName()));
7088 Results.AddResult(Builder.TakeString());
7089 }
7090 }
7091
7092 continue;
7093 }
7094
7095 Result R(MethList->Method, Results.getBasePriority(MethList->Method), 0);
7096 R.StartParameter = SelIdents.size();
7097 R.AllParametersAreInformative = false;
7098 R.DeclaringEntity = true;
7099 Results.MaybeAddResult(R, CurContext);
7100 }
7101 }
7102
7103 Results.ExitScope();
7104 HandleCodeCompleteResults(this, CodeCompleter,
7105 CodeCompletionContext::CCC_Other,
7106 Results.data(),Results.size());
7107 }
7108
CodeCompletePreprocessorDirective(bool InConditional)7109 void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
7110 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7111 CodeCompleter->getCodeCompletionTUInfo(),
7112 CodeCompletionContext::CCC_PreprocessorDirective);
7113 Results.EnterNewScope();
7114
7115 // #if <condition>
7116 CodeCompletionBuilder Builder(Results.getAllocator(),
7117 Results.getCodeCompletionTUInfo());
7118 Builder.AddTypedTextChunk("if");
7119 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7120 Builder.AddPlaceholderChunk("condition");
7121 Results.AddResult(Builder.TakeString());
7122
7123 // #ifdef <macro>
7124 Builder.AddTypedTextChunk("ifdef");
7125 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7126 Builder.AddPlaceholderChunk("macro");
7127 Results.AddResult(Builder.TakeString());
7128
7129 // #ifndef <macro>
7130 Builder.AddTypedTextChunk("ifndef");
7131 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7132 Builder.AddPlaceholderChunk("macro");
7133 Results.AddResult(Builder.TakeString());
7134
7135 if (InConditional) {
7136 // #elif <condition>
7137 Builder.AddTypedTextChunk("elif");
7138 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7139 Builder.AddPlaceholderChunk("condition");
7140 Results.AddResult(Builder.TakeString());
7141
7142 // #else
7143 Builder.AddTypedTextChunk("else");
7144 Results.AddResult(Builder.TakeString());
7145
7146 // #endif
7147 Builder.AddTypedTextChunk("endif");
7148 Results.AddResult(Builder.TakeString());
7149 }
7150
7151 // #include "header"
7152 Builder.AddTypedTextChunk("include");
7153 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7154 Builder.AddTextChunk("\"");
7155 Builder.AddPlaceholderChunk("header");
7156 Builder.AddTextChunk("\"");
7157 Results.AddResult(Builder.TakeString());
7158
7159 // #include <header>
7160 Builder.AddTypedTextChunk("include");
7161 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7162 Builder.AddTextChunk("<");
7163 Builder.AddPlaceholderChunk("header");
7164 Builder.AddTextChunk(">");
7165 Results.AddResult(Builder.TakeString());
7166
7167 // #define <macro>
7168 Builder.AddTypedTextChunk("define");
7169 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7170 Builder.AddPlaceholderChunk("macro");
7171 Results.AddResult(Builder.TakeString());
7172
7173 // #define <macro>(<args>)
7174 Builder.AddTypedTextChunk("define");
7175 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7176 Builder.AddPlaceholderChunk("macro");
7177 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7178 Builder.AddPlaceholderChunk("args");
7179 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7180 Results.AddResult(Builder.TakeString());
7181
7182 // #undef <macro>
7183 Builder.AddTypedTextChunk("undef");
7184 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7185 Builder.AddPlaceholderChunk("macro");
7186 Results.AddResult(Builder.TakeString());
7187
7188 // #line <number>
7189 Builder.AddTypedTextChunk("line");
7190 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7191 Builder.AddPlaceholderChunk("number");
7192 Results.AddResult(Builder.TakeString());
7193
7194 // #line <number> "filename"
7195 Builder.AddTypedTextChunk("line");
7196 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7197 Builder.AddPlaceholderChunk("number");
7198 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7199 Builder.AddTextChunk("\"");
7200 Builder.AddPlaceholderChunk("filename");
7201 Builder.AddTextChunk("\"");
7202 Results.AddResult(Builder.TakeString());
7203
7204 // #error <message>
7205 Builder.AddTypedTextChunk("error");
7206 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7207 Builder.AddPlaceholderChunk("message");
7208 Results.AddResult(Builder.TakeString());
7209
7210 // #pragma <arguments>
7211 Builder.AddTypedTextChunk("pragma");
7212 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7213 Builder.AddPlaceholderChunk("arguments");
7214 Results.AddResult(Builder.TakeString());
7215
7216 if (getLangOpts().ObjC1) {
7217 // #import "header"
7218 Builder.AddTypedTextChunk("import");
7219 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7220 Builder.AddTextChunk("\"");
7221 Builder.AddPlaceholderChunk("header");
7222 Builder.AddTextChunk("\"");
7223 Results.AddResult(Builder.TakeString());
7224
7225 // #import <header>
7226 Builder.AddTypedTextChunk("import");
7227 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7228 Builder.AddTextChunk("<");
7229 Builder.AddPlaceholderChunk("header");
7230 Builder.AddTextChunk(">");
7231 Results.AddResult(Builder.TakeString());
7232 }
7233
7234 // #include_next "header"
7235 Builder.AddTypedTextChunk("include_next");
7236 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7237 Builder.AddTextChunk("\"");
7238 Builder.AddPlaceholderChunk("header");
7239 Builder.AddTextChunk("\"");
7240 Results.AddResult(Builder.TakeString());
7241
7242 // #include_next <header>
7243 Builder.AddTypedTextChunk("include_next");
7244 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7245 Builder.AddTextChunk("<");
7246 Builder.AddPlaceholderChunk("header");
7247 Builder.AddTextChunk(">");
7248 Results.AddResult(Builder.TakeString());
7249
7250 // #warning <message>
7251 Builder.AddTypedTextChunk("warning");
7252 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7253 Builder.AddPlaceholderChunk("message");
7254 Results.AddResult(Builder.TakeString());
7255
7256 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
7257 // completions for them. And __include_macros is a Clang-internal extension
7258 // that we don't want to encourage anyone to use.
7259
7260 // FIXME: we don't support #assert or #unassert, so don't suggest them.
7261 Results.ExitScope();
7262
7263 HandleCodeCompleteResults(this, CodeCompleter,
7264 CodeCompletionContext::CCC_PreprocessorDirective,
7265 Results.data(), Results.size());
7266 }
7267
CodeCompleteInPreprocessorConditionalExclusion(Scope * S)7268 void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
7269 CodeCompleteOrdinaryName(S,
7270 S->getFnParent()? Sema::PCC_RecoveryInFunction
7271 : Sema::PCC_Namespace);
7272 }
7273
CodeCompletePreprocessorMacroName(bool IsDefinition)7274 void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
7275 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7276 CodeCompleter->getCodeCompletionTUInfo(),
7277 IsDefinition? CodeCompletionContext::CCC_MacroName
7278 : CodeCompletionContext::CCC_MacroNameUse);
7279 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
7280 // Add just the names of macros, not their arguments.
7281 CodeCompletionBuilder Builder(Results.getAllocator(),
7282 Results.getCodeCompletionTUInfo());
7283 Results.EnterNewScope();
7284 for (Preprocessor::macro_iterator M = PP.macro_begin(),
7285 MEnd = PP.macro_end();
7286 M != MEnd; ++M) {
7287 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
7288 M->first->getName()));
7289 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
7290 CCP_CodePattern,
7291 CXCursor_MacroDefinition));
7292 }
7293 Results.ExitScope();
7294 } else if (IsDefinition) {
7295 // FIXME: Can we detect when the user just wrote an include guard above?
7296 }
7297
7298 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7299 Results.data(), Results.size());
7300 }
7301
CodeCompletePreprocessorExpression()7302 void Sema::CodeCompletePreprocessorExpression() {
7303 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7304 CodeCompleter->getCodeCompletionTUInfo(),
7305 CodeCompletionContext::CCC_PreprocessorExpression);
7306
7307 if (!CodeCompleter || CodeCompleter->includeMacros())
7308 AddMacroResults(PP, Results, true);
7309
7310 // defined (<macro>)
7311 Results.EnterNewScope();
7312 CodeCompletionBuilder Builder(Results.getAllocator(),
7313 Results.getCodeCompletionTUInfo());
7314 Builder.AddTypedTextChunk("defined");
7315 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7316 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7317 Builder.AddPlaceholderChunk("macro");
7318 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7319 Results.AddResult(Builder.TakeString());
7320 Results.ExitScope();
7321
7322 HandleCodeCompleteResults(this, CodeCompleter,
7323 CodeCompletionContext::CCC_PreprocessorExpression,
7324 Results.data(), Results.size());
7325 }
7326
CodeCompletePreprocessorMacroArgument(Scope * S,IdentifierInfo * Macro,MacroInfo * MacroInfo,unsigned Argument)7327 void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
7328 IdentifierInfo *Macro,
7329 MacroInfo *MacroInfo,
7330 unsigned Argument) {
7331 // FIXME: In the future, we could provide "overload" results, much like we
7332 // do for function calls.
7333
7334 // Now just ignore this. There will be another code-completion callback
7335 // for the expanded tokens.
7336 }
7337
CodeCompleteNaturalLanguage()7338 void Sema::CodeCompleteNaturalLanguage() {
7339 HandleCodeCompleteResults(this, CodeCompleter,
7340 CodeCompletionContext::CCC_NaturalLanguage,
7341 0, 0);
7342 }
7343
GatherGlobalCodeCompletions(CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,SmallVectorImpl<CodeCompletionResult> & Results)7344 void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
7345 CodeCompletionTUInfo &CCTUInfo,
7346 SmallVectorImpl<CodeCompletionResult> &Results) {
7347 ResultBuilder Builder(*this, Allocator, CCTUInfo,
7348 CodeCompletionContext::CCC_Recovery);
7349 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
7350 CodeCompletionDeclConsumer Consumer(Builder,
7351 Context.getTranslationUnitDecl());
7352 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
7353 Consumer);
7354 }
7355
7356 if (!CodeCompleter || CodeCompleter->includeMacros())
7357 AddMacroResults(PP, Builder, true);
7358
7359 Results.clear();
7360 Results.insert(Results.end(),
7361 Builder.data(), Builder.data() + Builder.size());
7362 }
7363