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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

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