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