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