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
6320QualType
6321SemaCodeCompletion::ProduceCallSignatureHelp(Expr *Fn, ArrayRef<Expr *> Args,
6322 SourceLocation OpenParLoc) {
6323 Fn = unwrapParenList(Base: Fn);
6324 if (!CodeCompleter || !Fn)
6325 return QualType();
6326
6327 // FIXME: Provide support for variadic template functions.
6328 // Ignore type-dependent call expressions entirely.
6329 if (Fn->isTypeDependent() || anyNullArguments(Args))
6330 return QualType();
6331 // In presence of dependent args we surface all possible signatures using the
6332 // non-dependent args in the prefix. Afterwards we do a post filtering to make
6333 // sure provided candidates satisfy parameter count restrictions.
6334 auto ArgsWithoutDependentTypes =
6335 Args.take_while(Pred: [](Expr *Arg) { return !Arg->isTypeDependent(); });
6336
6337 SmallVector<ResultCandidate, 8> Results;
6338
6339 Expr *NakedFn = Fn->IgnoreParenCasts();
6340 // Build an overload candidate set based on the functions we find.
6341 SourceLocation Loc = Fn->getExprLoc();
6342 OverloadCandidateSet CandidateSet(Loc,
6343 OverloadCandidateSet::CSK_CodeCompletion);
6344
6345 if (auto ULE = dyn_cast<UnresolvedLookupExpr>(Val: NakedFn)) {
6346 SemaRef.AddOverloadedCallCandidates(ULE, Args: ArgsWithoutDependentTypes,
6347 CandidateSet,
6348 /*PartialOverloading=*/true);
6349 } else if (auto UME = dyn_cast<UnresolvedMemberExpr>(Val: NakedFn)) {
6350 TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
6351 if (UME->hasExplicitTemplateArgs()) {
6352 UME->copyTemplateArgumentsInto(List&: TemplateArgsBuffer);
6353 TemplateArgs = &TemplateArgsBuffer;
6354 }
6355
6356 // Add the base as first argument (use a nullptr if the base is implicit).
6357 SmallVector<Expr *, 12> ArgExprs(
6358 1, UME->isImplicitAccess() ? nullptr : UME->getBase());
6359 ArgExprs.append(in_start: ArgsWithoutDependentTypes.begin(),
6360 in_end: ArgsWithoutDependentTypes.end());
6361 UnresolvedSet<8> Decls;
6362 Decls.append(I: UME->decls_begin(), E: UME->decls_end());
6363 const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase();
6364 SemaRef.AddFunctionCandidates(Functions: Decls, Args: ArgExprs, CandidateSet, ExplicitTemplateArgs: TemplateArgs,
6365 /*SuppressUserConversions=*/false,
6366 /*PartialOverloading=*/true,
6367 FirstArgumentIsBase);
6368 } else {
6369 FunctionDecl *FD = nullptr;
6370 if (auto *MCE = dyn_cast<MemberExpr>(Val: NakedFn))
6371 FD = dyn_cast<FunctionDecl>(Val: MCE->getMemberDecl());
6372 else if (auto *DRE = dyn_cast<DeclRefExpr>(Val: NakedFn))
6373 FD = dyn_cast<FunctionDecl>(Val: DRE->getDecl());
6374 if (FD) { // We check whether it's a resolved function declaration.
6375 if (!getLangOpts().CPlusPlus ||
6376 !FD->getType()->getAs<FunctionProtoType>())
6377 Results.push_back(Elt: ResultCandidate(FD));
6378 else
6379 SemaRef.AddOverloadCandidate(Function: FD,
6380 FoundDecl: DeclAccessPair::make(D: FD, AS: FD->getAccess()),
6381 Args: ArgsWithoutDependentTypes, CandidateSet,
6382 /*SuppressUserConversions=*/false,
6383 /*PartialOverloading=*/true);
6384
6385 } else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) {
6386 // If expression's type is CXXRecordDecl, it may overload the function
6387 // call operator, so we check if it does and add them as candidates.
6388 // A complete type is needed to lookup for member function call operators.
6389 if (SemaRef.isCompleteType(Loc, T: NakedFn->getType())) {
6390 DeclarationName OpName =
6391 getASTContext().DeclarationNames.getCXXOperatorName(Op: OO_Call);
6392 LookupResult R(SemaRef, OpName, Loc, Sema::LookupOrdinaryName);
6393 SemaRef.LookupQualifiedName(R, LookupCtx: DC);
6394 R.suppressDiagnostics();
6395 SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
6396 ArgExprs.append(in_start: ArgsWithoutDependentTypes.begin(),
6397 in_end: ArgsWithoutDependentTypes.end());
6398 SemaRef.AddFunctionCandidates(Functions: R.asUnresolvedSet(), Args: ArgExprs,
6399 CandidateSet,
6400 /*ExplicitArgs=*/ExplicitTemplateArgs: nullptr,
6401 /*SuppressUserConversions=*/false,
6402 /*PartialOverloading=*/true);
6403 }
6404 } else {
6405 // Lastly we check whether expression's type is function pointer or
6406 // function.
6407
6408 FunctionProtoTypeLoc P = Resolver.getFunctionProtoTypeLoc(Fn: NakedFn);
6409 QualType T = NakedFn->getType();
6410 if (!T->getPointeeType().isNull())
6411 T = T->getPointeeType();
6412
6413 if (auto FP = T->getAs<FunctionProtoType>()) {
6414 if (!SemaRef.TooManyArguments(NumParams: FP->getNumParams(),
6415 NumArgs: ArgsWithoutDependentTypes.size(),
6416 /*PartialOverloading=*/true) ||
6417 FP->isVariadic()) {
6418 if (P) {
6419 Results.push_back(Elt: ResultCandidate(P));
6420 } else {
6421 Results.push_back(Elt: ResultCandidate(FP));
6422 }
6423 }
6424 } else if (auto FT = T->getAs<FunctionType>())
6425 // No prototype and declaration, it may be a K & R style function.
6426 Results.push_back(Elt: ResultCandidate(FT));
6427 }
6428 }
6429 mergeCandidatesWithResults(SemaRef, Results, CandidateSet, Loc, ArgSize: Args.size());
6430 QualType ParamType = ProduceSignatureHelp(SemaRef, Candidates: Results, CurrentArg: Args.size(),
6431 OpenParLoc, /*Braced=*/false);
6432 return !CandidateSet.empty() ? ParamType : QualType();
6433}
6434
6435// Determine which param to continue aggregate initialization from after
6436// a designated initializer.
6437//
6438// Given struct S { int a,b,c,d,e; }:
6439// after `S{.b=1,` we want to suggest c to continue
6440// after `S{.b=1, 2,` we continue with d (this is legal C and ext in C++)
6441// after `S{.b=1, .a=2,` we continue with b (this is legal C and ext in C++)
6442//
6443// Possible outcomes:
6444// - we saw a designator for a field, and continue from the returned index.
6445// Only aggregate initialization is allowed.
6446// - we saw a designator, but it was complex or we couldn't find the field.
6447// Only aggregate initialization is possible, but we can't assist with it.
6448// Returns an out-of-range index.
6449// - we saw no designators, just positional arguments.
6450// Returns std::nullopt.
6451static std::optional<unsigned>
6452getNextAggregateIndexAfterDesignatedInit(const ResultCandidate &Aggregate,
6453 ArrayRef<Expr *> Args) {
6454 static constexpr unsigned Invalid = std::numeric_limits<unsigned>::max();
6455 assert(Aggregate.getKind() == ResultCandidate::CK_Aggregate);
6456
6457 // Look for designated initializers.
6458 // They're in their syntactic form, not yet resolved to fields.
6459 const IdentifierInfo *DesignatedFieldName = nullptr;
6460 unsigned ArgsAfterDesignator = 0;
6461 for (const Expr *Arg : Args) {
6462 if (const auto *DIE = dyn_cast<DesignatedInitExpr>(Val: Arg)) {
6463 if (DIE->size() == 1 && DIE->getDesignator(Idx: 0)->isFieldDesignator()) {
6464 DesignatedFieldName = DIE->getDesignator(Idx: 0)->getFieldName();
6465 ArgsAfterDesignator = 0;
6466 } else {
6467 return Invalid; // Complicated designator.
6468 }
6469 } else if (isa<DesignatedInitUpdateExpr>(Val: Arg)) {
6470 return Invalid; // Unsupported.
6471 } else {
6472 ++ArgsAfterDesignator;
6473 }
6474 }
6475 if (!DesignatedFieldName)
6476 return std::nullopt;
6477
6478 // Find the index within the class's fields.
6479 // (Probing getParamDecl() directly would be quadratic in number of fields).
6480 unsigned DesignatedIndex = 0;
6481 const FieldDecl *DesignatedField = nullptr;
6482 for (const auto *Field : Aggregate.getAggregate()->fields()) {
6483 if (Field->getIdentifier() == DesignatedFieldName) {
6484 DesignatedField = Field;
6485 break;
6486 }
6487 ++DesignatedIndex;
6488 }
6489 if (!DesignatedField)
6490 return Invalid; // Designator referred to a missing field, give up.
6491
6492 // Find the index within the aggregate (which may have leading bases).
6493 unsigned AggregateSize = Aggregate.getNumParams();
6494 while (DesignatedIndex < AggregateSize &&
6495 Aggregate.getParamDecl(N: DesignatedIndex) != DesignatedField)
6496 ++DesignatedIndex;
6497
6498 // Continue from the index after the last named field.
6499 return DesignatedIndex + ArgsAfterDesignator + 1;
6500}
6501
6502QualType SemaCodeCompletion::ProduceConstructorSignatureHelp(
6503 QualType Type, SourceLocation Loc, ArrayRef<Expr *> Args,
6504 SourceLocation OpenParLoc, bool Braced) {
6505 if (!CodeCompleter)
6506 return QualType();
6507 SmallVector<ResultCandidate, 8> Results;
6508
6509 // A complete type is needed to lookup for constructors.
6510 RecordDecl *RD =
6511 SemaRef.isCompleteType(Loc, T: Type) ? Type->getAsRecordDecl() : nullptr;
6512 if (!RD)
6513 return Type;
6514 CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(Val: RD);
6515
6516 // Consider aggregate initialization.
6517 // We don't check that types so far are correct.
6518 // We also don't handle C99/C++17 brace-elision, we assume init-list elements
6519 // are 1:1 with fields.
6520 // FIXME: it would be nice to support "unwrapping" aggregates that contain
6521 // a single subaggregate, like std::array<T, N> -> T __elements[N].
6522 if (Braced && !RD->isUnion() &&
6523 (!getLangOpts().CPlusPlus || (CRD && CRD->isAggregate()))) {
6524 ResultCandidate AggregateSig(RD);
6525 unsigned AggregateSize = AggregateSig.getNumParams();
6526
6527 if (auto NextIndex =
6528 getNextAggregateIndexAfterDesignatedInit(Aggregate: AggregateSig, Args)) {
6529 // A designator was used, only aggregate init is possible.
6530 if (*NextIndex >= AggregateSize)
6531 return Type;
6532 Results.push_back(Elt: AggregateSig);
6533 return ProduceSignatureHelp(SemaRef, Candidates: Results, CurrentArg: *NextIndex, OpenParLoc,
6534 Braced);
6535 }
6536
6537 // Describe aggregate initialization, but also constructors below.
6538 if (Args.size() < AggregateSize)
6539 Results.push_back(Elt: AggregateSig);
6540 }
6541
6542 // FIXME: Provide support for member initializers.
6543 // FIXME: Provide support for variadic template constructors.
6544
6545 if (CRD) {
6546 OverloadCandidateSet CandidateSet(Loc,
6547 OverloadCandidateSet::CSK_CodeCompletion);
6548 for (NamedDecl *C : SemaRef.LookupConstructors(Class: CRD)) {
6549 if (auto *FD = dyn_cast<FunctionDecl>(Val: C)) {
6550 // FIXME: we can't yet provide correct signature help for initializer
6551 // list constructors, so skip them entirely.
6552 if (Braced && getLangOpts().CPlusPlus &&
6553 SemaRef.isInitListConstructor(Ctor: FD))
6554 continue;
6555 SemaRef.AddOverloadCandidate(
6556 Function: FD, FoundDecl: DeclAccessPair::make(D: FD, AS: C->getAccess()), Args, CandidateSet,
6557 /*SuppressUserConversions=*/false,
6558 /*PartialOverloading=*/true,
6559 /*AllowExplicit*/ true);
6560 } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(Val: C)) {
6561 if (Braced && getLangOpts().CPlusPlus &&
6562 SemaRef.isInitListConstructor(Ctor: FTD->getTemplatedDecl()))
6563 continue;
6564
6565 SemaRef.AddTemplateOverloadCandidate(
6566 FunctionTemplate: FTD, FoundDecl: DeclAccessPair::make(D: FTD, AS: C->getAccess()),
6567 /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet,
6568 /*SuppressUserConversions=*/false,
6569 /*PartialOverloading=*/true);
6570 }
6571 }
6572 mergeCandidatesWithResults(SemaRef, Results, CandidateSet, Loc,
6573 ArgSize: Args.size());
6574 }
6575
6576 return ProduceSignatureHelp(SemaRef, Candidates: Results, CurrentArg: Args.size(), OpenParLoc,
6577 Braced);
6578}
6579
6580QualType SemaCodeCompletion::ProduceCtorInitMemberSignatureHelp(
6581 Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy,
6582 ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc,
6583 bool Braced) {
6584 if (!CodeCompleter)
6585 return QualType();
6586
6587 CXXConstructorDecl *Constructor =
6588 dyn_cast<CXXConstructorDecl>(Val: ConstructorDecl);
6589 if (!Constructor)
6590 return QualType();
6591 // FIXME: Add support for Base class constructors as well.
6592 if (ValueDecl *MemberDecl = SemaRef.tryLookupCtorInitMemberDecl(
6593 ClassDecl: Constructor->getParent(), SS, TemplateTypeTy, MemberOrBase: II))
6594 return ProduceConstructorSignatureHelp(Type: MemberDecl->getType(),
6595 Loc: MemberDecl->getLocation(), Args: ArgExprs,
6596 OpenParLoc, Braced);
6597 return QualType();
6598}
6599
6600static bool argMatchesTemplateParams(const ParsedTemplateArgument &Arg,
6601 unsigned Index,
6602 const TemplateParameterList &Params) {
6603 const NamedDecl *Param;
6604 if (Index < Params.size())
6605 Param = Params.getParam(Idx: Index);
6606 else if (Params.hasParameterPack())
6607 Param = Params.asArray().back();
6608 else
6609 return false; // too many args
6610
6611 switch (Arg.getKind()) {
6612 case ParsedTemplateArgument::Type:
6613 return llvm::isa<TemplateTypeParmDecl>(Val: Param); // constraints not checked
6614 case ParsedTemplateArgument::NonType:
6615 return llvm::isa<NonTypeTemplateParmDecl>(Val: Param); // type not checked
6616 case ParsedTemplateArgument::Template:
6617 return llvm::isa<TemplateTemplateParmDecl>(Val: Param); // signature not checked
6618 }
6619 llvm_unreachable("Unhandled switch case");
6620}
6621
6622QualType SemaCodeCompletion::ProduceTemplateArgumentSignatureHelp(
6623 TemplateTy ParsedTemplate, ArrayRef<ParsedTemplateArgument> Args,
6624 SourceLocation LAngleLoc) {
6625 if (!CodeCompleter || !ParsedTemplate)
6626 return QualType();
6627
6628 SmallVector<ResultCandidate, 8> Results;
6629 auto Consider = [&](const TemplateDecl *TD) {
6630 // Only add if the existing args are compatible with the template.
6631 bool Matches = true;
6632 for (unsigned I = 0; I < Args.size(); ++I) {
6633 if (!argMatchesTemplateParams(Arg: Args[I], Index: I, Params: *TD->getTemplateParameters())) {
6634 Matches = false;
6635 break;
6636 }
6637 }
6638 if (Matches)
6639 Results.emplace_back(Args&: TD);
6640 };
6641
6642 TemplateName Template = ParsedTemplate.get();
6643 if (const auto *TD = Template.getAsTemplateDecl()) {
6644 Consider(TD);
6645 } else if (const auto *OTS = Template.getAsOverloadedTemplate()) {
6646 for (const NamedDecl *ND : *OTS)
6647 if (const auto *TD = llvm::dyn_cast<TemplateDecl>(Val: ND))
6648 Consider(TD);
6649 }
6650 return ProduceSignatureHelp(SemaRef, Candidates: Results, CurrentArg: Args.size(), OpenParLoc: LAngleLoc,
6651 /*Braced=*/false);
6652}
6653
6654static QualType getDesignatedType(QualType BaseType, const Designation &Desig,
6655 HeuristicResolver &Resolver) {
6656 for (unsigned I = 0; I < Desig.getNumDesignators(); ++I) {
6657 if (BaseType.isNull())
6658 break;
6659 QualType NextType;
6660 const auto &D = Desig.getDesignator(Idx: I);
6661 if (D.isArrayDesignator() || D.isArrayRangeDesignator()) {
6662 if (BaseType->isArrayType())
6663 NextType = BaseType->getAsArrayTypeUnsafe()->getElementType();
6664 } else {
6665 assert(D.isFieldDesignator());
6666 auto *RD = getAsRecordDecl(BaseType, Resolver);
6667 if (RD && RD->isCompleteDefinition()) {
6668 for (const auto *Member : RD->lookup(Name: D.getFieldDecl()))
6669 if (const FieldDecl *FD = llvm::dyn_cast<FieldDecl>(Val: Member)) {
6670 NextType = FD->getType();
6671 break;
6672 }
6673 }
6674 }
6675 BaseType = NextType;
6676 }
6677 return BaseType;
6678}
6679
6680void SemaCodeCompletion::CodeCompleteDesignator(
6681 QualType BaseType, llvm::ArrayRef<Expr *> InitExprs, const Designation &D) {
6682 BaseType = getDesignatedType(BaseType, Desig: D, Resolver);
6683 if (BaseType.isNull())
6684 return;
6685 const auto *RD = getAsRecordDecl(BaseType, Resolver);
6686 if (!RD || RD->fields().empty())
6687 return;
6688
6689 CodeCompletionContext CCC(CodeCompletionContext::CCC_DotMemberAccess,
6690 BaseType);
6691 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6692 CodeCompleter->getCodeCompletionTUInfo(), CCC);
6693
6694 Results.EnterNewScope();
6695 for (const Decl *D : RD->decls()) {
6696 const FieldDecl *FD;
6697 if (auto *IFD = dyn_cast<IndirectFieldDecl>(Val: D))
6698 FD = IFD->getAnonField();
6699 else if (auto *DFD = dyn_cast<FieldDecl>(Val: D))
6700 FD = DFD;
6701 else
6702 continue;
6703
6704 // FIXME: Make use of previous designators to mark any fields before those
6705 // inaccessible, and also compute the next initializer priority.
6706 ResultBuilder::Result Result(FD, Results.getBasePriority(ND: FD));
6707 Results.AddResult(R: Result, CurContext: SemaRef.CurContext, /*Hiding=*/nullptr);
6708 }
6709 Results.ExitScope();
6710 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
6711 Context: Results.getCompletionContext(), Results: Results.data(),
6712 NumResults: Results.size());
6713}
6714
6715void SemaCodeCompletion::CodeCompleteInitializer(Scope *S, Decl *D) {
6716 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(Val: D);
6717 if (!VD) {
6718 CodeCompleteOrdinaryName(S, CompletionContext: PCC_Expression);
6719 return;
6720 }
6721
6722 CodeCompleteExpressionData Data;
6723 Data.PreferredType = VD->getType();
6724 // Ignore VD to avoid completing the variable itself, e.g. in 'int foo = ^'.
6725 Data.IgnoreDecls.push_back(Elt: VD);
6726
6727 CodeCompleteExpression(S, Data);
6728}
6729
6730void SemaCodeCompletion::CodeCompleteKeywordAfterIf(bool AfterExclaim) const {
6731 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6732 CodeCompleter->getCodeCompletionTUInfo(),
6733 CodeCompletionContext::CCC_Other);
6734 CodeCompletionBuilder Builder(Results.getAllocator(),
6735 Results.getCodeCompletionTUInfo());
6736 if (getLangOpts().CPlusPlus17) {
6737 if (!AfterExclaim) {
6738 if (Results.includeCodePatterns()) {
6739 Builder.AddTypedTextChunk(Text: "constexpr");
6740 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
6741 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
6742 Builder.AddPlaceholderChunk(Placeholder: "condition");
6743 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
6744 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
6745 Builder.AddChunk(CK: CodeCompletionString::CK_LeftBrace);
6746 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
6747 Builder.AddPlaceholderChunk(Placeholder: "statements");
6748 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
6749 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
6750 Results.AddResult(R: {Builder.TakeString()});
6751 } else {
6752 Results.AddResult(R: {"constexpr"});
6753 }
6754 }
6755 }
6756 if (getLangOpts().CPlusPlus23) {
6757 if (Results.includeCodePatterns()) {
6758 Builder.AddTypedTextChunk(Text: "consteval");
6759 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
6760 Builder.AddChunk(CK: CodeCompletionString::CK_LeftBrace);
6761 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
6762 Builder.AddPlaceholderChunk(Placeholder: "statements");
6763 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
6764 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
6765 Results.AddResult(R: {Builder.TakeString()});
6766 } else {
6767 Results.AddResult(R: {"consteval"});
6768 }
6769 }
6770
6771 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
6772 Context: Results.getCompletionContext(), Results: Results.data(),
6773 NumResults: Results.size());
6774}
6775
6776void SemaCodeCompletion::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
6777 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6778 CodeCompleter->getCodeCompletionTUInfo(),
6779 mapCodeCompletionContext(S&: SemaRef, PCC: PCC_Statement));
6780 Results.setFilter(&ResultBuilder::IsOrdinaryName);
6781 Results.EnterNewScope();
6782
6783 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6784 SemaRef.LookupVisibleDecls(S, Kind: Sema::LookupOrdinaryName, Consumer,
6785 IncludeGlobalScope: CodeCompleter->includeGlobals(),
6786 LoadExternal: CodeCompleter->loadExternal());
6787
6788 AddOrdinaryNameResults(CCC: PCC_Statement, S, SemaRef, Results);
6789
6790 // "else" block
6791 CodeCompletionBuilder Builder(Results.getAllocator(),
6792 Results.getCodeCompletionTUInfo());
6793
6794 auto AddElseBodyPattern = [&] {
6795 if (IsBracedThen) {
6796 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
6797 Builder.AddChunk(CK: CodeCompletionString::CK_LeftBrace);
6798 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
6799 Builder.AddPlaceholderChunk(Placeholder: "statements");
6800 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
6801 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
6802 } else {
6803 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
6804 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
6805 Builder.AddPlaceholderChunk(Placeholder: "statement");
6806 Builder.AddChunk(CK: CodeCompletionString::CK_SemiColon);
6807 }
6808 };
6809 Builder.AddTypedTextChunk(Text: "else");
6810 if (Results.includeCodePatterns())
6811 AddElseBodyPattern();
6812 Results.AddResult(R: Builder.TakeString());
6813
6814 // "else if" block
6815 Builder.AddTypedTextChunk(Text: "else if");
6816 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
6817 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
6818 if (getLangOpts().CPlusPlus)
6819 Builder.AddPlaceholderChunk(Placeholder: "condition");
6820 else
6821 Builder.AddPlaceholderChunk(Placeholder: "expression");
6822 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
6823 if (Results.includeCodePatterns()) {
6824 AddElseBodyPattern();
6825 }
6826 Results.AddResult(R: Builder.TakeString());
6827
6828 Results.ExitScope();
6829
6830 if (S->getFnParent())
6831 AddPrettyFunctionResults(LangOpts: getLangOpts(), Results);
6832
6833 if (CodeCompleter->includeMacros())
6834 AddMacroResults(PP&: SemaRef.PP, Results, LoadExternal: CodeCompleter->loadExternal(), IncludeUndefined: false);
6835
6836 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
6837 Context: Results.getCompletionContext(), Results: Results.data(),
6838 NumResults: Results.size());
6839}
6840
6841void SemaCodeCompletion::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
6842 bool EnteringContext,
6843 bool IsUsingDeclaration,
6844 QualType BaseType,
6845 QualType PreferredType) {
6846 if (SS.isEmpty() || !CodeCompleter)
6847 return;
6848
6849 CodeCompletionContext CC(CodeCompletionContext::CCC_Symbol, PreferredType);
6850 CC.setIsUsingDeclaration(IsUsingDeclaration);
6851 CC.setCXXScopeSpecifier(SS);
6852
6853 // We want to keep the scope specifier even if it's invalid (e.g. the scope
6854 // "a::b::" is not corresponding to any context/namespace in the AST), since
6855 // it can be useful for global code completion which have information about
6856 // contexts/symbols that are not in the AST.
6857 if (SS.isInvalid()) {
6858 // As SS is invalid, we try to collect accessible contexts from the current
6859 // scope with a dummy lookup so that the completion consumer can try to
6860 // guess what the specified scope is.
6861 ResultBuilder DummyResults(SemaRef, CodeCompleter->getAllocator(),
6862 CodeCompleter->getCodeCompletionTUInfo(), CC);
6863 if (!PreferredType.isNull())
6864 DummyResults.setPreferredType(PreferredType);
6865 if (S->getEntity()) {
6866 CodeCompletionDeclConsumer Consumer(DummyResults, S->getEntity(),
6867 BaseType);
6868 SemaRef.LookupVisibleDecls(S, Kind: Sema::LookupOrdinaryName, Consumer,
6869 /*IncludeGlobalScope=*/false,
6870 /*LoadExternal=*/false);
6871 }
6872 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
6873 Context: DummyResults.getCompletionContext(), Results: nullptr, NumResults: 0);
6874 return;
6875 }
6876 // Always pretend to enter a context to ensure that a dependent type
6877 // resolves to a dependent record.
6878 DeclContext *Ctx = SemaRef.computeDeclContext(SS, /*EnteringContext=*/true);
6879
6880 // Try to instantiate any non-dependent declaration contexts before
6881 // we look in them. Bail out if we fail.
6882 NestedNameSpecifier *NNS = SS.getScopeRep();
6883 if (NNS != nullptr && SS.isValid() && !NNS->isDependent()) {
6884 if (Ctx == nullptr || SemaRef.RequireCompleteDeclContext(SS, DC: Ctx))
6885 return;
6886 }
6887
6888 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6889 CodeCompleter->getCodeCompletionTUInfo(), CC);
6890 if (!PreferredType.isNull())
6891 Results.setPreferredType(PreferredType);
6892 Results.EnterNewScope();
6893
6894 // The "template" keyword can follow "::" in the grammar, but only
6895 // put it into the grammar if the nested-name-specifier is dependent.
6896 // FIXME: results is always empty, this appears to be dead.
6897 if (!Results.empty() && NNS && NNS->isDependent())
6898 Results.AddResult(R: "template");
6899
6900 // If the scope is a concept-constrained type parameter, infer nested
6901 // members based on the constraints.
6902 if (NNS) {
6903 if (const auto *TTPT =
6904 dyn_cast_or_null<TemplateTypeParmType>(Val: NNS->getAsType())) {
6905 for (const auto &R : ConceptInfo(*TTPT, S).members()) {
6906 if (R.Operator != ConceptInfo::Member::Colons)
6907 continue;
6908 Results.AddResult(R: CodeCompletionResult(
6909 R.render(S&: SemaRef, Alloc&: CodeCompleter->getAllocator(),
6910 Info&: CodeCompleter->getCodeCompletionTUInfo())));
6911 }
6912 }
6913 }
6914
6915 // Add calls to overridden virtual functions, if there are any.
6916 //
6917 // FIXME: This isn't wonderful, because we don't know whether we're actually
6918 // in a context that permits expressions. This is a general issue with
6919 // qualified-id completions.
6920 if (Ctx && !EnteringContext)
6921 MaybeAddOverrideCalls(S&: SemaRef, InContext: Ctx, Results);
6922 Results.ExitScope();
6923
6924 if (Ctx &&
6925 (CodeCompleter->includeNamespaceLevelDecls() || !Ctx->isFileContext())) {
6926 CodeCompletionDeclConsumer Consumer(Results, Ctx, BaseType);
6927 SemaRef.LookupVisibleDecls(Ctx, Kind: Sema::LookupOrdinaryName, Consumer,
6928 /*IncludeGlobalScope=*/true,
6929 /*IncludeDependentBases=*/true,
6930 LoadExternal: CodeCompleter->loadExternal());
6931 }
6932
6933 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
6934 Context: Results.getCompletionContext(), Results: Results.data(),
6935 NumResults: Results.size());
6936}
6937
6938void SemaCodeCompletion::CodeCompleteUsing(Scope *S) {
6939 if (!CodeCompleter)
6940 return;
6941
6942 // This can be both a using alias or using declaration, in the former we
6943 // expect a new name and a symbol in the latter case.
6944 CodeCompletionContext Context(CodeCompletionContext::CCC_SymbolOrNewName);
6945 Context.setIsUsingDeclaration(true);
6946
6947 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6948 CodeCompleter->getCodeCompletionTUInfo(), Context,
6949 &ResultBuilder::IsNestedNameSpecifier);
6950 Results.EnterNewScope();
6951
6952 // If we aren't in class scope, we could see the "namespace" keyword.
6953 if (!S->isClassScope())
6954 Results.AddResult(R: CodeCompletionResult("namespace"));
6955
6956 // After "using", we can see anything that would start a
6957 // nested-name-specifier.
6958 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6959 SemaRef.LookupVisibleDecls(S, Kind: Sema::LookupOrdinaryName, Consumer,
6960 IncludeGlobalScope: CodeCompleter->includeGlobals(),
6961 LoadExternal: CodeCompleter->loadExternal());
6962 Results.ExitScope();
6963
6964 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
6965 Context: Results.getCompletionContext(), Results: Results.data(),
6966 NumResults: Results.size());
6967}
6968
6969void SemaCodeCompletion::CodeCompleteUsingDirective(Scope *S) {
6970 if (!CodeCompleter)
6971 return;
6972
6973 // After "using namespace", we expect to see a namespace name or namespace
6974 // alias.
6975 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6976 CodeCompleter->getCodeCompletionTUInfo(),
6977 CodeCompletionContext::CCC_Namespace,
6978 &ResultBuilder::IsNamespaceOrAlias);
6979 Results.EnterNewScope();
6980 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6981 SemaRef.LookupVisibleDecls(S, Kind: Sema::LookupOrdinaryName, Consumer,
6982 IncludeGlobalScope: CodeCompleter->includeGlobals(),
6983 LoadExternal: CodeCompleter->loadExternal());
6984 Results.ExitScope();
6985 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
6986 Context: Results.getCompletionContext(), Results: Results.data(),
6987 NumResults: Results.size());
6988}
6989
6990void SemaCodeCompletion::CodeCompleteNamespaceDecl(Scope *S) {
6991 if (!CodeCompleter)
6992 return;
6993
6994 DeclContext *Ctx = S->getEntity();
6995 if (!S->getParent())
6996 Ctx = getASTContext().getTranslationUnitDecl();
6997
6998 bool SuppressedGlobalResults =
6999 Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Val: Ctx);
7000
7001 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7002 CodeCompleter->getCodeCompletionTUInfo(),
7003 SuppressedGlobalResults
7004 ? CodeCompletionContext::CCC_Namespace
7005 : CodeCompletionContext::CCC_Other,
7006 &ResultBuilder::IsNamespace);
7007
7008 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
7009 // We only want to see those namespaces that have already been defined
7010 // within this scope, because its likely that the user is creating an
7011 // extended namespace declaration. Keep track of the most recent
7012 // definition of each namespace.
7013 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
7014 for (DeclContext::specific_decl_iterator<NamespaceDecl>
7015 NS(Ctx->decls_begin()),
7016 NSEnd(Ctx->decls_end());
7017 NS != NSEnd; ++NS)
7018 OrigToLatest[NS->getFirstDecl()] = *NS;
7019
7020 // Add the most recent definition (or extended definition) of each
7021 // namespace to the list of results.
7022 Results.EnterNewScope();
7023 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
7024 NS = OrigToLatest.begin(),
7025 NSEnd = OrigToLatest.end();
7026 NS != NSEnd; ++NS)
7027 Results.AddResult(
7028 R: CodeCompletionResult(NS->second, Results.getBasePriority(ND: NS->second),
7029 nullptr),
7030 CurContext: SemaRef.CurContext, Hiding: nullptr, InBaseClass: false);
7031 Results.ExitScope();
7032 }
7033
7034 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7035 Context: Results.getCompletionContext(), Results: Results.data(),
7036 NumResults: Results.size());
7037}
7038
7039void SemaCodeCompletion::CodeCompleteNamespaceAliasDecl(Scope *S) {
7040 if (!CodeCompleter)
7041 return;
7042
7043 // After "namespace", we expect to see a namespace or alias.
7044 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7045 CodeCompleter->getCodeCompletionTUInfo(),
7046 CodeCompletionContext::CCC_Namespace,
7047 &ResultBuilder::IsNamespaceOrAlias);
7048 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
7049 SemaRef.LookupVisibleDecls(S, Kind: Sema::LookupOrdinaryName, Consumer,
7050 IncludeGlobalScope: CodeCompleter->includeGlobals(),
7051 LoadExternal: CodeCompleter->loadExternal());
7052 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7053 Context: Results.getCompletionContext(), Results: Results.data(),
7054 NumResults: Results.size());
7055}
7056
7057void SemaCodeCompletion::CodeCompleteOperatorName(Scope *S) {
7058 if (!CodeCompleter)
7059 return;
7060
7061 typedef CodeCompletionResult Result;
7062 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7063 CodeCompleter->getCodeCompletionTUInfo(),
7064 CodeCompletionContext::CCC_Type,
7065 &ResultBuilder::IsType);
7066 Results.EnterNewScope();
7067
7068 // Add the names of overloadable operators. Note that OO_Conditional is not
7069 // actually overloadable.
7070#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
7071 if (OO_##Name != OO_Conditional) \
7072 Results.AddResult(Result(Spelling));
7073#include "clang/Basic/OperatorKinds.def"
7074
7075 // Add any type names visible from the current scope
7076 Results.allowNestedNameSpecifiers();
7077 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
7078 SemaRef.LookupVisibleDecls(S, Kind: Sema::LookupOrdinaryName, Consumer,
7079 IncludeGlobalScope: CodeCompleter->includeGlobals(),
7080 LoadExternal: CodeCompleter->loadExternal());
7081
7082 // Add any type specifiers
7083 AddTypeSpecifierResults(LangOpts: getLangOpts(), Results);
7084 Results.ExitScope();
7085
7086 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7087 Context: Results.getCompletionContext(), Results: Results.data(),
7088 NumResults: Results.size());
7089}
7090
7091void SemaCodeCompletion::CodeCompleteConstructorInitializer(
7092 Decl *ConstructorD, ArrayRef<CXXCtorInitializer *> Initializers) {
7093 if (!ConstructorD)
7094 return;
7095
7096 SemaRef.AdjustDeclIfTemplate(Decl&: ConstructorD);
7097
7098 auto *Constructor = dyn_cast<CXXConstructorDecl>(Val: ConstructorD);
7099 if (!Constructor)
7100 return;
7101
7102 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7103 CodeCompleter->getCodeCompletionTUInfo(),
7104 CodeCompletionContext::CCC_Symbol);
7105 Results.EnterNewScope();
7106
7107 // Fill in any already-initialized fields or base classes.
7108 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
7109 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
7110 for (unsigned I = 0, E = Initializers.size(); I != E; ++I) {
7111 if (Initializers[I]->isBaseInitializer())
7112 InitializedBases.insert(Ptr: getASTContext().getCanonicalType(
7113 T: QualType(Initializers[I]->getBaseClass(), 0)));
7114 else
7115 InitializedFields.insert(
7116 Ptr: cast<FieldDecl>(Val: Initializers[I]->getAnyMember()));
7117 }
7118
7119 // Add completions for base classes.
7120 PrintingPolicy Policy = getCompletionPrintingPolicy(S&: SemaRef);
7121 bool SawLastInitializer = Initializers.empty();
7122 CXXRecordDecl *ClassDecl = Constructor->getParent();
7123
7124 auto GenerateCCS = [&](const NamedDecl *ND, const char *Name) {
7125 CodeCompletionBuilder Builder(Results.getAllocator(),
7126 Results.getCodeCompletionTUInfo());
7127 Builder.AddTypedTextChunk(Text: Name);
7128 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
7129 if (const auto *Function = dyn_cast<FunctionDecl>(Val: ND))
7130 AddFunctionParameterChunks(PP&: SemaRef.PP, Policy, Function, Result&: Builder);
7131 else if (const auto *FunTemplDecl = dyn_cast<FunctionTemplateDecl>(Val: ND))
7132 AddFunctionParameterChunks(PP&: SemaRef.PP, Policy,
7133 Function: FunTemplDecl->getTemplatedDecl(), Result&: Builder);
7134 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7135 return Builder.TakeString();
7136 };
7137 auto AddDefaultCtorInit = [&](const char *Name, const char *Type,
7138 const NamedDecl *ND) {
7139 CodeCompletionBuilder Builder(Results.getAllocator(),
7140 Results.getCodeCompletionTUInfo());
7141 Builder.AddTypedTextChunk(Text: Name);
7142 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
7143 Builder.AddPlaceholderChunk(Placeholder: Type);
7144 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7145 if (ND) {
7146 auto CCR = CodeCompletionResult(
7147 Builder.TakeString(), ND,
7148 SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration);
7149 if (isa<FieldDecl>(Val: ND))
7150 CCR.CursorKind = CXCursor_MemberRef;
7151 return Results.AddResult(R: CCR);
7152 }
7153 return Results.AddResult(R: CodeCompletionResult(
7154 Builder.TakeString(),
7155 SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration));
7156 };
7157 auto AddCtorsWithName = [&](const CXXRecordDecl *RD, unsigned int Priority,
7158 const char *Name, const FieldDecl *FD) {
7159 if (!RD)
7160 return AddDefaultCtorInit(Name,
7161 FD ? Results.getAllocator().CopyString(
7162 String: FD->getType().getAsString(Policy))
7163 : Name,
7164 FD);
7165 auto Ctors = getConstructors(Context&: getASTContext(), Record: RD);
7166 if (Ctors.begin() == Ctors.end())
7167 return AddDefaultCtorInit(Name, Name, RD);
7168 for (const NamedDecl *Ctor : Ctors) {
7169 auto CCR = CodeCompletionResult(GenerateCCS(Ctor, Name), RD, Priority);
7170 CCR.CursorKind = getCursorKindForDecl(D: Ctor);
7171 Results.AddResult(R: CCR);
7172 }
7173 };
7174 auto AddBase = [&](const CXXBaseSpecifier &Base) {
7175 const char *BaseName =
7176 Results.getAllocator().CopyString(String: Base.getType().getAsString(Policy));
7177 const auto *RD = Base.getType()->getAsCXXRecordDecl();
7178 AddCtorsWithName(
7179 RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration,
7180 BaseName, nullptr);
7181 };
7182 auto AddField = [&](const FieldDecl *FD) {
7183 const char *FieldName =
7184 Results.getAllocator().CopyString(String: FD->getIdentifier()->getName());
7185 const CXXRecordDecl *RD = FD->getType()->getAsCXXRecordDecl();
7186 AddCtorsWithName(
7187 RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration,
7188 FieldName, FD);
7189 };
7190
7191 for (const auto &Base : ClassDecl->bases()) {
7192 if (!InitializedBases
7193 .insert(Ptr: getASTContext().getCanonicalType(T: Base.getType()))
7194 .second) {
7195 SawLastInitializer =
7196 !Initializers.empty() && Initializers.back()->isBaseInitializer() &&
7197 getASTContext().hasSameUnqualifiedType(
7198 T1: Base.getType(), T2: QualType(Initializers.back()->getBaseClass(), 0));
7199 continue;
7200 }
7201
7202 AddBase(Base);
7203 SawLastInitializer = false;
7204 }
7205
7206 // Add completions for virtual base classes.
7207 for (const auto &Base : ClassDecl->vbases()) {
7208 if (!InitializedBases
7209 .insert(Ptr: getASTContext().getCanonicalType(T: Base.getType()))
7210 .second) {
7211 SawLastInitializer =
7212 !Initializers.empty() && Initializers.back()->isBaseInitializer() &&
7213 getASTContext().hasSameUnqualifiedType(
7214 T1: Base.getType(), T2: QualType(Initializers.back()->getBaseClass(), 0));
7215 continue;
7216 }
7217
7218 AddBase(Base);
7219 SawLastInitializer = false;
7220 }
7221
7222 // Add completions for members.
7223 for (auto *Field : ClassDecl->fields()) {
7224 if (!InitializedFields.insert(Ptr: cast<FieldDecl>(Val: Field->getCanonicalDecl()))
7225 .second) {
7226 SawLastInitializer = !Initializers.empty() &&
7227 Initializers.back()->isAnyMemberInitializer() &&
7228 Initializers.back()->getAnyMember() == Field;
7229 continue;
7230 }
7231
7232 if (!Field->getDeclName())
7233 continue;
7234
7235 AddField(Field);
7236 SawLastInitializer = false;
7237 }
7238 Results.ExitScope();
7239
7240 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7241 Context: Results.getCompletionContext(), Results: Results.data(),
7242 NumResults: Results.size());
7243}
7244
7245/// Determine whether this scope denotes a namespace.
7246static bool isNamespaceScope(Scope *S) {
7247 DeclContext *DC = S->getEntity();
7248 if (!DC)
7249 return false;
7250
7251 return DC->isFileContext();
7252}
7253
7254void SemaCodeCompletion::CodeCompleteLambdaIntroducer(Scope *S,
7255 LambdaIntroducer &Intro,
7256 bool AfterAmpersand) {
7257 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7258 CodeCompleter->getCodeCompletionTUInfo(),
7259 CodeCompletionContext::CCC_Other);
7260 Results.EnterNewScope();
7261
7262 // Note what has already been captured.
7263 llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
7264 bool IncludedThis = false;
7265 for (const auto &C : Intro.Captures) {
7266 if (C.Kind == LCK_This) {
7267 IncludedThis = true;
7268 continue;
7269 }
7270
7271 Known.insert(Ptr: C.Id);
7272 }
7273
7274 // Look for other capturable variables.
7275 for (; S && !isNamespaceScope(S); S = S->getParent()) {
7276 for (const auto *D : S->decls()) {
7277 const auto *Var = dyn_cast<VarDecl>(Val: D);
7278 if (!Var || !Var->hasLocalStorage() || Var->hasAttr<BlocksAttr>())
7279 continue;
7280
7281 if (Known.insert(Ptr: Var->getIdentifier()).second)
7282 Results.AddResult(R: CodeCompletionResult(Var, CCP_LocalDeclaration),
7283 CurContext: SemaRef.CurContext, Hiding: nullptr, InBaseClass: false);
7284 }
7285 }
7286
7287 // Add 'this', if it would be valid.
7288 if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
7289 addThisCompletion(S&: SemaRef, Results);
7290
7291 Results.ExitScope();
7292
7293 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7294 Context: Results.getCompletionContext(), Results: Results.data(),
7295 NumResults: Results.size());
7296}
7297
7298void SemaCodeCompletion::CodeCompleteAfterFunctionEquals(Declarator &D) {
7299 if (!getLangOpts().CPlusPlus11)
7300 return;
7301 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7302 CodeCompleter->getCodeCompletionTUInfo(),
7303 CodeCompletionContext::CCC_Other);
7304 auto ShouldAddDefault = [&D, this]() {
7305 if (!D.isFunctionDeclarator())
7306 return false;
7307 auto &Id = D.getName();
7308 if (Id.getKind() == UnqualifiedIdKind::IK_DestructorName)
7309 return true;
7310 // FIXME(liuhui): Ideally, we should check the constructor parameter list to
7311 // verify that it is the default, copy or move constructor?
7312 if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName &&
7313 D.getFunctionTypeInfo().NumParams <= 1)
7314 return true;
7315 if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId) {
7316 auto Op = Id.OperatorFunctionId.Operator;
7317 // FIXME(liuhui): Ideally, we should check the function parameter list to
7318 // verify that it is the copy or move assignment?
7319 if (Op == OverloadedOperatorKind::OO_Equal)
7320 return true;
7321 if (getLangOpts().CPlusPlus20 &&
7322 (Op == OverloadedOperatorKind::OO_EqualEqual ||
7323 Op == OverloadedOperatorKind::OO_ExclaimEqual ||
7324 Op == OverloadedOperatorKind::OO_Less ||
7325 Op == OverloadedOperatorKind::OO_LessEqual ||
7326 Op == OverloadedOperatorKind::OO_Greater ||
7327 Op == OverloadedOperatorKind::OO_GreaterEqual ||
7328 Op == OverloadedOperatorKind::OO_Spaceship))
7329 return true;
7330 }
7331 return false;
7332 };
7333
7334 Results.EnterNewScope();
7335 if (ShouldAddDefault())
7336 Results.AddResult(R: "default");
7337 // FIXME(liuhui): Ideally, we should only provide `delete` completion for the
7338 // first function declaration.
7339 Results.AddResult(R: "delete");
7340 Results.ExitScope();
7341 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7342 Context: Results.getCompletionContext(), Results: Results.data(),
7343 NumResults: Results.size());
7344}
7345
7346/// Macro that optionally prepends an "@" to the string literal passed in via
7347/// Keyword, depending on whether NeedAt is true or false.
7348#define OBJC_AT_KEYWORD_NAME(NeedAt, Keyword) ((NeedAt) ? "@" Keyword : Keyword)
7349
7350static void AddObjCImplementationResults(const LangOptions &LangOpts,
7351 ResultBuilder &Results, bool NeedAt) {
7352 typedef CodeCompletionResult Result;
7353 // Since we have an implementation, we can end it.
7354 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end")));
7355
7356 CodeCompletionBuilder Builder(Results.getAllocator(),
7357 Results.getCodeCompletionTUInfo());
7358 if (LangOpts.ObjC) {
7359 // @dynamic
7360 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "dynamic"));
7361 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7362 Builder.AddPlaceholderChunk(Placeholder: "property");
7363 Results.AddResult(R: Result(Builder.TakeString()));
7364
7365 // @synthesize
7366 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synthesize"));
7367 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7368 Builder.AddPlaceholderChunk(Placeholder: "property");
7369 Results.AddResult(R: Result(Builder.TakeString()));
7370 }
7371}
7372
7373static void AddObjCInterfaceResults(const LangOptions &LangOpts,
7374 ResultBuilder &Results, bool NeedAt) {
7375 typedef CodeCompletionResult Result;
7376
7377 // Since we have an interface or protocol, we can end it.
7378 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end")));
7379
7380 if (LangOpts.ObjC) {
7381 // @property
7382 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "property")));
7383
7384 // @required
7385 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "required")));
7386
7387 // @optional
7388 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "optional")));
7389 }
7390}
7391
7392static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
7393 typedef CodeCompletionResult Result;
7394 CodeCompletionBuilder Builder(Results.getAllocator(),
7395 Results.getCodeCompletionTUInfo());
7396
7397 // @class name ;
7398 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "class"));
7399 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7400 Builder.AddPlaceholderChunk(Placeholder: "name");
7401 Results.AddResult(R: Result(Builder.TakeString()));
7402
7403 if (Results.includeCodePatterns()) {
7404 // @interface name
7405 // FIXME: Could introduce the whole pattern, including superclasses and
7406 // such.
7407 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "interface"));
7408 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7409 Builder.AddPlaceholderChunk(Placeholder: "class");
7410 Results.AddResult(R: Result(Builder.TakeString()));
7411
7412 // @protocol name
7413 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol"));
7414 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7415 Builder.AddPlaceholderChunk(Placeholder: "protocol");
7416 Results.AddResult(R: Result(Builder.TakeString()));
7417
7418 // @implementation name
7419 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "implementation"));
7420 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7421 Builder.AddPlaceholderChunk(Placeholder: "class");
7422 Results.AddResult(R: Result(Builder.TakeString()));
7423 }
7424
7425 // @compatibility_alias name
7426 Builder.AddTypedTextChunk(
7427 OBJC_AT_KEYWORD_NAME(NeedAt, "compatibility_alias"));
7428 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7429 Builder.AddPlaceholderChunk(Placeholder: "alias");
7430 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7431 Builder.AddPlaceholderChunk(Placeholder: "class");
7432 Results.AddResult(R: Result(Builder.TakeString()));
7433
7434 if (Results.getSema().getLangOpts().Modules) {
7435 // @import name
7436 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "import"));
7437 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7438 Builder.AddPlaceholderChunk(Placeholder: "module");
7439 Results.AddResult(R: Result(Builder.TakeString()));
7440 }
7441}
7442
7443void SemaCodeCompletion::CodeCompleteObjCAtDirective(Scope *S) {
7444 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7445 CodeCompleter->getCodeCompletionTUInfo(),
7446 CodeCompletionContext::CCC_Other);
7447 Results.EnterNewScope();
7448 if (isa<ObjCImplDecl>(Val: SemaRef.CurContext))
7449 AddObjCImplementationResults(LangOpts: getLangOpts(), Results, NeedAt: false);
7450 else if (SemaRef.CurContext->isObjCContainer())
7451 AddObjCInterfaceResults(LangOpts: getLangOpts(), Results, NeedAt: false);
7452 else
7453 AddObjCTopLevelResults(Results, NeedAt: false);
7454 Results.ExitScope();
7455 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7456 Context: Results.getCompletionContext(), Results: Results.data(),
7457 NumResults: Results.size());
7458}
7459
7460static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
7461 typedef CodeCompletionResult Result;
7462 CodeCompletionBuilder Builder(Results.getAllocator(),
7463 Results.getCodeCompletionTUInfo());
7464
7465 // @encode ( type-name )
7466 const char *EncodeType = "char[]";
7467 if (Results.getSema().getLangOpts().CPlusPlus ||
7468 Results.getSema().getLangOpts().ConstStrings)
7469 EncodeType = "const char[]";
7470 Builder.AddResultTypeChunk(ResultType: EncodeType);
7471 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "encode"));
7472 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
7473 Builder.AddPlaceholderChunk(Placeholder: "type-name");
7474 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7475 Results.AddResult(R: Result(Builder.TakeString()));
7476
7477 // @protocol ( protocol-name )
7478 Builder.AddResultTypeChunk(ResultType: "Protocol *");
7479 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol"));
7480 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
7481 Builder.AddPlaceholderChunk(Placeholder: "protocol-name");
7482 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7483 Results.AddResult(R: Result(Builder.TakeString()));
7484
7485 // @selector ( selector )
7486 Builder.AddResultTypeChunk(ResultType: "SEL");
7487 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "selector"));
7488 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
7489 Builder.AddPlaceholderChunk(Placeholder: "selector");
7490 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7491 Results.AddResult(R: Result(Builder.TakeString()));
7492
7493 // @"string"
7494 Builder.AddResultTypeChunk(ResultType: "NSString *");
7495 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "\""));
7496 Builder.AddPlaceholderChunk(Placeholder: "string");
7497 Builder.AddTextChunk(Text: "\"");
7498 Results.AddResult(R: Result(Builder.TakeString()));
7499
7500 // @[objects, ...]
7501 Builder.AddResultTypeChunk(ResultType: "NSArray *");
7502 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "["));
7503 Builder.AddPlaceholderChunk(Placeholder: "objects, ...");
7504 Builder.AddChunk(CK: CodeCompletionString::CK_RightBracket);
7505 Results.AddResult(R: Result(Builder.TakeString()));
7506
7507 // @{key : object, ...}
7508 Builder.AddResultTypeChunk(ResultType: "NSDictionary *");
7509 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "{"));
7510 Builder.AddPlaceholderChunk(Placeholder: "key");
7511 Builder.AddChunk(CK: CodeCompletionString::CK_Colon);
7512 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7513 Builder.AddPlaceholderChunk(Placeholder: "object, ...");
7514 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
7515 Results.AddResult(R: Result(Builder.TakeString()));
7516
7517 // @(expression)
7518 Builder.AddResultTypeChunk(ResultType: "id");
7519 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "("));
7520 Builder.AddPlaceholderChunk(Placeholder: "expression");
7521 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7522 Results.AddResult(R: Result(Builder.TakeString()));
7523}
7524
7525static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
7526 typedef CodeCompletionResult Result;
7527 CodeCompletionBuilder Builder(Results.getAllocator(),
7528 Results.getCodeCompletionTUInfo());
7529
7530 if (Results.includeCodePatterns()) {
7531 // @try { statements } @catch ( declaration ) { statements } @finally
7532 // { statements }
7533 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "try"));
7534 Builder.AddChunk(CK: CodeCompletionString::CK_LeftBrace);
7535 Builder.AddPlaceholderChunk(Placeholder: "statements");
7536 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
7537 Builder.AddTextChunk(Text: "@catch");
7538 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
7539 Builder.AddPlaceholderChunk(Placeholder: "parameter");
7540 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7541 Builder.AddChunk(CK: CodeCompletionString::CK_LeftBrace);
7542 Builder.AddPlaceholderChunk(Placeholder: "statements");
7543 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
7544 Builder.AddTextChunk(Text: "@finally");
7545 Builder.AddChunk(CK: CodeCompletionString::CK_LeftBrace);
7546 Builder.AddPlaceholderChunk(Placeholder: "statements");
7547 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
7548 Results.AddResult(R: Result(Builder.TakeString()));
7549 }
7550
7551 // @throw
7552 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "throw"));
7553 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7554 Builder.AddPlaceholderChunk(Placeholder: "expression");
7555 Results.AddResult(R: Result(Builder.TakeString()));
7556
7557 if (Results.includeCodePatterns()) {
7558 // @synchronized ( expression ) { statements }
7559 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synchronized"));
7560 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
7561 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
7562 Builder.AddPlaceholderChunk(Placeholder: "expression");
7563 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7564 Builder.AddChunk(CK: CodeCompletionString::CK_LeftBrace);
7565 Builder.AddPlaceholderChunk(Placeholder: "statements");
7566 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
7567 Results.AddResult(R: Result(Builder.TakeString()));
7568 }
7569}
7570
7571static void AddObjCVisibilityResults(const LangOptions &LangOpts,
7572 ResultBuilder &Results, bool NeedAt) {
7573 typedef CodeCompletionResult Result;
7574 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "private")));
7575 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "protected")));
7576 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "public")));
7577 if (LangOpts.ObjC)
7578 Results.AddResult(R: Result(OBJC_AT_KEYWORD_NAME(NeedAt, "package")));
7579}
7580
7581void SemaCodeCompletion::CodeCompleteObjCAtVisibility(Scope *S) {
7582 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7583 CodeCompleter->getCodeCompletionTUInfo(),
7584 CodeCompletionContext::CCC_Other);
7585 Results.EnterNewScope();
7586 AddObjCVisibilityResults(LangOpts: getLangOpts(), Results, NeedAt: false);
7587 Results.ExitScope();
7588 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7589 Context: Results.getCompletionContext(), Results: Results.data(),
7590 NumResults: Results.size());
7591}
7592
7593void SemaCodeCompletion::CodeCompleteObjCAtStatement(Scope *S) {
7594 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7595 CodeCompleter->getCodeCompletionTUInfo(),
7596 CodeCompletionContext::CCC_Other);
7597 Results.EnterNewScope();
7598 AddObjCStatementResults(Results, NeedAt: false);
7599 AddObjCExpressionResults(Results, NeedAt: false);
7600 Results.ExitScope();
7601 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7602 Context: Results.getCompletionContext(), Results: Results.data(),
7603 NumResults: Results.size());
7604}
7605
7606void SemaCodeCompletion::CodeCompleteObjCAtExpression(Scope *S) {
7607 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7608 CodeCompleter->getCodeCompletionTUInfo(),
7609 CodeCompletionContext::CCC_Other);
7610 Results.EnterNewScope();
7611 AddObjCExpressionResults(Results, NeedAt: false);
7612 Results.ExitScope();
7613 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7614 Context: Results.getCompletionContext(), Results: Results.data(),
7615 NumResults: Results.size());
7616}
7617
7618/// Determine whether the addition of the given flag to an Objective-C
7619/// property's attributes will cause a conflict.
7620static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
7621 // Check if we've already added this flag.
7622 if (Attributes & NewFlag)
7623 return true;
7624
7625 Attributes |= NewFlag;
7626
7627 // Check for collisions with "readonly".
7628 if ((Attributes & ObjCPropertyAttribute::kind_readonly) &&
7629 (Attributes & ObjCPropertyAttribute::kind_readwrite))
7630 return true;
7631
7632 // Check for more than one of { assign, copy, retain, strong, weak }.
7633 unsigned AssignCopyRetMask =
7634 Attributes &
7635 (ObjCPropertyAttribute::kind_assign |
7636 ObjCPropertyAttribute::kind_unsafe_unretained |
7637 ObjCPropertyAttribute::kind_copy | ObjCPropertyAttribute::kind_retain |
7638 ObjCPropertyAttribute::kind_strong | ObjCPropertyAttribute::kind_weak);
7639 if (AssignCopyRetMask &&
7640 AssignCopyRetMask != ObjCPropertyAttribute::kind_assign &&
7641 AssignCopyRetMask != ObjCPropertyAttribute::kind_unsafe_unretained &&
7642 AssignCopyRetMask != ObjCPropertyAttribute::kind_copy &&
7643 AssignCopyRetMask != ObjCPropertyAttribute::kind_retain &&
7644 AssignCopyRetMask != ObjCPropertyAttribute::kind_strong &&
7645 AssignCopyRetMask != ObjCPropertyAttribute::kind_weak)
7646 return true;
7647
7648 return false;
7649}
7650
7651void SemaCodeCompletion::CodeCompleteObjCPropertyFlags(Scope *S,
7652 ObjCDeclSpec &ODS) {
7653 if (!CodeCompleter)
7654 return;
7655
7656 unsigned Attributes = ODS.getPropertyAttributes();
7657
7658 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7659 CodeCompleter->getCodeCompletionTUInfo(),
7660 CodeCompletionContext::CCC_Other);
7661 Results.EnterNewScope();
7662 if (!ObjCPropertyFlagConflicts(Attributes,
7663 NewFlag: ObjCPropertyAttribute::kind_readonly))
7664 Results.AddResult(R: CodeCompletionResult("readonly"));
7665 if (!ObjCPropertyFlagConflicts(Attributes,
7666 NewFlag: ObjCPropertyAttribute::kind_assign))
7667 Results.AddResult(R: CodeCompletionResult("assign"));
7668 if (!ObjCPropertyFlagConflicts(Attributes,
7669 NewFlag: ObjCPropertyAttribute::kind_unsafe_unretained))
7670 Results.AddResult(R: CodeCompletionResult("unsafe_unretained"));
7671 if (!ObjCPropertyFlagConflicts(Attributes,
7672 NewFlag: ObjCPropertyAttribute::kind_readwrite))
7673 Results.AddResult(R: CodeCompletionResult("readwrite"));
7674 if (!ObjCPropertyFlagConflicts(Attributes,
7675 NewFlag: ObjCPropertyAttribute::kind_retain))
7676 Results.AddResult(R: CodeCompletionResult("retain"));
7677 if (!ObjCPropertyFlagConflicts(Attributes,
7678 NewFlag: ObjCPropertyAttribute::kind_strong))
7679 Results.AddResult(R: CodeCompletionResult("strong"));
7680 if (!ObjCPropertyFlagConflicts(Attributes, NewFlag: ObjCPropertyAttribute::kind_copy))
7681 Results.AddResult(R: CodeCompletionResult("copy"));
7682 if (!ObjCPropertyFlagConflicts(Attributes,
7683 NewFlag: ObjCPropertyAttribute::kind_nonatomic))
7684 Results.AddResult(R: CodeCompletionResult("nonatomic"));
7685 if (!ObjCPropertyFlagConflicts(Attributes,
7686 NewFlag: ObjCPropertyAttribute::kind_atomic))
7687 Results.AddResult(R: CodeCompletionResult("atomic"));
7688
7689 // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
7690 if (getLangOpts().ObjCWeak || getLangOpts().getGC() != LangOptions::NonGC)
7691 if (!ObjCPropertyFlagConflicts(Attributes,
7692 NewFlag: ObjCPropertyAttribute::kind_weak))
7693 Results.AddResult(R: CodeCompletionResult("weak"));
7694
7695 if (!ObjCPropertyFlagConflicts(Attributes,
7696 NewFlag: ObjCPropertyAttribute::kind_setter)) {
7697 CodeCompletionBuilder Setter(Results.getAllocator(),
7698 Results.getCodeCompletionTUInfo());
7699 Setter.AddTypedTextChunk(Text: "setter");
7700 Setter.AddTextChunk(Text: "=");
7701 Setter.AddPlaceholderChunk(Placeholder: "method");
7702 Results.AddResult(R: CodeCompletionResult(Setter.TakeString()));
7703 }
7704 if (!ObjCPropertyFlagConflicts(Attributes,
7705 NewFlag: ObjCPropertyAttribute::kind_getter)) {
7706 CodeCompletionBuilder Getter(Results.getAllocator(),
7707 Results.getCodeCompletionTUInfo());
7708 Getter.AddTypedTextChunk(Text: "getter");
7709 Getter.AddTextChunk(Text: "=");
7710 Getter.AddPlaceholderChunk(Placeholder: "method");
7711 Results.AddResult(R: CodeCompletionResult(Getter.TakeString()));
7712 }
7713 if (!ObjCPropertyFlagConflicts(Attributes,
7714 NewFlag: ObjCPropertyAttribute::kind_nullability)) {
7715 Results.AddResult(R: CodeCompletionResult("nonnull"));
7716 Results.AddResult(R: CodeCompletionResult("nullable"));
7717 Results.AddResult(R: CodeCompletionResult("null_unspecified"));
7718 Results.AddResult(R: CodeCompletionResult("null_resettable"));
7719 }
7720 Results.ExitScope();
7721 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7722 Context: Results.getCompletionContext(), Results: Results.data(),
7723 NumResults: Results.size());
7724}
7725
7726/// Describes the kind of Objective-C method that we want to find
7727/// via code completion.
7728enum ObjCMethodKind {
7729 MK_Any, ///< Any kind of method, provided it means other specified criteria.
7730 MK_ZeroArgSelector, ///< Zero-argument (unary) selector.
7731 MK_OneArgSelector ///< One-argument selector.
7732};
7733
7734static bool isAcceptableObjCSelector(Selector Sel, ObjCMethodKind WantKind,
7735 ArrayRef<const IdentifierInfo *> SelIdents,
7736 bool AllowSameLength = true) {
7737 unsigned NumSelIdents = SelIdents.size();
7738 if (NumSelIdents > Sel.getNumArgs())
7739 return false;
7740
7741 switch (WantKind) {
7742 case MK_Any:
7743 break;
7744 case MK_ZeroArgSelector:
7745 return Sel.isUnarySelector();
7746 case MK_OneArgSelector:
7747 return Sel.getNumArgs() == 1;
7748 }
7749
7750 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
7751 return false;
7752
7753 for (unsigned I = 0; I != NumSelIdents; ++I)
7754 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(argIndex: I))
7755 return false;
7756
7757 return true;
7758}
7759
7760static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
7761 ObjCMethodKind WantKind,
7762 ArrayRef<const IdentifierInfo *> SelIdents,
7763 bool AllowSameLength = true) {
7764 return isAcceptableObjCSelector(Sel: Method->getSelector(), WantKind, SelIdents,
7765 AllowSameLength);
7766}
7767
7768/// A set of selectors, which is used to avoid introducing multiple
7769/// completions with the same selector into the result set.
7770typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
7771
7772/// Add all of the Objective-C methods in the given Objective-C
7773/// container to the set of results.
7774///
7775/// The container will be a class, protocol, category, or implementation of
7776/// any of the above. This mether will recurse to include methods from
7777/// the superclasses of classes along with their categories, protocols, and
7778/// implementations.
7779///
7780/// \param Container the container in which we'll look to find methods.
7781///
7782/// \param WantInstanceMethods Whether to add instance methods (only); if
7783/// false, this routine will add factory methods (only).
7784///
7785/// \param CurContext the context in which we're performing the lookup that
7786/// finds methods.
7787///
7788/// \param AllowSameLength Whether we allow a method to be added to the list
7789/// when it has the same number of parameters as we have selector identifiers.
7790///
7791/// \param Results the structure into which we'll add results.
7792static void AddObjCMethods(ObjCContainerDecl *Container,
7793 bool WantInstanceMethods, ObjCMethodKind WantKind,
7794 ArrayRef<const IdentifierInfo *> SelIdents,
7795 DeclContext *CurContext,
7796 VisitedSelectorSet &Selectors, bool AllowSameLength,
7797 ResultBuilder &Results, bool InOriginalClass = true,
7798 bool IsRootClass = false) {
7799 typedef CodeCompletionResult Result;
7800 Container = getContainerDef(Container);
7801 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Val: Container);
7802 IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass());
7803 for (ObjCMethodDecl *M : Container->methods()) {
7804 // The instance methods on the root class can be messaged via the
7805 // metaclass.
7806 if (M->isInstanceMethod() == WantInstanceMethods ||
7807 (IsRootClass && !WantInstanceMethods)) {
7808 // Check whether the selector identifiers we've been given are a
7809 // subset of the identifiers for this particular method.
7810 if (!isAcceptableObjCMethod(Method: M, WantKind, SelIdents, AllowSameLength))
7811 continue;
7812
7813 if (!Selectors.insert(Ptr: M->getSelector()).second)
7814 continue;
7815
7816 Result R = Result(M, Results.getBasePriority(ND: M), nullptr);
7817 R.StartParameter = SelIdents.size();
7818 R.AllParametersAreInformative = (WantKind != MK_Any);
7819 if (!InOriginalClass)
7820 setInBaseClass(R);
7821 Results.MaybeAddResult(R, CurContext);
7822 }
7823 }
7824
7825 // Visit the protocols of protocols.
7826 if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Val: Container)) {
7827 if (Protocol->hasDefinition()) {
7828 const ObjCList<ObjCProtocolDecl> &Protocols =
7829 Protocol->getReferencedProtocols();
7830 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
7831 E = Protocols.end();
7832 I != E; ++I)
7833 AddObjCMethods(Container: *I, WantInstanceMethods, WantKind, SelIdents, CurContext,
7834 Selectors, AllowSameLength, Results, InOriginalClass: false, IsRootClass);
7835 }
7836 }
7837
7838 if (!IFace || !IFace->hasDefinition())
7839 return;
7840
7841 // Add methods in protocols.
7842 for (ObjCProtocolDecl *I : IFace->protocols())
7843 AddObjCMethods(Container: I, WantInstanceMethods, WantKind, SelIdents, CurContext,
7844 Selectors, AllowSameLength, Results, InOriginalClass: false, IsRootClass);
7845
7846 // Add methods in categories.
7847 for (ObjCCategoryDecl *CatDecl : IFace->known_categories()) {
7848 AddObjCMethods(Container: CatDecl, WantInstanceMethods, WantKind, SelIdents,
7849 CurContext, Selectors, AllowSameLength, Results,
7850 InOriginalClass, IsRootClass);
7851
7852 // Add a categories protocol methods.
7853 const ObjCList<ObjCProtocolDecl> &Protocols =
7854 CatDecl->getReferencedProtocols();
7855 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
7856 E = Protocols.end();
7857 I != E; ++I)
7858 AddObjCMethods(Container: *I, WantInstanceMethods, WantKind, SelIdents, CurContext,
7859 Selectors, AllowSameLength, Results, InOriginalClass: false, IsRootClass);
7860
7861 // Add methods in category implementations.
7862 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
7863 AddObjCMethods(Container: Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
7864 Selectors, AllowSameLength, Results, InOriginalClass,
7865 IsRootClass);
7866 }
7867
7868 // Add methods in superclass.
7869 // Avoid passing in IsRootClass since root classes won't have super classes.
7870 if (IFace->getSuperClass())
7871 AddObjCMethods(Container: IFace->getSuperClass(), WantInstanceMethods, WantKind,
7872 SelIdents, CurContext, Selectors, AllowSameLength, Results,
7873 /*IsRootClass=*/InOriginalClass: false);
7874
7875 // Add methods in our implementation, if any.
7876 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
7877 AddObjCMethods(Container: Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
7878 Selectors, AllowSameLength, Results, InOriginalClass,
7879 IsRootClass);
7880}
7881
7882void SemaCodeCompletion::CodeCompleteObjCPropertyGetter(Scope *S) {
7883 // Try to find the interface where getters might live.
7884 ObjCInterfaceDecl *Class =
7885 dyn_cast_or_null<ObjCInterfaceDecl>(Val: SemaRef.CurContext);
7886 if (!Class) {
7887 if (ObjCCategoryDecl *Category =
7888 dyn_cast_or_null<ObjCCategoryDecl>(Val: SemaRef.CurContext))
7889 Class = Category->getClassInterface();
7890
7891 if (!Class)
7892 return;
7893 }
7894
7895 // Find all of the potential getters.
7896 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7897 CodeCompleter->getCodeCompletionTUInfo(),
7898 CodeCompletionContext::CCC_Other);
7899 Results.EnterNewScope();
7900
7901 VisitedSelectorSet Selectors;
7902 AddObjCMethods(Container: Class, WantInstanceMethods: true, WantKind: MK_ZeroArgSelector, SelIdents: {}, CurContext: SemaRef.CurContext,
7903 Selectors,
7904 /*AllowSameLength=*/true, Results);
7905 Results.ExitScope();
7906 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7907 Context: Results.getCompletionContext(), Results: Results.data(),
7908 NumResults: Results.size());
7909}
7910
7911void SemaCodeCompletion::CodeCompleteObjCPropertySetter(Scope *S) {
7912 // Try to find the interface where setters might live.
7913 ObjCInterfaceDecl *Class =
7914 dyn_cast_or_null<ObjCInterfaceDecl>(Val: SemaRef.CurContext);
7915 if (!Class) {
7916 if (ObjCCategoryDecl *Category =
7917 dyn_cast_or_null<ObjCCategoryDecl>(Val: SemaRef.CurContext))
7918 Class = Category->getClassInterface();
7919
7920 if (!Class)
7921 return;
7922 }
7923
7924 // Find all of the potential getters.
7925 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7926 CodeCompleter->getCodeCompletionTUInfo(),
7927 CodeCompletionContext::CCC_Other);
7928 Results.EnterNewScope();
7929
7930 VisitedSelectorSet Selectors;
7931 AddObjCMethods(Container: Class, WantInstanceMethods: true, WantKind: MK_OneArgSelector, SelIdents: {}, CurContext: SemaRef.CurContext,
7932 Selectors,
7933 /*AllowSameLength=*/true, Results);
7934
7935 Results.ExitScope();
7936 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
7937 Context: Results.getCompletionContext(), Results: Results.data(),
7938 NumResults: Results.size());
7939}
7940
7941void SemaCodeCompletion::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
7942 bool IsParameter) {
7943 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7944 CodeCompleter->getCodeCompletionTUInfo(),
7945 CodeCompletionContext::CCC_Type);
7946 Results.EnterNewScope();
7947
7948 // Add context-sensitive, Objective-C parameter-passing keywords.
7949 bool AddedInOut = false;
7950 if ((DS.getObjCDeclQualifier() &
7951 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
7952 Results.AddResult(R: "in");
7953 Results.AddResult(R: "inout");
7954 AddedInOut = true;
7955 }
7956 if ((DS.getObjCDeclQualifier() &
7957 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
7958 Results.AddResult(R: "out");
7959 if (!AddedInOut)
7960 Results.AddResult(R: "inout");
7961 }
7962 if ((DS.getObjCDeclQualifier() &
7963 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
7964 ObjCDeclSpec::DQ_Oneway)) == 0) {
7965 Results.AddResult(R: "bycopy");
7966 Results.AddResult(R: "byref");
7967 Results.AddResult(R: "oneway");
7968 }
7969 if ((DS.getObjCDeclQualifier() & ObjCDeclSpec::DQ_CSNullability) == 0) {
7970 Results.AddResult(R: "nonnull");
7971 Results.AddResult(R: "nullable");
7972 Results.AddResult(R: "null_unspecified");
7973 }
7974
7975 // If we're completing the return type of an Objective-C method and the
7976 // identifier IBAction refers to a macro, provide a completion item for
7977 // an action, e.g.,
7978 // IBAction)<#selector#>:(id)sender
7979 if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
7980 SemaRef.PP.isMacroDefined(Id: "IBAction")) {
7981 CodeCompletionBuilder Builder(Results.getAllocator(),
7982 Results.getCodeCompletionTUInfo(),
7983 CCP_CodePattern, CXAvailability_Available);
7984 Builder.AddTypedTextChunk(Text: "IBAction");
7985 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7986 Builder.AddPlaceholderChunk(Placeholder: "selector");
7987 Builder.AddChunk(CK: CodeCompletionString::CK_Colon);
7988 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
7989 Builder.AddTextChunk(Text: "id");
7990 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
7991 Builder.AddTextChunk(Text: "sender");
7992 Results.AddResult(R: CodeCompletionResult(Builder.TakeString()));
7993 }
7994
7995 // If we're completing the return type, provide 'instancetype'.
7996 if (!IsParameter) {
7997 Results.AddResult(R: CodeCompletionResult("instancetype"));
7998 }
7999
8000 // Add various builtin type names and specifiers.
8001 AddOrdinaryNameResults(CCC: PCC_Type, S, SemaRef, Results);
8002 Results.ExitScope();
8003
8004 // Add the various type names
8005 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
8006 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
8007 SemaRef.LookupVisibleDecls(S, Kind: Sema::LookupOrdinaryName, Consumer,
8008 IncludeGlobalScope: CodeCompleter->includeGlobals(),
8009 LoadExternal: CodeCompleter->loadExternal());
8010
8011 if (CodeCompleter->includeMacros())
8012 AddMacroResults(PP&: SemaRef.PP, Results, LoadExternal: CodeCompleter->loadExternal(), IncludeUndefined: false);
8013
8014 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8015 Context: Results.getCompletionContext(), Results: Results.data(),
8016 NumResults: Results.size());
8017}
8018
8019/// When we have an expression with type "id", we may assume
8020/// that it has some more-specific class type based on knowledge of
8021/// common uses of Objective-C. This routine returns that class type,
8022/// or NULL if no better result could be determined.
8023static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
8024 auto *Msg = dyn_cast_or_null<ObjCMessageExpr>(Val: E);
8025 if (!Msg)
8026 return nullptr;
8027
8028 Selector Sel = Msg->getSelector();
8029 if (Sel.isNull())
8030 return nullptr;
8031
8032 const IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(argIndex: 0);
8033 if (!Id)
8034 return nullptr;
8035
8036 ObjCMethodDecl *Method = Msg->getMethodDecl();
8037 if (!Method)
8038 return nullptr;
8039
8040 // Determine the class that we're sending the message to.
8041 ObjCInterfaceDecl *IFace = nullptr;
8042 switch (Msg->getReceiverKind()) {
8043 case ObjCMessageExpr::Class:
8044 if (const ObjCObjectType *ObjType =
8045 Msg->getClassReceiver()->getAs<ObjCObjectType>())
8046 IFace = ObjType->getInterface();
8047 break;
8048
8049 case ObjCMessageExpr::Instance: {
8050 QualType T = Msg->getInstanceReceiver()->getType();
8051 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
8052 IFace = Ptr->getInterfaceDecl();
8053 break;
8054 }
8055
8056 case ObjCMessageExpr::SuperInstance:
8057 case ObjCMessageExpr::SuperClass:
8058 break;
8059 }
8060
8061 if (!IFace)
8062 return nullptr;
8063
8064 ObjCInterfaceDecl *Super = IFace->getSuperClass();
8065 if (Method->isInstanceMethod())
8066 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
8067 .Case(S: "retain", Value: IFace)
8068 .Case(S: "strong", Value: IFace)
8069 .Case(S: "autorelease", Value: IFace)
8070 .Case(S: "copy", Value: IFace)
8071 .Case(S: "copyWithZone", Value: IFace)
8072 .Case(S: "mutableCopy", Value: IFace)
8073 .Case(S: "mutableCopyWithZone", Value: IFace)
8074 .Case(S: "awakeFromCoder", Value: IFace)
8075 .Case(S: "replacementObjectFromCoder", Value: IFace)
8076 .Case(S: "class", Value: IFace)
8077 .Case(S: "classForCoder", Value: IFace)
8078 .Case(S: "superclass", Value: Super)
8079 .Default(Value: nullptr);
8080
8081 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
8082 .Case(S: "new", Value: IFace)
8083 .Case(S: "alloc", Value: IFace)
8084 .Case(S: "allocWithZone", Value: IFace)
8085 .Case(S: "class", Value: IFace)
8086 .Case(S: "superclass", Value: Super)
8087 .Default(Value: nullptr);
8088}
8089
8090// Add a special completion for a message send to "super", which fills in the
8091// most likely case of forwarding all of our arguments to the superclass
8092// function.
8093///
8094/// \param S The semantic analysis object.
8095///
8096/// \param NeedSuperKeyword Whether we need to prefix this completion with
8097/// the "super" keyword. Otherwise, we just need to provide the arguments.
8098///
8099/// \param SelIdents The identifiers in the selector that have already been
8100/// provided as arguments for a send to "super".
8101///
8102/// \param Results The set of results to augment.
8103///
8104/// \returns the Objective-C method declaration that would be invoked by
8105/// this "super" completion. If NULL, no completion was added.
8106static ObjCMethodDecl *
8107AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
8108 ArrayRef<const IdentifierInfo *> SelIdents,
8109 ResultBuilder &Results) {
8110 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
8111 if (!CurMethod)
8112 return nullptr;
8113
8114 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
8115 if (!Class)
8116 return nullptr;
8117
8118 // Try to find a superclass method with the same selector.
8119 ObjCMethodDecl *SuperMethod = nullptr;
8120 while ((Class = Class->getSuperClass()) && !SuperMethod) {
8121 // Check in the class
8122 SuperMethod = Class->getMethod(Sel: CurMethod->getSelector(),
8123 isInstance: CurMethod->isInstanceMethod());
8124
8125 // Check in categories or class extensions.
8126 if (!SuperMethod) {
8127 for (const auto *Cat : Class->known_categories()) {
8128 if ((SuperMethod = Cat->getMethod(Sel: CurMethod->getSelector(),
8129 isInstance: CurMethod->isInstanceMethod())))
8130 break;
8131 }
8132 }
8133 }
8134
8135 if (!SuperMethod)
8136 return nullptr;
8137
8138 // Check whether the superclass method has the same signature.
8139 if (CurMethod->param_size() != SuperMethod->param_size() ||
8140 CurMethod->isVariadic() != SuperMethod->isVariadic())
8141 return nullptr;
8142
8143 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
8144 CurPEnd = CurMethod->param_end(),
8145 SuperP = SuperMethod->param_begin();
8146 CurP != CurPEnd; ++CurP, ++SuperP) {
8147 // Make sure the parameter types are compatible.
8148 if (!S.Context.hasSameUnqualifiedType(T1: (*CurP)->getType(),
8149 T2: (*SuperP)->getType()))
8150 return nullptr;
8151
8152 // Make sure we have a parameter name to forward!
8153 if (!(*CurP)->getIdentifier())
8154 return nullptr;
8155 }
8156
8157 // We have a superclass method. Now, form the send-to-super completion.
8158 CodeCompletionBuilder Builder(Results.getAllocator(),
8159 Results.getCodeCompletionTUInfo());
8160
8161 // Give this completion a return type.
8162 AddResultTypeChunk(Context&: S.Context, Policy: getCompletionPrintingPolicy(S), ND: SuperMethod,
8163 BaseType: Results.getCompletionContext().getBaseType(), Result&: Builder);
8164
8165 // If we need the "super" keyword, add it (plus some spacing).
8166 if (NeedSuperKeyword) {
8167 Builder.AddTypedTextChunk(Text: "super");
8168 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
8169 }
8170
8171 Selector Sel = CurMethod->getSelector();
8172 if (Sel.isUnarySelector()) {
8173 if (NeedSuperKeyword)
8174 Builder.AddTextChunk(
8175 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: 0)));
8176 else
8177 Builder.AddTypedTextChunk(
8178 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: 0)));
8179 } else {
8180 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
8181 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
8182 if (I > SelIdents.size())
8183 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
8184
8185 if (I < SelIdents.size())
8186 Builder.AddInformativeChunk(
8187 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: I) + ":"));
8188 else if (NeedSuperKeyword || I > SelIdents.size()) {
8189 Builder.AddTextChunk(
8190 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: I) + ":"));
8191 Builder.AddPlaceholderChunk(Placeholder: Builder.getAllocator().CopyString(
8192 String: (*CurP)->getIdentifier()->getName()));
8193 } else {
8194 Builder.AddTypedTextChunk(
8195 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: I) + ":"));
8196 Builder.AddPlaceholderChunk(Placeholder: Builder.getAllocator().CopyString(
8197 String: (*CurP)->getIdentifier()->getName()));
8198 }
8199 }
8200 }
8201
8202 Results.AddResult(R: CodeCompletionResult(Builder.TakeString(), SuperMethod,
8203 CCP_SuperCompletion));
8204 return SuperMethod;
8205}
8206
8207void SemaCodeCompletion::CodeCompleteObjCMessageReceiver(Scope *S) {
8208 typedef CodeCompletionResult Result;
8209 ResultBuilder Results(
8210 SemaRef, CodeCompleter->getAllocator(),
8211 CodeCompleter->getCodeCompletionTUInfo(),
8212 CodeCompletionContext::CCC_ObjCMessageReceiver,
8213 getLangOpts().CPlusPlus11
8214 ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
8215 : &ResultBuilder::IsObjCMessageReceiver);
8216
8217 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
8218 Results.EnterNewScope();
8219 SemaRef.LookupVisibleDecls(S, Kind: Sema::LookupOrdinaryName, Consumer,
8220 IncludeGlobalScope: CodeCompleter->includeGlobals(),
8221 LoadExternal: CodeCompleter->loadExternal());
8222
8223 // If we are in an Objective-C method inside a class that has a superclass,
8224 // add "super" as an option.
8225 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
8226 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
8227 if (Iface->getSuperClass()) {
8228 Results.AddResult(R: Result("super"));
8229
8230 AddSuperSendCompletion(S&: SemaRef, /*NeedSuperKeyword=*/true, SelIdents: {}, Results);
8231 }
8232
8233 if (getLangOpts().CPlusPlus11)
8234 addThisCompletion(S&: SemaRef, Results);
8235
8236 Results.ExitScope();
8237
8238 if (CodeCompleter->includeMacros())
8239 AddMacroResults(PP&: SemaRef.PP, Results, LoadExternal: CodeCompleter->loadExternal(), IncludeUndefined: false);
8240 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8241 Context: Results.getCompletionContext(), Results: Results.data(),
8242 NumResults: Results.size());
8243}
8244
8245void SemaCodeCompletion::CodeCompleteObjCSuperMessage(
8246 Scope *S, SourceLocation SuperLoc,
8247 ArrayRef<const IdentifierInfo *> SelIdents, bool AtArgumentExpression) {
8248 ObjCInterfaceDecl *CDecl = nullptr;
8249 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl()) {
8250 // Figure out which interface we're in.
8251 CDecl = CurMethod->getClassInterface();
8252 if (!CDecl)
8253 return;
8254
8255 // Find the superclass of this class.
8256 CDecl = CDecl->getSuperClass();
8257 if (!CDecl)
8258 return;
8259
8260 if (CurMethod->isInstanceMethod()) {
8261 // We are inside an instance method, which means that the message
8262 // send [super ...] is actually calling an instance method on the
8263 // current object.
8264 return CodeCompleteObjCInstanceMessage(S, Receiver: nullptr, SelIdents,
8265 AtArgumentExpression, Super: CDecl);
8266 }
8267
8268 // Fall through to send to the superclass in CDecl.
8269 } else {
8270 // "super" may be the name of a type or variable. Figure out which
8271 // it is.
8272 const IdentifierInfo *Super = SemaRef.getSuperIdentifier();
8273 NamedDecl *ND =
8274 SemaRef.LookupSingleName(S, Name: Super, Loc: SuperLoc, NameKind: Sema::LookupOrdinaryName);
8275 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(Val: ND))) {
8276 // "super" names an interface. Use it.
8277 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(Val: ND)) {
8278 if (const ObjCObjectType *Iface =
8279 getASTContext().getTypeDeclType(Decl: TD)->getAs<ObjCObjectType>())
8280 CDecl = Iface->getInterface();
8281 } else if (ND && isa<UnresolvedUsingTypenameDecl>(Val: ND)) {
8282 // "super" names an unresolved type; we can't be more specific.
8283 } else {
8284 // Assume that "super" names some kind of value and parse that way.
8285 CXXScopeSpec SS;
8286 SourceLocation TemplateKWLoc;
8287 UnqualifiedId id;
8288 id.setIdentifier(Id: Super, IdLoc: SuperLoc);
8289 ExprResult SuperExpr =
8290 SemaRef.ActOnIdExpression(S, SS, TemplateKWLoc, Id&: id,
8291 /*HasTrailingLParen=*/false,
8292 /*IsAddressOfOperand=*/false);
8293 return CodeCompleteObjCInstanceMessage(S, Receiver: (Expr *)SuperExpr.get(),
8294 SelIdents, AtArgumentExpression);
8295 }
8296
8297 // Fall through
8298 }
8299
8300 ParsedType Receiver;
8301 if (CDecl)
8302 Receiver = ParsedType::make(P: getASTContext().getObjCInterfaceType(Decl: CDecl));
8303 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
8304 AtArgumentExpression,
8305 /*IsSuper=*/true);
8306}
8307
8308/// Given a set of code-completion results for the argument of a message
8309/// send, determine the preferred type (if any) for that argument expression.
8310static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
8311 unsigned NumSelIdents) {
8312 typedef CodeCompletionResult Result;
8313 ASTContext &Context = Results.getSema().Context;
8314
8315 QualType PreferredType;
8316 unsigned BestPriority = CCP_Unlikely * 2;
8317 Result *ResultsData = Results.data();
8318 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
8319 Result &R = ResultsData[I];
8320 if (R.Kind == Result::RK_Declaration &&
8321 isa<ObjCMethodDecl>(Val: R.Declaration)) {
8322 if (R.Priority <= BestPriority) {
8323 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(Val: R.Declaration);
8324 if (NumSelIdents <= Method->param_size()) {
8325 QualType MyPreferredType =
8326 Method->parameters()[NumSelIdents - 1]->getType();
8327 if (R.Priority < BestPriority || PreferredType.isNull()) {
8328 BestPriority = R.Priority;
8329 PreferredType = MyPreferredType;
8330 } else if (!Context.hasSameUnqualifiedType(T1: PreferredType,
8331 T2: MyPreferredType)) {
8332 PreferredType = QualType();
8333 }
8334 }
8335 }
8336 }
8337 }
8338
8339 return PreferredType;
8340}
8341
8342static void
8343AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver,
8344 ArrayRef<const IdentifierInfo *> SelIdents,
8345 bool AtArgumentExpression, bool IsSuper,
8346 ResultBuilder &Results) {
8347 typedef CodeCompletionResult Result;
8348 ObjCInterfaceDecl *CDecl = nullptr;
8349
8350 // If the given name refers to an interface type, retrieve the
8351 // corresponding declaration.
8352 if (Receiver) {
8353 QualType T = SemaRef.GetTypeFromParser(Ty: Receiver, TInfo: nullptr);
8354 if (!T.isNull())
8355 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
8356 CDecl = Interface->getInterface();
8357 }
8358
8359 // Add all of the factory methods in this Objective-C class, its protocols,
8360 // superclasses, categories, implementation, etc.
8361 Results.EnterNewScope();
8362
8363 // If this is a send-to-super, try to add the special "super" send
8364 // completion.
8365 if (IsSuper) {
8366 if (ObjCMethodDecl *SuperMethod =
8367 AddSuperSendCompletion(S&: SemaRef, NeedSuperKeyword: false, SelIdents, Results))
8368 Results.Ignore(D: SuperMethod);
8369 }
8370
8371 // If we're inside an Objective-C method definition, prefer its selector to
8372 // others.
8373 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
8374 Results.setPreferredSelector(CurMethod->getSelector());
8375
8376 VisitedSelectorSet Selectors;
8377 if (CDecl)
8378 AddObjCMethods(Container: CDecl, WantInstanceMethods: false, WantKind: MK_Any, SelIdents, CurContext: SemaRef.CurContext,
8379 Selectors, AllowSameLength: AtArgumentExpression, Results);
8380 else {
8381 // We're messaging "id" as a type; provide all class/factory methods.
8382
8383 // If we have an external source, load the entire class method
8384 // pool from the AST file.
8385 if (SemaRef.getExternalSource()) {
8386 for (uint32_t I = 0,
8387 N = SemaRef.getExternalSource()->GetNumExternalSelectors();
8388 I != N; ++I) {
8389 Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(ID: I);
8390 if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Val: Sel))
8391 continue;
8392
8393 SemaRef.ObjC().ReadMethodPool(Sel);
8394 }
8395 }
8396
8397 for (SemaObjC::GlobalMethodPool::iterator
8398 M = SemaRef.ObjC().MethodPool.begin(),
8399 MEnd = SemaRef.ObjC().MethodPool.end();
8400 M != MEnd; ++M) {
8401 for (ObjCMethodList *MethList = &M->second.second;
8402 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
8403 if (!isAcceptableObjCMethod(Method: MethList->getMethod(), WantKind: MK_Any, SelIdents))
8404 continue;
8405
8406 Result R(MethList->getMethod(),
8407 Results.getBasePriority(ND: MethList->getMethod()), nullptr);
8408 R.StartParameter = SelIdents.size();
8409 R.AllParametersAreInformative = false;
8410 Results.MaybeAddResult(R, CurContext: SemaRef.CurContext);
8411 }
8412 }
8413 }
8414
8415 Results.ExitScope();
8416}
8417
8418void SemaCodeCompletion::CodeCompleteObjCClassMessage(
8419 Scope *S, ParsedType Receiver, ArrayRef<const IdentifierInfo *> SelIdents,
8420 bool AtArgumentExpression, bool IsSuper) {
8421
8422 QualType T = SemaRef.GetTypeFromParser(Ty: Receiver);
8423
8424 ResultBuilder Results(
8425 SemaRef, CodeCompleter->getAllocator(),
8426 CodeCompleter->getCodeCompletionTUInfo(),
8427 CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage, T,
8428 SelIdents));
8429
8430 AddClassMessageCompletions(SemaRef, S, Receiver, SelIdents,
8431 AtArgumentExpression, IsSuper, Results);
8432
8433 // If we're actually at the argument expression (rather than prior to the
8434 // selector), we're actually performing code completion for an expression.
8435 // Determine whether we have a single, best method. If so, we can
8436 // code-complete the expression using the corresponding parameter type as
8437 // our preferred type, improving completion results.
8438 if (AtArgumentExpression) {
8439 QualType PreferredType =
8440 getPreferredArgumentTypeForMessageSend(Results, NumSelIdents: SelIdents.size());
8441 if (PreferredType.isNull())
8442 CodeCompleteOrdinaryName(S, CompletionContext: PCC_Expression);
8443 else
8444 CodeCompleteExpression(S, PreferredType);
8445 return;
8446 }
8447
8448 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8449 Context: Results.getCompletionContext(), Results: Results.data(),
8450 NumResults: Results.size());
8451}
8452
8453void SemaCodeCompletion::CodeCompleteObjCInstanceMessage(
8454 Scope *S, Expr *RecExpr, ArrayRef<const IdentifierInfo *> SelIdents,
8455 bool AtArgumentExpression, ObjCInterfaceDecl *Super) {
8456 typedef CodeCompletionResult Result;
8457 ASTContext &Context = getASTContext();
8458
8459 // If necessary, apply function/array conversion to the receiver.
8460 // C99 6.7.5.3p[7,8].
8461 if (RecExpr) {
8462 ExprResult Conv = SemaRef.DefaultFunctionArrayLvalueConversion(E: RecExpr);
8463 if (Conv.isInvalid()) // conversion failed. bail.
8464 return;
8465 RecExpr = Conv.get();
8466 }
8467 QualType ReceiverType = RecExpr
8468 ? RecExpr->getType()
8469 : Super ? Context.getObjCObjectPointerType(
8470 OIT: Context.getObjCInterfaceType(Decl: Super))
8471 : Context.getObjCIdType();
8472
8473 // If we're messaging an expression with type "id" or "Class", check
8474 // whether we know something special about the receiver that allows
8475 // us to assume a more-specific receiver type.
8476 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) {
8477 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(E: RecExpr)) {
8478 if (ReceiverType->isObjCClassType())
8479 return CodeCompleteObjCClassMessage(
8480 S, Receiver: ParsedType::make(P: Context.getObjCInterfaceType(Decl: IFace)), SelIdents,
8481 AtArgumentExpression, IsSuper: Super);
8482
8483 ReceiverType =
8484 Context.getObjCObjectPointerType(OIT: Context.getObjCInterfaceType(Decl: IFace));
8485 }
8486 } else if (RecExpr && getLangOpts().CPlusPlus) {
8487 ExprResult Conv = SemaRef.PerformContextuallyConvertToObjCPointer(From: RecExpr);
8488 if (Conv.isUsable()) {
8489 RecExpr = Conv.get();
8490 ReceiverType = RecExpr->getType();
8491 }
8492 }
8493
8494 // Build the set of methods we can see.
8495 ResultBuilder Results(
8496 SemaRef, CodeCompleter->getAllocator(),
8497 CodeCompleter->getCodeCompletionTUInfo(),
8498 CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
8499 ReceiverType, SelIdents));
8500
8501 Results.EnterNewScope();
8502
8503 // If this is a send-to-super, try to add the special "super" send
8504 // completion.
8505 if (Super) {
8506 if (ObjCMethodDecl *SuperMethod =
8507 AddSuperSendCompletion(S&: SemaRef, NeedSuperKeyword: false, SelIdents, Results))
8508 Results.Ignore(D: SuperMethod);
8509 }
8510
8511 // If we're inside an Objective-C method definition, prefer its selector to
8512 // others.
8513 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
8514 Results.setPreferredSelector(CurMethod->getSelector());
8515
8516 // Keep track of the selectors we've already added.
8517 VisitedSelectorSet Selectors;
8518
8519 // Handle messages to Class. This really isn't a message to an instance
8520 // method, so we treat it the same way we would treat a message send to a
8521 // class method.
8522 if (ReceiverType->isObjCClassType() ||
8523 ReceiverType->isObjCQualifiedClassType()) {
8524 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl()) {
8525 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
8526 AddObjCMethods(Container: ClassDecl, WantInstanceMethods: false, WantKind: MK_Any, SelIdents, CurContext: SemaRef.CurContext,
8527 Selectors, AllowSameLength: AtArgumentExpression, Results);
8528 }
8529 }
8530 // Handle messages to a qualified ID ("id<foo>").
8531 else if (const ObjCObjectPointerType *QualID =
8532 ReceiverType->getAsObjCQualifiedIdType()) {
8533 // Search protocols for instance methods.
8534 for (auto *I : QualID->quals())
8535 AddObjCMethods(Container: I, WantInstanceMethods: true, WantKind: MK_Any, SelIdents, CurContext: SemaRef.CurContext, Selectors,
8536 AllowSameLength: AtArgumentExpression, Results);
8537 }
8538 // Handle messages to a pointer to interface type.
8539 else if (const ObjCObjectPointerType *IFacePtr =
8540 ReceiverType->getAsObjCInterfacePointerType()) {
8541 // Search the class, its superclasses, etc., for instance methods.
8542 AddObjCMethods(Container: IFacePtr->getInterfaceDecl(), WantInstanceMethods: true, WantKind: MK_Any, SelIdents,
8543 CurContext: SemaRef.CurContext, Selectors, AllowSameLength: AtArgumentExpression,
8544 Results);
8545
8546 // Search protocols for instance methods.
8547 for (auto *I : IFacePtr->quals())
8548 AddObjCMethods(Container: I, WantInstanceMethods: true, WantKind: MK_Any, SelIdents, CurContext: SemaRef.CurContext, Selectors,
8549 AllowSameLength: AtArgumentExpression, Results);
8550 }
8551 // Handle messages to "id".
8552 else if (ReceiverType->isObjCIdType()) {
8553 // We're messaging "id", so provide all instance methods we know
8554 // about as code-completion results.
8555
8556 // If we have an external source, load the entire class method
8557 // pool from the AST file.
8558 if (SemaRef.ExternalSource) {
8559 for (uint32_t I = 0,
8560 N = SemaRef.ExternalSource->GetNumExternalSelectors();
8561 I != N; ++I) {
8562 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(ID: I);
8563 if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Val: Sel))
8564 continue;
8565
8566 SemaRef.ObjC().ReadMethodPool(Sel);
8567 }
8568 }
8569
8570 for (SemaObjC::GlobalMethodPool::iterator
8571 M = SemaRef.ObjC().MethodPool.begin(),
8572 MEnd = SemaRef.ObjC().MethodPool.end();
8573 M != MEnd; ++M) {
8574 for (ObjCMethodList *MethList = &M->second.first;
8575 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
8576 if (!isAcceptableObjCMethod(Method: MethList->getMethod(), WantKind: MK_Any, SelIdents))
8577 continue;
8578
8579 if (!Selectors.insert(Ptr: MethList->getMethod()->getSelector()).second)
8580 continue;
8581
8582 Result R(MethList->getMethod(),
8583 Results.getBasePriority(ND: MethList->getMethod()), nullptr);
8584 R.StartParameter = SelIdents.size();
8585 R.AllParametersAreInformative = false;
8586 Results.MaybeAddResult(R, CurContext: SemaRef.CurContext);
8587 }
8588 }
8589 }
8590 Results.ExitScope();
8591
8592 // If we're actually at the argument expression (rather than prior to the
8593 // selector), we're actually performing code completion for an expression.
8594 // Determine whether we have a single, best method. If so, we can
8595 // code-complete the expression using the corresponding parameter type as
8596 // our preferred type, improving completion results.
8597 if (AtArgumentExpression) {
8598 QualType PreferredType =
8599 getPreferredArgumentTypeForMessageSend(Results, NumSelIdents: SelIdents.size());
8600 if (PreferredType.isNull())
8601 CodeCompleteOrdinaryName(S, CompletionContext: PCC_Expression);
8602 else
8603 CodeCompleteExpression(S, PreferredType);
8604 return;
8605 }
8606
8607 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8608 Context: Results.getCompletionContext(), Results: Results.data(),
8609 NumResults: Results.size());
8610}
8611
8612void SemaCodeCompletion::CodeCompleteObjCForCollection(
8613 Scope *S, DeclGroupPtrTy IterationVar) {
8614 CodeCompleteExpressionData Data;
8615 Data.ObjCCollection = true;
8616
8617 if (IterationVar.getAsOpaquePtr()) {
8618 DeclGroupRef DG = IterationVar.get();
8619 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
8620 if (*I)
8621 Data.IgnoreDecls.push_back(Elt: *I);
8622 }
8623 }
8624
8625 CodeCompleteExpression(S, Data);
8626}
8627
8628void SemaCodeCompletion::CodeCompleteObjCSelector(
8629 Scope *S, ArrayRef<const IdentifierInfo *> SelIdents) {
8630 // If we have an external source, load the entire class method
8631 // pool from the AST file.
8632 if (SemaRef.ExternalSource) {
8633 for (uint32_t I = 0, N = SemaRef.ExternalSource->GetNumExternalSelectors();
8634 I != N; ++I) {
8635 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(ID: I);
8636 if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Val: Sel))
8637 continue;
8638
8639 SemaRef.ObjC().ReadMethodPool(Sel);
8640 }
8641 }
8642
8643 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8644 CodeCompleter->getCodeCompletionTUInfo(),
8645 CodeCompletionContext::CCC_SelectorName);
8646 Results.EnterNewScope();
8647 for (SemaObjC::GlobalMethodPool::iterator
8648 M = SemaRef.ObjC().MethodPool.begin(),
8649 MEnd = SemaRef.ObjC().MethodPool.end();
8650 M != MEnd; ++M) {
8651
8652 Selector Sel = M->first;
8653 if (!isAcceptableObjCSelector(Sel, WantKind: MK_Any, SelIdents))
8654 continue;
8655
8656 CodeCompletionBuilder Builder(Results.getAllocator(),
8657 Results.getCodeCompletionTUInfo());
8658 if (Sel.isUnarySelector()) {
8659 Builder.AddTypedTextChunk(
8660 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: 0)));
8661 Results.AddResult(R: Builder.TakeString());
8662 continue;
8663 }
8664
8665 std::string Accumulator;
8666 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
8667 if (I == SelIdents.size()) {
8668 if (!Accumulator.empty()) {
8669 Builder.AddInformativeChunk(
8670 Text: Builder.getAllocator().CopyString(String: Accumulator));
8671 Accumulator.clear();
8672 }
8673 }
8674
8675 Accumulator += Sel.getNameForSlot(argIndex: I);
8676 Accumulator += ':';
8677 }
8678 Builder.AddTypedTextChunk(Text: Builder.getAllocator().CopyString(String: Accumulator));
8679 Results.AddResult(R: Builder.TakeString());
8680 }
8681 Results.ExitScope();
8682
8683 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8684 Context: Results.getCompletionContext(), Results: Results.data(),
8685 NumResults: Results.size());
8686}
8687
8688/// Add all of the protocol declarations that we find in the given
8689/// (translation unit) context.
8690static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
8691 bool OnlyForwardDeclarations,
8692 ResultBuilder &Results) {
8693 typedef CodeCompletionResult Result;
8694
8695 for (const auto *D : Ctx->decls()) {
8696 // Record any protocols we find.
8697 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(Val: D))
8698 if (!OnlyForwardDeclarations || !Proto->hasDefinition())
8699 Results.AddResult(
8700 R: Result(Proto, Results.getBasePriority(ND: Proto), nullptr), CurContext,
8701 Hiding: nullptr, InBaseClass: false);
8702 }
8703}
8704
8705void SemaCodeCompletion::CodeCompleteObjCProtocolReferences(
8706 ArrayRef<IdentifierLoc> Protocols) {
8707 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8708 CodeCompleter->getCodeCompletionTUInfo(),
8709 CodeCompletionContext::CCC_ObjCProtocolName);
8710
8711 if (CodeCompleter->includeGlobals()) {
8712 Results.EnterNewScope();
8713
8714 // Tell the result set to ignore all of the protocols we have
8715 // already seen.
8716 // FIXME: This doesn't work when caching code-completion results.
8717 for (const IdentifierLoc &Pair : Protocols)
8718 if (ObjCProtocolDecl *Protocol = SemaRef.ObjC().LookupProtocol(
8719 II: Pair.getIdentifierInfo(), IdLoc: Pair.getLoc()))
8720 Results.Ignore(D: Protocol);
8721
8722 // Add all protocols.
8723 AddProtocolResults(Ctx: getASTContext().getTranslationUnitDecl(),
8724 CurContext: SemaRef.CurContext, OnlyForwardDeclarations: false, Results);
8725
8726 Results.ExitScope();
8727 }
8728
8729 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8730 Context: Results.getCompletionContext(), Results: Results.data(),
8731 NumResults: Results.size());
8732}
8733
8734void SemaCodeCompletion::CodeCompleteObjCProtocolDecl(Scope *) {
8735 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8736 CodeCompleter->getCodeCompletionTUInfo(),
8737 CodeCompletionContext::CCC_ObjCProtocolName);
8738
8739 if (CodeCompleter->includeGlobals()) {
8740 Results.EnterNewScope();
8741
8742 // Add all protocols.
8743 AddProtocolResults(Ctx: getASTContext().getTranslationUnitDecl(),
8744 CurContext: SemaRef.CurContext, OnlyForwardDeclarations: true, Results);
8745
8746 Results.ExitScope();
8747 }
8748
8749 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8750 Context: Results.getCompletionContext(), Results: Results.data(),
8751 NumResults: Results.size());
8752}
8753
8754/// Add all of the Objective-C interface declarations that we find in
8755/// the given (translation unit) context.
8756static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
8757 bool OnlyForwardDeclarations,
8758 bool OnlyUnimplemented,
8759 ResultBuilder &Results) {
8760 typedef CodeCompletionResult Result;
8761
8762 for (const auto *D : Ctx->decls()) {
8763 // Record any interfaces we find.
8764 if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(Val: D))
8765 if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
8766 (!OnlyUnimplemented || !Class->getImplementation()))
8767 Results.AddResult(
8768 R: Result(Class, Results.getBasePriority(ND: Class), nullptr), CurContext,
8769 Hiding: nullptr, InBaseClass: false);
8770 }
8771}
8772
8773void SemaCodeCompletion::CodeCompleteObjCInterfaceDecl(Scope *S) {
8774 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8775 CodeCompleter->getCodeCompletionTUInfo(),
8776 CodeCompletionContext::CCC_ObjCInterfaceName);
8777 Results.EnterNewScope();
8778
8779 if (CodeCompleter->includeGlobals()) {
8780 // Add all classes.
8781 AddInterfaceResults(Ctx: getASTContext().getTranslationUnitDecl(),
8782 CurContext: SemaRef.CurContext, OnlyForwardDeclarations: false, OnlyUnimplemented: false, Results);
8783 }
8784
8785 Results.ExitScope();
8786
8787 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8788 Context: Results.getCompletionContext(), Results: Results.data(),
8789 NumResults: Results.size());
8790}
8791
8792void SemaCodeCompletion::CodeCompleteObjCClassForwardDecl(Scope *S) {
8793 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8794 CodeCompleter->getCodeCompletionTUInfo(),
8795 CodeCompletionContext::CCC_ObjCClassForwardDecl);
8796 Results.EnterNewScope();
8797
8798 if (CodeCompleter->includeGlobals()) {
8799 // Add all classes.
8800 AddInterfaceResults(Ctx: getASTContext().getTranslationUnitDecl(),
8801 CurContext: SemaRef.CurContext, OnlyForwardDeclarations: false, OnlyUnimplemented: false, Results);
8802 }
8803
8804 Results.ExitScope();
8805
8806 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8807 Context: Results.getCompletionContext(), Results: Results.data(),
8808 NumResults: Results.size());
8809}
8810
8811void SemaCodeCompletion::CodeCompleteObjCSuperclass(
8812 Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
8813 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8814 CodeCompleter->getCodeCompletionTUInfo(),
8815 CodeCompletionContext::CCC_ObjCInterfaceName);
8816 Results.EnterNewScope();
8817
8818 // Make sure that we ignore the class we're currently defining.
8819 NamedDecl *CurClass = SemaRef.LookupSingleName(
8820 S: SemaRef.TUScope, Name: ClassName, Loc: ClassNameLoc, NameKind: Sema::LookupOrdinaryName);
8821 if (CurClass && isa<ObjCInterfaceDecl>(Val: CurClass))
8822 Results.Ignore(D: CurClass);
8823
8824 if (CodeCompleter->includeGlobals()) {
8825 // Add all classes.
8826 AddInterfaceResults(Ctx: getASTContext().getTranslationUnitDecl(),
8827 CurContext: SemaRef.CurContext, OnlyForwardDeclarations: false, OnlyUnimplemented: false, Results);
8828 }
8829
8830 Results.ExitScope();
8831
8832 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8833 Context: Results.getCompletionContext(), Results: Results.data(),
8834 NumResults: Results.size());
8835}
8836
8837void SemaCodeCompletion::CodeCompleteObjCImplementationDecl(Scope *S) {
8838 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8839 CodeCompleter->getCodeCompletionTUInfo(),
8840 CodeCompletionContext::CCC_ObjCImplementation);
8841 Results.EnterNewScope();
8842
8843 if (CodeCompleter->includeGlobals()) {
8844 // Add all unimplemented classes.
8845 AddInterfaceResults(Ctx: getASTContext().getTranslationUnitDecl(),
8846 CurContext: SemaRef.CurContext, OnlyForwardDeclarations: false, OnlyUnimplemented: true, Results);
8847 }
8848
8849 Results.ExitScope();
8850
8851 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8852 Context: Results.getCompletionContext(), Results: Results.data(),
8853 NumResults: Results.size());
8854}
8855
8856void SemaCodeCompletion::CodeCompleteObjCInterfaceCategory(
8857 Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
8858 typedef CodeCompletionResult Result;
8859
8860 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8861 CodeCompleter->getCodeCompletionTUInfo(),
8862 CodeCompletionContext::CCC_ObjCCategoryName);
8863
8864 // Ignore any categories we find that have already been implemented by this
8865 // interface.
8866 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
8867 NamedDecl *CurClass = SemaRef.LookupSingleName(
8868 S: SemaRef.TUScope, Name: ClassName, Loc: ClassNameLoc, NameKind: Sema::LookupOrdinaryName);
8869 if (ObjCInterfaceDecl *Class =
8870 dyn_cast_or_null<ObjCInterfaceDecl>(Val: CurClass)) {
8871 for (const auto *Cat : Class->visible_categories())
8872 CategoryNames.insert(Ptr: Cat->getIdentifier());
8873 }
8874
8875 // Add all of the categories we know about.
8876 Results.EnterNewScope();
8877 TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
8878 for (const auto *D : TU->decls())
8879 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Val: D))
8880 if (CategoryNames.insert(Ptr: Category->getIdentifier()).second)
8881 Results.AddResult(
8882 R: Result(Category, Results.getBasePriority(ND: Category), nullptr),
8883 CurContext: SemaRef.CurContext, Hiding: nullptr, InBaseClass: false);
8884 Results.ExitScope();
8885
8886 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8887 Context: Results.getCompletionContext(), Results: Results.data(),
8888 NumResults: Results.size());
8889}
8890
8891void SemaCodeCompletion::CodeCompleteObjCImplementationCategory(
8892 Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
8893 typedef CodeCompletionResult Result;
8894
8895 // Find the corresponding interface. If we couldn't find the interface, the
8896 // program itself is ill-formed. However, we'll try to be helpful still by
8897 // providing the list of all of the categories we know about.
8898 NamedDecl *CurClass = SemaRef.LookupSingleName(
8899 S: SemaRef.TUScope, Name: ClassName, Loc: ClassNameLoc, NameKind: Sema::LookupOrdinaryName);
8900 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(Val: CurClass);
8901 if (!Class)
8902 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
8903
8904 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8905 CodeCompleter->getCodeCompletionTUInfo(),
8906 CodeCompletionContext::CCC_ObjCCategoryName);
8907
8908 // Add all of the categories that have corresponding interface
8909 // declarations in this class and any of its superclasses, except for
8910 // already-implemented categories in the class itself.
8911 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
8912 Results.EnterNewScope();
8913 bool IgnoreImplemented = true;
8914 while (Class) {
8915 for (const auto *Cat : Class->visible_categories()) {
8916 if ((!IgnoreImplemented || !Cat->getImplementation()) &&
8917 CategoryNames.insert(Ptr: Cat->getIdentifier()).second)
8918 Results.AddResult(R: Result(Cat, Results.getBasePriority(ND: Cat), nullptr),
8919 CurContext: SemaRef.CurContext, Hiding: nullptr, InBaseClass: false);
8920 }
8921
8922 Class = Class->getSuperClass();
8923 IgnoreImplemented = false;
8924 }
8925 Results.ExitScope();
8926
8927 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8928 Context: Results.getCompletionContext(), Results: Results.data(),
8929 NumResults: Results.size());
8930}
8931
8932void SemaCodeCompletion::CodeCompleteObjCPropertyDefinition(Scope *S) {
8933 CodeCompletionContext CCContext(CodeCompletionContext::CCC_Other);
8934 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8935 CodeCompleter->getCodeCompletionTUInfo(), CCContext);
8936
8937 // Figure out where this @synthesize lives.
8938 ObjCContainerDecl *Container =
8939 dyn_cast_or_null<ObjCContainerDecl>(Val: SemaRef.CurContext);
8940 if (!Container || (!isa<ObjCImplementationDecl>(Val: Container) &&
8941 !isa<ObjCCategoryImplDecl>(Val: Container)))
8942 return;
8943
8944 // Ignore any properties that have already been implemented.
8945 Container = getContainerDef(Container);
8946 for (const auto *D : Container->decls())
8947 if (const auto *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(Val: D))
8948 Results.Ignore(D: PropertyImpl->getPropertyDecl());
8949
8950 // Add any properties that we find.
8951 AddedPropertiesSet AddedProperties;
8952 Results.EnterNewScope();
8953 if (ObjCImplementationDecl *ClassImpl =
8954 dyn_cast<ObjCImplementationDecl>(Val: Container))
8955 AddObjCProperties(CCContext, Container: ClassImpl->getClassInterface(), AllowCategories: false,
8956 /*AllowNullaryMethods=*/false, CurContext: SemaRef.CurContext,
8957 AddedProperties, Results);
8958 else
8959 AddObjCProperties(CCContext,
8960 Container: cast<ObjCCategoryImplDecl>(Val: Container)->getCategoryDecl(),
8961 AllowCategories: false, /*AllowNullaryMethods=*/false, CurContext: SemaRef.CurContext,
8962 AddedProperties, Results);
8963 Results.ExitScope();
8964
8965 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
8966 Context: Results.getCompletionContext(), Results: Results.data(),
8967 NumResults: Results.size());
8968}
8969
8970void SemaCodeCompletion::CodeCompleteObjCPropertySynthesizeIvar(
8971 Scope *S, IdentifierInfo *PropertyName) {
8972 typedef CodeCompletionResult Result;
8973 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8974 CodeCompleter->getCodeCompletionTUInfo(),
8975 CodeCompletionContext::CCC_Other);
8976
8977 // Figure out where this @synthesize lives.
8978 ObjCContainerDecl *Container =
8979 dyn_cast_or_null<ObjCContainerDecl>(Val: SemaRef.CurContext);
8980 if (!Container || (!isa<ObjCImplementationDecl>(Val: Container) &&
8981 !isa<ObjCCategoryImplDecl>(Val: Container)))
8982 return;
8983
8984 // Figure out which interface we're looking into.
8985 ObjCInterfaceDecl *Class = nullptr;
8986 if (ObjCImplementationDecl *ClassImpl =
8987 dyn_cast<ObjCImplementationDecl>(Val: Container))
8988 Class = ClassImpl->getClassInterface();
8989 else
8990 Class = cast<ObjCCategoryImplDecl>(Val: Container)
8991 ->getCategoryDecl()
8992 ->getClassInterface();
8993
8994 // Determine the type of the property we're synthesizing.
8995 QualType PropertyType = getASTContext().getObjCIdType();
8996 if (Class) {
8997 if (ObjCPropertyDecl *Property = Class->FindPropertyDeclaration(
8998 PropertyId: PropertyName, QueryKind: ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
8999 PropertyType =
9000 Property->getType().getNonReferenceType().getUnqualifiedType();
9001
9002 // Give preference to ivars
9003 Results.setPreferredType(PropertyType);
9004 }
9005 }
9006
9007 // Add all of the instance variables in this class and its superclasses.
9008 Results.EnterNewScope();
9009 bool SawSimilarlyNamedIvar = false;
9010 std::string NameWithPrefix;
9011 NameWithPrefix += '_';
9012 NameWithPrefix += PropertyName->getName();
9013 std::string NameWithSuffix = PropertyName->getName().str();
9014 NameWithSuffix += '_';
9015 for (; Class; Class = Class->getSuperClass()) {
9016 for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
9017 Ivar = Ivar->getNextIvar()) {
9018 Results.AddResult(R: Result(Ivar, Results.getBasePriority(ND: Ivar), nullptr),
9019 CurContext: SemaRef.CurContext, Hiding: nullptr, InBaseClass: false);
9020
9021 // Determine whether we've seen an ivar with a name similar to the
9022 // property.
9023 if ((PropertyName == Ivar->getIdentifier() ||
9024 NameWithPrefix == Ivar->getName() ||
9025 NameWithSuffix == Ivar->getName())) {
9026 SawSimilarlyNamedIvar = true;
9027
9028 // Reduce the priority of this result by one, to give it a slight
9029 // advantage over other results whose names don't match so closely.
9030 if (Results.size() &&
9031 Results.data()[Results.size() - 1].Kind ==
9032 CodeCompletionResult::RK_Declaration &&
9033 Results.data()[Results.size() - 1].Declaration == Ivar)
9034 Results.data()[Results.size() - 1].Priority--;
9035 }
9036 }
9037 }
9038
9039 if (!SawSimilarlyNamedIvar) {
9040 // Create ivar result _propName, that the user can use to synthesize
9041 // an ivar of the appropriate type.
9042 unsigned Priority = CCP_MemberDeclaration + 1;
9043 typedef CodeCompletionResult Result;
9044 CodeCompletionAllocator &Allocator = Results.getAllocator();
9045 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
9046 Priority, CXAvailability_Available);
9047
9048 PrintingPolicy Policy = getCompletionPrintingPolicy(S&: SemaRef);
9049 Builder.AddResultTypeChunk(ResultType: GetCompletionTypeString(
9050 T: PropertyType, Context&: getASTContext(), Policy, Allocator));
9051 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: NameWithPrefix));
9052 Results.AddResult(
9053 R: Result(Builder.TakeString(), Priority, CXCursor_ObjCIvarDecl));
9054 }
9055
9056 Results.ExitScope();
9057
9058 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
9059 Context: Results.getCompletionContext(), Results: Results.data(),
9060 NumResults: Results.size());
9061}
9062
9063// Mapping from selectors to the methods that implement that selector, along
9064// with the "in original class" flag.
9065typedef llvm::DenseMap<Selector,
9066 llvm::PointerIntPair<ObjCMethodDecl *, 1, bool>>
9067 KnownMethodsMap;
9068
9069/// Find all of the methods that reside in the given container
9070/// (and its superclasses, protocols, etc.) that meet the given
9071/// criteria. Insert those methods into the map of known methods,
9072/// indexed by selector so they can be easily found.
9073static void FindImplementableMethods(ASTContext &Context,
9074 ObjCContainerDecl *Container,
9075 std::optional<bool> WantInstanceMethods,
9076 QualType ReturnType,
9077 KnownMethodsMap &KnownMethods,
9078 bool InOriginalClass = true) {
9079 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Val: Container)) {
9080 // Make sure we have a definition; that's what we'll walk.
9081 if (!IFace->hasDefinition())
9082 return;
9083
9084 IFace = IFace->getDefinition();
9085 Container = IFace;
9086
9087 const ObjCList<ObjCProtocolDecl> &Protocols =
9088 IFace->getReferencedProtocols();
9089 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
9090 E = Protocols.end();
9091 I != E; ++I)
9092 FindImplementableMethods(Context, Container: *I, WantInstanceMethods, ReturnType,
9093 KnownMethods, InOriginalClass);
9094
9095 // Add methods from any class extensions and categories.
9096 for (auto *Cat : IFace->visible_categories()) {
9097 FindImplementableMethods(Context, Container: Cat, WantInstanceMethods, ReturnType,
9098 KnownMethods, InOriginalClass: false);
9099 }
9100
9101 // Visit the superclass.
9102 if (IFace->getSuperClass())
9103 FindImplementableMethods(Context, Container: IFace->getSuperClass(),
9104 WantInstanceMethods, ReturnType, KnownMethods,
9105 InOriginalClass: false);
9106 }
9107
9108 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Val: Container)) {
9109 // Recurse into protocols.
9110 const ObjCList<ObjCProtocolDecl> &Protocols =
9111 Category->getReferencedProtocols();
9112 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
9113 E = Protocols.end();
9114 I != E; ++I)
9115 FindImplementableMethods(Context, Container: *I, WantInstanceMethods, ReturnType,
9116 KnownMethods, InOriginalClass);
9117
9118 // If this category is the original class, jump to the interface.
9119 if (InOriginalClass && Category->getClassInterface())
9120 FindImplementableMethods(Context, Container: Category->getClassInterface(),
9121 WantInstanceMethods, ReturnType, KnownMethods,
9122 InOriginalClass: false);
9123 }
9124
9125 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Val: Container)) {
9126 // Make sure we have a definition; that's what we'll walk.
9127 if (!Protocol->hasDefinition())
9128 return;
9129 Protocol = Protocol->getDefinition();
9130 Container = Protocol;
9131
9132 // Recurse into protocols.
9133 const ObjCList<ObjCProtocolDecl> &Protocols =
9134 Protocol->getReferencedProtocols();
9135 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
9136 E = Protocols.end();
9137 I != E; ++I)
9138 FindImplementableMethods(Context, Container: *I, WantInstanceMethods, ReturnType,
9139 KnownMethods, InOriginalClass: false);
9140 }
9141
9142 // Add methods in this container. This operation occurs last because
9143 // we want the methods from this container to override any methods
9144 // we've previously seen with the same selector.
9145 for (auto *M : Container->methods()) {
9146 if (!WantInstanceMethods || M->isInstanceMethod() == *WantInstanceMethods) {
9147 if (!ReturnType.isNull() &&
9148 !Context.hasSameUnqualifiedType(T1: ReturnType, T2: M->getReturnType()))
9149 continue;
9150
9151 KnownMethods[M->getSelector()] =
9152 KnownMethodsMap::mapped_type(M, InOriginalClass);
9153 }
9154 }
9155}
9156
9157/// Add the parenthesized return or parameter type chunk to a code
9158/// completion string.
9159static void AddObjCPassingTypeChunk(QualType Type, unsigned ObjCDeclQuals,
9160 ASTContext &Context,
9161 const PrintingPolicy &Policy,
9162 CodeCompletionBuilder &Builder) {
9163 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9164 std::string Quals = formatObjCParamQualifiers(ObjCQuals: ObjCDeclQuals, Type);
9165 if (!Quals.empty())
9166 Builder.AddTextChunk(Text: Builder.getAllocator().CopyString(String: Quals));
9167 Builder.AddTextChunk(
9168 Text: GetCompletionTypeString(T: Type, Context, Policy, Allocator&: Builder.getAllocator()));
9169 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9170}
9171
9172/// Determine whether the given class is or inherits from a class by
9173/// the given name.
9174static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, StringRef Name) {
9175 if (!Class)
9176 return false;
9177
9178 if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name)
9179 return true;
9180
9181 return InheritsFromClassNamed(Class: Class->getSuperClass(), Name);
9182}
9183
9184/// Add code completions for Objective-C Key-Value Coding (KVC) and
9185/// Key-Value Observing (KVO).
9186static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
9187 bool IsInstanceMethod,
9188 QualType ReturnType, ASTContext &Context,
9189 VisitedSelectorSet &KnownSelectors,
9190 ResultBuilder &Results) {
9191 IdentifierInfo *PropName = Property->getIdentifier();
9192 if (!PropName || PropName->getLength() == 0)
9193 return;
9194
9195 PrintingPolicy Policy = getCompletionPrintingPolicy(S&: Results.getSema());
9196
9197 // Builder that will create each code completion.
9198 typedef CodeCompletionResult Result;
9199 CodeCompletionAllocator &Allocator = Results.getAllocator();
9200 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
9201
9202 // The selector table.
9203 SelectorTable &Selectors = Context.Selectors;
9204
9205 // The property name, copied into the code completion allocation region
9206 // on demand.
9207 struct KeyHolder {
9208 CodeCompletionAllocator &Allocator;
9209 StringRef Key;
9210 const char *CopiedKey;
9211
9212 KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
9213 : Allocator(Allocator), Key(Key), CopiedKey(nullptr) {}
9214
9215 operator const char *() {
9216 if (CopiedKey)
9217 return CopiedKey;
9218
9219 return CopiedKey = Allocator.CopyString(String: Key);
9220 }
9221 } Key(Allocator, PropName->getName());
9222
9223 // The uppercased name of the property name.
9224 std::string UpperKey = std::string(PropName->getName());
9225 if (!UpperKey.empty())
9226 UpperKey[0] = toUppercase(c: UpperKey[0]);
9227
9228 bool ReturnTypeMatchesProperty =
9229 ReturnType.isNull() ||
9230 Context.hasSameUnqualifiedType(T1: ReturnType.getNonReferenceType(),
9231 T2: Property->getType());
9232 bool ReturnTypeMatchesVoid = ReturnType.isNull() || ReturnType->isVoidType();
9233
9234 // Add the normal accessor -(type)key.
9235 if (IsInstanceMethod &&
9236 KnownSelectors.insert(Ptr: Selectors.getNullarySelector(ID: PropName)).second &&
9237 ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {
9238 if (ReturnType.isNull())
9239 AddObjCPassingTypeChunk(Type: Property->getType(), /*Quals=*/ObjCDeclQuals: 0, Context, Policy,
9240 Builder);
9241
9242 Builder.AddTypedTextChunk(Text: Key);
9243 Results.AddResult(R: Result(Builder.TakeString(), CCP_CodePattern,
9244 CXCursor_ObjCInstanceMethodDecl));
9245 }
9246
9247 // If we have an integral or boolean property (or the user has provided
9248 // an integral or boolean return type), add the accessor -(type)isKey.
9249 if (IsInstanceMethod &&
9250 ((!ReturnType.isNull() &&
9251 (ReturnType->isIntegerType() || ReturnType->isBooleanType())) ||
9252 (ReturnType.isNull() && (Property->getType()->isIntegerType() ||
9253 Property->getType()->isBooleanType())))) {
9254 std::string SelectorName = (Twine("is") + UpperKey).str();
9255 IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9256 if (KnownSelectors.insert(Ptr: Selectors.getNullarySelector(ID: SelectorId))
9257 .second) {
9258 if (ReturnType.isNull()) {
9259 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9260 Builder.AddTextChunk(Text: "BOOL");
9261 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9262 }
9263
9264 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorId->getName()));
9265 Results.AddResult(R: Result(Builder.TakeString(), CCP_CodePattern,
9266 CXCursor_ObjCInstanceMethodDecl));
9267 }
9268 }
9269
9270 // Add the normal mutator.
9271 if (IsInstanceMethod && ReturnTypeMatchesVoid &&
9272 !Property->getSetterMethodDecl()) {
9273 std::string SelectorName = (Twine("set") + UpperKey).str();
9274 IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9275 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9276 if (ReturnType.isNull()) {
9277 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9278 Builder.AddTextChunk(Text: "void");
9279 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9280 }
9281
9282 Builder.AddTypedTextChunk(
9283 Text: Allocator.CopyString(String: SelectorId->getName() + ":"));
9284 AddObjCPassingTypeChunk(Type: Property->getType(), /*Quals=*/ObjCDeclQuals: 0, Context, Policy,
9285 Builder);
9286 Builder.AddTextChunk(Text: Key);
9287 Results.AddResult(R: Result(Builder.TakeString(), CCP_CodePattern,
9288 CXCursor_ObjCInstanceMethodDecl));
9289 }
9290 }
9291
9292 // Indexed and unordered accessors
9293 unsigned IndexedGetterPriority = CCP_CodePattern;
9294 unsigned IndexedSetterPriority = CCP_CodePattern;
9295 unsigned UnorderedGetterPriority = CCP_CodePattern;
9296 unsigned UnorderedSetterPriority = CCP_CodePattern;
9297 if (const auto *ObjCPointer =
9298 Property->getType()->getAs<ObjCObjectPointerType>()) {
9299 if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) {
9300 // If this interface type is not provably derived from a known
9301 // collection, penalize the corresponding completions.
9302 if (!InheritsFromClassNamed(Class: IFace, Name: "NSMutableArray")) {
9303 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
9304 if (!InheritsFromClassNamed(Class: IFace, Name: "NSArray"))
9305 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
9306 }
9307
9308 if (!InheritsFromClassNamed(Class: IFace, Name: "NSMutableSet")) {
9309 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
9310 if (!InheritsFromClassNamed(Class: IFace, Name: "NSSet"))
9311 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
9312 }
9313 }
9314 } else {
9315 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
9316 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
9317 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
9318 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
9319 }
9320
9321 // Add -(NSUInteger)countOf<key>
9322 if (IsInstanceMethod &&
9323 (ReturnType.isNull() || ReturnType->isIntegerType())) {
9324 std::string SelectorName = (Twine("countOf") + UpperKey).str();
9325 IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9326 if (KnownSelectors.insert(Ptr: Selectors.getNullarySelector(ID: SelectorId))
9327 .second) {
9328 if (ReturnType.isNull()) {
9329 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9330 Builder.AddTextChunk(Text: "NSUInteger");
9331 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9332 }
9333
9334 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorId->getName()));
9335 Results.AddResult(
9336 R: Result(Builder.TakeString(),
9337 std::min(a: IndexedGetterPriority, b: UnorderedGetterPriority),
9338 CXCursor_ObjCInstanceMethodDecl));
9339 }
9340 }
9341
9342 // Indexed getters
9343 // Add -(id)objectInKeyAtIndex:(NSUInteger)index
9344 if (IsInstanceMethod &&
9345 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
9346 std::string SelectorName = (Twine("objectIn") + UpperKey + "AtIndex").str();
9347 IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9348 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9349 if (ReturnType.isNull()) {
9350 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9351 Builder.AddTextChunk(Text: "id");
9352 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9353 }
9354
9355 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9356 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9357 Builder.AddTextChunk(Text: "NSUInteger");
9358 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9359 Builder.AddTextChunk(Text: "index");
9360 Results.AddResult(R: Result(Builder.TakeString(), IndexedGetterPriority,
9361 CXCursor_ObjCInstanceMethodDecl));
9362 }
9363 }
9364
9365 // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes
9366 if (IsInstanceMethod &&
9367 (ReturnType.isNull() ||
9368 (ReturnType->isObjCObjectPointerType() &&
9369 ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
9370 ReturnType->castAs<ObjCObjectPointerType>()
9371 ->getInterfaceDecl()
9372 ->getName() == "NSArray"))) {
9373 std::string SelectorName = (Twine(Property->getName()) + "AtIndexes").str();
9374 IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9375 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9376 if (ReturnType.isNull()) {
9377 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9378 Builder.AddTextChunk(Text: "NSArray *");
9379 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9380 }
9381
9382 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9383 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9384 Builder.AddTextChunk(Text: "NSIndexSet *");
9385 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9386 Builder.AddTextChunk(Text: "indexes");
9387 Results.AddResult(R: Result(Builder.TakeString(), IndexedGetterPriority,
9388 CXCursor_ObjCInstanceMethodDecl));
9389 }
9390 }
9391
9392 // Add -(void)getKey:(type **)buffer range:(NSRange)inRange
9393 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9394 std::string SelectorName = (Twine("get") + UpperKey).str();
9395 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(Name: SelectorName),
9396 &Context.Idents.get(Name: "range")};
9397
9398 if (KnownSelectors.insert(Ptr: Selectors.getSelector(NumArgs: 2, IIV: SelectorIds)).second) {
9399 if (ReturnType.isNull()) {
9400 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9401 Builder.AddTextChunk(Text: "void");
9402 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9403 }
9404
9405 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9406 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9407 Builder.AddPlaceholderChunk(Placeholder: "object-type");
9408 Builder.AddTextChunk(Text: " **");
9409 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9410 Builder.AddTextChunk(Text: "buffer");
9411 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9412 Builder.AddTypedTextChunk(Text: "range:");
9413 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9414 Builder.AddTextChunk(Text: "NSRange");
9415 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9416 Builder.AddTextChunk(Text: "inRange");
9417 Results.AddResult(R: Result(Builder.TakeString(), IndexedGetterPriority,
9418 CXCursor_ObjCInstanceMethodDecl));
9419 }
9420 }
9421
9422 // Mutable indexed accessors
9423
9424 // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index
9425 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9426 std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str();
9427 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(Name: "insertObject"),
9428 &Context.Idents.get(Name: SelectorName)};
9429
9430 if (KnownSelectors.insert(Ptr: Selectors.getSelector(NumArgs: 2, IIV: SelectorIds)).second) {
9431 if (ReturnType.isNull()) {
9432 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9433 Builder.AddTextChunk(Text: "void");
9434 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9435 }
9436
9437 Builder.AddTypedTextChunk(Text: "insertObject:");
9438 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9439 Builder.AddPlaceholderChunk(Placeholder: "object-type");
9440 Builder.AddTextChunk(Text: " *");
9441 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9442 Builder.AddTextChunk(Text: "object");
9443 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9444 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9445 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9446 Builder.AddPlaceholderChunk(Placeholder: "NSUInteger");
9447 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9448 Builder.AddTextChunk(Text: "index");
9449 Results.AddResult(R: Result(Builder.TakeString(), IndexedSetterPriority,
9450 CXCursor_ObjCInstanceMethodDecl));
9451 }
9452 }
9453
9454 // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes
9455 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9456 std::string SelectorName = (Twine("insert") + UpperKey).str();
9457 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(Name: SelectorName),
9458 &Context.Idents.get(Name: "atIndexes")};
9459
9460 if (KnownSelectors.insert(Ptr: Selectors.getSelector(NumArgs: 2, IIV: SelectorIds)).second) {
9461 if (ReturnType.isNull()) {
9462 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9463 Builder.AddTextChunk(Text: "void");
9464 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9465 }
9466
9467 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9468 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9469 Builder.AddTextChunk(Text: "NSArray *");
9470 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9471 Builder.AddTextChunk(Text: "array");
9472 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9473 Builder.AddTypedTextChunk(Text: "atIndexes:");
9474 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9475 Builder.AddPlaceholderChunk(Placeholder: "NSIndexSet *");
9476 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9477 Builder.AddTextChunk(Text: "indexes");
9478 Results.AddResult(R: Result(Builder.TakeString(), IndexedSetterPriority,
9479 CXCursor_ObjCInstanceMethodDecl));
9480 }
9481 }
9482
9483 // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index
9484 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9485 std::string SelectorName =
9486 (Twine("removeObjectFrom") + UpperKey + "AtIndex").str();
9487 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9488 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9489 if (ReturnType.isNull()) {
9490 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9491 Builder.AddTextChunk(Text: "void");
9492 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9493 }
9494
9495 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9496 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9497 Builder.AddTextChunk(Text: "NSUInteger");
9498 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9499 Builder.AddTextChunk(Text: "index");
9500 Results.AddResult(R: Result(Builder.TakeString(), IndexedSetterPriority,
9501 CXCursor_ObjCInstanceMethodDecl));
9502 }
9503 }
9504
9505 // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes
9506 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9507 std::string SelectorName = (Twine("remove") + UpperKey + "AtIndexes").str();
9508 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9509 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9510 if (ReturnType.isNull()) {
9511 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9512 Builder.AddTextChunk(Text: "void");
9513 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9514 }
9515
9516 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9517 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9518 Builder.AddTextChunk(Text: "NSIndexSet *");
9519 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9520 Builder.AddTextChunk(Text: "indexes");
9521 Results.AddResult(R: Result(Builder.TakeString(), IndexedSetterPriority,
9522 CXCursor_ObjCInstanceMethodDecl));
9523 }
9524 }
9525
9526 // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object
9527 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9528 std::string SelectorName =
9529 (Twine("replaceObjectIn") + UpperKey + "AtIndex").str();
9530 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(Name: SelectorName),
9531 &Context.Idents.get(Name: "withObject")};
9532
9533 if (KnownSelectors.insert(Ptr: Selectors.getSelector(NumArgs: 2, IIV: SelectorIds)).second) {
9534 if (ReturnType.isNull()) {
9535 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9536 Builder.AddTextChunk(Text: "void");
9537 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9538 }
9539
9540 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9541 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9542 Builder.AddPlaceholderChunk(Placeholder: "NSUInteger");
9543 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9544 Builder.AddTextChunk(Text: "index");
9545 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9546 Builder.AddTypedTextChunk(Text: "withObject:");
9547 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9548 Builder.AddTextChunk(Text: "id");
9549 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9550 Builder.AddTextChunk(Text: "object");
9551 Results.AddResult(R: Result(Builder.TakeString(), IndexedSetterPriority,
9552 CXCursor_ObjCInstanceMethodDecl));
9553 }
9554 }
9555
9556 // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array
9557 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9558 std::string SelectorName1 =
9559 (Twine("replace") + UpperKey + "AtIndexes").str();
9560 std::string SelectorName2 = (Twine("with") + UpperKey).str();
9561 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(Name: SelectorName1),
9562 &Context.Idents.get(Name: SelectorName2)};
9563
9564 if (KnownSelectors.insert(Ptr: Selectors.getSelector(NumArgs: 2, IIV: SelectorIds)).second) {
9565 if (ReturnType.isNull()) {
9566 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9567 Builder.AddTextChunk(Text: "void");
9568 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9569 }
9570
9571 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName1 + ":"));
9572 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9573 Builder.AddPlaceholderChunk(Placeholder: "NSIndexSet *");
9574 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9575 Builder.AddTextChunk(Text: "indexes");
9576 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9577 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName2 + ":"));
9578 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9579 Builder.AddTextChunk(Text: "NSArray *");
9580 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9581 Builder.AddTextChunk(Text: "array");
9582 Results.AddResult(R: Result(Builder.TakeString(), IndexedSetterPriority,
9583 CXCursor_ObjCInstanceMethodDecl));
9584 }
9585 }
9586
9587 // Unordered getters
9588 // - (NSEnumerator *)enumeratorOfKey
9589 if (IsInstanceMethod &&
9590 (ReturnType.isNull() ||
9591 (ReturnType->isObjCObjectPointerType() &&
9592 ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
9593 ReturnType->castAs<ObjCObjectPointerType>()
9594 ->getInterfaceDecl()
9595 ->getName() == "NSEnumerator"))) {
9596 std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();
9597 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9598 if (KnownSelectors.insert(Ptr: Selectors.getNullarySelector(ID: SelectorId))
9599 .second) {
9600 if (ReturnType.isNull()) {
9601 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9602 Builder.AddTextChunk(Text: "NSEnumerator *");
9603 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9604 }
9605
9606 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName));
9607 Results.AddResult(R: Result(Builder.TakeString(), UnorderedGetterPriority,
9608 CXCursor_ObjCInstanceMethodDecl));
9609 }
9610 }
9611
9612 // - (type *)memberOfKey:(type *)object
9613 if (IsInstanceMethod &&
9614 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
9615 std::string SelectorName = (Twine("memberOf") + UpperKey).str();
9616 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9617 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9618 if (ReturnType.isNull()) {
9619 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9620 Builder.AddPlaceholderChunk(Placeholder: "object-type");
9621 Builder.AddTextChunk(Text: " *");
9622 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9623 }
9624
9625 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9626 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9627 if (ReturnType.isNull()) {
9628 Builder.AddPlaceholderChunk(Placeholder: "object-type");
9629 Builder.AddTextChunk(Text: " *");
9630 } else {
9631 Builder.AddTextChunk(Text: GetCompletionTypeString(
9632 T: ReturnType, Context, Policy, Allocator&: Builder.getAllocator()));
9633 }
9634 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9635 Builder.AddTextChunk(Text: "object");
9636 Results.AddResult(R: Result(Builder.TakeString(), UnorderedGetterPriority,
9637 CXCursor_ObjCInstanceMethodDecl));
9638 }
9639 }
9640
9641 // Mutable unordered accessors
9642 // - (void)addKeyObject:(type *)object
9643 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9644 std::string SelectorName =
9645 (Twine("add") + UpperKey + Twine("Object")).str();
9646 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9647 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9648 if (ReturnType.isNull()) {
9649 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9650 Builder.AddTextChunk(Text: "void");
9651 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9652 }
9653
9654 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9655 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9656 Builder.AddPlaceholderChunk(Placeholder: "object-type");
9657 Builder.AddTextChunk(Text: " *");
9658 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9659 Builder.AddTextChunk(Text: "object");
9660 Results.AddResult(R: Result(Builder.TakeString(), UnorderedSetterPriority,
9661 CXCursor_ObjCInstanceMethodDecl));
9662 }
9663 }
9664
9665 // - (void)addKey:(NSSet *)objects
9666 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9667 std::string SelectorName = (Twine("add") + UpperKey).str();
9668 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9669 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9670 if (ReturnType.isNull()) {
9671 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9672 Builder.AddTextChunk(Text: "void");
9673 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9674 }
9675
9676 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9677 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9678 Builder.AddTextChunk(Text: "NSSet *");
9679 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9680 Builder.AddTextChunk(Text: "objects");
9681 Results.AddResult(R: Result(Builder.TakeString(), UnorderedSetterPriority,
9682 CXCursor_ObjCInstanceMethodDecl));
9683 }
9684 }
9685
9686 // - (void)removeKeyObject:(type *)object
9687 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9688 std::string SelectorName =
9689 (Twine("remove") + UpperKey + Twine("Object")).str();
9690 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9691 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9692 if (ReturnType.isNull()) {
9693 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9694 Builder.AddTextChunk(Text: "void");
9695 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9696 }
9697
9698 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9699 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9700 Builder.AddPlaceholderChunk(Placeholder: "object-type");
9701 Builder.AddTextChunk(Text: " *");
9702 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9703 Builder.AddTextChunk(Text: "object");
9704 Results.AddResult(R: Result(Builder.TakeString(), UnorderedSetterPriority,
9705 CXCursor_ObjCInstanceMethodDecl));
9706 }
9707 }
9708
9709 // - (void)removeKey:(NSSet *)objects
9710 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9711 std::string SelectorName = (Twine("remove") + UpperKey).str();
9712 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9713 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9714 if (ReturnType.isNull()) {
9715 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9716 Builder.AddTextChunk(Text: "void");
9717 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9718 }
9719
9720 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9721 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9722 Builder.AddTextChunk(Text: "NSSet *");
9723 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9724 Builder.AddTextChunk(Text: "objects");
9725 Results.AddResult(R: Result(Builder.TakeString(), UnorderedSetterPriority,
9726 CXCursor_ObjCInstanceMethodDecl));
9727 }
9728 }
9729
9730 // - (void)intersectKey:(NSSet *)objects
9731 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9732 std::string SelectorName = (Twine("intersect") + UpperKey).str();
9733 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9734 if (KnownSelectors.insert(Ptr: Selectors.getUnarySelector(ID: SelectorId)).second) {
9735 if (ReturnType.isNull()) {
9736 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9737 Builder.AddTextChunk(Text: "void");
9738 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9739 }
9740
9741 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName + ":"));
9742 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9743 Builder.AddTextChunk(Text: "NSSet *");
9744 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9745 Builder.AddTextChunk(Text: "objects");
9746 Results.AddResult(R: Result(Builder.TakeString(), UnorderedSetterPriority,
9747 CXCursor_ObjCInstanceMethodDecl));
9748 }
9749 }
9750
9751 // Key-Value Observing
9752 // + (NSSet *)keyPathsForValuesAffectingKey
9753 if (!IsInstanceMethod &&
9754 (ReturnType.isNull() ||
9755 (ReturnType->isObjCObjectPointerType() &&
9756 ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
9757 ReturnType->castAs<ObjCObjectPointerType>()
9758 ->getInterfaceDecl()
9759 ->getName() == "NSSet"))) {
9760 std::string SelectorName =
9761 (Twine("keyPathsForValuesAffecting") + UpperKey).str();
9762 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9763 if (KnownSelectors.insert(Ptr: Selectors.getNullarySelector(ID: SelectorId))
9764 .second) {
9765 if (ReturnType.isNull()) {
9766 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9767 Builder.AddTextChunk(Text: "NSSet<NSString *> *");
9768 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9769 }
9770
9771 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName));
9772 Results.AddResult(R: Result(Builder.TakeString(), CCP_CodePattern,
9773 CXCursor_ObjCClassMethodDecl));
9774 }
9775 }
9776
9777 // + (BOOL)automaticallyNotifiesObserversForKey
9778 if (!IsInstanceMethod &&
9779 (ReturnType.isNull() || ReturnType->isIntegerType() ||
9780 ReturnType->isBooleanType())) {
9781 std::string SelectorName =
9782 (Twine("automaticallyNotifiesObserversOf") + UpperKey).str();
9783 const IdentifierInfo *SelectorId = &Context.Idents.get(Name: SelectorName);
9784 if (KnownSelectors.insert(Ptr: Selectors.getNullarySelector(ID: SelectorId))
9785 .second) {
9786 if (ReturnType.isNull()) {
9787 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
9788 Builder.AddTextChunk(Text: "BOOL");
9789 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
9790 }
9791
9792 Builder.AddTypedTextChunk(Text: Allocator.CopyString(String: SelectorName));
9793 Results.AddResult(R: Result(Builder.TakeString(), CCP_CodePattern,
9794 CXCursor_ObjCClassMethodDecl));
9795 }
9796 }
9797}
9798
9799void SemaCodeCompletion::CodeCompleteObjCMethodDecl(
9800 Scope *S, std::optional<bool> IsInstanceMethod, ParsedType ReturnTy) {
9801 ASTContext &Context = getASTContext();
9802 // Determine the return type of the method we're declaring, if
9803 // provided.
9804 QualType ReturnType = SemaRef.GetTypeFromParser(Ty: ReturnTy);
9805 Decl *IDecl = nullptr;
9806 if (SemaRef.CurContext->isObjCContainer()) {
9807 ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(Val: SemaRef.CurContext);
9808 IDecl = OCD;
9809 }
9810 // Determine where we should start searching for methods.
9811 ObjCContainerDecl *SearchDecl = nullptr;
9812 bool IsInImplementation = false;
9813 if (Decl *D = IDecl) {
9814 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(Val: D)) {
9815 SearchDecl = Impl->getClassInterface();
9816 IsInImplementation = true;
9817 } else if (ObjCCategoryImplDecl *CatImpl =
9818 dyn_cast<ObjCCategoryImplDecl>(Val: D)) {
9819 SearchDecl = CatImpl->getCategoryDecl();
9820 IsInImplementation = true;
9821 } else
9822 SearchDecl = dyn_cast<ObjCContainerDecl>(Val: D);
9823 }
9824
9825 if (!SearchDecl && S) {
9826 if (DeclContext *DC = S->getEntity())
9827 SearchDecl = dyn_cast<ObjCContainerDecl>(Val: DC);
9828 }
9829
9830 if (!SearchDecl) {
9831 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
9832 Context: CodeCompletionContext::CCC_Other, Results: nullptr, NumResults: 0);
9833 return;
9834 }
9835
9836 // Find all of the methods that we could declare/implement here.
9837 KnownMethodsMap KnownMethods;
9838 FindImplementableMethods(Context, Container: SearchDecl, WantInstanceMethods: IsInstanceMethod, ReturnType,
9839 KnownMethods);
9840
9841 // Add declarations or definitions for each of the known methods.
9842 typedef CodeCompletionResult Result;
9843 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9844 CodeCompleter->getCodeCompletionTUInfo(),
9845 CodeCompletionContext::CCC_Other);
9846 Results.EnterNewScope();
9847 PrintingPolicy Policy = getCompletionPrintingPolicy(S&: SemaRef);
9848 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
9849 MEnd = KnownMethods.end();
9850 M != MEnd; ++M) {
9851 ObjCMethodDecl *Method = M->second.getPointer();
9852 CodeCompletionBuilder Builder(Results.getAllocator(),
9853 Results.getCodeCompletionTUInfo());
9854
9855 // Add the '-'/'+' prefix if it wasn't provided yet.
9856 if (!IsInstanceMethod) {
9857 Builder.AddTextChunk(Text: Method->isInstanceMethod() ? "-" : "+");
9858 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9859 }
9860
9861 // If the result type was not already provided, add it to the
9862 // pattern as (type).
9863 if (ReturnType.isNull()) {
9864 QualType ResTy = Method->getSendResultType().stripObjCKindOfType(ctx: Context);
9865 AttributedType::stripOuterNullability(T&: ResTy);
9866 AddObjCPassingTypeChunk(Type: ResTy, ObjCDeclQuals: Method->getObjCDeclQualifier(), Context,
9867 Policy, Builder);
9868 }
9869
9870 Selector Sel = Method->getSelector();
9871
9872 if (Sel.isUnarySelector()) {
9873 // Unary selectors have no arguments.
9874 Builder.AddTypedTextChunk(
9875 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: 0)));
9876 } else {
9877 // Add all parameters to the pattern.
9878 unsigned I = 0;
9879 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
9880 PEnd = Method->param_end();
9881 P != PEnd; (void)++P, ++I) {
9882 // Add the part of the selector name.
9883 if (I == 0)
9884 Builder.AddTypedTextChunk(
9885 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: I) + ":"));
9886 else if (I < Sel.getNumArgs()) {
9887 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9888 Builder.AddTypedTextChunk(
9889 Text: Builder.getAllocator().CopyString(String: Sel.getNameForSlot(argIndex: I) + ":"));
9890 } else
9891 break;
9892
9893 // Add the parameter type.
9894 QualType ParamType;
9895 if ((*P)->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
9896 ParamType = (*P)->getType();
9897 else
9898 ParamType = (*P)->getOriginalType();
9899 ParamType = ParamType.substObjCTypeArgs(
9900 ctx&: Context, typeArgs: {}, context: ObjCSubstitutionContext::Parameter);
9901 AttributedType::stripOuterNullability(T&: ParamType);
9902 AddObjCPassingTypeChunk(Type: ParamType, ObjCDeclQuals: (*P)->getObjCDeclQualifier(),
9903 Context, Policy, Builder);
9904
9905 if (IdentifierInfo *Id = (*P)->getIdentifier())
9906 Builder.AddTextChunk(
9907 Text: Builder.getAllocator().CopyString(String: Id->getName()));
9908 }
9909 }
9910
9911 if (Method->isVariadic()) {
9912 if (Method->param_size() > 0)
9913 Builder.AddChunk(CK: CodeCompletionString::CK_Comma);
9914 Builder.AddTextChunk(Text: "...");
9915 }
9916
9917 if (IsInImplementation && Results.includeCodePatterns()) {
9918 // We will be defining the method here, so add a compound statement.
9919 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9920 Builder.AddChunk(CK: CodeCompletionString::CK_LeftBrace);
9921 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
9922 if (!Method->getReturnType()->isVoidType()) {
9923 // If the result type is not void, add a return clause.
9924 Builder.AddTextChunk(Text: "return");
9925 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
9926 Builder.AddPlaceholderChunk(Placeholder: "expression");
9927 Builder.AddChunk(CK: CodeCompletionString::CK_SemiColon);
9928 } else
9929 Builder.AddPlaceholderChunk(Placeholder: "statements");
9930
9931 Builder.AddChunk(CK: CodeCompletionString::CK_VerticalSpace);
9932 Builder.AddChunk(CK: CodeCompletionString::CK_RightBrace);
9933 }
9934
9935 unsigned Priority = CCP_CodePattern;
9936 auto R = Result(Builder.TakeString(), Method, Priority);
9937 if (!M->second.getInt())
9938 setInBaseClass(R);
9939 Results.AddResult(R: std::move(R));
9940 }
9941
9942 // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
9943 // the properties in this class and its categories.
9944 if (Context.getLangOpts().ObjC) {
9945 SmallVector<ObjCContainerDecl *, 4> Containers;
9946 Containers.push_back(Elt: SearchDecl);
9947
9948 VisitedSelectorSet KnownSelectors;
9949 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
9950 MEnd = KnownMethods.end();
9951 M != MEnd; ++M)
9952 KnownSelectors.insert(Ptr: M->first);
9953
9954 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Val: SearchDecl);
9955 if (!IFace)
9956 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Val: SearchDecl))
9957 IFace = Category->getClassInterface();
9958
9959 if (IFace)
9960 llvm::append_range(C&: Containers, R: IFace->visible_categories());
9961
9962 if (IsInstanceMethod) {
9963 for (unsigned I = 0, N = Containers.size(); I != N; ++I)
9964 for (auto *P : Containers[I]->instance_properties())
9965 AddObjCKeyValueCompletions(Property: P, IsInstanceMethod: *IsInstanceMethod, ReturnType, Context,
9966 KnownSelectors, Results);
9967 }
9968 }
9969
9970 Results.ExitScope();
9971
9972 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
9973 Context: Results.getCompletionContext(), Results: Results.data(),
9974 NumResults: Results.size());
9975}
9976
9977void SemaCodeCompletion::CodeCompleteObjCMethodDeclSelector(
9978 Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnTy,
9979 ArrayRef<const IdentifierInfo *> SelIdents) {
9980 // If we have an external source, load the entire class method
9981 // pool from the AST file.
9982 if (SemaRef.ExternalSource) {
9983 for (uint32_t I = 0, N = SemaRef.ExternalSource->GetNumExternalSelectors();
9984 I != N; ++I) {
9985 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(ID: I);
9986 if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Val: Sel))
9987 continue;
9988
9989 SemaRef.ObjC().ReadMethodPool(Sel);
9990 }
9991 }
9992
9993 // Build the set of methods we can see.
9994 typedef CodeCompletionResult Result;
9995 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9996 CodeCompleter->getCodeCompletionTUInfo(),
9997 CodeCompletionContext::CCC_Other);
9998
9999 if (ReturnTy)
10000 Results.setPreferredType(
10001 SemaRef.GetTypeFromParser(Ty: ReturnTy).getNonReferenceType());
10002
10003 Results.EnterNewScope();
10004 for (SemaObjC::GlobalMethodPool::iterator
10005 M = SemaRef.ObjC().MethodPool.begin(),
10006 MEnd = SemaRef.ObjC().MethodPool.end();
10007 M != MEnd; ++M) {
10008 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first
10009 : &M->second.second;
10010 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
10011 if (!isAcceptableObjCMethod(Method: MethList->getMethod(), WantKind: MK_Any, SelIdents))
10012 continue;
10013
10014 if (AtParameterName) {
10015 // Suggest parameter names we've seen before.
10016 unsigned NumSelIdents = SelIdents.size();
10017 if (NumSelIdents &&
10018 NumSelIdents <= MethList->getMethod()->param_size()) {
10019 ParmVarDecl *Param =
10020 MethList->getMethod()->parameters()[NumSelIdents - 1];
10021 if (Param->getIdentifier()) {
10022 CodeCompletionBuilder Builder(Results.getAllocator(),
10023 Results.getCodeCompletionTUInfo());
10024 Builder.AddTypedTextChunk(Text: Builder.getAllocator().CopyString(
10025 String: Param->getIdentifier()->getName()));
10026 Results.AddResult(R: Builder.TakeString());
10027 }
10028 }
10029
10030 continue;
10031 }
10032
10033 Result R(MethList->getMethod(),
10034 Results.getBasePriority(ND: MethList->getMethod()), nullptr);
10035 R.StartParameter = SelIdents.size();
10036 R.AllParametersAreInformative = false;
10037 R.DeclaringEntity = true;
10038 Results.MaybeAddResult(R, CurContext: SemaRef.CurContext);
10039 }
10040 }
10041
10042 Results.ExitScope();
10043
10044 if (!AtParameterName && !SelIdents.empty() &&
10045 SelIdents.front()->getName().starts_with(Prefix: "init")) {
10046 for (const auto &M : SemaRef.PP.macros()) {
10047 if (M.first->getName() != "NS_DESIGNATED_INITIALIZER")
10048 continue;
10049 Results.EnterNewScope();
10050 CodeCompletionBuilder Builder(Results.getAllocator(),
10051 Results.getCodeCompletionTUInfo());
10052 Builder.AddTypedTextChunk(
10053 Text: Builder.getAllocator().CopyString(String: M.first->getName()));
10054 Results.AddResult(R: CodeCompletionResult(Builder.TakeString(), CCP_Macro,
10055 CXCursor_MacroDefinition));
10056 Results.ExitScope();
10057 }
10058 }
10059
10060 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
10061 Context: Results.getCompletionContext(), Results: Results.data(),
10062 NumResults: Results.size());
10063}
10064
10065void SemaCodeCompletion::CodeCompletePreprocessorDirective(bool InConditional) {
10066 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10067 CodeCompleter->getCodeCompletionTUInfo(),
10068 CodeCompletionContext::CCC_PreprocessorDirective);
10069 Results.EnterNewScope();
10070
10071 // #if <condition>
10072 CodeCompletionBuilder Builder(Results.getAllocator(),
10073 Results.getCodeCompletionTUInfo());
10074 Builder.AddTypedTextChunk(Text: "if");
10075 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10076 Builder.AddPlaceholderChunk(Placeholder: "condition");
10077 Results.AddResult(R: Builder.TakeString());
10078
10079 // #ifdef <macro>
10080 Builder.AddTypedTextChunk(Text: "ifdef");
10081 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10082 Builder.AddPlaceholderChunk(Placeholder: "macro");
10083 Results.AddResult(R: Builder.TakeString());
10084
10085 // #ifndef <macro>
10086 Builder.AddTypedTextChunk(Text: "ifndef");
10087 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10088 Builder.AddPlaceholderChunk(Placeholder: "macro");
10089 Results.AddResult(R: Builder.TakeString());
10090
10091 if (InConditional) {
10092 // #elif <condition>
10093 Builder.AddTypedTextChunk(Text: "elif");
10094 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10095 Builder.AddPlaceholderChunk(Placeholder: "condition");
10096 Results.AddResult(R: Builder.TakeString());
10097
10098 // #elifdef <macro>
10099 Builder.AddTypedTextChunk(Text: "elifdef");
10100 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10101 Builder.AddPlaceholderChunk(Placeholder: "macro");
10102 Results.AddResult(R: Builder.TakeString());
10103
10104 // #elifndef <macro>
10105 Builder.AddTypedTextChunk(Text: "elifndef");
10106 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10107 Builder.AddPlaceholderChunk(Placeholder: "macro");
10108 Results.AddResult(R: Builder.TakeString());
10109
10110 // #else
10111 Builder.AddTypedTextChunk(Text: "else");
10112 Results.AddResult(R: Builder.TakeString());
10113
10114 // #endif
10115 Builder.AddTypedTextChunk(Text: "endif");
10116 Results.AddResult(R: Builder.TakeString());
10117 }
10118
10119 // #include "header"
10120 Builder.AddTypedTextChunk(Text: "include");
10121 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10122 Builder.AddTextChunk(Text: "\"");
10123 Builder.AddPlaceholderChunk(Placeholder: "header");
10124 Builder.AddTextChunk(Text: "\"");
10125 Results.AddResult(R: Builder.TakeString());
10126
10127 // #include <header>
10128 Builder.AddTypedTextChunk(Text: "include");
10129 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10130 Builder.AddTextChunk(Text: "<");
10131 Builder.AddPlaceholderChunk(Placeholder: "header");
10132 Builder.AddTextChunk(Text: ">");
10133 Results.AddResult(R: Builder.TakeString());
10134
10135 // #define <macro>
10136 Builder.AddTypedTextChunk(Text: "define");
10137 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10138 Builder.AddPlaceholderChunk(Placeholder: "macro");
10139 Results.AddResult(R: Builder.TakeString());
10140
10141 // #define <macro>(<args>)
10142 Builder.AddTypedTextChunk(Text: "define");
10143 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10144 Builder.AddPlaceholderChunk(Placeholder: "macro");
10145 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
10146 Builder.AddPlaceholderChunk(Placeholder: "args");
10147 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
10148 Results.AddResult(R: Builder.TakeString());
10149
10150 // #undef <macro>
10151 Builder.AddTypedTextChunk(Text: "undef");
10152 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10153 Builder.AddPlaceholderChunk(Placeholder: "macro");
10154 Results.AddResult(R: Builder.TakeString());
10155
10156 // #line <number>
10157 Builder.AddTypedTextChunk(Text: "line");
10158 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10159 Builder.AddPlaceholderChunk(Placeholder: "number");
10160 Results.AddResult(R: Builder.TakeString());
10161
10162 // #line <number> "filename"
10163 Builder.AddTypedTextChunk(Text: "line");
10164 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10165 Builder.AddPlaceholderChunk(Placeholder: "number");
10166 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10167 Builder.AddTextChunk(Text: "\"");
10168 Builder.AddPlaceholderChunk(Placeholder: "filename");
10169 Builder.AddTextChunk(Text: "\"");
10170 Results.AddResult(R: Builder.TakeString());
10171
10172 // #error <message>
10173 Builder.AddTypedTextChunk(Text: "error");
10174 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10175 Builder.AddPlaceholderChunk(Placeholder: "message");
10176 Results.AddResult(R: Builder.TakeString());
10177
10178 // #pragma <arguments>
10179 Builder.AddTypedTextChunk(Text: "pragma");
10180 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10181 Builder.AddPlaceholderChunk(Placeholder: "arguments");
10182 Results.AddResult(R: Builder.TakeString());
10183
10184 if (getLangOpts().ObjC) {
10185 // #import "header"
10186 Builder.AddTypedTextChunk(Text: "import");
10187 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10188 Builder.AddTextChunk(Text: "\"");
10189 Builder.AddPlaceholderChunk(Placeholder: "header");
10190 Builder.AddTextChunk(Text: "\"");
10191 Results.AddResult(R: Builder.TakeString());
10192
10193 // #import <header>
10194 Builder.AddTypedTextChunk(Text: "import");
10195 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10196 Builder.AddTextChunk(Text: "<");
10197 Builder.AddPlaceholderChunk(Placeholder: "header");
10198 Builder.AddTextChunk(Text: ">");
10199 Results.AddResult(R: Builder.TakeString());
10200 }
10201
10202 // #include_next "header"
10203 Builder.AddTypedTextChunk(Text: "include_next");
10204 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10205 Builder.AddTextChunk(Text: "\"");
10206 Builder.AddPlaceholderChunk(Placeholder: "header");
10207 Builder.AddTextChunk(Text: "\"");
10208 Results.AddResult(R: Builder.TakeString());
10209
10210 // #include_next <header>
10211 Builder.AddTypedTextChunk(Text: "include_next");
10212 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10213 Builder.AddTextChunk(Text: "<");
10214 Builder.AddPlaceholderChunk(Placeholder: "header");
10215 Builder.AddTextChunk(Text: ">");
10216 Results.AddResult(R: Builder.TakeString());
10217
10218 // #warning <message>
10219 Builder.AddTypedTextChunk(Text: "warning");
10220 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10221 Builder.AddPlaceholderChunk(Placeholder: "message");
10222 Results.AddResult(R: Builder.TakeString());
10223
10224 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
10225 // completions for them. And __include_macros is a Clang-internal extension
10226 // that we don't want to encourage anyone to use.
10227
10228 // FIXME: we don't support #assert or #unassert, so don't suggest them.
10229 Results.ExitScope();
10230
10231 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
10232 Context: Results.getCompletionContext(), Results: Results.data(),
10233 NumResults: Results.size());
10234}
10235
10236void SemaCodeCompletion::CodeCompleteInPreprocessorConditionalExclusion(
10237 Scope *S) {
10238 CodeCompleteOrdinaryName(S, CompletionContext: S->getFnParent()
10239 ? SemaCodeCompletion::PCC_RecoveryInFunction
10240 : SemaCodeCompletion::PCC_Namespace);
10241}
10242
10243void SemaCodeCompletion::CodeCompletePreprocessorMacroName(bool IsDefinition) {
10244 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10245 CodeCompleter->getCodeCompletionTUInfo(),
10246 IsDefinition ? CodeCompletionContext::CCC_MacroName
10247 : CodeCompletionContext::CCC_MacroNameUse);
10248 if (!IsDefinition && CodeCompleter->includeMacros()) {
10249 // Add just the names of macros, not their arguments.
10250 CodeCompletionBuilder Builder(Results.getAllocator(),
10251 Results.getCodeCompletionTUInfo());
10252 Results.EnterNewScope();
10253 for (Preprocessor::macro_iterator M = SemaRef.PP.macro_begin(),
10254 MEnd = SemaRef.PP.macro_end();
10255 M != MEnd; ++M) {
10256 Builder.AddTypedTextChunk(
10257 Text: Builder.getAllocator().CopyString(String: M->first->getName()));
10258 Results.AddResult(R: CodeCompletionResult(
10259 Builder.TakeString(), CCP_CodePattern, CXCursor_MacroDefinition));
10260 }
10261 Results.ExitScope();
10262 } else if (IsDefinition) {
10263 // FIXME: Can we detect when the user just wrote an include guard above?
10264 }
10265
10266 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
10267 Context: Results.getCompletionContext(), Results: Results.data(),
10268 NumResults: Results.size());
10269}
10270
10271void SemaCodeCompletion::CodeCompletePreprocessorExpression() {
10272 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10273 CodeCompleter->getCodeCompletionTUInfo(),
10274 CodeCompletionContext::CCC_PreprocessorExpression);
10275
10276 if (CodeCompleter->includeMacros())
10277 AddMacroResults(PP&: SemaRef.PP, Results, LoadExternal: CodeCompleter->loadExternal(), IncludeUndefined: true);
10278
10279 // defined (<macro>)
10280 Results.EnterNewScope();
10281 CodeCompletionBuilder Builder(Results.getAllocator(),
10282 Results.getCodeCompletionTUInfo());
10283 Builder.AddTypedTextChunk(Text: "defined");
10284 Builder.AddChunk(CK: CodeCompletionString::CK_HorizontalSpace);
10285 Builder.AddChunk(CK: CodeCompletionString::CK_LeftParen);
10286 Builder.AddPlaceholderChunk(Placeholder: "macro");
10287 Builder.AddChunk(CK: CodeCompletionString::CK_RightParen);
10288 Results.AddResult(R: Builder.TakeString());
10289 Results.ExitScope();
10290
10291 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
10292 Context: Results.getCompletionContext(), Results: Results.data(),
10293 NumResults: Results.size());
10294}
10295
10296void SemaCodeCompletion::CodeCompletePreprocessorMacroArgument(
10297 Scope *S, IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned Argument) {
10298 // FIXME: In the future, we could provide "overload" results, much like we
10299 // do for function calls.
10300
10301 // Now just ignore this. There will be another code-completion callback
10302 // for the expanded tokens.
10303}
10304
10305// This handles completion inside an #include filename, e.g. #include <foo/ba
10306// We look for the directory "foo" under each directory on the include path,
10307// list its files, and reassemble the appropriate #include.
10308void SemaCodeCompletion::CodeCompleteIncludedFile(llvm::StringRef Dir,
10309 bool Angled) {
10310 // RelDir should use /, but unescaped \ is possible on windows!
10311 // Our completions will normalize to / for simplicity, this case is rare.
10312 std::string RelDir = llvm::sys::path::convert_to_slash(path: Dir);
10313 // We need the native slashes for the actual file system interactions.
10314 SmallString<128> NativeRelDir = StringRef(RelDir);
10315 llvm::sys::path::native(path&: NativeRelDir);
10316 llvm::vfs::FileSystem &FS =
10317 SemaRef.getSourceManager().getFileManager().getVirtualFileSystem();
10318
10319 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10320 CodeCompleter->getCodeCompletionTUInfo(),
10321 CodeCompletionContext::CCC_IncludedFile);
10322 llvm::DenseSet<StringRef> SeenResults; // To deduplicate results.
10323
10324 // Helper: adds one file or directory completion result.
10325 auto AddCompletion = [&](StringRef Filename, bool IsDirectory) {
10326 SmallString<64> TypedChunk = Filename;
10327 // Directory completion is up to the slash, e.g. <sys/
10328 TypedChunk.push_back(Elt: IsDirectory ? '/' : Angled ? '>' : '"');
10329 auto R = SeenResults.insert(V: TypedChunk);
10330 if (R.second) { // New completion
10331 const char *InternedTyped = Results.getAllocator().CopyString(String: TypedChunk);
10332 *R.first = InternedTyped; // Avoid dangling StringRef.
10333 CodeCompletionBuilder Builder(CodeCompleter->getAllocator(),
10334 CodeCompleter->getCodeCompletionTUInfo());
10335 Builder.AddTypedTextChunk(Text: InternedTyped);
10336 // The result is a "Pattern", which is pretty opaque.
10337 // We may want to include the real filename to allow smart ranking.
10338 Results.AddResult(R: CodeCompletionResult(Builder.TakeString()));
10339 }
10340 };
10341
10342 // Helper: scans IncludeDir for nice files, and adds results for each.
10343 auto AddFilesFromIncludeDir = [&](StringRef IncludeDir,
10344 bool IsSystem,
10345 DirectoryLookup::LookupType_t LookupType) {
10346 llvm::SmallString<128> Dir = IncludeDir;
10347 if (!NativeRelDir.empty()) {
10348 if (LookupType == DirectoryLookup::LT_Framework) {
10349 // For a framework dir, #include <Foo/Bar/> actually maps to
10350 // a path of Foo.framework/Headers/Bar/.
10351 auto Begin = llvm::sys::path::begin(path: NativeRelDir);
10352 auto End = llvm::sys::path::end(path: NativeRelDir);
10353
10354 llvm::sys::path::append(path&: Dir, a: *Begin + ".framework", b: "Headers");
10355 llvm::sys::path::append(path&: Dir, begin: ++Begin, end: End);
10356 } else {
10357 llvm::sys::path::append(path&: Dir, a: NativeRelDir);
10358 }
10359 }
10360
10361 const StringRef &Dirname = llvm::sys::path::filename(path: Dir);
10362 const bool isQt = Dirname.starts_with(Prefix: "Qt") || Dirname == "ActiveQt";
10363 const bool ExtensionlessHeaders =
10364 IsSystem || isQt || Dir.ends_with(Suffix: ".framework/Headers");
10365 std::error_code EC;
10366 unsigned Count = 0;
10367 for (auto It = FS.dir_begin(Dir, EC);
10368 !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
10369 if (++Count == 2500) // If we happen to hit a huge directory,
10370 break; // bail out early so we're not too slow.
10371 StringRef Filename = llvm::sys::path::filename(path: It->path());
10372
10373 // To know whether a symlink should be treated as file or a directory, we
10374 // have to stat it. This should be cheap enough as there shouldn't be many
10375 // symlinks.
10376 llvm::sys::fs::file_type Type = It->type();
10377 if (Type == llvm::sys::fs::file_type::symlink_file) {
10378 if (auto FileStatus = FS.status(Path: It->path()))
10379 Type = FileStatus->getType();
10380 }
10381 switch (Type) {
10382 case llvm::sys::fs::file_type::directory_file:
10383 // All entries in a framework directory must have a ".framework" suffix,
10384 // but the suffix does not appear in the source code's include/import.
10385 if (LookupType == DirectoryLookup::LT_Framework &&
10386 NativeRelDir.empty() && !Filename.consume_back(Suffix: ".framework"))
10387 break;
10388
10389 AddCompletion(Filename, /*IsDirectory=*/true);
10390 break;
10391 case llvm::sys::fs::file_type::regular_file: {
10392 // Only files that really look like headers. (Except in special dirs).
10393 const bool IsHeader = Filename.ends_with_insensitive(Suffix: ".h") ||
10394 Filename.ends_with_insensitive(Suffix: ".hh") ||
10395 Filename.ends_with_insensitive(Suffix: ".hpp") ||
10396 Filename.ends_with_insensitive(Suffix: ".hxx") ||
10397 Filename.ends_with_insensitive(Suffix: ".inc") ||
10398 (ExtensionlessHeaders && !Filename.contains(C: '.'));
10399 if (!IsHeader)
10400 break;
10401 AddCompletion(Filename, /*IsDirectory=*/false);
10402 break;
10403 }
10404 default:
10405 break;
10406 }
10407 }
10408 };
10409
10410 // Helper: adds results relative to IncludeDir, if possible.
10411 auto AddFilesFromDirLookup = [&](const DirectoryLookup &IncludeDir,
10412 bool IsSystem) {
10413 switch (IncludeDir.getLookupType()) {
10414 case DirectoryLookup::LT_HeaderMap:
10415 // header maps are not (currently) enumerable.
10416 break;
10417 case DirectoryLookup::LT_NormalDir:
10418 AddFilesFromIncludeDir(IncludeDir.getDirRef()->getName(), IsSystem,
10419 DirectoryLookup::LT_NormalDir);
10420 break;
10421 case DirectoryLookup::LT_Framework:
10422 AddFilesFromIncludeDir(IncludeDir.getFrameworkDirRef()->getName(),
10423 IsSystem, DirectoryLookup::LT_Framework);
10424 break;
10425 }
10426 };
10427
10428 // Finally with all our helpers, we can scan the include path.
10429 // Do this in standard order so deduplication keeps the right file.
10430 // (In case we decide to add more details to the results later).
10431 const auto &S = SemaRef.PP.getHeaderSearchInfo();
10432 using llvm::make_range;
10433 if (!Angled) {
10434 // The current directory is on the include path for "quoted" includes.
10435 if (auto CurFile = SemaRef.PP.getCurrentFileLexer()->getFileEntry())
10436 AddFilesFromIncludeDir(CurFile->getDir().getName(), false,
10437 DirectoryLookup::LT_NormalDir);
10438 for (const auto &D : make_range(x: S.quoted_dir_begin(), y: S.quoted_dir_end()))
10439 AddFilesFromDirLookup(D, false);
10440 }
10441 for (const auto &D : make_range(x: S.angled_dir_begin(), y: S.angled_dir_end()))
10442 AddFilesFromDirLookup(D, false);
10443 for (const auto &D : make_range(x: S.system_dir_begin(), y: S.system_dir_end()))
10444 AddFilesFromDirLookup(D, true);
10445
10446 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
10447 Context: Results.getCompletionContext(), Results: Results.data(),
10448 NumResults: Results.size());
10449}
10450
10451void SemaCodeCompletion::CodeCompleteNaturalLanguage() {
10452 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
10453 Context: CodeCompletionContext::CCC_NaturalLanguage, Results: nullptr,
10454 NumResults: 0);
10455}
10456
10457void SemaCodeCompletion::CodeCompleteAvailabilityPlatformName() {
10458 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10459 CodeCompleter->getCodeCompletionTUInfo(),
10460 CodeCompletionContext::CCC_Other);
10461 Results.EnterNewScope();
10462 static const char *Platforms[] = {"macOS", "iOS", "watchOS", "tvOS"};
10463 for (const char *Platform : llvm::ArrayRef(Platforms)) {
10464 Results.AddResult(R: CodeCompletionResult(Platform));
10465 Results.AddResult(R: CodeCompletionResult(Results.getAllocator().CopyString(
10466 String: Twine(Platform) + "ApplicationExtension")));
10467 }
10468 Results.ExitScope();
10469 HandleCodeCompleteResults(S: &SemaRef, CodeCompleter,
10470 Context: Results.getCompletionContext(), Results: Results.data(),
10471 NumResults: Results.size());
10472}
10473
10474void SemaCodeCompletion::GatherGlobalCodeCompletions(
10475 CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
10476 SmallVectorImpl<CodeCompletionResult> &Results) {
10477 ResultBuilder Builder(SemaRef, Allocator, CCTUInfo,
10478 CodeCompletionContext::CCC_Recovery);
10479 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
10480 CodeCompletionDeclConsumer Consumer(
10481 Builder, getASTContext().getTranslationUnitDecl());
10482 SemaRef.LookupVisibleDecls(Ctx: getASTContext().getTranslationUnitDecl(),
10483 Kind: Sema::LookupAnyName, Consumer,
10484 IncludeGlobalScope: !CodeCompleter || CodeCompleter->loadExternal());
10485 }
10486
10487 if (!CodeCompleter || CodeCompleter->includeMacros())
10488 AddMacroResults(PP&: SemaRef.PP, Results&: Builder,
10489 LoadExternal: !CodeCompleter || CodeCompleter->loadExternal(), IncludeUndefined: true);
10490
10491 Results.clear();
10492 Results.insert(I: Results.end(), From: Builder.data(),
10493 To: Builder.data() + Builder.size());
10494}
10495
10496SemaCodeCompletion::SemaCodeCompletion(Sema &S,
10497 CodeCompleteConsumer *CompletionConsumer)
10498 : SemaBase(S), CodeCompleter(CompletionConsumer),
10499 Resolver(S.getASTContext()) {}
10500

source code of clang/lib/Sema/SemaCodeComplete.cpp