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