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