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