1 //===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the code-completion semantic actions.
10 //
11 //===----------------------------------------------------------------------===//
12 #include "clang/AST/Decl.h"
13 #include "clang/AST/DeclBase.h"
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/DeclObjC.h"
16 #include "clang/AST/ExprCXX.h"
17 #include "clang/AST/ExprObjC.h"
18 #include "clang/AST/QualTypeNames.h"
19 #include "clang/AST/Type.h"
20 #include "clang/Basic/CharInfo.h"
21 #include "clang/Basic/Specifiers.h"
22 #include "clang/Lex/HeaderSearch.h"
23 #include "clang/Lex/MacroInfo.h"
24 #include "clang/Lex/Preprocessor.h"
25 #include "clang/Sema/CodeCompleteConsumer.h"
26 #include "clang/Sema/Lookup.h"
27 #include "clang/Sema/Overload.h"
28 #include "clang/Sema/Scope.h"
29 #include "clang/Sema/ScopeInfo.h"
30 #include "clang/Sema/SemaInternal.h"
31 #include "llvm/ADT/DenseSet.h"
32 #include "llvm/ADT/SmallBitVector.h"
33 #include "llvm/ADT/SmallPtrSet.h"
34 #include "llvm/ADT/SmallString.h"
35 #include "llvm/ADT/StringExtras.h"
36 #include "llvm/ADT/StringSwitch.h"
37 #include "llvm/ADT/Twine.h"
38 #include "llvm/ADT/iterator_range.h"
39 #include "llvm/Support/Path.h"
40 #include <list>
41 #include <map>
42 #include <string>
43 #include <vector>
44
45 using namespace clang;
46 using namespace sema;
47
48 namespace {
49 /// A container of code-completion results.
50 class ResultBuilder {
51 public:
52 /// The type of a name-lookup filter, which can be provided to the
53 /// name-lookup routines to specify which declarations should be included in
54 /// the result set (when it returns true) and which declarations should be
55 /// filtered out (returns false).
56 typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const;
57
58 typedef CodeCompletionResult Result;
59
60 private:
61 /// The actual results we have found.
62 std::vector<Result> Results;
63
64 /// A record of all of the declarations we have found and placed
65 /// into the result set, used to ensure that no declaration ever gets into
66 /// the result set twice.
67 llvm::SmallPtrSet<const Decl *, 16> AllDeclsFound;
68
69 typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair;
70
71 /// An entry in the shadow map, which is optimized to store
72 /// a single (declaration, index) mapping (the common case) but
73 /// can also store a list of (declaration, index) mappings.
74 class ShadowMapEntry {
75 typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
76
77 /// Contains either the solitary NamedDecl * or a vector
78 /// of (declaration, index) pairs.
79 llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector *> DeclOrVector;
80
81 /// When the entry contains a single declaration, this is
82 /// the index associated with that entry.
83 unsigned SingleDeclIndex;
84
85 public:
ShadowMapEntry()86 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) {}
87 ShadowMapEntry(const ShadowMapEntry &) = delete;
ShadowMapEntry(ShadowMapEntry && Move)88 ShadowMapEntry(ShadowMapEntry &&Move) { *this = std::move(Move); }
89 ShadowMapEntry &operator=(const ShadowMapEntry &) = delete;
operator =(ShadowMapEntry && Move)90 ShadowMapEntry &operator=(ShadowMapEntry &&Move) {
91 SingleDeclIndex = Move.SingleDeclIndex;
92 DeclOrVector = Move.DeclOrVector;
93 Move.DeclOrVector = nullptr;
94 return *this;
95 }
96
Add(const NamedDecl * ND,unsigned Index)97 void Add(const NamedDecl *ND, unsigned Index) {
98 if (DeclOrVector.isNull()) {
99 // 0 - > 1 elements: just set the single element information.
100 DeclOrVector = ND;
101 SingleDeclIndex = Index;
102 return;
103 }
104
105 if (const NamedDecl *PrevND =
106 DeclOrVector.dyn_cast<const NamedDecl *>()) {
107 // 1 -> 2 elements: create the vector of results and push in the
108 // existing declaration.
109 DeclIndexPairVector *Vec = new DeclIndexPairVector;
110 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
111 DeclOrVector = Vec;
112 }
113
114 // Add the new element to the end of the vector.
115 DeclOrVector.get<DeclIndexPairVector *>()->push_back(
116 DeclIndexPair(ND, Index));
117 }
118
~ShadowMapEntry()119 ~ShadowMapEntry() {
120 if (DeclIndexPairVector *Vec =
121 DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
122 delete Vec;
123 DeclOrVector = ((NamedDecl *)nullptr);
124 }
125 }
126
127 // Iteration.
128 class iterator;
129 iterator begin() const;
130 iterator end() const;
131 };
132
133 /// A mapping from declaration names to the declarations that have
134 /// this name within a particular scope and their index within the list of
135 /// results.
136 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
137
138 /// The semantic analysis object for which results are being
139 /// produced.
140 Sema &SemaRef;
141
142 /// The allocator used to allocate new code-completion strings.
143 CodeCompletionAllocator &Allocator;
144
145 CodeCompletionTUInfo &CCTUInfo;
146
147 /// If non-NULL, a filter function used to remove any code-completion
148 /// results that are not desirable.
149 LookupFilter Filter;
150
151 /// Whether we should allow declarations as
152 /// nested-name-specifiers that would otherwise be filtered out.
153 bool AllowNestedNameSpecifiers;
154
155 /// If set, the type that we would prefer our resulting value
156 /// declarations to have.
157 ///
158 /// Closely matching the preferred type gives a boost to a result's
159 /// priority.
160 CanQualType PreferredType;
161
162 /// A list of shadow maps, which is used to model name hiding at
163 /// different levels of, e.g., the inheritance hierarchy.
164 std::list<ShadowMap> ShadowMaps;
165
166 /// Overloaded C++ member functions found by SemaLookup.
167 /// Used to determine when one overload is dominated by another.
168 llvm::DenseMap<std::pair<DeclContext *, /*Name*/uintptr_t>, ShadowMapEntry>
169 OverloadMap;
170
171 /// If we're potentially referring to a C++ member function, the set
172 /// of qualifiers applied to the object type.
173 Qualifiers ObjectTypeQualifiers;
174 /// The kind of the object expression, for rvalue/lvalue overloads.
175 ExprValueKind ObjectKind;
176
177 /// Whether the \p ObjectTypeQualifiers field is active.
178 bool HasObjectTypeQualifiers;
179
180 /// The selector that we prefer.
181 Selector PreferredSelector;
182
183 /// The completion context in which we are gathering results.
184 CodeCompletionContext CompletionContext;
185
186 /// If we are in an instance method definition, the \@implementation
187 /// object.
188 ObjCImplementationDecl *ObjCImplementation;
189
190 void AdjustResultPriorityForDecl(Result &R);
191
192 void MaybeAddConstructorResults(Result R);
193
194 public:
ResultBuilder(Sema & SemaRef,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,const CodeCompletionContext & CompletionContext,LookupFilter Filter=nullptr)195 explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
196 CodeCompletionTUInfo &CCTUInfo,
197 const CodeCompletionContext &CompletionContext,
198 LookupFilter Filter = nullptr)
199 : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
200 Filter(Filter), AllowNestedNameSpecifiers(false),
201 HasObjectTypeQualifiers(false), CompletionContext(CompletionContext),
202 ObjCImplementation(nullptr) {
203 // If this is an Objective-C instance method definition, dig out the
204 // corresponding implementation.
205 switch (CompletionContext.getKind()) {
206 case CodeCompletionContext::CCC_Expression:
207 case CodeCompletionContext::CCC_ObjCMessageReceiver:
208 case CodeCompletionContext::CCC_ParenthesizedExpression:
209 case CodeCompletionContext::CCC_Statement:
210 case CodeCompletionContext::CCC_Recovery:
211 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
212 if (Method->isInstanceMethod())
213 if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
214 ObjCImplementation = Interface->getImplementation();
215 break;
216
217 default:
218 break;
219 }
220 }
221
222 /// Determine the priority for a reference to the given declaration.
223 unsigned getBasePriority(const NamedDecl *D);
224
225 /// Whether we should include code patterns in the completion
226 /// results.
includeCodePatterns() const227 bool includeCodePatterns() const {
228 return SemaRef.CodeCompleter &&
229 SemaRef.CodeCompleter->includeCodePatterns();
230 }
231
232 /// Set the filter used for code-completion results.
setFilter(LookupFilter Filter)233 void setFilter(LookupFilter Filter) { this->Filter = Filter; }
234
data()235 Result *data() { return Results.empty() ? nullptr : &Results.front(); }
size() const236 unsigned size() const { return Results.size(); }
empty() const237 bool empty() const { return Results.empty(); }
238
239 /// Specify the preferred type.
setPreferredType(QualType T)240 void setPreferredType(QualType T) {
241 PreferredType = SemaRef.Context.getCanonicalType(T);
242 }
243
244 /// Set the cv-qualifiers on the object type, for us in filtering
245 /// calls to member functions.
246 ///
247 /// When there are qualifiers in this set, they will be used to filter
248 /// out member functions that aren't available (because there will be a
249 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
250 /// match.
setObjectTypeQualifiers(Qualifiers Quals,ExprValueKind Kind)251 void setObjectTypeQualifiers(Qualifiers Quals, ExprValueKind Kind) {
252 ObjectTypeQualifiers = Quals;
253 ObjectKind = Kind;
254 HasObjectTypeQualifiers = true;
255 }
256
257 /// Set the preferred selector.
258 ///
259 /// When an Objective-C method declaration result is added, and that
260 /// method's selector matches this preferred selector, we give that method
261 /// a slight priority boost.
setPreferredSelector(Selector Sel)262 void setPreferredSelector(Selector Sel) { PreferredSelector = Sel; }
263
264 /// Retrieve the code-completion context for which results are
265 /// being collected.
getCompletionContext() const266 const CodeCompletionContext &getCompletionContext() const {
267 return CompletionContext;
268 }
269
270 /// Specify whether nested-name-specifiers are allowed.
allowNestedNameSpecifiers(bool Allow=true)271 void allowNestedNameSpecifiers(bool Allow = true) {
272 AllowNestedNameSpecifiers = Allow;
273 }
274
275 /// Return the semantic analysis object for which we are collecting
276 /// code completion results.
getSema() const277 Sema &getSema() const { return SemaRef; }
278
279 /// Retrieve the allocator used to allocate code completion strings.
getAllocator() const280 CodeCompletionAllocator &getAllocator() const { return Allocator; }
281
getCodeCompletionTUInfo() const282 CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
283
284 /// Determine whether the given declaration is at all interesting
285 /// as a code-completion result.
286 ///
287 /// \param ND the declaration that we are inspecting.
288 ///
289 /// \param AsNestedNameSpecifier will be set true if this declaration is
290 /// only interesting when it is a nested-name-specifier.
291 bool isInterestingDecl(const NamedDecl *ND,
292 bool &AsNestedNameSpecifier) const;
293
294 /// Check whether the result is hidden by the Hiding declaration.
295 ///
296 /// \returns true if the result is hidden and cannot be found, false if
297 /// the hidden result could still be found. When false, \p R may be
298 /// modified to describe how the result can be found (e.g., via extra
299 /// qualification).
300 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
301 const NamedDecl *Hiding);
302
303 /// Add a new result to this result set (if it isn't already in one
304 /// of the shadow maps), or replace an existing result (for, e.g., a
305 /// redeclaration).
306 ///
307 /// \param R the result to add (if it is unique).
308 ///
309 /// \param CurContext the context in which this result will be named.
310 void MaybeAddResult(Result R, DeclContext *CurContext = nullptr);
311
312 /// Add a new result to this result set, where we already know
313 /// the hiding declaration (if any).
314 ///
315 /// \param R the result to add (if it is unique).
316 ///
317 /// \param CurContext the context in which this result will be named.
318 ///
319 /// \param Hiding the declaration that hides the result.
320 ///
321 /// \param InBaseClass whether the result was found in a base
322 /// class of the searched context.
323 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
324 bool InBaseClass);
325
326 /// Add a new non-declaration result to this result set.
327 void AddResult(Result R);
328
329 /// Enter into a new scope.
330 void EnterNewScope();
331
332 /// Exit from the current scope.
333 void ExitScope();
334
335 /// Ignore this declaration, if it is seen again.
Ignore(const Decl * D)336 void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
337
338 /// Add a visited context.
addVisitedContext(DeclContext * Ctx)339 void addVisitedContext(DeclContext *Ctx) {
340 CompletionContext.addVisitedContext(Ctx);
341 }
342
343 /// \name Name lookup predicates
344 ///
345 /// These predicates can be passed to the name lookup functions to filter the
346 /// results of name lookup. All of the predicates have the same type, so that
347 ///
348 //@{
349 bool IsOrdinaryName(const NamedDecl *ND) const;
350 bool IsOrdinaryNonTypeName(const NamedDecl *ND) const;
351 bool IsIntegralConstantValue(const NamedDecl *ND) const;
352 bool IsOrdinaryNonValueName(const NamedDecl *ND) const;
353 bool IsNestedNameSpecifier(const NamedDecl *ND) const;
354 bool IsEnum(const NamedDecl *ND) const;
355 bool IsClassOrStruct(const NamedDecl *ND) const;
356 bool IsUnion(const NamedDecl *ND) const;
357 bool IsNamespace(const NamedDecl *ND) const;
358 bool IsNamespaceOrAlias(const NamedDecl *ND) const;
359 bool IsType(const NamedDecl *ND) const;
360 bool IsMember(const NamedDecl *ND) const;
361 bool IsObjCIvar(const NamedDecl *ND) const;
362 bool IsObjCMessageReceiver(const NamedDecl *ND) const;
363 bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const;
364 bool IsObjCCollection(const NamedDecl *ND) const;
365 bool IsImpossibleToSatisfy(const NamedDecl *ND) const;
366 //@}
367 };
368 } // namespace
369
enterReturn(Sema & S,SourceLocation Tok)370 void PreferredTypeBuilder::enterReturn(Sema &S, SourceLocation Tok) {
371 if (isa<BlockDecl>(S.CurContext)) {
372 if (sema::BlockScopeInfo *BSI = S.getCurBlock()) {
373 ComputeType = nullptr;
374 Type = BSI->ReturnType;
375 ExpectedLoc = Tok;
376 }
377 } else if (const auto *Function = dyn_cast<FunctionDecl>(S.CurContext)) {
378 ComputeType = nullptr;
379 Type = Function->getReturnType();
380 ExpectedLoc = Tok;
381 } else if (const auto *Method = dyn_cast<ObjCMethodDecl>(S.CurContext)) {
382 ComputeType = nullptr;
383 Type = Method->getReturnType();
384 ExpectedLoc = Tok;
385 }
386 }
387
enterVariableInit(SourceLocation Tok,Decl * D)388 void PreferredTypeBuilder::enterVariableInit(SourceLocation Tok, Decl *D) {
389 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
390 ComputeType = nullptr;
391 Type = VD ? VD->getType() : QualType();
392 ExpectedLoc = Tok;
393 }
394
enterFunctionArgument(SourceLocation Tok,llvm::function_ref<QualType ()> ComputeType)395 void PreferredTypeBuilder::enterFunctionArgument(
396 SourceLocation Tok, llvm::function_ref<QualType()> ComputeType) {
397 this->ComputeType = ComputeType;
398 Type = QualType();
399 ExpectedLoc = Tok;
400 }
401
enterParenExpr(SourceLocation Tok,SourceLocation LParLoc)402 void PreferredTypeBuilder::enterParenExpr(SourceLocation Tok,
403 SourceLocation LParLoc) {
404 // expected type for parenthesized expression does not change.
405 if (ExpectedLoc == LParLoc)
406 ExpectedLoc = Tok;
407 }
408
getPreferredTypeOfBinaryRHS(Sema & S,Expr * LHS,tok::TokenKind Op)409 static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS,
410 tok::TokenKind Op) {
411 if (!LHS)
412 return QualType();
413
414 QualType LHSType = LHS->getType();
415 if (LHSType->isPointerType()) {
416 if (Op == tok::plus || Op == tok::plusequal || Op == tok::minusequal)
417 return S.getASTContext().getPointerDiffType();
418 // Pointer difference is more common than subtracting an int from a pointer.
419 if (Op == tok::minus)
420 return LHSType;
421 }
422
423 switch (Op) {
424 // No way to infer the type of RHS from LHS.
425 case tok::comma:
426 return QualType();
427 // Prefer the type of the left operand for all of these.
428 // Arithmetic operations.
429 case tok::plus:
430 case tok::plusequal:
431 case tok::minus:
432 case tok::minusequal:
433 case tok::percent:
434 case tok::percentequal:
435 case tok::slash:
436 case tok::slashequal:
437 case tok::star:
438 case tok::starequal:
439 // Assignment.
440 case tok::equal:
441 // Comparison operators.
442 case tok::equalequal:
443 case tok::exclaimequal:
444 case tok::less:
445 case tok::lessequal:
446 case tok::greater:
447 case tok::greaterequal:
448 case tok::spaceship:
449 return LHS->getType();
450 // Binary shifts are often overloaded, so don't try to guess those.
451 case tok::greatergreater:
452 case tok::greatergreaterequal:
453 case tok::lessless:
454 case tok::lesslessequal:
455 if (LHSType->isIntegralOrEnumerationType())
456 return S.getASTContext().IntTy;
457 return QualType();
458 // Logical operators, assume we want bool.
459 case tok::ampamp:
460 case tok::pipepipe:
461 case tok::caretcaret:
462 return S.getASTContext().BoolTy;
463 // Operators often used for bit manipulation are typically used with the type
464 // of the left argument.
465 case tok::pipe:
466 case tok::pipeequal:
467 case tok::caret:
468 case tok::caretequal:
469 case tok::amp:
470 case tok::ampequal:
471 if (LHSType->isIntegralOrEnumerationType())
472 return LHSType;
473 return QualType();
474 // RHS should be a pointer to a member of the 'LHS' type, but we can't give
475 // any particular type here.
476 case tok::periodstar:
477 case tok::arrowstar:
478 return QualType();
479 default:
480 // FIXME(ibiryukov): handle the missing op, re-add the assertion.
481 // assert(false && "unhandled binary op");
482 return QualType();
483 }
484 }
485
486 /// Get preferred type for an argument of an unary expression. \p ContextType is
487 /// preferred type of the whole unary expression.
getPreferredTypeOfUnaryArg(Sema & S,QualType ContextType,tok::TokenKind Op)488 static QualType getPreferredTypeOfUnaryArg(Sema &S, QualType ContextType,
489 tok::TokenKind Op) {
490 switch (Op) {
491 case tok::exclaim:
492 return S.getASTContext().BoolTy;
493 case tok::amp:
494 if (!ContextType.isNull() && ContextType->isPointerType())
495 return ContextType->getPointeeType();
496 return QualType();
497 case tok::star:
498 if (ContextType.isNull())
499 return QualType();
500 return S.getASTContext().getPointerType(ContextType.getNonReferenceType());
501 case tok::plus:
502 case tok::minus:
503 case tok::tilde:
504 case tok::minusminus:
505 case tok::plusplus:
506 if (ContextType.isNull())
507 return S.getASTContext().IntTy;
508 // leave as is, these operators typically return the same type.
509 return ContextType;
510 case tok::kw___real:
511 case tok::kw___imag:
512 return QualType();
513 default:
514 assert(false && "unhandled unary op");
515 return QualType();
516 }
517 }
518
enterBinary(Sema & S,SourceLocation Tok,Expr * LHS,tok::TokenKind Op)519 void PreferredTypeBuilder::enterBinary(Sema &S, SourceLocation Tok, Expr *LHS,
520 tok::TokenKind Op) {
521 ComputeType = nullptr;
522 Type = getPreferredTypeOfBinaryRHS(S, LHS, Op);
523 ExpectedLoc = Tok;
524 }
525
enterMemAccess(Sema & S,SourceLocation Tok,Expr * Base)526 void PreferredTypeBuilder::enterMemAccess(Sema &S, SourceLocation Tok,
527 Expr *Base) {
528 if (!Base)
529 return;
530 // Do we have expected type for Base?
531 if (ExpectedLoc != Base->getBeginLoc())
532 return;
533 // Keep the expected type, only update the location.
534 ExpectedLoc = Tok;
535 return;
536 }
537
enterUnary(Sema & S,SourceLocation Tok,tok::TokenKind OpKind,SourceLocation OpLoc)538 void PreferredTypeBuilder::enterUnary(Sema &S, SourceLocation Tok,
539 tok::TokenKind OpKind,
540 SourceLocation OpLoc) {
541 ComputeType = nullptr;
542 Type = getPreferredTypeOfUnaryArg(S, this->get(OpLoc), OpKind);
543 ExpectedLoc = Tok;
544 }
545
enterSubscript(Sema & S,SourceLocation Tok,Expr * LHS)546 void PreferredTypeBuilder::enterSubscript(Sema &S, SourceLocation Tok,
547 Expr *LHS) {
548 ComputeType = nullptr;
549 Type = S.getASTContext().IntTy;
550 ExpectedLoc = Tok;
551 }
552
enterTypeCast(SourceLocation Tok,QualType CastType)553 void PreferredTypeBuilder::enterTypeCast(SourceLocation Tok,
554 QualType CastType) {
555 ComputeType = nullptr;
556 Type = !CastType.isNull() ? CastType.getCanonicalType() : QualType();
557 ExpectedLoc = Tok;
558 }
559
enterCondition(Sema & S,SourceLocation Tok)560 void PreferredTypeBuilder::enterCondition(Sema &S, SourceLocation Tok) {
561 ComputeType = nullptr;
562 Type = S.getASTContext().BoolTy;
563 ExpectedLoc = Tok;
564 }
565
566 class ResultBuilder::ShadowMapEntry::iterator {
567 llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
568 unsigned SingleDeclIndex;
569
570 public:
571 typedef DeclIndexPair value_type;
572 typedef value_type reference;
573 typedef std::ptrdiff_t difference_type;
574 typedef std::input_iterator_tag iterator_category;
575
576 class pointer {
577 DeclIndexPair Value;
578
579 public:
pointer(const DeclIndexPair & Value)580 pointer(const DeclIndexPair &Value) : Value(Value) {}
581
operator ->() const582 const DeclIndexPair *operator->() const { return &Value; }
583 };
584
iterator()585 iterator() : DeclOrIterator((NamedDecl *)nullptr), SingleDeclIndex(0) {}
586
iterator(const NamedDecl * SingleDecl,unsigned Index)587 iterator(const NamedDecl *SingleDecl, unsigned Index)
588 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) {}
589
iterator(const DeclIndexPair * Iterator)590 iterator(const DeclIndexPair *Iterator)
591 : DeclOrIterator(Iterator), SingleDeclIndex(0) {}
592
operator ++()593 iterator &operator++() {
594 if (DeclOrIterator.is<const NamedDecl *>()) {
595 DeclOrIterator = (NamedDecl *)nullptr;
596 SingleDeclIndex = 0;
597 return *this;
598 }
599
600 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair *>();
601 ++I;
602 DeclOrIterator = I;
603 return *this;
604 }
605
606 /*iterator operator++(int) {
607 iterator tmp(*this);
608 ++(*this);
609 return tmp;
610 }*/
611
operator *() const612 reference operator*() const {
613 if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>())
614 return reference(ND, SingleDeclIndex);
615
616 return *DeclOrIterator.get<const DeclIndexPair *>();
617 }
618
operator ->() const619 pointer operator->() const { return pointer(**this); }
620
operator ==(const iterator & X,const iterator & Y)621 friend bool operator==(const iterator &X, const iterator &Y) {
622 return X.DeclOrIterator.getOpaqueValue() ==
623 Y.DeclOrIterator.getOpaqueValue() &&
624 X.SingleDeclIndex == Y.SingleDeclIndex;
625 }
626
operator !=(const iterator & X,const iterator & Y)627 friend bool operator!=(const iterator &X, const iterator &Y) {
628 return !(X == Y);
629 }
630 };
631
632 ResultBuilder::ShadowMapEntry::iterator
begin() const633 ResultBuilder::ShadowMapEntry::begin() const {
634 if (DeclOrVector.isNull())
635 return iterator();
636
637 if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>())
638 return iterator(ND, SingleDeclIndex);
639
640 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
641 }
642
643 ResultBuilder::ShadowMapEntry::iterator
end() const644 ResultBuilder::ShadowMapEntry::end() const {
645 if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull())
646 return iterator();
647
648 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
649 }
650
651 /// Compute the qualification required to get from the current context
652 /// (\p CurContext) to the target context (\p TargetContext).
653 ///
654 /// \param Context the AST context in which the qualification will be used.
655 ///
656 /// \param CurContext the context where an entity is being named, which is
657 /// typically based on the current scope.
658 ///
659 /// \param TargetContext the context in which the named entity actually
660 /// resides.
661 ///
662 /// \returns a nested name specifier that refers into the target context, or
663 /// NULL if no qualification is needed.
664 static NestedNameSpecifier *
getRequiredQualification(ASTContext & Context,const DeclContext * CurContext,const DeclContext * TargetContext)665 getRequiredQualification(ASTContext &Context, const DeclContext *CurContext,
666 const DeclContext *TargetContext) {
667 SmallVector<const DeclContext *, 4> TargetParents;
668
669 for (const DeclContext *CommonAncestor = TargetContext;
670 CommonAncestor && !CommonAncestor->Encloses(CurContext);
671 CommonAncestor = CommonAncestor->getLookupParent()) {
672 if (CommonAncestor->isTransparentContext() ||
673 CommonAncestor->isFunctionOrMethod())
674 continue;
675
676 TargetParents.push_back(CommonAncestor);
677 }
678
679 NestedNameSpecifier *Result = nullptr;
680 while (!TargetParents.empty()) {
681 const DeclContext *Parent = TargetParents.pop_back_val();
682
683 if (const auto *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
684 if (!Namespace->getIdentifier())
685 continue;
686
687 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
688 } else if (const auto *TD = dyn_cast<TagDecl>(Parent))
689 Result = NestedNameSpecifier::Create(
690 Context, Result, false, Context.getTypeDeclType(TD).getTypePtr());
691 }
692 return Result;
693 }
694
695 // Some declarations have reserved names that we don't want to ever show.
696 // Filter out names reserved for the implementation if they come from a
697 // system header.
shouldIgnoreDueToReservedName(const NamedDecl * ND,Sema & SemaRef)698 static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) {
699 const IdentifierInfo *Id = ND->getIdentifier();
700 if (!Id)
701 return false;
702
703 // Ignore reserved names for compiler provided decls.
704 if (Id->isReservedName() && ND->getLocation().isInvalid())
705 return true;
706
707 // For system headers ignore only double-underscore names.
708 // This allows for system headers providing private symbols with a single
709 // underscore.
710 if (Id->isReservedName(/*doubleUnderscoreOnly=*/true) &&
711 SemaRef.SourceMgr.isInSystemHeader(
712 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation())))
713 return true;
714
715 return false;
716 }
717
isInterestingDecl(const NamedDecl * ND,bool & AsNestedNameSpecifier) const718 bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
719 bool &AsNestedNameSpecifier) const {
720 AsNestedNameSpecifier = false;
721
722 auto *Named = ND;
723 ND = ND->getUnderlyingDecl();
724
725 // Skip unnamed entities.
726 if (!ND->getDeclName())
727 return false;
728
729 // Friend declarations and declarations introduced due to friends are never
730 // added as results.
731 if (ND->getFriendObjectKind() == Decl::FOK_Undeclared)
732 return false;
733
734 // Class template (partial) specializations are never added as results.
735 if (isa<ClassTemplateSpecializationDecl>(ND) ||
736 isa<ClassTemplatePartialSpecializationDecl>(ND))
737 return false;
738
739 // Using declarations themselves are never added as results.
740 if (isa<UsingDecl>(ND))
741 return false;
742
743 if (shouldIgnoreDueToReservedName(ND, SemaRef))
744 return false;
745
746 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
747 (isa<NamespaceDecl>(ND) && Filter != &ResultBuilder::IsNamespace &&
748 Filter != &ResultBuilder::IsNamespaceOrAlias && Filter != nullptr))
749 AsNestedNameSpecifier = true;
750
751 // Filter out any unwanted results.
752 if (Filter && !(this->*Filter)(Named)) {
753 // Check whether it is interesting as a nested-name-specifier.
754 if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus &&
755 IsNestedNameSpecifier(ND) &&
756 (Filter != &ResultBuilder::IsMember ||
757 (isa<CXXRecordDecl>(ND) &&
758 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
759 AsNestedNameSpecifier = true;
760 return true;
761 }
762
763 return false;
764 }
765 // ... then it must be interesting!
766 return true;
767 }
768
CheckHiddenResult(Result & R,DeclContext * CurContext,const NamedDecl * Hiding)769 bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
770 const NamedDecl *Hiding) {
771 // In C, there is no way to refer to a hidden name.
772 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
773 // name if we introduce the tag type.
774 if (!SemaRef.getLangOpts().CPlusPlus)
775 return true;
776
777 const DeclContext *HiddenCtx =
778 R.Declaration->getDeclContext()->getRedeclContext();
779
780 // There is no way to qualify a name declared in a function or method.
781 if (HiddenCtx->isFunctionOrMethod())
782 return true;
783
784 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
785 return true;
786
787 // We can refer to the result with the appropriate qualification. Do it.
788 R.Hidden = true;
789 R.QualifierIsInformative = false;
790
791 if (!R.Qualifier)
792 R.Qualifier = getRequiredQualification(SemaRef.Context, CurContext,
793 R.Declaration->getDeclContext());
794 return false;
795 }
796
797 /// A simplified classification of types used to determine whether two
798 /// types are "similar enough" when adjusting priorities.
getSimplifiedTypeClass(CanQualType T)799 SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
800 switch (T->getTypeClass()) {
801 case Type::Builtin:
802 switch (cast<BuiltinType>(T)->getKind()) {
803 case BuiltinType::Void:
804 return STC_Void;
805
806 case BuiltinType::NullPtr:
807 return STC_Pointer;
808
809 case BuiltinType::Overload:
810 case BuiltinType::Dependent:
811 return STC_Other;
812
813 case BuiltinType::ObjCId:
814 case BuiltinType::ObjCClass:
815 case BuiltinType::ObjCSel:
816 return STC_ObjectiveC;
817
818 default:
819 return STC_Arithmetic;
820 }
821
822 case Type::Complex:
823 return STC_Arithmetic;
824
825 case Type::Pointer:
826 return STC_Pointer;
827
828 case Type::BlockPointer:
829 return STC_Block;
830
831 case Type::LValueReference:
832 case Type::RValueReference:
833 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
834
835 case Type::ConstantArray:
836 case Type::IncompleteArray:
837 case Type::VariableArray:
838 case Type::DependentSizedArray:
839 return STC_Array;
840
841 case Type::DependentSizedExtVector:
842 case Type::Vector:
843 case Type::ExtVector:
844 return STC_Arithmetic;
845
846 case Type::FunctionProto:
847 case Type::FunctionNoProto:
848 return STC_Function;
849
850 case Type::Record:
851 return STC_Record;
852
853 case Type::Enum:
854 return STC_Arithmetic;
855
856 case Type::ObjCObject:
857 case Type::ObjCInterface:
858 case Type::ObjCObjectPointer:
859 return STC_ObjectiveC;
860
861 default:
862 return STC_Other;
863 }
864 }
865
866 /// Get the type that a given expression will have if this declaration
867 /// is used as an expression in its "typical" code-completion form.
getDeclUsageType(ASTContext & C,const NamedDecl * ND)868 QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
869 ND = ND->getUnderlyingDecl();
870
871 if (const auto *Type = dyn_cast<TypeDecl>(ND))
872 return C.getTypeDeclType(Type);
873 if (const auto *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
874 return C.getObjCInterfaceType(Iface);
875
876 QualType T;
877 if (const FunctionDecl *Function = ND->getAsFunction())
878 T = Function->getCallResultType();
879 else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND))
880 T = Method->getSendResultType();
881 else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND))
882 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
883 else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND))
884 T = Property->getType();
885 else if (const auto *Value = dyn_cast<ValueDecl>(ND))
886 T = Value->getType();
887
888 if (T.isNull())
889 return QualType();
890
891 // Dig through references, function pointers, and block pointers to
892 // get down to the likely type of an expression when the entity is
893 // used.
894 do {
895 if (const auto *Ref = T->getAs<ReferenceType>()) {
896 T = Ref->getPointeeType();
897 continue;
898 }
899
900 if (const auto *Pointer = T->getAs<PointerType>()) {
901 if (Pointer->getPointeeType()->isFunctionType()) {
902 T = Pointer->getPointeeType();
903 continue;
904 }
905
906 break;
907 }
908
909 if (const auto *Block = T->getAs<BlockPointerType>()) {
910 T = Block->getPointeeType();
911 continue;
912 }
913
914 if (const auto *Function = T->getAs<FunctionType>()) {
915 T = Function->getReturnType();
916 continue;
917 }
918
919 break;
920 } while (true);
921
922 return T;
923 }
924
getBasePriority(const NamedDecl * ND)925 unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) {
926 if (!ND)
927 return CCP_Unlikely;
928
929 // Context-based decisions.
930 const DeclContext *LexicalDC = ND->getLexicalDeclContext();
931 if (LexicalDC->isFunctionOrMethod()) {
932 // _cmd is relatively rare
933 if (const auto *ImplicitParam = dyn_cast<ImplicitParamDecl>(ND))
934 if (ImplicitParam->getIdentifier() &&
935 ImplicitParam->getIdentifier()->isStr("_cmd"))
936 return CCP_ObjC_cmd;
937
938 return CCP_LocalDeclaration;
939 }
940
941 const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
942 if (DC->isRecord() || isa<ObjCContainerDecl>(DC)) {
943 // Explicit destructor calls are very rare.
944 if (isa<CXXDestructorDecl>(ND))
945 return CCP_Unlikely;
946 // Explicit operator and conversion function calls are also very rare.
947 auto DeclNameKind = ND->getDeclName().getNameKind();
948 if (DeclNameKind == DeclarationName::CXXOperatorName ||
949 DeclNameKind == DeclarationName::CXXLiteralOperatorName ||
950 DeclNameKind == DeclarationName::CXXConversionFunctionName)
951 return CCP_Unlikely;
952 return CCP_MemberDeclaration;
953 }
954
955 // Content-based decisions.
956 if (isa<EnumConstantDecl>(ND))
957 return CCP_Constant;
958
959 // Use CCP_Type for type declarations unless we're in a statement, Objective-C
960 // message receiver, or parenthesized expression context. There, it's as
961 // likely that the user will want to write a type as other declarations.
962 if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
963 !(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement ||
964 CompletionContext.getKind() ==
965 CodeCompletionContext::CCC_ObjCMessageReceiver ||
966 CompletionContext.getKind() ==
967 CodeCompletionContext::CCC_ParenthesizedExpression))
968 return CCP_Type;
969
970 return CCP_Declaration;
971 }
972
AdjustResultPriorityForDecl(Result & R)973 void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
974 // If this is an Objective-C method declaration whose selector matches our
975 // preferred selector, give it a priority boost.
976 if (!PreferredSelector.isNull())
977 if (const auto *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
978 if (PreferredSelector == Method->getSelector())
979 R.Priority += CCD_SelectorMatch;
980
981 // If we have a preferred type, adjust the priority for results with exactly-
982 // matching or nearly-matching types.
983 if (!PreferredType.isNull()) {
984 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
985 if (!T.isNull()) {
986 CanQualType TC = SemaRef.Context.getCanonicalType(T);
987 // Check for exactly-matching types (modulo qualifiers).
988 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
989 R.Priority /= CCF_ExactTypeMatch;
990 // Check for nearly-matching types, based on classification of each.
991 else if ((getSimplifiedTypeClass(PreferredType) ==
992 getSimplifiedTypeClass(TC)) &&
993 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
994 R.Priority /= CCF_SimilarTypeMatch;
995 }
996 }
997 }
998
getConstructors(ASTContext & Context,const CXXRecordDecl * Record)999 static DeclContext::lookup_result getConstructors(ASTContext &Context,
1000 const CXXRecordDecl *Record) {
1001 QualType RecordTy = Context.getTypeDeclType(Record);
1002 DeclarationName ConstructorName =
1003 Context.DeclarationNames.getCXXConstructorName(
1004 Context.getCanonicalType(RecordTy));
1005 return Record->lookup(ConstructorName);
1006 }
1007
MaybeAddConstructorResults(Result R)1008 void ResultBuilder::MaybeAddConstructorResults(Result R) {
1009 if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration ||
1010 !CompletionContext.wantConstructorResults())
1011 return;
1012
1013 const NamedDecl *D = R.Declaration;
1014 const CXXRecordDecl *Record = nullptr;
1015 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
1016 Record = ClassTemplate->getTemplatedDecl();
1017 else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
1018 // Skip specializations and partial specializations.
1019 if (isa<ClassTemplateSpecializationDecl>(Record))
1020 return;
1021 } else {
1022 // There are no constructors here.
1023 return;
1024 }
1025
1026 Record = Record->getDefinition();
1027 if (!Record)
1028 return;
1029
1030 for (NamedDecl *Ctor : getConstructors(SemaRef.Context, Record)) {
1031 R.Declaration = Ctor;
1032 R.CursorKind = getCursorKindForDecl(R.Declaration);
1033 Results.push_back(R);
1034 }
1035 }
1036
isConstructor(const Decl * ND)1037 static bool isConstructor(const Decl *ND) {
1038 if (const auto *Tmpl = dyn_cast<FunctionTemplateDecl>(ND))
1039 ND = Tmpl->getTemplatedDecl();
1040 return isa<CXXConstructorDecl>(ND);
1041 }
1042
MaybeAddResult(Result R,DeclContext * CurContext)1043 void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
1044 assert(!ShadowMaps.empty() && "Must enter into a results scope");
1045
1046 if (R.Kind != Result::RK_Declaration) {
1047 // For non-declaration results, just add the result.
1048 Results.push_back(R);
1049 return;
1050 }
1051
1052 // Look through using declarations.
1053 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
1054 CodeCompletionResult Result(Using->getTargetDecl(),
1055 getBasePriority(Using->getTargetDecl()),
1056 R.Qualifier);
1057 Result.ShadowDecl = Using;
1058 MaybeAddResult(Result, CurContext);
1059 return;
1060 }
1061
1062 const Decl *CanonDecl = R.Declaration->getCanonicalDecl();
1063 unsigned IDNS = CanonDecl->getIdentifierNamespace();
1064
1065 bool AsNestedNameSpecifier = false;
1066 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
1067 return;
1068
1069 // C++ constructors are never found by name lookup.
1070 if (isConstructor(R.Declaration))
1071 return;
1072
1073 ShadowMap &SMap = ShadowMaps.back();
1074 ShadowMapEntry::iterator I, IEnd;
1075 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
1076 if (NamePos != SMap.end()) {
1077 I = NamePos->second.begin();
1078 IEnd = NamePos->second.end();
1079 }
1080
1081 for (; I != IEnd; ++I) {
1082 const NamedDecl *ND = I->first;
1083 unsigned Index = I->second;
1084 if (ND->getCanonicalDecl() == CanonDecl) {
1085 // This is a redeclaration. Always pick the newer declaration.
1086 Results[Index].Declaration = R.Declaration;
1087
1088 // We're done.
1089 return;
1090 }
1091 }
1092
1093 // This is a new declaration in this scope. However, check whether this
1094 // declaration name is hidden by a similarly-named declaration in an outer
1095 // scope.
1096 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
1097 --SMEnd;
1098 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
1099 ShadowMapEntry::iterator I, IEnd;
1100 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
1101 if (NamePos != SM->end()) {
1102 I = NamePos->second.begin();
1103 IEnd = NamePos->second.end();
1104 }
1105 for (; I != IEnd; ++I) {
1106 // A tag declaration does not hide a non-tag declaration.
1107 if (I->first->hasTagIdentifierNamespace() &&
1108 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
1109 Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol)))
1110 continue;
1111
1112 // Protocols are in distinct namespaces from everything else.
1113 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) ||
1114 (IDNS & Decl::IDNS_ObjCProtocol)) &&
1115 I->first->getIdentifierNamespace() != IDNS)
1116 continue;
1117
1118 // The newly-added result is hidden by an entry in the shadow map.
1119 if (CheckHiddenResult(R, CurContext, I->first))
1120 return;
1121
1122 break;
1123 }
1124 }
1125
1126 // Make sure that any given declaration only shows up in the result set once.
1127 if (!AllDeclsFound.insert(CanonDecl).second)
1128 return;
1129
1130 // If the filter is for nested-name-specifiers, then this result starts a
1131 // nested-name-specifier.
1132 if (AsNestedNameSpecifier) {
1133 R.StartsNestedNameSpecifier = true;
1134 R.Priority = CCP_NestedNameSpecifier;
1135 } else
1136 AdjustResultPriorityForDecl(R);
1137
1138 // If this result is supposed to have an informative qualifier, add one.
1139 if (R.QualifierIsInformative && !R.Qualifier &&
1140 !R.StartsNestedNameSpecifier) {
1141 const DeclContext *Ctx = R.Declaration->getDeclContext();
1142 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
1143 R.Qualifier =
1144 NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace);
1145 else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
1146 R.Qualifier = NestedNameSpecifier::Create(
1147 SemaRef.Context, nullptr, false,
1148 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
1149 else
1150 R.QualifierIsInformative = false;
1151 }
1152
1153 // Insert this result into the set of results and into the current shadow
1154 // map.
1155 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
1156 Results.push_back(R);
1157
1158 if (!AsNestedNameSpecifier)
1159 MaybeAddConstructorResults(R);
1160 }
1161
setInBaseClass(ResultBuilder::Result & R)1162 static void setInBaseClass(ResultBuilder::Result &R) {
1163 R.Priority += CCD_InBaseClass;
1164 R.InBaseClass = true;
1165 }
1166
1167 enum class OverloadCompare { BothViable, Dominates, Dominated };
1168 // Will Candidate ever be called on the object, when overloaded with Incumbent?
1169 // Returns Dominates if Candidate is always called, Dominated if Incumbent is
1170 // always called, BothViable if either may be called dependending on arguments.
1171 // Precondition: must actually be overloads!
compareOverloads(const CXXMethodDecl & Candidate,const CXXMethodDecl & Incumbent,const Qualifiers & ObjectQuals,ExprValueKind ObjectKind)1172 static OverloadCompare compareOverloads(const CXXMethodDecl &Candidate,
1173 const CXXMethodDecl &Incumbent,
1174 const Qualifiers &ObjectQuals,
1175 ExprValueKind ObjectKind) {
1176 // Base/derived shadowing is handled elsewhere.
1177 if (Candidate.getDeclContext() != Incumbent.getDeclContext())
1178 return OverloadCompare::BothViable;
1179 if (Candidate.isVariadic() != Incumbent.isVariadic() ||
1180 Candidate.getNumParams() != Incumbent.getNumParams() ||
1181 Candidate.getMinRequiredArguments() !=
1182 Incumbent.getMinRequiredArguments())
1183 return OverloadCompare::BothViable;
1184 for (unsigned I = 0, E = Candidate.getNumParams(); I != E; ++I)
1185 if (Candidate.parameters()[I]->getType().getCanonicalType() !=
1186 Incumbent.parameters()[I]->getType().getCanonicalType())
1187 return OverloadCompare::BothViable;
1188 if (!llvm::empty(Candidate.specific_attrs<EnableIfAttr>()) ||
1189 !llvm::empty(Incumbent.specific_attrs<EnableIfAttr>()))
1190 return OverloadCompare::BothViable;
1191 // At this point, we know calls can't pick one or the other based on
1192 // arguments, so one of the two must win. (Or both fail, handled elsewhere).
1193 RefQualifierKind CandidateRef = Candidate.getRefQualifier();
1194 RefQualifierKind IncumbentRef = Incumbent.getRefQualifier();
1195 if (CandidateRef != IncumbentRef) {
1196 // If the object kind is LValue/RValue, there's one acceptable ref-qualifier
1197 // and it can't be mixed with ref-unqualified overloads (in valid code).
1198
1199 // For xvalue objects, we prefer the rvalue overload even if we have to
1200 // add qualifiers (which is rare, because const&& is rare).
1201 if (ObjectKind == clang::VK_XValue)
1202 return CandidateRef == RQ_RValue ? OverloadCompare::Dominates
1203 : OverloadCompare::Dominated;
1204 }
1205 // Now the ref qualifiers are the same (or we're in some invalid state).
1206 // So make some decision based on the qualifiers.
1207 Qualifiers CandidateQual = Candidate.getMethodQualifiers();
1208 Qualifiers IncumbentQual = Incumbent.getMethodQualifiers();
1209 bool CandidateSuperset = CandidateQual.compatiblyIncludes(IncumbentQual);
1210 bool IncumbentSuperset = IncumbentQual.compatiblyIncludes(CandidateQual);
1211 if (CandidateSuperset == IncumbentSuperset)
1212 return OverloadCompare::BothViable;
1213 return IncumbentSuperset ? OverloadCompare::Dominates
1214 : OverloadCompare::Dominated;
1215 }
1216
AddResult(Result R,DeclContext * CurContext,NamedDecl * Hiding,bool InBaseClass=false)1217 void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
1218 NamedDecl *Hiding, bool InBaseClass = false) {
1219 if (R.Kind != Result::RK_Declaration) {
1220 // For non-declaration results, just add the result.
1221 Results.push_back(R);
1222 return;
1223 }
1224
1225 // Look through using declarations.
1226 if (const auto *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
1227 CodeCompletionResult Result(Using->getTargetDecl(),
1228 getBasePriority(Using->getTargetDecl()),
1229 R.Qualifier);
1230 Result.ShadowDecl = Using;
1231 AddResult(Result, CurContext, Hiding);
1232 return;
1233 }
1234
1235 bool AsNestedNameSpecifier = false;
1236 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
1237 return;
1238
1239 // C++ constructors are never found by name lookup.
1240 if (isConstructor(R.Declaration))
1241 return;
1242
1243 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
1244 return;
1245
1246 // Make sure that any given declaration only shows up in the result set once.
1247 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()).second)
1248 return;
1249
1250 // If the filter is for nested-name-specifiers, then this result starts a
1251 // nested-name-specifier.
1252 if (AsNestedNameSpecifier) {
1253 R.StartsNestedNameSpecifier = true;
1254 R.Priority = CCP_NestedNameSpecifier;
1255 } else if (Filter == &ResultBuilder::IsMember && !R.Qualifier &&
1256 InBaseClass &&
1257 isa<CXXRecordDecl>(
1258 R.Declaration->getDeclContext()->getRedeclContext()))
1259 R.QualifierIsInformative = true;
1260
1261 // If this result is supposed to have an informative qualifier, add one.
1262 if (R.QualifierIsInformative && !R.Qualifier &&
1263 !R.StartsNestedNameSpecifier) {
1264 const DeclContext *Ctx = R.Declaration->getDeclContext();
1265 if (const auto *Namespace = dyn_cast<NamespaceDecl>(Ctx))
1266 R.Qualifier =
1267 NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace);
1268 else if (const auto *Tag = dyn_cast<TagDecl>(Ctx))
1269 R.Qualifier = NestedNameSpecifier::Create(
1270 SemaRef.Context, nullptr, false,
1271 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
1272 else
1273 R.QualifierIsInformative = false;
1274 }
1275
1276 // Adjust the priority if this result comes from a base class.
1277 if (InBaseClass)
1278 setInBaseClass(R);
1279
1280 AdjustResultPriorityForDecl(R);
1281
1282 if (HasObjectTypeQualifiers)
1283 if (const auto *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
1284 if (Method->isInstance()) {
1285 Qualifiers MethodQuals = Method->getMethodQualifiers();
1286 if (ObjectTypeQualifiers == MethodQuals)
1287 R.Priority += CCD_ObjectQualifierMatch;
1288 else if (ObjectTypeQualifiers - MethodQuals) {
1289 // The method cannot be invoked, because doing so would drop
1290 // qualifiers.
1291 return;
1292 }
1293 // Detect cases where a ref-qualified method cannot be invoked.
1294 switch (Method->getRefQualifier()) {
1295 case RQ_LValue:
1296 if (ObjectKind != VK_LValue && !MethodQuals.hasConst())
1297 return;
1298 break;
1299 case RQ_RValue:
1300 if (ObjectKind == VK_LValue)
1301 return;
1302 break;
1303 case RQ_None:
1304 break;
1305 }
1306
1307 /// Check whether this dominates another overloaded method, which should
1308 /// be suppressed (or vice versa).
1309 /// Motivating case is const_iterator begin() const vs iterator begin().
1310 auto &OverloadSet = OverloadMap[std::make_pair(
1311 CurContext, Method->getDeclName().getAsOpaqueInteger())];
1312 for (const DeclIndexPair Entry : OverloadSet) {
1313 Result &Incumbent = Results[Entry.second];
1314 switch (compareOverloads(*Method,
1315 *cast<CXXMethodDecl>(Incumbent.Declaration),
1316 ObjectTypeQualifiers, ObjectKind)) {
1317 case OverloadCompare::Dominates:
1318 // Replace the dominated overload with this one.
1319 // FIXME: if the overload dominates multiple incumbents then we
1320 // should remove all. But two overloads is by far the common case.
1321 Incumbent = std::move(R);
1322 return;
1323 case OverloadCompare::Dominated:
1324 // This overload can't be called, drop it.
1325 return;
1326 case OverloadCompare::BothViable:
1327 break;
1328 }
1329 }
1330 OverloadSet.Add(Method, Results.size());
1331 }
1332
1333 // Insert this result into the set of results.
1334 Results.push_back(R);
1335
1336 if (!AsNestedNameSpecifier)
1337 MaybeAddConstructorResults(R);
1338 }
1339
AddResult(Result R)1340 void ResultBuilder::AddResult(Result R) {
1341 assert(R.Kind != Result::RK_Declaration &&
1342 "Declaration results need more context");
1343 Results.push_back(R);
1344 }
1345
1346 /// Enter into a new scope.
EnterNewScope()1347 void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); }
1348
1349 /// Exit from the current scope.
ExitScope()1350 void ResultBuilder::ExitScope() {
1351 ShadowMaps.pop_back();
1352 }
1353
1354 /// Determines whether this given declaration will be found by
1355 /// ordinary name lookup.
IsOrdinaryName(const NamedDecl * ND) const1356 bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
1357 ND = ND->getUnderlyingDecl();
1358
1359 // If name lookup finds a local extern declaration, then we are in a
1360 // context where it behaves like an ordinary name.
1361 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1362 if (SemaRef.getLangOpts().CPlusPlus)
1363 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1364 else if (SemaRef.getLangOpts().ObjC) {
1365 if (isa<ObjCIvarDecl>(ND))
1366 return true;
1367 }
1368
1369 return ND->getIdentifierNamespace() & IDNS;
1370 }
1371
1372 /// Determines whether this given declaration will be found by
1373 /// ordinary name lookup but is not a type name.
IsOrdinaryNonTypeName(const NamedDecl * ND) const1374 bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
1375 ND = ND->getUnderlyingDecl();
1376 if (isa<TypeDecl>(ND))
1377 return false;
1378 // Objective-C interfaces names are not filtered by this method because they
1379 // can be used in a class property expression. We can still filter out
1380 // @class declarations though.
1381 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
1382 if (!ID->getDefinition())
1383 return false;
1384 }
1385
1386 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1387 if (SemaRef.getLangOpts().CPlusPlus)
1388 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1389 else if (SemaRef.getLangOpts().ObjC) {
1390 if (isa<ObjCIvarDecl>(ND))
1391 return true;
1392 }
1393
1394 return ND->getIdentifierNamespace() & IDNS;
1395 }
1396
IsIntegralConstantValue(const NamedDecl * ND) const1397 bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {
1398 if (!IsOrdinaryNonTypeName(ND))
1399 return 0;
1400
1401 if (const auto *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
1402 if (VD->getType()->isIntegralOrEnumerationType())
1403 return true;
1404
1405 return false;
1406 }
1407
1408 /// Determines whether this given declaration will be found by
1409 /// ordinary name lookup.
IsOrdinaryNonValueName(const NamedDecl * ND) const1410 bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
1411 ND = ND->getUnderlyingDecl();
1412
1413 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1414 if (SemaRef.getLangOpts().CPlusPlus)
1415 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
1416
1417 return (ND->getIdentifierNamespace() & IDNS) && !isa<ValueDecl>(ND) &&
1418 !isa<FunctionTemplateDecl>(ND) && !isa<ObjCPropertyDecl>(ND);
1419 }
1420
1421 /// Determines whether the given declaration is suitable as the
1422 /// start of a C++ nested-name-specifier, e.g., a class or namespace.
IsNestedNameSpecifier(const NamedDecl * ND) const1423 bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {
1424 // Allow us to find class templates, too.
1425 if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1426 ND = ClassTemplate->getTemplatedDecl();
1427
1428 return SemaRef.isAcceptableNestedNameSpecifier(ND);
1429 }
1430
1431 /// Determines whether the given declaration is an enumeration.
IsEnum(const NamedDecl * ND) const1432 bool ResultBuilder::IsEnum(const NamedDecl *ND) const {
1433 return isa<EnumDecl>(ND);
1434 }
1435
1436 /// Determines whether the given declaration is a class or struct.
IsClassOrStruct(const NamedDecl * ND) const1437 bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {
1438 // Allow us to find class templates, too.
1439 if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1440 ND = ClassTemplate->getTemplatedDecl();
1441
1442 // For purposes of this check, interfaces match too.
1443 if (const auto *RD = dyn_cast<RecordDecl>(ND))
1444 return RD->getTagKind() == TTK_Class || RD->getTagKind() == TTK_Struct ||
1445 RD->getTagKind() == TTK_Interface;
1446
1447 return false;
1448 }
1449
1450 /// Determines whether the given declaration is a union.
IsUnion(const NamedDecl * ND) const1451 bool ResultBuilder::IsUnion(const NamedDecl *ND) const {
1452 // Allow us to find class templates, too.
1453 if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1454 ND = ClassTemplate->getTemplatedDecl();
1455
1456 if (const auto *RD = dyn_cast<RecordDecl>(ND))
1457 return RD->getTagKind() == TTK_Union;
1458
1459 return false;
1460 }
1461
1462 /// Determines whether the given declaration is a namespace.
IsNamespace(const NamedDecl * ND) const1463 bool ResultBuilder::IsNamespace(const NamedDecl *ND) const {
1464 return isa<NamespaceDecl>(ND);
1465 }
1466
1467 /// Determines whether the given declaration is a namespace or
1468 /// namespace alias.
IsNamespaceOrAlias(const NamedDecl * ND) const1469 bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {
1470 return isa<NamespaceDecl>(ND->getUnderlyingDecl());
1471 }
1472
1473 /// Determines whether the given declaration is a type.
IsType(const NamedDecl * ND) const1474 bool ResultBuilder::IsType(const NamedDecl *ND) const {
1475 ND = ND->getUnderlyingDecl();
1476 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
1477 }
1478
1479 /// Determines which members of a class should be visible via
1480 /// "." or "->". Only value declarations, nested name specifiers, and
1481 /// using declarations thereof should show up.
IsMember(const NamedDecl * ND) const1482 bool ResultBuilder::IsMember(const NamedDecl *ND) const {
1483 ND = ND->getUnderlyingDecl();
1484 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1485 isa<ObjCPropertyDecl>(ND);
1486 }
1487
isObjCReceiverType(ASTContext & C,QualType T)1488 static bool isObjCReceiverType(ASTContext &C, QualType T) {
1489 T = C.getCanonicalType(T);
1490 switch (T->getTypeClass()) {
1491 case Type::ObjCObject:
1492 case Type::ObjCInterface:
1493 case Type::ObjCObjectPointer:
1494 return true;
1495
1496 case Type::Builtin:
1497 switch (cast<BuiltinType>(T)->getKind()) {
1498 case BuiltinType::ObjCId:
1499 case BuiltinType::ObjCClass:
1500 case BuiltinType::ObjCSel:
1501 return true;
1502
1503 default:
1504 break;
1505 }
1506 return false;
1507
1508 default:
1509 break;
1510 }
1511
1512 if (!C.getLangOpts().CPlusPlus)
1513 return false;
1514
1515 // FIXME: We could perform more analysis here to determine whether a
1516 // particular class type has any conversions to Objective-C types. For now,
1517 // just accept all class types.
1518 return T->isDependentType() || T->isRecordType();
1519 }
1520
IsObjCMessageReceiver(const NamedDecl * ND) const1521 bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
1522 QualType T = getDeclUsageType(SemaRef.Context, ND);
1523 if (T.isNull())
1524 return false;
1525
1526 T = SemaRef.Context.getBaseElementType(T);
1527 return isObjCReceiverType(SemaRef.Context, T);
1528 }
1529
IsObjCMessageReceiverOrLambdaCapture(const NamedDecl * ND) const1530 bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(
1531 const NamedDecl *ND) const {
1532 if (IsObjCMessageReceiver(ND))
1533 return true;
1534
1535 const auto *Var = dyn_cast<VarDecl>(ND);
1536 if (!Var)
1537 return false;
1538
1539 return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
1540 }
1541
IsObjCCollection(const NamedDecl * ND) const1542 bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
1543 if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
1544 (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1545 return false;
1546
1547 QualType T = getDeclUsageType(SemaRef.Context, ND);
1548 if (T.isNull())
1549 return false;
1550
1551 T = SemaRef.Context.getBaseElementType(T);
1552 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1553 T->isObjCIdType() ||
1554 (SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
1555 }
1556
IsImpossibleToSatisfy(const NamedDecl * ND) const1557 bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {
1558 return false;
1559 }
1560
1561 /// Determines whether the given declaration is an Objective-C
1562 /// instance variable.
IsObjCIvar(const NamedDecl * ND) const1563 bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {
1564 return isa<ObjCIvarDecl>(ND);
1565 }
1566
1567 namespace {
1568
1569 /// Visible declaration consumer that adds a code-completion result
1570 /// for each visible declaration.
1571 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1572 ResultBuilder &Results;
1573 DeclContext *InitialLookupCtx;
1574 // NamingClass and BaseType are used for access-checking. See
1575 // Sema::IsSimplyAccessible for details.
1576 CXXRecordDecl *NamingClass;
1577 QualType BaseType;
1578 std::vector<FixItHint> FixIts;
1579
1580 public:
CodeCompletionDeclConsumer(ResultBuilder & Results,DeclContext * InitialLookupCtx,QualType BaseType=QualType (),std::vector<FixItHint> FixIts=std::vector<FixItHint> ())1581 CodeCompletionDeclConsumer(
1582 ResultBuilder &Results, DeclContext *InitialLookupCtx,
1583 QualType BaseType = QualType(),
1584 std::vector<FixItHint> FixIts = std::vector<FixItHint>())
1585 : Results(Results), InitialLookupCtx(InitialLookupCtx),
1586 FixIts(std::move(FixIts)) {
1587 NamingClass = llvm::dyn_cast<CXXRecordDecl>(InitialLookupCtx);
1588 // If BaseType was not provided explicitly, emulate implicit 'this->'.
1589 if (BaseType.isNull()) {
1590 auto ThisType = Results.getSema().getCurrentThisType();
1591 if (!ThisType.isNull()) {
1592 assert(ThisType->isPointerType());
1593 BaseType = ThisType->getPointeeType();
1594 if (!NamingClass)
1595 NamingClass = BaseType->getAsCXXRecordDecl();
1596 }
1597 }
1598 this->BaseType = BaseType;
1599 }
1600
FoundDecl(NamedDecl * ND,NamedDecl * Hiding,DeclContext * Ctx,bool InBaseClass)1601 void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
1602 bool InBaseClass) override {
1603 ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr,
1604 false, IsAccessible(ND, Ctx), FixIts);
1605 Results.AddResult(Result, InitialLookupCtx, Hiding, InBaseClass);
1606 }
1607
EnteredContext(DeclContext * Ctx)1608 void EnteredContext(DeclContext *Ctx) override {
1609 Results.addVisitedContext(Ctx);
1610 }
1611
1612 private:
IsAccessible(NamedDecl * ND,DeclContext * Ctx)1613 bool IsAccessible(NamedDecl *ND, DeclContext *Ctx) {
1614 // Naming class to use for access check. In most cases it was provided
1615 // explicitly (e.g. member access (lhs.foo) or qualified lookup (X::)),
1616 // for unqualified lookup we fallback to the \p Ctx in which we found the
1617 // member.
1618 auto *NamingClass = this->NamingClass;
1619 QualType BaseType = this->BaseType;
1620 if (auto *Cls = llvm::dyn_cast_or_null<CXXRecordDecl>(Ctx)) {
1621 if (!NamingClass)
1622 NamingClass = Cls;
1623 // When we emulate implicit 'this->' in an unqualified lookup, we might
1624 // end up with an invalid naming class. In that case, we avoid emulating
1625 // 'this->' qualifier to satisfy preconditions of the access checking.
1626 if (NamingClass->getCanonicalDecl() != Cls->getCanonicalDecl() &&
1627 !NamingClass->isDerivedFrom(Cls)) {
1628 NamingClass = Cls;
1629 BaseType = QualType();
1630 }
1631 } else {
1632 // The decl was found outside the C++ class, so only ObjC access checks
1633 // apply. Those do not rely on NamingClass and BaseType, so we clear them
1634 // out.
1635 NamingClass = nullptr;
1636 BaseType = QualType();
1637 }
1638 return Results.getSema().IsSimplyAccessible(ND, NamingClass, BaseType);
1639 }
1640 };
1641 } // namespace
1642
1643 /// Add type specifiers for the current language as keyword results.
AddTypeSpecifierResults(const LangOptions & LangOpts,ResultBuilder & Results)1644 static void AddTypeSpecifierResults(const LangOptions &LangOpts,
1645 ResultBuilder &Results) {
1646 typedef CodeCompletionResult Result;
1647 Results.AddResult(Result("short", CCP_Type));
1648 Results.AddResult(Result("long", CCP_Type));
1649 Results.AddResult(Result("signed", CCP_Type));
1650 Results.AddResult(Result("unsigned", CCP_Type));
1651 Results.AddResult(Result("void", CCP_Type));
1652 Results.AddResult(Result("char", CCP_Type));
1653 Results.AddResult(Result("int", CCP_Type));
1654 Results.AddResult(Result("float", CCP_Type));
1655 Results.AddResult(Result("double", CCP_Type));
1656 Results.AddResult(Result("enum", CCP_Type));
1657 Results.AddResult(Result("struct", CCP_Type));
1658 Results.AddResult(Result("union", CCP_Type));
1659 Results.AddResult(Result("const", CCP_Type));
1660 Results.AddResult(Result("volatile", CCP_Type));
1661
1662 if (LangOpts.C99) {
1663 // C99-specific
1664 Results.AddResult(Result("_Complex", CCP_Type));
1665 Results.AddResult(Result("_Imaginary", CCP_Type));
1666 Results.AddResult(Result("_Bool", CCP_Type));
1667 Results.AddResult(Result("restrict", CCP_Type));
1668 }
1669
1670 CodeCompletionBuilder Builder(Results.getAllocator(),
1671 Results.getCodeCompletionTUInfo());
1672 if (LangOpts.CPlusPlus) {
1673 // C++-specific
1674 Results.AddResult(
1675 Result("bool", CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0)));
1676 Results.AddResult(Result("class", CCP_Type));
1677 Results.AddResult(Result("wchar_t", CCP_Type));
1678
1679 // typename qualified-id
1680 Builder.AddTypedTextChunk("typename");
1681 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1682 Builder.AddPlaceholderChunk("qualifier");
1683 Builder.AddTextChunk("::");
1684 Builder.AddPlaceholderChunk("name");
1685 Results.AddResult(Result(Builder.TakeString()));
1686
1687 if (LangOpts.CPlusPlus11) {
1688 Results.AddResult(Result("auto", CCP_Type));
1689 Results.AddResult(Result("char16_t", CCP_Type));
1690 Results.AddResult(Result("char32_t", CCP_Type));
1691
1692 Builder.AddTypedTextChunk("decltype");
1693 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1694 Builder.AddPlaceholderChunk("expression");
1695 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1696 Results.AddResult(Result(Builder.TakeString()));
1697 }
1698 } else
1699 Results.AddResult(Result("__auto_type", CCP_Type));
1700
1701 // GNU keywords
1702 if (LangOpts.GNUKeywords) {
1703 // FIXME: Enable when we actually support decimal floating point.
1704 // Results.AddResult(Result("_Decimal32"));
1705 // Results.AddResult(Result("_Decimal64"));
1706 // Results.AddResult(Result("_Decimal128"));
1707
1708 Builder.AddTypedTextChunk("typeof");
1709 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1710 Builder.AddPlaceholderChunk("expression");
1711 Results.AddResult(Result(Builder.TakeString()));
1712
1713 Builder.AddTypedTextChunk("typeof");
1714 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1715 Builder.AddPlaceholderChunk("type");
1716 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1717 Results.AddResult(Result(Builder.TakeString()));
1718 }
1719
1720 // Nullability
1721 Results.AddResult(Result("_Nonnull", CCP_Type));
1722 Results.AddResult(Result("_Null_unspecified", CCP_Type));
1723 Results.AddResult(Result("_Nullable", CCP_Type));
1724 }
1725
AddStorageSpecifiers(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts,ResultBuilder & Results)1726 static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
1727 const LangOptions &LangOpts,
1728 ResultBuilder &Results) {
1729 typedef CodeCompletionResult Result;
1730 // Note: we don't suggest either "auto" or "register", because both
1731 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1732 // in C++0x as a type specifier.
1733 Results.AddResult(Result("extern"));
1734 Results.AddResult(Result("static"));
1735
1736 if (LangOpts.CPlusPlus11) {
1737 CodeCompletionAllocator &Allocator = Results.getAllocator();
1738 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1739
1740 // alignas
1741 Builder.AddTypedTextChunk("alignas");
1742 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1743 Builder.AddPlaceholderChunk("expression");
1744 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1745 Results.AddResult(Result(Builder.TakeString()));
1746
1747 Results.AddResult(Result("constexpr"));
1748 Results.AddResult(Result("thread_local"));
1749 }
1750 }
1751
AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts,ResultBuilder & Results)1752 static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
1753 const LangOptions &LangOpts,
1754 ResultBuilder &Results) {
1755 typedef CodeCompletionResult Result;
1756 switch (CCC) {
1757 case Sema::PCC_Class:
1758 case Sema::PCC_MemberTemplate:
1759 if (LangOpts.CPlusPlus) {
1760 Results.AddResult(Result("explicit"));
1761 Results.AddResult(Result("friend"));
1762 Results.AddResult(Result("mutable"));
1763 Results.AddResult(Result("virtual"));
1764 }
1765 LLVM_FALLTHROUGH;
1766
1767 case Sema::PCC_ObjCInterface:
1768 case Sema::PCC_ObjCImplementation:
1769 case Sema::PCC_Namespace:
1770 case Sema::PCC_Template:
1771 if (LangOpts.CPlusPlus || LangOpts.C99)
1772 Results.AddResult(Result("inline"));
1773 break;
1774
1775 case Sema::PCC_ObjCInstanceVariableList:
1776 case Sema::PCC_Expression:
1777 case Sema::PCC_Statement:
1778 case Sema::PCC_ForInit:
1779 case Sema::PCC_Condition:
1780 case Sema::PCC_RecoveryInFunction:
1781 case Sema::PCC_Type:
1782 case Sema::PCC_ParenthesizedExpression:
1783 case Sema::PCC_LocalDeclarationSpecifiers:
1784 break;
1785 }
1786 }
1787
1788 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1789 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1790 static void AddObjCVisibilityResults(const LangOptions &LangOpts,
1791 ResultBuilder &Results, bool NeedAt);
1792 static void AddObjCImplementationResults(const LangOptions &LangOpts,
1793 ResultBuilder &Results, bool NeedAt);
1794 static void AddObjCInterfaceResults(const LangOptions &LangOpts,
1795 ResultBuilder &Results, bool NeedAt);
1796 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
1797
AddTypedefResult(ResultBuilder & Results)1798 static void AddTypedefResult(ResultBuilder &Results) {
1799 CodeCompletionBuilder Builder(Results.getAllocator(),
1800 Results.getCodeCompletionTUInfo());
1801 Builder.AddTypedTextChunk("typedef");
1802 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1803 Builder.AddPlaceholderChunk("type");
1804 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1805 Builder.AddPlaceholderChunk("name");
1806 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1807 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1808 }
1809
WantTypesInContext(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts)1810 static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
1811 const LangOptions &LangOpts) {
1812 switch (CCC) {
1813 case Sema::PCC_Namespace:
1814 case Sema::PCC_Class:
1815 case Sema::PCC_ObjCInstanceVariableList:
1816 case Sema::PCC_Template:
1817 case Sema::PCC_MemberTemplate:
1818 case Sema::PCC_Statement:
1819 case Sema::PCC_RecoveryInFunction:
1820 case Sema::PCC_Type:
1821 case Sema::PCC_ParenthesizedExpression:
1822 case Sema::PCC_LocalDeclarationSpecifiers:
1823 return true;
1824
1825 case Sema::PCC_Expression:
1826 case Sema::PCC_Condition:
1827 return LangOpts.CPlusPlus;
1828
1829 case Sema::PCC_ObjCInterface:
1830 case Sema::PCC_ObjCImplementation:
1831 return false;
1832
1833 case Sema::PCC_ForInit:
1834 return LangOpts.CPlusPlus || LangOpts.ObjC || LangOpts.C99;
1835 }
1836
1837 llvm_unreachable("Invalid ParserCompletionContext!");
1838 }
1839
getCompletionPrintingPolicy(const ASTContext & Context,const Preprocessor & PP)1840 static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
1841 const Preprocessor &PP) {
1842 PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP);
1843 Policy.AnonymousTagLocations = false;
1844 Policy.SuppressStrongLifetime = true;
1845 Policy.SuppressUnwrittenScope = true;
1846 Policy.SuppressScope = true;
1847 return Policy;
1848 }
1849
1850 /// Retrieve a printing policy suitable for code completion.
getCompletionPrintingPolicy(Sema & S)1851 static PrintingPolicy getCompletionPrintingPolicy(Sema &S) {
1852 return getCompletionPrintingPolicy(S.Context, S.PP);
1853 }
1854
1855 /// Retrieve the string representation of the given type as a string
1856 /// that has the appropriate lifetime for code completion.
1857 ///
1858 /// This routine provides a fast path where we provide constant strings for
1859 /// common type names.
GetCompletionTypeString(QualType T,ASTContext & Context,const PrintingPolicy & Policy,CodeCompletionAllocator & Allocator)1860 static const char *GetCompletionTypeString(QualType T, ASTContext &Context,
1861 const PrintingPolicy &Policy,
1862 CodeCompletionAllocator &Allocator) {
1863 if (!T.getLocalQualifiers()) {
1864 // Built-in type names are constant strings.
1865 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T))
1866 return BT->getNameAsCString(Policy);
1867
1868 // Anonymous tag types are constant strings.
1869 if (const TagType *TagT = dyn_cast<TagType>(T))
1870 if (TagDecl *Tag = TagT->getDecl())
1871 if (!Tag->hasNameForLinkage()) {
1872 switch (Tag->getTagKind()) {
1873 case TTK_Struct:
1874 return "struct <anonymous>";
1875 case TTK_Interface:
1876 return "__interface <anonymous>";
1877 case TTK_Class:
1878 return "class <anonymous>";
1879 case TTK_Union:
1880 return "union <anonymous>";
1881 case TTK_Enum:
1882 return "enum <anonymous>";
1883 }
1884 }
1885 }
1886
1887 // Slow path: format the type as a string.
1888 std::string Result;
1889 T.getAsStringInternal(Result, Policy);
1890 return Allocator.CopyString(Result);
1891 }
1892
1893 /// Add a completion for "this", if we're in a member function.
addThisCompletion(Sema & S,ResultBuilder & Results)1894 static void addThisCompletion(Sema &S, ResultBuilder &Results) {
1895 QualType ThisTy = S.getCurrentThisType();
1896 if (ThisTy.isNull())
1897 return;
1898
1899 CodeCompletionAllocator &Allocator = Results.getAllocator();
1900 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1901 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
1902 Builder.AddResultTypeChunk(
1903 GetCompletionTypeString(ThisTy, S.Context, Policy, Allocator));
1904 Builder.AddTypedTextChunk("this");
1905 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1906 }
1907
AddStaticAssertResult(CodeCompletionBuilder & Builder,ResultBuilder & Results,const LangOptions & LangOpts)1908 static void AddStaticAssertResult(CodeCompletionBuilder &Builder,
1909 ResultBuilder &Results,
1910 const LangOptions &LangOpts) {
1911 if (!LangOpts.CPlusPlus11)
1912 return;
1913
1914 Builder.AddTypedTextChunk("static_assert");
1915 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1916 Builder.AddPlaceholderChunk("expression");
1917 Builder.AddChunk(CodeCompletionString::CK_Comma);
1918 Builder.AddPlaceholderChunk("message");
1919 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1920 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1921 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1922 }
1923
AddOverrideResults(ResultBuilder & Results,const CodeCompletionContext & CCContext,CodeCompletionBuilder & Builder)1924 static void AddOverrideResults(ResultBuilder &Results,
1925 const CodeCompletionContext &CCContext,
1926 CodeCompletionBuilder &Builder) {
1927 Sema &S = Results.getSema();
1928 const auto *CR = llvm::dyn_cast<CXXRecordDecl>(S.CurContext);
1929 // If not inside a class/struct/union return empty.
1930 if (!CR)
1931 return;
1932 // First store overrides within current class.
1933 // These are stored by name to make querying fast in the later step.
1934 llvm::StringMap<std::vector<FunctionDecl *>> Overrides;
1935 for (auto *Method : CR->methods()) {
1936 if (!Method->isVirtual() || !Method->getIdentifier())
1937 continue;
1938 Overrides[Method->getName()].push_back(Method);
1939 }
1940
1941 for (const auto &Base : CR->bases()) {
1942 const auto *BR = Base.getType().getTypePtr()->getAsCXXRecordDecl();
1943 if (!BR)
1944 continue;
1945 for (auto *Method : BR->methods()) {
1946 if (!Method->isVirtual() || !Method->getIdentifier())
1947 continue;
1948 const auto it = Overrides.find(Method->getName());
1949 bool IsOverriden = false;
1950 if (it != Overrides.end()) {
1951 for (auto *MD : it->second) {
1952 // If the method in current body is not an overload of this virtual
1953 // function, then it overrides this one.
1954 if (!S.IsOverload(MD, Method, false)) {
1955 IsOverriden = true;
1956 break;
1957 }
1958 }
1959 }
1960 if (!IsOverriden) {
1961 // Generates a new CodeCompletionResult by taking this function and
1962 // converting it into an override declaration with only one chunk in the
1963 // final CodeCompletionString as a TypedTextChunk.
1964 std::string OverrideSignature;
1965 llvm::raw_string_ostream OS(OverrideSignature);
1966 CodeCompletionResult CCR(Method, 0);
1967 PrintingPolicy Policy =
1968 getCompletionPrintingPolicy(S.getASTContext(), S.getPreprocessor());
1969 auto *CCS = CCR.createCodeCompletionStringForOverride(
1970 S.getPreprocessor(), S.getASTContext(), Builder,
1971 /*IncludeBriefComments=*/false, CCContext, Policy);
1972 Results.AddResult(CodeCompletionResult(CCS, Method, CCP_CodePattern));
1973 }
1974 }
1975 }
1976 }
1977
1978 /// Add language constructs that show up for "ordinary" names.
AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,Scope * S,Sema & SemaRef,ResultBuilder & Results)1979 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
1980 Sema &SemaRef, ResultBuilder &Results) {
1981 CodeCompletionAllocator &Allocator = Results.getAllocator();
1982 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1983
1984 typedef CodeCompletionResult Result;
1985 switch (CCC) {
1986 case Sema::PCC_Namespace:
1987 if (SemaRef.getLangOpts().CPlusPlus) {
1988 if (Results.includeCodePatterns()) {
1989 // namespace <identifier> { declarations }
1990 Builder.AddTypedTextChunk("namespace");
1991 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1992 Builder.AddPlaceholderChunk("identifier");
1993 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1994 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1995 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1996 Builder.AddPlaceholderChunk("declarations");
1997 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1998 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1999 Results.AddResult(Result(Builder.TakeString()));
2000 }
2001
2002 // namespace identifier = identifier ;
2003 Builder.AddTypedTextChunk("namespace");
2004 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2005 Builder.AddPlaceholderChunk("name");
2006 Builder.AddChunk(CodeCompletionString::CK_Equal);
2007 Builder.AddPlaceholderChunk("namespace");
2008 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2009 Results.AddResult(Result(Builder.TakeString()));
2010
2011 // Using directives
2012 Builder.AddTypedTextChunk("using namespace");
2013 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2014 Builder.AddPlaceholderChunk("identifier");
2015 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2016 Results.AddResult(Result(Builder.TakeString()));
2017
2018 // asm(string-literal)
2019 Builder.AddTypedTextChunk("asm");
2020 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2021 Builder.AddPlaceholderChunk("string-literal");
2022 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2023 Results.AddResult(Result(Builder.TakeString()));
2024
2025 if (Results.includeCodePatterns()) {
2026 // Explicit template instantiation
2027 Builder.AddTypedTextChunk("template");
2028 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2029 Builder.AddPlaceholderChunk("declaration");
2030 Results.AddResult(Result(Builder.TakeString()));
2031 } else {
2032 Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword));
2033 }
2034 }
2035
2036 if (SemaRef.getLangOpts().ObjC)
2037 AddObjCTopLevelResults(Results, true);
2038
2039 AddTypedefResult(Results);
2040 LLVM_FALLTHROUGH;
2041
2042 case Sema::PCC_Class:
2043 if (SemaRef.getLangOpts().CPlusPlus) {
2044 // Using declaration
2045 Builder.AddTypedTextChunk("using");
2046 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2047 Builder.AddPlaceholderChunk("qualifier");
2048 Builder.AddTextChunk("::");
2049 Builder.AddPlaceholderChunk("name");
2050 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2051 Results.AddResult(Result(Builder.TakeString()));
2052
2053 // using typename qualifier::name (only in a dependent context)
2054 if (SemaRef.CurContext->isDependentContext()) {
2055 Builder.AddTypedTextChunk("using typename");
2056 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2057 Builder.AddPlaceholderChunk("qualifier");
2058 Builder.AddTextChunk("::");
2059 Builder.AddPlaceholderChunk("name");
2060 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2061 Results.AddResult(Result(Builder.TakeString()));
2062 }
2063
2064 AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
2065
2066 if (CCC == Sema::PCC_Class) {
2067 AddTypedefResult(Results);
2068
2069 bool IsNotInheritanceScope =
2070 !(S->getFlags() & Scope::ClassInheritanceScope);
2071 // public:
2072 Builder.AddTypedTextChunk("public");
2073 if (IsNotInheritanceScope && Results.includeCodePatterns())
2074 Builder.AddChunk(CodeCompletionString::CK_Colon);
2075 Results.AddResult(Result(Builder.TakeString()));
2076
2077 // protected:
2078 Builder.AddTypedTextChunk("protected");
2079 if (IsNotInheritanceScope && Results.includeCodePatterns())
2080 Builder.AddChunk(CodeCompletionString::CK_Colon);
2081 Results.AddResult(Result(Builder.TakeString()));
2082
2083 // private:
2084 Builder.AddTypedTextChunk("private");
2085 if (IsNotInheritanceScope && Results.includeCodePatterns())
2086 Builder.AddChunk(CodeCompletionString::CK_Colon);
2087 Results.AddResult(Result(Builder.TakeString()));
2088
2089 // FIXME: This adds override results only if we are at the first word of
2090 // the declaration/definition. Also call this from other sides to have
2091 // more use-cases.
2092 AddOverrideResults(Results, CodeCompletionContext::CCC_ClassStructUnion,
2093 Builder);
2094 }
2095 }
2096 LLVM_FALLTHROUGH;
2097
2098 case Sema::PCC_Template:
2099 case Sema::PCC_MemberTemplate:
2100 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
2101 // template < parameters >
2102 Builder.AddTypedTextChunk("template");
2103 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2104 Builder.AddPlaceholderChunk("parameters");
2105 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2106 Results.AddResult(Result(Builder.TakeString()));
2107 } else {
2108 Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword));
2109 }
2110
2111 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2112 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2113 break;
2114
2115 case Sema::PCC_ObjCInterface:
2116 AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true);
2117 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2118 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2119 break;
2120
2121 case Sema::PCC_ObjCImplementation:
2122 AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true);
2123 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2124 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2125 break;
2126
2127 case Sema::PCC_ObjCInstanceVariableList:
2128 AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true);
2129 break;
2130
2131 case Sema::PCC_RecoveryInFunction:
2132 case Sema::PCC_Statement: {
2133 AddTypedefResult(Results);
2134
2135 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() &&
2136 SemaRef.getLangOpts().CXXExceptions) {
2137 Builder.AddTypedTextChunk("try");
2138 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2139 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2140 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2141 Builder.AddPlaceholderChunk("statements");
2142 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2143 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2144 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2145 Builder.AddTextChunk("catch");
2146 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2147 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2148 Builder.AddPlaceholderChunk("declaration");
2149 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2150 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2151 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2152 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2153 Builder.AddPlaceholderChunk("statements");
2154 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2155 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2156 Results.AddResult(Result(Builder.TakeString()));
2157 }
2158 if (SemaRef.getLangOpts().ObjC)
2159 AddObjCStatementResults(Results, true);
2160
2161 if (Results.includeCodePatterns()) {
2162 // if (condition) { statements }
2163 Builder.AddTypedTextChunk("if");
2164 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2165 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2166 if (SemaRef.getLangOpts().CPlusPlus)
2167 Builder.AddPlaceholderChunk("condition");
2168 else
2169 Builder.AddPlaceholderChunk("expression");
2170 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2171 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2172 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2173 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2174 Builder.AddPlaceholderChunk("statements");
2175 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2176 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2177 Results.AddResult(Result(Builder.TakeString()));
2178
2179 // switch (condition) { }
2180 Builder.AddTypedTextChunk("switch");
2181 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2182 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2183 if (SemaRef.getLangOpts().CPlusPlus)
2184 Builder.AddPlaceholderChunk("condition");
2185 else
2186 Builder.AddPlaceholderChunk("expression");
2187 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2188 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2189 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2190 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2191 Builder.AddPlaceholderChunk("cases");
2192 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2193 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2194 Results.AddResult(Result(Builder.TakeString()));
2195 }
2196
2197 // Switch-specific statements.
2198 if (SemaRef.getCurFunction() &&
2199 !SemaRef.getCurFunction()->SwitchStack.empty()) {
2200 // case expression:
2201 Builder.AddTypedTextChunk("case");
2202 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2203 Builder.AddPlaceholderChunk("expression");
2204 Builder.AddChunk(CodeCompletionString::CK_Colon);
2205 Results.AddResult(Result(Builder.TakeString()));
2206
2207 // default:
2208 Builder.AddTypedTextChunk("default");
2209 Builder.AddChunk(CodeCompletionString::CK_Colon);
2210 Results.AddResult(Result(Builder.TakeString()));
2211 }
2212
2213 if (Results.includeCodePatterns()) {
2214 /// while (condition) { statements }
2215 Builder.AddTypedTextChunk("while");
2216 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2217 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2218 if (SemaRef.getLangOpts().CPlusPlus)
2219 Builder.AddPlaceholderChunk("condition");
2220 else
2221 Builder.AddPlaceholderChunk("expression");
2222 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2223 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2224 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2225 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2226 Builder.AddPlaceholderChunk("statements");
2227 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2228 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2229 Results.AddResult(Result(Builder.TakeString()));
2230
2231 // do { statements } while ( expression );
2232 Builder.AddTypedTextChunk("do");
2233 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2234 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2235 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2236 Builder.AddPlaceholderChunk("statements");
2237 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2238 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2239 Builder.AddTextChunk("while");
2240 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2241 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2242 Builder.AddPlaceholderChunk("expression");
2243 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2244 Results.AddResult(Result(Builder.TakeString()));
2245
2246 // for ( for-init-statement ; condition ; expression ) { statements }
2247 Builder.AddTypedTextChunk("for");
2248 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2249 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2250 if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99)
2251 Builder.AddPlaceholderChunk("init-statement");
2252 else
2253 Builder.AddPlaceholderChunk("init-expression");
2254 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2255 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2256 Builder.AddPlaceholderChunk("condition");
2257 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2258 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2259 Builder.AddPlaceholderChunk("inc-expression");
2260 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2261 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2262 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2263 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2264 Builder.AddPlaceholderChunk("statements");
2265 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2266 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2267 Results.AddResult(Result(Builder.TakeString()));
2268 }
2269
2270 if (S->getContinueParent()) {
2271 // continue ;
2272 Builder.AddTypedTextChunk("continue");
2273 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2274 Results.AddResult(Result(Builder.TakeString()));
2275 }
2276
2277 if (S->getBreakParent()) {
2278 // break ;
2279 Builder.AddTypedTextChunk("break");
2280 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2281 Results.AddResult(Result(Builder.TakeString()));
2282 }
2283
2284 // "return expression ;" or "return ;", depending on the return type.
2285 QualType ReturnType;
2286 if (const auto *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
2287 ReturnType = Function->getReturnType();
2288 else if (const auto *Method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
2289 ReturnType = Method->getReturnType();
2290 else if (SemaRef.getCurBlock() &&
2291 !SemaRef.getCurBlock()->ReturnType.isNull())
2292 ReturnType = SemaRef.getCurBlock()->ReturnType;;
2293 if (ReturnType.isNull() || ReturnType->isVoidType()) {
2294 Builder.AddTypedTextChunk("return");
2295 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2296 Results.AddResult(Result(Builder.TakeString()));
2297 } else {
2298 assert(!ReturnType.isNull());
2299 // "return expression ;"
2300 Builder.AddTypedTextChunk("return");
2301 Builder.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace);
2302 Builder.AddPlaceholderChunk("expression");
2303 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2304 Results.AddResult(Result(Builder.TakeString()));
2305 // When boolean, also add 'return true;' and 'return false;'.
2306 if (ReturnType->isBooleanType()) {
2307 Builder.AddTypedTextChunk("return true");
2308 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2309 Results.AddResult(Result(Builder.TakeString()));
2310
2311 Builder.AddTypedTextChunk("return false");
2312 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2313 Results.AddResult(Result(Builder.TakeString()));
2314 }
2315 // For pointers, suggest 'return nullptr' in C++.
2316 if (SemaRef.getLangOpts().CPlusPlus11 &&
2317 (ReturnType->isPointerType() || ReturnType->isMemberPointerType())) {
2318 Builder.AddTypedTextChunk("return nullptr");
2319 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2320 Results.AddResult(Result(Builder.TakeString()));
2321 }
2322 }
2323
2324 // goto identifier ;
2325 Builder.AddTypedTextChunk("goto");
2326 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2327 Builder.AddPlaceholderChunk("label");
2328 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2329 Results.AddResult(Result(Builder.TakeString()));
2330
2331 // Using directives
2332 Builder.AddTypedTextChunk("using namespace");
2333 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2334 Builder.AddPlaceholderChunk("identifier");
2335 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2336 Results.AddResult(Result(Builder.TakeString()));
2337
2338 AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
2339 }
2340 LLVM_FALLTHROUGH;
2341
2342 // Fall through (for statement expressions).
2343 case Sema::PCC_ForInit:
2344 case Sema::PCC_Condition:
2345 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2346 // Fall through: conditions and statements can have expressions.
2347 LLVM_FALLTHROUGH;
2348
2349 case Sema::PCC_ParenthesizedExpression:
2350 if (SemaRef.getLangOpts().ObjCAutoRefCount &&
2351 CCC == Sema::PCC_ParenthesizedExpression) {
2352 // (__bridge <type>)<expression>
2353 Builder.AddTypedTextChunk("__bridge");
2354 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2355 Builder.AddPlaceholderChunk("type");
2356 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2357 Builder.AddPlaceholderChunk("expression");
2358 Results.AddResult(Result(Builder.TakeString()));
2359
2360 // (__bridge_transfer <Objective-C type>)<expression>
2361 Builder.AddTypedTextChunk("__bridge_transfer");
2362 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2363 Builder.AddPlaceholderChunk("Objective-C type");
2364 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2365 Builder.AddPlaceholderChunk("expression");
2366 Results.AddResult(Result(Builder.TakeString()));
2367
2368 // (__bridge_retained <CF type>)<expression>
2369 Builder.AddTypedTextChunk("__bridge_retained");
2370 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2371 Builder.AddPlaceholderChunk("CF type");
2372 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2373 Builder.AddPlaceholderChunk("expression");
2374 Results.AddResult(Result(Builder.TakeString()));
2375 }
2376 // Fall through
2377 LLVM_FALLTHROUGH;
2378
2379 case Sema::PCC_Expression: {
2380 if (SemaRef.getLangOpts().CPlusPlus) {
2381 // 'this', if we're in a non-static member function.
2382 addThisCompletion(SemaRef, Results);
2383
2384 // true
2385 Builder.AddResultTypeChunk("bool");
2386 Builder.AddTypedTextChunk("true");
2387 Results.AddResult(Result(Builder.TakeString()));
2388
2389 // false
2390 Builder.AddResultTypeChunk("bool");
2391 Builder.AddTypedTextChunk("false");
2392 Results.AddResult(Result(Builder.TakeString()));
2393
2394 if (SemaRef.getLangOpts().RTTI) {
2395 // dynamic_cast < type-id > ( expression )
2396 Builder.AddTypedTextChunk("dynamic_cast");
2397 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2398 Builder.AddPlaceholderChunk("type");
2399 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2400 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2401 Builder.AddPlaceholderChunk("expression");
2402 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2403 Results.AddResult(Result(Builder.TakeString()));
2404 }
2405
2406 // static_cast < type-id > ( expression )
2407 Builder.AddTypedTextChunk("static_cast");
2408 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2409 Builder.AddPlaceholderChunk("type");
2410 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2411 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2412 Builder.AddPlaceholderChunk("expression");
2413 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2414 Results.AddResult(Result(Builder.TakeString()));
2415
2416 // reinterpret_cast < type-id > ( expression )
2417 Builder.AddTypedTextChunk("reinterpret_cast");
2418 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2419 Builder.AddPlaceholderChunk("type");
2420 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2421 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2422 Builder.AddPlaceholderChunk("expression");
2423 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2424 Results.AddResult(Result(Builder.TakeString()));
2425
2426 // const_cast < type-id > ( expression )
2427 Builder.AddTypedTextChunk("const_cast");
2428 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2429 Builder.AddPlaceholderChunk("type");
2430 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2431 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2432 Builder.AddPlaceholderChunk("expression");
2433 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2434 Results.AddResult(Result(Builder.TakeString()));
2435
2436 if (SemaRef.getLangOpts().RTTI) {
2437 // typeid ( expression-or-type )
2438 Builder.AddResultTypeChunk("std::type_info");
2439 Builder.AddTypedTextChunk("typeid");
2440 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2441 Builder.AddPlaceholderChunk("expression-or-type");
2442 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2443 Results.AddResult(Result(Builder.TakeString()));
2444 }
2445
2446 // new T ( ... )
2447 Builder.AddTypedTextChunk("new");
2448 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2449 Builder.AddPlaceholderChunk("type");
2450 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2451 Builder.AddPlaceholderChunk("expressions");
2452 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2453 Results.AddResult(Result(Builder.TakeString()));
2454
2455 // new T [ ] ( ... )
2456 Builder.AddTypedTextChunk("new");
2457 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2458 Builder.AddPlaceholderChunk("type");
2459 Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
2460 Builder.AddPlaceholderChunk("size");
2461 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
2462 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2463 Builder.AddPlaceholderChunk("expressions");
2464 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2465 Results.AddResult(Result(Builder.TakeString()));
2466
2467 // delete expression
2468 Builder.AddResultTypeChunk("void");
2469 Builder.AddTypedTextChunk("delete");
2470 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2471 Builder.AddPlaceholderChunk("expression");
2472 Results.AddResult(Result(Builder.TakeString()));
2473
2474 // delete [] expression
2475 Builder.AddResultTypeChunk("void");
2476 Builder.AddTypedTextChunk("delete");
2477 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2478 Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
2479 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
2480 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2481 Builder.AddPlaceholderChunk("expression");
2482 Results.AddResult(Result(Builder.TakeString()));
2483
2484 if (SemaRef.getLangOpts().CXXExceptions) {
2485 // throw expression
2486 Builder.AddResultTypeChunk("void");
2487 Builder.AddTypedTextChunk("throw");
2488 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2489 Builder.AddPlaceholderChunk("expression");
2490 Results.AddResult(Result(Builder.TakeString()));
2491 }
2492
2493 // FIXME: Rethrow?
2494
2495 if (SemaRef.getLangOpts().CPlusPlus11) {
2496 // nullptr
2497 Builder.AddResultTypeChunk("std::nullptr_t");
2498 Builder.AddTypedTextChunk("nullptr");
2499 Results.AddResult(Result(Builder.TakeString()));
2500
2501 // alignof
2502 Builder.AddResultTypeChunk("size_t");
2503 Builder.AddTypedTextChunk("alignof");
2504 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2505 Builder.AddPlaceholderChunk("type");
2506 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2507 Results.AddResult(Result(Builder.TakeString()));
2508
2509 // noexcept
2510 Builder.AddResultTypeChunk("bool");
2511 Builder.AddTypedTextChunk("noexcept");
2512 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2513 Builder.AddPlaceholderChunk("expression");
2514 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2515 Results.AddResult(Result(Builder.TakeString()));
2516
2517 // sizeof... expression
2518 Builder.AddResultTypeChunk("size_t");
2519 Builder.AddTypedTextChunk("sizeof...");
2520 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2521 Builder.AddPlaceholderChunk("parameter-pack");
2522 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2523 Results.AddResult(Result(Builder.TakeString()));
2524 }
2525 }
2526
2527 if (SemaRef.getLangOpts().ObjC) {
2528 // Add "super", if we're in an Objective-C class with a superclass.
2529 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
2530 // The interface can be NULL.
2531 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
2532 if (ID->getSuperClass()) {
2533 std::string SuperType;
2534 SuperType = ID->getSuperClass()->getNameAsString();
2535 if (Method->isInstanceMethod())
2536 SuperType += " *";
2537
2538 Builder.AddResultTypeChunk(Allocator.CopyString(SuperType));
2539 Builder.AddTypedTextChunk("super");
2540 Results.AddResult(Result(Builder.TakeString()));
2541 }
2542 }
2543
2544 AddObjCExpressionResults(Results, true);
2545 }
2546
2547 if (SemaRef.getLangOpts().C11) {
2548 // _Alignof
2549 Builder.AddResultTypeChunk("size_t");
2550 if (SemaRef.PP.isMacroDefined("alignof"))
2551 Builder.AddTypedTextChunk("alignof");
2552 else
2553 Builder.AddTypedTextChunk("_Alignof");
2554 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2555 Builder.AddPlaceholderChunk("type");
2556 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2557 Results.AddResult(Result(Builder.TakeString()));
2558 }
2559
2560 // sizeof expression
2561 Builder.AddResultTypeChunk("size_t");
2562 Builder.AddTypedTextChunk("sizeof");
2563 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2564 Builder.AddPlaceholderChunk("expression-or-type");
2565 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2566 Results.AddResult(Result(Builder.TakeString()));
2567 break;
2568 }
2569
2570 case Sema::PCC_Type:
2571 case Sema::PCC_LocalDeclarationSpecifiers:
2572 break;
2573 }
2574
2575 if (WantTypesInContext(CCC, SemaRef.getLangOpts()))
2576 AddTypeSpecifierResults(SemaRef.getLangOpts(), Results);
2577
2578 if (SemaRef.getLangOpts().CPlusPlus && CCC != Sema::PCC_Type)
2579 Results.AddResult(Result("operator"));
2580 }
2581
2582 /// If the given declaration has an associated type, add it as a result
2583 /// type chunk.
AddResultTypeChunk(ASTContext & Context,const PrintingPolicy & Policy,const NamedDecl * ND,QualType BaseType,CodeCompletionBuilder & Result)2584 static void AddResultTypeChunk(ASTContext &Context,
2585 const PrintingPolicy &Policy,
2586 const NamedDecl *ND, QualType BaseType,
2587 CodeCompletionBuilder &Result) {
2588 if (!ND)
2589 return;
2590
2591 // Skip constructors and conversion functions, which have their return types
2592 // built into their names.
2593 if (isConstructor(ND) || isa<CXXConversionDecl>(ND))
2594 return;
2595
2596 // Determine the type of the declaration (if it has a type).
2597 QualType T;
2598 if (const FunctionDecl *Function = ND->getAsFunction())
2599 T = Function->getReturnType();
2600 else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) {
2601 if (!BaseType.isNull())
2602 T = Method->getSendResultType(BaseType);
2603 else
2604 T = Method->getReturnType();
2605 } else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND)) {
2606 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
2607 T = clang::TypeName::getFullyQualifiedType(T, Context);
2608 } else if (isa<UnresolvedUsingValueDecl>(ND)) {
2609 /* Do nothing: ignore unresolved using declarations*/
2610 } else if (const auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) {
2611 if (!BaseType.isNull())
2612 T = Ivar->getUsageType(BaseType);
2613 else
2614 T = Ivar->getType();
2615 } else if (const auto *Value = dyn_cast<ValueDecl>(ND)) {
2616 T = Value->getType();
2617 } else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND)) {
2618 if (!BaseType.isNull())
2619 T = Property->getUsageType(BaseType);
2620 else
2621 T = Property->getType();
2622 }
2623
2624 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
2625 return;
2626
2627 Result.AddResultTypeChunk(
2628 GetCompletionTypeString(T, Context, Policy, Result.getAllocator()));
2629 }
2630
MaybeAddSentinel(Preprocessor & PP,const NamedDecl * FunctionOrMethod,CodeCompletionBuilder & Result)2631 static void MaybeAddSentinel(Preprocessor &PP,
2632 const NamedDecl *FunctionOrMethod,
2633 CodeCompletionBuilder &Result) {
2634 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
2635 if (Sentinel->getSentinel() == 0) {
2636 if (PP.getLangOpts().ObjC && PP.isMacroDefined("nil"))
2637 Result.AddTextChunk(", nil");
2638 else if (PP.isMacroDefined("NULL"))
2639 Result.AddTextChunk(", NULL");
2640 else
2641 Result.AddTextChunk(", (void*)0");
2642 }
2643 }
2644
formatObjCParamQualifiers(unsigned ObjCQuals,QualType & Type)2645 static std::string formatObjCParamQualifiers(unsigned ObjCQuals,
2646 QualType &Type) {
2647 std::string Result;
2648 if (ObjCQuals & Decl::OBJC_TQ_In)
2649 Result += "in ";
2650 else if (ObjCQuals & Decl::OBJC_TQ_Inout)
2651 Result += "inout ";
2652 else if (ObjCQuals & Decl::OBJC_TQ_Out)
2653 Result += "out ";
2654 if (ObjCQuals & Decl::OBJC_TQ_Bycopy)
2655 Result += "bycopy ";
2656 else if (ObjCQuals & Decl::OBJC_TQ_Byref)
2657 Result += "byref ";
2658 if (ObjCQuals & Decl::OBJC_TQ_Oneway)
2659 Result += "oneway ";
2660 if (ObjCQuals & Decl::OBJC_TQ_CSNullability) {
2661 if (auto nullability = AttributedType::stripOuterNullability(Type)) {
2662 switch (*nullability) {
2663 case NullabilityKind::NonNull:
2664 Result += "nonnull ";
2665 break;
2666
2667 case NullabilityKind::Nullable:
2668 Result += "nullable ";
2669 break;
2670
2671 case NullabilityKind::Unspecified:
2672 Result += "null_unspecified ";
2673 break;
2674 }
2675 }
2676 }
2677 return Result;
2678 }
2679
2680 /// Tries to find the most appropriate type location for an Objective-C
2681 /// block placeholder.
2682 ///
2683 /// This function ignores things like typedefs and qualifiers in order to
2684 /// present the most relevant and accurate block placeholders in code completion
2685 /// results.
findTypeLocationForBlockDecl(const TypeSourceInfo * TSInfo,FunctionTypeLoc & Block,FunctionProtoTypeLoc & BlockProto,bool SuppressBlock=false)2686 static void findTypeLocationForBlockDecl(const TypeSourceInfo *TSInfo,
2687 FunctionTypeLoc &Block,
2688 FunctionProtoTypeLoc &BlockProto,
2689 bool SuppressBlock = false) {
2690 if (!TSInfo)
2691 return;
2692 TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
2693 while (true) {
2694 // Look through typedefs.
2695 if (!SuppressBlock) {
2696 if (TypedefTypeLoc TypedefTL = TL.getAs<TypedefTypeLoc>()) {
2697 if (TypeSourceInfo *InnerTSInfo =
2698 TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) {
2699 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
2700 continue;
2701 }
2702 }
2703
2704 // Look through qualified types
2705 if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) {
2706 TL = QualifiedTL.getUnqualifiedLoc();
2707 continue;
2708 }
2709
2710 if (AttributedTypeLoc AttrTL = TL.getAs<AttributedTypeLoc>()) {
2711 TL = AttrTL.getModifiedLoc();
2712 continue;
2713 }
2714 }
2715
2716 // Try to get the function prototype behind the block pointer type,
2717 // then we're done.
2718 if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) {
2719 TL = BlockPtr.getPointeeLoc().IgnoreParens();
2720 Block = TL.getAs<FunctionTypeLoc>();
2721 BlockProto = TL.getAs<FunctionProtoTypeLoc>();
2722 }
2723 break;
2724 }
2725 }
2726
2727 static std::string
2728 formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl,
2729 FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto,
2730 bool SuppressBlockName = false,
2731 bool SuppressBlock = false,
2732 Optional<ArrayRef<QualType>> ObjCSubsts = None);
2733
2734 static std::string
FormatFunctionParameter(const PrintingPolicy & Policy,const ParmVarDecl * Param,bool SuppressName=false,bool SuppressBlock=false,Optional<ArrayRef<QualType>> ObjCSubsts=None)2735 FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param,
2736 bool SuppressName = false, bool SuppressBlock = false,
2737 Optional<ArrayRef<QualType>> ObjCSubsts = None) {
2738 // Params are unavailable in FunctionTypeLoc if the FunctionType is invalid.
2739 // It would be better to pass in the param Type, which is usually avaliable.
2740 // But this case is rare, so just pretend we fell back to int as elsewhere.
2741 if (!Param)
2742 return "int";
2743 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
2744 if (Param->getType()->isDependentType() ||
2745 !Param->getType()->isBlockPointerType()) {
2746 // The argument for a dependent or non-block parameter is a placeholder
2747 // containing that parameter's type.
2748 std::string Result;
2749
2750 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
2751 Result = Param->getIdentifier()->getName();
2752
2753 QualType Type = Param->getType();
2754 if (ObjCSubsts)
2755 Type = Type.substObjCTypeArgs(Param->getASTContext(), *ObjCSubsts,
2756 ObjCSubstitutionContext::Parameter);
2757 if (ObjCMethodParam) {
2758 Result =
2759 "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier(), Type);
2760 Result += Type.getAsString(Policy) + ")";
2761 if (Param->getIdentifier() && !SuppressName)
2762 Result += Param->getIdentifier()->getName();
2763 } else {
2764 Type.getAsStringInternal(Result, Policy);
2765 }
2766 return Result;
2767 }
2768
2769 // The argument for a block pointer parameter is a block literal with
2770 // the appropriate type.
2771 FunctionTypeLoc Block;
2772 FunctionProtoTypeLoc BlockProto;
2773 findTypeLocationForBlockDecl(Param->getTypeSourceInfo(), Block, BlockProto,
2774 SuppressBlock);
2775 // Try to retrieve the block type information from the property if this is a
2776 // parameter in a setter.
2777 if (!Block && ObjCMethodParam &&
2778 cast<ObjCMethodDecl>(Param->getDeclContext())->isPropertyAccessor()) {
2779 if (const auto *PD = cast<ObjCMethodDecl>(Param->getDeclContext())
2780 ->findPropertyDecl(/*CheckOverrides=*/false))
2781 findTypeLocationForBlockDecl(PD->getTypeSourceInfo(), Block, BlockProto,
2782 SuppressBlock);
2783 }
2784
2785 if (!Block) {
2786 // We were unable to find a FunctionProtoTypeLoc with parameter names
2787 // for the block; just use the parameter type as a placeholder.
2788 std::string Result;
2789 if (!ObjCMethodParam && Param->getIdentifier())
2790 Result = Param->getIdentifier()->getName();
2791
2792 QualType Type = Param->getType().getUnqualifiedType();
2793
2794 if (ObjCMethodParam) {
2795 Result = Type.getAsString(Policy);
2796 std::string Quals =
2797 formatObjCParamQualifiers(Param->getObjCDeclQualifier(), Type);
2798 if (!Quals.empty())
2799 Result = "(" + Quals + " " + Result + ")";
2800 if (Result.back() != ')')
2801 Result += " ";
2802 if (Param->getIdentifier())
2803 Result += Param->getIdentifier()->getName();
2804 } else {
2805 Type.getAsStringInternal(Result, Policy);
2806 }
2807
2808 return Result;
2809 }
2810
2811 // We have the function prototype behind the block pointer type, as it was
2812 // written in the source.
2813 return formatBlockPlaceholder(Policy, Param, Block, BlockProto,
2814 /*SuppressBlockName=*/false, SuppressBlock,
2815 ObjCSubsts);
2816 }
2817
2818 /// Returns a placeholder string that corresponds to an Objective-C block
2819 /// declaration.
2820 ///
2821 /// \param BlockDecl A declaration with an Objective-C block type.
2822 ///
2823 /// \param Block The most relevant type location for that block type.
2824 ///
2825 /// \param SuppressBlockName Determines whether or not the name of the block
2826 /// declaration is included in the resulting string.
2827 static std::string
formatBlockPlaceholder(const PrintingPolicy & Policy,const NamedDecl * BlockDecl,FunctionTypeLoc & Block,FunctionProtoTypeLoc & BlockProto,bool SuppressBlockName,bool SuppressBlock,Optional<ArrayRef<QualType>> ObjCSubsts)2828 formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl,
2829 FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto,
2830 bool SuppressBlockName, bool SuppressBlock,
2831 Optional<ArrayRef<QualType>> ObjCSubsts) {
2832 std::string Result;
2833 QualType ResultType = Block.getTypePtr()->getReturnType();
2834 if (ObjCSubsts)
2835 ResultType =
2836 ResultType.substObjCTypeArgs(BlockDecl->getASTContext(), *ObjCSubsts,
2837 ObjCSubstitutionContext::Result);
2838 if (!ResultType->isVoidType() || SuppressBlock)
2839 ResultType.getAsStringInternal(Result, Policy);
2840
2841 // Format the parameter list.
2842 std::string Params;
2843 if (!BlockProto || Block.getNumParams() == 0) {
2844 if (BlockProto && BlockProto.getTypePtr()->isVariadic())
2845 Params = "(...)";
2846 else
2847 Params = "(void)";
2848 } else {
2849 Params += "(";
2850 for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) {
2851 if (I)
2852 Params += ", ";
2853 Params += FormatFunctionParameter(Policy, Block.getParam(I),
2854 /*SuppressName=*/false,
2855 /*SuppressBlock=*/true, ObjCSubsts);
2856
2857 if (I == N - 1 && BlockProto.getTypePtr()->isVariadic())
2858 Params += ", ...";
2859 }
2860 Params += ")";
2861 }
2862
2863 if (SuppressBlock) {
2864 // Format as a parameter.
2865 Result = Result + " (^";
2866 if (!SuppressBlockName && BlockDecl->getIdentifier())
2867 Result += BlockDecl->getIdentifier()->getName();
2868 Result += ")";
2869 Result += Params;
2870 } else {
2871 // Format as a block literal argument.
2872 Result = '^' + Result;
2873 Result += Params;
2874
2875 if (!SuppressBlockName && BlockDecl->getIdentifier())
2876 Result += BlockDecl->getIdentifier()->getName();
2877 }
2878
2879 return Result;
2880 }
2881
GetDefaultValueString(const ParmVarDecl * Param,const SourceManager & SM,const LangOptions & LangOpts)2882 static std::string GetDefaultValueString(const ParmVarDecl *Param,
2883 const SourceManager &SM,
2884 const LangOptions &LangOpts) {
2885 const SourceRange SrcRange = Param->getDefaultArgRange();
2886 CharSourceRange CharSrcRange = CharSourceRange::getTokenRange(SrcRange);
2887 bool Invalid = CharSrcRange.isInvalid();
2888 if (Invalid)
2889 return "";
2890 StringRef srcText =
2891 Lexer::getSourceText(CharSrcRange, SM, LangOpts, &Invalid);
2892 if (Invalid)
2893 return "";
2894
2895 if (srcText.empty() || srcText == "=") {
2896 // Lexer can't determine the value.
2897 // This happens if the code is incorrect (for example class is forward
2898 // declared).
2899 return "";
2900 }
2901 std::string DefValue(srcText.str());
2902 // FIXME: remove this check if the Lexer::getSourceText value is fixed and
2903 // this value always has (or always does not have) '=' in front of it
2904 if (DefValue.at(0) != '=') {
2905 // If we don't have '=' in front of value.
2906 // Lexer returns built-in types values without '=' and user-defined types
2907 // values with it.
2908 return " = " + DefValue;
2909 }
2910 return " " + DefValue;
2911 }
2912
2913 /// Add function parameter chunks to the given code completion string.
AddFunctionParameterChunks(Preprocessor & PP,const PrintingPolicy & Policy,const FunctionDecl * Function,CodeCompletionBuilder & Result,unsigned Start=0,bool InOptional=false)2914 static void AddFunctionParameterChunks(Preprocessor &PP,
2915 const PrintingPolicy &Policy,
2916 const FunctionDecl *Function,
2917 CodeCompletionBuilder &Result,
2918 unsigned Start = 0,
2919 bool InOptional = false) {
2920 bool FirstParameter = true;
2921
2922 for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) {
2923 const ParmVarDecl *Param = Function->getParamDecl(P);
2924
2925 if (Param->hasDefaultArg() && !InOptional) {
2926 // When we see an optional default argument, put that argument and
2927 // the remaining default arguments into a new, optional string.
2928 CodeCompletionBuilder Opt(Result.getAllocator(),
2929 Result.getCodeCompletionTUInfo());
2930 if (!FirstParameter)
2931 Opt.AddChunk(CodeCompletionString::CK_Comma);
2932 AddFunctionParameterChunks(PP, Policy, Function, Opt, P, true);
2933 Result.AddOptionalChunk(Opt.TakeString());
2934 break;
2935 }
2936
2937 if (FirstParameter)
2938 FirstParameter = false;
2939 else
2940 Result.AddChunk(CodeCompletionString::CK_Comma);
2941
2942 InOptional = false;
2943
2944 // Format the placeholder string.
2945 std::string PlaceholderStr = FormatFunctionParameter(Policy, Param);
2946 if (Param->hasDefaultArg())
2947 PlaceholderStr +=
2948 GetDefaultValueString(Param, PP.getSourceManager(), PP.getLangOpts());
2949
2950 if (Function->isVariadic() && P == N - 1)
2951 PlaceholderStr += ", ...";
2952
2953 // Add the placeholder string.
2954 Result.AddPlaceholderChunk(
2955 Result.getAllocator().CopyString(PlaceholderStr));
2956 }
2957
2958 if (const auto *Proto = Function->getType()->getAs<FunctionProtoType>())
2959 if (Proto->isVariadic()) {
2960 if (Proto->getNumParams() == 0)
2961 Result.AddPlaceholderChunk("...");
2962
2963 MaybeAddSentinel(PP, Function, Result);
2964 }
2965 }
2966
2967 /// 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)2968 static void AddTemplateParameterChunks(
2969 ASTContext &Context, const PrintingPolicy &Policy,
2970 const TemplateDecl *Template, CodeCompletionBuilder &Result,
2971 unsigned MaxParameters = 0, unsigned Start = 0, bool InDefaultArg = false) {
2972 bool FirstParameter = true;
2973
2974 // Prefer to take the template parameter names from the first declaration of
2975 // the template.
2976 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
2977
2978 TemplateParameterList *Params = Template->getTemplateParameters();
2979 TemplateParameterList::iterator PEnd = Params->end();
2980 if (MaxParameters)
2981 PEnd = Params->begin() + MaxParameters;
2982 for (TemplateParameterList::iterator P = Params->begin() + Start; P != PEnd;
2983 ++P) {
2984 bool HasDefaultArg = false;
2985 std::string PlaceholderStr;
2986 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
2987 if (TTP->wasDeclaredWithTypename())
2988 PlaceholderStr = "typename";
2989 else if (const auto *TC = TTP->getTypeConstraint()) {
2990 llvm::raw_string_ostream OS(PlaceholderStr);
2991 TC->print(OS, Policy);
2992 OS.flush();
2993 } else
2994 PlaceholderStr = "class";
2995
2996 if (TTP->getIdentifier()) {
2997 PlaceholderStr += ' ';
2998 PlaceholderStr += TTP->getIdentifier()->getName();
2999 }
3000
3001 HasDefaultArg = TTP->hasDefaultArgument();
3002 } else if (NonTypeTemplateParmDecl *NTTP =
3003 dyn_cast<NonTypeTemplateParmDecl>(*P)) {
3004 if (NTTP->getIdentifier())
3005 PlaceholderStr = NTTP->getIdentifier()->getName();
3006 NTTP->getType().getAsStringInternal(PlaceholderStr, Policy);
3007 HasDefaultArg = NTTP->hasDefaultArgument();
3008 } else {
3009 assert(isa<TemplateTemplateParmDecl>(*P));
3010 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
3011
3012 // Since putting the template argument list into the placeholder would
3013 // be very, very long, we just use an abbreviation.
3014 PlaceholderStr = "template<...> class";
3015 if (TTP->getIdentifier()) {
3016 PlaceholderStr += ' ';
3017 PlaceholderStr += TTP->getIdentifier()->getName();
3018 }
3019
3020 HasDefaultArg = TTP->hasDefaultArgument();
3021 }
3022
3023 if (HasDefaultArg && !InDefaultArg) {
3024 // When we see an optional default argument, put that argument and
3025 // the remaining default arguments into a new, optional string.
3026 CodeCompletionBuilder Opt(Result.getAllocator(),
3027 Result.getCodeCompletionTUInfo());
3028 if (!FirstParameter)
3029 Opt.AddChunk(CodeCompletionString::CK_Comma);
3030 AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
3031 P - Params->begin(), true);
3032 Result.AddOptionalChunk(Opt.TakeString());
3033 break;
3034 }
3035
3036 InDefaultArg = false;
3037
3038 if (FirstParameter)
3039 FirstParameter = false;
3040 else
3041 Result.AddChunk(CodeCompletionString::CK_Comma);
3042
3043 // Add the placeholder string.
3044 Result.AddPlaceholderChunk(
3045 Result.getAllocator().CopyString(PlaceholderStr));
3046 }
3047 }
3048
3049 /// Add a qualifier to the given code-completion string, if the
3050 /// provided nested-name-specifier is non-NULL.
AddQualifierToCompletionString(CodeCompletionBuilder & Result,NestedNameSpecifier * Qualifier,bool QualifierIsInformative,ASTContext & Context,const PrintingPolicy & Policy)3051 static void AddQualifierToCompletionString(CodeCompletionBuilder &Result,
3052 NestedNameSpecifier *Qualifier,
3053 bool QualifierIsInformative,
3054 ASTContext &Context,
3055 const PrintingPolicy &Policy) {
3056 if (!Qualifier)
3057 return;
3058
3059 std::string PrintedNNS;
3060 {
3061 llvm::raw_string_ostream OS(PrintedNNS);
3062 Qualifier->print(OS, Policy);
3063 }
3064 if (QualifierIsInformative)
3065 Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS));
3066 else
3067 Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS));
3068 }
3069
3070 static void
AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder & Result,const FunctionDecl * Function)3071 AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
3072 const FunctionDecl *Function) {
3073 const auto *Proto = Function->getType()->getAs<FunctionProtoType>();
3074 if (!Proto || !Proto->getMethodQuals())
3075 return;
3076
3077 // FIXME: Add ref-qualifier!
3078
3079 // Handle single qualifiers without copying
3080 if (Proto->getMethodQuals().hasOnlyConst()) {
3081 Result.AddInformativeChunk(" const");
3082 return;
3083 }
3084
3085 if (Proto->getMethodQuals().hasOnlyVolatile()) {
3086 Result.AddInformativeChunk(" volatile");
3087 return;
3088 }
3089
3090 if (Proto->getMethodQuals().hasOnlyRestrict()) {
3091 Result.AddInformativeChunk(" restrict");
3092 return;
3093 }
3094
3095 // Handle multiple qualifiers.
3096 std::string QualsStr;
3097 if (Proto->isConst())
3098 QualsStr += " const";
3099 if (Proto->isVolatile())
3100 QualsStr += " volatile";
3101 if (Proto->isRestrict())
3102 QualsStr += " restrict";
3103 Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
3104 }
3105
3106 /// Add the name of the given declaration
AddTypedNameChunk(ASTContext & Context,const PrintingPolicy & Policy,const NamedDecl * ND,CodeCompletionBuilder & Result)3107 static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
3108 const NamedDecl *ND,
3109 CodeCompletionBuilder &Result) {
3110 DeclarationName Name = ND->getDeclName();
3111 if (!Name)
3112 return;
3113
3114 switch (Name.getNameKind()) {
3115 case DeclarationName::CXXOperatorName: {
3116 const char *OperatorName = nullptr;
3117 switch (Name.getCXXOverloadedOperator()) {
3118 case OO_None:
3119 case OO_Conditional:
3120 case NUM_OVERLOADED_OPERATORS:
3121 OperatorName = "operator";
3122 break;
3123
3124 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
3125 case OO_##Name: \
3126 OperatorName = "operator" Spelling; \
3127 break;
3128 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemberOnly)
3129 #include "clang/Basic/OperatorKinds.def"
3130
3131 case OO_New:
3132 OperatorName = "operator new";
3133 break;
3134 case OO_Delete:
3135 OperatorName = "operator delete";
3136 break;
3137 case OO_Array_New:
3138 OperatorName = "operator new[]";
3139 break;
3140 case OO_Array_Delete:
3141 OperatorName = "operator delete[]";
3142 break;
3143 case OO_Call:
3144 OperatorName = "operator()";
3145 break;
3146 case OO_Subscript:
3147 OperatorName = "operator[]";
3148 break;
3149 }
3150 Result.AddTypedTextChunk(OperatorName);
3151 break;
3152 }
3153
3154 case DeclarationName::Identifier:
3155 case DeclarationName::CXXConversionFunctionName:
3156 case DeclarationName::CXXDestructorName:
3157 case DeclarationName::CXXLiteralOperatorName:
3158 Result.AddTypedTextChunk(
3159 Result.getAllocator().CopyString(ND->getNameAsString()));
3160 break;
3161
3162 case DeclarationName::CXXDeductionGuideName:
3163 case DeclarationName::CXXUsingDirective:
3164 case DeclarationName::ObjCZeroArgSelector:
3165 case DeclarationName::ObjCOneArgSelector:
3166 case DeclarationName::ObjCMultiArgSelector:
3167 break;
3168
3169 case DeclarationName::CXXConstructorName: {
3170 CXXRecordDecl *Record = nullptr;
3171 QualType Ty = Name.getCXXNameType();
3172 if (const auto *RecordTy = Ty->getAs<RecordType>())
3173 Record = cast<CXXRecordDecl>(RecordTy->getDecl());
3174 else if (const auto *InjectedTy = Ty->getAs<InjectedClassNameType>())
3175 Record = InjectedTy->getDecl();
3176 else {
3177 Result.AddTypedTextChunk(
3178 Result.getAllocator().CopyString(ND->getNameAsString()));
3179 break;
3180 }
3181
3182 Result.AddTypedTextChunk(
3183 Result.getAllocator().CopyString(Record->getNameAsString()));
3184 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
3185 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
3186 AddTemplateParameterChunks(Context, Policy, Template, Result);
3187 Result.AddChunk(CodeCompletionString::CK_RightAngle);
3188 }
3189 break;
3190 }
3191 }
3192 }
3193
CreateCodeCompletionString(Sema & S,const CodeCompletionContext & CCContext,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,bool IncludeBriefComments)3194 CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(
3195 Sema &S, const CodeCompletionContext &CCContext,
3196 CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
3197 bool IncludeBriefComments) {
3198 return CreateCodeCompletionString(S.Context, S.PP, CCContext, Allocator,
3199 CCTUInfo, IncludeBriefComments);
3200 }
3201
CreateCodeCompletionStringForMacro(Preprocessor & PP,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo)3202 CodeCompletionString *CodeCompletionResult::CreateCodeCompletionStringForMacro(
3203 Preprocessor &PP, CodeCompletionAllocator &Allocator,
3204 CodeCompletionTUInfo &CCTUInfo) {
3205 assert(Kind == RK_Macro);
3206 CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
3207 const MacroInfo *MI = PP.getMacroInfo(Macro);
3208 Result.AddTypedTextChunk(Result.getAllocator().CopyString(Macro->getName()));
3209
3210 if (!MI || !MI->isFunctionLike())
3211 return Result.TakeString();
3212
3213 // Format a function-like macro with placeholders for the arguments.
3214 Result.AddChunk(CodeCompletionString::CK_LeftParen);
3215 MacroInfo::param_iterator A = MI->param_begin(), AEnd = MI->param_end();
3216
3217 // C99 variadic macros add __VA_ARGS__ at the end. Skip it.
3218 if (MI->isC99Varargs()) {
3219 --AEnd;
3220
3221 if (A == AEnd) {
3222 Result.AddPlaceholderChunk("...");
3223 }
3224 }
3225
3226 for (MacroInfo::param_iterator A = MI->param_begin(); A != AEnd; ++A) {
3227 if (A != MI->param_begin())
3228 Result.AddChunk(CodeCompletionString::CK_Comma);
3229
3230 if (MI->isVariadic() && (A + 1) == AEnd) {
3231 SmallString<32> Arg = (*A)->getName();
3232 if (MI->isC99Varargs())
3233 Arg += ", ...";
3234 else
3235 Arg += "...";
3236 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
3237 break;
3238 }
3239
3240 // Non-variadic macros are simple.
3241 Result.AddPlaceholderChunk(
3242 Result.getAllocator().CopyString((*A)->getName()));
3243 }
3244 Result.AddChunk(CodeCompletionString::CK_RightParen);
3245 return Result.TakeString();
3246 }
3247
3248 /// If possible, create a new code completion string for the given
3249 /// result.
3250 ///
3251 /// \returns Either a new, heap-allocated code completion string describing
3252 /// how to use this result, or NULL to indicate that the string or name of the
3253 /// result is all that is needed.
CreateCodeCompletionString(ASTContext & Ctx,Preprocessor & PP,const CodeCompletionContext & CCContext,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,bool IncludeBriefComments)3254 CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(
3255 ASTContext &Ctx, Preprocessor &PP, const CodeCompletionContext &CCContext,
3256 CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
3257 bool IncludeBriefComments) {
3258 if (Kind == RK_Macro)
3259 return CreateCodeCompletionStringForMacro(PP, Allocator, CCTUInfo);
3260
3261 CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
3262
3263 PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
3264 if (Kind == RK_Pattern) {
3265 Pattern->Priority = Priority;
3266 Pattern->Availability = Availability;
3267
3268 if (Declaration) {
3269 Result.addParentContext(Declaration->getDeclContext());
3270 Pattern->ParentName = Result.getParentName();
3271 if (const RawComment *RC =
3272 getPatternCompletionComment(Ctx, Declaration)) {
3273 Result.addBriefComment(RC->getBriefText(Ctx));
3274 Pattern->BriefComment = Result.getBriefComment();
3275 }
3276 }
3277
3278 return Pattern;
3279 }
3280
3281 if (Kind == RK_Keyword) {
3282 Result.AddTypedTextChunk(Keyword);
3283 return Result.TakeString();
3284 }
3285 assert(Kind == RK_Declaration && "Missed a result kind?");
3286 return createCodeCompletionStringForDecl(
3287 PP, Ctx, Result, IncludeBriefComments, CCContext, Policy);
3288 }
3289
printOverrideString(const CodeCompletionString & CCS,std::string & BeforeName,std::string & NameAndSignature)3290 static void printOverrideString(const CodeCompletionString &CCS,
3291 std::string &BeforeName,
3292 std::string &NameAndSignature) {
3293 bool SeenTypedChunk = false;
3294 for (auto &Chunk : CCS) {
3295 if (Chunk.Kind == CodeCompletionString::CK_Optional) {
3296 assert(SeenTypedChunk && "optional parameter before name");
3297 // Note that we put all chunks inside into NameAndSignature.
3298 printOverrideString(*Chunk.Optional, NameAndSignature, NameAndSignature);
3299 continue;
3300 }
3301 SeenTypedChunk |= Chunk.Kind == CodeCompletionString::CK_TypedText;
3302 if (SeenTypedChunk)
3303 NameAndSignature += Chunk.Text;
3304 else
3305 BeforeName += Chunk.Text;
3306 }
3307 }
3308
3309 CodeCompletionString *
createCodeCompletionStringForOverride(Preprocessor & PP,ASTContext & Ctx,CodeCompletionBuilder & Result,bool IncludeBriefComments,const CodeCompletionContext & CCContext,PrintingPolicy & Policy)3310 CodeCompletionResult::createCodeCompletionStringForOverride(
3311 Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
3312 bool IncludeBriefComments, const CodeCompletionContext &CCContext,
3313 PrintingPolicy &Policy) {
3314 auto *CCS = createCodeCompletionStringForDecl(PP, Ctx, Result,
3315 /*IncludeBriefComments=*/false,
3316 CCContext, Policy);
3317 std::string BeforeName;
3318 std::string NameAndSignature;
3319 // For overrides all chunks go into the result, none are informative.
3320 printOverrideString(*CCS, BeforeName, NameAndSignature);
3321 NameAndSignature += " override";
3322
3323 Result.AddTextChunk(Result.getAllocator().CopyString(BeforeName));
3324 Result.AddChunk(CodeCompletionString::CK_HorizontalSpace);
3325 Result.AddTypedTextChunk(Result.getAllocator().CopyString(NameAndSignature));
3326 return Result.TakeString();
3327 }
3328
3329 // FIXME: Right now this works well with lambdas. Add support for other functor
3330 // types like std::function.
extractFunctorCallOperator(const NamedDecl * ND)3331 static const NamedDecl *extractFunctorCallOperator(const NamedDecl *ND) {
3332 const auto *VD = dyn_cast<VarDecl>(ND);
3333 if (!VD)
3334 return nullptr;
3335 const auto *RecordDecl = VD->getType()->getAsCXXRecordDecl();
3336 if (!RecordDecl || !RecordDecl->isLambda())
3337 return nullptr;
3338 return RecordDecl->getLambdaCallOperator();
3339 }
3340
createCodeCompletionStringForDecl(Preprocessor & PP,ASTContext & Ctx,CodeCompletionBuilder & Result,bool IncludeBriefComments,const CodeCompletionContext & CCContext,PrintingPolicy & Policy)3341 CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl(
3342 Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
3343 bool IncludeBriefComments, const CodeCompletionContext &CCContext,
3344 PrintingPolicy &Policy) {
3345 const NamedDecl *ND = Declaration;
3346 Result.addParentContext(ND->getDeclContext());
3347
3348 if (IncludeBriefComments) {
3349 // Add documentation comment, if it exists.
3350 if (const RawComment *RC = getCompletionComment(Ctx, Declaration)) {
3351 Result.addBriefComment(RC->getBriefText(Ctx));
3352 }
3353 }
3354
3355 if (StartsNestedNameSpecifier) {
3356 Result.AddTypedTextChunk(
3357 Result.getAllocator().CopyString(ND->getNameAsString()));
3358 Result.AddTextChunk("::");
3359 return Result.TakeString();
3360 }
3361
3362 for (const auto *I : ND->specific_attrs<AnnotateAttr>())
3363 Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation()));
3364
3365 auto AddFunctionTypeAndResult = [&](const FunctionDecl *Function) {
3366 AddResultTypeChunk(Ctx, Policy, Function, CCContext.getBaseType(), Result);
3367 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
3368 Ctx, Policy);
3369 AddTypedNameChunk(Ctx, Policy, ND, Result);
3370 Result.AddChunk(CodeCompletionString::CK_LeftParen);
3371 AddFunctionParameterChunks(PP, Policy, Function, Result);
3372 Result.AddChunk(CodeCompletionString::CK_RightParen);
3373 AddFunctionTypeQualsToCompletionString(Result, Function);
3374 };
3375
3376 if (const auto *Function = dyn_cast<FunctionDecl>(ND)) {
3377 AddFunctionTypeAndResult(Function);
3378 return Result.TakeString();
3379 }
3380
3381 if (const auto *CallOperator =
3382 dyn_cast_or_null<FunctionDecl>(extractFunctorCallOperator(ND))) {
3383 AddFunctionTypeAndResult(CallOperator);
3384 return Result.TakeString();
3385 }
3386
3387 AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result);
3388
3389 if (const FunctionTemplateDecl *FunTmpl =
3390 dyn_cast<FunctionTemplateDecl>(ND)) {
3391 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
3392 Ctx, Policy);
3393 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
3394 AddTypedNameChunk(Ctx, Policy, Function, Result);
3395
3396 // Figure out which template parameters are deduced (or have default
3397 // arguments).
3398 llvm::SmallBitVector Deduced;
3399 Sema::MarkDeducedTemplateParameters(Ctx, FunTmpl, Deduced);
3400 unsigned LastDeducibleArgument;
3401 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
3402 --LastDeducibleArgument) {
3403 if (!Deduced[LastDeducibleArgument - 1]) {
3404 // C++0x: Figure out if the template argument has a default. If so,
3405 // the user doesn't need to type this argument.
3406 // FIXME: We need to abstract template parameters better!
3407 bool HasDefaultArg = false;
3408 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
3409 LastDeducibleArgument - 1);
3410 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3411 HasDefaultArg = TTP->hasDefaultArgument();
3412 else if (NonTypeTemplateParmDecl *NTTP =
3413 dyn_cast<NonTypeTemplateParmDecl>(Param))
3414 HasDefaultArg = NTTP->hasDefaultArgument();
3415 else {
3416 assert(isa<TemplateTemplateParmDecl>(Param));
3417 HasDefaultArg =
3418 cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
3419 }
3420
3421 if (!HasDefaultArg)
3422 break;
3423 }
3424 }
3425
3426 if (LastDeducibleArgument) {
3427 // Some of the function template arguments cannot be deduced from a
3428 // function call, so we introduce an explicit template argument list
3429 // containing all of the arguments up to the first deducible argument.
3430 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
3431 AddTemplateParameterChunks(Ctx, Policy, FunTmpl, Result,
3432 LastDeducibleArgument);
3433 Result.AddChunk(CodeCompletionString::CK_RightAngle);
3434 }
3435
3436 // Add the function parameters
3437 Result.AddChunk(CodeCompletionString::CK_LeftParen);
3438 AddFunctionParameterChunks(PP, Policy, Function, Result);
3439 Result.AddChunk(CodeCompletionString::CK_RightParen);
3440 AddFunctionTypeQualsToCompletionString(Result, Function);
3441 return Result.TakeString();
3442 }
3443
3444 if (const auto *Template = dyn_cast<TemplateDecl>(ND)) {
3445 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
3446 Ctx, Policy);
3447 Result.AddTypedTextChunk(
3448 Result.getAllocator().CopyString(Template->getNameAsString()));
3449 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
3450 AddTemplateParameterChunks(Ctx, Policy, Template, Result);
3451 Result.AddChunk(CodeCompletionString::CK_RightAngle);
3452 return Result.TakeString();
3453 }
3454
3455 if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) {
3456 Selector Sel = Method->getSelector();
3457 if (Sel.isUnarySelector()) {
3458 Result.AddTypedTextChunk(
3459 Result.getAllocator().CopyString(Sel.getNameForSlot(0)));
3460 return Result.TakeString();
3461 }
3462
3463 std::string SelName = Sel.getNameForSlot(0).str();
3464 SelName += ':';
3465 if (StartParameter == 0)
3466 Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName));
3467 else {
3468 Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName));
3469
3470 // If there is only one parameter, and we're past it, add an empty
3471 // typed-text chunk since there is nothing to type.
3472 if (Method->param_size() == 1)
3473 Result.AddTypedTextChunk("");
3474 }
3475 unsigned Idx = 0;
3476 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
3477 PEnd = Method->param_end();
3478 P != PEnd; (void)++P, ++Idx) {
3479 if (Idx > 0) {
3480 std::string Keyword;
3481 if (Idx > StartParameter)
3482 Result.AddChunk(CodeCompletionString::CK_HorizontalSpace);
3483 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
3484 Keyword += II->getName();
3485 Keyword += ":";
3486 if (Idx < StartParameter || AllParametersAreInformative)
3487 Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword));
3488 else
3489 Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword));
3490 }
3491
3492 // If we're before the starting parameter, skip the placeholder.
3493 if (Idx < StartParameter)
3494 continue;
3495
3496 std::string Arg;
3497 QualType ParamType = (*P)->getType();
3498 Optional<ArrayRef<QualType>> ObjCSubsts;
3499 if (!CCContext.getBaseType().isNull())
3500 ObjCSubsts = CCContext.getBaseType()->getObjCSubstitutions(Method);
3501
3502 if (ParamType->isBlockPointerType() && !DeclaringEntity)
3503 Arg = FormatFunctionParameter(Policy, *P, true,
3504 /*SuppressBlock=*/false, ObjCSubsts);
3505 else {
3506 if (ObjCSubsts)
3507 ParamType = ParamType.substObjCTypeArgs(
3508 Ctx, *ObjCSubsts, ObjCSubstitutionContext::Parameter);
3509 Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier(),
3510 ParamType);
3511 Arg += ParamType.getAsString(Policy) + ")";
3512 if (IdentifierInfo *II = (*P)->getIdentifier())
3513 if (DeclaringEntity || AllParametersAreInformative)
3514 Arg += II->getName();
3515 }
3516
3517 if (Method->isVariadic() && (P + 1) == PEnd)
3518 Arg += ", ...";
3519
3520 if (DeclaringEntity)
3521 Result.AddTextChunk(Result.getAllocator().CopyString(Arg));
3522 else if (AllParametersAreInformative)
3523 Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg));
3524 else
3525 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
3526 }
3527
3528 if (Method->isVariadic()) {
3529 if (Method->param_size() == 0) {
3530 if (DeclaringEntity)
3531 Result.AddTextChunk(", ...");
3532 else if (AllParametersAreInformative)
3533 Result.AddInformativeChunk(", ...");
3534 else
3535 Result.AddPlaceholderChunk(", ...");
3536 }
3537
3538 MaybeAddSentinel(PP, Method, Result);
3539 }
3540
3541 return Result.TakeString();
3542 }
3543
3544 if (Qualifier)
3545 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
3546 Ctx, Policy);
3547
3548 Result.AddTypedTextChunk(
3549 Result.getAllocator().CopyString(ND->getNameAsString()));
3550 return Result.TakeString();
3551 }
3552
getCompletionComment(const ASTContext & Ctx,const NamedDecl * ND)3553 const RawComment *clang::getCompletionComment(const ASTContext &Ctx,
3554 const NamedDecl *ND) {
3555 if (!ND)
3556 return nullptr;
3557 if (auto *RC = Ctx.getRawCommentForAnyRedecl(ND))
3558 return RC;
3559
3560 // Try to find comment from a property for ObjC methods.
3561 const auto *M = dyn_cast<ObjCMethodDecl>(ND);
3562 if (!M)
3563 return nullptr;
3564 const ObjCPropertyDecl *PDecl = M->findPropertyDecl();
3565 if (!PDecl)
3566 return nullptr;
3567
3568 return Ctx.getRawCommentForAnyRedecl(PDecl);
3569 }
3570
getPatternCompletionComment(const ASTContext & Ctx,const NamedDecl * ND)3571 const RawComment *clang::getPatternCompletionComment(const ASTContext &Ctx,
3572 const NamedDecl *ND) {
3573 const auto *M = dyn_cast_or_null<ObjCMethodDecl>(ND);
3574 if (!M || !M->isPropertyAccessor())
3575 return nullptr;
3576
3577 // Provide code completion comment for self.GetterName where
3578 // GetterName is the getter method for a property with name
3579 // different from the property name (declared via a property
3580 // getter attribute.
3581 const ObjCPropertyDecl *PDecl = M->findPropertyDecl();
3582 if (!PDecl)
3583 return nullptr;
3584 if (PDecl->getGetterName() == M->getSelector() &&
3585 PDecl->getIdentifier() != M->getIdentifier()) {
3586 if (auto *RC = Ctx.getRawCommentForAnyRedecl(M))
3587 return RC;
3588 if (auto *RC = Ctx.getRawCommentForAnyRedecl(PDecl))
3589 return RC;
3590 }
3591 return nullptr;
3592 }
3593
getParameterComment(const ASTContext & Ctx,const CodeCompleteConsumer::OverloadCandidate & Result,unsigned ArgIndex)3594 const RawComment *clang::getParameterComment(
3595 const ASTContext &Ctx,
3596 const CodeCompleteConsumer::OverloadCandidate &Result, unsigned ArgIndex) {
3597 auto FDecl = Result.getFunction();
3598 if (!FDecl)
3599 return nullptr;
3600 if (ArgIndex < FDecl->getNumParams())
3601 return Ctx.getRawCommentForAnyRedecl(FDecl->getParamDecl(ArgIndex));
3602 return nullptr;
3603 }
3604
3605 /// Add function overload parameter chunks to the given code completion
3606 /// string.
AddOverloadParameterChunks(ASTContext & Context,const PrintingPolicy & Policy,const FunctionDecl * Function,const FunctionProtoType * Prototype,CodeCompletionBuilder & Result,unsigned CurrentArg,unsigned Start=0,bool InOptional=false)3607 static void AddOverloadParameterChunks(ASTContext &Context,
3608 const PrintingPolicy &Policy,
3609 const FunctionDecl *Function,
3610 const FunctionProtoType *Prototype,
3611 CodeCompletionBuilder &Result,
3612 unsigned CurrentArg, unsigned Start = 0,
3613 bool InOptional = false) {
3614 bool FirstParameter = true;
3615 unsigned NumParams =
3616 Function ? Function->getNumParams() : Prototype->getNumParams();
3617
3618 for (unsigned P = Start; P != NumParams; ++P) {
3619 if (Function && Function->getParamDecl(P)->hasDefaultArg() && !InOptional) {
3620 // When we see an optional default argument, put that argument and
3621 // the remaining default arguments into a new, optional string.
3622 CodeCompletionBuilder Opt(Result.getAllocator(),
3623 Result.getCodeCompletionTUInfo());
3624 if (!FirstParameter)
3625 Opt.AddChunk(CodeCompletionString::CK_Comma);
3626 // Optional sections are nested.
3627 AddOverloadParameterChunks(Context, Policy, Function, Prototype, Opt,
3628 CurrentArg, P, /*InOptional=*/true);
3629 Result.AddOptionalChunk(Opt.TakeString());
3630 return;
3631 }
3632
3633 if (FirstParameter)
3634 FirstParameter = false;
3635 else
3636 Result.AddChunk(CodeCompletionString::CK_Comma);
3637
3638 InOptional = false;
3639
3640 // Format the placeholder string.
3641 std::string Placeholder;
3642 if (Function) {
3643 const ParmVarDecl *Param = Function->getParamDecl(P);
3644 Placeholder = FormatFunctionParameter(Policy, Param);
3645 if (Param->hasDefaultArg())
3646 Placeholder += GetDefaultValueString(Param, Context.getSourceManager(),
3647 Context.getLangOpts());
3648 } else {
3649 Placeholder = Prototype->getParamType(P).getAsString(Policy);
3650 }
3651
3652 if (P == CurrentArg)
3653 Result.AddCurrentParameterChunk(
3654 Result.getAllocator().CopyString(Placeholder));
3655 else
3656 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Placeholder));
3657 }
3658
3659 if (Prototype && Prototype->isVariadic()) {
3660 CodeCompletionBuilder Opt(Result.getAllocator(),
3661 Result.getCodeCompletionTUInfo());
3662 if (!FirstParameter)
3663 Opt.AddChunk(CodeCompletionString::CK_Comma);
3664
3665 if (CurrentArg < NumParams)
3666 Opt.AddPlaceholderChunk("...");
3667 else
3668 Opt.AddCurrentParameterChunk("...");
3669
3670 Result.AddOptionalChunk(Opt.TakeString());
3671 }
3672 }
3673
3674 CodeCompletionString *
CreateSignatureString(unsigned CurrentArg,Sema & S,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,bool IncludeBriefComments) const3675 CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
3676 unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator,
3677 CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments) const {
3678 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
3679 // Show signatures of constructors as they are declared:
3680 // vector(int n) rather than vector<string>(int n)
3681 // This is less noisy without being less clear, and avoids tricky cases.
3682 Policy.SuppressTemplateArgsInCXXConstructors = true;
3683
3684 // FIXME: Set priority, availability appropriately.
3685 CodeCompletionBuilder Result(Allocator, CCTUInfo, 1,
3686 CXAvailability_Available);
3687 FunctionDecl *FDecl = getFunction();
3688 const FunctionProtoType *Proto =
3689 dyn_cast<FunctionProtoType>(getFunctionType());
3690 if (!FDecl && !Proto) {
3691 // Function without a prototype. Just give the return type and a
3692 // highlighted ellipsis.
3693 const FunctionType *FT = getFunctionType();
3694 Result.AddResultTypeChunk(Result.getAllocator().CopyString(
3695 FT->getReturnType().getAsString(Policy)));
3696 Result.AddChunk(CodeCompletionString::CK_LeftParen);
3697 Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
3698 Result.AddChunk(CodeCompletionString::CK_RightParen);
3699 return Result.TakeString();
3700 }
3701
3702 if (FDecl) {
3703 if (IncludeBriefComments) {
3704 if (auto RC = getParameterComment(S.getASTContext(), *this, CurrentArg))
3705 Result.addBriefComment(RC->getBriefText(S.getASTContext()));
3706 }
3707 AddResultTypeChunk(S.Context, Policy, FDecl, QualType(), Result);
3708 Result.AddTextChunk(
3709 Result.getAllocator().CopyString(FDecl->getNameAsString()));
3710 } else {
3711 Result.AddResultTypeChunk(Result.getAllocator().CopyString(
3712 Proto->getReturnType().getAsString(Policy)));
3713 }
3714
3715 Result.AddChunk(CodeCompletionString::CK_LeftParen);
3716 AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, Result,
3717 CurrentArg);
3718 Result.AddChunk(CodeCompletionString::CK_RightParen);
3719
3720 return Result.TakeString();
3721 }
3722
getMacroUsagePriority(StringRef MacroName,const LangOptions & LangOpts,bool PreferredTypeIsPointer)3723 unsigned clang::getMacroUsagePriority(StringRef MacroName,
3724 const LangOptions &LangOpts,
3725 bool PreferredTypeIsPointer) {
3726 unsigned Priority = CCP_Macro;
3727
3728 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
3729 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
3730 MacroName.equals("Nil")) {
3731 Priority = CCP_Constant;
3732 if (PreferredTypeIsPointer)
3733 Priority = Priority / CCF_SimilarTypeMatch;
3734 }
3735 // Treat "YES", "NO", "true", and "false" as constants.
3736 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
3737 MacroName.equals("true") || MacroName.equals("false"))
3738 Priority = CCP_Constant;
3739 // Treat "bool" as a type.
3740 else if (MacroName.equals("bool"))
3741 Priority = CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0);
3742
3743 return Priority;
3744 }
3745
getCursorKindForDecl(const Decl * D)3746 CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
3747 if (!D)
3748 return CXCursor_UnexposedDecl;
3749
3750 switch (D->getKind()) {
3751 case Decl::Enum:
3752 return CXCursor_EnumDecl;
3753 case Decl::EnumConstant:
3754 return CXCursor_EnumConstantDecl;
3755 case Decl::Field:
3756 return CXCursor_FieldDecl;
3757 case Decl::Function:
3758 return CXCursor_FunctionDecl;
3759 case Decl::ObjCCategory:
3760 return CXCursor_ObjCCategoryDecl;
3761 case Decl::ObjCCategoryImpl:
3762 return CXCursor_ObjCCategoryImplDecl;
3763 case Decl::ObjCImplementation:
3764 return CXCursor_ObjCImplementationDecl;
3765
3766 case Decl::ObjCInterface:
3767 return CXCursor_ObjCInterfaceDecl;
3768 case Decl::ObjCIvar:
3769 return CXCursor_ObjCIvarDecl;
3770 case Decl::ObjCMethod:
3771 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
3772 ? CXCursor_ObjCInstanceMethodDecl
3773 : CXCursor_ObjCClassMethodDecl;
3774 case Decl::CXXMethod:
3775 return CXCursor_CXXMethod;
3776 case Decl::CXXConstructor:
3777 return CXCursor_Constructor;
3778 case Decl::CXXDestructor:
3779 return CXCursor_Destructor;
3780 case Decl::CXXConversion:
3781 return CXCursor_ConversionFunction;
3782 case Decl::ObjCProperty:
3783 return CXCursor_ObjCPropertyDecl;
3784 case Decl::ObjCProtocol:
3785 return CXCursor_ObjCProtocolDecl;
3786 case Decl::ParmVar:
3787 return CXCursor_ParmDecl;
3788 case Decl::Typedef:
3789 return CXCursor_TypedefDecl;
3790 case Decl::TypeAlias:
3791 return CXCursor_TypeAliasDecl;
3792 case Decl::TypeAliasTemplate:
3793 return CXCursor_TypeAliasTemplateDecl;
3794 case Decl::Var:
3795 return CXCursor_VarDecl;
3796 case Decl::Namespace:
3797 return CXCursor_Namespace;
3798 case Decl::NamespaceAlias:
3799 return CXCursor_NamespaceAlias;
3800 case Decl::TemplateTypeParm:
3801 return CXCursor_TemplateTypeParameter;
3802 case Decl::NonTypeTemplateParm:
3803 return CXCursor_NonTypeTemplateParameter;
3804 case Decl::TemplateTemplateParm:
3805 return CXCursor_TemplateTemplateParameter;
3806 case Decl::FunctionTemplate:
3807 return CXCursor_FunctionTemplate;
3808 case Decl::ClassTemplate:
3809 return CXCursor_ClassTemplate;
3810 case Decl::AccessSpec:
3811 return CXCursor_CXXAccessSpecifier;
3812 case Decl::ClassTemplatePartialSpecialization:
3813 return CXCursor_ClassTemplatePartialSpecialization;
3814 case Decl::UsingDirective:
3815 return CXCursor_UsingDirective;
3816 case Decl::StaticAssert:
3817 return CXCursor_StaticAssert;
3818 case Decl::Friend:
3819 return CXCursor_FriendDecl;
3820 case Decl::TranslationUnit:
3821 return CXCursor_TranslationUnit;
3822
3823 case Decl::Using:
3824 case Decl::UnresolvedUsingValue:
3825 case Decl::UnresolvedUsingTypename:
3826 return CXCursor_UsingDeclaration;
3827
3828 case Decl::ObjCPropertyImpl:
3829 switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) {
3830 case ObjCPropertyImplDecl::Dynamic:
3831 return CXCursor_ObjCDynamicDecl;
3832
3833 case ObjCPropertyImplDecl::Synthesize:
3834 return CXCursor_ObjCSynthesizeDecl;
3835 }
3836 llvm_unreachable("Unexpected Kind!");
3837
3838 case Decl::Import:
3839 return CXCursor_ModuleImportDecl;
3840
3841 case Decl::ObjCTypeParam:
3842 return CXCursor_TemplateTypeParameter;
3843
3844 default:
3845 if (const auto *TD = dyn_cast<TagDecl>(D)) {
3846 switch (TD->getTagKind()) {
3847 case TTK_Interface: // fall through
3848 case TTK_Struct:
3849 return CXCursor_StructDecl;
3850 case TTK_Class:
3851 return CXCursor_ClassDecl;
3852 case TTK_Union:
3853 return CXCursor_UnionDecl;
3854 case TTK_Enum:
3855 return CXCursor_EnumDecl;
3856 }
3857 }
3858 }
3859
3860 return CXCursor_UnexposedDecl;
3861 }
3862
AddMacroResults(Preprocessor & PP,ResultBuilder & Results,bool LoadExternal,bool IncludeUndefined,bool TargetTypeIsPointer=false)3863 static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
3864 bool LoadExternal, bool IncludeUndefined,
3865 bool TargetTypeIsPointer = false) {
3866 typedef CodeCompletionResult Result;
3867
3868 Results.EnterNewScope();
3869
3870 for (Preprocessor::macro_iterator M = PP.macro_begin(LoadExternal),
3871 MEnd = PP.macro_end(LoadExternal);
3872 M != MEnd; ++M) {
3873 auto MD = PP.getMacroDefinition(M->first);
3874 if (IncludeUndefined || MD) {
3875 MacroInfo *MI = MD.getMacroInfo();
3876 if (MI && MI->isUsedForHeaderGuard())
3877 continue;
3878
3879 Results.AddResult(
3880 Result(M->first, MI,
3881 getMacroUsagePriority(M->first->getName(), PP.getLangOpts(),
3882 TargetTypeIsPointer)));
3883 }
3884 }
3885
3886 Results.ExitScope();
3887 }
3888
AddPrettyFunctionResults(const LangOptions & LangOpts,ResultBuilder & Results)3889 static void AddPrettyFunctionResults(const LangOptions &LangOpts,
3890 ResultBuilder &Results) {
3891 typedef CodeCompletionResult Result;
3892
3893 Results.EnterNewScope();
3894
3895 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
3896 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
3897 if (LangOpts.C99 || LangOpts.CPlusPlus11)
3898 Results.AddResult(Result("__func__", CCP_Constant));
3899 Results.ExitScope();
3900 }
3901
HandleCodeCompleteResults(Sema * S,CodeCompleteConsumer * CodeCompleter,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)3902 static void HandleCodeCompleteResults(Sema *S,
3903 CodeCompleteConsumer *CodeCompleter,
3904 CodeCompletionContext Context,
3905 CodeCompletionResult *Results,
3906 unsigned NumResults) {
3907 if (CodeCompleter)
3908 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
3909 }
3910
3911 static CodeCompletionContext
mapCodeCompletionContext(Sema & S,Sema::ParserCompletionContext PCC)3912 mapCodeCompletionContext(Sema &S, Sema::ParserCompletionContext PCC) {
3913 switch (PCC) {
3914 case Sema::PCC_Namespace:
3915 return CodeCompletionContext::CCC_TopLevel;
3916
3917 case Sema::PCC_Class:
3918 return CodeCompletionContext::CCC_ClassStructUnion;
3919
3920 case Sema::PCC_ObjCInterface:
3921 return CodeCompletionContext::CCC_ObjCInterface;
3922
3923 case Sema::PCC_ObjCImplementation:
3924 return CodeCompletionContext::CCC_ObjCImplementation;
3925
3926 case Sema::PCC_ObjCInstanceVariableList:
3927 return CodeCompletionContext::CCC_ObjCIvarList;
3928
3929 case Sema::PCC_Template:
3930 case Sema::PCC_MemberTemplate:
3931 if (S.CurContext->isFileContext())
3932 return CodeCompletionContext::CCC_TopLevel;
3933 if (S.CurContext->isRecord())
3934 return CodeCompletionContext::CCC_ClassStructUnion;
3935 return CodeCompletionContext::CCC_Other;
3936
3937 case Sema::PCC_RecoveryInFunction:
3938 return CodeCompletionContext::CCC_Recovery;
3939
3940 case Sema::PCC_ForInit:
3941 if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 ||
3942 S.getLangOpts().ObjC)
3943 return CodeCompletionContext::CCC_ParenthesizedExpression;
3944 else
3945 return CodeCompletionContext::CCC_Expression;
3946
3947 case Sema::PCC_Expression:
3948 return CodeCompletionContext::CCC_Expression;
3949 case Sema::PCC_Condition:
3950 return CodeCompletionContext(CodeCompletionContext::CCC_Expression,
3951 S.getASTContext().BoolTy);
3952
3953 case Sema::PCC_Statement:
3954 return CodeCompletionContext::CCC_Statement;
3955
3956 case Sema::PCC_Type:
3957 return CodeCompletionContext::CCC_Type;
3958
3959 case Sema::PCC_ParenthesizedExpression:
3960 return CodeCompletionContext::CCC_ParenthesizedExpression;
3961
3962 case Sema::PCC_LocalDeclarationSpecifiers:
3963 return CodeCompletionContext::CCC_Type;
3964 }
3965
3966 llvm_unreachable("Invalid ParserCompletionContext!");
3967 }
3968
3969 /// If we're in a C++ virtual member function, add completion results
3970 /// that invoke the functions we override, since it's common to invoke the
3971 /// overridden function as well as adding new functionality.
3972 ///
3973 /// \param S The semantic analysis object for which we are generating results.
3974 ///
3975 /// \param InContext This context in which the nested-name-specifier preceding
3976 /// the code-completion point
MaybeAddOverrideCalls(Sema & S,DeclContext * InContext,ResultBuilder & Results)3977 static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
3978 ResultBuilder &Results) {
3979 // Look through blocks.
3980 DeclContext *CurContext = S.CurContext;
3981 while (isa<BlockDecl>(CurContext))
3982 CurContext = CurContext->getParent();
3983
3984 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
3985 if (!Method || !Method->isVirtual())
3986 return;
3987
3988 // We need to have names for all of the parameters, if we're going to
3989 // generate a forwarding call.
3990 for (auto P : Method->parameters())
3991 if (!P->getDeclName())
3992 return;
3993
3994 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
3995 for (const CXXMethodDecl *Overridden : Method->overridden_methods()) {
3996 CodeCompletionBuilder Builder(Results.getAllocator(),
3997 Results.getCodeCompletionTUInfo());
3998 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
3999 continue;
4000
4001 // If we need a nested-name-specifier, add one now.
4002 if (!InContext) {
4003 NestedNameSpecifier *NNS = getRequiredQualification(
4004 S.Context, CurContext, Overridden->getDeclContext());
4005 if (NNS) {
4006 std::string Str;
4007 llvm::raw_string_ostream OS(Str);
4008 NNS->print(OS, Policy);
4009 Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str()));
4010 }
4011 } else if (!InContext->Equals(Overridden->getDeclContext()))
4012 continue;
4013
4014 Builder.AddTypedTextChunk(
4015 Results.getAllocator().CopyString(Overridden->getNameAsString()));
4016 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4017 bool FirstParam = true;
4018 for (auto P : Method->parameters()) {
4019 if (FirstParam)
4020 FirstParam = false;
4021 else
4022 Builder.AddChunk(CodeCompletionString::CK_Comma);
4023
4024 Builder.AddPlaceholderChunk(
4025 Results.getAllocator().CopyString(P->getIdentifier()->getName()));
4026 }
4027 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4028 Results.AddResult(CodeCompletionResult(
4029 Builder.TakeString(), CCP_SuperCompletion, CXCursor_CXXMethod,
4030 CXAvailability_Available, Overridden));
4031 Results.Ignore(Overridden);
4032 }
4033 }
4034
CodeCompleteModuleImport(SourceLocation ImportLoc,ModuleIdPath Path)4035 void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc,
4036 ModuleIdPath Path) {
4037 typedef CodeCompletionResult Result;
4038 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4039 CodeCompleter->getCodeCompletionTUInfo(),
4040 CodeCompletionContext::CCC_Other);
4041 Results.EnterNewScope();
4042
4043 CodeCompletionAllocator &Allocator = Results.getAllocator();
4044 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
4045 typedef CodeCompletionResult Result;
4046 if (Path.empty()) {
4047 // Enumerate all top-level modules.
4048 SmallVector<Module *, 8> Modules;
4049 PP.getHeaderSearchInfo().collectAllModules(Modules);
4050 for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
4051 Builder.AddTypedTextChunk(
4052 Builder.getAllocator().CopyString(Modules[I]->Name));
4053 Results.AddResult(Result(
4054 Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl,
4055 Modules[I]->isAvailable() ? CXAvailability_Available
4056 : CXAvailability_NotAvailable));
4057 }
4058 } else if (getLangOpts().Modules) {
4059 // Load the named module.
4060 Module *Mod =
4061 PP.getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible,
4062 /*IsInclusionDirective=*/false);
4063 // Enumerate submodules.
4064 if (Mod) {
4065 for (Module::submodule_iterator Sub = Mod->submodule_begin(),
4066 SubEnd = Mod->submodule_end();
4067 Sub != SubEnd; ++Sub) {
4068
4069 Builder.AddTypedTextChunk(
4070 Builder.getAllocator().CopyString((*Sub)->Name));
4071 Results.AddResult(Result(
4072 Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl,
4073 (*Sub)->isAvailable() ? CXAvailability_Available
4074 : CXAvailability_NotAvailable));
4075 }
4076 }
4077 }
4078 Results.ExitScope();
4079 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4080 Results.data(), Results.size());
4081 }
4082
CodeCompleteOrdinaryName(Scope * S,ParserCompletionContext CompletionContext)4083 void Sema::CodeCompleteOrdinaryName(Scope *S,
4084 ParserCompletionContext CompletionContext) {
4085 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4086 CodeCompleter->getCodeCompletionTUInfo(),
4087 mapCodeCompletionContext(*this, CompletionContext));
4088 Results.EnterNewScope();
4089
4090 // Determine how to filter results, e.g., so that the names of
4091 // values (functions, enumerators, function templates, etc.) are
4092 // only allowed where we can have an expression.
4093 switch (CompletionContext) {
4094 case PCC_Namespace:
4095 case PCC_Class:
4096 case PCC_ObjCInterface:
4097 case PCC_ObjCImplementation:
4098 case PCC_ObjCInstanceVariableList:
4099 case PCC_Template:
4100 case PCC_MemberTemplate:
4101 case PCC_Type:
4102 case PCC_LocalDeclarationSpecifiers:
4103 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4104 break;
4105
4106 case PCC_Statement:
4107 case PCC_ParenthesizedExpression:
4108 case PCC_Expression:
4109 case PCC_ForInit:
4110 case PCC_Condition:
4111 if (WantTypesInContext(CompletionContext, getLangOpts()))
4112 Results.setFilter(&ResultBuilder::IsOrdinaryName);
4113 else
4114 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
4115
4116 if (getLangOpts().CPlusPlus)
4117 MaybeAddOverrideCalls(*this, /*InContext=*/nullptr, Results);
4118 break;
4119
4120 case PCC_RecoveryInFunction:
4121 // Unfiltered
4122 break;
4123 }
4124
4125 // If we are in a C++ non-static member function, check the qualifiers on
4126 // the member function to filter/prioritize the results list.
4127 auto ThisType = getCurrentThisType();
4128 if (!ThisType.isNull())
4129 Results.setObjectTypeQualifiers(ThisType->getPointeeType().getQualifiers(),
4130 VK_LValue);
4131
4132 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4133 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4134 CodeCompleter->includeGlobals(),
4135 CodeCompleter->loadExternal());
4136
4137 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
4138 Results.ExitScope();
4139
4140 switch (CompletionContext) {
4141 case PCC_ParenthesizedExpression:
4142 case PCC_Expression:
4143 case PCC_Statement:
4144 case PCC_RecoveryInFunction:
4145 if (S->getFnParent())
4146 AddPrettyFunctionResults(getLangOpts(), Results);
4147 break;
4148
4149 case PCC_Namespace:
4150 case PCC_Class:
4151 case PCC_ObjCInterface:
4152 case PCC_ObjCImplementation:
4153 case PCC_ObjCInstanceVariableList:
4154 case PCC_Template:
4155 case PCC_MemberTemplate:
4156 case PCC_ForInit:
4157 case PCC_Condition:
4158 case PCC_Type:
4159 case PCC_LocalDeclarationSpecifiers:
4160 break;
4161 }
4162
4163 if (CodeCompleter->includeMacros())
4164 AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false);
4165
4166 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4167 Results.data(), Results.size());
4168 }
4169
4170 static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
4171 ParsedType Receiver,
4172 ArrayRef<IdentifierInfo *> SelIdents,
4173 bool AtArgumentExpression, bool IsSuper,
4174 ResultBuilder &Results);
4175
CodeCompleteDeclSpec(Scope * S,DeclSpec & DS,bool AllowNonIdentifiers,bool AllowNestedNameSpecifiers)4176 void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
4177 bool AllowNonIdentifiers,
4178 bool AllowNestedNameSpecifiers) {
4179 typedef CodeCompletionResult Result;
4180 ResultBuilder Results(
4181 *this, CodeCompleter->getAllocator(),
4182 CodeCompleter->getCodeCompletionTUInfo(),
4183 AllowNestedNameSpecifiers
4184 // FIXME: Try to separate codepath leading here to deduce whether we
4185 // need an existing symbol or a new one.
4186 ? CodeCompletionContext::CCC_SymbolOrNewName
4187 : CodeCompletionContext::CCC_NewName);
4188 Results.EnterNewScope();
4189
4190 // Type qualifiers can come after names.
4191 Results.AddResult(Result("const"));
4192 Results.AddResult(Result("volatile"));
4193 if (getLangOpts().C99)
4194 Results.AddResult(Result("restrict"));
4195
4196 if (getLangOpts().CPlusPlus) {
4197 if (getLangOpts().CPlusPlus11 &&
4198 (DS.getTypeSpecType() == DeclSpec::TST_class ||
4199 DS.getTypeSpecType() == DeclSpec::TST_struct))
4200 Results.AddResult("final");
4201
4202 if (AllowNonIdentifiers) {
4203 Results.AddResult(Result("operator"));
4204 }
4205
4206 // Add nested-name-specifiers.
4207 if (AllowNestedNameSpecifiers) {
4208 Results.allowNestedNameSpecifiers();
4209 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
4210 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4211 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
4212 CodeCompleter->includeGlobals(),
4213 CodeCompleter->loadExternal());
4214 Results.setFilter(nullptr);
4215 }
4216 }
4217 Results.ExitScope();
4218
4219 // If we're in a context where we might have an expression (rather than a
4220 // declaration), and what we've seen so far is an Objective-C type that could
4221 // be a receiver of a class message, this may be a class message send with
4222 // the initial opening bracket '[' missing. Add appropriate completions.
4223 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
4224 DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier &&
4225 DS.getTypeSpecType() == DeclSpec::TST_typename &&
4226 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
4227 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
4228 !DS.isTypeAltiVecVector() && S &&
4229 (S->getFlags() & Scope::DeclScope) != 0 &&
4230 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
4231 Scope::FunctionPrototypeScope | Scope::AtCatchScope)) ==
4232 0) {
4233 ParsedType T = DS.getRepAsType();
4234 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
4235 AddClassMessageCompletions(*this, S, T, None, false, false, Results);
4236 }
4237
4238 // Note that we intentionally suppress macro results here, since we do not
4239 // encourage using macros to produce the names of entities.
4240
4241 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4242 Results.data(), Results.size());
4243 }
4244
4245 struct Sema::CodeCompleteExpressionData {
CodeCompleteExpressionDataSema::CodeCompleteExpressionData4246 CodeCompleteExpressionData(QualType PreferredType = QualType(),
4247 bool IsParenthesized = false)
4248 : PreferredType(PreferredType), IntegralConstantExpression(false),
4249 ObjCCollection(false), IsParenthesized(IsParenthesized) {}
4250
4251 QualType PreferredType;
4252 bool IntegralConstantExpression;
4253 bool ObjCCollection;
4254 bool IsParenthesized;
4255 SmallVector<Decl *, 4> IgnoreDecls;
4256 };
4257
4258 namespace {
4259 /// Information that allows to avoid completing redundant enumerators.
4260 struct CoveredEnumerators {
4261 llvm::SmallPtrSet<EnumConstantDecl *, 8> Seen;
4262 NestedNameSpecifier *SuggestedQualifier = nullptr;
4263 };
4264 } // namespace
4265
AddEnumerators(ResultBuilder & Results,ASTContext & Context,EnumDecl * Enum,DeclContext * CurContext,const CoveredEnumerators & Enumerators)4266 static void AddEnumerators(ResultBuilder &Results, ASTContext &Context,
4267 EnumDecl *Enum, DeclContext *CurContext,
4268 const CoveredEnumerators &Enumerators) {
4269 NestedNameSpecifier *Qualifier = Enumerators.SuggestedQualifier;
4270 if (Context.getLangOpts().CPlusPlus && !Qualifier && Enumerators.Seen.empty()) {
4271 // If there are no prior enumerators in C++, check whether we have to
4272 // qualify the names of the enumerators that we suggest, because they
4273 // may not be visible in this scope.
4274 Qualifier = getRequiredQualification(Context, CurContext, Enum);
4275 }
4276
4277 Results.EnterNewScope();
4278 for (auto *E : Enum->enumerators()) {
4279 if (Enumerators.Seen.count(E))
4280 continue;
4281
4282 CodeCompletionResult R(E, CCP_EnumInCase, Qualifier);
4283 Results.AddResult(R, CurContext, nullptr, false);
4284 }
4285 Results.ExitScope();
4286 }
4287
4288 /// Try to find a corresponding FunctionProtoType for function-like types (e.g.
4289 /// function pointers, std::function, etc).
TryDeconstructFunctionLike(QualType T)4290 static const FunctionProtoType *TryDeconstructFunctionLike(QualType T) {
4291 assert(!T.isNull());
4292 // Try to extract first template argument from std::function<> and similar.
4293 // Note we only handle the sugared types, they closely match what users wrote.
4294 // We explicitly choose to not handle ClassTemplateSpecializationDecl.
4295 if (auto *Specialization = T->getAs<TemplateSpecializationType>()) {
4296 if (Specialization->getNumArgs() != 1)
4297 return nullptr;
4298 const TemplateArgument &Argument = Specialization->getArg(0);
4299 if (Argument.getKind() != TemplateArgument::Type)
4300 return nullptr;
4301 return Argument.getAsType()->getAs<FunctionProtoType>();
4302 }
4303 // Handle other cases.
4304 if (T->isPointerType())
4305 T = T->getPointeeType();
4306 return T->getAs<FunctionProtoType>();
4307 }
4308
4309 /// Adds a pattern completion for a lambda expression with the specified
4310 /// parameter types and placeholders for parameter names.
AddLambdaCompletion(ResultBuilder & Results,llvm::ArrayRef<QualType> Parameters,const LangOptions & LangOpts)4311 static void AddLambdaCompletion(ResultBuilder &Results,
4312 llvm::ArrayRef<QualType> Parameters,
4313 const LangOptions &LangOpts) {
4314 if (!Results.includeCodePatterns())
4315 return;
4316 CodeCompletionBuilder Completion(Results.getAllocator(),
4317 Results.getCodeCompletionTUInfo());
4318 // [](<parameters>) {}
4319 Completion.AddChunk(CodeCompletionString::CK_LeftBracket);
4320 Completion.AddPlaceholderChunk("=");
4321 Completion.AddChunk(CodeCompletionString::CK_RightBracket);
4322 if (!Parameters.empty()) {
4323 Completion.AddChunk(CodeCompletionString::CK_LeftParen);
4324 bool First = true;
4325 for (auto Parameter : Parameters) {
4326 if (!First)
4327 Completion.AddChunk(CodeCompletionString::ChunkKind::CK_Comma);
4328 else
4329 First = false;
4330
4331 constexpr llvm::StringLiteral NamePlaceholder = "!#!NAME_GOES_HERE!#!";
4332 std::string Type = NamePlaceholder;
4333 Parameter.getAsStringInternal(Type, PrintingPolicy(LangOpts));
4334 llvm::StringRef Prefix, Suffix;
4335 std::tie(Prefix, Suffix) = llvm::StringRef(Type).split(NamePlaceholder);
4336 Prefix = Prefix.rtrim();
4337 Suffix = Suffix.ltrim();
4338
4339 Completion.AddTextChunk(Completion.getAllocator().CopyString(Prefix));
4340 Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4341 Completion.AddPlaceholderChunk("parameter");
4342 Completion.AddTextChunk(Completion.getAllocator().CopyString(Suffix));
4343 };
4344 Completion.AddChunk(CodeCompletionString::CK_RightParen);
4345 }
4346 Completion.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace);
4347 Completion.AddChunk(CodeCompletionString::CK_LeftBrace);
4348 Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4349 Completion.AddPlaceholderChunk("body");
4350 Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4351 Completion.AddChunk(CodeCompletionString::CK_RightBrace);
4352
4353 Results.AddResult(Completion.TakeString());
4354 }
4355
4356 /// Perform code-completion in an expression context when we know what
4357 /// type we're looking for.
CodeCompleteExpression(Scope * S,const CodeCompleteExpressionData & Data)4358 void Sema::CodeCompleteExpression(Scope *S,
4359 const CodeCompleteExpressionData &Data) {
4360 ResultBuilder Results(
4361 *this, CodeCompleter->getAllocator(),
4362 CodeCompleter->getCodeCompletionTUInfo(),
4363 CodeCompletionContext(
4364 Data.IsParenthesized
4365 ? CodeCompletionContext::CCC_ParenthesizedExpression
4366 : CodeCompletionContext::CCC_Expression,
4367 Data.PreferredType));
4368 auto PCC =
4369 Data.IsParenthesized ? PCC_ParenthesizedExpression : PCC_Expression;
4370 if (Data.ObjCCollection)
4371 Results.setFilter(&ResultBuilder::IsObjCCollection);
4372 else if (Data.IntegralConstantExpression)
4373 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
4374 else if (WantTypesInContext(PCC, getLangOpts()))
4375 Results.setFilter(&ResultBuilder::IsOrdinaryName);
4376 else
4377 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
4378
4379 if (!Data.PreferredType.isNull())
4380 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
4381
4382 // Ignore any declarations that we were told that we don't care about.
4383 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
4384 Results.Ignore(Data.IgnoreDecls[I]);
4385
4386 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4387 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4388 CodeCompleter->includeGlobals(),
4389 CodeCompleter->loadExternal());
4390
4391 Results.EnterNewScope();
4392 AddOrdinaryNameResults(PCC, S, *this, Results);
4393 Results.ExitScope();
4394
4395 bool PreferredTypeIsPointer = false;
4396 if (!Data.PreferredType.isNull()) {
4397 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() ||
4398 Data.PreferredType->isMemberPointerType() ||
4399 Data.PreferredType->isBlockPointerType();
4400 if (Data.PreferredType->isEnumeralType()) {
4401 EnumDecl *Enum = Data.PreferredType->castAs<EnumType>()->getDecl();
4402 if (auto *Def = Enum->getDefinition())
4403 Enum = Def;
4404 // FIXME: collect covered enumerators in cases like:
4405 // if (x == my_enum::one) { ... } else if (x == ^) {}
4406 AddEnumerators(Results, Context, Enum, CurContext, CoveredEnumerators());
4407 }
4408 }
4409
4410 if (S->getFnParent() && !Data.ObjCCollection &&
4411 !Data.IntegralConstantExpression)
4412 AddPrettyFunctionResults(getLangOpts(), Results);
4413
4414 if (CodeCompleter->includeMacros())
4415 AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false,
4416 PreferredTypeIsPointer);
4417
4418 // Complete a lambda expression when preferred type is a function.
4419 if (!Data.PreferredType.isNull() && getLangOpts().CPlusPlus11) {
4420 if (const FunctionProtoType *F =
4421 TryDeconstructFunctionLike(Data.PreferredType))
4422 AddLambdaCompletion(Results, F->getParamTypes(), getLangOpts());
4423 }
4424
4425 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4426 Results.data(), Results.size());
4427 }
4428
CodeCompleteExpression(Scope * S,QualType PreferredType,bool IsParenthesized)4429 void Sema::CodeCompleteExpression(Scope *S, QualType PreferredType,
4430 bool IsParenthesized) {
4431 return CodeCompleteExpression(
4432 S, CodeCompleteExpressionData(PreferredType, IsParenthesized));
4433 }
4434
CodeCompletePostfixExpression(Scope * S,ExprResult E,QualType PreferredType)4435 void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E,
4436 QualType PreferredType) {
4437 if (E.isInvalid())
4438 CodeCompleteExpression(S, PreferredType);
4439 else if (getLangOpts().ObjC)
4440 CodeCompleteObjCInstanceMessage(S, E.get(), None, false);
4441 }
4442
4443 /// The set of properties that have already been added, referenced by
4444 /// property name.
4445 typedef llvm::SmallPtrSet<IdentifierInfo *, 16> AddedPropertiesSet;
4446
4447 /// Retrieve the container definition, if any?
getContainerDef(ObjCContainerDecl * Container)4448 static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {
4449 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
4450 if (Interface->hasDefinition())
4451 return Interface->getDefinition();
4452
4453 return Interface;
4454 }
4455
4456 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4457 if (Protocol->hasDefinition())
4458 return Protocol->getDefinition();
4459
4460 return Protocol;
4461 }
4462 return Container;
4463 }
4464
4465 /// Adds a block invocation code completion result for the given block
4466 /// declaration \p BD.
AddObjCBlockCall(ASTContext & Context,const PrintingPolicy & Policy,CodeCompletionBuilder & Builder,const NamedDecl * BD,const FunctionTypeLoc & BlockLoc,const FunctionProtoTypeLoc & BlockProtoLoc)4467 static void AddObjCBlockCall(ASTContext &Context, const PrintingPolicy &Policy,
4468 CodeCompletionBuilder &Builder,
4469 const NamedDecl *BD,
4470 const FunctionTypeLoc &BlockLoc,
4471 const FunctionProtoTypeLoc &BlockProtoLoc) {
4472 Builder.AddResultTypeChunk(
4473 GetCompletionTypeString(BlockLoc.getReturnLoc().getType(), Context,
4474 Policy, Builder.getAllocator()));
4475
4476 AddTypedNameChunk(Context, Policy, BD, Builder);
4477 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4478
4479 if (BlockProtoLoc && BlockProtoLoc.getTypePtr()->isVariadic()) {
4480 Builder.AddPlaceholderChunk("...");
4481 } else {
4482 for (unsigned I = 0, N = BlockLoc.getNumParams(); I != N; ++I) {
4483 if (I)
4484 Builder.AddChunk(CodeCompletionString::CK_Comma);
4485
4486 // Format the placeholder string.
4487 std::string PlaceholderStr =
4488 FormatFunctionParameter(Policy, BlockLoc.getParam(I));
4489
4490 if (I == N - 1 && BlockProtoLoc &&
4491 BlockProtoLoc.getTypePtr()->isVariadic())
4492 PlaceholderStr += ", ...";
4493
4494 // Add the placeholder string.
4495 Builder.AddPlaceholderChunk(
4496 Builder.getAllocator().CopyString(PlaceholderStr));
4497 }
4498 }
4499
4500 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4501 }
4502
4503 static void
AddObjCProperties(const CodeCompletionContext & CCContext,ObjCContainerDecl * Container,bool AllowCategories,bool AllowNullaryMethods,DeclContext * CurContext,AddedPropertiesSet & AddedProperties,ResultBuilder & Results,bool IsBaseExprStatement=false,bool IsClassProperty=false,bool InOriginalClass=true)4504 AddObjCProperties(const CodeCompletionContext &CCContext,
4505 ObjCContainerDecl *Container, bool AllowCategories,
4506 bool AllowNullaryMethods, DeclContext *CurContext,
4507 AddedPropertiesSet &AddedProperties, ResultBuilder &Results,
4508 bool IsBaseExprStatement = false,
4509 bool IsClassProperty = false, bool InOriginalClass = true) {
4510 typedef CodeCompletionResult Result;
4511
4512 // Retrieve the definition.
4513 Container = getContainerDef(Container);
4514
4515 // Add properties in this container.
4516 const auto AddProperty = [&](const ObjCPropertyDecl *P) {
4517 if (!AddedProperties.insert(P->getIdentifier()).second)
4518 return;
4519
4520 // FIXME: Provide block invocation completion for non-statement
4521 // expressions.
4522 if (!P->getType().getTypePtr()->isBlockPointerType() ||
4523 !IsBaseExprStatement) {
4524 Result R = Result(P, Results.getBasePriority(P), nullptr);
4525 if (!InOriginalClass)
4526 setInBaseClass(R);
4527 Results.MaybeAddResult(R, CurContext);
4528 return;
4529 }
4530
4531 // Block setter and invocation completion is provided only when we are able
4532 // to find the FunctionProtoTypeLoc with parameter names for the block.
4533 FunctionTypeLoc BlockLoc;
4534 FunctionProtoTypeLoc BlockProtoLoc;
4535 findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc,
4536 BlockProtoLoc);
4537 if (!BlockLoc) {
4538 Result R = Result(P, Results.getBasePriority(P), nullptr);
4539 if (!InOriginalClass)
4540 setInBaseClass(R);
4541 Results.MaybeAddResult(R, CurContext);
4542 return;
4543 }
4544
4545 // The default completion result for block properties should be the block
4546 // invocation completion when the base expression is a statement.
4547 CodeCompletionBuilder Builder(Results.getAllocator(),
4548 Results.getCodeCompletionTUInfo());
4549 AddObjCBlockCall(Container->getASTContext(),
4550 getCompletionPrintingPolicy(Results.getSema()), Builder, P,
4551 BlockLoc, BlockProtoLoc);
4552 Result R = Result(Builder.TakeString(), P, Results.getBasePriority(P));
4553 if (!InOriginalClass)
4554 setInBaseClass(R);
4555 Results.MaybeAddResult(R, CurContext);
4556
4557 // Provide additional block setter completion iff the base expression is a
4558 // statement and the block property is mutable.
4559 if (!P->isReadOnly()) {
4560 CodeCompletionBuilder Builder(Results.getAllocator(),
4561 Results.getCodeCompletionTUInfo());
4562 AddResultTypeChunk(Container->getASTContext(),
4563 getCompletionPrintingPolicy(Results.getSema()), P,
4564 CCContext.getBaseType(), Builder);
4565 Builder.AddTypedTextChunk(
4566 Results.getAllocator().CopyString(P->getName()));
4567 Builder.AddChunk(CodeCompletionString::CK_Equal);
4568
4569 std::string PlaceholderStr = formatBlockPlaceholder(
4570 getCompletionPrintingPolicy(Results.getSema()), P, BlockLoc,
4571 BlockProtoLoc, /*SuppressBlockName=*/true);
4572 // Add the placeholder string.
4573 Builder.AddPlaceholderChunk(
4574 Builder.getAllocator().CopyString(PlaceholderStr));
4575
4576 // When completing blocks properties that return void the default
4577 // property completion result should show up before the setter,
4578 // otherwise the setter completion should show up before the default
4579 // property completion, as we normally want to use the result of the
4580 // call.
4581 Result R =
4582 Result(Builder.TakeString(), P,
4583 Results.getBasePriority(P) +
4584 (BlockLoc.getTypePtr()->getReturnType()->isVoidType()
4585 ? CCD_BlockPropertySetter
4586 : -CCD_BlockPropertySetter));
4587 if (!InOriginalClass)
4588 setInBaseClass(R);
4589 Results.MaybeAddResult(R, CurContext);
4590 }
4591 };
4592
4593 if (IsClassProperty) {
4594 for (const auto *P : Container->class_properties())
4595 AddProperty(P);
4596 } else {
4597 for (const auto *P : Container->instance_properties())
4598 AddProperty(P);
4599 }
4600
4601 // Add nullary methods or implicit class properties
4602 if (AllowNullaryMethods) {
4603 ASTContext &Context = Container->getASTContext();
4604 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
4605 // Adds a method result
4606 const auto AddMethod = [&](const ObjCMethodDecl *M) {
4607 IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0);
4608 if (!Name)
4609 return;
4610 if (!AddedProperties.insert(Name).second)
4611 return;
4612 CodeCompletionBuilder Builder(Results.getAllocator(),
4613 Results.getCodeCompletionTUInfo());
4614 AddResultTypeChunk(Context, Policy, M, CCContext.getBaseType(), Builder);
4615 Builder.AddTypedTextChunk(
4616 Results.getAllocator().CopyString(Name->getName()));
4617 Result R = Result(Builder.TakeString(), M,
4618 CCP_MemberDeclaration + CCD_MethodAsProperty);
4619 if (!InOriginalClass)
4620 setInBaseClass(R);
4621 Results.MaybeAddResult(R, CurContext);
4622 };
4623
4624 if (IsClassProperty) {
4625 for (const auto *M : Container->methods()) {
4626 // Gather the class method that can be used as implicit property
4627 // getters. Methods with arguments or methods that return void aren't
4628 // added to the results as they can't be used as a getter.
4629 if (!M->getSelector().isUnarySelector() ||
4630 M->getReturnType()->isVoidType() || M->isInstanceMethod())
4631 continue;
4632 AddMethod(M);
4633 }
4634 } else {
4635 for (auto *M : Container->methods()) {
4636 if (M->getSelector().isUnarySelector())
4637 AddMethod(M);
4638 }
4639 }
4640 }
4641
4642 // Add properties in referenced protocols.
4643 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4644 for (auto *P : Protocol->protocols())
4645 AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
4646 CurContext, AddedProperties, Results,
4647 IsBaseExprStatement, IsClassProperty,
4648 /*InOriginalClass*/ false);
4649 } else if (ObjCInterfaceDecl *IFace =
4650 dyn_cast<ObjCInterfaceDecl>(Container)) {
4651 if (AllowCategories) {
4652 // Look through categories.
4653 for (auto *Cat : IFace->known_categories())
4654 AddObjCProperties(CCContext, Cat, AllowCategories, AllowNullaryMethods,
4655 CurContext, AddedProperties, Results,
4656 IsBaseExprStatement, IsClassProperty,
4657 InOriginalClass);
4658 }
4659
4660 // Look through protocols.
4661 for (auto *I : IFace->all_referenced_protocols())
4662 AddObjCProperties(CCContext, I, AllowCategories, AllowNullaryMethods,
4663 CurContext, AddedProperties, Results,
4664 IsBaseExprStatement, IsClassProperty,
4665 /*InOriginalClass*/ false);
4666
4667 // Look in the superclass.
4668 if (IFace->getSuperClass())
4669 AddObjCProperties(CCContext, IFace->getSuperClass(), AllowCategories,
4670 AllowNullaryMethods, CurContext, AddedProperties,
4671 Results, IsBaseExprStatement, IsClassProperty,
4672 /*InOriginalClass*/ false);
4673 } else if (const auto *Category =
4674 dyn_cast<ObjCCategoryDecl>(Container)) {
4675 // Look through protocols.
4676 for (auto *P : Category->protocols())
4677 AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
4678 CurContext, AddedProperties, Results,
4679 IsBaseExprStatement, IsClassProperty,
4680 /*InOriginalClass*/ false);
4681 }
4682 }
4683
AddRecordMembersCompletionResults(Sema & SemaRef,ResultBuilder & Results,Scope * S,QualType BaseType,ExprValueKind BaseKind,RecordDecl * RD,Optional<FixItHint> AccessOpFixIt)4684 static void AddRecordMembersCompletionResults(
4685 Sema &SemaRef, ResultBuilder &Results, Scope *S, QualType BaseType,
4686 ExprValueKind BaseKind, RecordDecl *RD, Optional<FixItHint> AccessOpFixIt) {
4687 // Indicate that we are performing a member access, and the cv-qualifiers
4688 // for the base object type.
4689 Results.setObjectTypeQualifiers(BaseType.getQualifiers(), BaseKind);
4690
4691 // Access to a C/C++ class, struct, or union.
4692 Results.allowNestedNameSpecifiers();
4693 std::vector<FixItHint> FixIts;
4694 if (AccessOpFixIt)
4695 FixIts.emplace_back(AccessOpFixIt.getValue());
4696 CodeCompletionDeclConsumer Consumer(Results, RD, BaseType, std::move(FixIts));
4697 SemaRef.LookupVisibleDecls(RD, Sema::LookupMemberName, Consumer,
4698 SemaRef.CodeCompleter->includeGlobals(),
4699 /*IncludeDependentBases=*/true,
4700 SemaRef.CodeCompleter->loadExternal());
4701
4702 if (SemaRef.getLangOpts().CPlusPlus) {
4703 if (!Results.empty()) {
4704 // The "template" keyword can follow "->" or "." in the grammar.
4705 // However, we only want to suggest the template keyword if something
4706 // is dependent.
4707 bool IsDependent = BaseType->isDependentType();
4708 if (!IsDependent) {
4709 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
4710 if (DeclContext *Ctx = DepScope->getEntity()) {
4711 IsDependent = Ctx->isDependentContext();
4712 break;
4713 }
4714 }
4715
4716 if (IsDependent)
4717 Results.AddResult(CodeCompletionResult("template"));
4718 }
4719 }
4720 }
4721
CodeCompleteMemberReferenceExpr(Scope * S,Expr * Base,Expr * OtherOpBase,SourceLocation OpLoc,bool IsArrow,bool IsBaseExprStatement,QualType PreferredType)4722 void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
4723 Expr *OtherOpBase,
4724 SourceLocation OpLoc, bool IsArrow,
4725 bool IsBaseExprStatement,
4726 QualType PreferredType) {
4727 if (!Base || !CodeCompleter)
4728 return;
4729
4730 ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
4731 if (ConvertedBase.isInvalid())
4732 return;
4733 QualType ConvertedBaseType = ConvertedBase.get()->getType();
4734
4735 enum CodeCompletionContext::Kind contextKind;
4736
4737 if (IsArrow) {
4738 if (const auto *Ptr = ConvertedBaseType->getAs<PointerType>())
4739 ConvertedBaseType = Ptr->getPointeeType();
4740 }
4741
4742 if (IsArrow) {
4743 contextKind = CodeCompletionContext::CCC_ArrowMemberAccess;
4744 } else {
4745 if (ConvertedBaseType->isObjCObjectPointerType() ||
4746 ConvertedBaseType->isObjCObjectOrInterfaceType()) {
4747 contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess;
4748 } else {
4749 contextKind = CodeCompletionContext::CCC_DotMemberAccess;
4750 }
4751 }
4752
4753 CodeCompletionContext CCContext(contextKind, ConvertedBaseType);
4754 CCContext.setPreferredType(PreferredType);
4755 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4756 CodeCompleter->getCodeCompletionTUInfo(), CCContext,
4757 &ResultBuilder::IsMember);
4758
4759 auto DoCompletion = [&](Expr *Base, bool IsArrow,
4760 Optional<FixItHint> AccessOpFixIt) -> bool {
4761 if (!Base)
4762 return false;
4763
4764 ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
4765 if (ConvertedBase.isInvalid())
4766 return false;
4767 Base = ConvertedBase.get();
4768
4769 QualType BaseType = Base->getType();
4770 ExprValueKind BaseKind = Base->getValueKind();
4771
4772 if (IsArrow) {
4773 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
4774 BaseType = Ptr->getPointeeType();
4775 BaseKind = VK_LValue;
4776 } else if (BaseType->isObjCObjectPointerType())
4777 /*Do nothing*/;
4778 else
4779 return false;
4780 }
4781
4782 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
4783 AddRecordMembersCompletionResults(*this, Results, S, BaseType, BaseKind,
4784 Record->getDecl(),
4785 std::move(AccessOpFixIt));
4786 } else if (const auto *TST =
4787 BaseType->getAs<TemplateSpecializationType>()) {
4788 TemplateName TN = TST->getTemplateName();
4789 if (const auto *TD =
4790 dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl())) {
4791 CXXRecordDecl *RD = TD->getTemplatedDecl();
4792 AddRecordMembersCompletionResults(*this, Results, S, BaseType, BaseKind,
4793 RD, std::move(AccessOpFixIt));
4794 }
4795 } else if (const auto *ICNT = BaseType->getAs<InjectedClassNameType>()) {
4796 if (auto *RD = ICNT->getDecl())
4797 AddRecordMembersCompletionResults(*this, Results, S, BaseType, BaseKind,
4798 RD, std::move(AccessOpFixIt));
4799 } else if (!IsArrow && BaseType->isObjCObjectPointerType()) {
4800 // Objective-C property reference.
4801 AddedPropertiesSet AddedProperties;
4802
4803 if (const ObjCObjectPointerType *ObjCPtr =
4804 BaseType->getAsObjCInterfacePointerType()) {
4805 // Add property results based on our interface.
4806 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
4807 AddObjCProperties(CCContext, ObjCPtr->getInterfaceDecl(), true,
4808 /*AllowNullaryMethods=*/true, CurContext,
4809 AddedProperties, Results, IsBaseExprStatement);
4810 }
4811
4812 // Add properties from the protocols in a qualified interface.
4813 for (auto *I : BaseType->castAs<ObjCObjectPointerType>()->quals())
4814 AddObjCProperties(CCContext, I, true, /*AllowNullaryMethods=*/true,
4815 CurContext, AddedProperties, Results,
4816 IsBaseExprStatement, /*IsClassProperty*/ false,
4817 /*InOriginalClass*/ false);
4818 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
4819 (!IsArrow && BaseType->isObjCObjectType())) {
4820 // Objective-C instance variable access.
4821 ObjCInterfaceDecl *Class = nullptr;
4822 if (const ObjCObjectPointerType *ObjCPtr =
4823 BaseType->getAs<ObjCObjectPointerType>())
4824 Class = ObjCPtr->getInterfaceDecl();
4825 else
4826 Class = BaseType->castAs<ObjCObjectType>()->getInterface();
4827
4828 // Add all ivars from this class and its superclasses.
4829 if (Class) {
4830 CodeCompletionDeclConsumer Consumer(Results, Class, BaseType);
4831 Results.setFilter(&ResultBuilder::IsObjCIvar);
4832 LookupVisibleDecls(
4833 Class, LookupMemberName, Consumer, CodeCompleter->includeGlobals(),
4834 /*IncludeDependentBases=*/false, CodeCompleter->loadExternal());
4835 }
4836 }
4837
4838 // FIXME: How do we cope with isa?
4839 return true;
4840 };
4841
4842 Results.EnterNewScope();
4843
4844 bool CompletionSucceded = DoCompletion(Base, IsArrow, None);
4845 if (CodeCompleter->includeFixIts()) {
4846 const CharSourceRange OpRange =
4847 CharSourceRange::getTokenRange(OpLoc, OpLoc);
4848 CompletionSucceded |= DoCompletion(
4849 OtherOpBase, !IsArrow,
4850 FixItHint::CreateReplacement(OpRange, IsArrow ? "." : "->"));
4851 }
4852
4853 Results.ExitScope();
4854
4855 if (!CompletionSucceded)
4856 return;
4857
4858 // Hand off the results found for code completion.
4859 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4860 Results.data(), Results.size());
4861 }
4862
CodeCompleteObjCClassPropertyRefExpr(Scope * S,IdentifierInfo & ClassName,SourceLocation ClassNameLoc,bool IsBaseExprStatement)4863 void Sema::CodeCompleteObjCClassPropertyRefExpr(Scope *S,
4864 IdentifierInfo &ClassName,
4865 SourceLocation ClassNameLoc,
4866 bool IsBaseExprStatement) {
4867 IdentifierInfo *ClassNamePtr = &ClassName;
4868 ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(ClassNamePtr, ClassNameLoc);
4869 if (!IFace)
4870 return;
4871 CodeCompletionContext CCContext(
4872 CodeCompletionContext::CCC_ObjCPropertyAccess);
4873 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4874 CodeCompleter->getCodeCompletionTUInfo(), CCContext,
4875 &ResultBuilder::IsMember);
4876 Results.EnterNewScope();
4877 AddedPropertiesSet AddedProperties;
4878 AddObjCProperties(CCContext, IFace, true,
4879 /*AllowNullaryMethods=*/true, CurContext, AddedProperties,
4880 Results, IsBaseExprStatement,
4881 /*IsClassProperty=*/true);
4882 Results.ExitScope();
4883 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4884 Results.data(), Results.size());
4885 }
4886
CodeCompleteTag(Scope * S,unsigned TagSpec)4887 void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
4888 if (!CodeCompleter)
4889 return;
4890
4891 ResultBuilder::LookupFilter Filter = nullptr;
4892 enum CodeCompletionContext::Kind ContextKind =
4893 CodeCompletionContext::CCC_Other;
4894 switch ((DeclSpec::TST)TagSpec) {
4895 case DeclSpec::TST_enum:
4896 Filter = &ResultBuilder::IsEnum;
4897 ContextKind = CodeCompletionContext::CCC_EnumTag;
4898 break;
4899
4900 case DeclSpec::TST_union:
4901 Filter = &ResultBuilder::IsUnion;
4902 ContextKind = CodeCompletionContext::CCC_UnionTag;
4903 break;
4904
4905 case DeclSpec::TST_struct:
4906 case DeclSpec::TST_class:
4907 case DeclSpec::TST_interface:
4908 Filter = &ResultBuilder::IsClassOrStruct;
4909 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
4910 break;
4911
4912 default:
4913 llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
4914 }
4915
4916 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4917 CodeCompleter->getCodeCompletionTUInfo(), ContextKind);
4918 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4919
4920 // First pass: look for tags.
4921 Results.setFilter(Filter);
4922 LookupVisibleDecls(S, LookupTagName, Consumer,
4923 CodeCompleter->includeGlobals(),
4924 CodeCompleter->loadExternal());
4925
4926 if (CodeCompleter->includeGlobals()) {
4927 // Second pass: look for nested name specifiers.
4928 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
4929 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
4930 CodeCompleter->includeGlobals(),
4931 CodeCompleter->loadExternal());
4932 }
4933
4934 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4935 Results.data(), Results.size());
4936 }
4937
AddTypeQualifierResults(DeclSpec & DS,ResultBuilder & Results,const LangOptions & LangOpts)4938 static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results,
4939 const LangOptions &LangOpts) {
4940 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
4941 Results.AddResult("const");
4942 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
4943 Results.AddResult("volatile");
4944 if (LangOpts.C99 && !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
4945 Results.AddResult("restrict");
4946 if (LangOpts.C11 && !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
4947 Results.AddResult("_Atomic");
4948 if (LangOpts.MSVCCompat && !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
4949 Results.AddResult("__unaligned");
4950 }
4951
CodeCompleteTypeQualifiers(DeclSpec & DS)4952 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
4953 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4954 CodeCompleter->getCodeCompletionTUInfo(),
4955 CodeCompletionContext::CCC_TypeQualifiers);
4956 Results.EnterNewScope();
4957 AddTypeQualifierResults(DS, Results, LangOpts);
4958 Results.ExitScope();
4959 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4960 Results.data(), Results.size());
4961 }
4962
CodeCompleteFunctionQualifiers(DeclSpec & DS,Declarator & D,const VirtSpecifiers * VS)4963 void Sema::CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
4964 const VirtSpecifiers *VS) {
4965 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4966 CodeCompleter->getCodeCompletionTUInfo(),
4967 CodeCompletionContext::CCC_TypeQualifiers);
4968 Results.EnterNewScope();
4969 AddTypeQualifierResults(DS, Results, LangOpts);
4970 if (LangOpts.CPlusPlus11) {
4971 Results.AddResult("noexcept");
4972 if (D.getContext() == DeclaratorContext::MemberContext &&
4973 !D.isCtorOrDtor() && !D.isStaticMember()) {
4974 if (!VS || !VS->isFinalSpecified())
4975 Results.AddResult("final");
4976 if (!VS || !VS->isOverrideSpecified())
4977 Results.AddResult("override");
4978 }
4979 }
4980 Results.ExitScope();
4981 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4982 Results.data(), Results.size());
4983 }
4984
CodeCompleteBracketDeclarator(Scope * S)4985 void Sema::CodeCompleteBracketDeclarator(Scope *S) {
4986 CodeCompleteExpression(S, QualType(getASTContext().getSizeType()));
4987 }
4988
CodeCompleteCase(Scope * S)4989 void Sema::CodeCompleteCase(Scope *S) {
4990 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
4991 return;
4992
4993 SwitchStmt *Switch = getCurFunction()->SwitchStack.back().getPointer();
4994 // Condition expression might be invalid, do not continue in this case.
4995 if (!Switch->getCond())
4996 return;
4997 QualType type = Switch->getCond()->IgnoreImplicit()->getType();
4998 if (!type->isEnumeralType()) {
4999 CodeCompleteExpressionData Data(type);
5000 Data.IntegralConstantExpression = true;
5001 CodeCompleteExpression(S, Data);
5002 return;
5003 }
5004
5005 // Code-complete the cases of a switch statement over an enumeration type
5006 // by providing the list of
5007 EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
5008 if (EnumDecl *Def = Enum->getDefinition())
5009 Enum = Def;
5010
5011 // Determine which enumerators we have already seen in the switch statement.
5012 // FIXME: Ideally, we would also be able to look *past* the code-completion
5013 // token, in case we are code-completing in the middle of the switch and not
5014 // at the end. However, we aren't able to do so at the moment.
5015 CoveredEnumerators Enumerators;
5016 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
5017 SC = SC->getNextSwitchCase()) {
5018 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
5019 if (!Case)
5020 continue;
5021
5022 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
5023 if (auto *DRE = dyn_cast<DeclRefExpr>(CaseVal))
5024 if (auto *Enumerator =
5025 dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
5026 // We look into the AST of the case statement to determine which
5027 // enumerator was named. Alternatively, we could compute the value of
5028 // the integral constant expression, then compare it against the
5029 // values of each enumerator. However, value-based approach would not
5030 // work as well with C++ templates where enumerators declared within a
5031 // template are type- and value-dependent.
5032 Enumerators.Seen.insert(Enumerator);
5033
5034 // If this is a qualified-id, keep track of the nested-name-specifier
5035 // so that we can reproduce it as part of code completion, e.g.,
5036 //
5037 // switch (TagD.getKind()) {
5038 // case TagDecl::TK_enum:
5039 // break;
5040 // case XXX
5041 //
5042 // At the XXX, our completions are TagDecl::TK_union,
5043 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
5044 // TK_struct, and TK_class.
5045 Enumerators.SuggestedQualifier = DRE->getQualifier();
5046 }
5047 }
5048
5049 // Add any enumerators that have not yet been mentioned.
5050 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5051 CodeCompleter->getCodeCompletionTUInfo(),
5052 CodeCompletionContext::CCC_Expression);
5053 AddEnumerators(Results, Context, Enum, CurContext, Enumerators);
5054
5055 if (CodeCompleter->includeMacros()) {
5056 AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false);
5057 }
5058 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5059 Results.data(), Results.size());
5060 }
5061
anyNullArguments(ArrayRef<Expr * > Args)5062 static bool anyNullArguments(ArrayRef<Expr *> Args) {
5063 if (Args.size() && !Args.data())
5064 return true;
5065
5066 for (unsigned I = 0; I != Args.size(); ++I)
5067 if (!Args[I])
5068 return true;
5069
5070 return false;
5071 }
5072
5073 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
5074
mergeCandidatesWithResults(Sema & SemaRef,SmallVectorImpl<ResultCandidate> & Results,OverloadCandidateSet & CandidateSet,SourceLocation Loc)5075 static void mergeCandidatesWithResults(
5076 Sema &SemaRef, SmallVectorImpl<ResultCandidate> &Results,
5077 OverloadCandidateSet &CandidateSet, SourceLocation Loc) {
5078 // Sort the overload candidate set by placing the best overloads first.
5079 llvm::stable_sort(CandidateSet, [&](const OverloadCandidate &X,
5080 const OverloadCandidate &Y) {
5081 return isBetterOverloadCandidate(SemaRef, X, Y, Loc,
5082 CandidateSet.getKind());
5083 });
5084
5085 // Add the remaining viable overload candidates as code-completion results.
5086 for (OverloadCandidate &Candidate : CandidateSet) {
5087 if (Candidate.Function && Candidate.Function->isDeleted())
5088 continue;
5089 if (Candidate.Viable)
5090 Results.push_back(ResultCandidate(Candidate.Function));
5091 }
5092 }
5093
5094 /// Get the type of the Nth parameter from a given set of overload
5095 /// candidates.
getParamType(Sema & SemaRef,ArrayRef<ResultCandidate> Candidates,unsigned N)5096 static QualType getParamType(Sema &SemaRef,
5097 ArrayRef<ResultCandidate> Candidates, unsigned N) {
5098
5099 // Given the overloads 'Candidates' for a function call matching all arguments
5100 // up to N, return the type of the Nth parameter if it is the same for all
5101 // overload candidates.
5102 QualType ParamType;
5103 for (auto &Candidate : Candidates) {
5104 if (const auto *FType = Candidate.getFunctionType())
5105 if (const auto *Proto = dyn_cast<FunctionProtoType>(FType))
5106 if (N < Proto->getNumParams()) {
5107 if (ParamType.isNull())
5108 ParamType = Proto->getParamType(N);
5109 else if (!SemaRef.Context.hasSameUnqualifiedType(
5110 ParamType.getNonReferenceType(),
5111 Proto->getParamType(N).getNonReferenceType()))
5112 // Otherwise return a default-constructed QualType.
5113 return QualType();
5114 }
5115 }
5116
5117 return ParamType;
5118 }
5119
5120 static QualType
ProduceSignatureHelp(Sema & SemaRef,Scope * S,MutableArrayRef<ResultCandidate> Candidates,unsigned CurrentArg,SourceLocation OpenParLoc)5121 ProduceSignatureHelp(Sema &SemaRef, Scope *S,
5122 MutableArrayRef<ResultCandidate> Candidates,
5123 unsigned CurrentArg, SourceLocation OpenParLoc) {
5124 if (Candidates.empty())
5125 return QualType();
5126 SemaRef.CodeCompleter->ProcessOverloadCandidates(
5127 SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc);
5128 return getParamType(SemaRef, Candidates, CurrentArg);
5129 }
5130
ProduceCallSignatureHelp(Scope * S,Expr * Fn,ArrayRef<Expr * > Args,SourceLocation OpenParLoc)5131 QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn,
5132 ArrayRef<Expr *> Args,
5133 SourceLocation OpenParLoc) {
5134 if (!CodeCompleter)
5135 return QualType();
5136
5137 // FIXME: Provide support for variadic template functions.
5138 // Ignore type-dependent call expressions entirely.
5139 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
5140 Expr::hasAnyTypeDependentArguments(Args)) {
5141 return QualType();
5142 }
5143
5144 // Build an overload candidate set based on the functions we find.
5145 SourceLocation Loc = Fn->getExprLoc();
5146 OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
5147
5148 SmallVector<ResultCandidate, 8> Results;
5149
5150 Expr *NakedFn = Fn->IgnoreParenCasts();
5151 if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
5152 AddOverloadedCallCandidates(ULE, Args, CandidateSet,
5153 /*PartialOverloading=*/true);
5154 else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) {
5155 TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
5156 if (UME->hasExplicitTemplateArgs()) {
5157 UME->copyTemplateArgumentsInto(TemplateArgsBuffer);
5158 TemplateArgs = &TemplateArgsBuffer;
5159 }
5160
5161 // Add the base as first argument (use a nullptr if the base is implicit).
5162 SmallVector<Expr *, 12> ArgExprs(
5163 1, UME->isImplicitAccess() ? nullptr : UME->getBase());
5164 ArgExprs.append(Args.begin(), Args.end());
5165 UnresolvedSet<8> Decls;
5166 Decls.append(UME->decls_begin(), UME->decls_end());
5167 const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase();
5168 AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,
5169 /*SuppressUserConversions=*/false,
5170 /*PartialOverloading=*/true, FirstArgumentIsBase);
5171 } else {
5172 FunctionDecl *FD = nullptr;
5173 if (auto *MCE = dyn_cast<MemberExpr>(NakedFn))
5174 FD = dyn_cast<FunctionDecl>(MCE->getMemberDecl());
5175 else if (auto *DRE = dyn_cast<DeclRefExpr>(NakedFn))
5176 FD = dyn_cast<FunctionDecl>(DRE->getDecl());
5177 if (FD) { // We check whether it's a resolved function declaration.
5178 if (!getLangOpts().CPlusPlus ||
5179 !FD->getType()->getAs<FunctionProtoType>())
5180 Results.push_back(ResultCandidate(FD));
5181 else
5182 AddOverloadCandidate(FD, DeclAccessPair::make(FD, FD->getAccess()),
5183 Args, CandidateSet,
5184 /*SuppressUserConversions=*/false,
5185 /*PartialOverloading=*/true);
5186
5187 } else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) {
5188 // If expression's type is CXXRecordDecl, it may overload the function
5189 // call operator, so we check if it does and add them as candidates.
5190 // A complete type is needed to lookup for member function call operators.
5191 if (isCompleteType(Loc, NakedFn->getType())) {
5192 DeclarationName OpName =
5193 Context.DeclarationNames.getCXXOperatorName(OO_Call);
5194 LookupResult R(*this, OpName, Loc, LookupOrdinaryName);
5195 LookupQualifiedName(R, DC);
5196 R.suppressDiagnostics();
5197 SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
5198 ArgExprs.append(Args.begin(), Args.end());
5199 AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs, CandidateSet,
5200 /*ExplicitArgs=*/nullptr,
5201 /*SuppressUserConversions=*/false,
5202 /*PartialOverloading=*/true);
5203 }
5204 } else {
5205 // Lastly we check whether expression's type is function pointer or
5206 // function.
5207 QualType T = NakedFn->getType();
5208 if (!T->getPointeeType().isNull())
5209 T = T->getPointeeType();
5210
5211 if (auto FP = T->getAs<FunctionProtoType>()) {
5212 if (!TooManyArguments(FP->getNumParams(), Args.size(),
5213 /*PartialOverloading=*/true) ||
5214 FP->isVariadic())
5215 Results.push_back(ResultCandidate(FP));
5216 } else if (auto FT = T->getAs<FunctionType>())
5217 // No prototype and declaration, it may be a K & R style function.
5218 Results.push_back(ResultCandidate(FT));
5219 }
5220 }
5221 mergeCandidatesWithResults(*this, Results, CandidateSet, Loc);
5222 QualType ParamType =
5223 ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc);
5224 return !CandidateSet.empty() ? ParamType : QualType();
5225 }
5226
ProduceConstructorSignatureHelp(Scope * S,QualType Type,SourceLocation Loc,ArrayRef<Expr * > Args,SourceLocation OpenParLoc)5227 QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type,
5228 SourceLocation Loc,
5229 ArrayRef<Expr *> Args,
5230 SourceLocation OpenParLoc) {
5231 if (!CodeCompleter)
5232 return QualType();
5233
5234 // A complete type is needed to lookup for constructors.
5235 CXXRecordDecl *RD =
5236 isCompleteType(Loc, Type) ? Type->getAsCXXRecordDecl() : nullptr;
5237 if (!RD)
5238 return Type;
5239
5240 // FIXME: Provide support for member initializers.
5241 // FIXME: Provide support for variadic template constructors.
5242
5243 OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
5244
5245 for (NamedDecl *C : LookupConstructors(RD)) {
5246 if (auto *FD = dyn_cast<FunctionDecl>(C)) {
5247 AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args,
5248 CandidateSet,
5249 /*SuppressUserConversions=*/false,
5250 /*PartialOverloading=*/true,
5251 /*AllowExplicit*/ true);
5252 } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) {
5253 AddTemplateOverloadCandidate(
5254 FTD, DeclAccessPair::make(FTD, C->getAccess()),
5255 /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet,
5256 /*SuppressUserConversions=*/false,
5257 /*PartialOverloading=*/true);
5258 }
5259 }
5260
5261 SmallVector<ResultCandidate, 8> Results;
5262 mergeCandidatesWithResults(*this, Results, CandidateSet, Loc);
5263 return ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc);
5264 }
5265
ProduceCtorInitMemberSignatureHelp(Scope * S,Decl * ConstructorDecl,CXXScopeSpec SS,ParsedType TemplateTypeTy,ArrayRef<Expr * > ArgExprs,IdentifierInfo * II,SourceLocation OpenParLoc)5266 QualType Sema::ProduceCtorInitMemberSignatureHelp(
5267 Scope *S, Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy,
5268 ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc) {
5269 if (!CodeCompleter)
5270 return QualType();
5271
5272 CXXConstructorDecl *Constructor =
5273 dyn_cast<CXXConstructorDecl>(ConstructorDecl);
5274 if (!Constructor)
5275 return QualType();
5276 // FIXME: Add support for Base class constructors as well.
5277 if (ValueDecl *MemberDecl = tryLookupCtorInitMemberDecl(
5278 Constructor->getParent(), SS, TemplateTypeTy, II))
5279 return ProduceConstructorSignatureHelp(getCurScope(), MemberDecl->getType(),
5280 MemberDecl->getLocation(), ArgExprs,
5281 OpenParLoc);
5282 return QualType();
5283 }
5284
CodeCompleteInitializer(Scope * S,Decl * D)5285 void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
5286 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
5287 if (!VD) {
5288 CodeCompleteOrdinaryName(S, PCC_Expression);
5289 return;
5290 }
5291
5292 CodeCompleteExpressionData Data;
5293 Data.PreferredType = VD->getType();
5294 // Ignore VD to avoid completing the variable itself, e.g. in 'int foo = ^'.
5295 Data.IgnoreDecls.push_back(VD);
5296
5297 CodeCompleteExpression(S, Data);
5298 }
5299
CodeCompleteAfterIf(Scope * S)5300 void Sema::CodeCompleteAfterIf(Scope *S) {
5301 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5302 CodeCompleter->getCodeCompletionTUInfo(),
5303 mapCodeCompletionContext(*this, PCC_Statement));
5304 Results.setFilter(&ResultBuilder::IsOrdinaryName);
5305 Results.EnterNewScope();
5306
5307 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5308 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5309 CodeCompleter->includeGlobals(),
5310 CodeCompleter->loadExternal());
5311
5312 AddOrdinaryNameResults(PCC_Statement, S, *this, Results);
5313
5314 // "else" block
5315 CodeCompletionBuilder Builder(Results.getAllocator(),
5316 Results.getCodeCompletionTUInfo());
5317 Builder.AddTypedTextChunk("else");
5318 if (Results.includeCodePatterns()) {
5319 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5320 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
5321 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
5322 Builder.AddPlaceholderChunk("statements");
5323 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
5324 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
5325 }
5326 Results.AddResult(Builder.TakeString());
5327
5328 // "else if" block
5329 Builder.AddTypedTextChunk("else if");
5330 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5331 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5332 if (getLangOpts().CPlusPlus)
5333 Builder.AddPlaceholderChunk("condition");
5334 else
5335 Builder.AddPlaceholderChunk("expression");
5336 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5337 if (Results.includeCodePatterns()) {
5338 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5339 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
5340 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
5341 Builder.AddPlaceholderChunk("statements");
5342 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
5343 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
5344 }
5345 Results.AddResult(Builder.TakeString());
5346
5347 Results.ExitScope();
5348
5349 if (S->getFnParent())
5350 AddPrettyFunctionResults(getLangOpts(), Results);
5351
5352 if (CodeCompleter->includeMacros())
5353 AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false);
5354
5355 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5356 Results.data(), Results.size());
5357 }
5358
CodeCompleteQualifiedId(Scope * S,CXXScopeSpec & SS,bool EnteringContext,bool IsUsingDeclaration,QualType BaseType,QualType PreferredType)5359 void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
5360 bool EnteringContext,
5361 bool IsUsingDeclaration, QualType BaseType,
5362 QualType PreferredType) {
5363 if (SS.isEmpty() || !CodeCompleter)
5364 return;
5365
5366 CodeCompletionContext CC(CodeCompletionContext::CCC_Symbol, PreferredType);
5367 CC.setIsUsingDeclaration(IsUsingDeclaration);
5368 CC.setCXXScopeSpecifier(SS);
5369
5370 // We want to keep the scope specifier even if it's invalid (e.g. the scope
5371 // "a::b::" is not corresponding to any context/namespace in the AST), since
5372 // it can be useful for global code completion which have information about
5373 // contexts/symbols that are not in the AST.
5374 if (SS.isInvalid()) {
5375 // As SS is invalid, we try to collect accessible contexts from the current
5376 // scope with a dummy lookup so that the completion consumer can try to
5377 // guess what the specified scope is.
5378 ResultBuilder DummyResults(*this, CodeCompleter->getAllocator(),
5379 CodeCompleter->getCodeCompletionTUInfo(), CC);
5380 if (!PreferredType.isNull())
5381 DummyResults.setPreferredType(PreferredType);
5382 if (S->getEntity()) {
5383 CodeCompletionDeclConsumer Consumer(DummyResults, S->getEntity(),
5384 BaseType);
5385 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5386 /*IncludeGlobalScope=*/false,
5387 /*LoadExternal=*/false);
5388 }
5389 HandleCodeCompleteResults(this, CodeCompleter,
5390 DummyResults.getCompletionContext(), nullptr, 0);
5391 return;
5392 }
5393 // Always pretend to enter a context to ensure that a dependent type
5394 // resolves to a dependent record.
5395 DeclContext *Ctx = computeDeclContext(SS, /*EnteringContext=*/true);
5396 if (!Ctx)
5397 return;
5398
5399 // Try to instantiate any non-dependent declaration contexts before
5400 // we look in them.
5401 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
5402 return;
5403
5404 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5405 CodeCompleter->getCodeCompletionTUInfo(), CC);
5406 if (!PreferredType.isNull())
5407 Results.setPreferredType(PreferredType);
5408 Results.EnterNewScope();
5409
5410 // The "template" keyword can follow "::" in the grammar, but only
5411 // put it into the grammar if the nested-name-specifier is dependent.
5412 NestedNameSpecifier *NNS = SS.getScopeRep();
5413 if (!Results.empty() && NNS->isDependent())
5414 Results.AddResult("template");
5415
5416 // Add calls to overridden virtual functions, if there are any.
5417 //
5418 // FIXME: This isn't wonderful, because we don't know whether we're actually
5419 // in a context that permits expressions. This is a general issue with
5420 // qualified-id completions.
5421 if (!EnteringContext)
5422 MaybeAddOverrideCalls(*this, Ctx, Results);
5423 Results.ExitScope();
5424
5425 if (CodeCompleter->includeNamespaceLevelDecls() ||
5426 (!Ctx->isNamespace() && !Ctx->isTranslationUnit())) {
5427 CodeCompletionDeclConsumer Consumer(Results, Ctx, BaseType);
5428 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer,
5429 /*IncludeGlobalScope=*/true,
5430 /*IncludeDependentBases=*/true,
5431 CodeCompleter->loadExternal());
5432 }
5433
5434 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5435 Results.data(), Results.size());
5436 }
5437
CodeCompleteUsing(Scope * S)5438 void Sema::CodeCompleteUsing(Scope *S) {
5439 if (!CodeCompleter)
5440 return;
5441
5442 // This can be both a using alias or using declaration, in the former we
5443 // expect a new name and a symbol in the latter case.
5444 CodeCompletionContext Context(CodeCompletionContext::CCC_SymbolOrNewName);
5445 Context.setIsUsingDeclaration(true);
5446
5447 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5448 CodeCompleter->getCodeCompletionTUInfo(), Context,
5449 &ResultBuilder::IsNestedNameSpecifier);
5450 Results.EnterNewScope();
5451
5452 // If we aren't in class scope, we could see the "namespace" keyword.
5453 if (!S->isClassScope())
5454 Results.AddResult(CodeCompletionResult("namespace"));
5455
5456 // After "using", we can see anything that would start a
5457 // nested-name-specifier.
5458 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5459 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5460 CodeCompleter->includeGlobals(),
5461 CodeCompleter->loadExternal());
5462 Results.ExitScope();
5463
5464 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5465 Results.data(), Results.size());
5466 }
5467
CodeCompleteUsingDirective(Scope * S)5468 void Sema::CodeCompleteUsingDirective(Scope *S) {
5469 if (!CodeCompleter)
5470 return;
5471
5472 // After "using namespace", we expect to see a namespace name or namespace
5473 // alias.
5474 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5475 CodeCompleter->getCodeCompletionTUInfo(),
5476 CodeCompletionContext::CCC_Namespace,
5477 &ResultBuilder::IsNamespaceOrAlias);
5478 Results.EnterNewScope();
5479 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5480 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5481 CodeCompleter->includeGlobals(),
5482 CodeCompleter->loadExternal());
5483 Results.ExitScope();
5484 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5485 Results.data(), Results.size());
5486 }
5487
CodeCompleteNamespaceDecl(Scope * S)5488 void Sema::CodeCompleteNamespaceDecl(Scope *S) {
5489 if (!CodeCompleter)
5490 return;
5491
5492 DeclContext *Ctx = S->getEntity();
5493 if (!S->getParent())
5494 Ctx = Context.getTranslationUnitDecl();
5495
5496 bool SuppressedGlobalResults =
5497 Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
5498
5499 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5500 CodeCompleter->getCodeCompletionTUInfo(),
5501 SuppressedGlobalResults
5502 ? CodeCompletionContext::CCC_Namespace
5503 : CodeCompletionContext::CCC_Other,
5504 &ResultBuilder::IsNamespace);
5505
5506 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
5507 // We only want to see those namespaces that have already been defined
5508 // within this scope, because its likely that the user is creating an
5509 // extended namespace declaration. Keep track of the most recent
5510 // definition of each namespace.
5511 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
5512 for (DeclContext::specific_decl_iterator<NamespaceDecl>
5513 NS(Ctx->decls_begin()),
5514 NSEnd(Ctx->decls_end());
5515 NS != NSEnd; ++NS)
5516 OrigToLatest[NS->getOriginalNamespace()] = *NS;
5517
5518 // Add the most recent definition (or extended definition) of each
5519 // namespace to the list of results.
5520 Results.EnterNewScope();
5521 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
5522 NS = OrigToLatest.begin(),
5523 NSEnd = OrigToLatest.end();
5524 NS != NSEnd; ++NS)
5525 Results.AddResult(
5526 CodeCompletionResult(NS->second, Results.getBasePriority(NS->second),
5527 nullptr),
5528 CurContext, nullptr, false);
5529 Results.ExitScope();
5530 }
5531
5532 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5533 Results.data(), Results.size());
5534 }
5535
CodeCompleteNamespaceAliasDecl(Scope * S)5536 void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
5537 if (!CodeCompleter)
5538 return;
5539
5540 // After "namespace", we expect to see a namespace or alias.
5541 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5542 CodeCompleter->getCodeCompletionTUInfo(),
5543 CodeCompletionContext::CCC_Namespace,
5544 &ResultBuilder::IsNamespaceOrAlias);
5545 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5546 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5547 CodeCompleter->includeGlobals(),
5548 CodeCompleter->loadExternal());
5549 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5550 Results.data(), Results.size());
5551 }
5552
CodeCompleteOperatorName(Scope * S)5553 void Sema::CodeCompleteOperatorName(Scope *S) {
5554 if (!CodeCompleter)
5555 return;
5556
5557 typedef CodeCompletionResult Result;
5558 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5559 CodeCompleter->getCodeCompletionTUInfo(),
5560 CodeCompletionContext::CCC_Type,
5561 &ResultBuilder::IsType);
5562 Results.EnterNewScope();
5563
5564 // Add the names of overloadable operators. Note that OO_Conditional is not
5565 // actually overloadable.
5566 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
5567 if (OO_##Name != OO_Conditional) \
5568 Results.AddResult(Result(Spelling));
5569 #include "clang/Basic/OperatorKinds.def"
5570
5571 // Add any type names visible from the current scope
5572 Results.allowNestedNameSpecifiers();
5573 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5574 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5575 CodeCompleter->includeGlobals(),
5576 CodeCompleter->loadExternal());
5577
5578 // Add any type specifiers
5579 AddTypeSpecifierResults(getLangOpts(), Results);
5580 Results.ExitScope();
5581
5582 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5583 Results.data(), Results.size());
5584 }
5585
CodeCompleteConstructorInitializer(Decl * ConstructorD,ArrayRef<CXXCtorInitializer * > Initializers)5586 void Sema::CodeCompleteConstructorInitializer(
5587 Decl *ConstructorD, ArrayRef<CXXCtorInitializer *> Initializers) {
5588 if (!ConstructorD)
5589 return;
5590
5591 AdjustDeclIfTemplate(ConstructorD);
5592
5593 auto *Constructor = dyn_cast<CXXConstructorDecl>(ConstructorD);
5594 if (!Constructor)
5595 return;
5596
5597 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5598 CodeCompleter->getCodeCompletionTUInfo(),
5599 CodeCompletionContext::CCC_Symbol);
5600 Results.EnterNewScope();
5601
5602 // Fill in any already-initialized fields or base classes.
5603 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
5604 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
5605 for (unsigned I = 0, E = Initializers.size(); I != E; ++I) {
5606 if (Initializers[I]->isBaseInitializer())
5607 InitializedBases.insert(Context.getCanonicalType(
5608 QualType(Initializers[I]->getBaseClass(), 0)));
5609 else
5610 InitializedFields.insert(
5611 cast<FieldDecl>(Initializers[I]->getAnyMember()));
5612 }
5613
5614 // Add completions for base classes.
5615 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
5616 bool SawLastInitializer = Initializers.empty();
5617 CXXRecordDecl *ClassDecl = Constructor->getParent();
5618
5619 auto GenerateCCS = [&](const NamedDecl *ND, const char *Name) {
5620 CodeCompletionBuilder Builder(Results.getAllocator(),
5621 Results.getCodeCompletionTUInfo());
5622 Builder.AddTypedTextChunk(Name);
5623 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5624 if (const auto *Function = dyn_cast<FunctionDecl>(ND))
5625 AddFunctionParameterChunks(PP, Policy, Function, Builder);
5626 else if (const auto *FunTemplDecl = dyn_cast<FunctionTemplateDecl>(ND))
5627 AddFunctionParameterChunks(PP, Policy, FunTemplDecl->getTemplatedDecl(),
5628 Builder);
5629 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5630 return Builder.TakeString();
5631 };
5632 auto AddDefaultCtorInit = [&](const char *Name, const char *Type,
5633 const NamedDecl *ND) {
5634 CodeCompletionBuilder Builder(Results.getAllocator(),
5635 Results.getCodeCompletionTUInfo());
5636 Builder.AddTypedTextChunk(Name);
5637 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5638 Builder.AddPlaceholderChunk(Type);
5639 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5640 if (ND) {
5641 auto CCR = CodeCompletionResult(
5642 Builder.TakeString(), ND,
5643 SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration);
5644 if (isa<FieldDecl>(ND))
5645 CCR.CursorKind = CXCursor_MemberRef;
5646 return Results.AddResult(CCR);
5647 }
5648 return Results.AddResult(CodeCompletionResult(
5649 Builder.TakeString(),
5650 SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration));
5651 };
5652 auto AddCtorsWithName = [&](const CXXRecordDecl *RD, unsigned int Priority,
5653 const char *Name, const FieldDecl *FD) {
5654 if (!RD)
5655 return AddDefaultCtorInit(Name,
5656 FD ? Results.getAllocator().CopyString(
5657 FD->getType().getAsString(Policy))
5658 : Name,
5659 FD);
5660 auto Ctors = getConstructors(Context, RD);
5661 if (Ctors.begin() == Ctors.end())
5662 return AddDefaultCtorInit(Name, Name, RD);
5663 for (const NamedDecl *Ctor : Ctors) {
5664 auto CCR = CodeCompletionResult(GenerateCCS(Ctor, Name), RD, Priority);
5665 CCR.CursorKind = getCursorKindForDecl(Ctor);
5666 Results.AddResult(CCR);
5667 }
5668 };
5669 auto AddBase = [&](const CXXBaseSpecifier &Base) {
5670 const char *BaseName =
5671 Results.getAllocator().CopyString(Base.getType().getAsString(Policy));
5672 const auto *RD = Base.getType()->getAsCXXRecordDecl();
5673 AddCtorsWithName(
5674 RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration,
5675 BaseName, nullptr);
5676 };
5677 auto AddField = [&](const FieldDecl *FD) {
5678 const char *FieldName =
5679 Results.getAllocator().CopyString(FD->getIdentifier()->getName());
5680 const CXXRecordDecl *RD = FD->getType()->getAsCXXRecordDecl();
5681 AddCtorsWithName(
5682 RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration,
5683 FieldName, FD);
5684 };
5685
5686 for (const auto &Base : ClassDecl->bases()) {
5687 if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))
5688 .second) {
5689 SawLastInitializer =
5690 !Initializers.empty() && Initializers.back()->isBaseInitializer() &&
5691 Context.hasSameUnqualifiedType(
5692 Base.getType(), QualType(Initializers.back()->getBaseClass(), 0));
5693 continue;
5694 }
5695
5696 AddBase(Base);
5697 SawLastInitializer = false;
5698 }
5699
5700 // Add completions for virtual base classes.
5701 for (const auto &Base : ClassDecl->vbases()) {
5702 if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))
5703 .second) {
5704 SawLastInitializer =
5705 !Initializers.empty() && Initializers.back()->isBaseInitializer() &&
5706 Context.hasSameUnqualifiedType(
5707 Base.getType(), QualType(Initializers.back()->getBaseClass(), 0));
5708 continue;
5709 }
5710
5711 AddBase(Base);
5712 SawLastInitializer = false;
5713 }
5714
5715 // Add completions for members.
5716 for (auto *Field : ClassDecl->fields()) {
5717 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))
5718 .second) {
5719 SawLastInitializer = !Initializers.empty() &&
5720 Initializers.back()->isAnyMemberInitializer() &&
5721 Initializers.back()->getAnyMember() == Field;
5722 continue;
5723 }
5724
5725 if (!Field->getDeclName())
5726 continue;
5727
5728 AddField(Field);
5729 SawLastInitializer = false;
5730 }
5731 Results.ExitScope();
5732
5733 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5734 Results.data(), Results.size());
5735 }
5736
5737 /// Determine whether this scope denotes a namespace.
isNamespaceScope(Scope * S)5738 static bool isNamespaceScope(Scope *S) {
5739 DeclContext *DC = S->getEntity();
5740 if (!DC)
5741 return false;
5742
5743 return DC->isFileContext();
5744 }
5745
CodeCompleteLambdaIntroducer(Scope * S,LambdaIntroducer & Intro,bool AfterAmpersand)5746 void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
5747 bool AfterAmpersand) {
5748 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5749 CodeCompleter->getCodeCompletionTUInfo(),
5750 CodeCompletionContext::CCC_Other);
5751 Results.EnterNewScope();
5752
5753 // Note what has already been captured.
5754 llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
5755 bool IncludedThis = false;
5756 for (const auto &C : Intro.Captures) {
5757 if (C.Kind == LCK_This) {
5758 IncludedThis = true;
5759 continue;
5760 }
5761
5762 Known.insert(C.Id);
5763 }
5764
5765 // Look for other capturable variables.
5766 for (; S && !isNamespaceScope(S); S = S->getParent()) {
5767 for (const auto *D : S->decls()) {
5768 const auto *Var = dyn_cast<VarDecl>(D);
5769 if (!Var || !Var->hasLocalStorage() || Var->hasAttr<BlocksAttr>())
5770 continue;
5771
5772 if (Known.insert(Var->getIdentifier()).second)
5773 Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),
5774 CurContext, nullptr, false);
5775 }
5776 }
5777
5778 // Add 'this', if it would be valid.
5779 if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
5780 addThisCompletion(*this, Results);
5781
5782 Results.ExitScope();
5783
5784 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5785 Results.data(), Results.size());
5786 }
5787
5788 /// Macro that optionally prepends an "@" to the string literal passed in via
5789 /// Keyword, depending on whether NeedAt is true or false.
5790 #define OBJC_AT_KEYWORD_NAME(NeedAt, Keyword) ((NeedAt) ? "@" Keyword : Keyword)
5791
AddObjCImplementationResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)5792 static void AddObjCImplementationResults(const LangOptions &LangOpts,
5793 ResultBuilder &Results, bool NeedAt) {
5794 typedef CodeCompletionResult Result;
5795 // Since we have an implementation, we can end it.
5796 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end")));
5797
5798 CodeCompletionBuilder Builder(Results.getAllocator(),
5799 Results.getCodeCompletionTUInfo());
5800 if (LangOpts.ObjC) {
5801 // @dynamic
5802 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "dynamic"));
5803 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5804 Builder.AddPlaceholderChunk("property");
5805 Results.AddResult(Result(Builder.TakeString()));
5806
5807 // @synthesize
5808 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synthesize"));
5809 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5810 Builder.AddPlaceholderChunk("property");
5811 Results.AddResult(Result(Builder.TakeString()));
5812 }
5813 }
5814
AddObjCInterfaceResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)5815 static void AddObjCInterfaceResults(const LangOptions &LangOpts,
5816 ResultBuilder &Results, bool NeedAt) {
5817 typedef CodeCompletionResult Result;
5818
5819 // Since we have an interface or protocol, we can end it.
5820 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end")));
5821
5822 if (LangOpts.ObjC) {
5823 // @property
5824 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "property")));
5825
5826 // @required
5827 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "required")));
5828
5829 // @optional
5830 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "optional")));
5831 }
5832 }
5833
AddObjCTopLevelResults(ResultBuilder & Results,bool NeedAt)5834 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
5835 typedef CodeCompletionResult Result;
5836 CodeCompletionBuilder Builder(Results.getAllocator(),
5837 Results.getCodeCompletionTUInfo());
5838
5839 // @class name ;
5840 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "class"));
5841 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5842 Builder.AddPlaceholderChunk("name");
5843 Results.AddResult(Result(Builder.TakeString()));
5844
5845 if (Results.includeCodePatterns()) {
5846 // @interface name
5847 // FIXME: Could introduce the whole pattern, including superclasses and
5848 // such.
5849 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "interface"));
5850 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5851 Builder.AddPlaceholderChunk("class");
5852 Results.AddResult(Result(Builder.TakeString()));
5853
5854 // @protocol name
5855 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol"));
5856 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5857 Builder.AddPlaceholderChunk("protocol");
5858 Results.AddResult(Result(Builder.TakeString()));
5859
5860 // @implementation name
5861 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "implementation"));
5862 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5863 Builder.AddPlaceholderChunk("class");
5864 Results.AddResult(Result(Builder.TakeString()));
5865 }
5866
5867 // @compatibility_alias name
5868 Builder.AddTypedTextChunk(
5869 OBJC_AT_KEYWORD_NAME(NeedAt, "compatibility_alias"));
5870 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5871 Builder.AddPlaceholderChunk("alias");
5872 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5873 Builder.AddPlaceholderChunk("class");
5874 Results.AddResult(Result(Builder.TakeString()));
5875
5876 if (Results.getSema().getLangOpts().Modules) {
5877 // @import name
5878 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "import"));
5879 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5880 Builder.AddPlaceholderChunk("module");
5881 Results.AddResult(Result(Builder.TakeString()));
5882 }
5883 }
5884
CodeCompleteObjCAtDirective(Scope * S)5885 void Sema::CodeCompleteObjCAtDirective(Scope *S) {
5886 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5887 CodeCompleter->getCodeCompletionTUInfo(),
5888 CodeCompletionContext::CCC_Other);
5889 Results.EnterNewScope();
5890 if (isa<ObjCImplDecl>(CurContext))
5891 AddObjCImplementationResults(getLangOpts(), Results, false);
5892 else if (CurContext->isObjCContainer())
5893 AddObjCInterfaceResults(getLangOpts(), Results, false);
5894 else
5895 AddObjCTopLevelResults(Results, false);
5896 Results.ExitScope();
5897 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5898 Results.data(), Results.size());
5899 }
5900
AddObjCExpressionResults(ResultBuilder & Results,bool NeedAt)5901 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
5902 typedef CodeCompletionResult Result;
5903 CodeCompletionBuilder Builder(Results.getAllocator(),
5904 Results.getCodeCompletionTUInfo());
5905
5906 // @encode ( type-name )
5907 const char *EncodeType = "char[]";
5908 if (Results.getSema().getLangOpts().CPlusPlus ||
5909 Results.getSema().getLangOpts().ConstStrings)
5910 EncodeType = "const char[]";
5911 Builder.AddResultTypeChunk(EncodeType);
5912 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "encode"));
5913 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5914 Builder.AddPlaceholderChunk("type-name");
5915 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5916 Results.AddResult(Result(Builder.TakeString()));
5917
5918 // @protocol ( protocol-name )
5919 Builder.AddResultTypeChunk("Protocol *");
5920 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol"));
5921 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5922 Builder.AddPlaceholderChunk("protocol-name");
5923 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5924 Results.AddResult(Result(Builder.TakeString()));
5925
5926 // @selector ( selector )
5927 Builder.AddResultTypeChunk("SEL");
5928 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "selector"));
5929 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5930 Builder.AddPlaceholderChunk("selector");
5931 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5932 Results.AddResult(Result(Builder.TakeString()));
5933
5934 // @"string"
5935 Builder.AddResultTypeChunk("NSString *");
5936 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "\""));
5937 Builder.AddPlaceholderChunk("string");
5938 Builder.AddTextChunk("\"");
5939 Results.AddResult(Result(Builder.TakeString()));
5940
5941 // @[objects, ...]
5942 Builder.AddResultTypeChunk("NSArray *");
5943 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "["));
5944 Builder.AddPlaceholderChunk("objects, ...");
5945 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
5946 Results.AddResult(Result(Builder.TakeString()));
5947
5948 // @{key : object, ...}
5949 Builder.AddResultTypeChunk("NSDictionary *");
5950 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "{"));
5951 Builder.AddPlaceholderChunk("key");
5952 Builder.AddChunk(CodeCompletionString::CK_Colon);
5953 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5954 Builder.AddPlaceholderChunk("object, ...");
5955 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
5956 Results.AddResult(Result(Builder.TakeString()));
5957
5958 // @(expression)
5959 Builder.AddResultTypeChunk("id");
5960 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "("));
5961 Builder.AddPlaceholderChunk("expression");
5962 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5963 Results.AddResult(Result(Builder.TakeString()));
5964 }
5965
AddObjCStatementResults(ResultBuilder & Results,bool NeedAt)5966 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
5967 typedef CodeCompletionResult Result;
5968 CodeCompletionBuilder Builder(Results.getAllocator(),
5969 Results.getCodeCompletionTUInfo());
5970
5971 if (Results.includeCodePatterns()) {
5972 // @try { statements } @catch ( declaration ) { statements } @finally
5973 // { statements }
5974 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "try"));
5975 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
5976 Builder.AddPlaceholderChunk("statements");
5977 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
5978 Builder.AddTextChunk("@catch");
5979 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5980 Builder.AddPlaceholderChunk("parameter");
5981 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5982 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
5983 Builder.AddPlaceholderChunk("statements");
5984 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
5985 Builder.AddTextChunk("@finally");
5986 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
5987 Builder.AddPlaceholderChunk("statements");
5988 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
5989 Results.AddResult(Result(Builder.TakeString()));
5990 }
5991
5992 // @throw
5993 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "throw"));
5994 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5995 Builder.AddPlaceholderChunk("expression");
5996 Results.AddResult(Result(Builder.TakeString()));
5997
5998 if (Results.includeCodePatterns()) {
5999 // @synchronized ( expression ) { statements }
6000 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synchronized"));
6001 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6002 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6003 Builder.AddPlaceholderChunk("expression");
6004 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6005 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
6006 Builder.AddPlaceholderChunk("statements");
6007 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
6008 Results.AddResult(Result(Builder.TakeString()));
6009 }
6010 }
6011
AddObjCVisibilityResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)6012 static void AddObjCVisibilityResults(const LangOptions &LangOpts,
6013 ResultBuilder &Results, bool NeedAt) {
6014 typedef CodeCompletionResult Result;
6015 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "private")));
6016 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "protected")));
6017 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "public")));
6018 if (LangOpts.ObjC)
6019 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "package")));
6020 }
6021
CodeCompleteObjCAtVisibility(Scope * S)6022 void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
6023 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6024 CodeCompleter->getCodeCompletionTUInfo(),
6025 CodeCompletionContext::CCC_Other);
6026 Results.EnterNewScope();
6027 AddObjCVisibilityResults(getLangOpts(), Results, false);
6028 Results.ExitScope();
6029 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6030 Results.data(), Results.size());
6031 }
6032
CodeCompleteObjCAtStatement(Scope * S)6033 void Sema::CodeCompleteObjCAtStatement(Scope *S) {
6034 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6035 CodeCompleter->getCodeCompletionTUInfo(),
6036 CodeCompletionContext::CCC_Other);
6037 Results.EnterNewScope();
6038 AddObjCStatementResults(Results, false);
6039 AddObjCExpressionResults(Results, false);
6040 Results.ExitScope();
6041 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6042 Results.data(), Results.size());
6043 }
6044
CodeCompleteObjCAtExpression(Scope * S)6045 void Sema::CodeCompleteObjCAtExpression(Scope *S) {
6046 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6047 CodeCompleter->getCodeCompletionTUInfo(),
6048 CodeCompletionContext::CCC_Other);
6049 Results.EnterNewScope();
6050 AddObjCExpressionResults(Results, false);
6051 Results.ExitScope();
6052 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6053 Results.data(), Results.size());
6054 }
6055
6056 /// Determine whether the addition of the given flag to an Objective-C
6057 /// property's attributes will cause a conflict.
ObjCPropertyFlagConflicts(unsigned Attributes,unsigned NewFlag)6058 static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
6059 // Check if we've already added this flag.
6060 if (Attributes & NewFlag)
6061 return true;
6062
6063 Attributes |= NewFlag;
6064
6065 // Check for collisions with "readonly".
6066 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
6067 (Attributes & ObjCDeclSpec::DQ_PR_readwrite))
6068 return true;
6069
6070 // Check for more than one of { assign, copy, retain, strong, weak }.
6071 unsigned AssignCopyRetMask =
6072 Attributes &
6073 (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_unsafe_unretained |
6074 ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain |
6075 ObjCDeclSpec::DQ_PR_strong | ObjCDeclSpec::DQ_PR_weak);
6076 if (AssignCopyRetMask && AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
6077 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained &&
6078 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
6079 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain &&
6080 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong &&
6081 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_weak)
6082 return true;
6083
6084 return false;
6085 }
6086
CodeCompleteObjCPropertyFlags(Scope * S,ObjCDeclSpec & ODS)6087 void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
6088 if (!CodeCompleter)
6089 return;
6090
6091 unsigned Attributes = ODS.getPropertyAttributes();
6092
6093 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6094 CodeCompleter->getCodeCompletionTUInfo(),
6095 CodeCompletionContext::CCC_Other);
6096 Results.EnterNewScope();
6097 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
6098 Results.AddResult(CodeCompletionResult("readonly"));
6099 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
6100 Results.AddResult(CodeCompletionResult("assign"));
6101 if (!ObjCPropertyFlagConflicts(Attributes,
6102 ObjCDeclSpec::DQ_PR_unsafe_unretained))
6103 Results.AddResult(CodeCompletionResult("unsafe_unretained"));
6104 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
6105 Results.AddResult(CodeCompletionResult("readwrite"));
6106 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
6107 Results.AddResult(CodeCompletionResult("retain"));
6108 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_strong))
6109 Results.AddResult(CodeCompletionResult("strong"));
6110 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
6111 Results.AddResult(CodeCompletionResult("copy"));
6112 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
6113 Results.AddResult(CodeCompletionResult("nonatomic"));
6114 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
6115 Results.AddResult(CodeCompletionResult("atomic"));
6116
6117 // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
6118 if (getLangOpts().ObjCWeak || getLangOpts().getGC() != LangOptions::NonGC)
6119 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak))
6120 Results.AddResult(CodeCompletionResult("weak"));
6121
6122 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
6123 CodeCompletionBuilder Setter(Results.getAllocator(),
6124 Results.getCodeCompletionTUInfo());
6125 Setter.AddTypedTextChunk("setter");
6126 Setter.AddTextChunk("=");
6127 Setter.AddPlaceholderChunk("method");
6128 Results.AddResult(CodeCompletionResult(Setter.TakeString()));
6129 }
6130 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
6131 CodeCompletionBuilder Getter(Results.getAllocator(),
6132 Results.getCodeCompletionTUInfo());
6133 Getter.AddTypedTextChunk("getter");
6134 Getter.AddTextChunk("=");
6135 Getter.AddPlaceholderChunk("method");
6136 Results.AddResult(CodeCompletionResult(Getter.TakeString()));
6137 }
6138 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nullability)) {
6139 Results.AddResult(CodeCompletionResult("nonnull"));
6140 Results.AddResult(CodeCompletionResult("nullable"));
6141 Results.AddResult(CodeCompletionResult("null_unspecified"));
6142 Results.AddResult(CodeCompletionResult("null_resettable"));
6143 }
6144 Results.ExitScope();
6145 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6146 Results.data(), Results.size());
6147 }
6148
6149 /// Describes the kind of Objective-C method that we want to find
6150 /// via code completion.
6151 enum ObjCMethodKind {
6152 MK_Any, ///< Any kind of method, provided it means other specified criteria.
6153 MK_ZeroArgSelector, ///< Zero-argument (unary) selector.
6154 MK_OneArgSelector ///< One-argument selector.
6155 };
6156
isAcceptableObjCSelector(Selector Sel,ObjCMethodKind WantKind,ArrayRef<IdentifierInfo * > SelIdents,bool AllowSameLength=true)6157 static bool isAcceptableObjCSelector(Selector Sel, ObjCMethodKind WantKind,
6158 ArrayRef<IdentifierInfo *> SelIdents,
6159 bool AllowSameLength = true) {
6160 unsigned NumSelIdents = SelIdents.size();
6161 if (NumSelIdents > Sel.getNumArgs())
6162 return false;
6163
6164 switch (WantKind) {
6165 case MK_Any:
6166 break;
6167 case MK_ZeroArgSelector:
6168 return Sel.isUnarySelector();
6169 case MK_OneArgSelector:
6170 return Sel.getNumArgs() == 1;
6171 }
6172
6173 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
6174 return false;
6175
6176 for (unsigned I = 0; I != NumSelIdents; ++I)
6177 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
6178 return false;
6179
6180 return true;
6181 }
6182
isAcceptableObjCMethod(ObjCMethodDecl * Method,ObjCMethodKind WantKind,ArrayRef<IdentifierInfo * > SelIdents,bool AllowSameLength=true)6183 static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
6184 ObjCMethodKind WantKind,
6185 ArrayRef<IdentifierInfo *> SelIdents,
6186 bool AllowSameLength = true) {
6187 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
6188 AllowSameLength);
6189 }
6190
6191 /// A set of selectors, which is used to avoid introducing multiple
6192 /// completions with the same selector into the result set.
6193 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
6194
6195 /// Add all of the Objective-C methods in the given Objective-C
6196 /// container to the set of results.
6197 ///
6198 /// The container will be a class, protocol, category, or implementation of
6199 /// any of the above. This mether will recurse to include methods from
6200 /// the superclasses of classes along with their categories, protocols, and
6201 /// implementations.
6202 ///
6203 /// \param Container the container in which we'll look to find methods.
6204 ///
6205 /// \param WantInstanceMethods Whether to add instance methods (only); if
6206 /// false, this routine will add factory methods (only).
6207 ///
6208 /// \param CurContext the context in which we're performing the lookup that
6209 /// finds methods.
6210 ///
6211 /// \param AllowSameLength Whether we allow a method to be added to the list
6212 /// when it has the same number of parameters as we have selector identifiers.
6213 ///
6214 /// \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,bool IsRootClass=false)6215 static void AddObjCMethods(ObjCContainerDecl *Container,
6216 bool WantInstanceMethods, ObjCMethodKind WantKind,
6217 ArrayRef<IdentifierInfo *> SelIdents,
6218 DeclContext *CurContext,
6219 VisitedSelectorSet &Selectors, bool AllowSameLength,
6220 ResultBuilder &Results, bool InOriginalClass = true,
6221 bool IsRootClass = false) {
6222 typedef CodeCompletionResult Result;
6223 Container = getContainerDef(Container);
6224 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
6225 IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass());
6226 for (ObjCMethodDecl *M : Container->methods()) {
6227 // The instance methods on the root class can be messaged via the
6228 // metaclass.
6229 if (M->isInstanceMethod() == WantInstanceMethods ||
6230 (IsRootClass && !WantInstanceMethods)) {
6231 // Check whether the selector identifiers we've been given are a
6232 // subset of the identifiers for this particular method.
6233 if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))
6234 continue;
6235
6236 if (!Selectors.insert(M->getSelector()).second)
6237 continue;
6238
6239 Result R = Result(M, Results.getBasePriority(M), nullptr);
6240 R.StartParameter = SelIdents.size();
6241 R.AllParametersAreInformative = (WantKind != MK_Any);
6242 if (!InOriginalClass)
6243 setInBaseClass(R);
6244 Results.MaybeAddResult(R, CurContext);
6245 }
6246 }
6247
6248 // Visit the protocols of protocols.
6249 if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
6250 if (Protocol->hasDefinition()) {
6251 const ObjCList<ObjCProtocolDecl> &Protocols =
6252 Protocol->getReferencedProtocols();
6253 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6254 E = Protocols.end();
6255 I != E; ++I)
6256 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
6257 Selectors, AllowSameLength, Results, false, IsRootClass);
6258 }
6259 }
6260
6261 if (!IFace || !IFace->hasDefinition())
6262 return;
6263
6264 // Add methods in protocols.
6265 for (ObjCProtocolDecl *I : IFace->protocols())
6266 AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, CurContext,
6267 Selectors, AllowSameLength, Results, false, IsRootClass);
6268
6269 // Add methods in categories.
6270 for (ObjCCategoryDecl *CatDecl : IFace->known_categories()) {
6271 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
6272 CurContext, Selectors, AllowSameLength, Results,
6273 InOriginalClass, IsRootClass);
6274
6275 // Add a categories protocol methods.
6276 const ObjCList<ObjCProtocolDecl> &Protocols =
6277 CatDecl->getReferencedProtocols();
6278 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6279 E = Protocols.end();
6280 I != E; ++I)
6281 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
6282 Selectors, AllowSameLength, Results, false, IsRootClass);
6283
6284 // Add methods in category implementations.
6285 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
6286 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
6287 Selectors, AllowSameLength, Results, InOriginalClass,
6288 IsRootClass);
6289 }
6290
6291 // Add methods in superclass.
6292 // Avoid passing in IsRootClass since root classes won't have super classes.
6293 if (IFace->getSuperClass())
6294 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
6295 SelIdents, CurContext, Selectors, AllowSameLength, Results,
6296 /*IsRootClass=*/false);
6297
6298 // Add methods in our implementation, if any.
6299 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6300 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
6301 Selectors, AllowSameLength, Results, InOriginalClass,
6302 IsRootClass);
6303 }
6304
CodeCompleteObjCPropertyGetter(Scope * S)6305 void Sema::CodeCompleteObjCPropertyGetter(Scope *S) {
6306 // Try to find the interface where getters might live.
6307 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
6308 if (!Class) {
6309 if (ObjCCategoryDecl *Category =
6310 dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
6311 Class = Category->getClassInterface();
6312
6313 if (!Class)
6314 return;
6315 }
6316
6317 // Find all of the potential getters.
6318 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6319 CodeCompleter->getCodeCompletionTUInfo(),
6320 CodeCompletionContext::CCC_Other);
6321 Results.EnterNewScope();
6322
6323 VisitedSelectorSet Selectors;
6324 AddObjCMethods(Class, true, MK_ZeroArgSelector, None, CurContext, Selectors,
6325 /*AllowSameLength=*/true, Results);
6326 Results.ExitScope();
6327 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6328 Results.data(), Results.size());
6329 }
6330
CodeCompleteObjCPropertySetter(Scope * S)6331 void Sema::CodeCompleteObjCPropertySetter(Scope *S) {
6332 // Try to find the interface where setters might live.
6333 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
6334 if (!Class) {
6335 if (ObjCCategoryDecl *Category =
6336 dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
6337 Class = Category->getClassInterface();
6338
6339 if (!Class)
6340 return;
6341 }
6342
6343 // Find all of the potential getters.
6344 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6345 CodeCompleter->getCodeCompletionTUInfo(),
6346 CodeCompletionContext::CCC_Other);
6347 Results.EnterNewScope();
6348
6349 VisitedSelectorSet Selectors;
6350 AddObjCMethods(Class, true, MK_OneArgSelector, None, CurContext, Selectors,
6351 /*AllowSameLength=*/true, Results);
6352
6353 Results.ExitScope();
6354 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6355 Results.data(), Results.size());
6356 }
6357
CodeCompleteObjCPassingType(Scope * S,ObjCDeclSpec & DS,bool IsParameter)6358 void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
6359 bool IsParameter) {
6360 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6361 CodeCompleter->getCodeCompletionTUInfo(),
6362 CodeCompletionContext::CCC_Type);
6363 Results.EnterNewScope();
6364
6365 // Add context-sensitive, Objective-C parameter-passing keywords.
6366 bool AddedInOut = false;
6367 if ((DS.getObjCDeclQualifier() &
6368 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
6369 Results.AddResult("in");
6370 Results.AddResult("inout");
6371 AddedInOut = true;
6372 }
6373 if ((DS.getObjCDeclQualifier() &
6374 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
6375 Results.AddResult("out");
6376 if (!AddedInOut)
6377 Results.AddResult("inout");
6378 }
6379 if ((DS.getObjCDeclQualifier() &
6380 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
6381 ObjCDeclSpec::DQ_Oneway)) == 0) {
6382 Results.AddResult("bycopy");
6383 Results.AddResult("byref");
6384 Results.AddResult("oneway");
6385 }
6386 if ((DS.getObjCDeclQualifier() & ObjCDeclSpec::DQ_CSNullability) == 0) {
6387 Results.AddResult("nonnull");
6388 Results.AddResult("nullable");
6389 Results.AddResult("null_unspecified");
6390 }
6391
6392 // If we're completing the return type of an Objective-C method and the
6393 // identifier IBAction refers to a macro, provide a completion item for
6394 // an action, e.g.,
6395 // IBAction)<#selector#>:(id)sender
6396 if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
6397 PP.isMacroDefined("IBAction")) {
6398 CodeCompletionBuilder Builder(Results.getAllocator(),
6399 Results.getCodeCompletionTUInfo(),
6400 CCP_CodePattern, CXAvailability_Available);
6401 Builder.AddTypedTextChunk("IBAction");
6402 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6403 Builder.AddPlaceholderChunk("selector");
6404 Builder.AddChunk(CodeCompletionString::CK_Colon);
6405 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6406 Builder.AddTextChunk("id");
6407 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6408 Builder.AddTextChunk("sender");
6409 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
6410 }
6411
6412 // If we're completing the return type, provide 'instancetype'.
6413 if (!IsParameter) {
6414 Results.AddResult(CodeCompletionResult("instancetype"));
6415 }
6416
6417 // Add various builtin type names and specifiers.
6418 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
6419 Results.ExitScope();
6420
6421 // Add the various type names
6422 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
6423 CodeCompletionDeclConsumer Consumer(Results, CurContext);
6424 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
6425 CodeCompleter->includeGlobals(),
6426 CodeCompleter->loadExternal());
6427
6428 if (CodeCompleter->includeMacros())
6429 AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false);
6430
6431 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6432 Results.data(), Results.size());
6433 }
6434
6435 /// When we have an expression with type "id", we may assume
6436 /// that it has some more-specific class type based on knowledge of
6437 /// common uses of Objective-C. This routine returns that class type,
6438 /// or NULL if no better result could be determined.
GetAssumedMessageSendExprType(Expr * E)6439 static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
6440 auto *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
6441 if (!Msg)
6442 return nullptr;
6443
6444 Selector Sel = Msg->getSelector();
6445 if (Sel.isNull())
6446 return nullptr;
6447
6448 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
6449 if (!Id)
6450 return nullptr;
6451
6452 ObjCMethodDecl *Method = Msg->getMethodDecl();
6453 if (!Method)
6454 return nullptr;
6455
6456 // Determine the class that we're sending the message to.
6457 ObjCInterfaceDecl *IFace = nullptr;
6458 switch (Msg->getReceiverKind()) {
6459 case ObjCMessageExpr::Class:
6460 if (const ObjCObjectType *ObjType =
6461 Msg->getClassReceiver()->getAs<ObjCObjectType>())
6462 IFace = ObjType->getInterface();
6463 break;
6464
6465 case ObjCMessageExpr::Instance: {
6466 QualType T = Msg->getInstanceReceiver()->getType();
6467 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
6468 IFace = Ptr->getInterfaceDecl();
6469 break;
6470 }
6471
6472 case ObjCMessageExpr::SuperInstance:
6473 case ObjCMessageExpr::SuperClass:
6474 break;
6475 }
6476
6477 if (!IFace)
6478 return nullptr;
6479
6480 ObjCInterfaceDecl *Super = IFace->getSuperClass();
6481 if (Method->isInstanceMethod())
6482 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
6483 .Case("retain", IFace)
6484 .Case("strong", IFace)
6485 .Case("autorelease", IFace)
6486 .Case("copy", IFace)
6487 .Case("copyWithZone", IFace)
6488 .Case("mutableCopy", IFace)
6489 .Case("mutableCopyWithZone", IFace)
6490 .Case("awakeFromCoder", IFace)
6491 .Case("replacementObjectFromCoder", IFace)
6492 .Case("class", IFace)
6493 .Case("classForCoder", IFace)
6494 .Case("superclass", Super)
6495 .Default(nullptr);
6496
6497 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
6498 .Case("new", IFace)
6499 .Case("alloc", IFace)
6500 .Case("allocWithZone", IFace)
6501 .Case("class", IFace)
6502 .Case("superclass", Super)
6503 .Default(nullptr);
6504 }
6505
6506 // Add a special completion for a message send to "super", which fills in the
6507 // most likely case of forwarding all of our arguments to the superclass
6508 // function.
6509 ///
6510 /// \param S The semantic analysis object.
6511 ///
6512 /// \param NeedSuperKeyword Whether we need to prefix this completion with
6513 /// the "super" keyword. Otherwise, we just need to provide the arguments.
6514 ///
6515 /// \param SelIdents The identifiers in the selector that have already been
6516 /// provided as arguments for a send to "super".
6517 ///
6518 /// \param Results The set of results to augment.
6519 ///
6520 /// \returns the Objective-C method declaration that would be invoked by
6521 /// this "super" completion. If NULL, no completion was added.
6522 static ObjCMethodDecl *
AddSuperSendCompletion(Sema & S,bool NeedSuperKeyword,ArrayRef<IdentifierInfo * > SelIdents,ResultBuilder & Results)6523 AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
6524 ArrayRef<IdentifierInfo *> SelIdents,
6525 ResultBuilder &Results) {
6526 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
6527 if (!CurMethod)
6528 return nullptr;
6529
6530 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
6531 if (!Class)
6532 return nullptr;
6533
6534 // Try to find a superclass method with the same selector.
6535 ObjCMethodDecl *SuperMethod = nullptr;
6536 while ((Class = Class->getSuperClass()) && !SuperMethod) {
6537 // Check in the class
6538 SuperMethod = Class->getMethod(CurMethod->getSelector(),
6539 CurMethod->isInstanceMethod());
6540
6541 // Check in categories or class extensions.
6542 if (!SuperMethod) {
6543 for (const auto *Cat : Class->known_categories()) {
6544 if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(),
6545 CurMethod->isInstanceMethod())))
6546 break;
6547 }
6548 }
6549 }
6550
6551 if (!SuperMethod)
6552 return nullptr;
6553
6554 // Check whether the superclass method has the same signature.
6555 if (CurMethod->param_size() != SuperMethod->param_size() ||
6556 CurMethod->isVariadic() != SuperMethod->isVariadic())
6557 return nullptr;
6558
6559 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
6560 CurPEnd = CurMethod->param_end(),
6561 SuperP = SuperMethod->param_begin();
6562 CurP != CurPEnd; ++CurP, ++SuperP) {
6563 // Make sure the parameter types are compatible.
6564 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
6565 (*SuperP)->getType()))
6566 return nullptr;
6567
6568 // Make sure we have a parameter name to forward!
6569 if (!(*CurP)->getIdentifier())
6570 return nullptr;
6571 }
6572
6573 // We have a superclass method. Now, form the send-to-super completion.
6574 CodeCompletionBuilder Builder(Results.getAllocator(),
6575 Results.getCodeCompletionTUInfo());
6576
6577 // Give this completion a return type.
6578 AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod,
6579 Results.getCompletionContext().getBaseType(), Builder);
6580
6581 // If we need the "super" keyword, add it (plus some spacing).
6582 if (NeedSuperKeyword) {
6583 Builder.AddTypedTextChunk("super");
6584 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6585 }
6586
6587 Selector Sel = CurMethod->getSelector();
6588 if (Sel.isUnarySelector()) {
6589 if (NeedSuperKeyword)
6590 Builder.AddTextChunk(
6591 Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
6592 else
6593 Builder.AddTypedTextChunk(
6594 Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
6595 } else {
6596 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
6597 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
6598 if (I > SelIdents.size())
6599 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6600
6601 if (I < SelIdents.size())
6602 Builder.AddInformativeChunk(
6603 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
6604 else if (NeedSuperKeyword || I > SelIdents.size()) {
6605 Builder.AddTextChunk(
6606 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
6607 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
6608 (*CurP)->getIdentifier()->getName()));
6609 } else {
6610 Builder.AddTypedTextChunk(
6611 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
6612 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
6613 (*CurP)->getIdentifier()->getName()));
6614 }
6615 }
6616 }
6617
6618 Results.AddResult(CodeCompletionResult(Builder.TakeString(), SuperMethod,
6619 CCP_SuperCompletion));
6620 return SuperMethod;
6621 }
6622
CodeCompleteObjCMessageReceiver(Scope * S)6623 void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
6624 typedef CodeCompletionResult Result;
6625 ResultBuilder Results(
6626 *this, CodeCompleter->getAllocator(),
6627 CodeCompleter->getCodeCompletionTUInfo(),
6628 CodeCompletionContext::CCC_ObjCMessageReceiver,
6629 getLangOpts().CPlusPlus11
6630 ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
6631 : &ResultBuilder::IsObjCMessageReceiver);
6632
6633 CodeCompletionDeclConsumer Consumer(Results, CurContext);
6634 Results.EnterNewScope();
6635 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
6636 CodeCompleter->includeGlobals(),
6637 CodeCompleter->loadExternal());
6638
6639 // If we are in an Objective-C method inside a class that has a superclass,
6640 // add "super" as an option.
6641 if (ObjCMethodDecl *Method = getCurMethodDecl())
6642 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
6643 if (Iface->getSuperClass()) {
6644 Results.AddResult(Result("super"));
6645
6646 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, None, Results);
6647 }
6648
6649 if (getLangOpts().CPlusPlus11)
6650 addThisCompletion(*this, Results);
6651
6652 Results.ExitScope();
6653
6654 if (CodeCompleter->includeMacros())
6655 AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false);
6656 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6657 Results.data(), Results.size());
6658 }
6659
CodeCompleteObjCSuperMessage(Scope * S,SourceLocation SuperLoc,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression)6660 void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
6661 ArrayRef<IdentifierInfo *> SelIdents,
6662 bool AtArgumentExpression) {
6663 ObjCInterfaceDecl *CDecl = nullptr;
6664 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
6665 // Figure out which interface we're in.
6666 CDecl = CurMethod->getClassInterface();
6667 if (!CDecl)
6668 return;
6669
6670 // Find the superclass of this class.
6671 CDecl = CDecl->getSuperClass();
6672 if (!CDecl)
6673 return;
6674
6675 if (CurMethod->isInstanceMethod()) {
6676 // We are inside an instance method, which means that the message
6677 // send [super ...] is actually calling an instance method on the
6678 // current object.
6679 return CodeCompleteObjCInstanceMessage(S, nullptr, SelIdents,
6680 AtArgumentExpression, CDecl);
6681 }
6682
6683 // Fall through to send to the superclass in CDecl.
6684 } else {
6685 // "super" may be the name of a type or variable. Figure out which
6686 // it is.
6687 IdentifierInfo *Super = getSuperIdentifier();
6688 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc, LookupOrdinaryName);
6689 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
6690 // "super" names an interface. Use it.
6691 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
6692 if (const ObjCObjectType *Iface =
6693 Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
6694 CDecl = Iface->getInterface();
6695 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
6696 // "super" names an unresolved type; we can't be more specific.
6697 } else {
6698 // Assume that "super" names some kind of value and parse that way.
6699 CXXScopeSpec SS;
6700 SourceLocation TemplateKWLoc;
6701 UnqualifiedId id;
6702 id.setIdentifier(Super, SuperLoc);
6703 ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id,
6704 /*HasTrailingLParen=*/false,
6705 /*IsAddressOfOperand=*/false);
6706 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
6707 SelIdents, AtArgumentExpression);
6708 }
6709
6710 // Fall through
6711 }
6712
6713 ParsedType Receiver;
6714 if (CDecl)
6715 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
6716 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
6717 AtArgumentExpression,
6718 /*IsSuper=*/true);
6719 }
6720
6721 /// Given a set of code-completion results for the argument of a message
6722 /// send, determine the preferred type (if any) for that argument expression.
getPreferredArgumentTypeForMessageSend(ResultBuilder & Results,unsigned NumSelIdents)6723 static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
6724 unsigned NumSelIdents) {
6725 typedef CodeCompletionResult Result;
6726 ASTContext &Context = Results.getSema().Context;
6727
6728 QualType PreferredType;
6729 unsigned BestPriority = CCP_Unlikely * 2;
6730 Result *ResultsData = Results.data();
6731 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
6732 Result &R = ResultsData[I];
6733 if (R.Kind == Result::RK_Declaration &&
6734 isa<ObjCMethodDecl>(R.Declaration)) {
6735 if (R.Priority <= BestPriority) {
6736 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
6737 if (NumSelIdents <= Method->param_size()) {
6738 QualType MyPreferredType =
6739 Method->parameters()[NumSelIdents - 1]->getType();
6740 if (R.Priority < BestPriority || PreferredType.isNull()) {
6741 BestPriority = R.Priority;
6742 PreferredType = MyPreferredType;
6743 } else if (!Context.hasSameUnqualifiedType(PreferredType,
6744 MyPreferredType)) {
6745 PreferredType = QualType();
6746 }
6747 }
6748 }
6749 }
6750 }
6751
6752 return PreferredType;
6753 }
6754
AddClassMessageCompletions(Sema & SemaRef,Scope * S,ParsedType Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,bool IsSuper,ResultBuilder & Results)6755 static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
6756 ParsedType Receiver,
6757 ArrayRef<IdentifierInfo *> SelIdents,
6758 bool AtArgumentExpression, bool IsSuper,
6759 ResultBuilder &Results) {
6760 typedef CodeCompletionResult Result;
6761 ObjCInterfaceDecl *CDecl = nullptr;
6762
6763 // If the given name refers to an interface type, retrieve the
6764 // corresponding declaration.
6765 if (Receiver) {
6766 QualType T = SemaRef.GetTypeFromParser(Receiver, nullptr);
6767 if (!T.isNull())
6768 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
6769 CDecl = Interface->getInterface();
6770 }
6771
6772 // Add all of the factory methods in this Objective-C class, its protocols,
6773 // superclasses, categories, implementation, etc.
6774 Results.EnterNewScope();
6775
6776 // If this is a send-to-super, try to add the special "super" send
6777 // completion.
6778 if (IsSuper) {
6779 if (ObjCMethodDecl *SuperMethod =
6780 AddSuperSendCompletion(SemaRef, false, SelIdents, Results))
6781 Results.Ignore(SuperMethod);
6782 }
6783
6784 // If we're inside an Objective-C method definition, prefer its selector to
6785 // others.
6786 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
6787 Results.setPreferredSelector(CurMethod->getSelector());
6788
6789 VisitedSelectorSet Selectors;
6790 if (CDecl)
6791 AddObjCMethods(CDecl, false, MK_Any, SelIdents, SemaRef.CurContext,
6792 Selectors, AtArgumentExpression, Results);
6793 else {
6794 // We're messaging "id" as a type; provide all class/factory methods.
6795
6796 // If we have an external source, load the entire class method
6797 // pool from the AST file.
6798 if (SemaRef.getExternalSource()) {
6799 for (uint32_t I = 0,
6800 N = SemaRef.getExternalSource()->GetNumExternalSelectors();
6801 I != N; ++I) {
6802 Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I);
6803 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
6804 continue;
6805
6806 SemaRef.ReadMethodPool(Sel);
6807 }
6808 }
6809
6810 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
6811 MEnd = SemaRef.MethodPool.end();
6812 M != MEnd; ++M) {
6813 for (ObjCMethodList *MethList = &M->second.second;
6814 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
6815 if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
6816 continue;
6817
6818 Result R(MethList->getMethod(),
6819 Results.getBasePriority(MethList->getMethod()), nullptr);
6820 R.StartParameter = SelIdents.size();
6821 R.AllParametersAreInformative = false;
6822 Results.MaybeAddResult(R, SemaRef.CurContext);
6823 }
6824 }
6825 }
6826
6827 Results.ExitScope();
6828 }
6829
CodeCompleteObjCClassMessage(Scope * S,ParsedType Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,bool IsSuper)6830 void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
6831 ArrayRef<IdentifierInfo *> SelIdents,
6832 bool AtArgumentExpression,
6833 bool IsSuper) {
6834
6835 QualType T = this->GetTypeFromParser(Receiver);
6836
6837 ResultBuilder Results(
6838 *this, CodeCompleter->getAllocator(),
6839 CodeCompleter->getCodeCompletionTUInfo(),
6840 CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage, T,
6841 SelIdents));
6842
6843 AddClassMessageCompletions(*this, S, Receiver, SelIdents,
6844 AtArgumentExpression, IsSuper, Results);
6845
6846 // If we're actually at the argument expression (rather than prior to the
6847 // selector), we're actually performing code completion for an expression.
6848 // Determine whether we have a single, best method. If so, we can
6849 // code-complete the expression using the corresponding parameter type as
6850 // our preferred type, improving completion results.
6851 if (AtArgumentExpression) {
6852 QualType PreferredType =
6853 getPreferredArgumentTypeForMessageSend(Results, SelIdents.size());
6854 if (PreferredType.isNull())
6855 CodeCompleteOrdinaryName(S, PCC_Expression);
6856 else
6857 CodeCompleteExpression(S, PreferredType);
6858 return;
6859 }
6860
6861 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
6862 Results.data(), Results.size());
6863 }
6864
CodeCompleteObjCInstanceMessage(Scope * S,Expr * Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,ObjCInterfaceDecl * Super)6865 void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
6866 ArrayRef<IdentifierInfo *> SelIdents,
6867 bool AtArgumentExpression,
6868 ObjCInterfaceDecl *Super) {
6869 typedef CodeCompletionResult Result;
6870
6871 Expr *RecExpr = static_cast<Expr *>(Receiver);
6872
6873 // If necessary, apply function/array conversion to the receiver.
6874 // C99 6.7.5.3p[7,8].
6875 if (RecExpr) {
6876 ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
6877 if (Conv.isInvalid()) // conversion failed. bail.
6878 return;
6879 RecExpr = Conv.get();
6880 }
6881 QualType ReceiverType = RecExpr
6882 ? RecExpr->getType()
6883 : Super ? Context.getObjCObjectPointerType(
6884 Context.getObjCInterfaceType(Super))
6885 : Context.getObjCIdType();
6886
6887 // If we're messaging an expression with type "id" or "Class", check
6888 // whether we know something special about the receiver that allows
6889 // us to assume a more-specific receiver type.
6890 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) {
6891 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
6892 if (ReceiverType->isObjCClassType())
6893 return CodeCompleteObjCClassMessage(
6894 S, ParsedType::make(Context.getObjCInterfaceType(IFace)), SelIdents,
6895 AtArgumentExpression, Super);
6896
6897 ReceiverType =
6898 Context.getObjCObjectPointerType(Context.getObjCInterfaceType(IFace));
6899 }
6900 } else if (RecExpr && getLangOpts().CPlusPlus) {
6901 ExprResult Conv = PerformContextuallyConvertToObjCPointer(RecExpr);
6902 if (Conv.isUsable()) {
6903 RecExpr = Conv.get();
6904 ReceiverType = RecExpr->getType();
6905 }
6906 }
6907
6908 // Build the set of methods we can see.
6909 ResultBuilder Results(
6910 *this, CodeCompleter->getAllocator(),
6911 CodeCompleter->getCodeCompletionTUInfo(),
6912 CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
6913 ReceiverType, SelIdents));
6914
6915 Results.EnterNewScope();
6916
6917 // If this is a send-to-super, try to add the special "super" send
6918 // completion.
6919 if (Super) {
6920 if (ObjCMethodDecl *SuperMethod =
6921 AddSuperSendCompletion(*this, false, SelIdents, Results))
6922 Results.Ignore(SuperMethod);
6923 }
6924
6925 // If we're inside an Objective-C method definition, prefer its selector to
6926 // others.
6927 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
6928 Results.setPreferredSelector(CurMethod->getSelector());
6929
6930 // Keep track of the selectors we've already added.
6931 VisitedSelectorSet Selectors;
6932
6933 // Handle messages to Class. This really isn't a message to an instance
6934 // method, so we treat it the same way we would treat a message send to a
6935 // class method.
6936 if (ReceiverType->isObjCClassType() ||
6937 ReceiverType->isObjCQualifiedClassType()) {
6938 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
6939 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
6940 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, CurContext,
6941 Selectors, AtArgumentExpression, Results);
6942 }
6943 }
6944 // Handle messages to a qualified ID ("id<foo>").
6945 else if (const ObjCObjectPointerType *QualID =
6946 ReceiverType->getAsObjCQualifiedIdType()) {
6947 // Search protocols for instance methods.
6948 for (auto *I : QualID->quals())
6949 AddObjCMethods(I, true, MK_Any, SelIdents, CurContext, Selectors,
6950 AtArgumentExpression, Results);
6951 }
6952 // Handle messages to a pointer to interface type.
6953 else if (const ObjCObjectPointerType *IFacePtr =
6954 ReceiverType->getAsObjCInterfacePointerType()) {
6955 // Search the class, its superclasses, etc., for instance methods.
6956 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
6957 CurContext, Selectors, AtArgumentExpression, Results);
6958
6959 // Search protocols for instance methods.
6960 for (auto *I : IFacePtr->quals())
6961 AddObjCMethods(I, true, MK_Any, SelIdents, CurContext, Selectors,
6962 AtArgumentExpression, Results);
6963 }
6964 // Handle messages to "id".
6965 else if (ReceiverType->isObjCIdType()) {
6966 // We're messaging "id", so provide all instance methods we know
6967 // about as code-completion results.
6968
6969 // If we have an external source, load the entire class method
6970 // pool from the AST file.
6971 if (ExternalSource) {
6972 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
6973 I != N; ++I) {
6974 Selector Sel = ExternalSource->GetExternalSelector(I);
6975 if (Sel.isNull() || MethodPool.count(Sel))
6976 continue;
6977
6978 ReadMethodPool(Sel);
6979 }
6980 }
6981
6982 for (GlobalMethodPool::iterator M = MethodPool.begin(),
6983 MEnd = MethodPool.end();
6984 M != MEnd; ++M) {
6985 for (ObjCMethodList *MethList = &M->second.first;
6986 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
6987 if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
6988 continue;
6989
6990 if (!Selectors.insert(MethList->getMethod()->getSelector()).second)
6991 continue;
6992
6993 Result R(MethList->getMethod(),
6994 Results.getBasePriority(MethList->getMethod()), nullptr);
6995 R.StartParameter = SelIdents.size();
6996 R.AllParametersAreInformative = false;
6997 Results.MaybeAddResult(R, CurContext);
6998 }
6999 }
7000 }
7001 Results.ExitScope();
7002
7003 // If we're actually at the argument expression (rather than prior to the
7004 // selector), we're actually performing code completion for an expression.
7005 // Determine whether we have a single, best method. If so, we can
7006 // code-complete the expression using the corresponding parameter type as
7007 // our preferred type, improving completion results.
7008 if (AtArgumentExpression) {
7009 QualType PreferredType =
7010 getPreferredArgumentTypeForMessageSend(Results, SelIdents.size());
7011 if (PreferredType.isNull())
7012 CodeCompleteOrdinaryName(S, PCC_Expression);
7013 else
7014 CodeCompleteExpression(S, PreferredType);
7015 return;
7016 }
7017
7018 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7019 Results.data(), Results.size());
7020 }
7021
CodeCompleteObjCForCollection(Scope * S,DeclGroupPtrTy IterationVar)7022 void Sema::CodeCompleteObjCForCollection(Scope *S,
7023 DeclGroupPtrTy IterationVar) {
7024 CodeCompleteExpressionData Data;
7025 Data.ObjCCollection = true;
7026
7027 if (IterationVar.getAsOpaquePtr()) {
7028 DeclGroupRef DG = IterationVar.get();
7029 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
7030 if (*I)
7031 Data.IgnoreDecls.push_back(*I);
7032 }
7033 }
7034
7035 CodeCompleteExpression(S, Data);
7036 }
7037
CodeCompleteObjCSelector(Scope * S,ArrayRef<IdentifierInfo * > SelIdents)7038 void Sema::CodeCompleteObjCSelector(Scope *S,
7039 ArrayRef<IdentifierInfo *> SelIdents) {
7040 // If we have an external source, load the entire class method
7041 // pool from the AST file.
7042 if (ExternalSource) {
7043 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); I != N;
7044 ++I) {
7045 Selector Sel = ExternalSource->GetExternalSelector(I);
7046 if (Sel.isNull() || MethodPool.count(Sel))
7047 continue;
7048
7049 ReadMethodPool(Sel);
7050 }
7051 }
7052
7053 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7054 CodeCompleter->getCodeCompletionTUInfo(),
7055 CodeCompletionContext::CCC_SelectorName);
7056 Results.EnterNewScope();
7057 for (GlobalMethodPool::iterator M = MethodPool.begin(),
7058 MEnd = MethodPool.end();
7059 M != MEnd; ++M) {
7060
7061 Selector Sel = M->first;
7062 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents))
7063 continue;
7064
7065 CodeCompletionBuilder Builder(Results.getAllocator(),
7066 Results.getCodeCompletionTUInfo());
7067 if (Sel.isUnarySelector()) {
7068 Builder.AddTypedTextChunk(
7069 Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
7070 Results.AddResult(Builder.TakeString());
7071 continue;
7072 }
7073
7074 std::string Accumulator;
7075 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
7076 if (I == SelIdents.size()) {
7077 if (!Accumulator.empty()) {
7078 Builder.AddInformativeChunk(
7079 Builder.getAllocator().CopyString(Accumulator));
7080 Accumulator.clear();
7081 }
7082 }
7083
7084 Accumulator += Sel.getNameForSlot(I);
7085 Accumulator += ':';
7086 }
7087 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(Accumulator));
7088 Results.AddResult(Builder.TakeString());
7089 }
7090 Results.ExitScope();
7091
7092 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7093 Results.data(), Results.size());
7094 }
7095
7096 /// Add all of the protocol declarations that we find in the given
7097 /// (translation unit) context.
AddProtocolResults(DeclContext * Ctx,DeclContext * CurContext,bool OnlyForwardDeclarations,ResultBuilder & Results)7098 static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
7099 bool OnlyForwardDeclarations,
7100 ResultBuilder &Results) {
7101 typedef CodeCompletionResult Result;
7102
7103 for (const auto *D : Ctx->decls()) {
7104 // Record any protocols we find.
7105 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(D))
7106 if (!OnlyForwardDeclarations || !Proto->hasDefinition())
7107 Results.AddResult(
7108 Result(Proto, Results.getBasePriority(Proto), nullptr), CurContext,
7109 nullptr, false);
7110 }
7111 }
7112
CodeCompleteObjCProtocolReferences(ArrayRef<IdentifierLocPair> Protocols)7113 void Sema::CodeCompleteObjCProtocolReferences(
7114 ArrayRef<IdentifierLocPair> Protocols) {
7115 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7116 CodeCompleter->getCodeCompletionTUInfo(),
7117 CodeCompletionContext::CCC_ObjCProtocolName);
7118
7119 if (CodeCompleter->includeGlobals()) {
7120 Results.EnterNewScope();
7121
7122 // Tell the result set to ignore all of the protocols we have
7123 // already seen.
7124 // FIXME: This doesn't work when caching code-completion results.
7125 for (const IdentifierLocPair &Pair : Protocols)
7126 if (ObjCProtocolDecl *Protocol = LookupProtocol(Pair.first, Pair.second))
7127 Results.Ignore(Protocol);
7128
7129 // Add all protocols.
7130 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
7131 Results);
7132
7133 Results.ExitScope();
7134 }
7135
7136 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7137 Results.data(), Results.size());
7138 }
7139
CodeCompleteObjCProtocolDecl(Scope *)7140 void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
7141 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7142 CodeCompleter->getCodeCompletionTUInfo(),
7143 CodeCompletionContext::CCC_ObjCProtocolName);
7144
7145 if (CodeCompleter->includeGlobals()) {
7146 Results.EnterNewScope();
7147
7148 // Add all protocols.
7149 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
7150 Results);
7151
7152 Results.ExitScope();
7153 }
7154
7155 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7156 Results.data(), Results.size());
7157 }
7158
7159 /// Add all of the Objective-C interface declarations that we find in
7160 /// the given (translation unit) context.
AddInterfaceResults(DeclContext * Ctx,DeclContext * CurContext,bool OnlyForwardDeclarations,bool OnlyUnimplemented,ResultBuilder & Results)7161 static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
7162 bool OnlyForwardDeclarations,
7163 bool OnlyUnimplemented,
7164 ResultBuilder &Results) {
7165 typedef CodeCompletionResult Result;
7166
7167 for (const auto *D : Ctx->decls()) {
7168 // Record any interfaces we find.
7169 if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(D))
7170 if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
7171 (!OnlyUnimplemented || !Class->getImplementation()))
7172 Results.AddResult(
7173 Result(Class, Results.getBasePriority(Class), nullptr), CurContext,
7174 nullptr, false);
7175 }
7176 }
7177
CodeCompleteObjCInterfaceDecl(Scope * S)7178 void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
7179 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7180 CodeCompleter->getCodeCompletionTUInfo(),
7181 CodeCompletionContext::CCC_ObjCInterfaceName);
7182 Results.EnterNewScope();
7183
7184 if (CodeCompleter->includeGlobals()) {
7185 // Add all classes.
7186 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
7187 false, Results);
7188 }
7189
7190 Results.ExitScope();
7191
7192 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7193 Results.data(), Results.size());
7194 }
7195
CodeCompleteObjCSuperclass(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)7196 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
7197 SourceLocation ClassNameLoc) {
7198 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7199 CodeCompleter->getCodeCompletionTUInfo(),
7200 CodeCompletionContext::CCC_ObjCInterfaceName);
7201 Results.EnterNewScope();
7202
7203 // Make sure that we ignore the class we're currently defining.
7204 NamedDecl *CurClass =
7205 LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
7206 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
7207 Results.Ignore(CurClass);
7208
7209 if (CodeCompleter->includeGlobals()) {
7210 // Add all classes.
7211 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
7212 false, Results);
7213 }
7214
7215 Results.ExitScope();
7216
7217 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7218 Results.data(), Results.size());
7219 }
7220
CodeCompleteObjCImplementationDecl(Scope * S)7221 void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
7222 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7223 CodeCompleter->getCodeCompletionTUInfo(),
7224 CodeCompletionContext::CCC_ObjCImplementation);
7225 Results.EnterNewScope();
7226
7227 if (CodeCompleter->includeGlobals()) {
7228 // Add all unimplemented classes.
7229 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
7230 true, Results);
7231 }
7232
7233 Results.ExitScope();
7234
7235 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7236 Results.data(), Results.size());
7237 }
7238
CodeCompleteObjCInterfaceCategory(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)7239 void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
7240 IdentifierInfo *ClassName,
7241 SourceLocation ClassNameLoc) {
7242 typedef CodeCompletionResult Result;
7243
7244 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7245 CodeCompleter->getCodeCompletionTUInfo(),
7246 CodeCompletionContext::CCC_ObjCCategoryName);
7247
7248 // Ignore any categories we find that have already been implemented by this
7249 // interface.
7250 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
7251 NamedDecl *CurClass =
7252 LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
7253 if (ObjCInterfaceDecl *Class =
7254 dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)) {
7255 for (const auto *Cat : Class->visible_categories())
7256 CategoryNames.insert(Cat->getIdentifier());
7257 }
7258
7259 // Add all of the categories we know about.
7260 Results.EnterNewScope();
7261 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
7262 for (const auto *D : TU->decls())
7263 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D))
7264 if (CategoryNames.insert(Category->getIdentifier()).second)
7265 Results.AddResult(
7266 Result(Category, Results.getBasePriority(Category), nullptr),
7267 CurContext, nullptr, false);
7268 Results.ExitScope();
7269
7270 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7271 Results.data(), Results.size());
7272 }
7273
CodeCompleteObjCImplementationCategory(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)7274 void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
7275 IdentifierInfo *ClassName,
7276 SourceLocation ClassNameLoc) {
7277 typedef CodeCompletionResult Result;
7278
7279 // Find the corresponding interface. If we couldn't find the interface, the
7280 // program itself is ill-formed. However, we'll try to be helpful still by
7281 // providing the list of all of the categories we know about.
7282 NamedDecl *CurClass =
7283 LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
7284 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
7285 if (!Class)
7286 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
7287
7288 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7289 CodeCompleter->getCodeCompletionTUInfo(),
7290 CodeCompletionContext::CCC_ObjCCategoryName);
7291
7292 // Add all of the categories that have have corresponding interface
7293 // declarations in this class and any of its superclasses, except for
7294 // already-implemented categories in the class itself.
7295 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
7296 Results.EnterNewScope();
7297 bool IgnoreImplemented = true;
7298 while (Class) {
7299 for (const auto *Cat : Class->visible_categories()) {
7300 if ((!IgnoreImplemented || !Cat->getImplementation()) &&
7301 CategoryNames.insert(Cat->getIdentifier()).second)
7302 Results.AddResult(Result(Cat, Results.getBasePriority(Cat), nullptr),
7303 CurContext, nullptr, false);
7304 }
7305
7306 Class = Class->getSuperClass();
7307 IgnoreImplemented = false;
7308 }
7309 Results.ExitScope();
7310
7311 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7312 Results.data(), Results.size());
7313 }
7314
CodeCompleteObjCPropertyDefinition(Scope * S)7315 void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
7316 CodeCompletionContext CCContext(CodeCompletionContext::CCC_Other);
7317 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7318 CodeCompleter->getCodeCompletionTUInfo(), CCContext);
7319
7320 // Figure out where this @synthesize lives.
7321 ObjCContainerDecl *Container =
7322 dyn_cast_or_null<ObjCContainerDecl>(CurContext);
7323 if (!Container || (!isa<ObjCImplementationDecl>(Container) &&
7324 !isa<ObjCCategoryImplDecl>(Container)))
7325 return;
7326
7327 // Ignore any properties that have already been implemented.
7328 Container = getContainerDef(Container);
7329 for (const auto *D : Container->decls())
7330 if (const auto *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(D))
7331 Results.Ignore(PropertyImpl->getPropertyDecl());
7332
7333 // Add any properties that we find.
7334 AddedPropertiesSet AddedProperties;
7335 Results.EnterNewScope();
7336 if (ObjCImplementationDecl *ClassImpl =
7337 dyn_cast<ObjCImplementationDecl>(Container))
7338 AddObjCProperties(CCContext, ClassImpl->getClassInterface(), false,
7339 /*AllowNullaryMethods=*/false, CurContext,
7340 AddedProperties, Results);
7341 else
7342 AddObjCProperties(CCContext,
7343 cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
7344 false, /*AllowNullaryMethods=*/false, CurContext,
7345 AddedProperties, Results);
7346 Results.ExitScope();
7347
7348 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7349 Results.data(), Results.size());
7350 }
7351
CodeCompleteObjCPropertySynthesizeIvar(Scope * S,IdentifierInfo * PropertyName)7352 void Sema::CodeCompleteObjCPropertySynthesizeIvar(
7353 Scope *S, IdentifierInfo *PropertyName) {
7354 typedef CodeCompletionResult Result;
7355 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7356 CodeCompleter->getCodeCompletionTUInfo(),
7357 CodeCompletionContext::CCC_Other);
7358
7359 // Figure out where this @synthesize lives.
7360 ObjCContainerDecl *Container =
7361 dyn_cast_or_null<ObjCContainerDecl>(CurContext);
7362 if (!Container || (!isa<ObjCImplementationDecl>(Container) &&
7363 !isa<ObjCCategoryImplDecl>(Container)))
7364 return;
7365
7366 // Figure out which interface we're looking into.
7367 ObjCInterfaceDecl *Class = nullptr;
7368 if (ObjCImplementationDecl *ClassImpl =
7369 dyn_cast<ObjCImplementationDecl>(Container))
7370 Class = ClassImpl->getClassInterface();
7371 else
7372 Class = cast<ObjCCategoryImplDecl>(Container)
7373 ->getCategoryDecl()
7374 ->getClassInterface();
7375
7376 // Determine the type of the property we're synthesizing.
7377 QualType PropertyType = Context.getObjCIdType();
7378 if (Class) {
7379 if (ObjCPropertyDecl *Property = Class->FindPropertyDeclaration(
7380 PropertyName, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
7381 PropertyType =
7382 Property->getType().getNonReferenceType().getUnqualifiedType();
7383
7384 // Give preference to ivars
7385 Results.setPreferredType(PropertyType);
7386 }
7387 }
7388
7389 // Add all of the instance variables in this class and its superclasses.
7390 Results.EnterNewScope();
7391 bool SawSimilarlyNamedIvar = false;
7392 std::string NameWithPrefix;
7393 NameWithPrefix += '_';
7394 NameWithPrefix += PropertyName->getName();
7395 std::string NameWithSuffix = PropertyName->getName().str();
7396 NameWithSuffix += '_';
7397 for (; Class; Class = Class->getSuperClass()) {
7398 for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
7399 Ivar = Ivar->getNextIvar()) {
7400 Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), nullptr),
7401 CurContext, nullptr, false);
7402
7403 // Determine whether we've seen an ivar with a name similar to the
7404 // property.
7405 if ((PropertyName == Ivar->getIdentifier() ||
7406 NameWithPrefix == Ivar->getName() ||
7407 NameWithSuffix == Ivar->getName())) {
7408 SawSimilarlyNamedIvar = true;
7409
7410 // Reduce the priority of this result by one, to give it a slight
7411 // advantage over other results whose names don't match so closely.
7412 if (Results.size() &&
7413 Results.data()[Results.size() - 1].Kind ==
7414 CodeCompletionResult::RK_Declaration &&
7415 Results.data()[Results.size() - 1].Declaration == Ivar)
7416 Results.data()[Results.size() - 1].Priority--;
7417 }
7418 }
7419 }
7420
7421 if (!SawSimilarlyNamedIvar) {
7422 // Create ivar result _propName, that the user can use to synthesize
7423 // an ivar of the appropriate type.
7424 unsigned Priority = CCP_MemberDeclaration + 1;
7425 typedef CodeCompletionResult Result;
7426 CodeCompletionAllocator &Allocator = Results.getAllocator();
7427 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
7428 Priority, CXAvailability_Available);
7429
7430 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
7431 Builder.AddResultTypeChunk(
7432 GetCompletionTypeString(PropertyType, Context, Policy, Allocator));
7433 Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix));
7434 Results.AddResult(
7435 Result(Builder.TakeString(), Priority, CXCursor_ObjCIvarDecl));
7436 }
7437
7438 Results.ExitScope();
7439
7440 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7441 Results.data(), Results.size());
7442 }
7443
7444 // Mapping from selectors to the methods that implement that selector, along
7445 // with the "in original class" flag.
7446 typedef llvm::DenseMap<Selector,
7447 llvm::PointerIntPair<ObjCMethodDecl *, 1, bool>>
7448 KnownMethodsMap;
7449
7450 /// Find all of the methods that reside in the given container
7451 /// (and its superclasses, protocols, etc.) that meet the given
7452 /// criteria. Insert those methods into the map of known methods,
7453 /// indexed by selector so they can be easily found.
FindImplementableMethods(ASTContext & Context,ObjCContainerDecl * Container,Optional<bool> WantInstanceMethods,QualType ReturnType,KnownMethodsMap & KnownMethods,bool InOriginalClass=true)7454 static void FindImplementableMethods(ASTContext &Context,
7455 ObjCContainerDecl *Container,
7456 Optional<bool> WantInstanceMethods,
7457 QualType ReturnType,
7458 KnownMethodsMap &KnownMethods,
7459 bool InOriginalClass = true) {
7460 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
7461 // Make sure we have a definition; that's what we'll walk.
7462 if (!IFace->hasDefinition())
7463 return;
7464
7465 IFace = IFace->getDefinition();
7466 Container = IFace;
7467
7468 const ObjCList<ObjCProtocolDecl> &Protocols =
7469 IFace->getReferencedProtocols();
7470 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
7471 E = Protocols.end();
7472 I != E; ++I)
7473 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
7474 KnownMethods, InOriginalClass);
7475
7476 // Add methods from any class extensions and categories.
7477 for (auto *Cat : IFace->visible_categories()) {
7478 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
7479 KnownMethods, false);
7480 }
7481
7482 // Visit the superclass.
7483 if (IFace->getSuperClass())
7484 FindImplementableMethods(Context, IFace->getSuperClass(),
7485 WantInstanceMethods, ReturnType, KnownMethods,
7486 false);
7487 }
7488
7489 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
7490 // Recurse into protocols.
7491 const ObjCList<ObjCProtocolDecl> &Protocols =
7492 Category->getReferencedProtocols();
7493 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
7494 E = Protocols.end();
7495 I != E; ++I)
7496 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
7497 KnownMethods, InOriginalClass);
7498
7499 // If this category is the original class, jump to the interface.
7500 if (InOriginalClass && Category->getClassInterface())
7501 FindImplementableMethods(Context, Category->getClassInterface(),
7502 WantInstanceMethods, ReturnType, KnownMethods,
7503 false);
7504 }
7505
7506 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
7507 // Make sure we have a definition; that's what we'll walk.
7508 if (!Protocol->hasDefinition())
7509 return;
7510 Protocol = Protocol->getDefinition();
7511 Container = Protocol;
7512
7513 // Recurse into protocols.
7514 const ObjCList<ObjCProtocolDecl> &Protocols =
7515 Protocol->getReferencedProtocols();
7516 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
7517 E = Protocols.end();
7518 I != E; ++I)
7519 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
7520 KnownMethods, false);
7521 }
7522
7523 // Add methods in this container. This operation occurs last because
7524 // we want the methods from this container to override any methods
7525 // we've previously seen with the same selector.
7526 for (auto *M : Container->methods()) {
7527 if (!WantInstanceMethods || M->isInstanceMethod() == *WantInstanceMethods) {
7528 if (!ReturnType.isNull() &&
7529 !Context.hasSameUnqualifiedType(ReturnType, M->getReturnType()))
7530 continue;
7531
7532 KnownMethods[M->getSelector()] =
7533 KnownMethodsMap::mapped_type(M, InOriginalClass);
7534 }
7535 }
7536 }
7537
7538 /// Add the parenthesized return or parameter type chunk to a code
7539 /// completion string.
AddObjCPassingTypeChunk(QualType Type,unsigned ObjCDeclQuals,ASTContext & Context,const PrintingPolicy & Policy,CodeCompletionBuilder & Builder)7540 static void AddObjCPassingTypeChunk(QualType Type, unsigned ObjCDeclQuals,
7541 ASTContext &Context,
7542 const PrintingPolicy &Policy,
7543 CodeCompletionBuilder &Builder) {
7544 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7545 std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals, Type);
7546 if (!Quals.empty())
7547 Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals));
7548 Builder.AddTextChunk(
7549 GetCompletionTypeString(Type, Context, Policy, Builder.getAllocator()));
7550 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7551 }
7552
7553 /// Determine whether the given class is or inherits from a class by
7554 /// the given name.
InheritsFromClassNamed(ObjCInterfaceDecl * Class,StringRef Name)7555 static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, StringRef Name) {
7556 if (!Class)
7557 return false;
7558
7559 if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name)
7560 return true;
7561
7562 return InheritsFromClassNamed(Class->getSuperClass(), Name);
7563 }
7564
7565 /// Add code completions for Objective-C Key-Value Coding (KVC) and
7566 /// Key-Value Observing (KVO).
AddObjCKeyValueCompletions(ObjCPropertyDecl * Property,bool IsInstanceMethod,QualType ReturnType,ASTContext & Context,VisitedSelectorSet & KnownSelectors,ResultBuilder & Results)7567 static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
7568 bool IsInstanceMethod,
7569 QualType ReturnType, ASTContext &Context,
7570 VisitedSelectorSet &KnownSelectors,
7571 ResultBuilder &Results) {
7572 IdentifierInfo *PropName = Property->getIdentifier();
7573 if (!PropName || PropName->getLength() == 0)
7574 return;
7575
7576 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
7577
7578 // Builder that will create each code completion.
7579 typedef CodeCompletionResult Result;
7580 CodeCompletionAllocator &Allocator = Results.getAllocator();
7581 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
7582
7583 // The selector table.
7584 SelectorTable &Selectors = Context.Selectors;
7585
7586 // The property name, copied into the code completion allocation region
7587 // on demand.
7588 struct KeyHolder {
7589 CodeCompletionAllocator &Allocator;
7590 StringRef Key;
7591 const char *CopiedKey;
7592
7593 KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
7594 : Allocator(Allocator), Key(Key), CopiedKey(nullptr) {}
7595
7596 operator const char *() {
7597 if (CopiedKey)
7598 return CopiedKey;
7599
7600 return CopiedKey = Allocator.CopyString(Key);
7601 }
7602 } Key(Allocator, PropName->getName());
7603
7604 // The uppercased name of the property name.
7605 std::string UpperKey = PropName->getName();
7606 if (!UpperKey.empty())
7607 UpperKey[0] = toUppercase(UpperKey[0]);
7608
7609 bool ReturnTypeMatchesProperty =
7610 ReturnType.isNull() ||
7611 Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(),
7612 Property->getType());
7613 bool ReturnTypeMatchesVoid = ReturnType.isNull() || ReturnType->isVoidType();
7614
7615 // Add the normal accessor -(type)key.
7616 if (IsInstanceMethod &&
7617 KnownSelectors.insert(Selectors.getNullarySelector(PropName)).second &&
7618 ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {
7619 if (ReturnType.isNull())
7620 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy,
7621 Builder);
7622
7623 Builder.AddTypedTextChunk(Key);
7624 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
7625 CXCursor_ObjCInstanceMethodDecl));
7626 }
7627
7628 // If we have an integral or boolean property (or the user has provided
7629 // an integral or boolean return type), add the accessor -(type)isKey.
7630 if (IsInstanceMethod &&
7631 ((!ReturnType.isNull() &&
7632 (ReturnType->isIntegerType() || ReturnType->isBooleanType())) ||
7633 (ReturnType.isNull() && (Property->getType()->isIntegerType() ||
7634 Property->getType()->isBooleanType())))) {
7635 std::string SelectorName = (Twine("is") + UpperKey).str();
7636 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7637 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
7638 .second) {
7639 if (ReturnType.isNull()) {
7640 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7641 Builder.AddTextChunk("BOOL");
7642 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7643 }
7644
7645 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName()));
7646 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
7647 CXCursor_ObjCInstanceMethodDecl));
7648 }
7649 }
7650
7651 // Add the normal mutator.
7652 if (IsInstanceMethod && ReturnTypeMatchesVoid &&
7653 !Property->getSetterMethodDecl()) {
7654 std::string SelectorName = (Twine("set") + UpperKey).str();
7655 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7656 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
7657 if (ReturnType.isNull()) {
7658 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7659 Builder.AddTextChunk("void");
7660 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7661 }
7662
7663 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName()));
7664 Builder.AddTypedTextChunk(":");
7665 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy,
7666 Builder);
7667 Builder.AddTextChunk(Key);
7668 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
7669 CXCursor_ObjCInstanceMethodDecl));
7670 }
7671 }
7672
7673 // Indexed and unordered accessors
7674 unsigned IndexedGetterPriority = CCP_CodePattern;
7675 unsigned IndexedSetterPriority = CCP_CodePattern;
7676 unsigned UnorderedGetterPriority = CCP_CodePattern;
7677 unsigned UnorderedSetterPriority = CCP_CodePattern;
7678 if (const auto *ObjCPointer =
7679 Property->getType()->getAs<ObjCObjectPointerType>()) {
7680 if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) {
7681 // If this interface type is not provably derived from a known
7682 // collection, penalize the corresponding completions.
7683 if (!InheritsFromClassNamed(IFace, "NSMutableArray")) {
7684 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
7685 if (!InheritsFromClassNamed(IFace, "NSArray"))
7686 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
7687 }
7688
7689 if (!InheritsFromClassNamed(IFace, "NSMutableSet")) {
7690 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
7691 if (!InheritsFromClassNamed(IFace, "NSSet"))
7692 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
7693 }
7694 }
7695 } else {
7696 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
7697 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
7698 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
7699 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
7700 }
7701
7702 // Add -(NSUInteger)countOf<key>
7703 if (IsInstanceMethod &&
7704 (ReturnType.isNull() || ReturnType->isIntegerType())) {
7705 std::string SelectorName = (Twine("countOf") + UpperKey).str();
7706 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7707 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
7708 .second) {
7709 if (ReturnType.isNull()) {
7710 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7711 Builder.AddTextChunk("NSUInteger");
7712 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7713 }
7714
7715 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName()));
7716 Results.AddResult(
7717 Result(Builder.TakeString(),
7718 std::min(IndexedGetterPriority, UnorderedGetterPriority),
7719 CXCursor_ObjCInstanceMethodDecl));
7720 }
7721 }
7722
7723 // Indexed getters
7724 // Add -(id)objectInKeyAtIndex:(NSUInteger)index
7725 if (IsInstanceMethod &&
7726 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
7727 std::string SelectorName = (Twine("objectIn") + UpperKey + "AtIndex").str();
7728 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7729 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
7730 if (ReturnType.isNull()) {
7731 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7732 Builder.AddTextChunk("id");
7733 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7734 }
7735
7736 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
7737 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7738 Builder.AddTextChunk("NSUInteger");
7739 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7740 Builder.AddTextChunk("index");
7741 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
7742 CXCursor_ObjCInstanceMethodDecl));
7743 }
7744 }
7745
7746 // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes
7747 if (IsInstanceMethod &&
7748 (ReturnType.isNull() ||
7749 (ReturnType->isObjCObjectPointerType() &&
7750 ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
7751 ReturnType->castAs<ObjCObjectPointerType>()
7752 ->getInterfaceDecl()
7753 ->getName() == "NSArray"))) {
7754 std::string SelectorName = (Twine(Property->getName()) + "AtIndexes").str();
7755 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7756 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
7757 if (ReturnType.isNull()) {
7758 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7759 Builder.AddTextChunk("NSArray *");
7760 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7761 }
7762
7763 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
7764 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7765 Builder.AddTextChunk("NSIndexSet *");
7766 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7767 Builder.AddTextChunk("indexes");
7768 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
7769 CXCursor_ObjCInstanceMethodDecl));
7770 }
7771 }
7772
7773 // Add -(void)getKey:(type **)buffer range:(NSRange)inRange
7774 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
7775 std::string SelectorName = (Twine("get") + UpperKey).str();
7776 IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
7777 &Context.Idents.get("range")};
7778
7779 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
7780 if (ReturnType.isNull()) {
7781 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7782 Builder.AddTextChunk("void");
7783 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7784 }
7785
7786 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
7787 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7788 Builder.AddPlaceholderChunk("object-type");
7789 Builder.AddTextChunk(" **");
7790 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7791 Builder.AddTextChunk("buffer");
7792 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7793 Builder.AddTypedTextChunk("range:");
7794 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7795 Builder.AddTextChunk("NSRange");
7796 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7797 Builder.AddTextChunk("inRange");
7798 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
7799 CXCursor_ObjCInstanceMethodDecl));
7800 }
7801 }
7802
7803 // Mutable indexed accessors
7804
7805 // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index
7806 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
7807 std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str();
7808 IdentifierInfo *SelectorIds[2] = {&Context.Idents.get("insertObject"),
7809 &Context.Idents.get(SelectorName)};
7810
7811 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
7812 if (ReturnType.isNull()) {
7813 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7814 Builder.AddTextChunk("void");
7815 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7816 }
7817
7818 Builder.AddTypedTextChunk("insertObject:");
7819 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7820 Builder.AddPlaceholderChunk("object-type");
7821 Builder.AddTextChunk(" *");
7822 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7823 Builder.AddTextChunk("object");
7824 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7825 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
7826 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7827 Builder.AddPlaceholderChunk("NSUInteger");
7828 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7829 Builder.AddTextChunk("index");
7830 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
7831 CXCursor_ObjCInstanceMethodDecl));
7832 }
7833 }
7834
7835 // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes
7836 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
7837 std::string SelectorName = (Twine("insert") + UpperKey).str();
7838 IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
7839 &Context.Idents.get("atIndexes")};
7840
7841 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
7842 if (ReturnType.isNull()) {
7843 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7844 Builder.AddTextChunk("void");
7845 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7846 }
7847
7848 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
7849 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7850 Builder.AddTextChunk("NSArray *");
7851 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7852 Builder.AddTextChunk("array");
7853 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7854 Builder.AddTypedTextChunk("atIndexes:");
7855 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7856 Builder.AddPlaceholderChunk("NSIndexSet *");
7857 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7858 Builder.AddTextChunk("indexes");
7859 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
7860 CXCursor_ObjCInstanceMethodDecl));
7861 }
7862 }
7863
7864 // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index
7865 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
7866 std::string SelectorName =
7867 (Twine("removeObjectFrom") + UpperKey + "AtIndex").str();
7868 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7869 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
7870 if (ReturnType.isNull()) {
7871 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7872 Builder.AddTextChunk("void");
7873 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7874 }
7875
7876 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
7877 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7878 Builder.AddTextChunk("NSUInteger");
7879 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7880 Builder.AddTextChunk("index");
7881 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
7882 CXCursor_ObjCInstanceMethodDecl));
7883 }
7884 }
7885
7886 // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes
7887 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
7888 std::string SelectorName = (Twine("remove") + UpperKey + "AtIndexes").str();
7889 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7890 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
7891 if (ReturnType.isNull()) {
7892 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7893 Builder.AddTextChunk("void");
7894 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7895 }
7896
7897 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
7898 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7899 Builder.AddTextChunk("NSIndexSet *");
7900 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7901 Builder.AddTextChunk("indexes");
7902 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
7903 CXCursor_ObjCInstanceMethodDecl));
7904 }
7905 }
7906
7907 // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object
7908 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
7909 std::string SelectorName =
7910 (Twine("replaceObjectIn") + UpperKey + "AtIndex").str();
7911 IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
7912 &Context.Idents.get("withObject")};
7913
7914 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
7915 if (ReturnType.isNull()) {
7916 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7917 Builder.AddTextChunk("void");
7918 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7919 }
7920
7921 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
7922 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7923 Builder.AddPlaceholderChunk("NSUInteger");
7924 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7925 Builder.AddTextChunk("index");
7926 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7927 Builder.AddTypedTextChunk("withObject:");
7928 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7929 Builder.AddTextChunk("id");
7930 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7931 Builder.AddTextChunk("object");
7932 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
7933 CXCursor_ObjCInstanceMethodDecl));
7934 }
7935 }
7936
7937 // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array
7938 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
7939 std::string SelectorName1 =
7940 (Twine("replace") + UpperKey + "AtIndexes").str();
7941 std::string SelectorName2 = (Twine("with") + UpperKey).str();
7942 IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName1),
7943 &Context.Idents.get(SelectorName2)};
7944
7945 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
7946 if (ReturnType.isNull()) {
7947 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7948 Builder.AddTextChunk("void");
7949 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7950 }
7951
7952 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":"));
7953 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7954 Builder.AddPlaceholderChunk("NSIndexSet *");
7955 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7956 Builder.AddTextChunk("indexes");
7957 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7958 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":"));
7959 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7960 Builder.AddTextChunk("NSArray *");
7961 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7962 Builder.AddTextChunk("array");
7963 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
7964 CXCursor_ObjCInstanceMethodDecl));
7965 }
7966 }
7967
7968 // Unordered getters
7969 // - (NSEnumerator *)enumeratorOfKey
7970 if (IsInstanceMethod &&
7971 (ReturnType.isNull() ||
7972 (ReturnType->isObjCObjectPointerType() &&
7973 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
7974 ReturnType->getAs<ObjCObjectPointerType>()
7975 ->getInterfaceDecl()
7976 ->getName() == "NSEnumerator"))) {
7977 std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();
7978 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7979 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
7980 .second) {
7981 if (ReturnType.isNull()) {
7982 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7983 Builder.AddTextChunk("NSEnumerator *");
7984 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7985 }
7986
7987 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
7988 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
7989 CXCursor_ObjCInstanceMethodDecl));
7990 }
7991 }
7992
7993 // - (type *)memberOfKey:(type *)object
7994 if (IsInstanceMethod &&
7995 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
7996 std::string SelectorName = (Twine("memberOf") + UpperKey).str();
7997 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7998 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
7999 if (ReturnType.isNull()) {
8000 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8001 Builder.AddPlaceholderChunk("object-type");
8002 Builder.AddTextChunk(" *");
8003 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8004 }
8005
8006 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
8007 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8008 if (ReturnType.isNull()) {
8009 Builder.AddPlaceholderChunk("object-type");
8010 Builder.AddTextChunk(" *");
8011 } else {
8012 Builder.AddTextChunk(GetCompletionTypeString(
8013 ReturnType, Context, Policy, Builder.getAllocator()));
8014 }
8015 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8016 Builder.AddTextChunk("object");
8017 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
8018 CXCursor_ObjCInstanceMethodDecl));
8019 }
8020 }
8021
8022 // Mutable unordered accessors
8023 // - (void)addKeyObject:(type *)object
8024 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
8025 std::string SelectorName =
8026 (Twine("add") + UpperKey + Twine("Object")).str();
8027 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
8028 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
8029 if (ReturnType.isNull()) {
8030 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8031 Builder.AddTextChunk("void");
8032 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8033 }
8034
8035 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
8036 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8037 Builder.AddPlaceholderChunk("object-type");
8038 Builder.AddTextChunk(" *");
8039 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8040 Builder.AddTextChunk("object");
8041 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
8042 CXCursor_ObjCInstanceMethodDecl));
8043 }
8044 }
8045
8046 // - (void)addKey:(NSSet *)objects
8047 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
8048 std::string SelectorName = (Twine("add") + UpperKey).str();
8049 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
8050 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
8051 if (ReturnType.isNull()) {
8052 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8053 Builder.AddTextChunk("void");
8054 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8055 }
8056
8057 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
8058 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8059 Builder.AddTextChunk("NSSet *");
8060 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8061 Builder.AddTextChunk("objects");
8062 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
8063 CXCursor_ObjCInstanceMethodDecl));
8064 }
8065 }
8066
8067 // - (void)removeKeyObject:(type *)object
8068 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
8069 std::string SelectorName =
8070 (Twine("remove") + UpperKey + Twine("Object")).str();
8071 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
8072 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
8073 if (ReturnType.isNull()) {
8074 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8075 Builder.AddTextChunk("void");
8076 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8077 }
8078
8079 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
8080 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8081 Builder.AddPlaceholderChunk("object-type");
8082 Builder.AddTextChunk(" *");
8083 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8084 Builder.AddTextChunk("object");
8085 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
8086 CXCursor_ObjCInstanceMethodDecl));
8087 }
8088 }
8089
8090 // - (void)removeKey:(NSSet *)objects
8091 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
8092 std::string SelectorName = (Twine("remove") + UpperKey).str();
8093 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
8094 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
8095 if (ReturnType.isNull()) {
8096 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8097 Builder.AddTextChunk("void");
8098 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8099 }
8100
8101 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
8102 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8103 Builder.AddTextChunk("NSSet *");
8104 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8105 Builder.AddTextChunk("objects");
8106 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
8107 CXCursor_ObjCInstanceMethodDecl));
8108 }
8109 }
8110
8111 // - (void)intersectKey:(NSSet *)objects
8112 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
8113 std::string SelectorName = (Twine("intersect") + UpperKey).str();
8114 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
8115 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
8116 if (ReturnType.isNull()) {
8117 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8118 Builder.AddTextChunk("void");
8119 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8120 }
8121
8122 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
8123 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8124 Builder.AddTextChunk("NSSet *");
8125 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8126 Builder.AddTextChunk("objects");
8127 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
8128 CXCursor_ObjCInstanceMethodDecl));
8129 }
8130 }
8131
8132 // Key-Value Observing
8133 // + (NSSet *)keyPathsForValuesAffectingKey
8134 if (!IsInstanceMethod &&
8135 (ReturnType.isNull() ||
8136 (ReturnType->isObjCObjectPointerType() &&
8137 ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
8138 ReturnType->castAs<ObjCObjectPointerType>()
8139 ->getInterfaceDecl()
8140 ->getName() == "NSSet"))) {
8141 std::string SelectorName =
8142 (Twine("keyPathsForValuesAffecting") + UpperKey).str();
8143 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
8144 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
8145 .second) {
8146 if (ReturnType.isNull()) {
8147 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8148 Builder.AddTextChunk("NSSet<NSString *> *");
8149 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8150 }
8151
8152 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
8153 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
8154 CXCursor_ObjCClassMethodDecl));
8155 }
8156 }
8157
8158 // + (BOOL)automaticallyNotifiesObserversForKey
8159 if (!IsInstanceMethod &&
8160 (ReturnType.isNull() || ReturnType->isIntegerType() ||
8161 ReturnType->isBooleanType())) {
8162 std::string SelectorName =
8163 (Twine("automaticallyNotifiesObserversOf") + UpperKey).str();
8164 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
8165 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
8166 .second) {
8167 if (ReturnType.isNull()) {
8168 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8169 Builder.AddTextChunk("BOOL");
8170 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8171 }
8172
8173 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
8174 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
8175 CXCursor_ObjCClassMethodDecl));
8176 }
8177 }
8178 }
8179
CodeCompleteObjCMethodDecl(Scope * S,Optional<bool> IsInstanceMethod,ParsedType ReturnTy)8180 void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod,
8181 ParsedType ReturnTy) {
8182 // Determine the return type of the method we're declaring, if
8183 // provided.
8184 QualType ReturnType = GetTypeFromParser(ReturnTy);
8185 Decl *IDecl = nullptr;
8186 if (CurContext->isObjCContainer()) {
8187 ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
8188 IDecl = OCD;
8189 }
8190 // Determine where we should start searching for methods.
8191 ObjCContainerDecl *SearchDecl = nullptr;
8192 bool IsInImplementation = false;
8193 if (Decl *D = IDecl) {
8194 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
8195 SearchDecl = Impl->getClassInterface();
8196 IsInImplementation = true;
8197 } else if (ObjCCategoryImplDecl *CatImpl =
8198 dyn_cast<ObjCCategoryImplDecl>(D)) {
8199 SearchDecl = CatImpl->getCategoryDecl();
8200 IsInImplementation = true;
8201 } else
8202 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
8203 }
8204
8205 if (!SearchDecl && S) {
8206 if (DeclContext *DC = S->getEntity())
8207 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
8208 }
8209
8210 if (!SearchDecl) {
8211 HandleCodeCompleteResults(this, CodeCompleter,
8212 CodeCompletionContext::CCC_Other, nullptr, 0);
8213 return;
8214 }
8215
8216 // Find all of the methods that we could declare/implement here.
8217 KnownMethodsMap KnownMethods;
8218 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod, ReturnType,
8219 KnownMethods);
8220
8221 // Add declarations or definitions for each of the known methods.
8222 typedef CodeCompletionResult Result;
8223 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
8224 CodeCompleter->getCodeCompletionTUInfo(),
8225 CodeCompletionContext::CCC_Other);
8226 Results.EnterNewScope();
8227 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
8228 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
8229 MEnd = KnownMethods.end();
8230 M != MEnd; ++M) {
8231 ObjCMethodDecl *Method = M->second.getPointer();
8232 CodeCompletionBuilder Builder(Results.getAllocator(),
8233 Results.getCodeCompletionTUInfo());
8234
8235 // Add the '-'/'+' prefix if it wasn't provided yet.
8236 if (!IsInstanceMethod) {
8237 Builder.AddTextChunk(Method->isInstanceMethod() ? "-" : "+");
8238 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8239 }
8240
8241 // If the result type was not already provided, add it to the
8242 // pattern as (type).
8243 if (ReturnType.isNull()) {
8244 QualType ResTy = Method->getSendResultType().stripObjCKindOfType(Context);
8245 AttributedType::stripOuterNullability(ResTy);
8246 AddObjCPassingTypeChunk(ResTy, Method->getObjCDeclQualifier(), Context,
8247 Policy, Builder);
8248 }
8249
8250 Selector Sel = Method->getSelector();
8251
8252 // Add the first part of the selector to the pattern.
8253 Builder.AddTypedTextChunk(
8254 Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
8255
8256 // Add parameters to the pattern.
8257 unsigned I = 0;
8258 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
8259 PEnd = Method->param_end();
8260 P != PEnd; (void)++P, ++I) {
8261 // Add the part of the selector name.
8262 if (I == 0)
8263 Builder.AddTypedTextChunk(":");
8264 else if (I < Sel.getNumArgs()) {
8265 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8266 Builder.AddTypedTextChunk(
8267 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
8268 } else
8269 break;
8270
8271 // Add the parameter type.
8272 QualType ParamType;
8273 if ((*P)->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
8274 ParamType = (*P)->getType();
8275 else
8276 ParamType = (*P)->getOriginalType();
8277 ParamType = ParamType.substObjCTypeArgs(
8278 Context, {}, ObjCSubstitutionContext::Parameter);
8279 AttributedType::stripOuterNullability(ParamType);
8280 AddObjCPassingTypeChunk(ParamType, (*P)->getObjCDeclQualifier(), Context,
8281 Policy, Builder);
8282
8283 if (IdentifierInfo *Id = (*P)->getIdentifier())
8284 Builder.AddTextChunk(Builder.getAllocator().CopyString(Id->getName()));
8285 }
8286
8287 if (Method->isVariadic()) {
8288 if (Method->param_size() > 0)
8289 Builder.AddChunk(CodeCompletionString::CK_Comma);
8290 Builder.AddTextChunk("...");
8291 }
8292
8293 if (IsInImplementation && Results.includeCodePatterns()) {
8294 // We will be defining the method here, so add a compound statement.
8295 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8296 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
8297 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
8298 if (!Method->getReturnType()->isVoidType()) {
8299 // If the result type is not void, add a return clause.
8300 Builder.AddTextChunk("return");
8301 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8302 Builder.AddPlaceholderChunk("expression");
8303 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
8304 } else
8305 Builder.AddPlaceholderChunk("statements");
8306
8307 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
8308 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
8309 }
8310
8311 unsigned Priority = CCP_CodePattern;
8312 auto R = Result(Builder.TakeString(), Method, Priority);
8313 if (!M->second.getInt())
8314 setInBaseClass(R);
8315 Results.AddResult(std::move(R));
8316 }
8317
8318 // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
8319 // the properties in this class and its categories.
8320 if (Context.getLangOpts().ObjC) {
8321 SmallVector<ObjCContainerDecl *, 4> Containers;
8322 Containers.push_back(SearchDecl);
8323
8324 VisitedSelectorSet KnownSelectors;
8325 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
8326 MEnd = KnownMethods.end();
8327 M != MEnd; ++M)
8328 KnownSelectors.insert(M->first);
8329
8330 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl);
8331 if (!IFace)
8332 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl))
8333 IFace = Category->getClassInterface();
8334
8335 if (IFace)
8336 for (auto *Cat : IFace->visible_categories())
8337 Containers.push_back(Cat);
8338
8339 if (IsInstanceMethod) {
8340 for (unsigned I = 0, N = Containers.size(); I != N; ++I)
8341 for (auto *P : Containers[I]->instance_properties())
8342 AddObjCKeyValueCompletions(P, *IsInstanceMethod, ReturnType, Context,
8343 KnownSelectors, Results);
8344 }
8345 }
8346
8347 Results.ExitScope();
8348
8349 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
8350 Results.data(), Results.size());
8351 }
8352
CodeCompleteObjCMethodDeclSelector(Scope * S,bool IsInstanceMethod,bool AtParameterName,ParsedType ReturnTy,ArrayRef<IdentifierInfo * > SelIdents)8353 void Sema::CodeCompleteObjCMethodDeclSelector(
8354 Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnTy,
8355 ArrayRef<IdentifierInfo *> SelIdents) {
8356 // If we have an external source, load the entire class method
8357 // pool from the AST file.
8358 if (ExternalSource) {
8359 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); I != N;
8360 ++I) {
8361 Selector Sel = ExternalSource->GetExternalSelector(I);
8362 if (Sel.isNull() || MethodPool.count(Sel))
8363 continue;
8364
8365 ReadMethodPool(Sel);
8366 }
8367 }
8368
8369 // Build the set of methods we can see.
8370 typedef CodeCompletionResult Result;
8371 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
8372 CodeCompleter->getCodeCompletionTUInfo(),
8373 CodeCompletionContext::CCC_Other);
8374
8375 if (ReturnTy)
8376 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
8377
8378 Results.EnterNewScope();
8379 for (GlobalMethodPool::iterator M = MethodPool.begin(),
8380 MEnd = MethodPool.end();
8381 M != MEnd; ++M) {
8382 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first
8383 : &M->second.second;
8384 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
8385 if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
8386 continue;
8387
8388 if (AtParameterName) {
8389 // Suggest parameter names we've seen before.
8390 unsigned NumSelIdents = SelIdents.size();
8391 if (NumSelIdents &&
8392 NumSelIdents <= MethList->getMethod()->param_size()) {
8393 ParmVarDecl *Param =
8394 MethList->getMethod()->parameters()[NumSelIdents - 1];
8395 if (Param->getIdentifier()) {
8396 CodeCompletionBuilder Builder(Results.getAllocator(),
8397 Results.getCodeCompletionTUInfo());
8398 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
8399 Param->getIdentifier()->getName()));
8400 Results.AddResult(Builder.TakeString());
8401 }
8402 }
8403
8404 continue;
8405 }
8406
8407 Result R(MethList->getMethod(),
8408 Results.getBasePriority(MethList->getMethod()), nullptr);
8409 R.StartParameter = SelIdents.size();
8410 R.AllParametersAreInformative = false;
8411 R.DeclaringEntity = true;
8412 Results.MaybeAddResult(R, CurContext);
8413 }
8414 }
8415
8416 Results.ExitScope();
8417
8418 if (!AtParameterName && !SelIdents.empty() &&
8419 SelIdents.front()->getName().startswith("init")) {
8420 for (const auto &M : PP.macros()) {
8421 if (M.first->getName() != "NS_DESIGNATED_INITIALIZER")
8422 continue;
8423 Results.EnterNewScope();
8424 CodeCompletionBuilder Builder(Results.getAllocator(),
8425 Results.getCodeCompletionTUInfo());
8426 Builder.AddTypedTextChunk(
8427 Builder.getAllocator().CopyString(M.first->getName()));
8428 Results.AddResult(CodeCompletionResult(Builder.TakeString(), CCP_Macro,
8429 CXCursor_MacroDefinition));
8430 Results.ExitScope();
8431 }
8432 }
8433
8434 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
8435 Results.data(), Results.size());
8436 }
8437
CodeCompletePreprocessorDirective(bool InConditional)8438 void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
8439 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
8440 CodeCompleter->getCodeCompletionTUInfo(),
8441 CodeCompletionContext::CCC_PreprocessorDirective);
8442 Results.EnterNewScope();
8443
8444 // #if <condition>
8445 CodeCompletionBuilder Builder(Results.getAllocator(),
8446 Results.getCodeCompletionTUInfo());
8447 Builder.AddTypedTextChunk("if");
8448 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8449 Builder.AddPlaceholderChunk("condition");
8450 Results.AddResult(Builder.TakeString());
8451
8452 // #ifdef <macro>
8453 Builder.AddTypedTextChunk("ifdef");
8454 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8455 Builder.AddPlaceholderChunk("macro");
8456 Results.AddResult(Builder.TakeString());
8457
8458 // #ifndef <macro>
8459 Builder.AddTypedTextChunk("ifndef");
8460 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8461 Builder.AddPlaceholderChunk("macro");
8462 Results.AddResult(Builder.TakeString());
8463
8464 if (InConditional) {
8465 // #elif <condition>
8466 Builder.AddTypedTextChunk("elif");
8467 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8468 Builder.AddPlaceholderChunk("condition");
8469 Results.AddResult(Builder.TakeString());
8470
8471 // #else
8472 Builder.AddTypedTextChunk("else");
8473 Results.AddResult(Builder.TakeString());
8474
8475 // #endif
8476 Builder.AddTypedTextChunk("endif");
8477 Results.AddResult(Builder.TakeString());
8478 }
8479
8480 // #include "header"
8481 Builder.AddTypedTextChunk("include");
8482 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8483 Builder.AddTextChunk("\"");
8484 Builder.AddPlaceholderChunk("header");
8485 Builder.AddTextChunk("\"");
8486 Results.AddResult(Builder.TakeString());
8487
8488 // #include <header>
8489 Builder.AddTypedTextChunk("include");
8490 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8491 Builder.AddTextChunk("<");
8492 Builder.AddPlaceholderChunk("header");
8493 Builder.AddTextChunk(">");
8494 Results.AddResult(Builder.TakeString());
8495
8496 // #define <macro>
8497 Builder.AddTypedTextChunk("define");
8498 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8499 Builder.AddPlaceholderChunk("macro");
8500 Results.AddResult(Builder.TakeString());
8501
8502 // #define <macro>(<args>)
8503 Builder.AddTypedTextChunk("define");
8504 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8505 Builder.AddPlaceholderChunk("macro");
8506 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8507 Builder.AddPlaceholderChunk("args");
8508 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8509 Results.AddResult(Builder.TakeString());
8510
8511 // #undef <macro>
8512 Builder.AddTypedTextChunk("undef");
8513 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8514 Builder.AddPlaceholderChunk("macro");
8515 Results.AddResult(Builder.TakeString());
8516
8517 // #line <number>
8518 Builder.AddTypedTextChunk("line");
8519 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8520 Builder.AddPlaceholderChunk("number");
8521 Results.AddResult(Builder.TakeString());
8522
8523 // #line <number> "filename"
8524 Builder.AddTypedTextChunk("line");
8525 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8526 Builder.AddPlaceholderChunk("number");
8527 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8528 Builder.AddTextChunk("\"");
8529 Builder.AddPlaceholderChunk("filename");
8530 Builder.AddTextChunk("\"");
8531 Results.AddResult(Builder.TakeString());
8532
8533 // #error <message>
8534 Builder.AddTypedTextChunk("error");
8535 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8536 Builder.AddPlaceholderChunk("message");
8537 Results.AddResult(Builder.TakeString());
8538
8539 // #pragma <arguments>
8540 Builder.AddTypedTextChunk("pragma");
8541 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8542 Builder.AddPlaceholderChunk("arguments");
8543 Results.AddResult(Builder.TakeString());
8544
8545 if (getLangOpts().ObjC) {
8546 // #import "header"
8547 Builder.AddTypedTextChunk("import");
8548 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8549 Builder.AddTextChunk("\"");
8550 Builder.AddPlaceholderChunk("header");
8551 Builder.AddTextChunk("\"");
8552 Results.AddResult(Builder.TakeString());
8553
8554 // #import <header>
8555 Builder.AddTypedTextChunk("import");
8556 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8557 Builder.AddTextChunk("<");
8558 Builder.AddPlaceholderChunk("header");
8559 Builder.AddTextChunk(">");
8560 Results.AddResult(Builder.TakeString());
8561 }
8562
8563 // #include_next "header"
8564 Builder.AddTypedTextChunk("include_next");
8565 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8566 Builder.AddTextChunk("\"");
8567 Builder.AddPlaceholderChunk("header");
8568 Builder.AddTextChunk("\"");
8569 Results.AddResult(Builder.TakeString());
8570
8571 // #include_next <header>
8572 Builder.AddTypedTextChunk("include_next");
8573 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8574 Builder.AddTextChunk("<");
8575 Builder.AddPlaceholderChunk("header");
8576 Builder.AddTextChunk(">");
8577 Results.AddResult(Builder.TakeString());
8578
8579 // #warning <message>
8580 Builder.AddTypedTextChunk("warning");
8581 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8582 Builder.AddPlaceholderChunk("message");
8583 Results.AddResult(Builder.TakeString());
8584
8585 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
8586 // completions for them. And __include_macros is a Clang-internal extension
8587 // that we don't want to encourage anyone to use.
8588
8589 // FIXME: we don't support #assert or #unassert, so don't suggest them.
8590 Results.ExitScope();
8591
8592 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
8593 Results.data(), Results.size());
8594 }
8595
CodeCompleteInPreprocessorConditionalExclusion(Scope * S)8596 void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
8597 CodeCompleteOrdinaryName(S, S->getFnParent() ? Sema::PCC_RecoveryInFunction
8598 : Sema::PCC_Namespace);
8599 }
8600
CodeCompletePreprocessorMacroName(bool IsDefinition)8601 void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
8602 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
8603 CodeCompleter->getCodeCompletionTUInfo(),
8604 IsDefinition ? CodeCompletionContext::CCC_MacroName
8605 : CodeCompletionContext::CCC_MacroNameUse);
8606 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
8607 // Add just the names of macros, not their arguments.
8608 CodeCompletionBuilder Builder(Results.getAllocator(),
8609 Results.getCodeCompletionTUInfo());
8610 Results.EnterNewScope();
8611 for (Preprocessor::macro_iterator M = PP.macro_begin(),
8612 MEnd = PP.macro_end();
8613 M != MEnd; ++M) {
8614 Builder.AddTypedTextChunk(
8615 Builder.getAllocator().CopyString(M->first->getName()));
8616 Results.AddResult(CodeCompletionResult(
8617 Builder.TakeString(), CCP_CodePattern, CXCursor_MacroDefinition));
8618 }
8619 Results.ExitScope();
8620 } else if (IsDefinition) {
8621 // FIXME: Can we detect when the user just wrote an include guard above?
8622 }
8623
8624 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
8625 Results.data(), Results.size());
8626 }
8627
CodeCompletePreprocessorExpression()8628 void Sema::CodeCompletePreprocessorExpression() {
8629 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
8630 CodeCompleter->getCodeCompletionTUInfo(),
8631 CodeCompletionContext::CCC_PreprocessorExpression);
8632
8633 if (!CodeCompleter || CodeCompleter->includeMacros())
8634 AddMacroResults(PP, Results,
8635 !CodeCompleter || CodeCompleter->loadExternal(), true);
8636
8637 // defined (<macro>)
8638 Results.EnterNewScope();
8639 CodeCompletionBuilder Builder(Results.getAllocator(),
8640 Results.getCodeCompletionTUInfo());
8641 Builder.AddTypedTextChunk("defined");
8642 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8643 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8644 Builder.AddPlaceholderChunk("macro");
8645 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8646 Results.AddResult(Builder.TakeString());
8647 Results.ExitScope();
8648
8649 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
8650 Results.data(), Results.size());
8651 }
8652
CodeCompletePreprocessorMacroArgument(Scope * S,IdentifierInfo * Macro,MacroInfo * MacroInfo,unsigned Argument)8653 void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
8654 IdentifierInfo *Macro,
8655 MacroInfo *MacroInfo,
8656 unsigned Argument) {
8657 // FIXME: In the future, we could provide "overload" results, much like we
8658 // do for function calls.
8659
8660 // Now just ignore this. There will be another code-completion callback
8661 // for the expanded tokens.
8662 }
8663
8664 // This handles completion inside an #include filename, e.g. #include <foo/ba
8665 // We look for the directory "foo" under each directory on the include path,
8666 // list its files, and reassemble the appropriate #include.
CodeCompleteIncludedFile(llvm::StringRef Dir,bool Angled)8667 void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) {
8668 // RelDir should use /, but unescaped \ is possible on windows!
8669 // Our completions will normalize to / for simplicity, this case is rare.
8670 std::string RelDir = llvm::sys::path::convert_to_slash(Dir);
8671 // We need the native slashes for the actual file system interactions.
8672 SmallString<128> NativeRelDir = StringRef(RelDir);
8673 llvm::sys::path::native(NativeRelDir);
8674 llvm::vfs::FileSystem &FS =
8675 getSourceManager().getFileManager().getVirtualFileSystem();
8676
8677 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
8678 CodeCompleter->getCodeCompletionTUInfo(),
8679 CodeCompletionContext::CCC_IncludedFile);
8680 llvm::DenseSet<StringRef> SeenResults; // To deduplicate results.
8681
8682 // Helper: adds one file or directory completion result.
8683 auto AddCompletion = [&](StringRef Filename, bool IsDirectory) {
8684 SmallString<64> TypedChunk = Filename;
8685 // Directory completion is up to the slash, e.g. <sys/
8686 TypedChunk.push_back(IsDirectory ? '/' : Angled ? '>' : '"');
8687 auto R = SeenResults.insert(TypedChunk);
8688 if (R.second) { // New completion
8689 const char *InternedTyped = Results.getAllocator().CopyString(TypedChunk);
8690 *R.first = InternedTyped; // Avoid dangling StringRef.
8691 CodeCompletionBuilder Builder(CodeCompleter->getAllocator(),
8692 CodeCompleter->getCodeCompletionTUInfo());
8693 Builder.AddTypedTextChunk(InternedTyped);
8694 // The result is a "Pattern", which is pretty opaque.
8695 // We may want to include the real filename to allow smart ranking.
8696 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
8697 }
8698 };
8699
8700 // Helper: scans IncludeDir for nice files, and adds results for each.
8701 auto AddFilesFromIncludeDir = [&](StringRef IncludeDir,
8702 bool IsSystem,
8703 DirectoryLookup::LookupType_t LookupType) {
8704 llvm::SmallString<128> Dir = IncludeDir;
8705 if (!NativeRelDir.empty()) {
8706 if (LookupType == DirectoryLookup::LT_Framework) {
8707 // For a framework dir, #include <Foo/Bar/> actually maps to
8708 // a path of Foo.framework/Headers/Bar/.
8709 auto Begin = llvm::sys::path::begin(NativeRelDir);
8710 auto End = llvm::sys::path::end(NativeRelDir);
8711
8712 llvm::sys::path::append(Dir, *Begin + ".framework", "Headers");
8713 llvm::sys::path::append(Dir, ++Begin, End);
8714 } else {
8715 llvm::sys::path::append(Dir, NativeRelDir);
8716 }
8717 }
8718
8719 std::error_code EC;
8720 unsigned Count = 0;
8721 for (auto It = FS.dir_begin(Dir, EC);
8722 !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
8723 if (++Count == 2500) // If we happen to hit a huge directory,
8724 break; // bail out early so we're not too slow.
8725 StringRef Filename = llvm::sys::path::filename(It->path());
8726 switch (It->type()) {
8727 case llvm::sys::fs::file_type::directory_file:
8728 // All entries in a framework directory must have a ".framework" suffix,
8729 // but the suffix does not appear in the source code's include/import.
8730 if (LookupType == DirectoryLookup::LT_Framework &&
8731 NativeRelDir.empty() && !Filename.consume_back(".framework"))
8732 break;
8733
8734 AddCompletion(Filename, /*IsDirectory=*/true);
8735 break;
8736 case llvm::sys::fs::file_type::regular_file:
8737 // Only files that really look like headers. (Except in system dirs).
8738 if (!IsSystem) {
8739 // Header extensions from Types.def, which we can't depend on here.
8740 if (!(Filename.endswith_lower(".h") ||
8741 Filename.endswith_lower(".hh") ||
8742 Filename.endswith_lower(".hpp") ||
8743 Filename.endswith_lower(".inc")))
8744 break;
8745 }
8746 AddCompletion(Filename, /*IsDirectory=*/false);
8747 break;
8748 default:
8749 break;
8750 }
8751 }
8752 };
8753
8754 // Helper: adds results relative to IncludeDir, if possible.
8755 auto AddFilesFromDirLookup = [&](const DirectoryLookup &IncludeDir,
8756 bool IsSystem) {
8757 switch (IncludeDir.getLookupType()) {
8758 case DirectoryLookup::LT_HeaderMap:
8759 // header maps are not (currently) enumerable.
8760 break;
8761 case DirectoryLookup::LT_NormalDir:
8762 AddFilesFromIncludeDir(IncludeDir.getDir()->getName(), IsSystem,
8763 DirectoryLookup::LT_NormalDir);
8764 break;
8765 case DirectoryLookup::LT_Framework:
8766 AddFilesFromIncludeDir(IncludeDir.getFrameworkDir()->getName(), IsSystem,
8767 DirectoryLookup::LT_Framework);
8768 break;
8769 }
8770 };
8771
8772 // Finally with all our helpers, we can scan the include path.
8773 // Do this in standard order so deduplication keeps the right file.
8774 // (In case we decide to add more details to the results later).
8775 const auto &S = PP.getHeaderSearchInfo();
8776 using llvm::make_range;
8777 if (!Angled) {
8778 // The current directory is on the include path for "quoted" includes.
8779 auto *CurFile = PP.getCurrentFileLexer()->getFileEntry();
8780 if (CurFile && CurFile->getDir())
8781 AddFilesFromIncludeDir(CurFile->getDir()->getName(), false,
8782 DirectoryLookup::LT_NormalDir);
8783 for (const auto &D : make_range(S.quoted_dir_begin(), S.quoted_dir_end()))
8784 AddFilesFromDirLookup(D, false);
8785 }
8786 for (const auto &D : make_range(S.angled_dir_begin(), S.angled_dir_end()))
8787 AddFilesFromDirLookup(D, false);
8788 for (const auto &D : make_range(S.system_dir_begin(), S.system_dir_end()))
8789 AddFilesFromDirLookup(D, true);
8790
8791 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
8792 Results.data(), Results.size());
8793 }
8794
CodeCompleteNaturalLanguage()8795 void Sema::CodeCompleteNaturalLanguage() {
8796 HandleCodeCompleteResults(this, CodeCompleter,
8797 CodeCompletionContext::CCC_NaturalLanguage, nullptr,
8798 0);
8799 }
8800
CodeCompleteAvailabilityPlatformName()8801 void Sema::CodeCompleteAvailabilityPlatformName() {
8802 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
8803 CodeCompleter->getCodeCompletionTUInfo(),
8804 CodeCompletionContext::CCC_Other);
8805 Results.EnterNewScope();
8806 static const char *Platforms[] = {"macOS", "iOS", "watchOS", "tvOS"};
8807 for (const char *Platform : llvm::makeArrayRef(Platforms)) {
8808 Results.AddResult(CodeCompletionResult(Platform));
8809 Results.AddResult(CodeCompletionResult(Results.getAllocator().CopyString(
8810 Twine(Platform) + "ApplicationExtension")));
8811 }
8812 Results.ExitScope();
8813 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
8814 Results.data(), Results.size());
8815 }
8816
GatherGlobalCodeCompletions(CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,SmallVectorImpl<CodeCompletionResult> & Results)8817 void Sema::GatherGlobalCodeCompletions(
8818 CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
8819 SmallVectorImpl<CodeCompletionResult> &Results) {
8820 ResultBuilder Builder(*this, Allocator, CCTUInfo,
8821 CodeCompletionContext::CCC_Recovery);
8822 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
8823 CodeCompletionDeclConsumer Consumer(Builder,
8824 Context.getTranslationUnitDecl());
8825 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
8826 Consumer,
8827 !CodeCompleter || CodeCompleter->loadExternal());
8828 }
8829
8830 if (!CodeCompleter || CodeCompleter->includeMacros())
8831 AddMacroResults(PP, Builder,
8832 !CodeCompleter || CodeCompleter->loadExternal(), true);
8833
8834 Results.clear();
8835 Results.insert(Results.end(), Builder.data(),
8836 Builder.data() + Builder.size());
8837 }
8838