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