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