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