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