clang 24.0.0git
SemaCodeComplete.cpp
Go to the documentation of this file.
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//===----------------------------------------------------------------------===//
13#include "clang/AST/Decl.h"
14#include "clang/AST/DeclBase.h"
15#include "clang/AST/DeclCXX.h"
16#include "clang/AST/DeclObjC.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/ExprCXX.h"
22#include "clang/AST/ExprObjC.h"
26#include "clang/AST/Type.h"
34#include "clang/Lex/MacroInfo.h"
37#include "clang/Sema/DeclSpec.h"
40#include "clang/Sema/Lookup.h"
41#include "clang/Sema/Overload.h"
44#include "clang/Sema/Scope.h"
46#include "clang/Sema/Sema.h"
48#include "clang/Sema/SemaObjC.h"
49#include "llvm/ADT/ArrayRef.h"
50#include "llvm/ADT/DenseSet.h"
51#include "llvm/ADT/SmallBitVector.h"
52#include "llvm/ADT/SmallPtrSet.h"
53#include "llvm/ADT/SmallString.h"
54#include "llvm/ADT/StringSet.h"
55#include "llvm/ADT/StringSwitch.h"
56#include "llvm/ADT/Twine.h"
57#include "llvm/ADT/iterator_range.h"
58#include "llvm/Support/Casting.h"
59#include "llvm/Support/FileSystem.h"
60#include "llvm/Support/Path.h"
61#include "llvm/Support/VirtualFileSystem.h"
62#include "llvm/Support/raw_ostream.h"
63
64#include <list>
65#include <map>
66#include <optional>
67#include <string>
68#include <vector>
69
70using namespace clang;
71using namespace sema;
72
73namespace {
74/// A container of code-completion results.
75class ResultBuilder {
76public:
77 /// The type of a name-lookup filter, which can be provided to the
78 /// name-lookup routines to specify which declarations should be included in
79 /// the result set (when it returns true) and which declarations should be
80 /// filtered out (returns false).
81 typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const;
82
83 typedef CodeCompletionResult Result;
84
85private:
86 /// The actual results we have found.
87 std::vector<Result> Results;
88
89 /// A record of all of the declarations we have found and placed
90 /// into the result set, used to ensure that no declaration ever gets into
91 /// the result set twice.
92 llvm::SmallPtrSet<const Decl *, 16> AllDeclsFound;
93
94 typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair;
95
96 /// An entry in the shadow map, which is optimized to store
97 /// a single (declaration, index) mapping (the common case) but
98 /// can also store a list of (declaration, index) mappings.
99 class ShadowMapEntry {
100 typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
101
102 /// Contains either the solitary NamedDecl * or a vector
103 /// of (declaration, index) pairs.
104 llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector *> DeclOrVector;
105
106 /// When the entry contains a single declaration, this is
107 /// the index associated with that entry.
108 unsigned SingleDeclIndex = 0;
109
110 public:
111 ShadowMapEntry() = default;
112 ShadowMapEntry(const ShadowMapEntry &) = delete;
113 ShadowMapEntry(ShadowMapEntry &&Move) { *this = std::move(Move); }
114 ShadowMapEntry &operator=(const ShadowMapEntry &) = delete;
115 ShadowMapEntry &operator=(ShadowMapEntry &&Move) {
116 SingleDeclIndex = Move.SingleDeclIndex;
117 DeclOrVector = Move.DeclOrVector;
118 Move.DeclOrVector = nullptr;
119 return *this;
120 }
121
122 void Add(const NamedDecl *ND, unsigned Index) {
123 if (DeclOrVector.isNull()) {
124 // 0 - > 1 elements: just set the single element information.
125 DeclOrVector = ND;
126 SingleDeclIndex = Index;
127 return;
128 }
129
130 if (const NamedDecl *PrevND = dyn_cast<const NamedDecl *>(DeclOrVector)) {
131 // 1 -> 2 elements: create the vector of results and push in the
132 // existing declaration.
133 DeclIndexPairVector *Vec = new DeclIndexPairVector;
134 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
135 DeclOrVector = Vec;
136 }
137
138 // Add the new element to the end of the vector.
139 cast<DeclIndexPairVector *>(DeclOrVector)
140 ->push_back(DeclIndexPair(ND, Index));
141 }
142
143 ~ShadowMapEntry() {
144 if (DeclIndexPairVector *Vec =
145 dyn_cast_if_present<DeclIndexPairVector *>(DeclOrVector)) {
146 delete Vec;
147 DeclOrVector = ((NamedDecl *)nullptr);
148 }
149 }
150
151 // Iteration.
152 class iterator;
153 iterator begin() const;
154 iterator end() const;
155 };
156
157 /// A mapping from declaration names to the declarations that have
158 /// this name within a particular scope and their index within the list of
159 /// results.
160 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
161
162 /// The semantic analysis object for which results are being
163 /// produced.
164 Sema &SemaRef;
165
166 /// The allocator used to allocate new code-completion strings.
167 CodeCompletionAllocator &Allocator;
168
169 CodeCompletionTUInfo &CCTUInfo;
170
171 /// If non-NULL, a filter function used to remove any code-completion
172 /// results that are not desirable.
173 LookupFilter Filter;
174
175 /// Whether we should allow declarations as
176 /// nested-name-specifiers that would otherwise be filtered out.
177 bool AllowNestedNameSpecifiers;
178
179 /// If set, the type that we would prefer our resulting value
180 /// declarations to have.
181 ///
182 /// Closely matching the preferred type gives a boost to a result's
183 /// priority.
184 CanQualType PreferredType;
185
186 /// A list of shadow maps, which is used to model name hiding at
187 /// different levels of, e.g., the inheritance hierarchy.
188 std::list<ShadowMap> ShadowMaps;
189
190 /// Overloaded C++ member functions found by SemaLookup.
191 /// Used to determine when one overload is dominated by another.
192 llvm::DenseMap<std::pair<DeclContext *, /*Name*/uintptr_t>, ShadowMapEntry>
193 OverloadMap;
194
195 /// If we're potentially referring to a C++ member function, the set
196 /// of qualifiers applied to the object type.
197 Qualifiers ObjectTypeQualifiers;
198 /// The kind of the object expression, for rvalue/lvalue overloads.
199 ExprValueKind ObjectKind;
200
201 /// Whether the \p ObjectTypeQualifiers field is active.
202 bool HasObjectTypeQualifiers;
203
204 // Whether the member function is using an explicit object parameter
205 bool IsExplicitObjectMemberFunction;
206
207 /// The selector that we prefer.
208 Selector PreferredSelector;
209
210 /// The completion context in which we are gathering results.
211 CodeCompletionContext CompletionContext;
212
213 /// If we are in an instance method definition, the \@implementation
214 /// object.
215 ObjCImplementationDecl *ObjCImplementation;
216
217 void AdjustResultPriorityForDecl(Result &R);
218
219 void MaybeAddConstructorResults(Result R);
220
221public:
222 explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
223 CodeCompletionTUInfo &CCTUInfo,
224 const CodeCompletionContext &CompletionContext,
225 LookupFilter Filter = nullptr)
226 : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
227 Filter(Filter), AllowNestedNameSpecifiers(false),
228 HasObjectTypeQualifiers(false), IsExplicitObjectMemberFunction(false),
229 CompletionContext(CompletionContext), ObjCImplementation(nullptr) {
230 // If this is an Objective-C instance method definition, dig out the
231 // corresponding implementation.
232 switch (CompletionContext.getKind()) {
233 case CodeCompletionContext::CCC_Expression:
234 case CodeCompletionContext::CCC_ObjCMessageReceiver:
235 case CodeCompletionContext::CCC_ParenthesizedExpression:
236 case CodeCompletionContext::CCC_Statement:
237 case CodeCompletionContext::CCC_TopLevelOrExpression:
238 case CodeCompletionContext::CCC_Recovery:
239 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
240 if (Method->isInstanceMethod())
241 if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
242 ObjCImplementation = Interface->getImplementation();
243 break;
244
245 default:
246 break;
247 }
248 }
249
250 /// Determine the priority for a reference to the given declaration.
251 unsigned getBasePriority(const NamedDecl *D);
252
253 /// Whether we should include code patterns in the completion
254 /// results.
255 bool includeCodePatterns() const {
256 return SemaRef.CodeCompletion().CodeCompleter &&
257 SemaRef.CodeCompletion().CodeCompleter->includeCodePatterns();
258 }
259
260 /// Set the filter used for code-completion results.
261 void setFilter(LookupFilter Filter) { this->Filter = Filter; }
262
263 Result *data() { return Results.empty() ? nullptr : &Results.front(); }
264 unsigned size() const { return Results.size(); }
265 bool empty() const { return Results.empty(); }
266
267 /// Specify the preferred type.
268 void setPreferredType(QualType T) {
269 PreferredType = SemaRef.Context.getCanonicalType(T);
270 }
271
272 /// Set the cv-qualifiers on the object type, for us in filtering
273 /// calls to member functions.
274 ///
275 /// When there are qualifiers in this set, they will be used to filter
276 /// out member functions that aren't available (because there will be a
277 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
278 /// match.
279 void setObjectTypeQualifiers(Qualifiers Quals, ExprValueKind Kind) {
280 ObjectTypeQualifiers = Quals;
281 ObjectKind = Kind;
282 HasObjectTypeQualifiers = true;
283 }
284
285 void setExplicitObjectMemberFn(bool IsExplicitObjectFn) {
286 IsExplicitObjectMemberFunction = IsExplicitObjectFn;
287 }
288
289 /// Set the preferred selector.
290 ///
291 /// When an Objective-C method declaration result is added, and that
292 /// method's selector matches this preferred selector, we give that method
293 /// a slight priority boost.
294 void setPreferredSelector(Selector Sel) { PreferredSelector = Sel; }
295
296 /// Retrieve the code-completion context for which results are
297 /// being collected.
298 const CodeCompletionContext &getCompletionContext() const {
299 return CompletionContext;
300 }
301
302 /// Specify whether nested-name-specifiers are allowed.
303 void allowNestedNameSpecifiers(bool Allow = true) {
304 AllowNestedNameSpecifiers = Allow;
305 }
306
307 /// Return the semantic analysis object for which we are collecting
308 /// code completion results.
309 Sema &getSema() const { return SemaRef; }
310
311 /// Retrieve the allocator used to allocate code completion strings.
312 CodeCompletionAllocator &getAllocator() const { return Allocator; }
313
314 CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
315
316 /// Determine whether the given declaration is at all interesting
317 /// as a code-completion result.
318 ///
319 /// \param ND the declaration that we are inspecting.
320 ///
321 /// \param AsNestedNameSpecifier will be set true if this declaration is
322 /// only interesting when it is a nested-name-specifier.
323 bool isInterestingDecl(const NamedDecl *ND,
324 bool &AsNestedNameSpecifier) const;
325
326 /// Decide whether or not a use of function Decl can be a call.
327 ///
328 /// \param ND the function declaration.
329 ///
330 /// \param BaseExprType the object type in a member access expression,
331 /// if any.
332 bool canFunctionBeCalled(const NamedDecl *ND, QualType BaseExprType) const;
333
334 /// Decide whether or not a use of member function Decl can be a call.
335 ///
336 /// \param Method the function declaration.
337 ///
338 /// \param BaseExprType the object type in a member access expression,
339 /// if any.
340 bool canCxxMethodBeCalled(const CXXMethodDecl *Method,
341 QualType BaseExprType) const;
342
343 /// Check whether the result is hidden by the Hiding declaration.
344 ///
345 /// \returns true if the result is hidden and cannot be found, false if
346 /// the hidden result could still be found. When false, \p R may be
347 /// modified to describe how the result can be found (e.g., via extra
348 /// qualification).
349 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
350 const NamedDecl *Hiding);
351
352 /// Add a new result to this result set (if it isn't already in one
353 /// of the shadow maps), or replace an existing result (for, e.g., a
354 /// redeclaration).
355 ///
356 /// \param R the result to add (if it is unique).
357 ///
358 /// \param CurContext the context in which this result will be named.
359 void MaybeAddResult(Result R, DeclContext *CurContext = nullptr);
360
361 /// Add a new result to this result set, where we already know
362 /// the hiding declaration (if any).
363 ///
364 /// \param R the result to add (if it is unique).
365 ///
366 /// \param CurContext the context in which this result will be named.
367 ///
368 /// \param Hiding the declaration that hides the result.
369 ///
370 /// \param InBaseClass whether the result was found in a base
371 /// class of the searched context.
372 ///
373 /// \param BaseExprType the type of expression that precedes the "." or "->"
374 /// in a member access expression.
375 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
376 bool InBaseClass, QualType BaseExprType,
377 bool IsInDeclarationContext, bool IsAddressOfOperand);
378
379 /// Add a new non-declaration result to this result set.
380 void AddResult(Result R);
381
382 /// Enter into a new scope.
383 void EnterNewScope();
384
385 /// Exit from the current scope.
386 void ExitScope();
387
388 /// Ignore this declaration, if it is seen again.
389 void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
390
391 /// Add a visited context.
392 void addVisitedContext(DeclContext *Ctx) {
393 CompletionContext.addVisitedContext(Ctx);
394 }
395
396 /// \name Name lookup predicates
397 ///
398 /// These predicates can be passed to the name lookup functions to filter the
399 /// results of name lookup. All of the predicates have the same type, so that
400 ///
401 //@{
402 bool IsOrdinaryName(const NamedDecl *ND) const;
403 bool IsOrdinaryNonTypeName(const NamedDecl *ND) const;
404 bool IsIntegralConstantValue(const NamedDecl *ND) const;
405 bool IsOrdinaryNonValueName(const NamedDecl *ND) const;
406 bool IsNestedNameSpecifier(const NamedDecl *ND) const;
407 bool IsEnum(const NamedDecl *ND) const;
408 bool IsClassOrStruct(const NamedDecl *ND) const;
409 bool IsUnion(const NamedDecl *ND) const;
410 bool IsNamespace(const NamedDecl *ND) const;
411 bool IsNamespaceOrAlias(const NamedDecl *ND) const;
412 bool IsType(const NamedDecl *ND) const;
413 bool IsMember(const NamedDecl *ND) const;
414 bool IsOffsetofField(const NamedDecl *ND) const;
415 bool IsObjCIvar(const NamedDecl *ND) const;
416 bool IsObjCMessageReceiver(const NamedDecl *ND) const;
417 bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const;
418 bool IsObjCCollection(const NamedDecl *ND) const;
419 bool IsImpossibleToSatisfy(const NamedDecl *ND) const;
420 //@}
421};
422
423// Traverse declarations of the function (in a deterministic order,
424// for consistency) to find one which has parameter names.
425// For simplicity, consider a redecl to have parameter names
426// if at least one parameter has a name.
427const FunctionDecl *BetterSignature(const FunctionDecl *Function,
428 unsigned Start) {
429 auto ParaCount = Function->getNumParams();
430 // Note that `redecls()` traverses in a circular order from the current decl,
431 // so for consistency we have to first get the first declaration.
432 for (auto *Redecl : Function->getFirstDecl()->redecls()) {
433 // The callers will expect to be able to use the same index from the initial
434 // function on the redeclaration. While we do not expect this to happen,
435 // this is a failsafe.
436 if (Redecl->getNumParams() < ParaCount)
437 continue;
438 for (unsigned P = Start, N = Redecl->getNumParams(); P != N; ++P)
439 if (Redecl->getParamDecl(P)->getIdentifier())
440 return Redecl;
441 }
442 return Function;
443}
444} // namespace
445
447 if (!Enabled)
448 return;
449 if (isa<BlockDecl>(S.CurContext)) {
450 if (sema::BlockScopeInfo *BSI = S.getCurBlock()) {
451 ComputeType = nullptr;
452 Type = BSI->ReturnType;
453 ExpectedLoc = Tok;
454 }
455 } else if (const auto *Function = dyn_cast<FunctionDecl>(S.CurContext)) {
456 ComputeType = nullptr;
457 Type = Function->getReturnType();
458 ExpectedLoc = Tok;
459 } else if (const auto *Method = dyn_cast<ObjCMethodDecl>(S.CurContext)) {
460 ComputeType = nullptr;
461 Type = Method->getReturnType();
462 ExpectedLoc = Tok;
463 }
464}
465
467 if (!Enabled)
468 return;
469 auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
470 ComputeType = nullptr;
471 Type = VD ? VD->getType() : QualType();
472 ExpectedLoc = Tok;
473}
474
475static const FieldDecl *lookupDirectField(RecordDecl *RD, const Designator &D);
477 ASTContext &Context, QualType BaseType, const Designation &Desig,
478 HeuristicResolver &Resolver,
479 llvm::function_ref<const FieldDecl *(RecordDecl *, const Designator &)>
480 LookupField);
481
483 QualType BaseType,
484 const Designation &D) {
485 if (!Enabled)
486 return;
487 ComputeType = nullptr;
488 HeuristicResolver Resolver(*Ctx);
489 Type = getDesignatedType(*Ctx, BaseType, D, Resolver, lookupDirectField);
490 ExpectedLoc = Tok;
491}
492
494 SourceLocation Tok, llvm::function_ref<QualType()> ComputeType) {
495 if (!Enabled)
496 return;
497 this->ComputeType = ComputeType;
498 Type = QualType();
499 ExpectedLoc = Tok;
500}
501
503 SourceLocation LParLoc) {
504 if (!Enabled)
505 return;
506 // expected type for parenthesized expression does not change.
507 if (ExpectedLoc == LParLoc)
508 ExpectedLoc = Tok;
509}
510
512 tok::TokenKind Op) {
513 if (!LHS)
514 return QualType();
515
516 QualType LHSType = LHS->getType();
517 if (LHSType->isPointerType()) {
518 if (Op == tok::plus || Op == tok::plusequal || Op == tok::minusequal)
520 // Pointer difference is more common than subtracting an int from a pointer.
521 if (Op == tok::minus)
522 return LHSType;
523 }
524
525 switch (Op) {
526 // No way to infer the type of RHS from LHS.
527 case tok::comma:
528 return QualType();
529 // Prefer the type of the left operand for all of these.
530 // Arithmetic operations.
531 case tok::plus:
532 case tok::plusequal:
533 case tok::minus:
534 case tok::minusequal:
535 case tok::percent:
536 case tok::percentequal:
537 case tok::slash:
538 case tok::slashequal:
539 case tok::star:
540 case tok::starequal:
541 // Assignment.
542 case tok::equal:
543 // Comparison operators.
544 case tok::equalequal:
545 case tok::exclaimequal:
546 case tok::less:
547 case tok::lessequal:
548 case tok::greater:
549 case tok::greaterequal:
550 case tok::spaceship:
551 return LHS->getType();
552 // Binary shifts are often overloaded, so don't try to guess those.
553 case tok::greatergreater:
554 case tok::greatergreaterequal:
555 case tok::lessless:
556 case tok::lesslessequal:
557 if (LHSType->isIntegralOrEnumerationType())
558 return S.getASTContext().IntTy;
559 return QualType();
560 // Logical operators, assume we want bool.
561 case tok::ampamp:
562 case tok::pipepipe:
563 return S.getASTContext().BoolTy;
564 // Operators often used for bit manipulation are typically used with the type
565 // of the left argument.
566 case tok::pipe:
567 case tok::pipeequal:
568 case tok::caret:
569 case tok::caretequal:
570 case tok::amp:
571 case tok::ampequal:
572 if (LHSType->isIntegralOrEnumerationType())
573 return LHSType;
574 return QualType();
575 // RHS should be a pointer to a member of the 'LHS' type, but we can't give
576 // any particular type here.
577 case tok::periodstar:
578 case tok::arrowstar:
579 return QualType();
580 default:
581 // FIXME(ibiryukov): handle the missing op, re-add the assertion.
582 // assert(false && "unhandled binary op");
583 return QualType();
584 }
585}
586
587/// Get preferred type for an argument of an unary expression. \p ContextType is
588/// preferred type of the whole unary expression.
590 tok::TokenKind Op) {
591 switch (Op) {
592 case tok::exclaim:
593 return S.getASTContext().BoolTy;
594 case tok::amp:
595 if (!ContextType.isNull() && ContextType->isPointerType())
596 return ContextType->getPointeeType();
597 return QualType();
598 case tok::star:
599 if (ContextType.isNull())
600 return QualType();
601 return S.getASTContext().getPointerType(ContextType.getNonReferenceType());
602 case tok::plus:
603 case tok::minus:
604 case tok::tilde:
605 case tok::minusminus:
606 case tok::plusplus:
607 if (ContextType.isNull())
608 return S.getASTContext().IntTy;
609 // leave as is, these operators typically return the same type.
610 return ContextType;
611 case tok::kw___real:
612 case tok::kw___imag:
613 return QualType();
614 default:
615 assert(false && "unhandled unary op");
616 return QualType();
617 }
618}
619
621 tok::TokenKind Op) {
622 if (!Enabled)
623 return;
624 ComputeType = nullptr;
625 Type = getPreferredTypeOfBinaryRHS(S, LHS, Op);
626 ExpectedLoc = Tok;
627}
628
630 Expr *Base) {
631 if (!Enabled || !Base)
632 return;
633 // Do we have expected type for Base?
634 if (ExpectedLoc != Base->getBeginLoc())
635 return;
636 // Keep the expected type, only update the location.
637 ExpectedLoc = Tok;
638}
639
641 tok::TokenKind OpKind,
642 SourceLocation OpLoc) {
643 if (!Enabled)
644 return;
645 ComputeType = nullptr;
646 Type = getPreferredTypeOfUnaryArg(S, this->get(OpLoc), OpKind);
647 ExpectedLoc = Tok;
648}
649
651 Expr *LHS) {
652 if (!Enabled)
653 return;
654 ComputeType = nullptr;
655 Type = S.getASTContext().IntTy;
656 ExpectedLoc = Tok;
657}
658
661 if (!Enabled)
662 return;
663 ComputeType = nullptr;
664 Type = !CastType.isNull() ? CastType.getCanonicalType() : QualType();
665 ExpectedLoc = Tok;
666}
667
669 if (!Enabled)
670 return;
671 ComputeType = nullptr;
672 Type = S.getASTContext().BoolTy;
673 ExpectedLoc = Tok;
674}
675
677 llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
678 unsigned SingleDeclIndex;
679
680public:
681 typedef DeclIndexPair value_type;
683 typedef std::ptrdiff_t difference_type;
684 typedef std::input_iterator_tag iterator_category;
685
686 class pointer {
687 DeclIndexPair Value;
688
689 public:
690 pointer(const DeclIndexPair &Value) : Value(Value) {}
691
692 const DeclIndexPair *operator->() const { return &Value; }
693 };
694
695 iterator() : DeclOrIterator((NamedDecl *)nullptr), SingleDeclIndex(0) {}
696
697 iterator(const NamedDecl *SingleDecl, unsigned Index)
698 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) {}
699
700 iterator(const DeclIndexPair *Iterator)
701 : DeclOrIterator(Iterator), SingleDeclIndex(0) {}
702
704 if (isa<const NamedDecl *>(DeclOrIterator)) {
705 DeclOrIterator = (NamedDecl *)nullptr;
706 SingleDeclIndex = 0;
707 return *this;
708 }
709
710 const DeclIndexPair *I = cast<const DeclIndexPair *>(DeclOrIterator);
711 ++I;
712 DeclOrIterator = I;
713 return *this;
714 }
715
716 /*iterator operator++(int) {
717 iterator tmp(*this);
718 ++(*this);
719 return tmp;
720 }*/
721
723 if (const NamedDecl *ND = dyn_cast<const NamedDecl *>(DeclOrIterator))
724 return reference(ND, SingleDeclIndex);
725
726 return *cast<const DeclIndexPair *>(DeclOrIterator);
727 }
728
729 pointer operator->() const { return pointer(**this); }
730
731 friend bool operator==(const iterator &X, const iterator &Y) {
732 return X.DeclOrIterator.getOpaqueValue() ==
733 Y.DeclOrIterator.getOpaqueValue() &&
734 X.SingleDeclIndex == Y.SingleDeclIndex;
735 }
736
737 friend bool operator!=(const iterator &X, const iterator &Y) {
738 return !(X == Y);
739 }
740};
741
743ResultBuilder::ShadowMapEntry::begin() const {
744 if (DeclOrVector.isNull())
745 return iterator();
746
747 if (const NamedDecl *ND = dyn_cast<const NamedDecl *>(DeclOrVector))
748 return iterator(ND, SingleDeclIndex);
749
750 return iterator(cast<DeclIndexPairVector *>(DeclOrVector)->begin());
751}
752
754ResultBuilder::ShadowMapEntry::end() const {
755 if (isa<const NamedDecl *>(DeclOrVector) || DeclOrVector.isNull())
756 return iterator();
757
758 return iterator(cast<DeclIndexPairVector *>(DeclOrVector)->end());
759}
760
761/// Compute the qualification required to get from the current context
762/// (\p CurContext) to the target context (\p TargetContext).
763///
764/// \param Context the AST context in which the qualification will be used.
765///
766/// \param CurContext the context where an entity is being named, which is
767/// typically based on the current scope.
768///
769/// \param TargetContext the context in which the named entity actually
770/// resides.
771///
772/// \returns a nested name specifier that refers into the target context, or
773/// NULL if no qualification is needed.
776 const DeclContext *TargetContext) {
778
779 for (const DeclContext *CommonAncestor = TargetContext;
780 CommonAncestor && !CommonAncestor->Encloses(CurContext);
781 CommonAncestor = CommonAncestor->getLookupParent()) {
782 if (CommonAncestor->isTransparentContext() ||
783 CommonAncestor->isFunctionOrMethod())
784 continue;
785
786 TargetParents.push_back(CommonAncestor);
787 }
788
789 NestedNameSpecifier Result = std::nullopt;
790 while (!TargetParents.empty()) {
791 const DeclContext *Parent = TargetParents.pop_back_val();
792
793 if (const auto *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
794 if (!Namespace->getIdentifier())
795 continue;
796
797 Result = NestedNameSpecifier(Context, Namespace, Result);
798 } else if (const auto *TD = dyn_cast<TagDecl>(Parent)) {
799 QualType TT = Context.getTagType(ElaboratedTypeKeyword::None, Result, TD,
800 /*OwnsTag=*/false);
802 }
803 }
804 return Result;
805}
806
807// Some declarations have reserved names that we don't want to ever show.
808// Filter out names reserved for the implementation if they come from a
809// system header.
810static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) {
811 // Debuggers want access to all identifiers, including reserved ones.
812 if (SemaRef.getLangOpts().DebuggerSupport)
813 return false;
814
815 ReservedIdentifierStatus Status = ND->isReserved(SemaRef.getLangOpts());
816 // Ignore reserved names for compiler provided decls.
817 if (isReservedInAllContexts(Status) && ND->getLocation().isInvalid())
818 return true;
819
820 // For system headers ignore only double-underscore names.
821 // This allows for system headers providing private symbols with a single
822 // underscore.
825 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation())))
826 return true;
827
828 return false;
829}
830
831bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
832 bool &AsNestedNameSpecifier) const {
833 AsNestedNameSpecifier = false;
834
835 auto *Named = ND;
836 ND = ND->getUnderlyingDecl();
837
838 // Skip unnamed entities.
839 if (!ND->getDeclName())
840 return false;
841
842 // Friend declarations and declarations introduced due to friends are never
843 // added as results.
845 return false;
846
847 // Class template (partial) specializations are never added as results.
850 return false;
851
852 // Using declarations themselves are never added as results.
853 if (isa<UsingDecl>(ND))
854 return false;
855
856 if (shouldIgnoreDueToReservedName(ND, SemaRef))
857 return false;
858
859 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
860 (isa<NamespaceDecl>(ND) && Filter != &ResultBuilder::IsNamespace &&
861 Filter != &ResultBuilder::IsNamespaceOrAlias && Filter != nullptr))
862 AsNestedNameSpecifier = true;
863
864 // Filter out any unwanted results.
865 if (Filter && !(this->*Filter)(Named)) {
866 // Check whether it is interesting as a nested-name-specifier.
867 if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus &&
868 IsNestedNameSpecifier(ND) &&
869 (Filter != &ResultBuilder::IsMember ||
870 (isa<CXXRecordDecl>(ND) &&
871 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
872 AsNestedNameSpecifier = true;
873 return true;
874 }
875
876 return false;
877 }
878 // ... then it must be interesting!
879 return true;
880}
881
882bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
883 const NamedDecl *Hiding) {
884 // In C, there is no way to refer to a hidden name.
885 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
886 // name if we introduce the tag type.
887 if (!SemaRef.getLangOpts().CPlusPlus)
888 return true;
889
890 const DeclContext *HiddenCtx =
891 R.Declaration->getDeclContext()->getRedeclContext();
892
893 // There is no way to qualify a name declared in a function or method.
894 if (HiddenCtx->isFunctionOrMethod())
895 return true;
896
897 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
898 return true;
899
900 // We can refer to the result with the appropriate qualification. Do it.
901 R.Hidden = true;
902 R.QualifierIsInformative = false;
903
904 if (!R.Qualifier)
905 R.Qualifier = getRequiredQualification(SemaRef.Context, CurContext,
906 R.Declaration->getDeclContext());
907 return false;
908}
909
910/// A simplified classification of types used to determine whether two
911/// types are "similar enough" when adjusting priorities.
913 switch (T->getTypeClass()) {
914 case Type::Builtin:
915 switch (cast<BuiltinType>(T)->getKind()) {
916 case BuiltinType::Void:
917 return STC_Void;
918
919 case BuiltinType::NullPtr:
920 return STC_Pointer;
921
922 case BuiltinType::Overload:
923 case BuiltinType::Dependent:
924 return STC_Other;
925
926 case BuiltinType::ObjCId:
927 case BuiltinType::ObjCClass:
928 case BuiltinType::ObjCSel:
929 return STC_ObjectiveC;
930
931 default:
932 return STC_Arithmetic;
933 }
934
935 case Type::Complex:
936 return STC_Arithmetic;
937
938 case Type::Pointer:
939 return STC_Pointer;
940
941 case Type::BlockPointer:
942 return STC_Block;
943
944 case Type::LValueReference:
945 case Type::RValueReference:
947
948 case Type::ConstantArray:
949 case Type::IncompleteArray:
950 case Type::VariableArray:
951 case Type::DependentSizedArray:
952 return STC_Array;
953
954 case Type::DependentSizedExtVector:
955 case Type::Vector:
956 case Type::ExtVector:
957 return STC_Arithmetic;
958
959 case Type::FunctionProto:
960 case Type::FunctionNoProto:
961 return STC_Function;
962
963 case Type::Record:
964 return STC_Record;
965
966 case Type::Enum:
967 return STC_Arithmetic;
968
969 case Type::ObjCObject:
970 case Type::ObjCInterface:
971 case Type::ObjCObjectPointer:
972 return STC_ObjectiveC;
973
974 default:
975 return STC_Other;
976 }
977}
978
979/// Get the type that a given expression will have if this declaration
980/// is used as an expression in its "typical" code-completion form.
982 const NamedDecl *ND) {
983 ND = ND->getUnderlyingDecl();
984
985 if (const auto *Type = dyn_cast<TypeDecl>(ND))
986 return C.getTypeDeclType(ElaboratedTypeKeyword::None, Qualifier, Type);
987 if (const auto *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
988 return C.getObjCInterfaceType(Iface);
989
990 QualType T;
991 if (const FunctionDecl *Function = ND->getAsFunction())
992 T = Function->getCallResultType();
993 else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND))
994 T = Method->getSendResultType();
995 else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND))
996 T = C.getTagType(ElaboratedTypeKeyword::None, Qualifier,
997 cast<EnumDecl>(Enumerator->getDeclContext()),
998 /*OwnsTag=*/false);
999 else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND))
1000 T = Property->getType();
1001 else if (const auto *Value = dyn_cast<ValueDecl>(ND))
1002 T = Value->getType();
1003
1004 if (T.isNull())
1005 return QualType();
1006
1007 // Dig through references, function pointers, and block pointers to
1008 // get down to the likely type of an expression when the entity is
1009 // used.
1010 do {
1011 if (const auto *Ref = T->getAs<ReferenceType>()) {
1012 T = Ref->getPointeeType();
1013 continue;
1014 }
1015
1016 if (const auto *Pointer = T->getAs<PointerType>()) {
1017 if (Pointer->getPointeeType()->isFunctionType()) {
1018 T = Pointer->getPointeeType();
1019 continue;
1020 }
1021
1022 break;
1023 }
1024
1025 if (const auto *Block = T->getAs<BlockPointerType>()) {
1026 T = Block->getPointeeType();
1027 continue;
1028 }
1029
1030 if (const auto *Function = T->getAs<FunctionType>()) {
1031 T = Function->getReturnType();
1032 continue;
1033 }
1034
1035 break;
1036 } while (true);
1037
1038 return T;
1039}
1040
1041unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) {
1042 if (!ND)
1043 return CCP_Unlikely;
1044
1045 // Context-based decisions.
1046 const DeclContext *LexicalDC = ND->getLexicalDeclContext();
1047 if (LexicalDC->isFunctionOrMethod()) {
1048 // _cmd is relatively rare
1049 if (const auto *ImplicitParam = dyn_cast<ImplicitParamDecl>(ND))
1050 if (ImplicitParam->getIdentifier() &&
1051 ImplicitParam->getIdentifier()->isStr("_cmd"))
1052 return CCP_ObjC_cmd;
1053
1054 return CCP_LocalDeclaration;
1055 }
1056
1057 const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
1058 if (DC->isRecord() || isa<ObjCContainerDecl>(DC)) {
1059 // Explicit destructor calls are very rare.
1060 if (isa<CXXDestructorDecl>(ND))
1061 return CCP_Unlikely;
1062 // Explicit operator and conversion function calls are also very rare.
1063 auto DeclNameKind = ND->getDeclName().getNameKind();
1064 if (DeclNameKind == DeclarationName::CXXOperatorName ||
1067 return CCP_Unlikely;
1068 return CCP_MemberDeclaration;
1069 }
1070
1071 // Content-based decisions.
1072 if (isa<EnumConstantDecl>(ND))
1073 return CCP_Constant;
1074
1075 // Use CCP_Type for type declarations unless we're in a statement, Objective-C
1076 // message receiver, or parenthesized expression context. There, it's as
1077 // likely that the user will want to write a type as other declarations.
1078 if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
1079 !(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement ||
1080 CompletionContext.getKind() ==
1082 CompletionContext.getKind() ==
1084 return CCP_Type;
1085
1086 return CCP_Declaration;
1087}
1088
1089void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
1090 // If this is an Objective-C method declaration whose selector matches our
1091 // preferred selector, give it a priority boost.
1092 if (!PreferredSelector.isNull())
1093 if (const auto *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
1094 if (PreferredSelector == Method->getSelector())
1095 R.Priority += CCD_SelectorMatch;
1096
1097 // If we have a preferred type, adjust the priority for results with exactly-
1098 // matching or nearly-matching types.
1099 if (!PreferredType.isNull()) {
1100 QualType T = getDeclUsageType(SemaRef.Context, R.Qualifier, R.Declaration);
1101 if (!T.isNull()) {
1102 CanQualType TC = SemaRef.Context.getCanonicalType(T);
1103 // Check for exactly-matching types (modulo qualifiers).
1104 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
1105 R.Priority /= CCF_ExactTypeMatch;
1106 // Check for nearly-matching types, based on classification of each.
1107 else if ((getSimplifiedTypeClass(PreferredType) ==
1109 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
1110 R.Priority /= CCF_SimilarTypeMatch;
1111 }
1112 }
1113}
1114
1116 const CXXRecordDecl *Record) {
1117 CanQualType RecordTy = Context.getCanonicalTagType(Record);
1118 DeclarationName ConstructorName =
1119 Context.DeclarationNames.getCXXConstructorName(RecordTy);
1120 return Record->lookup(ConstructorName);
1121}
1122
1123void ResultBuilder::MaybeAddConstructorResults(Result R) {
1124 if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration ||
1125 !CompletionContext.wantConstructorResults())
1126 return;
1127
1128 const NamedDecl *D = R.Declaration;
1129 const CXXRecordDecl *Record = nullptr;
1130 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
1131 Record = ClassTemplate->getTemplatedDecl();
1132 else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
1133 // Skip specializations and partial specializations.
1135 return;
1136 } else {
1137 // There are no constructors here.
1138 return;
1139 }
1140
1142 if (!Record)
1143 return;
1144
1145 for (NamedDecl *Ctor : getConstructors(SemaRef.Context, Record)) {
1146 R.Declaration = Ctor;
1147 R.CursorKind = getCursorKindForDecl(R.Declaration);
1148 Results.push_back(R);
1149 }
1150}
1151
1152static bool isConstructor(const Decl *ND) {
1153 if (const auto *Tmpl = dyn_cast<FunctionTemplateDecl>(ND))
1154 ND = Tmpl->getTemplatedDecl();
1155 return isa<CXXConstructorDecl>(ND);
1156}
1157
1158void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
1159 assert(!ShadowMaps.empty() && "Must enter into a results scope");
1160
1161 if (R.Kind != Result::RK_Declaration) {
1162 // For non-declaration results, just add the result.
1163 Results.push_back(R);
1164 return;
1165 }
1166
1167 // Look through using declarations.
1168 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
1169 CodeCompletionResult Result(Using->getTargetDecl(),
1170 getBasePriority(Using->getTargetDecl()),
1171 R.Qualifier, false,
1172 (R.Availability == CXAvailability_Available ||
1173 R.Availability == CXAvailability_Deprecated),
1174 std::move(R.FixIts));
1175 Result.ShadowDecl = Using;
1176 MaybeAddResult(Result, CurContext);
1177 return;
1178 }
1179
1180 const Decl *CanonDecl = R.Declaration->getCanonicalDecl();
1181 unsigned IDNS = CanonDecl->getIdentifierNamespace();
1182
1183 bool AsNestedNameSpecifier = false;
1184 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
1185 return;
1186
1187 // C++ constructors are never found by name lookup.
1188 if (isConstructor(R.Declaration))
1189 return;
1190
1191 ShadowMap &SMap = ShadowMaps.back();
1192 ShadowMapEntry::iterator I, IEnd;
1193 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
1194 if (NamePos != SMap.end()) {
1195 I = NamePos->second.begin();
1196 IEnd = NamePos->second.end();
1197 }
1198
1199 for (; I != IEnd; ++I) {
1200 const NamedDecl *ND = I->first;
1201 unsigned Index = I->second;
1202 if (ND->getCanonicalDecl() == CanonDecl) {
1203 // This is a redeclaration. Always pick the newer declaration.
1204 Results[Index].Declaration = R.Declaration;
1205
1206 // We're done.
1207 return;
1208 }
1209 }
1210
1211 // This is a new declaration in this scope. However, check whether this
1212 // declaration name is hidden by a similarly-named declaration in an outer
1213 // scope.
1214 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
1215 --SMEnd;
1216 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
1217 ShadowMapEntry::iterator I, IEnd;
1218 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
1219 if (NamePos != SM->end()) {
1220 I = NamePos->second.begin();
1221 IEnd = NamePos->second.end();
1222 }
1223 for (; I != IEnd; ++I) {
1224 // A tag declaration does not hide a non-tag declaration.
1225 if (I->first->hasTagIdentifierNamespace() &&
1228 continue;
1229
1230 // Protocols are in distinct namespaces from everything else.
1231 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) ||
1232 (IDNS & Decl::IDNS_ObjCProtocol)) &&
1233 I->first->getIdentifierNamespace() != IDNS)
1234 continue;
1235
1236 // The newly-added result is hidden by an entry in the shadow map.
1237 if (CheckHiddenResult(R, CurContext, I->first))
1238 return;
1239
1240 break;
1241 }
1242 }
1243
1244 // Make sure that any given declaration only shows up in the result set once.
1245 if (!AllDeclsFound.insert(CanonDecl).second)
1246 return;
1247
1248 // If the filter is for nested-name-specifiers, then this result starts a
1249 // nested-name-specifier.
1250 if (AsNestedNameSpecifier) {
1251 R.StartsNestedNameSpecifier = true;
1252 R.Priority = CCP_NestedNameSpecifier;
1253 } else
1254 AdjustResultPriorityForDecl(R);
1255
1256 // If this result is supposed to have an informative qualifier, add one.
1257 if (R.QualifierIsInformative && !R.Qualifier &&
1258 !R.StartsNestedNameSpecifier) {
1259 const DeclContext *Ctx = R.Declaration->getDeclContext();
1260 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
1261 R.Qualifier =
1262 NestedNameSpecifier(SemaRef.Context, Namespace, std::nullopt);
1263 else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
1264 R.Qualifier = NestedNameSpecifier(
1265 SemaRef.Context
1267 /*Qualifier=*/std::nullopt, Tag, /*OwnsTag=*/false)
1268 .getTypePtr());
1269 else
1270 R.QualifierIsInformative = false;
1271 }
1272
1273 // Insert this result into the set of results and into the current shadow
1274 // map.
1275 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
1276 Results.push_back(R);
1277
1278 if (!AsNestedNameSpecifier)
1279 MaybeAddConstructorResults(R);
1280}
1281
1282static void setInBaseClass(ResultBuilder::Result &R) {
1283 R.Priority += CCD_InBaseClass;
1284 R.InBaseClass = true;
1285}
1286
1288// Will Candidate ever be called on the object, when overloaded with Incumbent?
1289// Returns Dominates if Candidate is always called, Dominated if Incumbent is
1290// always called, BothViable if either may be called depending on arguments.
1291// Precondition: must actually be overloads!
1293 const CXXMethodDecl &Incumbent,
1294 const Qualifiers &ObjectQuals,
1295 ExprValueKind ObjectKind,
1296 const ASTContext &Ctx) {
1297 // Base/derived shadowing is handled elsewhere.
1298 if (Candidate.getDeclContext() != Incumbent.getDeclContext())
1300 if (Candidate.isVariadic() != Incumbent.isVariadic() ||
1301 Candidate.getNumParams() != Incumbent.getNumParams() ||
1302 Candidate.getMinRequiredArguments() !=
1303 Incumbent.getMinRequiredArguments())
1305 for (unsigned I = 0, E = Candidate.getNumParams(); I != E; ++I)
1306 if (Candidate.parameters()[I]->getType().getCanonicalType() !=
1307 Incumbent.parameters()[I]->getType().getCanonicalType())
1309 if (!Candidate.specific_attrs<EnableIfAttr>().empty() ||
1310 !Incumbent.specific_attrs<EnableIfAttr>().empty())
1312 // At this point, we know calls can't pick one or the other based on
1313 // arguments, so one of the two must win. (Or both fail, handled elsewhere).
1314 RefQualifierKind CandidateRef = Candidate.getRefQualifier();
1315 RefQualifierKind IncumbentRef = Incumbent.getRefQualifier();
1316 if (CandidateRef != IncumbentRef) {
1317 // If the object kind is LValue/RValue, there's one acceptable ref-qualifier
1318 // and it can't be mixed with ref-unqualified overloads (in valid code).
1319
1320 // For xvalue objects, we prefer the rvalue overload even if we have to
1321 // add qualifiers (which is rare, because const&& is rare).
1322 if (ObjectKind == clang::VK_XValue)
1323 return CandidateRef == RQ_RValue ? OverloadCompare::Dominates
1325 }
1326 // Now the ref qualifiers are the same (or we're in some invalid state).
1327 // So make some decision based on the qualifiers.
1328 Qualifiers CandidateQual = Candidate.getMethodQualifiers();
1329 Qualifiers IncumbentQual = Incumbent.getMethodQualifiers();
1330 bool CandidateSuperset = CandidateQual.compatiblyIncludes(IncumbentQual, Ctx);
1331 bool IncumbentSuperset = IncumbentQual.compatiblyIncludes(CandidateQual, Ctx);
1332 if (CandidateSuperset == IncumbentSuperset)
1334 return IncumbentSuperset ? OverloadCompare::Dominates
1336}
1337
1338bool ResultBuilder::canCxxMethodBeCalled(const CXXMethodDecl *Method,
1339 QualType BaseExprType) const {
1340 // Find the class scope that we're currently in.
1341 // We could e.g. be inside a lambda, so walk up the DeclContext until we
1342 // find a CXXMethodDecl.
1343 DeclContext *CurContext = SemaRef.CurContext;
1344 const auto *CurrentClassScope = [&]() -> const CXXRecordDecl * {
1345 for (DeclContext *Ctx = CurContext; Ctx; Ctx = Ctx->getParent()) {
1346 const auto *CtxMethod = llvm::dyn_cast<CXXMethodDecl>(Ctx);
1347 if (CtxMethod && !CtxMethod->getParent()->isLambda()) {
1348 return CtxMethod->getParent();
1349 }
1350 }
1351 return nullptr;
1352 }();
1353
1354 // If we're not inside the scope of the method's class, it can't be a call.
1355 bool FunctionCanBeCall =
1356 CurrentClassScope &&
1357 (CurrentClassScope == Method->getParent() ||
1358 CurrentClassScope->isDerivedFrom(Method->getParent()));
1359
1360 // We skip the following calculation for exceptions if it's already true.
1361 if (FunctionCanBeCall)
1362 return true;
1363
1364 // Exception: foo->FooBase::bar() or foo->Foo::bar() *is* a call.
1365 if (const CXXRecordDecl *MaybeDerived =
1366 BaseExprType.isNull() ? nullptr
1367 : BaseExprType->getAsCXXRecordDecl()) {
1368 auto *MaybeBase = Method->getParent();
1369 FunctionCanBeCall =
1370 MaybeDerived == MaybeBase || MaybeDerived->isDerivedFrom(MaybeBase);
1371 }
1372
1373 return FunctionCanBeCall;
1374}
1375
1376bool ResultBuilder::canFunctionBeCalled(const NamedDecl *ND,
1377 QualType BaseExprType) const {
1378 // We apply heuristics only to CCC_Symbol:
1379 // * CCC_{Arrow,Dot}MemberAccess reflect member access expressions:
1380 // f.method() and f->method(). These are always calls.
1381 // * A qualified name to a member function may *not* be a call. We have to
1382 // subdivide the cases: For example, f.Base::method(), which is regarded as
1383 // CCC_Symbol, should be a call.
1384 // * Non-member functions and static member functions are always considered
1385 // calls.
1386 if (CompletionContext.getKind() == clang::CodeCompletionContext::CCC_Symbol) {
1387 if (const auto *FuncTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
1388 ND = FuncTmpl->getTemplatedDecl();
1389 }
1390 const auto *Method = dyn_cast<CXXMethodDecl>(ND);
1391 if (Method && !Method->isStatic()) {
1392 return canCxxMethodBeCalled(Method, BaseExprType);
1393 }
1394 }
1395 return true;
1396}
1397
1398void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
1399 NamedDecl *Hiding, bool InBaseClass = false,
1400 QualType BaseExprType = QualType(),
1401 bool IsInDeclarationContext = false,
1402 bool IsAddressOfOperand = false) {
1403 if (R.Kind != Result::RK_Declaration) {
1404 // For non-declaration results, just add the result.
1405 Results.push_back(R);
1406 return;
1407 }
1408
1409 // Look through using declarations.
1410 if (const auto *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
1411 CodeCompletionResult Result(Using->getTargetDecl(),
1412 getBasePriority(Using->getTargetDecl()),
1413 R.Qualifier, false,
1414 (R.Availability == CXAvailability_Available ||
1415 R.Availability == CXAvailability_Deprecated),
1416 std::move(R.FixIts));
1417 Result.ShadowDecl = Using;
1418 AddResult(Result, CurContext, Hiding, /*InBaseClass=*/false,
1419 /*BaseExprType=*/BaseExprType);
1420 return;
1421 }
1422
1423 bool AsNestedNameSpecifier = false;
1424 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
1425 return;
1426
1427 // C++ constructors are never found by name lookup.
1428 if (isConstructor(R.Declaration))
1429 return;
1430
1431 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
1432 return;
1433
1434 // Make sure that any given declaration only shows up in the result set once.
1435 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()).second)
1436 return;
1437
1438 // If the filter is for nested-name-specifiers, then this result starts a
1439 // nested-name-specifier.
1440 if (AsNestedNameSpecifier) {
1441 R.StartsNestedNameSpecifier = true;
1442 R.Priority = CCP_NestedNameSpecifier;
1443 } else if (Filter == &ResultBuilder::IsMember && !R.Qualifier &&
1444 InBaseClass &&
1446 R.Declaration->getDeclContext()->getRedeclContext()))
1447 R.QualifierIsInformative = true;
1448
1449 // If this result is supposed to have an informative qualifier, add one.
1450 if (R.QualifierIsInformative && !R.Qualifier &&
1451 !R.StartsNestedNameSpecifier) {
1452 const DeclContext *Ctx = R.Declaration->getDeclContext();
1453 if (const auto *Namespace = dyn_cast<NamespaceDecl>(Ctx))
1454 R.Qualifier =
1455 NestedNameSpecifier(SemaRef.Context, Namespace, std::nullopt);
1456 else if (const auto *Tag = dyn_cast<TagDecl>(Ctx))
1457 R.Qualifier = NestedNameSpecifier(
1458 SemaRef.Context
1460 /*Qualifier=*/std::nullopt, Tag, /*OwnsTag=*/false)
1461 .getTypePtr());
1462 else
1463 R.QualifierIsInformative = false;
1464 }
1465
1466 // Adjust the priority if this result comes from a base class.
1467 if (InBaseClass)
1468 setInBaseClass(R);
1469
1470 AdjustResultPriorityForDecl(R);
1471
1472 // Account for explicit object parameter
1473 const auto GetQualifiers = [&](const CXXMethodDecl *MethodDecl) {
1474 if (MethodDecl->isExplicitObjectMemberFunction())
1475 return MethodDecl->getFunctionObjectParameterType().getQualifiers();
1476 else
1477 return MethodDecl->getMethodQualifiers();
1478 };
1479
1480 if (IsExplicitObjectMemberFunction &&
1482 (isa<CXXMethodDecl>(R.Declaration) || isa<FieldDecl>(R.Declaration))) {
1483 // If result is a member in the context of an explicit-object member
1484 // function, drop it because it must be accessed through the object
1485 // parameter
1486 return;
1487 }
1488
1489 if (HasObjectTypeQualifiers)
1490 if (const auto *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
1491 if (Method->isInstance()) {
1492 Qualifiers MethodQuals = GetQualifiers(Method);
1493 if (ObjectTypeQualifiers == MethodQuals)
1494 R.Priority += CCD_ObjectQualifierMatch;
1495 else if (ObjectTypeQualifiers - MethodQuals) {
1496 // The method cannot be invoked, because doing so would drop
1497 // qualifiers.
1498 return;
1499 }
1500 // Detect cases where a ref-qualified method cannot be invoked.
1501 switch (Method->getRefQualifier()) {
1502 case RQ_LValue:
1503 if (ObjectKind != VK_LValue && !MethodQuals.hasConst())
1504 return;
1505 break;
1506 case RQ_RValue:
1507 if (ObjectKind == VK_LValue)
1508 return;
1509 break;
1510 case RQ_None:
1511 break;
1512 }
1513
1514 /// Check whether this dominates another overloaded method, which should
1515 /// be suppressed (or vice versa).
1516 /// Motivating case is const_iterator begin() const vs iterator begin().
1517 auto &OverloadSet = OverloadMap[std::make_pair(
1518 CurContext, Method->getDeclName().getAsOpaqueInteger())];
1519 for (const DeclIndexPair Entry : OverloadSet) {
1520 Result &Incumbent = Results[Entry.second];
1521 switch (compareOverloads(*Method,
1522 *cast<CXXMethodDecl>(Incumbent.Declaration),
1523 ObjectTypeQualifiers, ObjectKind,
1524 CurContext->getParentASTContext())) {
1526 // Replace the dominated overload with this one.
1527 // FIXME: if the overload dominates multiple incumbents then we
1528 // should remove all. But two overloads is by far the common case.
1529 Incumbent = std::move(R);
1530 return;
1532 // This overload can't be called, drop it.
1533 return;
1535 break;
1536 }
1537 }
1538 OverloadSet.Add(Method, Results.size());
1539 }
1540 R.DeclaringEntity = IsInDeclarationContext;
1541 R.FunctionCanBeCall =
1542 canFunctionBeCalled(R.getDeclaration(), BaseExprType) &&
1543 // If the user wrote `&` before the function name, assume the
1544 // user is more likely to take the address of the function rather
1545 // than call it and take the address of the result.
1546 !IsAddressOfOperand;
1547
1548 // Insert this result into the set of results.
1549 Results.push_back(R);
1550
1551 if (!AsNestedNameSpecifier)
1552 MaybeAddConstructorResults(R);
1553}
1554
1555void ResultBuilder::AddResult(Result R) {
1556 assert(R.Kind != Result::RK_Declaration &&
1557 "Declaration results need more context");
1558 Results.push_back(R);
1559}
1560
1561/// Enter into a new scope.
1562void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); }
1563
1564/// Exit from the current scope.
1565void ResultBuilder::ExitScope() {
1566 ShadowMaps.pop_back();
1567}
1568
1569/// Determines whether this given declaration will be found by
1570/// ordinary name lookup.
1571bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
1572 ND = ND->getUnderlyingDecl();
1573
1574 // If name lookup finds a local extern declaration, then we are in a
1575 // context where it behaves like an ordinary name.
1577 if (SemaRef.getLangOpts().CPlusPlus)
1579 else if (SemaRef.getLangOpts().ObjC) {
1580 if (isa<ObjCIvarDecl>(ND))
1581 return true;
1582 }
1583
1584 return ND->getIdentifierNamespace() & IDNS;
1585}
1586
1587/// Determines whether this given declaration will be found by
1588/// ordinary name lookup but is not a type name.
1589bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
1590 ND = ND->getUnderlyingDecl();
1591 if (isa<TypeDecl>(ND))
1592 return false;
1593 // Objective-C interfaces names are not filtered by this method because they
1594 // can be used in a class property expression. We can still filter out
1595 // @class declarations though.
1596 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
1597 if (!ID->getDefinition())
1598 return false;
1599 }
1600
1602 if (SemaRef.getLangOpts().CPlusPlus)
1604 else if (SemaRef.getLangOpts().ObjC) {
1605 if (isa<ObjCIvarDecl>(ND))
1606 return true;
1607 }
1608
1609 return ND->getIdentifierNamespace() & IDNS;
1610}
1611
1612bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {
1613 if (!IsOrdinaryNonTypeName(ND))
1614 return false;
1615
1616 if (const auto *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
1617 if (VD->getType()->isIntegralOrEnumerationType())
1618 return true;
1619
1620 return false;
1621}
1622
1623/// Determines whether this given declaration will be found by
1624/// ordinary name lookup.
1625bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
1626 ND = ND->getUnderlyingDecl();
1627
1629 if (SemaRef.getLangOpts().CPlusPlus)
1631
1632 return (ND->getIdentifierNamespace() & IDNS) && !isa<ValueDecl>(ND) &&
1634}
1635
1636/// Determines whether the given declaration is suitable as the
1637/// start of a C++ nested-name-specifier, e.g., a class or namespace.
1638bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {
1639 // Allow us to find class templates, too.
1640 if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1641 ND = ClassTemplate->getTemplatedDecl();
1642
1643 return SemaRef.isAcceptableNestedNameSpecifier(ND);
1644}
1645
1646/// Determines whether the given declaration is an enumeration.
1647bool ResultBuilder::IsEnum(const NamedDecl *ND) const {
1648 return isa<EnumDecl>(ND);
1649}
1650
1651/// Determines whether the given declaration is a class or struct.
1652bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {
1653 // Allow us to find class templates, too.
1654 if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1655 ND = ClassTemplate->getTemplatedDecl();
1656
1657 // For purposes of this check, interfaces match too.
1658 if (const auto *RD = dyn_cast<RecordDecl>(ND))
1659 return RD->getTagKind() == TagTypeKind::Class ||
1660 RD->getTagKind() == TagTypeKind::Struct ||
1661 RD->getTagKind() == TagTypeKind::Interface;
1662
1663 return false;
1664}
1665
1666/// Determines whether the given declaration is a union.
1667bool ResultBuilder::IsUnion(const NamedDecl *ND) const {
1668 // Allow us to find class templates, too.
1669 if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1670 ND = ClassTemplate->getTemplatedDecl();
1671
1672 if (const auto *RD = dyn_cast<RecordDecl>(ND))
1673 return RD->getTagKind() == TagTypeKind::Union;
1674
1675 return false;
1676}
1677
1678/// Determines whether the given declaration is a namespace.
1679bool ResultBuilder::IsNamespace(const NamedDecl *ND) const {
1680 return isa<NamespaceDecl>(ND);
1681}
1682
1683/// Determines whether the given declaration is a namespace or
1684/// namespace alias.
1685bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {
1687}
1688
1689/// Determines whether the given declaration is a type.
1690bool ResultBuilder::IsType(const NamedDecl *ND) const {
1691 ND = ND->getUnderlyingDecl();
1692 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
1693}
1694
1695/// Determines which members of a class should be visible via
1696/// "." or "->". Only value declarations, nested name specifiers, and
1697/// using declarations thereof should show up.
1698bool ResultBuilder::IsMember(const NamedDecl *ND) const {
1699 ND = ND->getUnderlyingDecl();
1700 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1702}
1703
1704/// Determines whether the given declaration is a member that
1705/// __builtin_offsetof can name: a (direct or indirect) non-bit-field.
1706bool ResultBuilder::IsOffsetofField(const NamedDecl *ND) const {
1707 ND = ND->getUnderlyingDecl();
1708 if (const auto *FD = dyn_cast<FieldDecl>(ND))
1709 return !FD->isBitField();
1710 if (const auto *IFD = dyn_cast<IndirectFieldDecl>(ND))
1711 return !IFD->getAnonField()->isBitField();
1712 return false;
1713}
1714
1716 T = C.getCanonicalType(T);
1717 switch (T->getTypeClass()) {
1718 case Type::ObjCObject:
1719 case Type::ObjCInterface:
1720 case Type::ObjCObjectPointer:
1721 return true;
1722
1723 case Type::Builtin:
1724 switch (cast<BuiltinType>(T)->getKind()) {
1725 case BuiltinType::ObjCId:
1726 case BuiltinType::ObjCClass:
1727 case BuiltinType::ObjCSel:
1728 return true;
1729
1730 default:
1731 break;
1732 }
1733 return false;
1734
1735 default:
1736 break;
1737 }
1738
1739 if (!C.getLangOpts().CPlusPlus)
1740 return false;
1741
1742 // FIXME: We could perform more analysis here to determine whether a
1743 // particular class type has any conversions to Objective-C types. For now,
1744 // just accept all class types.
1745 return T->isDependentType() || T->isRecordType();
1746}
1747
1748bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
1749 QualType T =
1750 getDeclUsageType(SemaRef.Context, /*Qualifier=*/std::nullopt, ND);
1751 if (T.isNull())
1752 return false;
1753
1754 T = SemaRef.Context.getBaseElementType(T);
1755 return isObjCReceiverType(SemaRef.Context, T);
1756}
1757
1758bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(
1759 const NamedDecl *ND) const {
1760 if (IsObjCMessageReceiver(ND))
1761 return true;
1762
1763 const auto *Var = dyn_cast<VarDecl>(ND);
1764 if (!Var)
1765 return false;
1766
1767 return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
1768}
1769
1770bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
1771 if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
1772 (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1773 return false;
1774
1775 QualType T =
1776 getDeclUsageType(SemaRef.Context, /*Qualifier=*/std::nullopt, ND);
1777 if (T.isNull())
1778 return false;
1779
1780 T = SemaRef.Context.getBaseElementType(T);
1781 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1782 T->isObjCIdType() ||
1783 (SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
1784}
1785
1786bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {
1787 return false;
1788}
1789
1790/// Determines whether the given declaration is an Objective-C
1791/// instance variable.
1792bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {
1793 return isa<ObjCIvarDecl>(ND);
1794}
1795
1796namespace {
1797
1798/// Visible declaration consumer that adds a code-completion result
1799/// for each visible declaration.
1800class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1801 ResultBuilder &Results;
1802 DeclContext *InitialLookupCtx;
1803 // NamingClass and BaseType are used for access-checking. See
1804 // Sema::IsSimplyAccessible for details.
1805 CXXRecordDecl *NamingClass;
1806 QualType BaseType;
1807 std::vector<FixItHint> FixIts;
1808 bool IsInDeclarationContext;
1809 // Completion is invoked after an identifier preceded by '&'.
1810 bool IsAddressOfOperand;
1811
1812public:
1813 CodeCompletionDeclConsumer(
1814 ResultBuilder &Results, DeclContext *InitialLookupCtx,
1815 QualType BaseType = QualType(),
1816 std::vector<FixItHint> FixIts = std::vector<FixItHint>())
1817 : Results(Results), InitialLookupCtx(InitialLookupCtx),
1818 FixIts(std::move(FixIts)), IsInDeclarationContext(false),
1819 IsAddressOfOperand(false) {
1820 NamingClass = llvm::dyn_cast<CXXRecordDecl>(InitialLookupCtx);
1821 // If BaseType was not provided explicitly, emulate implicit 'this->'.
1822 if (BaseType.isNull()) {
1823 auto ThisType = Results.getSema().getCurrentThisType();
1824 if (!ThisType.isNull()) {
1825 assert(ThisType->isPointerType());
1826 BaseType = ThisType->getPointeeType();
1827 if (!NamingClass)
1828 NamingClass = BaseType->getAsCXXRecordDecl();
1829 }
1830 }
1831 this->BaseType = BaseType;
1832 }
1833
1834 void setIsInDeclarationContext(bool IsInDeclarationContext) {
1835 this->IsInDeclarationContext = IsInDeclarationContext;
1836 }
1837
1838 void setIsAddressOfOperand(bool IsAddressOfOperand) {
1839 this->IsAddressOfOperand = IsAddressOfOperand;
1840 }
1841
1842 void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
1843 bool InBaseClass) override {
1844 ResultBuilder::Result Result(ND, Results.getBasePriority(ND),
1845 /*Qualifier=*/std::nullopt,
1846 /*QualifierIsInformative=*/false,
1847 IsAccessible(ND, Ctx), FixIts);
1848 Results.AddResult(Result, InitialLookupCtx, Hiding, InBaseClass, BaseType,
1849 IsInDeclarationContext, IsAddressOfOperand);
1850 }
1851
1852 void EnteredContext(DeclContext *Ctx) override {
1853 Results.addVisitedContext(Ctx);
1854 }
1855
1856private:
1857 bool IsAccessible(NamedDecl *ND, DeclContext *Ctx) {
1858 // Naming class to use for access check. In most cases it was provided
1859 // explicitly (e.g. member access (lhs.foo) or qualified lookup (X::)),
1860 // for unqualified lookup we fallback to the \p Ctx in which we found the
1861 // member.
1862 auto *NamingClass = this->NamingClass;
1863 QualType BaseType = this->BaseType;
1864 if (auto *Cls = llvm::dyn_cast_or_null<CXXRecordDecl>(Ctx)) {
1865 if (!NamingClass)
1866 NamingClass = Cls;
1867 // When we emulate implicit 'this->' in an unqualified lookup, we might
1868 // end up with an invalid naming class. In that case, we avoid emulating
1869 // 'this->' qualifier to satisfy preconditions of the access checking.
1870 if (NamingClass->getCanonicalDecl() != Cls->getCanonicalDecl() &&
1871 !NamingClass->isDerivedFrom(Cls)) {
1872 NamingClass = Cls;
1873 BaseType = QualType();
1874 }
1875 } else {
1876 // The decl was found outside the C++ class, so only ObjC access checks
1877 // apply. Those do not rely on NamingClass and BaseType, so we clear them
1878 // out.
1879 NamingClass = nullptr;
1880 BaseType = QualType();
1881 }
1882 return Results.getSema().IsSimplyAccessible(ND, NamingClass, BaseType);
1883 }
1884};
1885} // namespace
1886
1887/// Add type specifiers for the current language as keyword results.
1888static void AddTypeSpecifierResults(const LangOptions &LangOpts,
1889 ResultBuilder &Results) {
1891 Results.AddResult(Result("short", CCP_Type));
1892 Results.AddResult(Result("long", CCP_Type));
1893 Results.AddResult(Result("signed", CCP_Type));
1894 Results.AddResult(Result("unsigned", CCP_Type));
1895 Results.AddResult(Result("void", CCP_Type));
1896 Results.AddResult(Result("char", CCP_Type));
1897 Results.AddResult(Result("int", CCP_Type));
1898 Results.AddResult(Result("float", CCP_Type));
1899 Results.AddResult(Result("double", CCP_Type));
1900 Results.AddResult(Result("enum", CCP_Type));
1901 Results.AddResult(Result("struct", CCP_Type));
1902 Results.AddResult(Result("union", CCP_Type));
1903 Results.AddResult(Result("const", CCP_Type));
1904 Results.AddResult(Result("volatile", CCP_Type));
1905
1906 if (LangOpts.C99) {
1907 // C99-specific
1908 Results.AddResult(Result("_Complex", CCP_Type));
1909 if (!LangOpts.C2y)
1910 Results.AddResult(Result("_Imaginary", CCP_Type));
1911 Results.AddResult(Result("_Bool", CCP_Type));
1912 Results.AddResult(Result("restrict", CCP_Type));
1913 }
1914
1915 CodeCompletionBuilder Builder(Results.getAllocator(),
1916 Results.getCodeCompletionTUInfo());
1917 if (LangOpts.CPlusPlus) {
1918 // C++-specific
1919 Results.AddResult(
1920 Result("bool", CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0)));
1921 Results.AddResult(Result("class", CCP_Type));
1922 Results.AddResult(Result("wchar_t", CCP_Type));
1923
1924 // typename name
1925 Builder.AddTypedTextChunk("typename");
1927 Builder.AddPlaceholderChunk("name");
1928 Results.AddResult(Result(Builder.TakeString()));
1929
1930 if (LangOpts.CPlusPlus11) {
1931 Results.AddResult(Result("auto", CCP_Type));
1932 Results.AddResult(Result("char16_t", CCP_Type));
1933 Results.AddResult(Result("char32_t", CCP_Type));
1934
1935 Builder.AddTypedTextChunk("decltype");
1936 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1937 Builder.AddPlaceholderChunk("expression");
1938 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1939 Results.AddResult(Result(Builder.TakeString()));
1940 }
1941
1942 if (LangOpts.Char8 || LangOpts.CPlusPlus20)
1943 Results.AddResult(Result("char8_t", CCP_Type));
1944 } else
1945 Results.AddResult(Result("__auto_type", CCP_Type));
1946
1947 // GNU keywords
1948 if (LangOpts.GNUKeywords) {
1949 // FIXME: Enable when we actually support decimal floating point.
1950 // Results.AddResult(Result("_Decimal32"));
1951 // Results.AddResult(Result("_Decimal64"));
1952 // Results.AddResult(Result("_Decimal128"));
1953
1954 Builder.AddTypedTextChunk("typeof");
1956 Builder.AddPlaceholderChunk("expression");
1957 Results.AddResult(Result(Builder.TakeString()));
1958
1959 Builder.AddTypedTextChunk("typeof");
1960 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1961 Builder.AddPlaceholderChunk("type");
1962 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1963 Results.AddResult(Result(Builder.TakeString()));
1964 }
1965
1966 // Nullability
1967 Results.AddResult(Result("_Nonnull", CCP_Type));
1968 Results.AddResult(Result("_Null_unspecified", CCP_Type));
1969 Results.AddResult(Result("_Nullable", CCP_Type));
1970}
1971
1972static void
1974 const LangOptions &LangOpts, ResultBuilder &Results) {
1976 // Note: we don't suggest either "auto" or "register", because both
1977 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1978 // in C++0x as a type specifier.
1979 Results.AddResult(Result("extern"));
1980 Results.AddResult(Result("static"));
1981
1982 if (LangOpts.CPlusPlus11) {
1983 CodeCompletionAllocator &Allocator = Results.getAllocator();
1984 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1985
1986 // alignas
1987 Builder.AddTypedTextChunk("alignas");
1988 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1989 Builder.AddPlaceholderChunk("expression");
1990 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1991 Results.AddResult(Result(Builder.TakeString()));
1992
1993 Results.AddResult(Result("constexpr"));
1994 Results.AddResult(Result("thread_local"));
1995 }
1996
1997 if (LangOpts.CPlusPlus20)
1998 Results.AddResult(Result("constinit"));
1999}
2000
2001static void
2003 const LangOptions &LangOpts, ResultBuilder &Results) {
2005 switch (CCC) {
2008 if (LangOpts.CPlusPlus) {
2009 Results.AddResult(Result("explicit"));
2010 Results.AddResult(Result("friend"));
2011 Results.AddResult(Result("mutable"));
2012 Results.AddResult(Result("virtual"));
2013 }
2014 [[fallthrough]];
2015
2020 if (LangOpts.CPlusPlus || LangOpts.C99)
2021 Results.AddResult(Result("inline"));
2022
2023 if (LangOpts.CPlusPlus20)
2024 Results.AddResult(Result("consteval"));
2025 break;
2026
2037 break;
2038 }
2039}
2040
2041static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
2042static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
2043static void AddObjCVisibilityResults(const LangOptions &LangOpts,
2044 ResultBuilder &Results, bool NeedAt);
2045static void AddObjCImplementationResults(const LangOptions &LangOpts,
2046 ResultBuilder &Results, bool NeedAt);
2047static void AddObjCInterfaceResults(const LangOptions &LangOpts,
2048 ResultBuilder &Results, bool NeedAt);
2049static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
2050
2051static void AddTypedefResult(ResultBuilder &Results) {
2052 CodeCompletionBuilder Builder(Results.getAllocator(),
2053 Results.getCodeCompletionTUInfo());
2054 Builder.AddTypedTextChunk("typedef");
2056 Builder.AddPlaceholderChunk("type");
2058 Builder.AddPlaceholderChunk("name");
2059 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2060 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
2061}
2062
2063// using name = type
2065 ResultBuilder &Results) {
2066 Builder.AddTypedTextChunk("using");
2068 Builder.AddPlaceholderChunk("name");
2069 Builder.AddChunk(CodeCompletionString::CK_Equal);
2070 Builder.AddPlaceholderChunk("type");
2071 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2072 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
2073}
2074
2076 const LangOptions &LangOpts) {
2077 switch (CCC) {
2089 return true;
2090
2093 return LangOpts.CPlusPlus;
2094
2097 return false;
2098
2100 return LangOpts.CPlusPlus || LangOpts.ObjC || LangOpts.C99;
2101 }
2102
2103 llvm_unreachable("Invalid ParserCompletionContext!");
2104}
2105
2107 const Preprocessor &PP) {
2108 PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP);
2109 Policy.AnonymousTagNameStyle =
2110 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
2111 Policy.SuppressStrongLifetime = true;
2112 Policy.SuppressUnwrittenScope = true;
2113 Policy.CleanUglifiedParameters = true;
2114 Policy.ResolveDecltype = true;
2115 return Policy;
2116}
2117
2118/// Retrieve a printing policy suitable for code completion.
2122
2123/// Retrieve the string representation of the given type as a string
2124/// that has the appropriate lifetime for code completion.
2125///
2126/// This routine provides a fast path where we provide constant strings for
2127/// common type names.
2128static const char *GetCompletionTypeString(QualType T, ASTContext &Context,
2129 const PrintingPolicy &Policy,
2130 CodeCompletionAllocator &Allocator) {
2131 if (!T.getLocalQualifiers()) {
2132 // Built-in type names are constant strings.
2133 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T))
2134 return BT->getNameAsCString(Policy);
2135
2136 // Anonymous tag types are constant strings.
2137 if (const TagType *TagT = dyn_cast<TagType>(T))
2138 if (TagDecl *Tag = TagT->getDecl())
2139 if (!Tag->hasNameForLinkage()) {
2140 switch (Tag->getTagKind()) {
2142 return "struct <anonymous>";
2144 return "__interface <anonymous>";
2145 case TagTypeKind::Class:
2146 return "class <anonymous>";
2147 case TagTypeKind::Union:
2148 return "union <anonymous>";
2149 case TagTypeKind::Enum:
2150 return "enum <anonymous>";
2151 }
2152 }
2153 }
2154
2155 // Slow path: format the type as a string.
2156 std::string Result;
2157 T.getAsStringInternal(Result, Policy);
2158 return Allocator.CopyString(Result);
2159}
2160
2161/// Add a completion for "this", if we're in a member function.
2162static void addThisCompletion(Sema &S, ResultBuilder &Results) {
2163 QualType ThisTy = S.getCurrentThisType();
2164 if (ThisTy.isNull())
2165 return;
2166
2167 CodeCompletionAllocator &Allocator = Results.getAllocator();
2168 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
2170 Builder.AddResultTypeChunk(
2171 GetCompletionTypeString(ThisTy, S.Context, Policy, Allocator));
2172 Builder.AddTypedTextChunk("this");
2173 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
2174}
2175
2177 ResultBuilder &Results,
2178 const LangOptions &LangOpts) {
2179 if (!LangOpts.CPlusPlus11)
2180 return;
2181
2182 Builder.AddTypedTextChunk("static_assert");
2183 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2184 Builder.AddPlaceholderChunk("expression");
2185 Builder.AddChunk(CodeCompletionString::CK_Comma);
2186 Builder.AddPlaceholderChunk("message");
2187 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2188 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2189 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
2190}
2191
2192static void AddOverrideResults(ResultBuilder &Results,
2193 const CodeCompletionContext &CCContext,
2194 CodeCompletionBuilder &Builder) {
2195 Sema &S = Results.getSema();
2196 const auto *CR = llvm::dyn_cast<CXXRecordDecl>(S.CurContext);
2197 // If not inside a class/struct/union return empty.
2198 if (!CR)
2199 return;
2200 // First store overrides within current class.
2201 // These are stored by name to make querying fast in the later step.
2202 llvm::StringMap<std::vector<FunctionDecl *>> Overrides;
2203 for (auto *Method : CR->methods()) {
2204 if (!Method->isVirtual() || !Method->getIdentifier())
2205 continue;
2206 Overrides[Method->getName()].push_back(Method);
2207 }
2208
2209 for (const auto &Base : CR->bases()) {
2210 const auto *BR = Base.getType().getTypePtr()->getAsCXXRecordDecl();
2211 if (!BR)
2212 continue;
2213 for (auto *Method : BR->methods()) {
2214 if (!Method->isVirtual() || !Method->getIdentifier())
2215 continue;
2216 const auto it = Overrides.find(Method->getName());
2217 bool IsOverriden = false;
2218 if (it != Overrides.end()) {
2219 for (auto *MD : it->second) {
2220 // If the method in current body is not an overload of this virtual
2221 // function, then it overrides this one.
2222 if (!S.IsOverload(MD, Method, false)) {
2223 IsOverriden = true;
2224 break;
2225 }
2226 }
2227 }
2228 if (!IsOverriden) {
2229 // Generates a new CodeCompletionResult by taking this function and
2230 // converting it into an override declaration with only one chunk in the
2231 // final CodeCompletionString as a TypedTextChunk.
2232 CodeCompletionResult CCR(Method, 0);
2233 PrintingPolicy Policy =
2236 S.getPreprocessor(), S.getASTContext(), Builder,
2237 /*IncludeBriefComments=*/false, CCContext, Policy);
2238 Results.AddResult(CodeCompletionResult(CCS, Method, CCP_CodePattern));
2239 }
2240 }
2241 }
2242}
2243
2244/// Add language constructs that show up for "ordinary" names.
2245static void
2247 Scope *S, Sema &SemaRef, ResultBuilder &Results) {
2248 CodeCompletionAllocator &Allocator = Results.getAllocator();
2249 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
2250
2252 switch (CCC) {
2254 if (SemaRef.getLangOpts().CPlusPlus) {
2255 if (Results.includeCodePatterns()) {
2256 // namespace <identifier> { declarations }
2257 Builder.AddTypedTextChunk("namespace");
2259 Builder.AddPlaceholderChunk("identifier");
2261 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2263 Builder.AddPlaceholderChunk("declarations");
2265 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2266 Results.AddResult(Result(Builder.TakeString()));
2267 }
2268
2269 // namespace identifier = identifier ;
2270 Builder.AddTypedTextChunk("namespace");
2272 Builder.AddPlaceholderChunk("name");
2273 Builder.AddChunk(CodeCompletionString::CK_Equal);
2274 Builder.AddPlaceholderChunk("namespace");
2275 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2276 Results.AddResult(Result(Builder.TakeString()));
2277
2278 // Using directives
2279 Builder.AddTypedTextChunk("using namespace");
2281 Builder.AddPlaceholderChunk("identifier");
2282 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2283 Results.AddResult(Result(Builder.TakeString()));
2284
2285 // asm(string-literal)
2286 Builder.AddTypedTextChunk("asm");
2287 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2288 Builder.AddPlaceholderChunk("string-literal");
2289 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2290 Results.AddResult(Result(Builder.TakeString()));
2291
2292 if (Results.includeCodePatterns()) {
2293 // Explicit template instantiation
2294 Builder.AddTypedTextChunk("template");
2296 Builder.AddPlaceholderChunk("declaration");
2297 Results.AddResult(Result(Builder.TakeString()));
2298 } else {
2299 Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword));
2300 }
2301
2302 if (SemaRef.getLangOpts().CPlusPlus20 &&
2303 SemaRef.getLangOpts().CPlusPlusModules) {
2304 clang::Module *CurrentModule = SemaRef.getCurrentModule();
2305 if (SemaRef.CurContext->isTranslationUnit()) {
2306 /// Global module fragment can only be declared in the beginning of
2307 /// the file. CurrentModule should be null in this case.
2308 if (!CurrentModule) {
2309 // module;
2310 Builder.AddTypedTextChunk("module");
2311 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2313 Results.AddResult(Result(Builder.TakeString()));
2314 }
2315
2316 /// Named module should be declared in the beginning of the file,
2317 /// or after the global module fragment.
2318 if (!CurrentModule ||
2319 CurrentModule->Kind == Module::ExplicitGlobalModuleFragment ||
2320 CurrentModule->Kind == Module::ImplicitGlobalModuleFragment) {
2321 // export module;
2322 // module name;
2323 Builder.AddTypedTextChunk("module");
2325 Builder.AddPlaceholderChunk("name");
2326 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2328 Results.AddResult(Result(Builder.TakeString()));
2329 }
2330
2331 /// Import can occur in non module file or after the named module
2332 /// declaration.
2333 if (!CurrentModule ||
2334 CurrentModule->Kind == Module::ModuleInterfaceUnit ||
2335 CurrentModule->Kind == Module::ModulePartitionInterface) {
2336 // import name;
2337 Builder.AddTypedTextChunk("import");
2339 Builder.AddPlaceholderChunk("name");
2340 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2342 Results.AddResult(Result(Builder.TakeString()));
2343 }
2344
2345 if (CurrentModule &&
2346 (CurrentModule->Kind == Module::ModuleInterfaceUnit ||
2347 CurrentModule->Kind == Module::ModulePartitionInterface)) {
2348 // module: private;
2349 Builder.AddTypedTextChunk("module");
2350 Builder.AddChunk(CodeCompletionString::CK_Colon);
2352 Builder.AddTypedTextChunk("private");
2353 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2355 Results.AddResult(Result(Builder.TakeString()));
2356 }
2357 }
2358
2359 // export
2360 if (!CurrentModule ||
2362 Results.AddResult(Result("export", CodeCompletionResult::RK_Keyword));
2363 }
2364 }
2365
2366 if (SemaRef.getLangOpts().ObjC)
2367 AddObjCTopLevelResults(Results, true);
2368
2369 AddTypedefResult(Results);
2370 [[fallthrough]];
2371
2373 if (SemaRef.getLangOpts().CPlusPlus) {
2374 // Using declaration
2375 Builder.AddTypedTextChunk("using");
2377 Builder.AddPlaceholderChunk("qualifier");
2378 Builder.AddTextChunk("::");
2379 Builder.AddPlaceholderChunk("name");
2380 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2381 Results.AddResult(Result(Builder.TakeString()));
2382
2383 if (SemaRef.getLangOpts().CPlusPlus11)
2384 AddUsingAliasResult(Builder, Results);
2385
2386 // using typename qualifier::name (only in a dependent context)
2387 if (SemaRef.CurContext->isDependentContext()) {
2388 Builder.AddTypedTextChunk("using typename");
2390 Builder.AddPlaceholderChunk("qualifier");
2391 Builder.AddTextChunk("::");
2392 Builder.AddPlaceholderChunk("name");
2393 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2394 Results.AddResult(Result(Builder.TakeString()));
2395 }
2396
2397 AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
2398
2399 if (CCC == SemaCodeCompletion::PCC_Class) {
2400 AddTypedefResult(Results);
2401
2402 bool IsNotInheritanceScope = !S->isClassInheritanceScope();
2403 // public:
2404 Builder.AddTypedTextChunk("public");
2405 if (IsNotInheritanceScope && Results.includeCodePatterns())
2406 Builder.AddChunk(CodeCompletionString::CK_Colon);
2407 Results.AddResult(Result(Builder.TakeString()));
2408
2409 // protected:
2410 Builder.AddTypedTextChunk("protected");
2411 if (IsNotInheritanceScope && Results.includeCodePatterns())
2412 Builder.AddChunk(CodeCompletionString::CK_Colon);
2413 Results.AddResult(Result(Builder.TakeString()));
2414
2415 // private:
2416 Builder.AddTypedTextChunk("private");
2417 if (IsNotInheritanceScope && Results.includeCodePatterns())
2418 Builder.AddChunk(CodeCompletionString::CK_Colon);
2419 Results.AddResult(Result(Builder.TakeString()));
2420
2421 // FIXME: This adds override results only if we are at the first word of
2422 // the declaration/definition. Also call this from other sides to have
2423 // more use-cases.
2425 Builder);
2426 }
2427 }
2428 [[fallthrough]];
2429
2431 if (SemaRef.getLangOpts().CPlusPlus20 &&
2433 Results.AddResult(Result("concept", CCP_Keyword));
2434 [[fallthrough]];
2435
2437 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
2438 // template < parameters >
2439 Builder.AddTypedTextChunk("template");
2440 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2441 Builder.AddPlaceholderChunk("parameters");
2442 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2443 Results.AddResult(Result(Builder.TakeString()));
2444 } else {
2445 Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword));
2446 }
2447
2448 if (SemaRef.getLangOpts().CPlusPlus20 &&
2451 Results.AddResult(Result("requires", CCP_Keyword));
2452
2453 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2454 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2455 break;
2456
2458 AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true);
2459 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2460 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2461 break;
2462
2464 AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true);
2465 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2466 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2467 break;
2468
2470 AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true);
2471 break;
2472
2476 if (SemaRef.getLangOpts().CPlusPlus11)
2477 AddUsingAliasResult(Builder, Results);
2478
2479 AddTypedefResult(Results);
2480
2481 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() &&
2482 SemaRef.getLangOpts().CXXExceptions) {
2483 Builder.AddTypedTextChunk("try");
2485 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2487 Builder.AddPlaceholderChunk("statements");
2489 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2491 Builder.AddTextChunk("catch");
2493 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2494 Builder.AddPlaceholderChunk("declaration");
2495 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2497 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2499 Builder.AddPlaceholderChunk("statements");
2501 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2502 Results.AddResult(Result(Builder.TakeString()));
2503 }
2504 if (SemaRef.getLangOpts().ObjC)
2505 AddObjCStatementResults(Results, true);
2506
2507 if (Results.includeCodePatterns()) {
2508 // if (condition) { statements }
2509 Builder.AddTypedTextChunk("if");
2511 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2512 if (SemaRef.getLangOpts().CPlusPlus)
2513 Builder.AddPlaceholderChunk("condition");
2514 else
2515 Builder.AddPlaceholderChunk("expression");
2516 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2518 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2520 Builder.AddPlaceholderChunk("statements");
2522 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2523 Results.AddResult(Result(Builder.TakeString()));
2524
2525 // switch (condition) { }
2526 Builder.AddTypedTextChunk("switch");
2528 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2529 if (SemaRef.getLangOpts().CPlusPlus)
2530 Builder.AddPlaceholderChunk("condition");
2531 else
2532 Builder.AddPlaceholderChunk("expression");
2533 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2535 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2537 Builder.AddPlaceholderChunk("cases");
2539 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2540 Results.AddResult(Result(Builder.TakeString()));
2541 }
2542
2543 // Switch-specific statements.
2544 if (SemaRef.getCurFunction() &&
2545 !SemaRef.getCurFunction()->SwitchStack.empty()) {
2546 // case expression:
2547 Builder.AddTypedTextChunk("case");
2549 Builder.AddPlaceholderChunk("expression");
2550 Builder.AddChunk(CodeCompletionString::CK_Colon);
2551 Results.AddResult(Result(Builder.TakeString()));
2552
2553 // default:
2554 Builder.AddTypedTextChunk("default");
2555 Builder.AddChunk(CodeCompletionString::CK_Colon);
2556 Results.AddResult(Result(Builder.TakeString()));
2557 }
2558
2559 if (Results.includeCodePatterns()) {
2560 /// while (condition) { statements }
2561 Builder.AddTypedTextChunk("while");
2563 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2564 if (SemaRef.getLangOpts().CPlusPlus)
2565 Builder.AddPlaceholderChunk("condition");
2566 else
2567 Builder.AddPlaceholderChunk("expression");
2568 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2570 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2572 Builder.AddPlaceholderChunk("statements");
2574 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2575 Results.AddResult(Result(Builder.TakeString()));
2576
2577 // do { statements } while ( expression );
2578 Builder.AddTypedTextChunk("do");
2580 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2582 Builder.AddPlaceholderChunk("statements");
2584 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2585 Builder.AddTextChunk("while");
2587 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2588 Builder.AddPlaceholderChunk("expression");
2589 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2590 Results.AddResult(Result(Builder.TakeString()));
2591
2592 // for ( for-init-statement ; condition ; expression ) { statements }
2593 Builder.AddTypedTextChunk("for");
2595 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2596 if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99)
2597 Builder.AddPlaceholderChunk("init-statement");
2598 else
2599 Builder.AddPlaceholderChunk("init-expression");
2600 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2602 Builder.AddPlaceholderChunk("condition");
2603 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2605 Builder.AddPlaceholderChunk("inc-expression");
2606 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2608 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2610 Builder.AddPlaceholderChunk("statements");
2612 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2613 Results.AddResult(Result(Builder.TakeString()));
2614
2615 if (SemaRef.getLangOpts().CPlusPlus11 || SemaRef.getLangOpts().ObjC) {
2616 // for ( range_declaration (:|in) range_expression ) { statements }
2617 Builder.AddTypedTextChunk("for");
2619 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2620 Builder.AddPlaceholderChunk("range-declaration");
2622 if (SemaRef.getLangOpts().ObjC)
2623 Builder.AddTextChunk("in");
2624 else
2625 Builder.AddChunk(CodeCompletionString::CK_Colon);
2627 Builder.AddPlaceholderChunk("range-expression");
2628 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2630 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2632 Builder.AddPlaceholderChunk("statements");
2634 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2635 Results.AddResult(Result(Builder.TakeString()));
2636 }
2637 }
2638
2639 if (S->getContinueParent()) {
2640 // continue ;
2641 Builder.AddTypedTextChunk("continue");
2642 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2643 Results.AddResult(Result(Builder.TakeString()));
2644 }
2645
2646 if (S->getBreakParent()) {
2647 // break ;
2648 Builder.AddTypedTextChunk("break");
2649 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2650 Results.AddResult(Result(Builder.TakeString()));
2651 }
2652
2653 // "return expression ;" or "return ;", depending on the return type.
2654 QualType ReturnType;
2655 if (const auto *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext)) {
2656 if (!Function->getType().isNull())
2657 ReturnType = Function->getReturnType();
2658 } else if (const auto *Method =
2659 dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
2660 ReturnType = Method->getReturnType();
2661 else if (SemaRef.getCurBlock() &&
2662 !SemaRef.getCurBlock()->ReturnType.isNull())
2663 ReturnType = SemaRef.getCurBlock()->ReturnType;;
2664 if (ReturnType.isNull() || ReturnType->isVoidType()) {
2665 Builder.AddTypedTextChunk("return");
2666 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2667 Results.AddResult(Result(Builder.TakeString()));
2668 } else {
2669 assert(!ReturnType.isNull());
2670 // "return expression ;"
2671 Builder.AddTypedTextChunk("return");
2673 Builder.AddPlaceholderChunk("expression");
2674 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2675 Results.AddResult(Result(Builder.TakeString()));
2676 // "co_return expression ;" for coroutines(C++20).
2677 if (SemaRef.getLangOpts().CPlusPlus20) {
2678 Builder.AddTypedTextChunk("co_return");
2680 Builder.AddPlaceholderChunk("expression");
2681 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2682 Results.AddResult(Result(Builder.TakeString()));
2683 }
2684 // When boolean, also add 'return true;' and 'return false;'.
2685 if (ReturnType->isBooleanType()) {
2686 Builder.AddTypedTextChunk("return true");
2687 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2688 Results.AddResult(Result(Builder.TakeString()));
2689
2690 Builder.AddTypedTextChunk("return false");
2691 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2692 Results.AddResult(Result(Builder.TakeString()));
2693 }
2694 // For pointers, suggest 'return nullptr' in C++.
2695 if (SemaRef.getLangOpts().CPlusPlus11 &&
2696 (ReturnType->isPointerType() || ReturnType->isMemberPointerType())) {
2697 Builder.AddTypedTextChunk("return nullptr");
2698 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2699 Results.AddResult(Result(Builder.TakeString()));
2700 }
2701 }
2702
2703 // goto identifier ;
2704 Builder.AddTypedTextChunk("goto");
2706 Builder.AddPlaceholderChunk("label");
2707 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2708 Results.AddResult(Result(Builder.TakeString()));
2709
2710 // Using directives
2711 Builder.AddTypedTextChunk("using namespace");
2713 Builder.AddPlaceholderChunk("identifier");
2714 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2715 Results.AddResult(Result(Builder.TakeString()));
2716
2717 AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
2718 }
2719 [[fallthrough]];
2720
2721 // Fall through (for statement expressions).
2724 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2725 // Fall through: conditions and statements can have expressions.
2726 [[fallthrough]];
2727
2729 if (SemaRef.getLangOpts().ObjCAutoRefCount &&
2731 // (__bridge <type>)<expression>
2732 Builder.AddTypedTextChunk("__bridge");
2734 Builder.AddPlaceholderChunk("type");
2735 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2736 Builder.AddPlaceholderChunk("expression");
2737 Results.AddResult(Result(Builder.TakeString()));
2738
2739 // (__bridge_transfer <Objective-C type>)<expression>
2740 Builder.AddTypedTextChunk("__bridge_transfer");
2742 Builder.AddPlaceholderChunk("Objective-C type");
2743 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2744 Builder.AddPlaceholderChunk("expression");
2745 Results.AddResult(Result(Builder.TakeString()));
2746
2747 // (__bridge_retained <CF type>)<expression>
2748 Builder.AddTypedTextChunk("__bridge_retained");
2750 Builder.AddPlaceholderChunk("CF type");
2751 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2752 Builder.AddPlaceholderChunk("expression");
2753 Results.AddResult(Result(Builder.TakeString()));
2754 }
2755 // Fall through
2756 [[fallthrough]];
2757
2759 if (SemaRef.getLangOpts().CPlusPlus) {
2760 // 'this', if we're in a non-static member function.
2761 addThisCompletion(SemaRef, Results);
2762
2763 // true
2764 Builder.AddResultTypeChunk("bool");
2765 Builder.AddTypedTextChunk("true");
2766 Results.AddResult(Result(Builder.TakeString()));
2767
2768 // false
2769 Builder.AddResultTypeChunk("bool");
2770 Builder.AddTypedTextChunk("false");
2771 Results.AddResult(Result(Builder.TakeString()));
2772
2773 if (SemaRef.getLangOpts().RTTI) {
2774 // dynamic_cast < type-id > ( expression )
2775 Builder.AddTypedTextChunk("dynamic_cast");
2776 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2777 Builder.AddPlaceholderChunk("type");
2778 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2779 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2780 Builder.AddPlaceholderChunk("expression");
2781 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2782 Results.AddResult(Result(Builder.TakeString()));
2783 }
2784
2785 // static_cast < type-id > ( expression )
2786 Builder.AddTypedTextChunk("static_cast");
2787 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2788 Builder.AddPlaceholderChunk("type");
2789 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2790 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2791 Builder.AddPlaceholderChunk("expression");
2792 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2793 Results.AddResult(Result(Builder.TakeString()));
2794
2795 // reinterpret_cast < type-id > ( expression )
2796 Builder.AddTypedTextChunk("reinterpret_cast");
2797 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2798 Builder.AddPlaceholderChunk("type");
2799 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2800 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2801 Builder.AddPlaceholderChunk("expression");
2802 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2803 Results.AddResult(Result(Builder.TakeString()));
2804
2805 // const_cast < type-id > ( expression )
2806 Builder.AddTypedTextChunk("const_cast");
2807 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2808 Builder.AddPlaceholderChunk("type");
2809 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2810 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2811 Builder.AddPlaceholderChunk("expression");
2812 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2813 Results.AddResult(Result(Builder.TakeString()));
2814
2815 if (SemaRef.getLangOpts().RTTI) {
2816 // typeid ( expression-or-type )
2817 Builder.AddResultTypeChunk("std::type_info");
2818 Builder.AddTypedTextChunk("typeid");
2819 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2820 Builder.AddPlaceholderChunk("expression-or-type");
2821 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2822 Results.AddResult(Result(Builder.TakeString()));
2823 }
2824
2825 // new T ( ... )
2826 Builder.AddTypedTextChunk("new");
2828 Builder.AddPlaceholderChunk("type");
2829 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2830 Builder.AddPlaceholderChunk("expressions");
2831 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2832 Results.AddResult(Result(Builder.TakeString()));
2833
2834 // new T [ ] ( ... )
2835 Builder.AddTypedTextChunk("new");
2837 Builder.AddPlaceholderChunk("type");
2838 Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
2839 Builder.AddPlaceholderChunk("size");
2840 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
2841 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2842 Builder.AddPlaceholderChunk("expressions");
2843 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2844 Results.AddResult(Result(Builder.TakeString()));
2845
2846 // delete expression
2847 Builder.AddResultTypeChunk("void");
2848 Builder.AddTypedTextChunk("delete");
2850 Builder.AddPlaceholderChunk("expression");
2851 Results.AddResult(Result(Builder.TakeString()));
2852
2853 // delete [] expression
2854 Builder.AddResultTypeChunk("void");
2855 Builder.AddTypedTextChunk("delete");
2857 Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
2858 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
2860 Builder.AddPlaceholderChunk("expression");
2861 Results.AddResult(Result(Builder.TakeString()));
2862
2863 if (SemaRef.getLangOpts().CXXExceptions) {
2864 // throw expression
2865 Builder.AddResultTypeChunk("void");
2866 Builder.AddTypedTextChunk("throw");
2868 Builder.AddPlaceholderChunk("expression");
2869 Results.AddResult(Result(Builder.TakeString()));
2870 }
2871
2872 // FIXME: Rethrow?
2873
2874 if (SemaRef.getLangOpts().CPlusPlus11) {
2875 // nullptr
2876 Builder.AddResultTypeChunk("std::nullptr_t");
2877 Builder.AddTypedTextChunk("nullptr");
2878 Results.AddResult(Result(Builder.TakeString()));
2879
2880 // alignof
2881 Builder.AddResultTypeChunk("size_t");
2882 Builder.AddTypedTextChunk("alignof");
2883 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2884 Builder.AddPlaceholderChunk("type");
2885 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2886 Results.AddResult(Result(Builder.TakeString()));
2887
2888 // noexcept
2889 Builder.AddResultTypeChunk("bool");
2890 Builder.AddTypedTextChunk("noexcept");
2891 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2892 Builder.AddPlaceholderChunk("expression");
2893 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2894 Results.AddResult(Result(Builder.TakeString()));
2895
2896 // sizeof... expression
2897 Builder.AddResultTypeChunk("size_t");
2898 Builder.AddTypedTextChunk("sizeof...");
2899 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2900 Builder.AddPlaceholderChunk("parameter-pack");
2901 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2902 Results.AddResult(Result(Builder.TakeString()));
2903 }
2904
2905 if (SemaRef.getLangOpts().CPlusPlus20) {
2906 // co_await expression
2907 Builder.AddTypedTextChunk("co_await");
2909 Builder.AddPlaceholderChunk("expression");
2910 Results.AddResult(Result(Builder.TakeString()));
2911
2912 // co_yield expression
2913 Builder.AddTypedTextChunk("co_yield");
2915 Builder.AddPlaceholderChunk("expression");
2916 Results.AddResult(Result(Builder.TakeString()));
2917
2918 // requires (parameters) { requirements }
2919 Builder.AddResultTypeChunk("bool");
2920 Builder.AddTypedTextChunk("requires");
2922 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2923 Builder.AddPlaceholderChunk("parameters");
2924 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2926 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2928 Builder.AddPlaceholderChunk("requirements");
2930 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2931 Results.AddResult(Result(Builder.TakeString()));
2932
2933 if (SemaRef.CurContext->isRequiresExprBody()) {
2934 // requires expression ;
2935 Builder.AddTypedTextChunk("requires");
2937 Builder.AddPlaceholderChunk("expression");
2938 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2939 Results.AddResult(Result(Builder.TakeString()));
2940 }
2941 }
2942 }
2943
2944 if (SemaRef.getLangOpts().ObjC) {
2945 // Add "super", if we're in an Objective-C class with a superclass.
2946 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
2947 // The interface can be NULL.
2948 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
2949 if (ID->getSuperClass()) {
2950 std::string SuperType;
2951 SuperType = ID->getSuperClass()->getNameAsString();
2952 if (Method->isInstanceMethod())
2953 SuperType += " *";
2954
2955 Builder.AddResultTypeChunk(Allocator.CopyString(SuperType));
2956 Builder.AddTypedTextChunk("super");
2957 Results.AddResult(Result(Builder.TakeString()));
2958 }
2959 }
2960
2961 AddObjCExpressionResults(Results, true);
2962 }
2963
2964 if (SemaRef.getLangOpts().C11) {
2965 // _Alignof
2966 Builder.AddResultTypeChunk("size_t");
2967 if (SemaRef.PP.isMacroDefined("alignof"))
2968 Builder.AddTypedTextChunk("alignof");
2969 else
2970 Builder.AddTypedTextChunk("_Alignof");
2971 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2972 Builder.AddPlaceholderChunk("type");
2973 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2974 Results.AddResult(Result(Builder.TakeString()));
2975 }
2976
2977 if (SemaRef.getLangOpts().C23) {
2978 // nullptr
2979 Builder.AddResultTypeChunk("nullptr_t");
2980 Builder.AddTypedTextChunk("nullptr");
2981 Results.AddResult(Result(Builder.TakeString()));
2982 }
2983
2984 // sizeof expression
2985 Builder.AddResultTypeChunk("size_t");
2986 Builder.AddTypedTextChunk("sizeof");
2987 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2988 Builder.AddPlaceholderChunk("expression-or-type");
2989 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2990 Results.AddResult(Result(Builder.TakeString()));
2991 break;
2992 }
2993
2996 break;
2997 }
2998
2999 if (WantTypesInContext(CCC, SemaRef.getLangOpts()))
3000 AddTypeSpecifierResults(SemaRef.getLangOpts(), Results);
3001
3002 if (SemaRef.getLangOpts().CPlusPlus && CCC != SemaCodeCompletion::PCC_Type)
3003 Results.AddResult(Result("operator"));
3004}
3005
3006/// If the given declaration has an associated type, add it as a result
3007/// type chunk.
3008static void AddResultTypeChunk(ASTContext &Context,
3009 const PrintingPolicy &Policy,
3010 const NamedDecl *ND, QualType BaseType,
3012 if (!ND)
3013 return;
3014
3015 // Skip constructors and conversion functions, which have their return types
3016 // built into their names.
3018 return;
3019
3020 // Determine the type of the declaration (if it has a type).
3021 QualType T;
3022 if (const FunctionDecl *Function = ND->getAsFunction())
3023 T = Function->getReturnType();
3024 else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) {
3025 if (!BaseType.isNull())
3026 T = Method->getSendResultType(BaseType);
3027 else
3028 T = Method->getReturnType();
3029 } else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND)) {
3030 T = Context.getCanonicalTagType(
3031 cast<EnumDecl>(Enumerator->getDeclContext()));
3032 } else if (isa<UnresolvedUsingValueDecl>(ND)) {
3033 /* Do nothing: ignore unresolved using declarations*/
3034 } else if (const auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) {
3035 if (!BaseType.isNull())
3036 T = Ivar->getUsageType(BaseType);
3037 else
3038 T = Ivar->getType();
3039 } else if (const auto *Value = dyn_cast<ValueDecl>(ND)) {
3040 T = Value->getType();
3041 } else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND)) {
3042 if (!BaseType.isNull())
3043 T = Property->getUsageType(BaseType);
3044 else
3045 T = Property->getType();
3046 }
3047
3048 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
3049 return;
3050
3051 Result.AddResultTypeChunk(
3052 GetCompletionTypeString(T, Context, Policy, Result.getAllocator()));
3053}
3054
3056 const NamedDecl *FunctionOrMethod,
3058 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
3059 if (Sentinel->getSentinel() == 0) {
3060 if (PP.getLangOpts().ObjC && PP.isMacroDefined("nil"))
3061 Result.AddTextChunk(", nil");
3062 else if (PP.isMacroDefined("NULL"))
3063 Result.AddTextChunk(", NULL");
3064 else
3065 Result.AddTextChunk(", (void*)0");
3066 }
3067}
3068
3069static std::string formatObjCParamQualifiers(unsigned ObjCQuals,
3070 QualType &Type) {
3071 std::string Result;
3072 if (ObjCQuals & Decl::OBJC_TQ_In)
3073 Result += "in ";
3074 else if (ObjCQuals & Decl::OBJC_TQ_Inout)
3075 Result += "inout ";
3076 else if (ObjCQuals & Decl::OBJC_TQ_Out)
3077 Result += "out ";
3078 if (ObjCQuals & Decl::OBJC_TQ_Bycopy)
3079 Result += "bycopy ";
3080 else if (ObjCQuals & Decl::OBJC_TQ_Byref)
3081 Result += "byref ";
3082 if (ObjCQuals & Decl::OBJC_TQ_Oneway)
3083 Result += "oneway ";
3084 if (ObjCQuals & Decl::OBJC_TQ_CSNullability) {
3085 if (auto nullability = AttributedType::stripOuterNullability(Type)) {
3086 switch (*nullability) {
3088 Result += "nonnull ";
3089 break;
3090
3092 Result += "nullable ";
3093 break;
3094
3096 Result += "null_unspecified ";
3097 break;
3098
3100 llvm_unreachable("Not supported as a context-sensitive keyword!");
3101 break;
3102 }
3103 }
3104 }
3105 return Result;
3106}
3107
3108/// Tries to find the most appropriate type location for an Objective-C
3109/// block placeholder.
3110///
3111/// This function ignores things like typedefs and qualifiers in order to
3112/// present the most relevant and accurate block placeholders in code completion
3113/// results.
3116 FunctionProtoTypeLoc &BlockProto,
3117 bool SuppressBlock = false) {
3118 if (!TSInfo)
3119 return;
3120 TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
3121 while (true) {
3122 // Look through typedefs.
3123 if (!SuppressBlock) {
3124 if (TypedefTypeLoc TypedefTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
3125 if (TypeSourceInfo *InnerTSInfo =
3126 TypedefTL.getDecl()->getTypeSourceInfo()) {
3127 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
3128 continue;
3129 }
3130 }
3131
3132 // Look through qualified types
3133 if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) {
3134 TL = QualifiedTL.getUnqualifiedLoc();
3135 continue;
3136 }
3137
3138 if (AttributedTypeLoc AttrTL = TL.getAs<AttributedTypeLoc>()) {
3139 TL = AttrTL.getModifiedLoc();
3140 continue;
3141 }
3142 }
3143
3144 // Try to get the function prototype behind the block pointer type,
3145 // then we're done.
3146 if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) {
3147 TL = BlockPtr.getPointeeLoc().IgnoreParens();
3148 Block = TL.getAs<FunctionTypeLoc>();
3149 BlockProto = TL.getAs<FunctionProtoTypeLoc>();
3150 }
3151 break;
3152 }
3153}
3154
3155static std::string formatBlockPlaceholder(
3156 const PrintingPolicy &Policy, const NamedDecl *BlockDecl,
3158 bool SuppressBlockName = false, bool SuppressBlock = false,
3159 std::optional<ArrayRef<QualType>> ObjCSubsts = std::nullopt);
3160
3161static std::string FormatFunctionParameter(
3162 const PrintingPolicy &Policy, const DeclaratorDecl *Param,
3163 bool SuppressName = false, bool SuppressBlock = false,
3164 std::optional<ArrayRef<QualType>> ObjCSubsts = std::nullopt) {
3165 // Params are unavailable in FunctionTypeLoc if the FunctionType is invalid.
3166 // It would be better to pass in the param Type, which is usually available.
3167 // But this case is rare, so just pretend we fell back to int as elsewhere.
3168 if (!Param)
3169 return "int";
3171 if (const auto *PVD = dyn_cast<ParmVarDecl>(Param))
3172 ObjCQual = PVD->getObjCDeclQualifier();
3173 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
3174 if (Param->getType()->isDependentType() ||
3175 !Param->getType()->isBlockPointerType()) {
3176 // The argument for a dependent or non-block parameter is a placeholder
3177 // containing that parameter's type.
3178 std::string Result;
3179
3180 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
3181 Result = std::string(Param->getIdentifier()->deuglifiedName());
3182
3183 QualType Type = Param->getType();
3184 if (ObjCSubsts)
3185 Type = Type.substObjCTypeArgs(Param->getASTContext(), *ObjCSubsts,
3187 if (ObjCMethodParam) {
3188 Result = "(" + formatObjCParamQualifiers(ObjCQual, Type);
3189 Result += Type.getAsString(Policy) + ")";
3190 if (Param->getIdentifier() && !SuppressName)
3191 Result += Param->getIdentifier()->deuglifiedName();
3192 } else {
3193 Type.getAsStringInternal(Result, Policy);
3194 }
3195 return Result;
3196 }
3197
3198 // The argument for a block pointer parameter is a block literal with
3199 // the appropriate type.
3201 FunctionProtoTypeLoc BlockProto;
3202 findTypeLocationForBlockDecl(Param->getTypeSourceInfo(), Block, BlockProto,
3203 SuppressBlock);
3204 // Try to retrieve the block type information from the property if this is a
3205 // parameter in a setter.
3206 if (!Block && ObjCMethodParam &&
3207 cast<ObjCMethodDecl>(Param->getDeclContext())->isPropertyAccessor()) {
3208 if (const auto *PD = cast<ObjCMethodDecl>(Param->getDeclContext())
3209 ->findPropertyDecl(/*CheckOverrides=*/false))
3210 findTypeLocationForBlockDecl(PD->getTypeSourceInfo(), Block, BlockProto,
3211 SuppressBlock);
3212 }
3213
3214 if (!Block) {
3215 // We were unable to find a FunctionProtoTypeLoc with parameter names
3216 // for the block; just use the parameter type as a placeholder.
3217 std::string Result;
3218 if (!ObjCMethodParam && Param->getIdentifier())
3219 Result = std::string(Param->getIdentifier()->deuglifiedName());
3220
3221 QualType Type = Param->getType().getUnqualifiedType();
3222
3223 if (ObjCMethodParam) {
3224 Result = Type.getAsString(Policy);
3225 std::string Quals = formatObjCParamQualifiers(ObjCQual, Type);
3226 if (!Quals.empty())
3227 Result = "(" + Quals + " " + Result + ")";
3228 if (Result.back() != ')')
3229 Result += " ";
3230 if (Param->getIdentifier())
3231 Result += Param->getIdentifier()->deuglifiedName();
3232 } else {
3233 Type.getAsStringInternal(Result, Policy);
3234 }
3235
3236 return Result;
3237 }
3238
3239 // We have the function prototype behind the block pointer type, as it was
3240 // written in the source.
3241 return formatBlockPlaceholder(Policy, Param, Block, BlockProto,
3242 /*SuppressBlockName=*/false, SuppressBlock,
3243 ObjCSubsts);
3244}
3245
3246/// Returns a placeholder string that corresponds to an Objective-C block
3247/// declaration.
3248///
3249/// \param BlockDecl A declaration with an Objective-C block type.
3250///
3251/// \param Block The most relevant type location for that block type.
3252///
3253/// \param SuppressBlockName Determines whether or not the name of the block
3254/// declaration is included in the resulting string.
3255static std::string
3258 bool SuppressBlockName, bool SuppressBlock,
3259 std::optional<ArrayRef<QualType>> ObjCSubsts) {
3260 std::string Result;
3261 QualType ResultType = Block.getTypePtr()->getReturnType();
3262 if (ObjCSubsts)
3263 ResultType =
3264 ResultType.substObjCTypeArgs(BlockDecl->getASTContext(), *ObjCSubsts,
3266 if (!ResultType->isVoidType() || SuppressBlock)
3267 ResultType.getAsStringInternal(Result, Policy);
3268
3269 // Format the parameter list.
3270 std::string Params;
3271 if (!BlockProto || Block.getNumParams() == 0) {
3272 if (BlockProto && BlockProto.getTypePtr()->isVariadic())
3273 Params = "(...)";
3274 else
3275 Params = "(void)";
3276 } else {
3277 Params += "(";
3278 for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) {
3279 if (I)
3280 Params += ", ";
3281 Params += FormatFunctionParameter(Policy, Block.getParam(I),
3282 /*SuppressName=*/false,
3283 /*SuppressBlock=*/true, ObjCSubsts);
3284
3285 if (I == N - 1 && BlockProto.getTypePtr()->isVariadic())
3286 Params += ", ...";
3287 }
3288 Params += ")";
3289 }
3290
3291 if (SuppressBlock) {
3292 // Format as a parameter.
3293 Result = Result + " (^";
3294 if (!SuppressBlockName && BlockDecl->getIdentifier())
3295 Result += BlockDecl->getIdentifier()->getName();
3296 Result += ")";
3297 Result += Params;
3298 } else {
3299 // Format as a block literal argument.
3300 Result = '^' + Result;
3301 Result += Params;
3302
3303 if (!SuppressBlockName && BlockDecl->getIdentifier())
3304 Result += BlockDecl->getIdentifier()->getName();
3305 }
3306
3307 return Result;
3308}
3309
3310static std::string GetDefaultValueString(const ParmVarDecl *Param,
3311 const SourceManager &SM,
3312 const LangOptions &LangOpts) {
3313 const SourceRange SrcRange = Param->getDefaultArgRange();
3314 CharSourceRange CharSrcRange = CharSourceRange::getTokenRange(SrcRange);
3315 bool Invalid = CharSrcRange.isInvalid();
3316 if (Invalid)
3317 return "";
3318 StringRef srcText =
3319 Lexer::getSourceText(CharSrcRange, SM, LangOpts, &Invalid);
3320 if (Invalid)
3321 return "";
3322
3323 if (srcText.empty() || srcText == "=") {
3324 // Lexer can't determine the value.
3325 // This happens if the code is incorrect (for example class is forward
3326 // declared).
3327 return "";
3328 }
3329 std::string DefValue(srcText.str());
3330 // FIXME: remove this check if the Lexer::getSourceText value is fixed and
3331 // this value always has (or always does not have) '=' in front of it
3332 if (DefValue.at(0) != '=') {
3333 // If we don't have '=' in front of value.
3334 // Lexer returns built-in types values without '=' and user-defined types
3335 // values with it.
3336 return " = " + DefValue;
3337 }
3338 return " " + DefValue;
3339}
3340
3341/// Add function parameter chunks to the given code completion string.
3343 Preprocessor &PP, const PrintingPolicy &Policy,
3344 const FunctionDecl *Function, CodeCompletionBuilder &Result,
3345 unsigned Start = 0, bool InOptional = false, bool FunctionCanBeCall = true,
3346 bool IsInDeclarationContext = false) {
3347 bool FirstParameter = true;
3348 bool AsInformativeChunk = !(FunctionCanBeCall || IsInDeclarationContext);
3349
3350 const FunctionDecl *BetterSignatureDecl = BetterSignature(Function, Start);
3351
3352 for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) {
3353 const ParmVarDecl *Param = BetterSignatureDecl->getParamDecl(P);
3354
3355 if (Param->hasDefaultArg() && !InOptional && !IsInDeclarationContext &&
3356 !AsInformativeChunk) {
3357 // When we see an optional default argument, put that argument and
3358 // the remaining default arguments into a new, optional string.
3359 CodeCompletionBuilder Opt(Result.getAllocator(),
3360 Result.getCodeCompletionTUInfo());
3361 if (!FirstParameter)
3363 AddFunctionParameterChunks(PP, Policy, Function, Opt, P, true);
3364 Result.AddOptionalChunk(Opt.TakeString());
3365 break;
3366 }
3367
3368 // C++23 introduces an explicit object parameter, a.k.a. "deducing this"
3369 // Skip it for autocomplete and treat the next parameter as the first
3370 // parameter
3371 if (FirstParameter && Param->isExplicitObjectParameter()) {
3372 continue;
3373 }
3374
3375 if (FirstParameter)
3376 FirstParameter = false;
3377 else {
3378 if (AsInformativeChunk)
3379 Result.AddInformativeChunk(", ");
3380 else
3382 }
3383
3384 InOptional = false;
3385
3386 // Format the placeholder string.
3387 std::string PlaceholderStr = FormatFunctionParameter(Policy, Param);
3388 std::string DefaultValue;
3389 if (Param->hasDefaultArg()) {
3390 if (IsInDeclarationContext)
3391 DefaultValue = GetDefaultValueString(Param, PP.getSourceManager(),
3392 PP.getLangOpts());
3393 else
3394 PlaceholderStr += GetDefaultValueString(Param, PP.getSourceManager(),
3395 PP.getLangOpts());
3396 }
3397
3398 if (Function->isVariadic() && P == N - 1)
3399 PlaceholderStr += ", ...";
3400
3401 // Add the placeholder string.
3402 if (AsInformativeChunk)
3403 Result.AddInformativeChunk(
3404 Result.getAllocator().CopyString(PlaceholderStr));
3405 else if (IsInDeclarationContext) { // No placeholders in declaration context
3406 Result.AddTextChunk(Result.getAllocator().CopyString(PlaceholderStr));
3407 if (DefaultValue.length() != 0)
3408 Result.AddInformativeChunk(
3409 Result.getAllocator().CopyString(DefaultValue));
3410 } else
3411 Result.AddPlaceholderChunk(
3412 Result.getAllocator().CopyString(PlaceholderStr));
3413 }
3414
3415 if (const auto *Proto = Function->getType()->getAs<FunctionProtoType>())
3416 if (Proto->isVariadic()) {
3417 if (Proto->getNumParams() == 0)
3418 Result.AddPlaceholderChunk("...");
3419
3420 MaybeAddSentinel(PP, Function, Result);
3421 }
3422}
3423
3424/// Add template parameter chunks to the given code completion string.
3426 ASTContext &Context, const PrintingPolicy &Policy,
3428 unsigned MaxParameters = 0, unsigned Start = 0, bool InDefaultArg = false,
3429 bool AsInformativeChunk = false) {
3430 bool FirstParameter = true;
3431
3432 // Prefer to take the template parameter names from the first declaration of
3433 // the template.
3434 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
3435
3436 TemplateParameterList *Params = Template->getTemplateParameters();
3437 TemplateParameterList::iterator PEnd = Params->end();
3438 if (MaxParameters)
3439 PEnd = Params->begin() + MaxParameters;
3440 for (TemplateParameterList::iterator P = Params->begin() + Start; P != PEnd;
3441 ++P) {
3442 bool HasDefaultArg = false;
3443 std::string PlaceholderStr;
3444 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
3445 if (TTP->wasDeclaredWithTypename())
3446 PlaceholderStr = "typename";
3447 else if (const auto *TC = TTP->getTypeConstraint()) {
3448 llvm::raw_string_ostream OS(PlaceholderStr);
3449 TC->print(OS, Policy);
3450 } else
3451 PlaceholderStr = "class";
3452
3453 if (TTP->getIdentifier()) {
3454 PlaceholderStr += ' ';
3455 PlaceholderStr += TTP->getIdentifier()->deuglifiedName();
3456 }
3457
3458 HasDefaultArg = TTP->hasDefaultArgument();
3459 } else if (NonTypeTemplateParmDecl *NTTP =
3460 dyn_cast<NonTypeTemplateParmDecl>(*P)) {
3461 if (NTTP->getIdentifier())
3462 PlaceholderStr = std::string(NTTP->getIdentifier()->deuglifiedName());
3463 NTTP->getType().getAsStringInternal(PlaceholderStr, Policy);
3464 HasDefaultArg = NTTP->hasDefaultArgument();
3465 } else {
3468
3469 // Since putting the template argument list into the placeholder would
3470 // be very, very long, we just use an abbreviation.
3471 PlaceholderStr = "template<...> class";
3472 if (TTP->getIdentifier()) {
3473 PlaceholderStr += ' ';
3474 PlaceholderStr += TTP->getIdentifier()->deuglifiedName();
3475 }
3476
3477 HasDefaultArg = TTP->hasDefaultArgument();
3478 }
3479
3480 if (HasDefaultArg && !InDefaultArg && !AsInformativeChunk) {
3481 // When we see an optional default argument, put that argument and
3482 // the remaining default arguments into a new, optional string.
3483 CodeCompletionBuilder Opt(Result.getAllocator(),
3484 Result.getCodeCompletionTUInfo());
3485 if (!FirstParameter)
3487 AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
3488 P - Params->begin(), true);
3489 Result.AddOptionalChunk(Opt.TakeString());
3490 break;
3491 }
3492
3493 InDefaultArg = false;
3494
3495 if (FirstParameter)
3496 FirstParameter = false;
3497 else {
3498 if (AsInformativeChunk)
3499 Result.AddInformativeChunk(", ");
3500 else
3502 }
3503
3504 if (AsInformativeChunk)
3505 Result.AddInformativeChunk(
3506 Result.getAllocator().CopyString(PlaceholderStr));
3507 else // Add the placeholder string.
3508 Result.AddPlaceholderChunk(
3509 Result.getAllocator().CopyString(PlaceholderStr));
3510 }
3511}
3512
3513/// Add a qualifier to the given code-completion string, if the
3514/// provided nested-name-specifier is non-NULL.
3516 NestedNameSpecifier Qualifier,
3517 bool QualifierIsInformative,
3518 ASTContext &Context,
3519 const PrintingPolicy &Policy) {
3520 if (!Qualifier)
3521 return;
3522
3523 std::string PrintedNNS;
3524 {
3525 llvm::raw_string_ostream OS(PrintedNNS);
3526 Qualifier.print(OS, Policy);
3527 }
3528 if (QualifierIsInformative)
3529 Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS));
3530 else
3531 Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS));
3532}
3533
3535 const Qualifiers Quals,
3536 bool AsInformativeChunk = true) {
3537 // FIXME: Add ref-qualifier!
3538
3539 // Handle single qualifiers without copying
3540 if (Quals.hasOnlyConst()) {
3541 if (AsInformativeChunk)
3542 Result.AddInformativeChunk(" const");
3543 else
3544 Result.AddTextChunk(" const");
3545 return;
3546 }
3547
3548 if (Quals.hasOnlyVolatile()) {
3549 if (AsInformativeChunk)
3550 Result.AddInformativeChunk(" volatile");
3551 else
3552 Result.AddTextChunk(" volatile");
3553 return;
3554 }
3555
3556 if (Quals.hasOnlyRestrict()) {
3557 if (AsInformativeChunk)
3558 Result.AddInformativeChunk(" restrict");
3559 else
3560 Result.AddTextChunk(" restrict");
3561 return;
3562 }
3563
3564 // Handle multiple qualifiers.
3565 std::string QualsStr;
3566 if (Quals.hasConst())
3567 QualsStr += " const";
3568 if (Quals.hasVolatile())
3569 QualsStr += " volatile";
3570 if (Quals.hasRestrict())
3571 QualsStr += " restrict";
3572
3573 if (AsInformativeChunk)
3574 Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
3575 else
3576 Result.AddTextChunk(Result.getAllocator().CopyString(QualsStr));
3577}
3578
3579static void
3581 const FunctionDecl *Function,
3582 bool AsInformativeChunks = true) {
3583 if (auto *CxxMethodDecl = llvm::dyn_cast_if_present<CXXMethodDecl>(Function);
3584 CxxMethodDecl && CxxMethodDecl->hasCXXExplicitFunctionObjectParameter()) {
3585 // if explicit object method, infer quals from the object parameter
3586 const auto Quals = CxxMethodDecl->getFunctionObjectParameterType();
3587 if (!Quals.hasQualifiers())
3588 return;
3589
3590 AddFunctionTypeQuals(Result, Quals.getQualifiers(), AsInformativeChunks);
3591 } else {
3592 const auto *Proto = Function->getType()->getAs<FunctionProtoType>();
3593 if (!Proto || !Proto->getMethodQuals())
3594 return;
3595
3596 AddFunctionTypeQuals(Result, Proto->getMethodQuals(), AsInformativeChunks);
3597 }
3598}
3599
3600static void
3601AddFunctionExceptSpecToCompletionString(std::string &NameAndSignature,
3602 const FunctionDecl *Function) {
3603 const auto *Proto = Function->getType()->getAs<FunctionProtoType>();
3604 if (!Proto)
3605 return;
3606
3607 auto ExceptInfo = Proto->getExceptionSpecInfo();
3608 switch (ExceptInfo.Type) {
3609 case EST_BasicNoexcept:
3610 case EST_NoexceptTrue:
3611 NameAndSignature += " noexcept";
3612 break;
3613
3614 default:
3615 break;
3616 }
3617}
3618
3619/// Add the name of the given declaration
3620static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
3621 const NamedDecl *ND,
3623 DeclarationName Name = ND->getDeclName();
3624 if (!Name)
3625 return;
3626
3627 switch (Name.getNameKind()) {
3629 const char *OperatorName = nullptr;
3630 switch (Name.getCXXOverloadedOperator()) {
3631 case OO_None:
3632 case OO_Conditional:
3634 OperatorName = "operator";
3635 break;
3636
3637#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
3638 case OO_##Name: \
3639 OperatorName = "operator" Spelling; \
3640 break;
3641#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemberOnly)
3642#include "clang/Basic/OperatorKinds.def"
3643
3644 case OO_New:
3645 OperatorName = "operator new";
3646 break;
3647 case OO_Delete:
3648 OperatorName = "operator delete";
3649 break;
3650 case OO_Array_New:
3651 OperatorName = "operator new[]";
3652 break;
3653 case OO_Array_Delete:
3654 OperatorName = "operator delete[]";
3655 break;
3656 case OO_Call:
3657 OperatorName = "operator()";
3658 break;
3659 case OO_Subscript:
3660 OperatorName = "operator[]";
3661 break;
3662 }
3663 Result.AddTypedTextChunk(OperatorName);
3664 break;
3665 }
3666
3671 Result.AddTypedTextChunk(
3672 Result.getAllocator().CopyString(ND->getNameAsString()));
3673 break;
3674
3680 break;
3681
3683 CXXRecordDecl *Record = nullptr;
3684 QualType Ty = Name.getCXXNameType();
3685 if (auto *RD = Ty->getAsCXXRecordDecl()) {
3686 Record = RD;
3687 } else {
3688 Result.AddTypedTextChunk(
3689 Result.getAllocator().CopyString(ND->getNameAsString()));
3690 break;
3691 }
3692
3693 Result.AddTypedTextChunk(
3694 Result.getAllocator().CopyString(Record->getNameAsString()));
3695 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
3697 AddTemplateParameterChunks(Context, Policy, Template, Result);
3699 }
3700 break;
3701 }
3702 }
3703}
3704
3706 Sema &S, const CodeCompletionContext &CCContext,
3707 CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
3708 bool IncludeBriefComments) {
3709 return CreateCodeCompletionString(S.Context, S.PP, CCContext, Allocator,
3710 CCTUInfo, IncludeBriefComments);
3711}
3712
3714 Preprocessor &PP, CodeCompletionAllocator &Allocator,
3715 CodeCompletionTUInfo &CCTUInfo) {
3716 assert(Kind == RK_Macro);
3717 CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
3718 const MacroInfo *MI = PP.getMacroInfo(Macro);
3719 Result.AddTypedTextChunk(Result.getAllocator().CopyString(Macro->getName()));
3720
3721 if (!MI || !MI->isFunctionLike())
3722 return Result.TakeString();
3723
3724 // Format a function-like macro with placeholders for the arguments.
3726 MacroInfo::param_iterator A = MI->param_begin(), AEnd = MI->param_end();
3727
3728 // C99 variadic macros add __VA_ARGS__ at the end. Skip it.
3729 if (MI->isC99Varargs()) {
3730 --AEnd;
3731
3732 if (A == AEnd) {
3733 Result.AddPlaceholderChunk("...");
3734 }
3735 }
3736
3737 for (MacroInfo::param_iterator A = MI->param_begin(); A != AEnd; ++A) {
3738 if (A != MI->param_begin())
3740
3741 if (MI->isVariadic() && (A + 1) == AEnd) {
3742 SmallString<32> Arg = (*A)->getName();
3743 if (MI->isC99Varargs())
3744 Arg += ", ...";
3745 else
3746 Arg += "...";
3747 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
3748 break;
3749 }
3750
3751 // Non-variadic macros are simple.
3752 Result.AddPlaceholderChunk(
3753 Result.getAllocator().CopyString((*A)->getName()));
3754 }
3756 return Result.TakeString();
3757}
3758
3759/// If possible, create a new code completion string for the given
3760/// result.
3761///
3762/// \returns Either a new, heap-allocated code completion string describing
3763/// how to use this result, or NULL to indicate that the string or name of the
3764/// result is all that is needed.
3766 ASTContext &Ctx, Preprocessor &PP, const CodeCompletionContext &CCContext,
3767 CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
3768 bool IncludeBriefComments) {
3769 if (Kind == RK_Macro)
3770 return CreateCodeCompletionStringForMacro(PP, Allocator, CCTUInfo);
3771
3772 CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
3773
3775 if (Kind == RK_Pattern) {
3776 Pattern->Priority = Priority;
3777 Pattern->Availability = Availability;
3778
3779 if (Declaration) {
3780 Result.addParentContext(Declaration->getDeclContext());
3781 Pattern->ParentName = Result.getParentName();
3782 if (const RawComment *RC =
3784 Result.addBriefComment(RC->getBriefText(Ctx));
3785 Pattern->BriefComment = Result.getBriefComment();
3786 }
3787 }
3788
3789 return Pattern;
3790 }
3791
3792 if (Kind == RK_Keyword) {
3793 Result.AddTypedTextChunk(Keyword);
3794 return Result.TakeString();
3795 }
3796 assert(Kind == RK_Declaration && "Missed a result kind?");
3798 PP, Ctx, Result, IncludeBriefComments, CCContext, Policy);
3799}
3800
3802 std::string &BeforeName,
3803 std::string &NameAndSignature) {
3804 bool SeenTypedChunk = false;
3805 for (auto &Chunk : CCS) {
3806 if (Chunk.Kind == CodeCompletionString::CK_Optional) {
3807 assert(SeenTypedChunk && "optional parameter before name");
3808 // Note that we put all chunks inside into NameAndSignature.
3809 printOverrideString(*Chunk.Optional, NameAndSignature, NameAndSignature);
3810 continue;
3811 }
3812 SeenTypedChunk |= Chunk.Kind == CodeCompletionString::CK_TypedText;
3813 if (SeenTypedChunk)
3814 NameAndSignature += Chunk.Text;
3815 else
3816 BeforeName += Chunk.Text;
3817 }
3818}
3819
3823 bool IncludeBriefComments, const CodeCompletionContext &CCContext,
3824 PrintingPolicy &Policy) {
3825 auto *CCS = createCodeCompletionStringForDecl(PP, Ctx, Result,
3826 /*IncludeBriefComments=*/false,
3827 CCContext, Policy);
3828 std::string BeforeName;
3829 std::string NameAndSignature;
3830 // For overrides all chunks go into the result, none are informative.
3831 printOverrideString(*CCS, BeforeName, NameAndSignature);
3832
3833 // If the virtual function is declared with "noexcept", add it in the result
3834 // code completion string.
3835 const auto *VirtualFunc = dyn_cast<FunctionDecl>(Declaration);
3836 assert(VirtualFunc && "overridden decl must be a function");
3837 AddFunctionExceptSpecToCompletionString(NameAndSignature, VirtualFunc);
3838
3839 NameAndSignature += " override";
3840
3841 Result.AddTextChunk(Result.getAllocator().CopyString(BeforeName));
3843 Result.AddTypedTextChunk(Result.getAllocator().CopyString(NameAndSignature));
3844 return Result.TakeString();
3845}
3846
3847// FIXME: Right now this works well with lambdas. Add support for other functor
3848// types like std::function.
3850 const auto *VD = dyn_cast<VarDecl>(ND);
3851 if (!VD)
3852 return nullptr;
3853 const auto *RecordDecl = VD->getType()->getAsCXXRecordDecl();
3854 if (!RecordDecl || !RecordDecl->isLambda())
3855 return nullptr;
3856 return RecordDecl->getLambdaCallOperator();
3857}
3858
3861 bool IncludeBriefComments, const CodeCompletionContext &CCContext,
3862 PrintingPolicy &Policy) {
3863 const NamedDecl *ND = Declaration;
3864 Result.addParentContext(ND->getDeclContext());
3865
3866 if (IncludeBriefComments) {
3867 // Add documentation comment, if it exists.
3868 if (const RawComment *RC = getCompletionComment(Ctx, Declaration)) {
3869 Result.addBriefComment(RC->getBriefText(Ctx));
3870 }
3871 }
3872
3874 Result.AddTypedTextChunk(
3875 Result.getAllocator().CopyString(ND->getNameAsString()));
3876 Result.AddTextChunk("::");
3877 return Result.TakeString();
3878 }
3879
3880 for (const auto *I : ND->specific_attrs<AnnotateAttr>())
3881 Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation()));
3882
3883 auto AddFunctionTypeAndResult = [&](const FunctionDecl *Function) {
3884 AddResultTypeChunk(Ctx, Policy, Function, CCContext.getBaseType(), Result);
3886 Ctx, Policy);
3887 AddTypedNameChunk(Ctx, Policy, ND, Result);
3888 bool InsertParameters = FunctionCanBeCall || DeclaringEntity;
3889 if (InsertParameters)
3891 else
3892 Result.AddInformativeChunk("(");
3893 AddFunctionParameterChunks(PP, Policy, Function, Result, /*Start=*/0,
3894 /*InOptional=*/false,
3895 /*FunctionCanBeCall=*/FunctionCanBeCall,
3896 /*IsInDeclarationContext=*/DeclaringEntity);
3897 if (InsertParameters)
3899 else
3900 Result.AddInformativeChunk(")");
3902 Result, Function, /*AsInformativeChunks=*/!DeclaringEntity);
3903 };
3904
3905 if (const auto *Function = dyn_cast<FunctionDecl>(ND)) {
3906 AddFunctionTypeAndResult(Function);
3907 return Result.TakeString();
3908 }
3909
3910 if (const auto *CallOperator =
3911 dyn_cast_or_null<FunctionDecl>(extractFunctorCallOperator(ND))) {
3912 AddFunctionTypeAndResult(CallOperator);
3913 return Result.TakeString();
3914 }
3915
3916 AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result);
3917
3918 if (const FunctionTemplateDecl *FunTmpl =
3919 dyn_cast<FunctionTemplateDecl>(ND)) {
3921 Ctx, Policy);
3922 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
3923 AddTypedNameChunk(Ctx, Policy, Function, Result);
3924
3925 // Figure out which template parameters are deduced (or have default
3926 // arguments).
3927 // Note that we're creating a non-empty bit vector so that we can go
3928 // through the loop below to omit default template parameters for non-call
3929 // cases.
3930 llvm::SmallBitVector Deduced(FunTmpl->getTemplateParameters()->size());
3931 // Avoid running it if this is not a call: We should emit *all* template
3932 // parameters.
3935 unsigned LastDeducibleArgument;
3936 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
3937 --LastDeducibleArgument) {
3938 if (!Deduced[LastDeducibleArgument - 1]) {
3939 // C++0x: Figure out if the template argument has a default. If so,
3940 // the user doesn't need to type this argument.
3941 // FIXME: We need to abstract template parameters better!
3942 bool HasDefaultArg = false;
3943 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
3944 LastDeducibleArgument - 1);
3945 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3946 HasDefaultArg = TTP->hasDefaultArgument();
3947 else if (NonTypeTemplateParmDecl *NTTP =
3948 dyn_cast<NonTypeTemplateParmDecl>(Param))
3949 HasDefaultArg = NTTP->hasDefaultArgument();
3950 else {
3951 assert(isa<TemplateTemplateParmDecl>(Param));
3952 HasDefaultArg =
3953 cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
3954 }
3955
3956 if (!HasDefaultArg)
3957 break;
3958 }
3959 }
3960
3961 if (LastDeducibleArgument || !FunctionCanBeCall) {
3962 // Some of the function template arguments cannot be deduced from a
3963 // function call, so we introduce an explicit template argument list
3964 // containing all of the arguments up to the first deducible argument.
3965 //
3966 // Or, if this isn't a call, emit all the template arguments
3967 // to disambiguate the (potential) overloads.
3968 //
3969 // FIXME: Detect cases where the function parameters can be deduced from
3970 // the surrounding context, as per [temp.deduct.funcaddr].
3971 // e.g.,
3972 // template <class T> void foo(T);
3973 // void (*f)(int) = foo;
3974 if (!DeclaringEntity)
3976 else
3977 Result.AddInformativeChunk("<");
3979 Ctx, Policy, FunTmpl, Result, LastDeducibleArgument, /*Start=*/0,
3980 /*InDefaultArg=*/false, /*AsInformativeChunk=*/DeclaringEntity);
3981 // Only adds template arguments as informative chunks in declaration
3982 // context.
3983 if (!DeclaringEntity)
3985 else
3986 Result.AddInformativeChunk(">");
3987 }
3988
3989 // Add the function parameters
3990 bool InsertParameters = FunctionCanBeCall || DeclaringEntity;
3991 if (InsertParameters)
3993 else
3994 Result.AddInformativeChunk("(");
3995 AddFunctionParameterChunks(PP, Policy, Function, Result, /*Start=*/0,
3996 /*InOptional=*/false,
3997 /*FunctionCanBeCall=*/FunctionCanBeCall,
3998 /*IsInDeclarationContext=*/DeclaringEntity);
3999 if (InsertParameters)
4001 else
4002 Result.AddInformativeChunk(")");
4004 return Result.TakeString();
4005 }
4006
4007 if (const auto *Template = dyn_cast<TemplateDecl>(ND)) {
4009 Ctx, Policy);
4010 Result.AddTypedTextChunk(
4011 Result.getAllocator().CopyString(Template->getNameAsString()));
4015 return Result.TakeString();
4016 }
4017
4018 if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) {
4019 Selector Sel = Method->getSelector();
4020 if (Sel.isUnarySelector()) {
4021 Result.AddTypedTextChunk(
4022 Result.getAllocator().CopyString(Sel.getNameForSlot(0)));
4023 return Result.TakeString();
4024 }
4025
4026 std::string SelName = Sel.getNameForSlot(0).str();
4027 SelName += ':';
4028 if (StartParameter == 0)
4029 Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName));
4030 else {
4031 Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName));
4032
4033 // If there is only one parameter, and we're past it, add an empty
4034 // typed-text chunk since there is nothing to type.
4035 if (Method->param_size() == 1)
4036 Result.AddTypedTextChunk("");
4037 }
4038 unsigned Idx = 0;
4039 // The extra Idx < Sel.getNumArgs() check is needed due to legacy C-style
4040 // method parameters.
4041 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
4042 PEnd = Method->param_end();
4043 P != PEnd && Idx < Sel.getNumArgs(); (void)++P, ++Idx) {
4044 if (Idx > 0) {
4045 std::string Keyword;
4046 if (Idx > StartParameter)
4048 if (const IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
4049 Keyword += II->getName();
4050 Keyword += ":";
4052 Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword));
4053 else
4054 Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword));
4055 }
4056
4057 // If we're before the starting parameter, skip the placeholder.
4058 if (Idx < StartParameter)
4059 continue;
4060
4061 std::string Arg;
4062 QualType ParamType = (*P)->getType();
4063 std::optional<ArrayRef<QualType>> ObjCSubsts;
4064 if (!CCContext.getBaseType().isNull())
4065 ObjCSubsts = CCContext.getBaseType()->getObjCSubstitutions(Method);
4066
4067 if (ParamType->isBlockPointerType() && !DeclaringEntity)
4068 Arg = FormatFunctionParameter(Policy, *P, true,
4069 /*SuppressBlock=*/false, ObjCSubsts);
4070 else {
4071 if (ObjCSubsts)
4072 ParamType = ParamType.substObjCTypeArgs(
4073 Ctx, *ObjCSubsts, ObjCSubstitutionContext::Parameter);
4074 Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier(),
4075 ParamType);
4076 Arg += ParamType.getAsString(Policy) + ")";
4077 if (const IdentifierInfo *II = (*P)->getIdentifier())
4079 Arg += II->getName();
4080 }
4081
4082 if (Method->isVariadic() && (P + 1) == PEnd)
4083 Arg += ", ...";
4084
4085 if (DeclaringEntity)
4086 Result.AddTextChunk(Result.getAllocator().CopyString(Arg));
4088 Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg));
4089 else
4090 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
4091 }
4092
4093 if (Method->isVariadic()) {
4094 if (Method->param_size() == 0) {
4095 if (DeclaringEntity)
4096 Result.AddTextChunk(", ...");
4098 Result.AddInformativeChunk(", ...");
4099 else
4100 Result.AddPlaceholderChunk(", ...");
4101 }
4102
4104 }
4105
4106 return Result.TakeString();
4107 }
4108
4109 if (Qualifier)
4111 Ctx, Policy);
4112
4113 Result.AddTypedTextChunk(
4114 Result.getAllocator().CopyString(ND->getNameAsString()));
4115 return Result.TakeString();
4116}
4117
4119 const NamedDecl *ND) {
4120 if (!ND)
4121 return nullptr;
4122 if (auto *RC = Ctx.getRawCommentForAnyRedecl(ND))
4123 return RC;
4124
4125 // Try to find comment from a property for ObjC methods.
4126 const auto *M = dyn_cast<ObjCMethodDecl>(ND);
4127 if (!M)
4128 return nullptr;
4129 const ObjCPropertyDecl *PDecl = M->findPropertyDecl();
4130 if (!PDecl)
4131 return nullptr;
4132
4133 return Ctx.getRawCommentForAnyRedecl(PDecl);
4134}
4135
4137 const NamedDecl *ND) {
4138 const auto *M = dyn_cast_or_null<ObjCMethodDecl>(ND);
4139 if (!M || !M->isPropertyAccessor())
4140 return nullptr;
4141
4142 // Provide code completion comment for self.GetterName where
4143 // GetterName is the getter method for a property with name
4144 // different from the property name (declared via a property
4145 // getter attribute.
4146 const ObjCPropertyDecl *PDecl = M->findPropertyDecl();
4147 if (!PDecl)
4148 return nullptr;
4149 if (PDecl->getGetterName() == M->getSelector() &&
4150 PDecl->getIdentifier() != M->getIdentifier()) {
4151 if (auto *RC = Ctx.getRawCommentForAnyRedecl(M))
4152 return RC;
4153 if (auto *RC = Ctx.getRawCommentForAnyRedecl(PDecl))
4154 return RC;
4155 }
4156 return nullptr;
4157}
4158
4160 const ASTContext &Ctx,
4161 const CodeCompleteConsumer::OverloadCandidate &Result, unsigned ArgIndex) {
4162 auto FDecl = Result.getFunction();
4163 if (!FDecl)
4164 return nullptr;
4165 if (ArgIndex < FDecl->getNumParams())
4166 return Ctx.getRawCommentForAnyRedecl(FDecl->getParamDecl(ArgIndex));
4167 return nullptr;
4168}
4169
4171 const PrintingPolicy &Policy,
4173 unsigned CurrentArg) {
4174 unsigned ChunkIndex = 0;
4175 auto AddChunk = [&](llvm::StringRef Placeholder) {
4176 if (ChunkIndex > 0)
4178 const char *Copy = Result.getAllocator().CopyString(Placeholder);
4179 if (ChunkIndex == CurrentArg)
4180 Result.AddCurrentParameterChunk(Copy);
4181 else
4182 Result.AddPlaceholderChunk(Copy);
4183 ++ChunkIndex;
4184 };
4185 // Aggregate initialization has all bases followed by all fields.
4186 // (Bases are not legal in C++11 but in that case we never get here).
4187 if (auto *CRD = llvm::dyn_cast<CXXRecordDecl>(RD)) {
4188 for (const auto &Base : CRD->bases())
4189 AddChunk(Base.getType().getAsString(Policy));
4190 }
4191 for (const auto &Field : RD->fields())
4192 AddChunk(FormatFunctionParameter(Policy, Field));
4193}
4194
4195/// Add function overload parameter chunks to the given code completion
4196/// string.
4198 ASTContext &Context, const PrintingPolicy &Policy,
4199 const FunctionDecl *Function, const FunctionProtoType *Prototype,
4201 unsigned CurrentArg, unsigned Start = 0, bool InOptional = false) {
4202 if (!Function && !Prototype) {
4204 return;
4205 }
4206
4207 bool FirstParameter = true;
4208 unsigned NumParams =
4209 Function ? Function->getNumParams() : Prototype->getNumParams();
4210 const FunctionDecl *BetterSignatureDecl =
4211 Function ? BetterSignature(Function, Start) : nullptr;
4212
4213 for (unsigned P = Start; P != NumParams; ++P) {
4214 if (Function && Function->getParamDecl(P)->hasDefaultArg() && !InOptional) {
4215 // When we see an optional default argument, put that argument and
4216 // the remaining default arguments into a new, optional string.
4217 CodeCompletionBuilder Opt(Result.getAllocator(),
4218 Result.getCodeCompletionTUInfo());
4219 if (!FirstParameter)
4221 // Optional sections are nested.
4222 AddOverloadParameterChunks(Context, Policy, Function, Prototype,
4223 PrototypeLoc, Opt, CurrentArg, P,
4224 /*InOptional=*/true);
4225 Result.AddOptionalChunk(Opt.TakeString());
4226 return;
4227 }
4228
4229 // C++23 introduces an explicit object parameter, a.k.a. "deducing this"
4230 // Skip it for autocomplete and treat the next parameter as the first
4231 // parameter
4232 if (Function && FirstParameter &&
4233 Function->getParamDecl(P)->isExplicitObjectParameter()) {
4234 continue;
4235 }
4236
4237 if (FirstParameter)
4238 FirstParameter = false;
4239 else
4241
4242 InOptional = false;
4243
4244 // Format the placeholder string.
4245 std::string Placeholder;
4246 assert(P < Prototype->getNumParams());
4247 if (Function || PrototypeLoc) {
4248 const ParmVarDecl *Param = Function ? BetterSignatureDecl->getParamDecl(P)
4249 : PrototypeLoc.getParam(P);
4250 Placeholder = FormatFunctionParameter(Policy, Param);
4251 if (Param->hasDefaultArg())
4252 Placeholder += GetDefaultValueString(Param, Context.getSourceManager(),
4253 Context.getLangOpts());
4254 } else {
4255 Placeholder = Prototype->getParamType(P).getAsString(Policy);
4256 }
4257
4258 if (P == CurrentArg)
4259 Result.AddCurrentParameterChunk(
4260 Result.getAllocator().CopyString(Placeholder));
4261 else
4262 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Placeholder));
4263 }
4264
4265 if (Prototype && Prototype->isVariadic()) {
4266 CodeCompletionBuilder Opt(Result.getAllocator(),
4267 Result.getCodeCompletionTUInfo());
4268 if (!FirstParameter)
4270
4271 if (CurrentArg < NumParams)
4272 Opt.AddPlaceholderChunk("...");
4273 else
4274 Opt.AddCurrentParameterChunk("...");
4275
4276 Result.AddOptionalChunk(Opt.TakeString());
4277 }
4278}
4279
4280static std::string
4282 const PrintingPolicy &Policy) {
4283 if (const auto *Type = dyn_cast<TemplateTypeParmDecl>(Param)) {
4284 Optional = Type->hasDefaultArgument();
4285 } else if (const auto *NonType = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
4286 Optional = NonType->hasDefaultArgument();
4287 } else if (const auto *Template = dyn_cast<TemplateTemplateParmDecl>(Param)) {
4288 Optional = Template->hasDefaultArgument();
4289 }
4290 std::string Result;
4291 llvm::raw_string_ostream OS(Result);
4292 Param->print(OS, Policy);
4293 return Result;
4294}
4295
4296static std::string templateResultType(const TemplateDecl *TD,
4297 const PrintingPolicy &Policy) {
4298 if (const auto *CTD = dyn_cast<ClassTemplateDecl>(TD))
4299 return CTD->getTemplatedDecl()->getKindName().str();
4300 if (const auto *VTD = dyn_cast<VarTemplateDecl>(TD))
4301 return VTD->getTemplatedDecl()->getType().getAsString(Policy);
4302 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(TD))
4303 return FTD->getTemplatedDecl()->getReturnType().getAsString(Policy);
4305 return "type";
4307 return "class";
4308 if (isa<ConceptDecl>(TD))
4309 return "concept";
4310 return "";
4311}
4312
4314 const TemplateDecl *TD, CodeCompletionBuilder &Builder, unsigned CurrentArg,
4315 const PrintingPolicy &Policy) {
4317 CodeCompletionBuilder OptionalBuilder(Builder.getAllocator(),
4318 Builder.getCodeCompletionTUInfo());
4319 std::string ResultType = templateResultType(TD, Policy);
4320 if (!ResultType.empty())
4321 Builder.AddResultTypeChunk(Builder.getAllocator().CopyString(ResultType));
4322 Builder.AddTextChunk(
4323 Builder.getAllocator().CopyString(TD->getNameAsString()));
4324 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
4325 // Initially we're writing into the main string. Once we see an optional arg
4326 // (with default), we're writing into the nested optional chunk.
4327 CodeCompletionBuilder *Current = &Builder;
4328 for (unsigned I = 0; I < Params.size(); ++I) {
4329 bool Optional = false;
4330 std::string Placeholder =
4331 formatTemplateParameterPlaceholder(Params[I], Optional, Policy);
4332 if (Optional)
4333 Current = &OptionalBuilder;
4334 if (I > 0)
4336 Current->AddChunk(I == CurrentArg
4339 Current->getAllocator().CopyString(Placeholder));
4340 }
4341 // Add the optional chunk to the main string if we ever used it.
4342 if (Current == &OptionalBuilder)
4343 Builder.AddOptionalChunk(OptionalBuilder.TakeString());
4344 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
4345 // For function templates, ResultType was the function's return type.
4346 // Give some clue this is a function. (Don't show the possibly-bulky params).
4348 Builder.AddInformativeChunk("()");
4349 return Builder.TakeString();
4350}
4351
4354 unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator,
4355 CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments,
4356 bool Braced) const {
4358 // Show signatures of constructors as they are declared:
4359 // vector(int n) rather than vector<string>(int n)
4360 // This is less noisy without being less clear, and avoids tricky cases.
4362
4363 // FIXME: Set priority, availability appropriately.
4364 CodeCompletionBuilder Result(Allocator, CCTUInfo, 1,
4366
4367 if (getKind() == CK_Template)
4368 return createTemplateSignatureString(getTemplate(), Result, CurrentArg,
4369 Policy);
4370
4371 FunctionDecl *FDecl = getFunction();
4372 const FunctionProtoType *Proto =
4373 dyn_cast_or_null<FunctionProtoType>(getFunctionType());
4374
4375 // First, the name/type of the callee.
4376 if (getKind() == CK_Aggregate) {
4377 Result.AddTextChunk(
4378 Result.getAllocator().CopyString(getAggregate()->getName()));
4379 } else if (FDecl) {
4380 if (IncludeBriefComments) {
4381 if (auto RC = getParameterComment(S.getASTContext(), *this, CurrentArg))
4382 Result.addBriefComment(RC->getBriefText(S.getASTContext()));
4383 }
4384 AddResultTypeChunk(S.Context, Policy, FDecl, QualType(), Result);
4385
4386 std::string Name;
4387 llvm::raw_string_ostream OS(Name);
4388 FDecl->getDeclName().print(OS, Policy);
4389 Result.AddTextChunk(Result.getAllocator().CopyString(Name));
4390 } else {
4391 // Function without a declaration. Just give the return type.
4392 Result.AddResultTypeChunk(Result.getAllocator().CopyString(
4393 getFunctionType()->getReturnType().getAsString(Policy)));
4394 }
4395
4396 // Next, the brackets and parameters.
4399 if (getKind() == CK_Aggregate)
4400 AddOverloadAggregateChunks(getAggregate(), Policy, Result, CurrentArg);
4401 else
4402 AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto,
4403 getFunctionProtoTypeLoc(), Result, CurrentArg);
4406
4407 return Result.TakeString();
4408}
4409
4410unsigned clang::getMacroUsagePriority(StringRef MacroName,
4411 const LangOptions &LangOpts,
4412 bool PreferredTypeIsPointer) {
4413 unsigned Priority = CCP_Macro;
4414
4415 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
4416 if (MacroName == "nil" || MacroName == "NULL" || MacroName == "Nil") {
4417 Priority = CCP_Constant;
4418 if (PreferredTypeIsPointer)
4419 Priority = Priority / CCF_SimilarTypeMatch;
4420 }
4421 // Treat "YES", "NO", "true", and "false" as constants.
4422 else if (MacroName == "YES" || MacroName == "NO" || MacroName == "true" ||
4423 MacroName == "false")
4424 Priority = CCP_Constant;
4425 // Treat "bool" as a type.
4426 else if (MacroName == "bool")
4427 Priority = CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0);
4428
4429 return Priority;
4430}
4431
4432CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
4433 if (!D)
4435
4436 switch (D->getKind()) {
4437 case Decl::Enum:
4438 return CXCursor_EnumDecl;
4439 case Decl::EnumConstant:
4441 case Decl::Field:
4442 return CXCursor_FieldDecl;
4443 case Decl::Function:
4444 return CXCursor_FunctionDecl;
4445 case Decl::ObjCCategory:
4447 case Decl::ObjCCategoryImpl:
4449 case Decl::ObjCImplementation:
4451
4452 case Decl::ObjCInterface:
4454 case Decl::ObjCIvar:
4455 return CXCursor_ObjCIvarDecl;
4456 case Decl::ObjCMethod:
4457 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
4460 case Decl::CXXMethod:
4461 return CXCursor_CXXMethod;
4462 case Decl::CXXConstructor:
4463 return CXCursor_Constructor;
4464 case Decl::CXXDestructor:
4465 return CXCursor_Destructor;
4466 case Decl::CXXConversion:
4468 case Decl::ObjCProperty:
4470 case Decl::ObjCProtocol:
4472 case Decl::ParmVar:
4473 return CXCursor_ParmDecl;
4474 case Decl::Typedef:
4475 return CXCursor_TypedefDecl;
4476 case Decl::TypeAlias:
4478 case Decl::TypeAliasTemplate:
4480 case Decl::Var:
4481 return CXCursor_VarDecl;
4482 case Decl::Namespace:
4483 return CXCursor_Namespace;
4484 case Decl::NamespaceAlias:
4486 case Decl::TemplateTypeParm:
4488 case Decl::NonTypeTemplateParm:
4490 case Decl::TemplateTemplateParm:
4492 case Decl::FunctionTemplate:
4494 case Decl::ClassTemplate:
4496 case Decl::AccessSpec:
4498 case Decl::ClassTemplatePartialSpecialization:
4500 case Decl::UsingDirective:
4502 case Decl::StaticAssert:
4503 return CXCursor_StaticAssert;
4504 case Decl::Friend:
4505 case Decl::FriendTemplate:
4506 return CXCursor_FriendDecl;
4507 case Decl::TranslationUnit:
4509
4510 case Decl::Using:
4511 case Decl::UnresolvedUsingValue:
4512 case Decl::UnresolvedUsingTypename:
4514
4515 case Decl::UsingEnum:
4516 return CXCursor_EnumDecl;
4517
4518 case Decl::ObjCPropertyImpl:
4519 switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) {
4522
4525 }
4526 llvm_unreachable("Unexpected Kind!");
4527
4528 case Decl::Import:
4530
4531 case Decl::ObjCTypeParam:
4533
4534 case Decl::Concept:
4535 return CXCursor_ConceptDecl;
4536
4537 case Decl::LinkageSpec:
4538 return CXCursor_LinkageSpec;
4539
4540 default:
4541 if (const auto *TD = dyn_cast<TagDecl>(D)) {
4542 switch (TD->getTagKind()) {
4543 case TagTypeKind::Interface: // fall through
4545 return CXCursor_StructDecl;
4546 case TagTypeKind::Class:
4547 return CXCursor_ClassDecl;
4548 case TagTypeKind::Union:
4549 return CXCursor_UnionDecl;
4550 case TagTypeKind::Enum:
4551 return CXCursor_EnumDecl;
4552 }
4553 }
4554 }
4555
4557}
4558
4559static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
4560 bool LoadExternal, bool IncludeUndefined,
4561 bool TargetTypeIsPointer = false) {
4563
4564 Results.EnterNewScope();
4565
4566 for (const auto &M : PP.macros(LoadExternal)) {
4567 auto MD = PP.getMacroDefinition(M.first);
4568 if (IncludeUndefined || MD) {
4569 MacroInfo *MI = MD.getMacroInfo();
4570 if (MI && MI->isUsedForHeaderGuard())
4571 continue;
4572
4573 Results.AddResult(
4574 Result(M.first, MI,
4575 getMacroUsagePriority(M.first->getName(), PP.getLangOpts(),
4576 TargetTypeIsPointer)));
4577 }
4578 }
4579
4580 Results.ExitScope();
4581}
4582
4583static void AddPrettyFunctionResults(const LangOptions &LangOpts,
4584 ResultBuilder &Results) {
4586
4587 Results.EnterNewScope();
4588
4589 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
4590 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
4591 if (LangOpts.C99 || LangOpts.CPlusPlus11)
4592 Results.AddResult(Result("__func__", CCP_Constant));
4593 Results.ExitScope();
4594}
4595
4597 CodeCompleteConsumer *CodeCompleter,
4598 const CodeCompletionContext &Context,
4599 CodeCompletionResult *Results,
4600 unsigned NumResults) {
4601 if (CodeCompleter)
4602 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
4603}
4604
4605static CodeCompletionContext
4608 switch (PCC) {
4611
4614
4617
4620
4623
4626 if (S.CurContext->isFileContext())
4628 if (S.CurContext->isRecord())
4631
4634
4636 if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 ||
4637 S.getLangOpts().ObjC)
4639 else
4641
4646 S.getASTContext().BoolTy);
4647
4650
4653
4656
4661 }
4662
4663 llvm_unreachable("Invalid ParserCompletionContext!");
4664}
4665
4666/// If we're in a C++ virtual member function, add completion results
4667/// that invoke the functions we override, since it's common to invoke the
4668/// overridden function as well as adding new functionality.
4669///
4670/// \param S The semantic analysis object for which we are generating results.
4671///
4672/// \param InContext This context in which the nested-name-specifier preceding
4673/// the code-completion point
4674static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
4675 ResultBuilder &Results) {
4676 // Look through blocks.
4677 DeclContext *CurContext = S.CurContext;
4678 while (isa<BlockDecl>(CurContext))
4679 CurContext = CurContext->getParent();
4680
4681 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
4682 if (!Method || !Method->isVirtual())
4683 return;
4684
4685 // We need to have names for all of the parameters, if we're going to
4686 // generate a forwarding call.
4687 for (auto *P : Method->parameters())
4688 if (!P->getDeclName())
4689 return;
4690
4692 for (const CXXMethodDecl *Overridden : Method->overridden_methods()) {
4693 CodeCompletionBuilder Builder(Results.getAllocator(),
4694 Results.getCodeCompletionTUInfo());
4695 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
4696 continue;
4697
4698 // If we need a nested-name-specifier, add one now.
4699 if (!InContext) {
4701 S.Context, CurContext, Overridden->getDeclContext());
4702 if (NNS) {
4703 std::string Str;
4704 llvm::raw_string_ostream OS(Str);
4705 NNS.print(OS, Policy);
4706 Builder.AddTextChunk(Results.getAllocator().CopyString(Str));
4707 }
4708 } else if (!InContext->Equals(Overridden->getDeclContext()))
4709 continue;
4710
4711 Builder.AddTypedTextChunk(
4712 Results.getAllocator().CopyString(Overridden->getNameAsString()));
4713 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4714 bool FirstParam = true;
4715 for (auto *P : Method->parameters()) {
4716 if (FirstParam)
4717 FirstParam = false;
4718 else
4719 Builder.AddChunk(CodeCompletionString::CK_Comma);
4720
4721 Builder.AddPlaceholderChunk(
4722 Results.getAllocator().CopyString(P->getIdentifier()->getName()));
4723 }
4724 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4725 Results.AddResult(CodeCompletionResult(
4726 Builder.TakeString(), CCP_SuperCompletion, CXCursor_CXXMethod,
4727 CXAvailability_Available, Overridden));
4728 Results.Ignore(Overridden);
4729 }
4730}
4731
4733 ModuleIdPath Path) {
4735 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
4736 CodeCompleter->getCodeCompletionTUInfo(),
4738 Results.EnterNewScope();
4739
4740 CodeCompletionAllocator &Allocator = Results.getAllocator();
4741 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
4743 if (Path.empty()) {
4744 // Enumerate all top-level modules.
4746 SemaRef.PP.getHeaderSearchInfo().collectAllModules(Modules);
4747 // Determine the primary module interface name of the current file's
4748 // declared module, if any. Prefer Sema's view, but fall back to the
4749 // preprocessor's module declaration state: module declarations are
4750 // processed as preprocessor directives, so the preprocessor may know the
4751 // declared module before Sema has acted on it (e.g. when completing an
4752 // import right after the module declaration).
4753 StringRef CurrentPrimary;
4754 if (Module *CurrentModule = SemaRef.getCurrentModule())
4755 CurrentPrimary = CurrentModule->getPrimaryModuleInterfaceName();
4756 else if (SemaRef.PP.isInNamedModule())
4757 CurrentPrimary = SemaRef.PP.getNamedModuleName().split(':').first;
4758 llvm::StringSet<> AddedModules;
4759 for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
4760 // Skip module partitions that don't belong to the current file's declared
4761 // module.
4762 if (Modules[I]->isModulePartition()) {
4763 if (CurrentPrimary.empty() ||
4764 Modules[I]->getPrimaryModuleInterfaceName() != CurrentPrimary)
4765 continue;
4766 }
4767 Builder.AddTypedTextChunk(
4768 Builder.getAllocator().CopyString(Modules[I]->Name));
4769 Results.AddResult(Result(
4770 Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl,
4771 Modules[I]->isAvailable() ? CXAvailability_Available
4773 AddedModules.insert(Modules[I]->Name);
4774 }
4775
4776 // Also suggest C++20 named modules from -fmodule-file=<name>=<path> that
4777 // haven't been loaded into the module map yet.
4778 for (const auto &Entry : SemaRef.PP.getHeaderSearchInfo()
4779 .getHeaderSearchOpts()
4780 .PrebuiltModuleFiles) {
4781 if (AddedModules.count(Entry.first))
4782 continue;
4783 StringRef Name = Entry.first;
4784 // Apply the same partition filtering as above.
4785 if (auto [Primary, Partition] = Name.split(':'); !Partition.empty()) {
4786 if (CurrentPrimary.empty() || Primary != CurrentPrimary)
4787 continue;
4788 }
4789 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(Name));
4790 Results.AddResult(Result(Builder.TakeString(), CCP_Declaration,
4793 }
4794 } else if (getLangOpts().Modules) {
4795 // Load the named module.
4796 Module *Mod = SemaRef.PP.getModuleLoader().loadModule(
4797 ImportLoc, Path, Module::AllVisible,
4798 /*IsInclusionDirective=*/false);
4799 // Enumerate submodules.
4800 if (Mod) {
4801 for (Module *Submodule : Mod->submodules()) {
4802 Builder.AddTypedTextChunk(
4803 Builder.getAllocator().CopyString(Submodule->Name));
4804 Results.AddResult(Result(
4805 Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl,
4806 Submodule->isAvailable() ? CXAvailability_Available
4808 }
4809 }
4810 }
4811 Results.ExitScope();
4813 Results.getCompletionContext(), Results.data(),
4814 Results.size());
4815}
4816
4818 Scope *S, SemaCodeCompletion::ParserCompletionContext CompletionContext) {
4819 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
4820 CodeCompleter->getCodeCompletionTUInfo(),
4821 mapCodeCompletionContext(SemaRef, CompletionContext));
4822 Results.EnterNewScope();
4823
4824 // Determine how to filter results, e.g., so that the names of
4825 // values (functions, enumerators, function templates, etc.) are
4826 // only allowed where we can have an expression.
4827 switch (CompletionContext) {
4828 case PCC_Namespace:
4829 case PCC_Class:
4830 case PCC_ObjCInterface:
4833 case PCC_Template:
4834 case PCC_MemberTemplate:
4835 case PCC_Type:
4837 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4838 break;
4839
4840 case PCC_Statement:
4843 case PCC_Expression:
4844 case PCC_ForInit:
4845 case PCC_Condition:
4846 if (WantTypesInContext(CompletionContext, getLangOpts()))
4847 Results.setFilter(&ResultBuilder::IsOrdinaryName);
4848 else
4849 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
4850
4851 if (getLangOpts().CPlusPlus)
4852 MaybeAddOverrideCalls(SemaRef, /*InContext=*/nullptr, Results);
4853 break;
4854
4856 // Unfiltered
4857 break;
4858 }
4859
4860 auto ThisType = SemaRef.getCurrentThisType();
4861 if (ThisType.isNull()) {
4862 // check if function scope is an explicit object function
4863 if (auto *MethodDecl = llvm::dyn_cast_if_present<CXXMethodDecl>(
4864 SemaRef.getCurFunctionDecl()))
4865 Results.setExplicitObjectMemberFn(
4866 MethodDecl->isExplicitObjectMemberFunction());
4867 } else {
4868 // If we are in a C++ non-static member function, check the qualifiers on
4869 // the member function to filter/prioritize the results list.
4870 Results.setObjectTypeQualifiers(ThisType->getPointeeType().getQualifiers(),
4871 VK_LValue);
4872 }
4873
4874 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
4875 SemaRef.LookupVisibleDecls(S, SemaRef.LookupOrdinaryName, Consumer,
4876 CodeCompleter->includeGlobals(),
4877 CodeCompleter->loadExternal());
4878
4879 AddOrdinaryNameResults(CompletionContext, S, SemaRef, Results);
4880 Results.ExitScope();
4881
4882 switch (CompletionContext) {
4884 case PCC_Expression:
4885 case PCC_Statement:
4888 if (S->getFnParent())
4890 break;
4891
4892 case PCC_Namespace:
4893 case PCC_Class:
4894 case PCC_ObjCInterface:
4897 case PCC_Template:
4898 case PCC_MemberTemplate:
4899 case PCC_ForInit:
4900 case PCC_Condition:
4901 case PCC_Type:
4903 break;
4904 }
4905
4906 if (CodeCompleter->includeMacros())
4907 AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
4908
4910 Results.getCompletionContext(), Results.data(),
4911 Results.size());
4912}
4913
4914static void
4915AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver,
4917 bool AtArgumentExpression, bool IsSuper,
4918 ResultBuilder &Results);
4919
4921 bool AllowNonIdentifiers,
4922 bool AllowNestedNameSpecifiers) {
4924 ResultBuilder Results(
4925 SemaRef, CodeCompleter->getAllocator(),
4926 CodeCompleter->getCodeCompletionTUInfo(),
4927 AllowNestedNameSpecifiers
4928 // FIXME: Try to separate codepath leading here to deduce whether we
4929 // need an existing symbol or a new one.
4932 Results.EnterNewScope();
4933
4934 // Type qualifiers can come after names.
4935 Results.AddResult(Result("const"));
4936 Results.AddResult(Result("volatile"));
4937 if (getLangOpts().C99)
4938 Results.AddResult(Result("restrict"));
4939
4940 if (getLangOpts().CPlusPlus) {
4941 if (getLangOpts().CPlusPlus11 &&
4944 Results.AddResult("final");
4945
4946 if (AllowNonIdentifiers) {
4947 Results.AddResult(Result("operator"));
4948 }
4949
4950 // Add nested-name-specifiers.
4951 if (AllowNestedNameSpecifiers) {
4952 Results.allowNestedNameSpecifiers();
4953 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
4954 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
4955 SemaRef.LookupVisibleDecls(S, Sema::LookupNestedNameSpecifierName,
4956 Consumer, CodeCompleter->includeGlobals(),
4957 CodeCompleter->loadExternal());
4958 Results.setFilter(nullptr);
4959 }
4960 }
4961 Results.ExitScope();
4962
4963 // If we're in a context where we might have an expression (rather than a
4964 // declaration), and what we've seen so far is an Objective-C type that could
4965 // be a receiver of a class message, this may be a class message send with
4966 // the initial opening bracket '[' missing. Add appropriate completions.
4967 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
4972 !DS.isTypeAltiVecVector() && S &&
4973 (S->getFlags() & Scope::DeclScope) != 0 &&
4976 0) {
4977 ParsedType T = DS.getRepAsType();
4978 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
4979 AddClassMessageCompletions(SemaRef, S, T, {}, false, false, Results);
4980 }
4981
4982 // Note that we intentionally suppress macro results here, since we do not
4983 // encourage using macros to produce the names of entities.
4984
4986 Results.getCompletionContext(), Results.data(),
4987 Results.size());
4988}
4989
4990static const char *underscoreAttrScope(llvm::StringRef Scope) {
4991 if (Scope == "clang")
4992 return "_Clang";
4993 if (Scope == "gnu")
4994 return "__gnu__";
4995 return nullptr;
4996}
4997
4998static const char *noUnderscoreAttrScope(llvm::StringRef Scope) {
4999 if (Scope == "_Clang")
5000 return "clang";
5001 if (Scope == "__gnu__")
5002 return "gnu";
5003 return nullptr;
5004}
5005
5008 const IdentifierInfo *InScope) {
5009 if (Completion == AttributeCompletion::None)
5010 return;
5011 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
5012 CodeCompleter->getCodeCompletionTUInfo(),
5014
5015 // We're going to iterate over the normalized spellings of the attribute.
5016 // These don't include "underscore guarding": the normalized spelling is
5017 // clang::foo but you can also write _Clang::__foo__.
5018 //
5019 // (Clang supports a mix like clang::__foo__ but we won't suggest it: either
5020 // you care about clashing with macros or you don't).
5021 //
5022 // So if we're already in a scope, we determine its canonical spellings
5023 // (for comparison with normalized attr spelling) and remember whether it was
5024 // underscore-guarded (so we know how to spell contained attributes).
5025 llvm::StringRef InScopeName;
5026 bool InScopeUnderscore = false;
5027 if (InScope) {
5028 InScopeName = InScope->getName();
5029 if (const char *NoUnderscore = noUnderscoreAttrScope(InScopeName)) {
5030 InScopeName = NoUnderscore;
5031 InScopeUnderscore = true;
5032 }
5033 }
5034 bool SyntaxSupportsGuards = Syntax == AttributeCommonInfo::AS_GNU ||
5037
5038 llvm::DenseSet<llvm::StringRef> FoundScopes;
5039 auto AddCompletions = [&](const ParsedAttrInfo &A) {
5040 if (A.IsTargetSpecific &&
5041 !A.existsInTarget(getASTContext().getTargetInfo()))
5042 return;
5043 if (!A.acceptsLangOpts(getLangOpts()))
5044 return;
5045 for (const auto &S : A.Spellings) {
5046 if (S.Syntax != Syntax)
5047 continue;
5048 llvm::StringRef Name = S.NormalizedFullName;
5049 llvm::StringRef Scope;
5050 if ((Syntax == AttributeCommonInfo::AS_CXX11 ||
5051 Syntax == AttributeCommonInfo::AS_C23)) {
5052 std::tie(Scope, Name) = Name.split("::");
5053 if (Name.empty()) // oops, unscoped
5054 std::swap(Name, Scope);
5055 }
5056
5057 // Do we just want a list of scopes rather than attributes?
5058 if (Completion == AttributeCompletion::Scope) {
5059 // Make sure to emit each scope only once.
5060 if (!Scope.empty() && FoundScopes.insert(Scope).second) {
5061 Results.AddResult(
5062 CodeCompletionResult(Results.getAllocator().CopyString(Scope)));
5063 // Include alternate form (__gnu__ instead of gnu).
5064 if (const char *Scope2 = underscoreAttrScope(Scope))
5065 Results.AddResult(CodeCompletionResult(Scope2));
5066 }
5067 continue;
5068 }
5069
5070 // If a scope was specified, it must match but we don't need to print it.
5071 if (!InScopeName.empty()) {
5072 if (Scope != InScopeName)
5073 continue;
5074 Scope = "";
5075 }
5076
5077 auto Add = [&](llvm::StringRef Scope, llvm::StringRef Name,
5078 bool Underscores) {
5079 CodeCompletionBuilder Builder(Results.getAllocator(),
5080 Results.getCodeCompletionTUInfo());
5082 if (!Scope.empty()) {
5083 Text.append(Scope);
5084 Text.append("::");
5085 }
5086 if (Underscores)
5087 Text.append("__");
5088 Text.append(Name);
5089 if (Underscores)
5090 Text.append("__");
5091 Builder.AddTypedTextChunk(Results.getAllocator().CopyString(Text));
5092
5093 if (!A.ArgNames.empty()) {
5094 Builder.AddChunk(CodeCompletionString::CK_LeftParen, "(");
5095 bool First = true;
5096 for (const char *Arg : A.ArgNames) {
5097 if (!First)
5098 Builder.AddChunk(CodeCompletionString::CK_Comma, ", ");
5099 First = false;
5100 Builder.AddPlaceholderChunk(Arg);
5101 }
5102 Builder.AddChunk(CodeCompletionString::CK_RightParen, ")");
5103 }
5104
5105 Results.AddResult(Builder.TakeString());
5106 };
5107
5108 // Generate the non-underscore-guarded result.
5109 // Note this is (a suffix of) the NormalizedFullName, no need to copy.
5110 // If an underscore-guarded scope was specified, only the
5111 // underscore-guarded attribute name is relevant.
5112 if (!InScopeUnderscore)
5113 Add(Scope, Name, /*Underscores=*/false);
5114
5115 // Generate the underscore-guarded version, for syntaxes that support it.
5116 // We skip this if the scope was already spelled and not guarded, or
5117 // we must spell it and can't guard it.
5118 if (!(InScope && !InScopeUnderscore) && SyntaxSupportsGuards) {
5119 if (Scope.empty()) {
5120 Add(Scope, Name, /*Underscores=*/true);
5121 } else {
5122 const char *GuardedScope = underscoreAttrScope(Scope);
5123 if (!GuardedScope)
5124 continue;
5125 Add(GuardedScope, Name, /*Underscores=*/true);
5126 }
5127 }
5128
5129 // It may be nice to include the Kind so we can look up the docs later.
5130 }
5131 };
5132
5133 for (const auto *A : ParsedAttrInfo::getAllBuiltin())
5134 AddCompletions(*A);
5135 for (const auto &Entry : ParsedAttrInfoRegistry::entries())
5136 AddCompletions(*Entry.instantiate());
5137
5139 Results.getCompletionContext(), Results.data(),
5140 Results.size());
5141}
5142
5155
5156namespace {
5157/// Information that allows to avoid completing redundant enumerators.
5158struct CoveredEnumerators {
5160 NestedNameSpecifier SuggestedQualifier = std::nullopt;
5161};
5162} // namespace
5163
5164static void AddEnumerators(ResultBuilder &Results, ASTContext &Context,
5165 EnumDecl *Enum, DeclContext *CurContext,
5166 const CoveredEnumerators &Enumerators) {
5167 NestedNameSpecifier Qualifier = Enumerators.SuggestedQualifier;
5168 if (Context.getLangOpts().CPlusPlus && !Qualifier && Enumerators.Seen.empty()) {
5169 // If there are no prior enumerators in C++, check whether we have to
5170 // qualify the names of the enumerators that we suggest, because they
5171 // may not be visible in this scope.
5172 Qualifier = getRequiredQualification(Context, CurContext, Enum);
5173 }
5174
5175 Results.EnterNewScope();
5176 for (auto *E : Enum->enumerators()) {
5177 if (Enumerators.Seen.count(E))
5178 continue;
5179
5180 CodeCompletionResult R(E, CCP_EnumInCase, Qualifier);
5181 Results.AddResult(R, CurContext, nullptr, false);
5182 }
5183 Results.ExitScope();
5184}
5185
5186/// Try to find a corresponding FunctionProtoType for function-like types (e.g.
5187/// function pointers, std::function, etc).
5189 assert(!T.isNull());
5190 // Try to extract first template argument from std::function<> and similar.
5191 // Note we only handle the sugared types, they closely match what users wrote.
5192 // We explicitly choose to not handle ClassTemplateSpecializationDecl.
5193 if (auto *Specialization = T->getAs<TemplateSpecializationType>()) {
5194 if (Specialization->template_arguments().size() != 1)
5195 return nullptr;
5196 const TemplateArgument &Argument = Specialization->template_arguments()[0];
5197 if (Argument.getKind() != TemplateArgument::Type)
5198 return nullptr;
5199 return Argument.getAsType()->getAs<FunctionProtoType>();
5200 }
5201 // Handle other cases.
5202 if (T->isPointerType())
5203 T = T->getPointeeType();
5204 return T->getAs<FunctionProtoType>();
5205}
5206
5207/// Adds a pattern completion for a lambda expression with the specified
5208/// parameter types and placeholders for parameter names.
5209static void AddLambdaCompletion(ResultBuilder &Results,
5210 llvm::ArrayRef<QualType> Parameters,
5211 const LangOptions &LangOpts) {
5212 if (!Results.includeCodePatterns())
5213 return;
5214 CodeCompletionBuilder Completion(Results.getAllocator(),
5215 Results.getCodeCompletionTUInfo());
5216 // [](<parameters>) {}
5218 Completion.AddPlaceholderChunk("=");
5220 if (!Parameters.empty()) {
5222 bool First = true;
5223 for (auto Parameter : Parameters) {
5224 if (!First)
5226 else
5227 First = false;
5228
5229 constexpr llvm::StringLiteral NamePlaceholder = "!#!NAME_GOES_HERE!#!";
5230 std::string Type = std::string(NamePlaceholder);
5231 Parameter.getAsStringInternal(Type, PrintingPolicy(LangOpts));
5232 llvm::StringRef Prefix, Suffix;
5233 std::tie(Prefix, Suffix) = llvm::StringRef(Type).split(NamePlaceholder);
5234 Prefix = Prefix.rtrim();
5235 Suffix = Suffix.ltrim();
5236
5237 Completion.AddTextChunk(Completion.getAllocator().CopyString(Prefix));
5239 Completion.AddPlaceholderChunk("parameter");
5240 Completion.AddTextChunk(Completion.getAllocator().CopyString(Suffix));
5241 };
5243 }
5247 Completion.AddPlaceholderChunk("body");
5250
5251 Results.AddResult(Completion.TakeString());
5252}
5253
5254/// Perform code-completion in an expression context when we know what
5255/// type we're looking for.
5257 Scope *S, const CodeCompleteExpressionData &Data, bool IsAddressOfOperand) {
5258 ResultBuilder Results(
5259 SemaRef, CodeCompleter->getAllocator(),
5260 CodeCompleter->getCodeCompletionTUInfo(),
5262 Data.IsParenthesized
5265 Data.PreferredType));
5266 auto PCC =
5268 if (Data.ObjCCollection)
5269 Results.setFilter(&ResultBuilder::IsObjCCollection);
5270 else if (Data.IntegralConstantExpression)
5271 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
5272 else if (WantTypesInContext(PCC, getLangOpts()))
5273 Results.setFilter(&ResultBuilder::IsOrdinaryName);
5274 else
5275 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
5276
5277 if (!Data.PreferredType.isNull())
5278 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
5279
5280 // Ignore any declarations that we were told that we don't care about.
5281 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
5282 Results.Ignore(Data.IgnoreDecls[I]);
5283
5284 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
5285 Consumer.setIsAddressOfOperand(IsAddressOfOperand);
5286 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
5287 CodeCompleter->includeGlobals(),
5288 CodeCompleter->loadExternal());
5289
5290 Results.EnterNewScope();
5291 AddOrdinaryNameResults(PCC, S, SemaRef, Results);
5292 Results.ExitScope();
5293
5294 bool PreferredTypeIsPointer = false;
5295 if (!Data.PreferredType.isNull()) {
5296 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() ||
5297 Data.PreferredType->isMemberPointerType() ||
5298 Data.PreferredType->isBlockPointerType();
5299 if (auto *Enum = Data.PreferredType->getAsEnumDecl()) {
5300 // FIXME: collect covered enumerators in cases like:
5301 // if (x == my_enum::one) { ... } else if (x == ^) {}
5302 AddEnumerators(Results, getASTContext(), Enum, SemaRef.CurContext,
5303 CoveredEnumerators());
5304 }
5305 }
5306
5307 if (S->getFnParent() && !Data.ObjCCollection &&
5308 !Data.IntegralConstantExpression)
5310
5311 if (CodeCompleter->includeMacros())
5312 AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false,
5313 PreferredTypeIsPointer);
5314
5315 // Complete a lambda expression when preferred type is a function.
5316 if (!Data.PreferredType.isNull() && getLangOpts().CPlusPlus11) {
5317 if (const FunctionProtoType *F =
5318 TryDeconstructFunctionLike(Data.PreferredType))
5319 AddLambdaCompletion(Results, F->getParamTypes(), getLangOpts());
5320 }
5321
5323 Results.getCompletionContext(), Results.data(),
5324 Results.size());
5325}
5326
5328 QualType PreferredType,
5329 bool IsParenthesized,
5330 bool IsAddressOfOperand) {
5332 S, CodeCompleteExpressionData(PreferredType, IsParenthesized),
5333 IsAddressOfOperand);
5334}
5335
5337 QualType PreferredType) {
5338 if (E.isInvalid())
5339 CodeCompleteExpression(S, PreferredType);
5340 else if (getLangOpts().ObjC)
5341 CodeCompleteObjCInstanceMessage(S, E.get(), {}, false);
5342}
5343
5344/// The set of properties that have already been added, referenced by
5345/// property name.
5347
5348/// Retrieve the container definition, if any?
5350 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5351 if (Interface->hasDefinition())
5352 return Interface->getDefinition();
5353
5354 return Interface;
5355 }
5356
5357 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5358 if (Protocol->hasDefinition())
5359 return Protocol->getDefinition();
5360
5361 return Protocol;
5362 }
5363 return Container;
5364}
5365
5366/// Adds a block invocation code completion result for the given block
5367/// declaration \p BD.
5368static void AddObjCBlockCall(ASTContext &Context, const PrintingPolicy &Policy,
5369 CodeCompletionBuilder &Builder,
5370 const NamedDecl *BD,
5371 const FunctionTypeLoc &BlockLoc,
5372 const FunctionProtoTypeLoc &BlockProtoLoc) {
5373 Builder.AddResultTypeChunk(
5374 GetCompletionTypeString(BlockLoc.getReturnLoc().getType(), Context,
5375 Policy, Builder.getAllocator()));
5376
5377 AddTypedNameChunk(Context, Policy, BD, Builder);
5378 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5379
5380 if (BlockProtoLoc && BlockProtoLoc.getTypePtr()->isVariadic()) {
5381 Builder.AddPlaceholderChunk("...");
5382 } else {
5383 for (unsigned I = 0, N = BlockLoc.getNumParams(); I != N; ++I) {
5384 if (I)
5385 Builder.AddChunk(CodeCompletionString::CK_Comma);
5386
5387 // Format the placeholder string.
5388 std::string PlaceholderStr =
5389 FormatFunctionParameter(Policy, BlockLoc.getParam(I));
5390
5391 if (I == N - 1 && BlockProtoLoc &&
5392 BlockProtoLoc.getTypePtr()->isVariadic())
5393 PlaceholderStr += ", ...";
5394
5395 // Add the placeholder string.
5396 Builder.AddPlaceholderChunk(
5397 Builder.getAllocator().CopyString(PlaceholderStr));
5398 }
5399 }
5400
5401 Builder.AddChunk(CodeCompletionString::CK_RightParen);
5402}
5403
5404static void
5406 ObjCContainerDecl *Container, bool AllowCategories,
5407 bool AllowNullaryMethods, DeclContext *CurContext,
5408 AddedPropertiesSet &AddedProperties, ResultBuilder &Results,
5409 bool IsBaseExprStatement = false,
5410 bool IsClassProperty = false, bool InOriginalClass = true) {
5412
5413 // Retrieve the definition.
5414 Container = getContainerDef(Container);
5415
5416 // Add properties in this container.
5417 const auto AddProperty = [&](const ObjCPropertyDecl *P) {
5418 if (!AddedProperties.insert(P->getIdentifier()).second)
5419 return;
5420
5421 // FIXME: Provide block invocation completion for non-statement
5422 // expressions.
5423 if (!P->getType().getTypePtr()->isBlockPointerType() ||
5424 !IsBaseExprStatement) {
5425 Result R =
5426 Result(P, Results.getBasePriority(P), /*Qualifier=*/std::nullopt);
5427 if (!InOriginalClass)
5428 setInBaseClass(R);
5429 Results.MaybeAddResult(R, CurContext);
5430 return;
5431 }
5432
5433 // Block setter and invocation completion is provided only when we are able
5434 // to find the FunctionProtoTypeLoc with parameter names for the block.
5435 FunctionTypeLoc BlockLoc;
5436 FunctionProtoTypeLoc BlockProtoLoc;
5437 findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc,
5438 BlockProtoLoc);
5439 if (!BlockLoc) {
5440 Result R =
5441 Result(P, Results.getBasePriority(P), /*Qualifier=*/std::nullopt);
5442 if (!InOriginalClass)
5443 setInBaseClass(R);
5444 Results.MaybeAddResult(R, CurContext);
5445 return;
5446 }
5447
5448 // The default completion result for block properties should be the block
5449 // invocation completion when the base expression is a statement.
5450 CodeCompletionBuilder Builder(Results.getAllocator(),
5451 Results.getCodeCompletionTUInfo());
5452 AddObjCBlockCall(Container->getASTContext(),
5453 getCompletionPrintingPolicy(Results.getSema()), Builder, P,
5454 BlockLoc, BlockProtoLoc);
5455 Result R = Result(Builder.TakeString(), P, Results.getBasePriority(P));
5456 if (!InOriginalClass)
5457 setInBaseClass(R);
5458 Results.MaybeAddResult(R, CurContext);
5459
5460 // Provide additional block setter completion iff the base expression is a
5461 // statement and the block property is mutable.
5462 if (!P->isReadOnly()) {
5463 CodeCompletionBuilder Builder(Results.getAllocator(),
5464 Results.getCodeCompletionTUInfo());
5465 AddResultTypeChunk(Container->getASTContext(),
5466 getCompletionPrintingPolicy(Results.getSema()), P,
5467 CCContext.getBaseType(), Builder);
5468 Builder.AddTypedTextChunk(
5469 Results.getAllocator().CopyString(P->getName()));
5470 Builder.AddChunk(CodeCompletionString::CK_Equal);
5471
5472 std::string PlaceholderStr = formatBlockPlaceholder(
5473 getCompletionPrintingPolicy(Results.getSema()), P, BlockLoc,
5474 BlockProtoLoc, /*SuppressBlockName=*/true);
5475 // Add the placeholder string.
5476 Builder.AddPlaceholderChunk(
5477 Builder.getAllocator().CopyString(PlaceholderStr));
5478
5479 // When completing blocks properties that return void the default
5480 // property completion result should show up before the setter,
5481 // otherwise the setter completion should show up before the default
5482 // property completion, as we normally want to use the result of the
5483 // call.
5484 Result R =
5485 Result(Builder.TakeString(), P,
5486 Results.getBasePriority(P) +
5487 (BlockLoc.getTypePtr()->getReturnType()->isVoidType()
5490 if (!InOriginalClass)
5491 setInBaseClass(R);
5492 Results.MaybeAddResult(R, CurContext);
5493 }
5494 };
5495
5496 if (IsClassProperty) {
5497 for (const auto *P : Container->class_properties())
5498 AddProperty(P);
5499 } else {
5500 for (const auto *P : Container->instance_properties())
5501 AddProperty(P);
5502 }
5503
5504 // Add nullary methods or implicit class properties
5505 if (AllowNullaryMethods) {
5506 ASTContext &Context = Container->getASTContext();
5507 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
5508 // Adds a method result
5509 const auto AddMethod = [&](const ObjCMethodDecl *M) {
5510 const IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0);
5511 if (!Name)
5512 return;
5513 if (!AddedProperties.insert(Name).second)
5514 return;
5515 CodeCompletionBuilder Builder(Results.getAllocator(),
5516 Results.getCodeCompletionTUInfo());
5517 AddResultTypeChunk(Context, Policy, M, CCContext.getBaseType(), Builder);
5518 Builder.AddTypedTextChunk(
5519 Results.getAllocator().CopyString(Name->getName()));
5520 Result R = Result(Builder.TakeString(), M,
5522 if (!InOriginalClass)
5523 setInBaseClass(R);
5524 Results.MaybeAddResult(R, CurContext);
5525 };
5526
5527 if (IsClassProperty) {
5528 for (const auto *M : Container->methods()) {
5529 // Gather the class method that can be used as implicit property
5530 // getters. Methods with arguments or methods that return void aren't
5531 // added to the results as they can't be used as a getter.
5532 if (!M->getSelector().isUnarySelector() ||
5533 M->getReturnType()->isVoidType() || M->isInstanceMethod())
5534 continue;
5535 AddMethod(M);
5536 }
5537 } else {
5538 for (auto *M : Container->methods()) {
5539 if (M->getSelector().isUnarySelector())
5540 AddMethod(M);
5541 }
5542 }
5543 }
5544
5545 // Add properties in referenced protocols.
5546 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5547 for (auto *P : Protocol->protocols())
5548 AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
5549 CurContext, AddedProperties, Results,
5550 IsBaseExprStatement, IsClassProperty,
5551 /*InOriginalClass*/ false);
5552 } else if (ObjCInterfaceDecl *IFace =
5553 dyn_cast<ObjCInterfaceDecl>(Container)) {
5554 if (AllowCategories) {
5555 // Look through categories.
5556 for (auto *Cat : IFace->known_categories())
5557 AddObjCProperties(CCContext, Cat, AllowCategories, AllowNullaryMethods,
5558 CurContext, AddedProperties, Results,
5559 IsBaseExprStatement, IsClassProperty,
5560 InOriginalClass);
5561 }
5562
5563 // Look through protocols.
5564 for (auto *I : IFace->all_referenced_protocols())
5565 AddObjCProperties(CCContext, I, AllowCategories, AllowNullaryMethods,
5566 CurContext, AddedProperties, Results,
5567 IsBaseExprStatement, IsClassProperty,
5568 /*InOriginalClass*/ false);
5569
5570 // Look in the superclass.
5571 if (IFace->getSuperClass())
5572 AddObjCProperties(CCContext, IFace->getSuperClass(), AllowCategories,
5573 AllowNullaryMethods, CurContext, AddedProperties,
5574 Results, IsBaseExprStatement, IsClassProperty,
5575 /*InOriginalClass*/ false);
5576 } else if (const auto *Category =
5577 dyn_cast<ObjCCategoryDecl>(Container)) {
5578 // Look through protocols.
5579 for (auto *P : Category->protocols())
5580 AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
5581 CurContext, AddedProperties, Results,
5582 IsBaseExprStatement, IsClassProperty,
5583 /*InOriginalClass*/ false);
5584 }
5585}
5586
5587static void
5588AddRecordMembersCompletionResults(Sema &SemaRef, ResultBuilder &Results,
5589 Scope *S, QualType BaseType,
5590 ExprValueKind BaseKind, RecordDecl *RD,
5591 std::optional<FixItHint> AccessOpFixIt) {
5592 // Indicate that we are performing a member access, and the cv-qualifiers
5593 // for the base object type.
5594 Results.setObjectTypeQualifiers(BaseType.getQualifiers(), BaseKind);
5595
5596 // Access to a C/C++ class, struct, or union.
5597 Results.allowNestedNameSpecifiers();
5598 std::vector<FixItHint> FixIts;
5599 if (AccessOpFixIt)
5600 FixIts.emplace_back(*AccessOpFixIt);
5601 CodeCompletionDeclConsumer Consumer(Results, RD, BaseType, std::move(FixIts));
5602 SemaRef.LookupVisibleDecls(
5603 RD, Sema::LookupMemberName, Consumer,
5605 /*IncludeDependentBases=*/true,
5607
5608 if (SemaRef.getLangOpts().CPlusPlus) {
5609 if (!Results.empty()) {
5610 // The "template" keyword can follow "->" or "." in the grammar.
5611 // However, we only want to suggest the template keyword if something
5612 // is dependent.
5613 bool IsDependent = BaseType->isDependentType();
5614 if (!IsDependent) {
5615 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
5616 if (DeclContext *Ctx = DepScope->getEntity()) {
5617 IsDependent = Ctx->isDependentContext();
5618 break;
5619 }
5620 }
5621
5622 if (IsDependent)
5623 Results.AddResult(CodeCompletionResult("template"));
5624 }
5625 }
5626}
5627
5628// Returns the RecordDecl inside the BaseType, falling back to primary template
5629// in case of specializations. Since we might not have a decl for the
5630// instantiation/specialization yet, e.g. dependent code.
5632 HeuristicResolver &Resolver) {
5633 BaseType = Resolver.simplifyType(BaseType, nullptr, /*UnwrapPointer=*/false);
5634 return dyn_cast_if_present<RecordDecl>(
5635 Resolver.resolveTypeToTagDecl(BaseType));
5636}
5637
5638namespace {
5639// Collects completion-relevant information about a concept-constrainted type T.
5640// In particular, examines the constraint expressions to find members of T.
5641//
5642// The design is very simple: we walk down each constraint looking for
5643// expressions of the form T.foo().
5644// If we're extra lucky, the return type is specified.
5645// We don't do any clever handling of && or || in constraint expressions, we
5646// take members from both branches.
5647//
5648// For example, given:
5649// template <class T> concept X = requires (T t, string& s) { t.print(s); };
5650// template <X U> void foo(U u) { u.^ }
5651// We want to suggest the inferred member function 'print(string)'.
5652// We see that u has type U, so X<U> holds.
5653// X<U> requires t.print(s) to be valid, where t has type U (substituted for T).
5654// By looking at the CallExpr we find the signature of print().
5655//
5656// While we tend to know in advance which kind of members (access via . -> ::)
5657// we want, it's simpler just to gather them all and post-filter.
5658//
5659// FIXME: some of this machinery could be used for non-concept type-parms too,
5660// enabling completion for type parameters based on other uses of that param.
5661//
5662// FIXME: there are other cases where a type can be constrained by a concept,
5663// e.g. inside `if constexpr(ConceptSpecializationExpr) { ... }`
5664class ConceptInfo {
5665public:
5666 // Describes a likely member of a type, inferred by concept constraints.
5667 // Offered as a code completion for T. T-> and T:: contexts.
5668 struct Member {
5669 // Always non-null: we only handle members with ordinary identifier names.
5670 const IdentifierInfo *Name = nullptr;
5671 // Set for functions we've seen called.
5672 // We don't have the declared parameter types, only the actual types of
5673 // arguments we've seen. These are still valuable, as it's hard to render
5674 // a useful function completion with neither parameter types nor names!
5675 std::optional<SmallVector<QualType, 1>> ArgTypes;
5676 // Whether this is accessed as T.member, T->member, or T::member.
5677 enum AccessOperator {
5678 Colons,
5679 Arrow,
5680 Dot,
5681 } Operator = Dot;
5682 // What's known about the type of a variable or return type of a function.
5683 const TypeConstraint *ResultType = nullptr;
5684 // FIXME: also track:
5685 // - kind of entity (function/variable/type), to expose structured results
5686 // - template args kinds/types, as a proxy for template params
5687
5688 // For now we simply return these results as "pattern" strings.
5689 CodeCompletionString *render(Sema &S, CodeCompletionAllocator &Alloc,
5690 CodeCompletionTUInfo &Info) const {
5691 CodeCompletionBuilder B(Alloc, Info);
5692 // Result type
5693 if (ResultType) {
5694 std::string AsString;
5695 {
5696 llvm::raw_string_ostream OS(AsString);
5697 QualType ExactType = deduceType(*ResultType);
5698 if (!ExactType.isNull())
5699 ExactType.print(OS, getCompletionPrintingPolicy(S));
5700 else
5701 ResultType->print(OS, getCompletionPrintingPolicy(S));
5702 }
5703 B.AddResultTypeChunk(Alloc.CopyString(AsString));
5704 }
5705 // Member name
5706 B.AddTypedTextChunk(Alloc.CopyString(Name->getName()));
5707 // Function argument list
5708 if (ArgTypes) {
5710 bool First = true;
5711 for (QualType Arg : *ArgTypes) {
5712 if (First)
5713 First = false;
5714 else {
5717 }
5718 B.AddPlaceholderChunk(Alloc.CopyString(
5719 Arg.getAsString(getCompletionPrintingPolicy(S))));
5720 }
5722 }
5723 return B.TakeString();
5724 }
5725 };
5726
5727 // BaseType is the type parameter T to infer members from.
5728 // T must be accessible within S, as we use it to find the template entity
5729 // that T is attached to in order to gather the relevant constraints.
5730 ConceptInfo(const TemplateTypeParmType &BaseType, Scope *S) {
5731 auto *TemplatedEntity = getTemplatedEntity(BaseType.getDecl(), S);
5732 for (const AssociatedConstraint &AC :
5733 constraintsForTemplatedEntity(TemplatedEntity))
5734 believe(AC.ConstraintExpr, &BaseType);
5735 }
5736
5737 std::vector<Member> members() {
5738 std::vector<Member> Results;
5739 for (const auto &E : this->Results)
5740 Results.push_back(E.second);
5741 llvm::sort(Results, [](const Member &L, const Member &R) {
5742 return L.Name->getName() < R.Name->getName();
5743 });
5744 return Results;
5745 }
5746
5747private:
5748 // Infer members of T, given that the expression E (dependent on T) is true.
5749 void believe(const Expr *E, const TemplateTypeParmType *T) {
5750 if (!E || !T)
5751 return;
5752 if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(E)) {
5753 // If the concept is
5754 // template <class A, class B> concept CD = f<A, B>();
5755 // And the concept specialization is
5756 // CD<int, T>
5757 // Then we're substituting T for B, so we want to make f<A, B>() true
5758 // by adding members to B - i.e. believe(f<A, B>(), B);
5759 //
5760 // For simplicity:
5761 // - we don't attempt to substitute int for A
5762 // - when T is used in other ways (like CD<T*>) we ignore it
5763 ConceptDecl *CD = CSE->getConceptDecl();
5764 TemplateParameterList *Params = CD->getTemplateParameters();
5765 unsigned Index = 0;
5766 for (const auto &Arg : CSE->getTemplateArguments()) {
5767 if (Index >= Params->size())
5768 break; // Won't happen in valid code.
5769 if (isApprox(Arg, T)) {
5770 auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Params->getParam(Index));
5771 if (!TTPD)
5772 continue;
5773 // T was used as an argument, and bound to the parameter TT.
5774 auto *TT = cast<TemplateTypeParmType>(TTPD->getTypeForDecl());
5775 // So now we know the constraint as a function of TT is true.
5776 believe(CD->getConstraintExpr(), TT);
5777 // (concepts themselves have no associated constraints to require)
5778 }
5779
5780 ++Index;
5781 }
5782 } else if (auto *BO = dyn_cast<BinaryOperator>(E)) {
5783 // For A && B, we can infer members from both branches.
5784 // For A || B, the union is still more useful than the intersection.
5785 if (BO->getOpcode() == BO_LAnd || BO->getOpcode() == BO_LOr) {
5786 believe(BO->getLHS(), T);
5787 believe(BO->getRHS(), T);
5788 }
5789 } else if (auto *RE = dyn_cast<RequiresExpr>(E)) {
5790 // A requires(){...} lets us infer members from each requirement.
5791 for (const concepts::Requirement *Req : RE->getRequirements()) {
5792 if (!Req->isDependent())
5793 continue; // Can't tell us anything about T.
5794 // Now Req cannot a substitution-error: those aren't dependent.
5795
5796 if (auto *TR = dyn_cast<concepts::TypeRequirement>(Req)) {
5797 // Do a full traversal so we get `foo` from `typename T::foo::bar`.
5798 QualType AssertedType = TR->getType()->getType();
5799 ValidVisitor(this, T).TraverseType(AssertedType);
5800 } else if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
5801 ValidVisitor Visitor(this, T);
5802 // If we have a type constraint on the value of the expression,
5803 // AND the whole outer expression describes a member, then we'll
5804 // be able to use the constraint to provide the return type.
5805 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
5806 Visitor.OuterType =
5807 ER->getReturnTypeRequirement().getTypeConstraint();
5808 Visitor.OuterExpr = ER->getExpr();
5809 }
5810 Visitor.TraverseStmt(ER->getExpr());
5811 } else if (auto *NR = dyn_cast<concepts::NestedRequirement>(Req)) {
5812 believe(NR->getConstraintExpr(), T);
5813 }
5814 }
5815 }
5816 }
5817
5818 // This visitor infers members of T based on traversing expressions/types
5819 // that involve T. It is invoked with code known to be valid for T.
5820 class ValidVisitor : public DynamicRecursiveASTVisitor {
5821 ConceptInfo *Outer;
5822 const TemplateTypeParmType *T;
5823
5824 CallExpr *Caller = nullptr;
5825 Expr *Callee = nullptr;
5826
5827 public:
5828 // If set, OuterExpr is constrained by OuterType.
5829 Expr *OuterExpr = nullptr;
5830 const TypeConstraint *OuterType = nullptr;
5831
5832 ValidVisitor(ConceptInfo *Outer, const TemplateTypeParmType *T)
5833 : Outer(Outer), T(T) {
5834 assert(T);
5835 }
5836
5837 // In T.foo or T->foo, `foo` is a member function/variable.
5838 bool
5839 VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override {
5840 const Type *Base = E->getBaseType().getTypePtr();
5841 bool IsArrow = E->isArrow();
5842 if (Base->isPointerType() && IsArrow) {
5843 IsArrow = false;
5844 Base = Base->getPointeeType().getTypePtr();
5845 }
5846 if (isApprox(Base, T))
5847 addValue(E, E->getMember(), IsArrow ? Member::Arrow : Member::Dot);
5848 return true;
5849 }
5850
5851 // In T::foo, `foo` is a static member function/variable.
5852 bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) override {
5853 NestedNameSpecifier Qualifier = E->getQualifier();
5854 if (Qualifier.getKind() == NestedNameSpecifier::Kind::Type &&
5855 isApprox(Qualifier.getAsType(), T))
5856 addValue(E, E->getDeclName(), Member::Colons);
5857 return true;
5858 }
5859
5860 // In T::typename foo, `foo` is a type.
5861 bool VisitDependentNameType(DependentNameType *DNT) override {
5862 NestedNameSpecifier Q = DNT->getQualifier();
5863 if (Q.getKind() == NestedNameSpecifier::Kind::Type &&
5864 isApprox(Q.getAsType(), T))
5865 addType(DNT->getIdentifier());
5866 return true;
5867 }
5868
5869 // In T::foo::bar, `foo` must be a type.
5870 // VisitNNS() doesn't exist, and TraverseNNS isn't always called :-(
5871 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) override {
5872 if (NNSL) {
5873 NestedNameSpecifier NNS = NNSL.getNestedNameSpecifier();
5874 if (NNS.getKind() == NestedNameSpecifier::Kind::Type) {
5875 const Type *NNST = NNS.getAsType();
5876 if (NestedNameSpecifier Q = NNST->getPrefix();
5877 Q.getKind() == NestedNameSpecifier::Kind::Type &&
5878 isApprox(Q.getAsType(), T))
5879 if (const auto *DNT = dyn_cast_or_null<DependentNameType>(NNST))
5880 addType(DNT->getIdentifier());
5881 }
5882 }
5883 // FIXME: also handle T::foo<X>::bar
5885 }
5886
5887 // FIXME also handle T::foo<X>
5888
5889 // Track the innermost caller/callee relationship so we can tell if a
5890 // nested expr is being called as a function.
5891 bool VisitCallExpr(CallExpr *CE) override {
5892 Caller = CE;
5893 Callee = CE->getCallee();
5894 return true;
5895 }
5896
5897 private:
5898 void addResult(Member &&M) {
5899 auto R = Outer->Results.try_emplace(M.Name);
5900 Member &O = R.first->second;
5901 // Overwrite existing if the new member has more info.
5902 // The preference of . vs :: vs -> is fairly arbitrary.
5903 if (/*Inserted*/ R.second ||
5904 std::make_tuple(M.ArgTypes.has_value(), M.ResultType != nullptr,
5905 M.Operator) > std::make_tuple(O.ArgTypes.has_value(),
5906 O.ResultType != nullptr,
5907 O.Operator))
5908 O = std::move(M);
5909 }
5910
5911 void addType(const IdentifierInfo *Name) {
5912 if (!Name)
5913 return;
5914 Member M;
5915 M.Name = Name;
5916 M.Operator = Member::Colons;
5917 addResult(std::move(M));
5918 }
5919
5920 void addValue(Expr *E, DeclarationName Name,
5921 Member::AccessOperator Operator) {
5922 if (!Name.isIdentifier())
5923 return;
5924 Member Result;
5925 Result.Name = Name.getAsIdentifierInfo();
5926 Result.Operator = Operator;
5927 // If this is the callee of an immediately-enclosing CallExpr, then
5928 // treat it as a method, otherwise it's a variable.
5929 if (Caller != nullptr && Callee == E) {
5930 Result.ArgTypes.emplace();
5931 for (const auto *Arg : Caller->arguments())
5932 Result.ArgTypes->push_back(Arg->getType());
5933 if (Caller == OuterExpr) {
5934 Result.ResultType = OuterType;
5935 }
5936 } else {
5937 if (E == OuterExpr)
5938 Result.ResultType = OuterType;
5939 }
5940 addResult(std::move(Result));
5941 }
5942 };
5943
5944 static bool isApprox(const TemplateArgument &Arg, const Type *T) {
5945 return Arg.getKind() == TemplateArgument::Type &&
5946 isApprox(Arg.getAsType().getTypePtr(), T);
5947 }
5948
5949 static bool isApprox(const Type *T1, const Type *T2) {
5950 return T1 && T2 &&
5953 }
5954
5955 // Returns the DeclContext immediately enclosed by the template parameter
5956 // scope. For primary templates, this is the templated (e.g.) CXXRecordDecl.
5957 // For specializations, this is e.g. ClassTemplatePartialSpecializationDecl.
5958 static DeclContext *getTemplatedEntity(const TemplateTypeParmDecl *D,
5959 Scope *S) {
5960 if (D == nullptr)
5961 return nullptr;
5962 Scope *Inner = nullptr;
5963 while (S) {
5964 if (S->isTemplateParamScope() && S->isDeclScope(D))
5965 return Inner ? Inner->getEntity() : nullptr;
5966 Inner = S;
5967 S = S->getParent();
5968 }
5969 return nullptr;
5970 }
5971
5972 // Gets all the type constraint expressions that might apply to the type
5973 // variables associated with DC (as returned by getTemplatedEntity()).
5974 static SmallVector<AssociatedConstraint, 1>
5975 constraintsForTemplatedEntity(DeclContext *DC) {
5976 SmallVector<AssociatedConstraint, 1> Result;
5977 if (DC == nullptr)
5978 return Result;
5979 // Primary templates can have constraints.
5980 if (const auto *TD = cast<Decl>(DC)->getDescribedTemplate())
5981 TD->getAssociatedConstraints(Result);
5982 // Partial specializations may have constraints.
5983 if (const auto *CTPSD =
5984 dyn_cast<ClassTemplatePartialSpecializationDecl>(DC))
5985 CTPSD->getAssociatedConstraints(Result);
5986 if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(DC))
5987 VTPSD->getAssociatedConstraints(Result);
5988 return Result;
5989 }
5990
5991 // Attempt to find the unique type satisfying a constraint.
5992 // This lets us show e.g. `int` instead of `std::same_as<int>`.
5993 static QualType deduceType(const TypeConstraint &T) {
5994 // Assume a same_as<T> return type constraint is std::same_as or equivalent.
5995 // In this case the return type is T.
5996 DeclarationName DN =
5997 T.getConceptReference()->getConceptNameInfo().getName();
5998 if (DN.isIdentifier() && DN.getAsIdentifierInfo()->isStr("same_as"))
5999 if (const auto *Args = T.getTemplateArgsAsWritten())
6000 if (Args->getNumTemplateArgs() == 1) {
6001 const auto &Arg = Args->arguments().front().getArgument();
6002 if (Arg.getKind() == TemplateArgument::Type)
6003 return Arg.getAsType();
6004 }
6005 return {};
6006 }
6007
6008 llvm::DenseMap<const IdentifierInfo *, Member> Results;
6009};
6010
6011// Returns a type for E that yields acceptable member completions.
6012// In particular, when E->getType() is DependentTy, try to guess a likely type.
6013// We accept some lossiness (like dropping parameters).
6014// We only try to handle common expressions on the LHS of MemberExpr.
6015QualType getApproximateType(const Expr *E, HeuristicResolver &Resolver) {
6016 QualType Result = Resolver.resolveExprToType(E);
6017 if (Result.isNull())
6018 return Result;
6019 Result = Resolver.simplifyType(Result.getNonReferenceType(), E, false);
6020 if (Result.isNull())
6021 return Result;
6022 return Result.getNonReferenceType();
6023}
6024
6025// If \p Base is ParenListExpr, assume a chain of comma operators and pick the
6026// last expr. We expect other ParenListExprs to be resolved to e.g. constructor
6027// calls before here. (So the ParenListExpr should be nonempty, but check just
6028// in case)
6029Expr *unwrapParenList(Expr *Base) {
6030 if (auto *PLE = llvm::dyn_cast_or_null<ParenListExpr>(Base)) {
6031 if (PLE->getNumExprs() == 0)
6032 return nullptr;
6033 Base = PLE->getExpr(PLE->getNumExprs() - 1);
6034 }
6035 return Base;
6036}
6037
6038} // namespace
6039
6041 Scope *S, Expr *Base, Expr *OtherOpBase, SourceLocation OpLoc, bool IsArrow,
6042 bool IsBaseExprStatement, QualType PreferredType) {
6043 Base = unwrapParenList(Base);
6044 OtherOpBase = unwrapParenList(OtherOpBase);
6045 if (!Base || !CodeCompleter)
6046 return;
6047
6048 ExprResult ConvertedBase =
6049 SemaRef.PerformMemberExprBaseConversion(Base, IsArrow);
6050 if (ConvertedBase.isInvalid())
6051 return;
6052 QualType ConvertedBaseType =
6053 getApproximateType(ConvertedBase.get(), Resolver);
6054
6055 enum CodeCompletionContext::Kind contextKind;
6056
6057 if (IsArrow) {
6058 if (QualType PointeeType = Resolver.getPointeeType(ConvertedBaseType);
6059 !PointeeType.isNull()) {
6060 ConvertedBaseType = PointeeType;
6061 }
6062 }
6063
6064 if (IsArrow) {
6066 } else {
6067 if (ConvertedBaseType->isObjCObjectPointerType() ||
6068 ConvertedBaseType->isObjCObjectOrInterfaceType()) {
6070 } else {
6072 }
6073 }
6074
6075 CodeCompletionContext CCContext(contextKind, ConvertedBaseType);
6076 CCContext.setPreferredType(PreferredType);
6077 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6078 CodeCompleter->getCodeCompletionTUInfo(), CCContext,
6079 &ResultBuilder::IsMember);
6080
6081 auto DoCompletion = [&](Expr *Base, bool IsArrow,
6082 std::optional<FixItHint> AccessOpFixIt) -> bool {
6083 if (!Base)
6084 return false;
6085
6086 ExprResult ConvertedBase =
6087 SemaRef.PerformMemberExprBaseConversion(Base, IsArrow);
6088 if (ConvertedBase.isInvalid())
6089 return false;
6090 Base = ConvertedBase.get();
6091
6092 QualType BaseType = getApproximateType(Base, Resolver);
6093 if (BaseType.isNull())
6094 return false;
6095 ExprValueKind BaseKind = Base->getValueKind();
6096
6097 if (IsArrow) {
6098 if (QualType PointeeType = Resolver.getPointeeType(BaseType);
6099 !PointeeType.isNull()) {
6100 BaseType = PointeeType;
6101 BaseKind = VK_LValue;
6102 } else if (BaseType->isObjCObjectPointerType() ||
6103 BaseType->isTemplateTypeParmType()) {
6104 // Both cases (dot/arrow) handled below.
6105 } else {
6106 return false;
6107 }
6108 }
6109
6110 if (RecordDecl *RD = getAsRecordDecl(BaseType, Resolver)) {
6111 AddRecordMembersCompletionResults(SemaRef, Results, S, BaseType, BaseKind,
6112 RD, std::move(AccessOpFixIt));
6113 } else if (const auto *TTPT =
6114 dyn_cast<TemplateTypeParmType>(BaseType.getTypePtr())) {
6115 auto Operator =
6116 IsArrow ? ConceptInfo::Member::Arrow : ConceptInfo::Member::Dot;
6117 for (const auto &R : ConceptInfo(*TTPT, S).members()) {
6118 if (R.Operator != Operator)
6119 continue;
6121 R.render(SemaRef, CodeCompleter->getAllocator(),
6122 CodeCompleter->getCodeCompletionTUInfo()));
6123 if (AccessOpFixIt)
6124 Result.FixIts.push_back(*AccessOpFixIt);
6125 Results.AddResult(std::move(Result));
6126 }
6127 } else if (!IsArrow && BaseType->isObjCObjectPointerType()) {
6128 // Objective-C property reference. Bail if we're performing fix-it code
6129 // completion since Objective-C properties are normally backed by ivars,
6130 // most Objective-C fix-its here would have little value.
6131 if (AccessOpFixIt) {
6132 return false;
6133 }
6134 AddedPropertiesSet AddedProperties;
6135
6136 if (const ObjCObjectPointerType *ObjCPtr =
6137 BaseType->getAsObjCInterfacePointerType()) {
6138 // Add property results based on our interface.
6139 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
6140 AddObjCProperties(CCContext, ObjCPtr->getInterfaceDecl(), true,
6141 /*AllowNullaryMethods=*/true, SemaRef.CurContext,
6142 AddedProperties, Results, IsBaseExprStatement);
6143 }
6144
6145 // Add properties from the protocols in a qualified interface.
6146 for (auto *I : BaseType->castAs<ObjCObjectPointerType>()->quals())
6147 AddObjCProperties(CCContext, I, true, /*AllowNullaryMethods=*/true,
6148 SemaRef.CurContext, AddedProperties, Results,
6149 IsBaseExprStatement, /*IsClassProperty*/ false,
6150 /*InOriginalClass*/ false);
6151 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
6152 (!IsArrow && BaseType->isObjCObjectType())) {
6153 // Objective-C instance variable access. Bail if we're performing fix-it
6154 // code completion since Objective-C properties are normally backed by
6155 // ivars, most Objective-C fix-its here would have little value.
6156 if (AccessOpFixIt) {
6157 return false;
6158 }
6159 ObjCInterfaceDecl *Class = nullptr;
6160 if (const ObjCObjectPointerType *ObjCPtr =
6161 BaseType->getAs<ObjCObjectPointerType>())
6162 Class = ObjCPtr->getInterfaceDecl();
6163 else
6164 Class = BaseType->castAs<ObjCObjectType>()->getInterface();
6165
6166 // Add all ivars from this class and its superclasses.
6167 if (Class) {
6168 CodeCompletionDeclConsumer Consumer(Results, Class, BaseType);
6169 Results.setFilter(&ResultBuilder::IsObjCIvar);
6170 SemaRef.LookupVisibleDecls(Class, Sema::LookupMemberName, Consumer,
6171 CodeCompleter->includeGlobals(),
6172 /*IncludeDependentBases=*/false,
6173 CodeCompleter->loadExternal());
6174 }
6175 }
6176
6177 // FIXME: How do we cope with isa?
6178 return true;
6179 };
6180
6181 Results.EnterNewScope();
6182
6183 bool CompletionSucceded = DoCompletion(Base, IsArrow, std::nullopt);
6184 if (CodeCompleter->includeFixIts()) {
6185 const CharSourceRange OpRange =
6186 CharSourceRange::getTokenRange(OpLoc, OpLoc);
6187 CompletionSucceded |= DoCompletion(
6188 OtherOpBase, !IsArrow,
6189 FixItHint::CreateReplacement(OpRange, IsArrow ? "." : "->"));
6190 }
6191
6192 Results.ExitScope();
6193
6194 if (!CompletionSucceded)
6195 return;
6196
6197 // Hand off the results found for code completion.
6199 Results.getCompletionContext(), Results.data(),
6200 Results.size());
6201}
6202
6204 Scope *S, const IdentifierInfo &ClassName, SourceLocation ClassNameLoc,
6205 bool IsBaseExprStatement) {
6206 const IdentifierInfo *ClassNamePtr = &ClassName;
6207 ObjCInterfaceDecl *IFace =
6208 SemaRef.ObjC().getObjCInterfaceDecl(ClassNamePtr, ClassNameLoc);
6209 if (!IFace)
6210 return;
6211 CodeCompletionContext CCContext(
6213 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6214 CodeCompleter->getCodeCompletionTUInfo(), CCContext,
6215 &ResultBuilder::IsMember);
6216 Results.EnterNewScope();
6217 AddedPropertiesSet AddedProperties;
6218 AddObjCProperties(CCContext, IFace, true,
6219 /*AllowNullaryMethods=*/true, SemaRef.CurContext,
6220 AddedProperties, Results, IsBaseExprStatement,
6221 /*IsClassProperty=*/true);
6222 Results.ExitScope();
6224 Results.getCompletionContext(), Results.data(),
6225 Results.size());
6226}
6227
6228void SemaCodeCompletion::CodeCompleteTag(Scope *S, unsigned TagSpec) {
6229 if (!CodeCompleter)
6230 return;
6231
6232 ResultBuilder::LookupFilter Filter = nullptr;
6233 enum CodeCompletionContext::Kind ContextKind =
6235 switch ((DeclSpec::TST)TagSpec) {
6236 case DeclSpec::TST_enum:
6237 Filter = &ResultBuilder::IsEnum;
6239 break;
6240
6242 Filter = &ResultBuilder::IsUnion;
6244 break;
6245
6249 Filter = &ResultBuilder::IsClassOrStruct;
6251 break;
6252
6253 default:
6254 llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
6255 }
6256
6257 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6258 CodeCompleter->getCodeCompletionTUInfo(), ContextKind);
6259 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6260
6261 // First pass: look for tags.
6262 Results.setFilter(Filter);
6263 SemaRef.LookupVisibleDecls(S, Sema::LookupTagName, Consumer,
6264 CodeCompleter->includeGlobals(),
6265 CodeCompleter->loadExternal());
6266
6267 if (CodeCompleter->includeGlobals()) {
6268 // Second pass: look for nested name specifiers.
6269 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
6270 SemaRef.LookupVisibleDecls(S, Sema::LookupNestedNameSpecifierName, Consumer,
6271 CodeCompleter->includeGlobals(),
6272 CodeCompleter->loadExternal());
6273 }
6274
6276 Results.getCompletionContext(), Results.data(),
6277 Results.size());
6278}
6279
6280static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results,
6281 const LangOptions &LangOpts) {
6283 Results.AddResult("const");
6285 Results.AddResult("volatile");
6286 if (LangOpts.C99 && !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
6287 Results.AddResult("restrict");
6288 if (LangOpts.C11 && !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
6289 Results.AddResult("_Atomic");
6290 if (LangOpts.MSVCCompat && !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
6291 Results.AddResult("__unaligned");
6292}
6293
6295 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6296 CodeCompleter->getCodeCompletionTUInfo(),
6298 Results.EnterNewScope();
6299 AddTypeQualifierResults(DS, Results, getLangOpts());
6300 Results.ExitScope();
6302 Results.getCompletionContext(), Results.data(),
6303 Results.size());
6304}
6305
6307 DeclSpec &DS, Declarator &D, const VirtSpecifiers *VS) {
6308 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6309 CodeCompleter->getCodeCompletionTUInfo(),
6311 Results.EnterNewScope();
6312 AddTypeQualifierResults(DS, Results, getLangOpts());
6313 if (getLangOpts().CPlusPlus11) {
6314 Results.AddResult("noexcept");
6316 !D.isStaticMember()) {
6317 if (!VS || !VS->isFinalSpecified())
6318 Results.AddResult("final");
6319 if (!VS || !VS->isOverrideSpecified())
6320 Results.AddResult("override");
6321 }
6322 }
6323 Results.ExitScope();
6325 Results.getCompletionContext(), Results.data(),
6326 Results.size());
6327}
6328
6332
6334 if (SemaRef.getCurFunction()->SwitchStack.empty() || !CodeCompleter)
6335 return;
6336
6338 SemaRef.getCurFunction()->SwitchStack.back().getPointer();
6339 // Condition expression might be invalid, do not continue in this case.
6340 if (!Switch->getCond())
6341 return;
6342 QualType type = Switch->getCond()->IgnoreImplicit()->getType();
6343 EnumDecl *Enum = type->getAsEnumDecl();
6344 if (!Enum) {
6346 Data.IntegralConstantExpression = true;
6348 return;
6349 }
6350
6351 // Determine which enumerators we have already seen in the switch statement.
6352 // FIXME: Ideally, we would also be able to look *past* the code-completion
6353 // token, in case we are code-completing in the middle of the switch and not
6354 // at the end. However, we aren't able to do so at the moment.
6355 CoveredEnumerators Enumerators;
6356 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
6357 SC = SC->getNextSwitchCase()) {
6358 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
6359 if (!Case)
6360 continue;
6361
6362 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
6363 if (auto *DRE = dyn_cast<DeclRefExpr>(CaseVal))
6364 if (auto *Enumerator =
6365 dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
6366 // We look into the AST of the case statement to determine which
6367 // enumerator was named. Alternatively, we could compute the value of
6368 // the integral constant expression, then compare it against the
6369 // values of each enumerator. However, value-based approach would not
6370 // work as well with C++ templates where enumerators declared within a
6371 // template are type- and value-dependent.
6372 Enumerators.Seen.insert(Enumerator);
6373
6374 // If this is a qualified-id, keep track of the nested-name-specifier
6375 // so that we can reproduce it as part of code completion, e.g.,
6376 //
6377 // switch (TagD.getKind()) {
6378 // case TagDecl::TK_enum:
6379 // break;
6380 // case XXX
6381 //
6382 // At the XXX, our completions are TagDecl::TK_union,
6383 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
6384 // TK_struct, and TK_class.
6385 Enumerators.SuggestedQualifier = DRE->getQualifier();
6386 }
6387 }
6388
6389 // Add any enumerators that have not yet been mentioned.
6390 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6391 CodeCompleter->getCodeCompletionTUInfo(),
6393 AddEnumerators(Results, getASTContext(), Enum, SemaRef.CurContext,
6394 Enumerators);
6395
6396 if (CodeCompleter->includeMacros()) {
6397 AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
6398 }
6400 Results.getCompletionContext(), Results.data(),
6401 Results.size());
6402}
6403
6405 if (Args.size() && !Args.data())
6406 return true;
6407
6408 for (unsigned I = 0; I != Args.size(); ++I)
6409 if (!Args[I])
6410 return true;
6411
6412 return false;
6413}
6414
6416
6418 Sema &SemaRef, SmallVectorImpl<ResultCandidate> &Results,
6419 OverloadCandidateSet &CandidateSet, SourceLocation Loc, size_t ArgSize) {
6420 // Sort the overload candidate set by placing the best overloads first.
6421 llvm::stable_sort(CandidateSet, [&](const OverloadCandidate &X,
6422 const OverloadCandidate &Y) {
6423 return isBetterOverloadCandidate(SemaRef, X, Y, Loc, CandidateSet.getKind(),
6424 /*PartialOverloading=*/true);
6425 });
6426
6427 // Add the remaining viable overload candidates as code-completion results.
6428 for (OverloadCandidate &Candidate : CandidateSet) {
6429 if (Candidate.Function) {
6430 if (Candidate.Function->isDeleted())
6431 continue;
6432 if (shouldEnforceArgLimit(/*PartialOverloading=*/true,
6433 Candidate.Function) &&
6434 Candidate.Function->getNumParams() <= ArgSize &&
6435 // Having zero args is annoying, normally we don't surface a function
6436 // with 2 params, if you already have 2 params, because you are
6437 // inserting the 3rd now. But with zero, it helps the user to figure
6438 // out there are no overloads that take any arguments. Hence we are
6439 // keeping the overload.
6440 ArgSize > 0)
6441 continue;
6442 }
6443 if (Candidate.Viable)
6444 Results.push_back(ResultCandidate(Candidate.Function));
6445 }
6446}
6447
6448/// Get the type of the Nth parameter from a given set of overload
6449/// candidates.
6451 ArrayRef<ResultCandidate> Candidates, unsigned N) {
6452
6453 // Given the overloads 'Candidates' for a function call matching all arguments
6454 // up to N, return the type of the Nth parameter if it is the same for all
6455 // overload candidates.
6456 QualType ParamType;
6457 for (auto &Candidate : Candidates) {
6458 QualType CandidateParamType = Candidate.getParamType(N);
6459 if (CandidateParamType.isNull())
6460 continue;
6461 if (ParamType.isNull()) {
6462 ParamType = CandidateParamType;
6463 continue;
6464 }
6465 if (!SemaRef.Context.hasSameUnqualifiedType(
6466 ParamType.getNonReferenceType(),
6467 CandidateParamType.getNonReferenceType()))
6468 // Two conflicting types, give up.
6469 return QualType();
6470 }
6471
6472 return ParamType;
6473}
6474
6475static QualType
6477 unsigned CurrentArg, SourceLocation OpenParLoc,
6478 bool Braced) {
6479 if (Candidates.empty())
6480 return QualType();
6483 SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc,
6484 Braced);
6485 return getParamType(SemaRef, Candidates, CurrentArg);
6486}
6487
6488QualType
6490 SourceLocation OpenParLoc) {
6491 Fn = unwrapParenList(Fn);
6492 if (!CodeCompleter || !Fn)
6493 return QualType();
6494
6495 // FIXME: Provide support for variadic template functions.
6496 // Ignore type-dependent call expressions entirely.
6497 if (Fn->isTypeDependent() || anyNullArguments(Args))
6498 return QualType();
6499 // In presence of dependent args we surface all possible signatures using the
6500 // non-dependent args in the prefix. Afterwards we do a post filtering to make
6501 // sure provided candidates satisfy parameter count restrictions.
6502 auto ArgsWithoutDependentTypes =
6503 Args.take_while([](Expr *Arg) { return !Arg->isTypeDependent(); });
6504
6506
6507 Expr *NakedFn = Fn->IgnoreParenCasts();
6508 // Build an overload candidate set based on the functions we find.
6509 SourceLocation Loc = Fn->getExprLoc();
6510 OverloadCandidateSet CandidateSet(Loc,
6512
6513 if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) {
6514 SemaRef.AddOverloadedCallCandidates(ULE, ArgsWithoutDependentTypes,
6515 CandidateSet,
6516 /*PartialOverloading=*/true);
6517 } else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) {
6518 TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
6519 if (UME->hasExplicitTemplateArgs()) {
6520 UME->copyTemplateArgumentsInto(TemplateArgsBuffer);
6521 TemplateArgs = &TemplateArgsBuffer;
6522 }
6523
6524 // Add the base as first argument (use a nullptr if the base is implicit).
6525 SmallVector<Expr *, 12> ArgExprs(
6526 1, UME->isImplicitAccess() ? nullptr : UME->getBase());
6527 ArgExprs.append(ArgsWithoutDependentTypes.begin(),
6528 ArgsWithoutDependentTypes.end());
6529 UnresolvedSet<8> Decls;
6530 Decls.append(UME->decls_begin(), UME->decls_end());
6531 const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase();
6532 SemaRef.AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,
6533 /*SuppressUserConversions=*/false,
6534 /*PartialOverloading=*/true,
6535 FirstArgumentIsBase);
6536 } else {
6537 FunctionDecl *FD = nullptr;
6538 if (auto *MCE = dyn_cast<MemberExpr>(NakedFn))
6539 FD = dyn_cast<FunctionDecl>(MCE->getMemberDecl());
6540 else if (auto *DRE = dyn_cast<DeclRefExpr>(NakedFn))
6541 FD = dyn_cast<FunctionDecl>(DRE->getDecl());
6542 if (FD) { // We check whether it's a resolved function declaration.
6543 if (!getLangOpts().CPlusPlus ||
6544 !FD->getType()->getAs<FunctionProtoType>())
6545 Results.push_back(ResultCandidate(FD));
6546 else
6547 SemaRef.AddOverloadCandidate(FD,
6549 ArgsWithoutDependentTypes, CandidateSet,
6550 /*SuppressUserConversions=*/false,
6551 /*PartialOverloading=*/true);
6552
6553 } else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) {
6554 // If expression's type is CXXRecordDecl, it may overload the function
6555 // call operator, so we check if it does and add them as candidates.
6556 // A complete type is needed to lookup for member function call operators.
6557 if (SemaRef.isCompleteType(Loc, NakedFn->getType())) {
6558 DeclarationName OpName =
6559 getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
6561 SemaRef.LookupQualifiedName(R, DC);
6562 R.suppressDiagnostics();
6563 SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
6564 ArgExprs.append(ArgsWithoutDependentTypes.begin(),
6565 ArgsWithoutDependentTypes.end());
6566 SemaRef.AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs,
6567 CandidateSet,
6568 /*ExplicitArgs=*/nullptr,
6569 /*SuppressUserConversions=*/false,
6570 /*PartialOverloading=*/true);
6571 }
6572 } else {
6573 // Lastly we check whether expression's type is function pointer or
6574 // function.
6575
6576 FunctionProtoTypeLoc P = Resolver.getFunctionProtoTypeLoc(NakedFn);
6577 QualType T = NakedFn->getType();
6578 if (!T->getPointeeType().isNull())
6579 T = T->getPointeeType();
6580
6581 if (auto FP = T->getAs<FunctionProtoType>()) {
6582 if (!SemaRef.TooManyArguments(FP->getNumParams(),
6583 ArgsWithoutDependentTypes.size(),
6584 /*PartialOverloading=*/true) ||
6585 FP->isVariadic()) {
6586 if (P) {
6587 Results.push_back(ResultCandidate(P));
6588 } else {
6589 Results.push_back(ResultCandidate(FP));
6590 }
6591 }
6592 } else if (auto FT = T->getAs<FunctionType>())
6593 // No prototype and declaration, it may be a K & R style function.
6594 Results.push_back(ResultCandidate(FT));
6595 }
6596 }
6597 mergeCandidatesWithResults(SemaRef, Results, CandidateSet, Loc, Args.size());
6598 QualType ParamType = ProduceSignatureHelp(SemaRef, Results, Args.size(),
6599 OpenParLoc, /*Braced=*/false);
6600 return !CandidateSet.empty() ? ParamType : QualType();
6601}
6602
6603// Determine which param to continue aggregate initialization from after
6604// a designated initializer.
6605//
6606// Given struct S { int a,b,c,d,e; }:
6607// after `S{.b=1,` we want to suggest c to continue
6608// after `S{.b=1, 2,` we continue with d (this is legal C and ext in C++)
6609// after `S{.b=1, .a=2,` we continue with b (this is legal C and ext in C++)
6610//
6611// Possible outcomes:
6612// - we saw a designator for a field, and continue from the returned index.
6613// Only aggregate initialization is allowed.
6614// - we saw a designator, but it was complex or we couldn't find the field.
6615// Only aggregate initialization is possible, but we can't assist with it.
6616// Returns an out-of-range index.
6617// - we saw no designators, just positional arguments.
6618// Returns std::nullopt.
6619static std::optional<unsigned>
6621 ArrayRef<Expr *> Args) {
6622 static constexpr unsigned Invalid = std::numeric_limits<unsigned>::max();
6623 assert(Aggregate.getKind() == ResultCandidate::CK_Aggregate);
6624
6625 // Look for designated initializers.
6626 // They're in their syntactic form, not yet resolved to fields.
6627 const IdentifierInfo *DesignatedFieldName = nullptr;
6628 unsigned ArgsAfterDesignator = 0;
6629 for (const Expr *Arg : Args) {
6630 if (const auto *DIE = dyn_cast<DesignatedInitExpr>(Arg)) {
6631 if (DIE->size() == 1 && DIE->getDesignator(0)->isFieldDesignator()) {
6632 DesignatedFieldName = DIE->getDesignator(0)->getFieldName();
6633 ArgsAfterDesignator = 0;
6634 } else {
6635 return Invalid; // Complicated designator.
6636 }
6637 } else if (isa<DesignatedInitUpdateExpr>(Arg)) {
6638 return Invalid; // Unsupported.
6639 } else {
6640 ++ArgsAfterDesignator;
6641 }
6642 }
6643 if (!DesignatedFieldName)
6644 return std::nullopt;
6645
6646 // Find the index within the class's fields.
6647 // (Probing getParamDecl() directly would be quadratic in number of fields).
6648 unsigned DesignatedIndex = 0;
6649 const FieldDecl *DesignatedField = nullptr;
6650 for (const auto *Field : Aggregate.getAggregate()->fields()) {
6651 if (Field->getIdentifier() == DesignatedFieldName) {
6652 DesignatedField = Field;
6653 break;
6654 }
6655 ++DesignatedIndex;
6656 }
6657 if (!DesignatedField)
6658 return Invalid; // Designator referred to a missing field, give up.
6659
6660 // Find the index within the aggregate (which may have leading bases).
6661 unsigned AggregateSize = Aggregate.getNumParams();
6662 while (DesignatedIndex < AggregateSize &&
6663 Aggregate.getParamDecl(DesignatedIndex) != DesignatedField)
6664 ++DesignatedIndex;
6665
6666 // Continue from the index after the last named field.
6667 return DesignatedIndex + ArgsAfterDesignator + 1;
6668}
6669
6672 SourceLocation OpenParLoc, bool Braced) {
6673 if (!CodeCompleter)
6674 return QualType();
6676
6677 // A complete type is needed to lookup for constructors.
6678 RecordDecl *RD =
6679 SemaRef.isCompleteType(Loc, Type) ? Type->getAsRecordDecl() : nullptr;
6680 if (!RD)
6681 return Type;
6682 CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD);
6683
6684 // Consider aggregate initialization.
6685 // We don't check that types so far are correct.
6686 // We also don't handle C99/C++17 brace-elision, we assume init-list elements
6687 // are 1:1 with fields.
6688 // FIXME: it would be nice to support "unwrapping" aggregates that contain
6689 // a single subaggregate, like std::array<T, N> -> T __elements[N].
6690 if (Braced && !RD->isUnion() &&
6691 (!getLangOpts().CPlusPlus || (CRD && CRD->isAggregate()))) {
6692 ResultCandidate AggregateSig(RD);
6693 unsigned AggregateSize = AggregateSig.getNumParams();
6694
6695 if (auto NextIndex =
6696 getNextAggregateIndexAfterDesignatedInit(AggregateSig, Args)) {
6697 // A designator was used, only aggregate init is possible.
6698 if (*NextIndex >= AggregateSize)
6699 return Type;
6700 Results.push_back(AggregateSig);
6701 return ProduceSignatureHelp(SemaRef, Results, *NextIndex, OpenParLoc,
6702 Braced);
6703 }
6704
6705 // Describe aggregate initialization, but also constructors below.
6706 if (Args.size() < AggregateSize)
6707 Results.push_back(AggregateSig);
6708 }
6709
6710 // FIXME: Provide support for member initializers.
6711 // FIXME: Provide support for variadic template constructors.
6712
6713 if (CRD) {
6714 OverloadCandidateSet CandidateSet(Loc,
6716 for (NamedDecl *C : SemaRef.LookupConstructors(CRD)) {
6717 if (auto *FD = dyn_cast<FunctionDecl>(C)) {
6718 // FIXME: we can't yet provide correct signature help for initializer
6719 // list constructors, so skip them entirely.
6720 if (Braced && getLangOpts().CPlusPlus &&
6721 SemaRef.isInitListConstructor(FD))
6722 continue;
6723 SemaRef.AddOverloadCandidate(
6724 FD, DeclAccessPair::make(FD, C->getAccess()), Args, CandidateSet,
6725 /*SuppressUserConversions=*/false,
6726 /*PartialOverloading=*/true,
6727 /*AllowExplicit*/ true);
6728 } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) {
6729 if (Braced && getLangOpts().CPlusPlus &&
6730 SemaRef.isInitListConstructor(FTD->getTemplatedDecl()))
6731 continue;
6732
6733 SemaRef.AddTemplateOverloadCandidate(
6734 FTD, DeclAccessPair::make(FTD, C->getAccess()),
6735 /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet,
6736 /*SuppressUserConversions=*/false,
6737 /*PartialOverloading=*/true);
6738 }
6739 }
6740 mergeCandidatesWithResults(SemaRef, Results, CandidateSet, Loc,
6741 Args.size());
6742 }
6743
6744 return ProduceSignatureHelp(SemaRef, Results, Args.size(), OpenParLoc,
6745 Braced);
6746}
6747
6749 Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy,
6750 ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc,
6751 bool Braced) {
6752 if (!CodeCompleter)
6753 return QualType();
6754
6756 dyn_cast<CXXConstructorDecl>(ConstructorDecl);
6757 if (!Constructor)
6758 return QualType();
6759 // FIXME: Add support for Base class constructors as well.
6760 if (ValueDecl *MemberDecl = SemaRef.tryLookupCtorInitMemberDecl(
6761 Constructor->getParent(), SS, TemplateTypeTy, II))
6762 return ProduceConstructorSignatureHelp(MemberDecl->getType(),
6763 MemberDecl->getLocation(), ArgExprs,
6764 OpenParLoc, Braced);
6765 return QualType();
6766}
6767
6769 unsigned Index,
6770 const TemplateParameterList &Params) {
6771 const NamedDecl *Param;
6772 if (Index < Params.size())
6773 Param = Params.getParam(Index);
6774 else if (Params.hasParameterPack())
6775 Param = Params.asArray().back();
6776 else
6777 return false; // too many args
6778
6779 switch (Arg.getKind()) {
6781 return llvm::isa<TemplateTypeParmDecl>(Param); // constraints not checked
6783 return llvm::isa<NonTypeTemplateParmDecl>(Param); // type not checked
6785 return llvm::isa<TemplateTemplateParmDecl>(Param); // signature not checked
6786 }
6787 llvm_unreachable("Unhandled switch case");
6788}
6789
6791 TemplateTy ParsedTemplate, ArrayRef<ParsedTemplateArgument> Args,
6792 SourceLocation LAngleLoc) {
6793 if (!CodeCompleter || !ParsedTemplate)
6794 return QualType();
6795
6797 auto Consider = [&](const TemplateDecl *TD) {
6798 // Only add if the existing args are compatible with the template.
6799 bool Matches = true;
6800 for (unsigned I = 0; I < Args.size(); ++I) {
6801 if (!argMatchesTemplateParams(Args[I], I, *TD->getTemplateParameters())) {
6802 Matches = false;
6803 break;
6804 }
6805 }
6806 if (Matches)
6807 Results.emplace_back(TD);
6808 };
6809
6810 TemplateName Template = ParsedTemplate.get();
6811 if (const auto *TD = Template.getAsTemplateDecl()) {
6812 Consider(TD);
6813 } else if (const auto *OTS = Template.getAsOverloadedTemplate()) {
6814 for (const NamedDecl *ND : *OTS)
6815 if (const auto *TD = llvm::dyn_cast<TemplateDecl>(ND))
6816 Consider(TD);
6817 }
6818 return ProduceSignatureHelp(SemaRef, Results, Args.size(), LAngleLoc,
6819 /*Braced=*/false);
6820}
6821
6822// Direct member lookup, used by designated initializers: only fields declared
6823// in `RD` itself (including indirect fields from anonymous members) are valid.
6824static const FieldDecl *lookupDirectField(RecordDecl *RD, const Designator &D) {
6825 for (const auto *Member : RD->lookup(D.getFieldDecl())) {
6826 if (const auto *FD = llvm::dyn_cast<FieldDecl>(Member))
6827 return FD;
6828 if (const auto *IFD = llvm::dyn_cast<IndirectFieldDecl>(Member))
6829 return IFD->getAnonField();
6830 }
6831 return nullptr;
6832}
6833
6835 ASTContext &Context, QualType BaseType, const Designation &Desig,
6836 HeuristicResolver &Resolver,
6837 llvm::function_ref<const FieldDecl *(RecordDecl *, const Designator &)>
6838 LookupField) {
6839 for (unsigned I = 0; I < Desig.getNumDesignators(); ++I) {
6840 if (BaseType.isNull())
6841 break;
6842
6843 const auto &D = Desig.getDesignator(I);
6844 if (D.isArrayDesignator() || D.isArrayRangeDesignator()) {
6845 if (BaseType->isDependentType()) {
6846 BaseType = Context.DependentTy;
6847 continue;
6848 }
6849 const ArrayType *AT = Context.getAsArrayType(BaseType);
6850 if (!AT)
6851 return QualType();
6852 BaseType = AT->getElementType();
6853 continue;
6854 }
6855
6856 assert(D.isFieldDesignator());
6857 if (BaseType->isDependentType()) {
6858 BaseType = Context.DependentTy;
6859 continue;
6860 }
6861
6862 RecordDecl *RD = getAsRecordDecl(BaseType, Resolver);
6863 if (!RD || !RD->isCompleteDefinition())
6864 return QualType();
6865
6866 const FieldDecl *MemberDecl = LookupField(RD, D);
6867 if (!MemberDecl)
6868 return QualType();
6869
6870 BaseType = MemberDecl->getType().getNonReferenceType();
6871 }
6872 return BaseType;
6873}
6874
6876 QualType BaseType, llvm::ArrayRef<Expr *> InitExprs, const Designation &D) {
6877 BaseType = getDesignatedType(SemaRef.Context, BaseType, D, Resolver,
6879 if (BaseType.isNull())
6880 return;
6881 const auto *RD = getAsRecordDecl(BaseType, Resolver);
6882 if (!RD || RD->fields().empty())
6883 return;
6884
6886 BaseType);
6887 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6888 CodeCompleter->getCodeCompletionTUInfo(), CCC);
6889
6890 Results.EnterNewScope();
6891 for (const Decl *D : RD->decls()) {
6892 const FieldDecl *FD;
6893 if (auto *IFD = dyn_cast<IndirectFieldDecl>(D))
6894 FD = IFD->getAnonField();
6895 else if (auto *DFD = dyn_cast<FieldDecl>(D))
6896 FD = DFD;
6897 else
6898 continue;
6899
6900 // FIXME: Make use of previous designators to mark any fields before those
6901 // inaccessible, and also compute the next initializer priority.
6902 ResultBuilder::Result Result(FD, Results.getBasePriority(FD));
6903 Results.AddResult(Result, SemaRef.CurContext, /*Hiding=*/nullptr);
6904 }
6905 Results.ExitScope();
6907 Results.getCompletionContext(), Results.data(),
6908 Results.size());
6909}
6910
6912 const Designation &D) {
6913 // offsetof allows inherited fields and follows normal qualified name lookup,
6914 // not the direct-member iteration used by designated initializers.
6915 auto LookupQualified = [&](RecordDecl *RD,
6916 const Designator &Des) -> const FieldDecl * {
6917 LookupResult R(SemaRef, Des.getFieldDecl(), Des.getFieldLoc(),
6919 SemaRef.LookupQualifiedName(R, RD);
6920 // Peel via getUnderlyingDecl so a field exposed by `using Base::f;`
6921 // resolves through its UsingShadowDecl.
6922 for (NamedDecl *ND : R) {
6923 ND = ND->getUnderlyingDecl();
6924 if (auto *FD = dyn_cast<FieldDecl>(ND))
6925 return FD;
6926 if (auto *IFD = dyn_cast<IndirectFieldDecl>(ND))
6927 return IFD->getAnonField();
6928 }
6929 return nullptr;
6930 };
6931 BaseType = getDesignatedType(SemaRef.Context, BaseType, D, Resolver,
6932 LookupQualified);
6933 if (BaseType.isNull())
6934 return;
6935
6936 RecordDecl *RD = getAsRecordDecl(BaseType, Resolver);
6937 if (!RD)
6938 return;
6939
6941 BaseType);
6942 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6943 CodeCompleter->getCodeCompletionTUInfo(), CCC,
6944 &ResultBuilder::IsOffsetofField);
6945
6946 Results.EnterNewScope();
6947 CodeCompletionDeclConsumer Consumer(Results, RD, BaseType);
6948 // LookupVisibleDecls traverses base classes (required for inherited fields)
6949 // and dependent bases (best-effort for templates). Globals are skipped:
6950 // offsetof designators name only members of the surrounding type.
6951 SemaRef.LookupVisibleDecls(RD, Sema::LookupMemberName, Consumer,
6952 /*IncludeGlobalScope=*/false,
6953 /*IncludeDependentBases=*/true,
6954 CodeCompleter->loadExternal());
6955 Results.ExitScope();
6956
6958 Results.getCompletionContext(), Results.data(),
6959 Results.size());
6960}
6961
6963 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
6964 if (!VD) {
6966 return;
6967 }
6968
6970 Data.PreferredType = VD->getType();
6971 // Ignore VD to avoid completing the variable itself, e.g. in 'int foo = ^'.
6972 Data.IgnoreDecls.push_back(VD);
6973
6975}
6976
6978 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6979 CodeCompleter->getCodeCompletionTUInfo(),
6981 CodeCompletionBuilder Builder(Results.getAllocator(),
6982 Results.getCodeCompletionTUInfo());
6983 if (getLangOpts().CPlusPlus17) {
6984 if (!AfterExclaim) {
6985 if (Results.includeCodePatterns()) {
6986 Builder.AddTypedTextChunk("constexpr");
6988 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6989 Builder.AddPlaceholderChunk("condition");
6990 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6992 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
6994 Builder.AddPlaceholderChunk("statements");
6996 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
6997 Results.AddResult({Builder.TakeString()});
6998 } else {
6999 Results.AddResult({"constexpr"});
7000 }
7001 }
7002 }
7003 if (getLangOpts().CPlusPlus23) {
7004 if (Results.includeCodePatterns()) {
7005 Builder.AddTypedTextChunk("consteval");
7007 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7009 Builder.AddPlaceholderChunk("statements");
7011 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7012 Results.AddResult({Builder.TakeString()});
7013 } else {
7014 Results.AddResult({"consteval"});
7015 }
7016 }
7017
7019 Results.getCompletionContext(), Results.data(),
7020 Results.size());
7021}
7022
7024 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7025 CodeCompleter->getCodeCompletionTUInfo(),
7027 Results.setFilter(&ResultBuilder::IsOrdinaryName);
7028 Results.EnterNewScope();
7029
7030 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
7031 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
7032 CodeCompleter->includeGlobals(),
7033 CodeCompleter->loadExternal());
7034
7036
7037 // "else" block
7038 CodeCompletionBuilder Builder(Results.getAllocator(),
7039 Results.getCodeCompletionTUInfo());
7040
7041 auto AddElseBodyPattern = [&] {
7042 if (IsBracedThen) {
7044 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7046 Builder.AddPlaceholderChunk("statements");
7048 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7049 } else {
7052 Builder.AddPlaceholderChunk("statement");
7053 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
7054 }
7055 };
7056 Builder.AddTypedTextChunk("else");
7057 if (Results.includeCodePatterns())
7058 AddElseBodyPattern();
7059 Results.AddResult(Builder.TakeString());
7060
7061 // "else if" block
7062 Builder.AddTypedTextChunk("else if");
7064 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7065 if (getLangOpts().CPlusPlus)
7066 Builder.AddPlaceholderChunk("condition");
7067 else
7068 Builder.AddPlaceholderChunk("expression");
7069 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7070 if (Results.includeCodePatterns()) {
7071 AddElseBodyPattern();
7072 }
7073 Results.AddResult(Builder.TakeString());
7074
7075 Results.ExitScope();
7076
7077 if (S->getFnParent())
7079
7080 if (CodeCompleter->includeMacros())
7081 AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
7082
7084 Results.getCompletionContext(), Results.data(),
7085 Results.size());
7086}
7087
7089 Scope *S, CXXScopeSpec &SS, bool EnteringContext, bool IsUsingDeclaration,
7090 bool IsAddressOfOperand, bool IsInDeclarationContext, QualType BaseType,
7091 QualType PreferredType) {
7092 if (SS.isEmpty() || !CodeCompleter)
7093 return;
7094
7096 CC.setIsUsingDeclaration(IsUsingDeclaration);
7097 CC.setCXXScopeSpecifier(SS);
7098
7099 // We want to keep the scope specifier even if it's invalid (e.g. the scope
7100 // "a::b::" is not corresponding to any context/namespace in the AST), since
7101 // it can be useful for global code completion which have information about
7102 // contexts/symbols that are not in the AST.
7103 if (SS.isInvalid()) {
7104 // As SS is invalid, we try to collect accessible contexts from the current
7105 // scope with a dummy lookup so that the completion consumer can try to
7106 // guess what the specified scope is.
7107 ResultBuilder DummyResults(SemaRef, CodeCompleter->getAllocator(),
7108 CodeCompleter->getCodeCompletionTUInfo(), CC);
7109 if (!PreferredType.isNull())
7110 DummyResults.setPreferredType(PreferredType);
7111 if (S->getEntity()) {
7112 CodeCompletionDeclConsumer Consumer(DummyResults, S->getEntity(),
7113 BaseType);
7114 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
7115 /*IncludeGlobalScope=*/false,
7116 /*LoadExternal=*/false);
7117 }
7119 DummyResults.getCompletionContext(), nullptr, 0);
7120 return;
7121 }
7122 // Always pretend to enter a context to ensure that a dependent type
7123 // resolves to a dependent record.
7124 DeclContext *Ctx = SemaRef.computeDeclContext(SS, /*EnteringContext=*/true);
7125
7126 std::optional<Sema::ContextRAII> SimulateContext;
7127 // When completing a definition, simulate that we are in class scope to access
7128 // private methods.
7129 if (IsInDeclarationContext && Ctx != nullptr)
7130 SimulateContext.emplace(SemaRef, Ctx);
7131
7132 // Try to instantiate any non-dependent declaration contexts before
7133 // we look in them. Bail out if we fail.
7135 if (NNS && !NNS.isDependent()) {
7136 if (Ctx == nullptr || SemaRef.RequireCompleteDeclContext(SS, Ctx))
7137 return;
7138 }
7139
7140 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7141 CodeCompleter->getCodeCompletionTUInfo(), CC);
7142 if (!PreferredType.isNull())
7143 Results.setPreferredType(PreferredType);
7144 Results.EnterNewScope();
7145
7146 // The "template" keyword can follow "::" in the grammar, but only
7147 // put it into the grammar if the nested-name-specifier is dependent.
7148 // FIXME: results is always empty, this appears to be dead.
7149 if (!Results.empty() && NNS.isDependent())
7150 Results.AddResult("template");
7151
7152 // If the scope is a concept-constrained type parameter, infer nested
7153 // members based on the constraints.
7155 if (const auto *TTPT = dyn_cast<TemplateTypeParmType>(NNS.getAsType())) {
7156 for (const auto &R : ConceptInfo(*TTPT, S).members()) {
7157 if (R.Operator != ConceptInfo::Member::Colons)
7158 continue;
7159 Results.AddResult(CodeCompletionResult(
7160 R.render(SemaRef, CodeCompleter->getAllocator(),
7161 CodeCompleter->getCodeCompletionTUInfo())));
7162 }
7163 }
7164 }
7165
7166 // Add calls to overridden virtual functions, if there are any.
7167 //
7168 // FIXME: This isn't wonderful, because we don't know whether we're actually
7169 // in a context that permits expressions. This is a general issue with
7170 // qualified-id completions.
7171 if (Ctx && !EnteringContext)
7172 MaybeAddOverrideCalls(SemaRef, Ctx, Results);
7173 Results.ExitScope();
7174
7175 if (Ctx &&
7176 (CodeCompleter->includeNamespaceLevelDecls() || !Ctx->isFileContext())) {
7177 CodeCompletionDeclConsumer Consumer(Results, Ctx, BaseType);
7178 Consumer.setIsInDeclarationContext(IsInDeclarationContext);
7179 Consumer.setIsAddressOfOperand(IsAddressOfOperand);
7180 SemaRef.LookupVisibleDecls(Ctx, Sema::LookupOrdinaryName, Consumer,
7181 /*IncludeGlobalScope=*/true,
7182 /*IncludeDependentBases=*/true,
7183 CodeCompleter->loadExternal());
7184 }
7185 SimulateContext.reset();
7187 Results.getCompletionContext(), Results.data(),
7188 Results.size());
7189}
7190
7192 if (!CodeCompleter)
7193 return;
7194
7195 // This can be both a using alias or using declaration, in the former we
7196 // expect a new name and a symbol in the latter case.
7198 Context.setIsUsingDeclaration(true);
7199
7200 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7201 CodeCompleter->getCodeCompletionTUInfo(), Context,
7202 &ResultBuilder::IsNestedNameSpecifier);
7203 Results.EnterNewScope();
7204
7205 // If we aren't in class scope, we could see the "namespace" keyword.
7206 if (!S->isClassScope())
7207 Results.AddResult(CodeCompletionResult("namespace"));
7208
7209 // After "using", we can see anything that would start a
7210 // nested-name-specifier.
7211 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
7212 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
7213 CodeCompleter->includeGlobals(),
7214 CodeCompleter->loadExternal());
7215 Results.ExitScope();
7216
7218 Results.getCompletionContext(), Results.data(),
7219 Results.size());
7220}
7221
7223 if (!CodeCompleter)
7224 return;
7225
7226 // After "using namespace", we expect to see a namespace name or namespace
7227 // alias.
7228 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7229 CodeCompleter->getCodeCompletionTUInfo(),
7231 &ResultBuilder::IsNamespaceOrAlias);
7232 Results.EnterNewScope();
7233 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
7234 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
7235 CodeCompleter->includeGlobals(),
7236 CodeCompleter->loadExternal());
7237 Results.ExitScope();
7239 Results.getCompletionContext(), Results.data(),
7240 Results.size());
7241}
7242
7244 if (!CodeCompleter)
7245 return;
7246
7247 DeclContext *Ctx = S->getEntity();
7248 if (!S->getParent())
7249 Ctx = getASTContext().getTranslationUnitDecl();
7250
7251 bool SuppressedGlobalResults =
7252 Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
7253
7254 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7255 CodeCompleter->getCodeCompletionTUInfo(),
7256 SuppressedGlobalResults
7259 &ResultBuilder::IsNamespace);
7260
7261 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
7262 // We only want to see those namespaces that have already been defined
7263 // within this scope, because its likely that the user is creating an
7264 // extended namespace declaration. Keep track of the most recent
7265 // definition of each namespace.
7266 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
7268 NS(Ctx->decls_begin()),
7269 NSEnd(Ctx->decls_end());
7270 NS != NSEnd; ++NS)
7271 OrigToLatest[NS->getFirstDecl()] = *NS;
7272
7273 // Add the most recent definition (or extended definition) of each
7274 // namespace to the list of results.
7275 Results.EnterNewScope();
7276 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
7277 NS = OrigToLatest.begin(),
7278 NSEnd = OrigToLatest.end();
7279 NS != NSEnd; ++NS)
7280 Results.AddResult(
7281 CodeCompletionResult(NS->second, Results.getBasePriority(NS->second),
7282 /*Qualifier=*/std::nullopt),
7283 SemaRef.CurContext, nullptr, false);
7284 Results.ExitScope();
7285 }
7286
7288 Results.getCompletionContext(), Results.data(),
7289 Results.size());
7290}
7291
7293 if (!CodeCompleter)
7294 return;
7295
7296 // After "namespace", we expect to see a namespace or alias.
7297 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7298 CodeCompleter->getCodeCompletionTUInfo(),
7300 &ResultBuilder::IsNamespaceOrAlias);
7301 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
7302 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
7303 CodeCompleter->includeGlobals(),
7304 CodeCompleter->loadExternal());
7306 Results.getCompletionContext(), Results.data(),
7307 Results.size());
7308}
7309
7311 if (!CodeCompleter)
7312 return;
7313
7315 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7316 CodeCompleter->getCodeCompletionTUInfo(),
7318 &ResultBuilder::IsType);
7319 Results.EnterNewScope();
7320
7321 // Add the names of overloadable operators. Note that OO_Conditional is not
7322 // actually overloadable.
7323#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
7324 if (OO_##Name != OO_Conditional) \
7325 Results.AddResult(Result(Spelling));
7326#include "clang/Basic/OperatorKinds.def"
7327
7328 // Add any type names visible from the current scope
7329 Results.allowNestedNameSpecifiers();
7330 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
7331 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
7332 CodeCompleter->includeGlobals(),
7333 CodeCompleter->loadExternal());
7334
7335 // Add any type specifiers
7337 Results.ExitScope();
7338
7340 Results.getCompletionContext(), Results.data(),
7341 Results.size());
7342}
7343
7345 Decl *ConstructorD, ArrayRef<CXXCtorInitializer *> Initializers) {
7346 if (!ConstructorD)
7347 return;
7348
7349 SemaRef.AdjustDeclIfTemplate(ConstructorD);
7350
7351 auto *Constructor = dyn_cast<CXXConstructorDecl>(ConstructorD);
7352 if (!Constructor)
7353 return;
7354
7355 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7356 CodeCompleter->getCodeCompletionTUInfo(),
7358 Results.EnterNewScope();
7359
7360 // Fill in any already-initialized fields or base classes.
7361 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
7362 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
7363 for (unsigned I = 0, E = Initializers.size(); I != E; ++I) {
7364 if (Initializers[I]->isBaseInitializer())
7365 InitializedBases.insert(getASTContext().getCanonicalType(
7366 QualType(Initializers[I]->getBaseClass(), 0)));
7367 else
7368 InitializedFields.insert(
7369 cast<FieldDecl>(Initializers[I]->getAnyMember()));
7370 }
7371
7372 // Add completions for base classes.
7374 bool SawLastInitializer = Initializers.empty();
7375 CXXRecordDecl *ClassDecl = Constructor->getParent();
7376
7377 auto GenerateCCS = [&](const NamedDecl *ND, const char *Name) {
7378 CodeCompletionBuilder Builder(Results.getAllocator(),
7379 Results.getCodeCompletionTUInfo());
7380 Builder.AddTypedTextChunk(Name);
7381 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7382 if (const auto *Function = dyn_cast<FunctionDecl>(ND))
7383 AddFunctionParameterChunks(SemaRef.PP, Policy, Function, Builder);
7384 else if (const auto *FunTemplDecl = dyn_cast<FunctionTemplateDecl>(ND))
7386 FunTemplDecl->getTemplatedDecl(), Builder);
7387 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7388 return Builder.TakeString();
7389 };
7390 auto AddDefaultCtorInit = [&](const char *Name, const char *Type,
7391 const NamedDecl *ND) {
7392 CodeCompletionBuilder Builder(Results.getAllocator(),
7393 Results.getCodeCompletionTUInfo());
7394 Builder.AddTypedTextChunk(Name);
7395 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7396 Builder.AddPlaceholderChunk(Type);
7397 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7398 if (ND) {
7399 auto CCR = CodeCompletionResult(
7400 Builder.TakeString(), ND,
7401 SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration);
7402 if (isa<FieldDecl>(ND))
7403 CCR.CursorKind = CXCursor_MemberRef;
7404 return Results.AddResult(CCR);
7405 }
7406 return Results.AddResult(CodeCompletionResult(
7407 Builder.TakeString(),
7408 SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration));
7409 };
7410 auto AddCtorsWithName = [&](const CXXRecordDecl *RD, unsigned int Priority,
7411 const char *Name, const FieldDecl *FD) {
7412 if (!RD)
7413 return AddDefaultCtorInit(Name,
7414 FD ? Results.getAllocator().CopyString(
7415 FD->getType().getAsString(Policy))
7416 : Name,
7417 FD);
7418 auto Ctors = getConstructors(getASTContext(), RD);
7419 if (Ctors.begin() == Ctors.end())
7420 return AddDefaultCtorInit(Name, Name, RD);
7421 for (const NamedDecl *Ctor : Ctors) {
7422 auto CCR = CodeCompletionResult(GenerateCCS(Ctor, Name), RD, Priority);
7423 CCR.CursorKind = getCursorKindForDecl(Ctor);
7424 Results.AddResult(CCR);
7425 }
7426 };
7427 auto AddBase = [&](const CXXBaseSpecifier &Base) {
7428 const char *BaseName =
7429 Results.getAllocator().CopyString(Base.getType().getAsString(Policy));
7430 const auto *RD = Base.getType()->getAsCXXRecordDecl();
7431 AddCtorsWithName(
7432 RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration,
7433 BaseName, nullptr);
7434 };
7435 auto AddField = [&](const FieldDecl *FD) {
7436 const char *FieldName =
7437 Results.getAllocator().CopyString(FD->getIdentifier()->getName());
7438 const CXXRecordDecl *RD = FD->getType()->getAsCXXRecordDecl();
7439 AddCtorsWithName(
7440 RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration,
7441 FieldName, FD);
7442 };
7443
7444 for (const auto &Base : ClassDecl->bases()) {
7445 if (!InitializedBases
7446 .insert(getASTContext().getCanonicalType(Base.getType()))
7447 .second) {
7448 SawLastInitializer =
7449 !Initializers.empty() && Initializers.back()->isBaseInitializer() &&
7450 getASTContext().hasSameUnqualifiedType(
7451 Base.getType(), QualType(Initializers.back()->getBaseClass(), 0));
7452 continue;
7453 }
7454
7455 AddBase(Base);
7456 SawLastInitializer = false;
7457 }
7458
7459 // Add completions for virtual base classes.
7460 for (const auto &Base : ClassDecl->vbases()) {
7461 if (!InitializedBases
7462 .insert(getASTContext().getCanonicalType(Base.getType()))
7463 .second) {
7464 SawLastInitializer =
7465 !Initializers.empty() && Initializers.back()->isBaseInitializer() &&
7466 getASTContext().hasSameUnqualifiedType(
7467 Base.getType(), QualType(Initializers.back()->getBaseClass(), 0));
7468 continue;
7469 }
7470
7471 AddBase(Base);
7472 SawLastInitializer = false;
7473 }
7474
7475 // Add completions for members.
7476 for (auto *Field : ClassDecl->fields()) {
7477 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))
7478 .second) {
7479 SawLastInitializer = !Initializers.empty() &&
7480 Initializers.back()->isAnyMemberInitializer() &&
7481 Initializers.back()->getAnyMember() == Field;
7482 continue;
7483 }
7484
7485 if (!Field->getDeclName())
7486 continue;
7487
7488 AddField(Field);
7489 SawLastInitializer = false;
7490 }
7491 Results.ExitScope();
7492
7494 Results.getCompletionContext(), Results.data(),
7495 Results.size());
7496}
7497
7498/// Determine whether this scope denotes a namespace.
7499static bool isNamespaceScope(Scope *S) {
7500 DeclContext *DC = S->getEntity();
7501 if (!DC)
7502 return false;
7503
7504 return DC->isFileContext();
7505}
7506
7508 LambdaIntroducer &Intro,
7509 bool AfterAmpersand) {
7510 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7511 CodeCompleter->getCodeCompletionTUInfo(),
7513 Results.EnterNewScope();
7514
7515 // Note what has already been captured.
7517 bool IncludedThis = false;
7518 for (const auto &C : Intro.Captures) {
7519 if (C.Kind == LCK_This) {
7520 IncludedThis = true;
7521 continue;
7522 }
7523
7524 Known.insert(C.Id);
7525 }
7526
7527 // Look for other capturable variables.
7528 for (; S && !isNamespaceScope(S); S = S->getParent()) {
7529 for (const auto *D : S->decls()) {
7530 const auto *Var = dyn_cast<VarDecl>(D);
7531 if (!Var || !Var->hasLocalStorage() || Var->hasAttr<BlocksAttr>())
7532 continue;
7533
7534 if (Known.insert(Var->getIdentifier()).second)
7535 Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),
7536 SemaRef.CurContext, nullptr, false);
7537 }
7538 }
7539
7540 // Add 'this', if it would be valid.
7541 if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
7542 addThisCompletion(SemaRef, Results);
7543
7544 Results.ExitScope();
7545
7547 Results.getCompletionContext(), Results.data(),
7548 Results.size());
7549}
7550
7552 if (!getLangOpts().CPlusPlus11)
7553 return;
7554 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7555 CodeCompleter->getCodeCompletionTUInfo(),
7557 auto ShouldAddDefault = [&D, this]() {
7558 if (!D.isFunctionDeclarator())
7559 return false;
7560 auto &Id = D.getName();
7561 if (Id.getKind() == UnqualifiedIdKind::IK_DestructorName)
7562 return true;
7563 // FIXME(liuhui): Ideally, we should check the constructor parameter list to
7564 // verify that it is the default, copy or move constructor?
7565 if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName &&
7567 return true;
7568 if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId) {
7569 auto Op = Id.OperatorFunctionId.Operator;
7570 // FIXME(liuhui): Ideally, we should check the function parameter list to
7571 // verify that it is the copy or move assignment?
7572 if (Op == OverloadedOperatorKind::OO_Equal)
7573 return true;
7574 if (getLangOpts().CPlusPlus20 &&
7575 (Op == OverloadedOperatorKind::OO_EqualEqual ||
7576 Op == OverloadedOperatorKind::OO_ExclaimEqual ||
7577 Op == OverloadedOperatorKind::OO_Less ||
7578 Op == OverloadedOperatorKind::OO_LessEqual ||
7579 Op == OverloadedOperatorKind::OO_Greater ||
7580 Op == OverloadedOperatorKind::OO_GreaterEqual ||
7581 Op == OverloadedOperatorKind::OO_Spaceship))
7582 return true;
7583 }
7584 return false;
7585 };
7586
7587 Results.EnterNewScope();
7588 if (ShouldAddDefault())
7589 Results.AddResult("default");
7590 // FIXME(liuhui): Ideally, we should only provide `delete` completion for the
7591 // first function declaration.
7592 Results.AddResult("delete");
7593 Results.ExitScope();
7595 Results.getCompletionContext(), Results.data(),
7596 Results.size());
7597}
7598
7599/// Macro that optionally prepends an "@" to the string literal passed in via
7600/// Keyword, depending on whether NeedAt is true or false.
7601#define OBJC_AT_KEYWORD_NAME(NeedAt, Keyword) ((NeedAt) ? "@" Keyword : Keyword)
7602
7603static void AddObjCImplementationResults(const LangOptions &LangOpts,
7604 ResultBuilder &Results, bool NeedAt) {
7606 // Since we have an implementation, we can end it.
7607 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end")));
7608
7609 CodeCompletionBuilder Builder(Results.getAllocator(),
7610 Results.getCodeCompletionTUInfo());
7611 if (LangOpts.ObjC) {
7612 // @dynamic
7613 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "dynamic"));
7615 Builder.AddPlaceholderChunk("property");
7616 Results.AddResult(Result(Builder.TakeString()));
7617
7618 // @synthesize
7619 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synthesize"));
7621 Builder.AddPlaceholderChunk("property");
7622 Results.AddResult(Result(Builder.TakeString()));
7623 }
7624}
7625
7626static void AddObjCInterfaceResults(const LangOptions &LangOpts,
7627 ResultBuilder &Results, bool NeedAt) {
7629
7630 // Since we have an interface or protocol, we can end it.
7631 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end")));
7632
7633 if (LangOpts.ObjC) {
7634 // @property
7635 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "property")));
7636
7637 // @required
7638 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "required")));
7639
7640 // @optional
7641 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "optional")));
7642 }
7643}
7644
7645static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
7647 CodeCompletionBuilder Builder(Results.getAllocator(),
7648 Results.getCodeCompletionTUInfo());
7649
7650 // @class name ;
7651 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "class"));
7653 Builder.AddPlaceholderChunk("name");
7654 Results.AddResult(Result(Builder.TakeString()));
7655
7656 if (Results.includeCodePatterns()) {
7657 // @interface name
7658 // FIXME: Could introduce the whole pattern, including superclasses and
7659 // such.
7660 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "interface"));
7662 Builder.AddPlaceholderChunk("class");
7663 Results.AddResult(Result(Builder.TakeString()));
7664
7665 // @protocol name
7666 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol"));
7668 Builder.AddPlaceholderChunk("protocol");
7669 Results.AddResult(Result(Builder.TakeString()));
7670
7671 // @implementation name
7672 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "implementation"));
7674 Builder.AddPlaceholderChunk("class");
7675 Results.AddResult(Result(Builder.TakeString()));
7676 }
7677
7678 // @compatibility_alias name
7679 Builder.AddTypedTextChunk(
7680 OBJC_AT_KEYWORD_NAME(NeedAt, "compatibility_alias"));
7682 Builder.AddPlaceholderChunk("alias");
7684 Builder.AddPlaceholderChunk("class");
7685 Results.AddResult(Result(Builder.TakeString()));
7686
7687 if (Results.getSema().getLangOpts().Modules) {
7688 // @import name
7689 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "import"));
7691 Builder.AddPlaceholderChunk("module");
7692 Results.AddResult(Result(Builder.TakeString()));
7693 }
7694}
7695
7697 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7698 CodeCompleter->getCodeCompletionTUInfo(),
7700 Results.EnterNewScope();
7701 if (isa<ObjCImplDecl>(SemaRef.CurContext))
7702 AddObjCImplementationResults(getLangOpts(), Results, false);
7703 else if (SemaRef.CurContext->isObjCContainer())
7704 AddObjCInterfaceResults(getLangOpts(), Results, false);
7705 else
7706 AddObjCTopLevelResults(Results, false);
7707 Results.ExitScope();
7709 Results.getCompletionContext(), Results.data(),
7710 Results.size());
7711}
7712
7713static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
7715 CodeCompletionBuilder Builder(Results.getAllocator(),
7716 Results.getCodeCompletionTUInfo());
7717
7718 // @encode ( type-name )
7719 const char *EncodeType = "char[]";
7720 if (Results.getSema().getLangOpts().CPlusPlus ||
7721 Results.getSema().getLangOpts().ConstStrings)
7722 EncodeType = "const char[]";
7723 Builder.AddResultTypeChunk(EncodeType);
7724 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "encode"));
7725 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7726 Builder.AddPlaceholderChunk("type-name");
7727 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7728 Results.AddResult(Result(Builder.TakeString()));
7729
7730 // @protocol ( protocol-name )
7731 Builder.AddResultTypeChunk("Protocol *");
7732 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol"));
7733 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7734 Builder.AddPlaceholderChunk("protocol-name");
7735 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7736 Results.AddResult(Result(Builder.TakeString()));
7737
7738 // @selector ( selector )
7739 Builder.AddResultTypeChunk("SEL");
7740 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "selector"));
7741 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7742 Builder.AddPlaceholderChunk("selector");
7743 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7744 Results.AddResult(Result(Builder.TakeString()));
7745
7746 // @"string"
7747 Builder.AddResultTypeChunk("NSString *");
7748 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "\""));
7749 Builder.AddPlaceholderChunk("string");
7750 Builder.AddTextChunk("\"");
7751 Results.AddResult(Result(Builder.TakeString()));
7752
7753 // @[objects, ...]
7754 Builder.AddResultTypeChunk("NSArray *");
7755 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "["));
7756 Builder.AddPlaceholderChunk("objects, ...");
7757 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
7758 Results.AddResult(Result(Builder.TakeString()));
7759
7760 // @{key : object, ...}
7761 Builder.AddResultTypeChunk("NSDictionary *");
7762 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "{"));
7763 Builder.AddPlaceholderChunk("key");
7764 Builder.AddChunk(CodeCompletionString::CK_Colon);
7766 Builder.AddPlaceholderChunk("object, ...");
7767 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7768 Results.AddResult(Result(Builder.TakeString()));
7769
7770 // @(expression)
7771 Builder.AddResultTypeChunk("id");
7772 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "("));
7773 Builder.AddPlaceholderChunk("expression");
7774 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7775 Results.AddResult(Result(Builder.TakeString()));
7776}
7777
7778static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
7780 CodeCompletionBuilder Builder(Results.getAllocator(),
7781 Results.getCodeCompletionTUInfo());
7782
7783 if (Results.includeCodePatterns()) {
7784 // @try { statements } @catch ( declaration ) { statements } @finally
7785 // { statements }
7786 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "try"));
7787 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7788 Builder.AddPlaceholderChunk("statements");
7789 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7790 Builder.AddTextChunk("@catch");
7791 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7792 Builder.AddPlaceholderChunk("parameter");
7793 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7794 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7795 Builder.AddPlaceholderChunk("statements");
7796 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7797 Builder.AddTextChunk("@finally");
7798 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7799 Builder.AddPlaceholderChunk("statements");
7800 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7801 Results.AddResult(Result(Builder.TakeString()));
7802 }
7803
7804 // @throw
7805 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "throw"));
7807 Builder.AddPlaceholderChunk("expression");
7808 Results.AddResult(Result(Builder.TakeString()));
7809
7810 if (Results.includeCodePatterns()) {
7811 // @synchronized ( expression ) { statements }
7812 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synchronized"));
7814 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7815 Builder.AddPlaceholderChunk("expression");
7816 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7817 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7818 Builder.AddPlaceholderChunk("statements");
7819 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7820 Results.AddResult(Result(Builder.TakeString()));
7821 }
7822}
7823
7824static void AddObjCVisibilityResults(const LangOptions &LangOpts,
7825 ResultBuilder &Results, bool NeedAt) {
7827 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "private")));
7828 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "protected")));
7829 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "public")));
7830 if (LangOpts.ObjC)
7831 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "package")));
7832}
7833
7835 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7836 CodeCompleter->getCodeCompletionTUInfo(),
7838 Results.EnterNewScope();
7839 AddObjCVisibilityResults(getLangOpts(), Results, false);
7840 Results.ExitScope();
7842 Results.getCompletionContext(), Results.data(),
7843 Results.size());
7844}
7845
7847 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7848 CodeCompleter->getCodeCompletionTUInfo(),
7850 Results.EnterNewScope();
7851 AddObjCStatementResults(Results, false);
7852 AddObjCExpressionResults(Results, false);
7853 Results.ExitScope();
7855 Results.getCompletionContext(), Results.data(),
7856 Results.size());
7857}
7858
7860 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7861 CodeCompleter->getCodeCompletionTUInfo(),
7863 Results.EnterNewScope();
7864 AddObjCExpressionResults(Results, false);
7865 Results.ExitScope();
7867 Results.getCompletionContext(), Results.data(),
7868 Results.size());
7869}
7870
7871/// Determine whether the addition of the given flag to an Objective-C
7872/// property's attributes will cause a conflict.
7873static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
7874 // Check if we've already added this flag.
7875 if (Attributes & NewFlag)
7876 return true;
7877
7878 Attributes |= NewFlag;
7879
7880 // Check for collisions with "readonly".
7881 if ((Attributes & ObjCPropertyAttribute::kind_readonly) &&
7883 return true;
7884
7885 // Check for more than one of { assign, copy, retain, strong, weak }.
7886 unsigned AssignCopyRetMask =
7887 Attributes &
7892 if (AssignCopyRetMask &&
7893 AssignCopyRetMask != ObjCPropertyAttribute::kind_assign &&
7894 AssignCopyRetMask != ObjCPropertyAttribute::kind_unsafe_unretained &&
7895 AssignCopyRetMask != ObjCPropertyAttribute::kind_copy &&
7896 AssignCopyRetMask != ObjCPropertyAttribute::kind_retain &&
7897 AssignCopyRetMask != ObjCPropertyAttribute::kind_strong &&
7898 AssignCopyRetMask != ObjCPropertyAttribute::kind_weak)
7899 return true;
7900
7901 return false;
7902}
7903
7905 ObjCDeclSpec &ODS) {
7906 if (!CodeCompleter)
7907 return;
7908
7909 unsigned Attributes = ODS.getPropertyAttributes();
7910
7911 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7912 CodeCompleter->getCodeCompletionTUInfo(),
7914 Results.EnterNewScope();
7915 if (!ObjCPropertyFlagConflicts(Attributes,
7917 Results.AddResult(CodeCompletionResult("readonly"));
7918 if (!ObjCPropertyFlagConflicts(Attributes,
7920 Results.AddResult(CodeCompletionResult("assign"));
7921 if (!ObjCPropertyFlagConflicts(Attributes,
7923 Results.AddResult(CodeCompletionResult("unsafe_unretained"));
7924 if (!ObjCPropertyFlagConflicts(Attributes,
7926 Results.AddResult(CodeCompletionResult("readwrite"));
7927 if (!ObjCPropertyFlagConflicts(Attributes,
7929 Results.AddResult(CodeCompletionResult("retain"));
7930 if (!ObjCPropertyFlagConflicts(Attributes,
7932 Results.AddResult(CodeCompletionResult("strong"));
7934 Results.AddResult(CodeCompletionResult("copy"));
7935 if (!ObjCPropertyFlagConflicts(Attributes,
7937 Results.AddResult(CodeCompletionResult("nonatomic"));
7938 if (!ObjCPropertyFlagConflicts(Attributes,
7940 Results.AddResult(CodeCompletionResult("atomic"));
7941
7942 // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
7943 if (getLangOpts().ObjCWeak || getLangOpts().getGC() != LangOptions::NonGC)
7944 if (!ObjCPropertyFlagConflicts(Attributes,
7946 Results.AddResult(CodeCompletionResult("weak"));
7947
7948 if (!ObjCPropertyFlagConflicts(Attributes,
7950 CodeCompletionBuilder Setter(Results.getAllocator(),
7951 Results.getCodeCompletionTUInfo());
7952 Setter.AddTypedTextChunk("setter");
7953 Setter.AddTextChunk("=");
7954 Setter.AddPlaceholderChunk("method");
7955 Results.AddResult(CodeCompletionResult(Setter.TakeString()));
7956 }
7957 if (!ObjCPropertyFlagConflicts(Attributes,
7959 CodeCompletionBuilder Getter(Results.getAllocator(),
7960 Results.getCodeCompletionTUInfo());
7961 Getter.AddTypedTextChunk("getter");
7962 Getter.AddTextChunk("=");
7963 Getter.AddPlaceholderChunk("method");
7964 Results.AddResult(CodeCompletionResult(Getter.TakeString()));
7965 }
7966 if (!ObjCPropertyFlagConflicts(Attributes,
7968 Results.AddResult(CodeCompletionResult("nonnull"));
7969 Results.AddResult(CodeCompletionResult("nullable"));
7970 Results.AddResult(CodeCompletionResult("null_unspecified"));
7971 Results.AddResult(CodeCompletionResult("null_resettable"));
7972 }
7973 Results.ExitScope();
7975 Results.getCompletionContext(), Results.data(),
7976 Results.size());
7977}
7978
7979/// Describes the kind of Objective-C method that we want to find
7980/// via code completion.
7982 MK_Any, ///< Any kind of method, provided it means other specified criteria.
7983 MK_ZeroArgSelector, ///< Zero-argument (unary) selector.
7984 MK_OneArgSelector ///< One-argument selector.
7985};
7986
7989 bool AllowSameLength = true) {
7990 unsigned NumSelIdents = SelIdents.size();
7991 if (NumSelIdents > Sel.getNumArgs())
7992 return false;
7993
7994 switch (WantKind) {
7995 case MK_Any:
7996 break;
7997 case MK_ZeroArgSelector:
7998 return Sel.isUnarySelector();
7999 case MK_OneArgSelector:
8000 return Sel.getNumArgs() == 1;
8001 }
8002
8003 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
8004 return false;
8005
8006 for (unsigned I = 0; I != NumSelIdents; ++I)
8007 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
8008 return false;
8009
8010 return true;
8011}
8012
8014 ObjCMethodKind WantKind,
8016 bool AllowSameLength = true) {
8017 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
8018 AllowSameLength);
8019}
8020
8021/// A set of selectors, which is used to avoid introducing multiple
8022/// completions with the same selector into the result set.
8024
8025/// Add all of the Objective-C methods in the given Objective-C
8026/// container to the set of results.
8027///
8028/// The container will be a class, protocol, category, or implementation of
8029/// any of the above. This mether will recurse to include methods from
8030/// the superclasses of classes along with their categories, protocols, and
8031/// implementations.
8032///
8033/// \param Container the container in which we'll look to find methods.
8034///
8035/// \param WantInstanceMethods Whether to add instance methods (only); if
8036/// false, this routine will add factory methods (only).
8037///
8038/// \param CurContext the context in which we're performing the lookup that
8039/// finds methods.
8040///
8041/// \param AllowSameLength Whether we allow a method to be added to the list
8042/// when it has the same number of parameters as we have selector identifiers.
8043///
8044/// \param Results the structure into which we'll add results.
8045static void AddObjCMethods(ObjCContainerDecl *Container,
8046 bool WantInstanceMethods, ObjCMethodKind WantKind,
8048 DeclContext *CurContext,
8049 VisitedSelectorSet &Selectors, bool AllowSameLength,
8050 ResultBuilder &Results, bool InOriginalClass = true,
8051 bool IsRootClass = false) {
8053 Container = getContainerDef(Container);
8054 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
8055 IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass());
8056 for (ObjCMethodDecl *M : Container->methods()) {
8057 // The instance methods on the root class can be messaged via the
8058 // metaclass.
8059 if (M->isInstanceMethod() == WantInstanceMethods ||
8060 (IsRootClass && !WantInstanceMethods)) {
8061 // Check whether the selector identifiers we've been given are a
8062 // subset of the identifiers for this particular method.
8063 if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))
8064 continue;
8065
8066 if (!Selectors.insert(M->getSelector()).second)
8067 continue;
8068
8069 Result R =
8070 Result(M, Results.getBasePriority(M), /*Qualifier=*/std::nullopt);
8071 R.StartParameter = SelIdents.size();
8072 R.AllParametersAreInformative = (WantKind != MK_Any);
8073 if (!InOriginalClass)
8074 setInBaseClass(R);
8075 Results.MaybeAddResult(R, CurContext);
8076 }
8077 }
8078
8079 // Visit the protocols of protocols.
8080 if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
8081 if (Protocol->hasDefinition()) {
8082 const ObjCList<ObjCProtocolDecl> &Protocols =
8083 Protocol->getReferencedProtocols();
8084 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
8085 E = Protocols.end();
8086 I != E; ++I)
8087 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
8088 Selectors, AllowSameLength, Results, false, IsRootClass);
8089 }
8090 }
8091
8092 if (!IFace || !IFace->hasDefinition())
8093 return;
8094
8095 // Add methods in protocols.
8096 for (ObjCProtocolDecl *I : IFace->protocols())
8097 AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, CurContext,
8098 Selectors, AllowSameLength, Results, false, IsRootClass);
8099
8100 // Add methods in categories.
8101 for (ObjCCategoryDecl *CatDecl : IFace->known_categories()) {
8102 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
8103 CurContext, Selectors, AllowSameLength, Results,
8104 InOriginalClass, IsRootClass);
8105
8106 // Add a categories protocol methods.
8107 const ObjCList<ObjCProtocolDecl> &Protocols =
8108 CatDecl->getReferencedProtocols();
8109 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
8110 E = Protocols.end();
8111 I != E; ++I)
8112 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
8113 Selectors, AllowSameLength, Results, false, IsRootClass);
8114
8115 // Add methods in category implementations.
8116 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
8117 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
8118 Selectors, AllowSameLength, Results, InOriginalClass,
8119 IsRootClass);
8120 }
8121
8122 // Add methods in superclass.
8123 // Avoid passing in IsRootClass since root classes won't have super classes.
8124 if (IFace->getSuperClass())
8125 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
8126 SelIdents, CurContext, Selectors, AllowSameLength, Results,
8127 /*IsRootClass=*/false);
8128
8129 // Add methods in our implementation, if any.
8130 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
8131 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
8132 Selectors, AllowSameLength, Results, InOriginalClass,
8133 IsRootClass);
8134}
8135
8137 // Try to find the interface where getters might live.
8139 dyn_cast_or_null<ObjCInterfaceDecl>(SemaRef.CurContext);
8140 if (!Class) {
8141 if (ObjCCategoryDecl *Category =
8142 dyn_cast_or_null<ObjCCategoryDecl>(SemaRef.CurContext))
8143 Class = Category->getClassInterface();
8144
8145 if (!Class)
8146 return;
8147 }
8148
8149 // Find all of the potential getters.
8150 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8151 CodeCompleter->getCodeCompletionTUInfo(),
8153 Results.EnterNewScope();
8154
8155 VisitedSelectorSet Selectors;
8156 AddObjCMethods(Class, true, MK_ZeroArgSelector, {}, SemaRef.CurContext,
8157 Selectors,
8158 /*AllowSameLength=*/true, Results);
8159 Results.ExitScope();
8161 Results.getCompletionContext(), Results.data(),
8162 Results.size());
8163}
8164
8166 // Try to find the interface where setters might live.
8168 dyn_cast_or_null<ObjCInterfaceDecl>(SemaRef.CurContext);
8169 if (!Class) {
8170 if (ObjCCategoryDecl *Category =
8171 dyn_cast_or_null<ObjCCategoryDecl>(SemaRef.CurContext))
8172 Class = Category->getClassInterface();
8173
8174 if (!Class)
8175 return;
8176 }
8177
8178 // Find all of the potential getters.
8179 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8180 CodeCompleter->getCodeCompletionTUInfo(),
8182 Results.EnterNewScope();
8183
8184 VisitedSelectorSet Selectors;
8185 AddObjCMethods(Class, true, MK_OneArgSelector, {}, SemaRef.CurContext,
8186 Selectors,
8187 /*AllowSameLength=*/true, Results);
8188
8189 Results.ExitScope();
8191 Results.getCompletionContext(), Results.data(),
8192 Results.size());
8193}
8194
8196 bool IsParameter) {
8197 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8198 CodeCompleter->getCodeCompletionTUInfo(),
8200 Results.EnterNewScope();
8201
8202 // Add context-sensitive, Objective-C parameter-passing keywords.
8203 bool AddedInOut = false;
8204 if ((DS.getObjCDeclQualifier() &
8206 Results.AddResult("in");
8207 Results.AddResult("inout");
8208 AddedInOut = true;
8209 }
8210 if ((DS.getObjCDeclQualifier() &
8212 Results.AddResult("out");
8213 if (!AddedInOut)
8214 Results.AddResult("inout");
8215 }
8216 if ((DS.getObjCDeclQualifier() &
8218 ObjCDeclSpec::DQ_Oneway)) == 0) {
8219 Results.AddResult("bycopy");
8220 Results.AddResult("byref");
8221 Results.AddResult("oneway");
8222 }
8224 Results.AddResult("nonnull");
8225 Results.AddResult("nullable");
8226 Results.AddResult("null_unspecified");
8227 }
8228
8229 // If we're completing the return type of an Objective-C method and the
8230 // identifier IBAction refers to a macro, provide a completion item for
8231 // an action, e.g.,
8232 // IBAction)<#selector#>:(id)sender
8233 if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
8234 SemaRef.PP.isMacroDefined("IBAction")) {
8235 CodeCompletionBuilder Builder(Results.getAllocator(),
8236 Results.getCodeCompletionTUInfo(),
8238 Builder.AddTypedTextChunk("IBAction");
8239 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8240 Builder.AddPlaceholderChunk("selector");
8241 Builder.AddChunk(CodeCompletionString::CK_Colon);
8242 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
8243 Builder.AddTextChunk("id");
8244 Builder.AddChunk(CodeCompletionString::CK_RightParen);
8245 Builder.AddTextChunk("sender");
8246 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
8247 }
8248
8249 // If we're completing the return type, provide 'instancetype'.
8250 if (!IsParameter) {
8251 Results.AddResult(CodeCompletionResult("instancetype"));
8252 }
8253
8254 // Add various builtin type names and specifiers.
8256 Results.ExitScope();
8257
8258 // Add the various type names
8259 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
8260 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
8261 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
8262 CodeCompleter->includeGlobals(),
8263 CodeCompleter->loadExternal());
8264
8265 if (CodeCompleter->includeMacros())
8266 AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
8267
8269 Results.getCompletionContext(), Results.data(),
8270 Results.size());
8271}
8272
8273/// When we have an expression with type "id", we may assume
8274/// that it has some more-specific class type based on knowledge of
8275/// common uses of Objective-C. This routine returns that class type,
8276/// or NULL if no better result could be determined.
8278 auto *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
8279 if (!Msg)
8280 return nullptr;
8281
8282 Selector Sel = Msg->getSelector();
8283 if (Sel.isNull())
8284 return nullptr;
8285
8286 const IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
8287 if (!Id)
8288 return nullptr;
8289
8290 ObjCMethodDecl *Method = Msg->getMethodDecl();
8291 if (!Method)
8292 return nullptr;
8293
8294 // Determine the class that we're sending the message to.
8295 ObjCInterfaceDecl *IFace = nullptr;
8296 switch (Msg->getReceiverKind()) {
8298 if (const ObjCObjectType *ObjType =
8299 Msg->getClassReceiver()->getAs<ObjCObjectType>())
8300 IFace = ObjType->getInterface();
8301 break;
8302
8304 QualType T = Msg->getInstanceReceiver()->getType();
8305 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
8306 IFace = Ptr->getInterfaceDecl();
8307 break;
8308 }
8309
8312 break;
8313 }
8314
8315 if (!IFace)
8316 return nullptr;
8317
8318 ObjCInterfaceDecl *Super = IFace->getSuperClass();
8319 if (Method->isInstanceMethod())
8320 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
8321 .Case("retain", IFace)
8322 .Case("strong", IFace)
8323 .Case("autorelease", IFace)
8324 .Case("copy", IFace)
8325 .Case("copyWithZone", IFace)
8326 .Case("mutableCopy", IFace)
8327 .Case("mutableCopyWithZone", IFace)
8328 .Case("awakeFromCoder", IFace)
8329 .Case("replacementObjectFromCoder", IFace)
8330 .Case("class", IFace)
8331 .Case("classForCoder", IFace)
8332 .Case("superclass", Super)
8333 .Default(nullptr);
8334
8335 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
8336 .Case("new", IFace)
8337 .Case("alloc", IFace)
8338 .Case("allocWithZone", IFace)
8339 .Case("class", IFace)
8340 .Case("superclass", Super)
8341 .Default(nullptr);
8342}
8343
8344// Add a special completion for a message send to "super", which fills in the
8345// most likely case of forwarding all of our arguments to the superclass
8346// function.
8347///
8348/// \param S The semantic analysis object.
8349///
8350/// \param NeedSuperKeyword Whether we need to prefix this completion with
8351/// the "super" keyword. Otherwise, we just need to provide the arguments.
8352///
8353/// \param SelIdents The identifiers in the selector that have already been
8354/// provided as arguments for a send to "super".
8355///
8356/// \param Results The set of results to augment.
8357///
8358/// \returns the Objective-C method declaration that would be invoked by
8359/// this "super" completion. If NULL, no completion was added.
8360static ObjCMethodDecl *
8361AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
8363 ResultBuilder &Results) {
8364 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
8365 if (!CurMethod)
8366 return nullptr;
8367
8368 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
8369 if (!Class)
8370 return nullptr;
8371
8372 // Try to find a superclass method with the same selector.
8373 ObjCMethodDecl *SuperMethod = nullptr;
8374 while ((Class = Class->getSuperClass()) && !SuperMethod) {
8375 // Check in the class
8376 SuperMethod = Class->getMethod(CurMethod->getSelector(),
8377 CurMethod->isInstanceMethod());
8378
8379 // Check in categories or class extensions.
8380 if (!SuperMethod) {
8381 for (const auto *Cat : Class->known_categories()) {
8382 if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(),
8383 CurMethod->isInstanceMethod())))
8384 break;
8385 }
8386 }
8387 }
8388
8389 if (!SuperMethod)
8390 return nullptr;
8391
8392 // Check whether the superclass method has the same signature.
8393 if (CurMethod->param_size() != SuperMethod->param_size() ||
8394 CurMethod->isVariadic() != SuperMethod->isVariadic())
8395 return nullptr;
8396
8397 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
8398 CurPEnd = CurMethod->param_end(),
8399 SuperP = SuperMethod->param_begin();
8400 CurP != CurPEnd; ++CurP, ++SuperP) {
8401 // Make sure the parameter types are compatible.
8402 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
8403 (*SuperP)->getType()))
8404 return nullptr;
8405
8406 // Make sure we have a parameter name to forward!
8407 if (!(*CurP)->getIdentifier())
8408 return nullptr;
8409 }
8410
8411 // We have a superclass method. Now, form the send-to-super completion.
8412 CodeCompletionBuilder Builder(Results.getAllocator(),
8413 Results.getCodeCompletionTUInfo());
8414
8415 // Give this completion a return type.
8417 Results.getCompletionContext().getBaseType(), Builder);
8418
8419 // If we need the "super" keyword, add it (plus some spacing).
8420 if (NeedSuperKeyword) {
8421 Builder.AddTypedTextChunk("super");
8423 }
8424
8425 Selector Sel = CurMethod->getSelector();
8426 if (Sel.isUnarySelector()) {
8427 if (NeedSuperKeyword)
8428 Builder.AddTextChunk(
8429 Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
8430 else
8431 Builder.AddTypedTextChunk(
8432 Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
8433 } else {
8434 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
8435 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
8436 if (I > SelIdents.size())
8438
8439 if (I < SelIdents.size())
8440 Builder.AddInformativeChunk(
8441 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
8442 else if (NeedSuperKeyword || I > SelIdents.size()) {
8443 Builder.AddTextChunk(
8444 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
8445 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
8446 (*CurP)->getIdentifier()->getName()));
8447 } else {
8448 Builder.AddTypedTextChunk(
8449 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
8450 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
8451 (*CurP)->getIdentifier()->getName()));
8452 }
8453 }
8454 }
8455
8456 Results.AddResult(CodeCompletionResult(Builder.TakeString(), SuperMethod,
8458 return SuperMethod;
8459}
8460
8463 ResultBuilder Results(
8464 SemaRef, CodeCompleter->getAllocator(),
8465 CodeCompleter->getCodeCompletionTUInfo(),
8468 ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
8469 : &ResultBuilder::IsObjCMessageReceiver);
8470
8471 CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
8472 Results.EnterNewScope();
8473 SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
8474 CodeCompleter->includeGlobals(),
8475 CodeCompleter->loadExternal());
8476
8477 // If we are in an Objective-C method inside a class that has a superclass,
8478 // add "super" as an option.
8479 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
8480 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
8481 if (Iface->getSuperClass()) {
8482 Results.AddResult(Result("super"));
8483
8484 AddSuperSendCompletion(SemaRef, /*NeedSuperKeyword=*/true, {}, Results);
8485 }
8486
8488 addThisCompletion(SemaRef, Results);
8489
8490 Results.ExitScope();
8491
8492 if (CodeCompleter->includeMacros())
8493 AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
8495 Results.getCompletionContext(), Results.data(),
8496 Results.size());
8497}
8498
8500 Scope *S, SourceLocation SuperLoc,
8501 ArrayRef<const IdentifierInfo *> SelIdents, bool AtArgumentExpression) {
8502 ObjCInterfaceDecl *CDecl = nullptr;
8503 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl()) {
8504 // Figure out which interface we're in.
8505 CDecl = CurMethod->getClassInterface();
8506 if (!CDecl)
8507 return;
8508
8509 // Find the superclass of this class.
8510 CDecl = CDecl->getSuperClass();
8511 if (!CDecl)
8512 return;
8513
8514 if (CurMethod->isInstanceMethod()) {
8515 // We are inside an instance method, which means that the message
8516 // send [super ...] is actually calling an instance method on the
8517 // current object.
8518 return CodeCompleteObjCInstanceMessage(S, nullptr, SelIdents,
8519 AtArgumentExpression, CDecl);
8520 }
8521
8522 // Fall through to send to the superclass in CDecl.
8523 } else {
8524 // "super" may be the name of a type or variable. Figure out which
8525 // it is.
8526 const IdentifierInfo *Super = SemaRef.getSuperIdentifier();
8527 NamedDecl *ND =
8528 SemaRef.LookupSingleName(S, Super, SuperLoc, Sema::LookupOrdinaryName);
8529 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
8530 // "super" names an interface. Use it.
8531 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
8532 if (const ObjCObjectType *Iface =
8533 getASTContext().getTypeDeclType(TD)->getAs<ObjCObjectType>())
8534 CDecl = Iface->getInterface();
8535 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
8536 // "super" names an unresolved type; we can't be more specific.
8537 } else {
8538 // Assume that "super" names some kind of value and parse that way.
8539 CXXScopeSpec SS;
8540 SourceLocation TemplateKWLoc;
8541 UnqualifiedId id;
8542 id.setIdentifier(Super, SuperLoc);
8543 ExprResult SuperExpr =
8544 SemaRef.ActOnIdExpression(S, SS, TemplateKWLoc, id,
8545 /*HasTrailingLParen=*/false,
8546 /*IsAddressOfOperand=*/false);
8547 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
8548 SelIdents, AtArgumentExpression);
8549 }
8550
8551 // Fall through
8552 }
8553
8554 ParsedType Receiver;
8555 if (CDecl)
8556 Receiver = ParsedType::make(getASTContext().getObjCInterfaceType(CDecl));
8557 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
8558 AtArgumentExpression,
8559 /*IsSuper=*/true);
8560}
8561
8562/// Given a set of code-completion results for the argument of a message
8563/// send, determine the preferred type (if any) for that argument expression.
8565 unsigned NumSelIdents) {
8567 ASTContext &Context = Results.getSema().Context;
8568
8569 QualType PreferredType;
8570 unsigned BestPriority = CCP_Unlikely * 2;
8571 Result *ResultsData = Results.data();
8572 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
8573 Result &R = ResultsData[I];
8574 if (R.Kind == Result::RK_Declaration &&
8575 isa<ObjCMethodDecl>(R.Declaration)) {
8576 if (R.Priority <= BestPriority) {
8577 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
8578 if (NumSelIdents <= Method->param_size()) {
8579 QualType MyPreferredType =
8580 Method->parameters()[NumSelIdents - 1]->getType();
8581 if (R.Priority < BestPriority || PreferredType.isNull()) {
8582 BestPriority = R.Priority;
8583 PreferredType = MyPreferredType;
8584 } else if (!Context.hasSameUnqualifiedType(PreferredType,
8585 MyPreferredType)) {
8586 PreferredType = QualType();
8587 }
8588 }
8589 }
8590 }
8591 }
8592
8593 return PreferredType;
8594}
8595
8596static void
8599 bool AtArgumentExpression, bool IsSuper,
8600 ResultBuilder &Results) {
8602 ObjCInterfaceDecl *CDecl = nullptr;
8603
8604 // If the given name refers to an interface type, retrieve the
8605 // corresponding declaration.
8606 if (Receiver) {
8607 QualType T = SemaRef.GetTypeFromParser(Receiver, nullptr);
8608 if (!T.isNull())
8609 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
8610 CDecl = Interface->getInterface();
8611 }
8612
8613 // Add all of the factory methods in this Objective-C class, its protocols,
8614 // superclasses, categories, implementation, etc.
8615 Results.EnterNewScope();
8616
8617 // If this is a send-to-super, try to add the special "super" send
8618 // completion.
8619 if (IsSuper) {
8620 if (ObjCMethodDecl *SuperMethod =
8621 AddSuperSendCompletion(SemaRef, false, SelIdents, Results))
8622 Results.Ignore(SuperMethod);
8623 }
8624
8625 // If we're inside an Objective-C method definition, prefer its selector to
8626 // others.
8627 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
8628 Results.setPreferredSelector(CurMethod->getSelector());
8629
8630 VisitedSelectorSet Selectors;
8631 if (CDecl)
8632 AddObjCMethods(CDecl, false, MK_Any, SelIdents, SemaRef.CurContext,
8633 Selectors, AtArgumentExpression, Results);
8634 else {
8635 // We're messaging "id" as a type; provide all class/factory methods.
8636
8637 // If we have an external source, load the entire class method
8638 // pool from the AST file.
8639 if (SemaRef.getExternalSource()) {
8640 for (uint32_t I = 0,
8642 I != N; ++I) {
8644 if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel))
8645 continue;
8646
8647 SemaRef.ObjC().ReadMethodPool(Sel);
8648 }
8649 }
8650
8651 for (SemaObjC::GlobalMethodPool::iterator
8652 M = SemaRef.ObjC().MethodPool.begin(),
8653 MEnd = SemaRef.ObjC().MethodPool.end();
8654 M != MEnd; ++M) {
8655 for (ObjCMethodList *MethList = &M->second.second;
8656 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
8657 if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
8658 continue;
8659
8660 Result R(MethList->getMethod(),
8661 Results.getBasePriority(MethList->getMethod()),
8662 /*Qualifier=*/std::nullopt);
8663 R.StartParameter = SelIdents.size();
8664 R.AllParametersAreInformative = false;
8665 Results.MaybeAddResult(R, SemaRef.CurContext);
8666 }
8667 }
8668 }
8669
8670 Results.ExitScope();
8671}
8672
8674 Scope *S, ParsedType Receiver, ArrayRef<const IdentifierInfo *> SelIdents,
8675 bool AtArgumentExpression, bool IsSuper) {
8676
8677 QualType T = SemaRef.GetTypeFromParser(Receiver);
8678
8679 ResultBuilder Results(
8680 SemaRef, CodeCompleter->getAllocator(),
8681 CodeCompleter->getCodeCompletionTUInfo(),
8683 SelIdents));
8684
8685 AddClassMessageCompletions(SemaRef, S, Receiver, SelIdents,
8686 AtArgumentExpression, IsSuper, Results);
8687
8688 // If we're actually at the argument expression (rather than prior to the
8689 // selector), we're actually performing code completion for an expression.
8690 // Determine whether we have a single, best method. If so, we can
8691 // code-complete the expression using the corresponding parameter type as
8692 // our preferred type, improving completion results.
8693 if (AtArgumentExpression) {
8694 QualType PreferredType =
8695 getPreferredArgumentTypeForMessageSend(Results, SelIdents.size());
8696 if (PreferredType.isNull())
8698 else
8699 CodeCompleteExpression(S, PreferredType);
8700 return;
8701 }
8702
8704 Results.getCompletionContext(), Results.data(),
8705 Results.size());
8706}
8707
8709 Scope *S, Expr *RecExpr, ArrayRef<const IdentifierInfo *> SelIdents,
8710 bool AtArgumentExpression, ObjCInterfaceDecl *Super) {
8712 ASTContext &Context = getASTContext();
8713
8714 // If necessary, apply function/array conversion to the receiver.
8715 // C99 6.7.5.3p[7,8].
8716 if (RecExpr) {
8717 // If the receiver expression has no type (e.g., a parenthesized C-style
8718 // cast that hasn't been resolved), bail out to avoid dereferencing a null
8719 // type.
8720 if (RecExpr->getType().isNull())
8721 return;
8722 ExprResult Conv = SemaRef.DefaultFunctionArrayLvalueConversion(RecExpr);
8723 if (Conv.isInvalid()) // conversion failed. bail.
8724 return;
8725 RecExpr = Conv.get();
8726 }
8727 QualType ReceiverType = RecExpr
8728 ? RecExpr->getType()
8729 : Super ? Context.getObjCObjectPointerType(
8730 Context.getObjCInterfaceType(Super))
8731 : Context.getObjCIdType();
8732
8733 // If we're messaging an expression with type "id" or "Class", check
8734 // whether we know something special about the receiver that allows
8735 // us to assume a more-specific receiver type.
8736 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) {
8737 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
8738 if (ReceiverType->isObjCClassType())
8740 S, ParsedType::make(Context.getObjCInterfaceType(IFace)), SelIdents,
8741 AtArgumentExpression, Super);
8742
8743 ReceiverType =
8744 Context.getObjCObjectPointerType(Context.getObjCInterfaceType(IFace));
8745 }
8746 } else if (RecExpr && getLangOpts().CPlusPlus) {
8747 ExprResult Conv = SemaRef.PerformContextuallyConvertToObjCPointer(RecExpr);
8748 if (Conv.isUsable()) {
8749 RecExpr = Conv.get();
8750 ReceiverType = RecExpr->getType();
8751 }
8752 }
8753
8754 // Build the set of methods we can see.
8755 ResultBuilder Results(
8756 SemaRef, CodeCompleter->getAllocator(),
8757 CodeCompleter->getCodeCompletionTUInfo(),
8759 ReceiverType, SelIdents));
8760
8761 Results.EnterNewScope();
8762
8763 // If this is a send-to-super, try to add the special "super" send
8764 // completion.
8765 if (Super) {
8766 if (ObjCMethodDecl *SuperMethod =
8767 AddSuperSendCompletion(SemaRef, false, SelIdents, Results))
8768 Results.Ignore(SuperMethod);
8769 }
8770
8771 // If we're inside an Objective-C method definition, prefer its selector to
8772 // others.
8773 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
8774 Results.setPreferredSelector(CurMethod->getSelector());
8775
8776 // Keep track of the selectors we've already added.
8777 VisitedSelectorSet Selectors;
8778
8779 // Handle messages to Class. This really isn't a message to an instance
8780 // method, so we treat it the same way we would treat a message send to a
8781 // class method.
8782 if (ReceiverType->isObjCClassType() ||
8783 ReceiverType->isObjCQualifiedClassType()) {
8784 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl()) {
8785 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
8786 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, SemaRef.CurContext,
8787 Selectors, AtArgumentExpression, Results);
8788 }
8789 }
8790 // Handle messages to a qualified ID ("id<foo>").
8791 else if (const ObjCObjectPointerType *QualID =
8792 ReceiverType->getAsObjCQualifiedIdType()) {
8793 // Search protocols for instance methods.
8794 for (auto *I : QualID->quals())
8795 AddObjCMethods(I, true, MK_Any, SelIdents, SemaRef.CurContext, Selectors,
8796 AtArgumentExpression, Results);
8797 }
8798 // Handle messages to a pointer to interface type.
8799 else if (const ObjCObjectPointerType *IFacePtr =
8800 ReceiverType->getAsObjCInterfacePointerType()) {
8801 // Search the class, its superclasses, etc., for instance methods.
8802 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
8803 SemaRef.CurContext, Selectors, AtArgumentExpression,
8804 Results);
8805
8806 // Search protocols for instance methods.
8807 for (auto *I : IFacePtr->quals())
8808 AddObjCMethods(I, true, MK_Any, SelIdents, SemaRef.CurContext, Selectors,
8809 AtArgumentExpression, Results);
8810 }
8811 // Handle messages to "id".
8812 else if (ReceiverType->isObjCIdType()) {
8813 // We're messaging "id", so provide all instance methods we know
8814 // about as code-completion results.
8815
8816 // If we have an external source, load the entire class method
8817 // pool from the AST file.
8818 if (SemaRef.ExternalSource) {
8819 for (uint32_t I = 0,
8820 N = SemaRef.ExternalSource->GetNumExternalSelectors();
8821 I != N; ++I) {
8822 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
8823 if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel))
8824 continue;
8825
8826 SemaRef.ObjC().ReadMethodPool(Sel);
8827 }
8828 }
8829
8830 for (SemaObjC::GlobalMethodPool::iterator
8831 M = SemaRef.ObjC().MethodPool.begin(),
8832 MEnd = SemaRef.ObjC().MethodPool.end();
8833 M != MEnd; ++M) {
8834 for (ObjCMethodList *MethList = &M->second.first;
8835 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
8836 if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
8837 continue;
8838
8839 if (!Selectors.insert(MethList->getMethod()->getSelector()).second)
8840 continue;
8841
8842 Result R(MethList->getMethod(),
8843 Results.getBasePriority(MethList->getMethod()),
8844 /*Qualifier=*/std::nullopt);
8845 R.StartParameter = SelIdents.size();
8846 R.AllParametersAreInformative = false;
8847 Results.MaybeAddResult(R, SemaRef.CurContext);
8848 }
8849 }
8850 }
8851 Results.ExitScope();
8852
8853 // If we're actually at the argument expression (rather than prior to the
8854 // selector), we're actually performing code completion for an expression.
8855 // Determine whether we have a single, best method. If so, we can
8856 // code-complete the expression using the corresponding parameter type as
8857 // our preferred type, improving completion results.
8858 if (AtArgumentExpression) {
8859 QualType PreferredType =
8860 getPreferredArgumentTypeForMessageSend(Results, SelIdents.size());
8861 if (PreferredType.isNull())
8863 else
8864 CodeCompleteExpression(S, PreferredType);
8865 return;
8866 }
8867
8869 Results.getCompletionContext(), Results.data(),
8870 Results.size());
8871}
8872
8874 Scope *S, DeclGroupPtrTy IterationVar) {
8876 Data.ObjCCollection = true;
8877
8878 if (IterationVar.getAsOpaquePtr()) {
8879 DeclGroupRef DG = IterationVar.get();
8880 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
8881 if (*I)
8882 Data.IgnoreDecls.push_back(*I);
8883 }
8884 }
8885
8887}
8888
8891 // If we have an external source, load the entire class method
8892 // pool from the AST file.
8893 if (SemaRef.ExternalSource) {
8894 for (uint32_t I = 0, N = SemaRef.ExternalSource->GetNumExternalSelectors();
8895 I != N; ++I) {
8896 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
8897 if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel))
8898 continue;
8899
8900 SemaRef.ObjC().ReadMethodPool(Sel);
8901 }
8902 }
8903
8904 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8905 CodeCompleter->getCodeCompletionTUInfo(),
8907 Results.EnterNewScope();
8908 for (SemaObjC::GlobalMethodPool::iterator
8909 M = SemaRef.ObjC().MethodPool.begin(),
8910 MEnd = SemaRef.ObjC().MethodPool.end();
8911 M != MEnd; ++M) {
8912
8913 Selector Sel = M->first;
8914 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents))
8915 continue;
8916
8917 CodeCompletionBuilder Builder(Results.getAllocator(),
8918 Results.getCodeCompletionTUInfo());
8919 if (Sel.isUnarySelector()) {
8920 Builder.AddTypedTextChunk(
8921 Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
8922 Results.AddResult(Builder.TakeString());
8923 continue;
8924 }
8925
8926 std::string Accumulator;
8927 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
8928 if (I == SelIdents.size()) {
8929 if (!Accumulator.empty()) {
8930 Builder.AddInformativeChunk(
8931 Builder.getAllocator().CopyString(Accumulator));
8932 Accumulator.clear();
8933 }
8934 }
8935
8936 Accumulator += Sel.getNameForSlot(I);
8937 Accumulator += ':';
8938 }
8939 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(Accumulator));
8940 Results.AddResult(Builder.TakeString());
8941 }
8942 Results.ExitScope();
8943
8945 Results.getCompletionContext(), Results.data(),
8946 Results.size());
8947}
8948
8949/// Add all of the protocol declarations that we find in the given
8950/// (translation unit) context.
8951static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
8952 bool OnlyForwardDeclarations,
8953 ResultBuilder &Results) {
8955
8956 for (const auto *D : Ctx->decls()) {
8957 // Record any protocols we find.
8958 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(D))
8959 if (!OnlyForwardDeclarations || !Proto->hasDefinition())
8960 Results.AddResult(Result(Proto, Results.getBasePriority(Proto),
8961 /*Qualifier=*/std::nullopt),
8962 CurContext, nullptr, false);
8963 }
8964}
8965
8967 ArrayRef<IdentifierLoc> Protocols) {
8968 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8969 CodeCompleter->getCodeCompletionTUInfo(),
8971
8972 if (CodeCompleter->includeGlobals()) {
8973 Results.EnterNewScope();
8974
8975 // Tell the result set to ignore all of the protocols we have
8976 // already seen.
8977 // FIXME: This doesn't work when caching code-completion results.
8978 for (const IdentifierLoc &Pair : Protocols)
8979 if (ObjCProtocolDecl *Protocol = SemaRef.ObjC().LookupProtocol(
8980 Pair.getIdentifierInfo(), Pair.getLoc()))
8981 Results.Ignore(Protocol);
8982
8983 // Add all protocols.
8984 AddProtocolResults(getASTContext().getTranslationUnitDecl(),
8985 SemaRef.CurContext, false, Results);
8986
8987 Results.ExitScope();
8988 }
8989
8991 Results.getCompletionContext(), Results.data(),
8992 Results.size());
8993}
8994
8996 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8997 CodeCompleter->getCodeCompletionTUInfo(),
8999
9000 if (CodeCompleter->includeGlobals()) {
9001 Results.EnterNewScope();
9002
9003 // Add all protocols.
9004 AddProtocolResults(getASTContext().getTranslationUnitDecl(),
9005 SemaRef.CurContext, true, Results);
9006
9007 Results.ExitScope();
9008 }
9009
9011 Results.getCompletionContext(), Results.data(),
9012 Results.size());
9013}
9014
9015/// Add all of the Objective-C interface declarations that we find in
9016/// the given (translation unit) context.
9017static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
9018 bool OnlyForwardDeclarations,
9019 bool OnlyUnimplemented,
9020 ResultBuilder &Results) {
9022
9023 for (const auto *D : Ctx->decls()) {
9024 // Record any interfaces we find.
9025 if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(D))
9026 if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
9027 (!OnlyUnimplemented || !Class->getImplementation()))
9028 Results.AddResult(Result(Class, Results.getBasePriority(Class),
9029 /*Qualifier=*/std::nullopt),
9030 CurContext, nullptr, false);
9031 }
9032}
9033
9035 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9036 CodeCompleter->getCodeCompletionTUInfo(),
9038 Results.EnterNewScope();
9039
9040 if (CodeCompleter->includeGlobals()) {
9041 // Add all classes.
9042 AddInterfaceResults(getASTContext().getTranslationUnitDecl(),
9043 SemaRef.CurContext, false, false, Results);
9044 }
9045
9046 Results.ExitScope();
9047
9049 Results.getCompletionContext(), Results.data(),
9050 Results.size());
9051}
9052
9054 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9055 CodeCompleter->getCodeCompletionTUInfo(),
9057 Results.EnterNewScope();
9058
9059 if (CodeCompleter->includeGlobals()) {
9060 // Add all classes.
9061 AddInterfaceResults(getASTContext().getTranslationUnitDecl(),
9062 SemaRef.CurContext, false, false, Results);
9063 }
9064
9065 Results.ExitScope();
9066
9068 Results.getCompletionContext(), Results.data(),
9069 Results.size());
9070}
9071
9073 Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
9074 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9075 CodeCompleter->getCodeCompletionTUInfo(),
9077 Results.EnterNewScope();
9078
9079 // Make sure that we ignore the class we're currently defining.
9080 NamedDecl *CurClass = SemaRef.LookupSingleName(
9081 SemaRef.TUScope, ClassName, ClassNameLoc, Sema::LookupOrdinaryName);
9082 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
9083 Results.Ignore(CurClass);
9084
9085 if (CodeCompleter->includeGlobals()) {
9086 // Add all classes.
9087 AddInterfaceResults(getASTContext().getTranslationUnitDecl(),
9088 SemaRef.CurContext, false, false, Results);
9089 }
9090
9091 Results.ExitScope();
9092
9094 Results.getCompletionContext(), Results.data(),
9095 Results.size());
9096}
9097
9099 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9100 CodeCompleter->getCodeCompletionTUInfo(),
9102 Results.EnterNewScope();
9103
9104 if (CodeCompleter->includeGlobals()) {
9105 // Add all unimplemented classes.
9106 AddInterfaceResults(getASTContext().getTranslationUnitDecl(),
9107 SemaRef.CurContext, false, true, Results);
9108 }
9109
9110 Results.ExitScope();
9111
9113 Results.getCompletionContext(), Results.data(),
9114 Results.size());
9115}
9116
9118 Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
9120
9121 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9122 CodeCompleter->getCodeCompletionTUInfo(),
9124
9125 // Ignore any categories we find that have already been implemented by this
9126 // interface.
9128 NamedDecl *CurClass = SemaRef.LookupSingleName(
9129 SemaRef.TUScope, ClassName, ClassNameLoc, Sema::LookupOrdinaryName);
9131 dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)) {
9132 for (const auto *Cat : Class->visible_categories())
9133 CategoryNames.insert(Cat->getIdentifier());
9134 }
9135
9136 // Add all of the categories we know about.
9137 Results.EnterNewScope();
9138 TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
9139 for (const auto *D : TU->decls())
9140 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D))
9141 if (CategoryNames.insert(Category->getIdentifier()).second)
9142 Results.AddResult(Result(Category, Results.getBasePriority(Category),
9143 /*Qualifier=*/std::nullopt),
9144 SemaRef.CurContext, nullptr, false);
9145 Results.ExitScope();
9146
9148 Results.getCompletionContext(), Results.data(),
9149 Results.size());
9150}
9151
9153 Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
9155
9156 // Find the corresponding interface. If we couldn't find the interface, the
9157 // program itself is ill-formed. However, we'll try to be helpful still by
9158 // providing the list of all of the categories we know about.
9159 NamedDecl *CurClass = SemaRef.LookupSingleName(
9160 SemaRef.TUScope, ClassName, ClassNameLoc, Sema::LookupOrdinaryName);
9161 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
9162 if (!Class)
9163 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
9164
9165 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9166 CodeCompleter->getCodeCompletionTUInfo(),
9168
9169 // Add all of the categories that have corresponding interface
9170 // declarations in this class and any of its superclasses, except for
9171 // already-implemented categories in the class itself.
9173 Results.EnterNewScope();
9174 bool IgnoreImplemented = true;
9175 while (Class) {
9176 for (const auto *Cat : Class->visible_categories()) {
9177 if ((!IgnoreImplemented || !Cat->getImplementation()) &&
9178 CategoryNames.insert(Cat->getIdentifier()).second)
9179 Results.AddResult(Result(Cat, Results.getBasePriority(Cat),
9180 /*Qualifier=*/std::nullopt),
9181 SemaRef.CurContext, nullptr, false);
9182 }
9183
9184 Class = Class->getSuperClass();
9185 IgnoreImplemented = false;
9186 }
9187 Results.ExitScope();
9188
9190 Results.getCompletionContext(), Results.data(),
9191 Results.size());
9192}
9193
9196 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9197 CodeCompleter->getCodeCompletionTUInfo(), CCContext);
9198
9199 // Figure out where this @synthesize lives.
9200 ObjCContainerDecl *Container =
9201 dyn_cast_or_null<ObjCContainerDecl>(SemaRef.CurContext);
9202 if (!Container || (!isa<ObjCImplementationDecl>(Container) &&
9203 !isa<ObjCCategoryImplDecl>(Container)))
9204 return;
9205
9206 // Ignore any properties that have already been implemented.
9207 Container = getContainerDef(Container);
9208 for (const auto *D : Container->decls())
9209 if (const auto *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(D))
9210 Results.Ignore(PropertyImpl->getPropertyDecl());
9211
9212 // Add any properties that we find.
9213 AddedPropertiesSet AddedProperties;
9214 Results.EnterNewScope();
9215 if (ObjCImplementationDecl *ClassImpl =
9216 dyn_cast<ObjCImplementationDecl>(Container))
9217 AddObjCProperties(CCContext, ClassImpl->getClassInterface(), false,
9218 /*AllowNullaryMethods=*/false, SemaRef.CurContext,
9219 AddedProperties, Results);
9220 else
9221 AddObjCProperties(CCContext,
9222 cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
9223 false, /*AllowNullaryMethods=*/false, SemaRef.CurContext,
9224 AddedProperties, Results);
9225 Results.ExitScope();
9226
9228 Results.getCompletionContext(), Results.data(),
9229 Results.size());
9230}
9231
9233 Scope *S, IdentifierInfo *PropertyName) {
9235 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9236 CodeCompleter->getCodeCompletionTUInfo(),
9238
9239 // Figure out where this @synthesize lives.
9240 ObjCContainerDecl *Container =
9241 dyn_cast_or_null<ObjCContainerDecl>(SemaRef.CurContext);
9242 if (!Container || (!isa<ObjCImplementationDecl>(Container) &&
9243 !isa<ObjCCategoryImplDecl>(Container)))
9244 return;
9245
9246 // Figure out which interface we're looking into.
9247 ObjCInterfaceDecl *Class = nullptr;
9248 if (ObjCImplementationDecl *ClassImpl =
9249 dyn_cast<ObjCImplementationDecl>(Container))
9250 Class = ClassImpl->getClassInterface();
9251 else
9253 ->getCategoryDecl()
9254 ->getClassInterface();
9255
9256 // Determine the type of the property we're synthesizing.
9257 QualType PropertyType = getASTContext().getObjCIdType();
9258 if (Class) {
9259 if (ObjCPropertyDecl *Property = Class->FindPropertyDeclaration(
9261 PropertyType =
9262 Property->getType().getNonReferenceType().getUnqualifiedType();
9263
9264 // Give preference to ivars
9265 Results.setPreferredType(PropertyType);
9266 }
9267 }
9268
9269 // Add all of the instance variables in this class and its superclasses.
9270 Results.EnterNewScope();
9271 bool SawSimilarlyNamedIvar = false;
9272 std::string NameWithPrefix;
9273 NameWithPrefix += '_';
9274 NameWithPrefix += PropertyName->getName();
9275 std::string NameWithSuffix = PropertyName->getName().str();
9276 NameWithSuffix += '_';
9277 for (; Class; Class = Class->getSuperClass()) {
9278 for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
9279 Ivar = Ivar->getNextIvar()) {
9280 Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar),
9281 /*Qualifier=*/std::nullopt),
9282 SemaRef.CurContext, nullptr, false);
9283
9284 // Determine whether we've seen an ivar with a name similar to the
9285 // property.
9286 if ((PropertyName == Ivar->getIdentifier() ||
9287 NameWithPrefix == Ivar->getName() ||
9288 NameWithSuffix == Ivar->getName())) {
9289 SawSimilarlyNamedIvar = true;
9290
9291 // Reduce the priority of this result by one, to give it a slight
9292 // advantage over other results whose names don't match so closely.
9293 if (Results.size() &&
9294 Results.data()[Results.size() - 1].Kind ==
9296 Results.data()[Results.size() - 1].Declaration == Ivar)
9297 Results.data()[Results.size() - 1].Priority--;
9298 }
9299 }
9300 }
9301
9302 if (!SawSimilarlyNamedIvar) {
9303 // Create ivar result _propName, that the user can use to synthesize
9304 // an ivar of the appropriate type.
9305 unsigned Priority = CCP_MemberDeclaration + 1;
9307 CodeCompletionAllocator &Allocator = Results.getAllocator();
9308 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
9309 Priority, CXAvailability_Available);
9310
9312 Builder.AddResultTypeChunk(GetCompletionTypeString(
9313 PropertyType, getASTContext(), Policy, Allocator));
9314 Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix));
9315 Results.AddResult(
9316 Result(Builder.TakeString(), Priority, CXCursor_ObjCIvarDecl));
9317 }
9318
9319 Results.ExitScope();
9320
9322 Results.getCompletionContext(), Results.data(),
9323 Results.size());
9324}
9325
9326// Mapping from selectors to the methods that implement that selector, along
9327// with the "in original class" flag.
9328typedef llvm::DenseMap<Selector,
9329 llvm::PointerIntPair<ObjCMethodDecl *, 1, bool>>
9331
9332/// Find all of the methods that reside in the given container
9333/// (and its superclasses, protocols, etc.) that meet the given
9334/// criteria. Insert those methods into the map of known methods,
9335/// indexed by selector so they can be easily found.
9337 ObjCContainerDecl *Container,
9338 std::optional<bool> WantInstanceMethods,
9339 QualType ReturnType,
9340 KnownMethodsMap &KnownMethods,
9341 bool InOriginalClass = true) {
9342 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
9343 // Make sure we have a definition; that's what we'll walk.
9344 if (!IFace->hasDefinition())
9345 return;
9346
9347 IFace = IFace->getDefinition();
9348 Container = IFace;
9349
9350 const ObjCList<ObjCProtocolDecl> &Protocols =
9351 IFace->getReferencedProtocols();
9352 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
9353 E = Protocols.end();
9354 I != E; ++I)
9355 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
9356 KnownMethods, InOriginalClass);
9357
9358 // Add methods from any class extensions and categories.
9359 for (auto *Cat : IFace->visible_categories()) {
9360 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
9361 KnownMethods, false);
9362 }
9363
9364 // Visit the superclass.
9365 if (IFace->getSuperClass())
9366 FindImplementableMethods(Context, IFace->getSuperClass(),
9367 WantInstanceMethods, ReturnType, KnownMethods,
9368 false);
9369 }
9370
9371 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
9372 // Recurse into protocols.
9373 const ObjCList<ObjCProtocolDecl> &Protocols =
9374 Category->getReferencedProtocols();
9375 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
9376 E = Protocols.end();
9377 I != E; ++I)
9378 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
9379 KnownMethods, InOriginalClass);
9380
9381 // If this category is the original class, jump to the interface.
9382 if (InOriginalClass && Category->getClassInterface())
9383 FindImplementableMethods(Context, Category->getClassInterface(),
9384 WantInstanceMethods, ReturnType, KnownMethods,
9385 false);
9386 }
9387
9388 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
9389 // Make sure we have a definition; that's what we'll walk.
9390 if (!Protocol->hasDefinition())
9391 return;
9392 Protocol = Protocol->getDefinition();
9393 Container = Protocol;
9394
9395 // Recurse into protocols.
9396 const ObjCList<ObjCProtocolDecl> &Protocols =
9397 Protocol->getReferencedProtocols();
9398 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
9399 E = Protocols.end();
9400 I != E; ++I)
9401 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
9402 KnownMethods, false);
9403 }
9404
9405 // Add methods in this container. This operation occurs last because
9406 // we want the methods from this container to override any methods
9407 // we've previously seen with the same selector.
9408 for (auto *M : Container->methods()) {
9409 if (!WantInstanceMethods || M->isInstanceMethod() == *WantInstanceMethods) {
9410 if (!ReturnType.isNull() &&
9411 !Context.hasSameUnqualifiedType(ReturnType, M->getReturnType()))
9412 continue;
9413
9414 KnownMethods[M->getSelector()] =
9415 KnownMethodsMap::mapped_type(M, InOriginalClass);
9416 }
9417 }
9418}
9419
9420/// Add the parenthesized return or parameter type chunk to a code
9421/// completion string.
9422static void AddObjCPassingTypeChunk(QualType Type, unsigned ObjCDeclQuals,
9423 ASTContext &Context,
9424 const PrintingPolicy &Policy,
9425 CodeCompletionBuilder &Builder) {
9426 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9427 std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals, Type);
9428 if (!Quals.empty())
9429 Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals));
9430 Builder.AddTextChunk(
9431 GetCompletionTypeString(Type, Context, Policy, Builder.getAllocator()));
9432 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9433}
9434
9435/// Determine whether the given class is or inherits from a class by
9436/// the given name.
9437static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, StringRef Name) {
9438 if (!Class)
9439 return false;
9440
9441 if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name)
9442 return true;
9443
9444 return InheritsFromClassNamed(Class->getSuperClass(), Name);
9445}
9446
9447/// Add code completions for Objective-C Key-Value Coding (KVC) and
9448/// Key-Value Observing (KVO).
9450 bool IsInstanceMethod,
9451 QualType ReturnType, ASTContext &Context,
9452 VisitedSelectorSet &KnownSelectors,
9453 ResultBuilder &Results) {
9454 IdentifierInfo *PropName = Property->getIdentifier();
9455 if (!PropName || PropName->getLength() == 0)
9456 return;
9457
9458 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
9459
9460 // Builder that will create each code completion.
9462 CodeCompletionAllocator &Allocator = Results.getAllocator();
9463 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
9464
9465 // The selector table.
9466 SelectorTable &Selectors = Context.Selectors;
9467
9468 // The property name, copied into the code completion allocation region
9469 // on demand.
9470 struct KeyHolder {
9471 CodeCompletionAllocator &Allocator;
9472 StringRef Key;
9473 const char *CopiedKey;
9474
9475 KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
9476 : Allocator(Allocator), Key(Key), CopiedKey(nullptr) {}
9477
9478 operator const char *() {
9479 if (CopiedKey)
9480 return CopiedKey;
9481
9482 return CopiedKey = Allocator.CopyString(Key);
9483 }
9484 } Key(Allocator, PropName->getName());
9485
9486 // The uppercased name of the property name.
9487 std::string UpperKey = std::string(PropName->getName());
9488 if (!UpperKey.empty())
9489 UpperKey[0] = toUppercase(UpperKey[0]);
9490
9491 bool ReturnTypeMatchesProperty =
9492 ReturnType.isNull() ||
9493 Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(),
9494 Property->getType());
9495 bool ReturnTypeMatchesVoid = ReturnType.isNull() || ReturnType->isVoidType();
9496
9497 // Add the normal accessor -(type)key.
9498 if (IsInstanceMethod &&
9499 KnownSelectors.insert(Selectors.getNullarySelector(PropName)).second &&
9500 ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {
9501 if (ReturnType.isNull())
9502 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy,
9503 Builder);
9504
9505 Builder.AddTypedTextChunk(Key);
9506 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
9508 }
9509
9510 // If we have an integral or boolean property (or the user has provided
9511 // an integral or boolean return type), add the accessor -(type)isKey.
9512 if (IsInstanceMethod &&
9513 ((!ReturnType.isNull() &&
9514 (ReturnType->isIntegerType() || ReturnType->isBooleanType())) ||
9515 (ReturnType.isNull() && (Property->getType()->isIntegerType() ||
9516 Property->getType()->isBooleanType())))) {
9517 std::string SelectorName = (Twine("is") + UpperKey).str();
9518 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9519 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
9520 .second) {
9521 if (ReturnType.isNull()) {
9522 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9523 Builder.AddTextChunk("BOOL");
9524 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9525 }
9526
9527 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName()));
9528 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
9530 }
9531 }
9532
9533 // Add the normal mutator.
9534 if (IsInstanceMethod && ReturnTypeMatchesVoid &&
9535 !Property->getSetterMethodDecl()) {
9536 std::string SelectorName = (Twine("set") + UpperKey).str();
9537 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9538 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9539 if (ReturnType.isNull()) {
9540 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9541 Builder.AddTextChunk("void");
9542 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9543 }
9544
9545 Builder.AddTypedTextChunk(
9546 Allocator.CopyString(SelectorId->getName() + ":"));
9547 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy,
9548 Builder);
9549 Builder.AddTextChunk(Key);
9550 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
9552 }
9553 }
9554
9555 // Indexed and unordered accessors
9556 unsigned IndexedGetterPriority = CCP_CodePattern;
9557 unsigned IndexedSetterPriority = CCP_CodePattern;
9558 unsigned UnorderedGetterPriority = CCP_CodePattern;
9559 unsigned UnorderedSetterPriority = CCP_CodePattern;
9560 if (const auto *ObjCPointer =
9561 Property->getType()->getAs<ObjCObjectPointerType>()) {
9562 if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) {
9563 // If this interface type is not provably derived from a known
9564 // collection, penalize the corresponding completions.
9565 if (!InheritsFromClassNamed(IFace, "NSMutableArray")) {
9566 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
9567 if (!InheritsFromClassNamed(IFace, "NSArray"))
9568 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
9569 }
9570
9571 if (!InheritsFromClassNamed(IFace, "NSMutableSet")) {
9572 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
9573 if (!InheritsFromClassNamed(IFace, "NSSet"))
9574 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
9575 }
9576 }
9577 } else {
9578 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
9579 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
9580 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
9581 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
9582 }
9583
9584 // Add -(NSUInteger)countOf<key>
9585 if (IsInstanceMethod &&
9586 (ReturnType.isNull() || ReturnType->isIntegerType())) {
9587 std::string SelectorName = (Twine("countOf") + UpperKey).str();
9588 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9589 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
9590 .second) {
9591 if (ReturnType.isNull()) {
9592 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9593 Builder.AddTextChunk("NSUInteger");
9594 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9595 }
9596
9597 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName()));
9598 Results.AddResult(
9599 Result(Builder.TakeString(),
9600 std::min(IndexedGetterPriority, UnorderedGetterPriority),
9602 }
9603 }
9604
9605 // Indexed getters
9606 // Add -(id)objectInKeyAtIndex:(NSUInteger)index
9607 if (IsInstanceMethod &&
9608 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
9609 std::string SelectorName = (Twine("objectIn") + UpperKey + "AtIndex").str();
9610 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9611 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9612 if (ReturnType.isNull()) {
9613 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9614 Builder.AddTextChunk("id");
9615 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9616 }
9617
9618 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9619 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9620 Builder.AddTextChunk("NSUInteger");
9621 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9622 Builder.AddTextChunk("index");
9623 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
9625 }
9626 }
9627
9628 // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes
9629 if (IsInstanceMethod &&
9630 (ReturnType.isNull() ||
9631 (ReturnType->isObjCObjectPointerType() &&
9632 ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
9633 ReturnType->castAs<ObjCObjectPointerType>()
9635 ->getName() == "NSArray"))) {
9636 std::string SelectorName = (Twine(Property->getName()) + "AtIndexes").str();
9637 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9638 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9639 if (ReturnType.isNull()) {
9640 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9641 Builder.AddTextChunk("NSArray *");
9642 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9643 }
9644
9645 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9646 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9647 Builder.AddTextChunk("NSIndexSet *");
9648 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9649 Builder.AddTextChunk("indexes");
9650 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
9652 }
9653 }
9654
9655 // Add -(void)getKey:(type **)buffer range:(NSRange)inRange
9656 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9657 std::string SelectorName = (Twine("get") + UpperKey).str();
9658 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
9659 &Context.Idents.get("range")};
9660
9661 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9662 if (ReturnType.isNull()) {
9663 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9664 Builder.AddTextChunk("void");
9665 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9666 }
9667
9668 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9669 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9670 Builder.AddPlaceholderChunk("object-type");
9671 Builder.AddTextChunk(" **");
9672 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9673 Builder.AddTextChunk("buffer");
9675 Builder.AddTypedTextChunk("range:");
9676 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9677 Builder.AddTextChunk("NSRange");
9678 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9679 Builder.AddTextChunk("inRange");
9680 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
9682 }
9683 }
9684
9685 // Mutable indexed accessors
9686
9687 // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index
9688 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9689 std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str();
9690 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get("insertObject"),
9691 &Context.Idents.get(SelectorName)};
9692
9693 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9694 if (ReturnType.isNull()) {
9695 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9696 Builder.AddTextChunk("void");
9697 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9698 }
9699
9700 Builder.AddTypedTextChunk("insertObject:");
9701 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9702 Builder.AddPlaceholderChunk("object-type");
9703 Builder.AddTextChunk(" *");
9704 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9705 Builder.AddTextChunk("object");
9707 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9708 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9709 Builder.AddPlaceholderChunk("NSUInteger");
9710 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9711 Builder.AddTextChunk("index");
9712 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9714 }
9715 }
9716
9717 // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes
9718 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9719 std::string SelectorName = (Twine("insert") + UpperKey).str();
9720 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
9721 &Context.Idents.get("atIndexes")};
9722
9723 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9724 if (ReturnType.isNull()) {
9725 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9726 Builder.AddTextChunk("void");
9727 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9728 }
9729
9730 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9731 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9732 Builder.AddTextChunk("NSArray *");
9733 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9734 Builder.AddTextChunk("array");
9736 Builder.AddTypedTextChunk("atIndexes:");
9737 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9738 Builder.AddPlaceholderChunk("NSIndexSet *");
9739 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9740 Builder.AddTextChunk("indexes");
9741 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9743 }
9744 }
9745
9746 // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index
9747 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9748 std::string SelectorName =
9749 (Twine("removeObjectFrom") + UpperKey + "AtIndex").str();
9750 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9751 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9752 if (ReturnType.isNull()) {
9753 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9754 Builder.AddTextChunk("void");
9755 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9756 }
9757
9758 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9759 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9760 Builder.AddTextChunk("NSUInteger");
9761 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9762 Builder.AddTextChunk("index");
9763 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9765 }
9766 }
9767
9768 // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes
9769 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9770 std::string SelectorName = (Twine("remove") + UpperKey + "AtIndexes").str();
9771 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9772 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9773 if (ReturnType.isNull()) {
9774 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9775 Builder.AddTextChunk("void");
9776 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9777 }
9778
9779 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9780 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9781 Builder.AddTextChunk("NSIndexSet *");
9782 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9783 Builder.AddTextChunk("indexes");
9784 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9786 }
9787 }
9788
9789 // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object
9790 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9791 std::string SelectorName =
9792 (Twine("replaceObjectIn") + UpperKey + "AtIndex").str();
9793 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
9794 &Context.Idents.get("withObject")};
9795
9796 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9797 if (ReturnType.isNull()) {
9798 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9799 Builder.AddTextChunk("void");
9800 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9801 }
9802
9803 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9804 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9805 Builder.AddPlaceholderChunk("NSUInteger");
9806 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9807 Builder.AddTextChunk("index");
9809 Builder.AddTypedTextChunk("withObject:");
9810 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9811 Builder.AddTextChunk("id");
9812 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9813 Builder.AddTextChunk("object");
9814 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9816 }
9817 }
9818
9819 // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array
9820 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9821 std::string SelectorName1 =
9822 (Twine("replace") + UpperKey + "AtIndexes").str();
9823 std::string SelectorName2 = (Twine("with") + UpperKey).str();
9824 const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName1),
9825 &Context.Idents.get(SelectorName2)};
9826
9827 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9828 if (ReturnType.isNull()) {
9829 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9830 Builder.AddTextChunk("void");
9831 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9832 }
9833
9834 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":"));
9835 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9836 Builder.AddPlaceholderChunk("NSIndexSet *");
9837 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9838 Builder.AddTextChunk("indexes");
9840 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":"));
9841 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9842 Builder.AddTextChunk("NSArray *");
9843 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9844 Builder.AddTextChunk("array");
9845 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9847 }
9848 }
9849
9850 // Unordered getters
9851 // - (NSEnumerator *)enumeratorOfKey
9852 if (IsInstanceMethod &&
9853 (ReturnType.isNull() ||
9854 (ReturnType->isObjCObjectPointerType() &&
9855 ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
9856 ReturnType->castAs<ObjCObjectPointerType>()
9858 ->getName() == "NSEnumerator"))) {
9859 std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();
9860 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9861 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
9862 .second) {
9863 if (ReturnType.isNull()) {
9864 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9865 Builder.AddTextChunk("NSEnumerator *");
9866 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9867 }
9868
9869 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
9870 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
9872 }
9873 }
9874
9875 // - (type *)memberOfKey:(type *)object
9876 if (IsInstanceMethod &&
9877 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
9878 std::string SelectorName = (Twine("memberOf") + UpperKey).str();
9879 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9880 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9881 if (ReturnType.isNull()) {
9882 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9883 Builder.AddPlaceholderChunk("object-type");
9884 Builder.AddTextChunk(" *");
9885 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9886 }
9887
9888 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9889 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9890 if (ReturnType.isNull()) {
9891 Builder.AddPlaceholderChunk("object-type");
9892 Builder.AddTextChunk(" *");
9893 } else {
9894 Builder.AddTextChunk(GetCompletionTypeString(
9895 ReturnType, Context, Policy, Builder.getAllocator()));
9896 }
9897 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9898 Builder.AddTextChunk("object");
9899 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
9901 }
9902 }
9903
9904 // Mutable unordered accessors
9905 // - (void)addKeyObject:(type *)object
9906 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9907 std::string SelectorName =
9908 (Twine("add") + UpperKey + Twine("Object")).str();
9909 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9910 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9911 if (ReturnType.isNull()) {
9912 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9913 Builder.AddTextChunk("void");
9914 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9915 }
9916
9917 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9918 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9919 Builder.AddPlaceholderChunk("object-type");
9920 Builder.AddTextChunk(" *");
9921 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9922 Builder.AddTextChunk("object");
9923 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9925 }
9926 }
9927
9928 // - (void)addKey:(NSSet *)objects
9929 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9930 std::string SelectorName = (Twine("add") + UpperKey).str();
9931 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9932 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9933 if (ReturnType.isNull()) {
9934 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9935 Builder.AddTextChunk("void");
9936 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9937 }
9938
9939 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9940 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9941 Builder.AddTextChunk("NSSet *");
9942 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9943 Builder.AddTextChunk("objects");
9944 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9946 }
9947 }
9948
9949 // - (void)removeKeyObject:(type *)object
9950 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9951 std::string SelectorName =
9952 (Twine("remove") + UpperKey + Twine("Object")).str();
9953 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9954 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9955 if (ReturnType.isNull()) {
9956 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9957 Builder.AddTextChunk("void");
9958 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9959 }
9960
9961 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9962 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9963 Builder.AddPlaceholderChunk("object-type");
9964 Builder.AddTextChunk(" *");
9965 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9966 Builder.AddTextChunk("object");
9967 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9969 }
9970 }
9971
9972 // - (void)removeKey:(NSSet *)objects
9973 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9974 std::string SelectorName = (Twine("remove") + UpperKey).str();
9975 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9976 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9977 if (ReturnType.isNull()) {
9978 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9979 Builder.AddTextChunk("void");
9980 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9981 }
9982
9983 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9984 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9985 Builder.AddTextChunk("NSSet *");
9986 Builder.AddChunk(CodeCompletionString::CK_RightParen);
9987 Builder.AddTextChunk("objects");
9988 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9990 }
9991 }
9992
9993 // - (void)intersectKey:(NSSet *)objects
9994 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9995 std::string SelectorName = (Twine("intersect") + UpperKey).str();
9996 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9997 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9998 if (ReturnType.isNull()) {
9999 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
10000 Builder.AddTextChunk("void");
10001 Builder.AddChunk(CodeCompletionString::CK_RightParen);
10002 }
10003
10004 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
10005 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
10006 Builder.AddTextChunk("NSSet *");
10007 Builder.AddChunk(CodeCompletionString::CK_RightParen);
10008 Builder.AddTextChunk("objects");
10009 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
10011 }
10012 }
10013
10014 // Key-Value Observing
10015 // + (NSSet *)keyPathsForValuesAffectingKey
10016 if (!IsInstanceMethod &&
10017 (ReturnType.isNull() ||
10018 (ReturnType->isObjCObjectPointerType() &&
10019 ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
10020 ReturnType->castAs<ObjCObjectPointerType>()
10022 ->getName() == "NSSet"))) {
10023 std::string SelectorName =
10024 (Twine("keyPathsForValuesAffecting") + UpperKey).str();
10025 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
10026 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
10027 .second) {
10028 if (ReturnType.isNull()) {
10029 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
10030 Builder.AddTextChunk("NSSet<NSString *> *");
10031 Builder.AddChunk(CodeCompletionString::CK_RightParen);
10032 }
10033
10034 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
10035 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
10037 }
10038 }
10039
10040 // + (BOOL)automaticallyNotifiesObserversForKey
10041 if (!IsInstanceMethod &&
10042 (ReturnType.isNull() || ReturnType->isIntegerType() ||
10043 ReturnType->isBooleanType())) {
10044 std::string SelectorName =
10045 (Twine("automaticallyNotifiesObserversOf") + UpperKey).str();
10046 const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
10047 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
10048 .second) {
10049 if (ReturnType.isNull()) {
10050 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
10051 Builder.AddTextChunk("BOOL");
10052 Builder.AddChunk(CodeCompletionString::CK_RightParen);
10053 }
10054
10055 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
10056 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
10058 }
10059 }
10060}
10061
10063 Scope *S, std::optional<bool> IsInstanceMethod, ParsedType ReturnTy) {
10064 ASTContext &Context = getASTContext();
10065 // Determine the return type of the method we're declaring, if
10066 // provided.
10067 QualType ReturnType = SemaRef.GetTypeFromParser(ReturnTy);
10068 Decl *IDecl = nullptr;
10069 if (SemaRef.CurContext->isObjCContainer()) {
10070 ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(SemaRef.CurContext);
10071 IDecl = OCD;
10072 }
10073 // Determine where we should start searching for methods.
10074 ObjCContainerDecl *SearchDecl = nullptr;
10075 bool IsInImplementation = false;
10076 if (Decl *D = IDecl) {
10077 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
10078 SearchDecl = Impl->getClassInterface();
10079 IsInImplementation = true;
10080 } else if (ObjCCategoryImplDecl *CatImpl =
10081 dyn_cast<ObjCCategoryImplDecl>(D)) {
10082 SearchDecl = CatImpl->getCategoryDecl();
10083 IsInImplementation = true;
10084 } else
10085 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
10086 }
10087
10088 if (!SearchDecl && S) {
10089 if (DeclContext *DC = S->getEntity())
10090 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
10091 }
10092
10093 if (!SearchDecl) {
10096 return;
10097 }
10098
10099 // Find all of the methods that we could declare/implement here.
10100 KnownMethodsMap KnownMethods;
10101 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod, ReturnType,
10102 KnownMethods);
10103
10104 // Add declarations or definitions for each of the known methods.
10106 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10107 CodeCompleter->getCodeCompletionTUInfo(),
10109 Results.EnterNewScope();
10111 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
10112 MEnd = KnownMethods.end();
10113 M != MEnd; ++M) {
10114 ObjCMethodDecl *Method = M->second.getPointer();
10115 CodeCompletionBuilder Builder(Results.getAllocator(),
10116 Results.getCodeCompletionTUInfo());
10117
10118 // Add the '-'/'+' prefix if it wasn't provided yet.
10119 if (!IsInstanceMethod) {
10120 Builder.AddTextChunk(Method->isInstanceMethod() ? "-" : "+");
10122 }
10123
10124 // If the result type was not already provided, add it to the
10125 // pattern as (type).
10126 if (ReturnType.isNull()) {
10127 QualType ResTy = Method->getSendResultType().stripObjCKindOfType(Context);
10128 AttributedType::stripOuterNullability(ResTy);
10129 AddObjCPassingTypeChunk(ResTy, Method->getObjCDeclQualifier(), Context,
10130 Policy, Builder);
10131 }
10132
10133 Selector Sel = Method->getSelector();
10134
10135 if (Sel.isUnarySelector()) {
10136 // Unary selectors have no arguments.
10137 Builder.AddTypedTextChunk(
10138 Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
10139 } else {
10140 // Add all parameters to the pattern.
10141 unsigned I = 0;
10142 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
10143 PEnd = Method->param_end();
10144 P != PEnd; (void)++P, ++I) {
10145 // Add the part of the selector name.
10146 if (I == 0)
10147 Builder.AddTypedTextChunk(
10148 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
10149 else if (I < Sel.getNumArgs()) {
10151 Builder.AddTypedTextChunk(
10152 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
10153 } else
10154 break;
10155
10156 // Add the parameter type.
10157 QualType ParamType;
10158 if ((*P)->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
10159 ParamType = (*P)->getType();
10160 else
10161 ParamType = (*P)->getOriginalType();
10162 ParamType = ParamType.substObjCTypeArgs(
10164 AttributedType::stripOuterNullability(ParamType);
10165 AddObjCPassingTypeChunk(ParamType, (*P)->getObjCDeclQualifier(),
10166 Context, Policy, Builder);
10167
10168 if (IdentifierInfo *Id = (*P)->getIdentifier())
10169 Builder.AddTextChunk(
10170 Builder.getAllocator().CopyString(Id->getName()));
10171 }
10172 }
10173
10174 if (Method->isVariadic()) {
10175 if (Method->param_size() > 0)
10176 Builder.AddChunk(CodeCompletionString::CK_Comma);
10177 Builder.AddTextChunk("...");
10178 }
10179
10180 if (IsInImplementation && Results.includeCodePatterns()) {
10181 // We will be defining the method here, so add a compound statement.
10183 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
10185 if (!Method->getReturnType()->isVoidType()) {
10186 // If the result type is not void, add a return clause.
10187 Builder.AddTextChunk("return");
10189 Builder.AddPlaceholderChunk("expression");
10190 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
10191 } else
10192 Builder.AddPlaceholderChunk("statements");
10193
10195 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
10196 }
10197
10198 unsigned Priority = CCP_CodePattern;
10199 auto R = Result(Builder.TakeString(), Method, Priority);
10200 if (!M->second.getInt())
10201 setInBaseClass(R);
10202 Results.AddResult(std::move(R));
10203 }
10204
10205 // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
10206 // the properties in this class and its categories.
10207 if (Context.getLangOpts().ObjC) {
10209 Containers.push_back(SearchDecl);
10210
10211 VisitedSelectorSet KnownSelectors;
10212 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
10213 MEnd = KnownMethods.end();
10214 M != MEnd; ++M)
10215 KnownSelectors.insert(M->first);
10216
10217 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl);
10218 if (!IFace)
10219 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl))
10220 IFace = Category->getClassInterface();
10221
10222 if (IFace)
10223 llvm::append_range(Containers, IFace->visible_categories());
10224
10225 if (IsInstanceMethod) {
10226 for (unsigned I = 0, N = Containers.size(); I != N; ++I)
10227 for (auto *P : Containers[I]->instance_properties())
10228 AddObjCKeyValueCompletions(P, *IsInstanceMethod, ReturnType, Context,
10229 KnownSelectors, Results);
10230 }
10231 }
10232
10233 Results.ExitScope();
10234
10236 Results.getCompletionContext(), Results.data(),
10237 Results.size());
10238}
10239
10241 Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnTy,
10243 // If we have an external source, load the entire class method
10244 // pool from the AST file.
10245 if (SemaRef.ExternalSource) {
10246 for (uint32_t I = 0, N = SemaRef.ExternalSource->GetNumExternalSelectors();
10247 I != N; ++I) {
10248 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
10249 if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel))
10250 continue;
10251
10252 SemaRef.ObjC().ReadMethodPool(Sel);
10253 }
10254 }
10255
10256 // Build the set of methods we can see.
10258 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10259 CodeCompleter->getCodeCompletionTUInfo(),
10261
10262 if (ReturnTy)
10263 Results.setPreferredType(
10264 SemaRef.GetTypeFromParser(ReturnTy).getNonReferenceType());
10265
10266 Results.EnterNewScope();
10267 for (SemaObjC::GlobalMethodPool::iterator
10268 M = SemaRef.ObjC().MethodPool.begin(),
10269 MEnd = SemaRef.ObjC().MethodPool.end();
10270 M != MEnd; ++M) {
10271 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first
10272 : &M->second.second;
10273 MethList && MethList->getMethod(); MethList = MethList->getNext()) {
10274 if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
10275 continue;
10276
10277 if (AtParameterName) {
10278 // Suggest parameter names we've seen before.
10279 unsigned NumSelIdents = SelIdents.size();
10280 if (NumSelIdents &&
10281 NumSelIdents <= MethList->getMethod()->param_size()) {
10282 ParmVarDecl *Param =
10283 MethList->getMethod()->parameters()[NumSelIdents - 1];
10284 if (Param->getIdentifier()) {
10285 CodeCompletionBuilder Builder(Results.getAllocator(),
10286 Results.getCodeCompletionTUInfo());
10287 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
10288 Param->getIdentifier()->getName()));
10289 Results.AddResult(Builder.TakeString());
10290 }
10291 }
10292
10293 continue;
10294 }
10295
10296 Result R(MethList->getMethod(),
10297 Results.getBasePriority(MethList->getMethod()),
10298 /*Qualifier=*/std::nullopt);
10299 R.StartParameter = SelIdents.size();
10300 R.AllParametersAreInformative = false;
10301 R.DeclaringEntity = true;
10302 Results.MaybeAddResult(R, SemaRef.CurContext);
10303 }
10304 }
10305
10306 Results.ExitScope();
10307
10308 if (!AtParameterName && !SelIdents.empty() &&
10309 SelIdents.front()->getName().starts_with("init")) {
10310 for (const auto &M : SemaRef.PP.macros()) {
10311 if (M.first->getName() != "NS_DESIGNATED_INITIALIZER")
10312 continue;
10313 Results.EnterNewScope();
10314 CodeCompletionBuilder Builder(Results.getAllocator(),
10315 Results.getCodeCompletionTUInfo());
10316 Builder.AddTypedTextChunk(
10317 Builder.getAllocator().CopyString(M.first->getName()));
10318 Results.AddResult(CodeCompletionResult(Builder.TakeString(), CCP_Macro,
10320 Results.ExitScope();
10321 }
10322 }
10323
10325 Results.getCompletionContext(), Results.data(),
10326 Results.size());
10327}
10328
10330 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10331 CodeCompleter->getCodeCompletionTUInfo(),
10333 Results.EnterNewScope();
10334
10335 // #if <condition>
10336 CodeCompletionBuilder Builder(Results.getAllocator(),
10337 Results.getCodeCompletionTUInfo());
10338 Builder.AddTypedTextChunk("if");
10340 Builder.AddPlaceholderChunk("condition");
10341 Results.AddResult(Builder.TakeString());
10342
10343 // #ifdef <macro>
10344 Builder.AddTypedTextChunk("ifdef");
10346 Builder.AddPlaceholderChunk("macro");
10347 Results.AddResult(Builder.TakeString());
10348
10349 // #ifndef <macro>
10350 Builder.AddTypedTextChunk("ifndef");
10352 Builder.AddPlaceholderChunk("macro");
10353 Results.AddResult(Builder.TakeString());
10354
10355 if (InConditional) {
10356 // #elif <condition>
10357 Builder.AddTypedTextChunk("elif");
10359 Builder.AddPlaceholderChunk("condition");
10360 Results.AddResult(Builder.TakeString());
10361
10362 // #elifdef <macro>
10363 Builder.AddTypedTextChunk("elifdef");
10365 Builder.AddPlaceholderChunk("macro");
10366 Results.AddResult(Builder.TakeString());
10367
10368 // #elifndef <macro>
10369 Builder.AddTypedTextChunk("elifndef");
10371 Builder.AddPlaceholderChunk("macro");
10372 Results.AddResult(Builder.TakeString());
10373
10374 // #else
10375 Builder.AddTypedTextChunk("else");
10376 Results.AddResult(Builder.TakeString());
10377
10378 // #endif
10379 Builder.AddTypedTextChunk("endif");
10380 Results.AddResult(Builder.TakeString());
10381 }
10382
10383 // #include "header"
10384 Builder.AddTypedTextChunk("include");
10386 Builder.AddTextChunk("\"");
10387 Builder.AddPlaceholderChunk("header");
10388 Builder.AddTextChunk("\"");
10389 Results.AddResult(Builder.TakeString());
10390
10391 // #include <header>
10392 Builder.AddTypedTextChunk("include");
10394 Builder.AddTextChunk("<");
10395 Builder.AddPlaceholderChunk("header");
10396 Builder.AddTextChunk(">");
10397 Results.AddResult(Builder.TakeString());
10398
10399 // #define <macro>
10400 Builder.AddTypedTextChunk("define");
10402 Builder.AddPlaceholderChunk("macro");
10403 Results.AddResult(Builder.TakeString());
10404
10405 // #define <macro>(<args>)
10406 Builder.AddTypedTextChunk("define");
10408 Builder.AddPlaceholderChunk("macro");
10409 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
10410 Builder.AddPlaceholderChunk("args");
10411 Builder.AddChunk(CodeCompletionString::CK_RightParen);
10412 Results.AddResult(Builder.TakeString());
10413
10414 // #undef <macro>
10415 Builder.AddTypedTextChunk("undef");
10417 Builder.AddPlaceholderChunk("macro");
10418 Results.AddResult(Builder.TakeString());
10419
10420 // #line <number>
10421 Builder.AddTypedTextChunk("line");
10423 Builder.AddPlaceholderChunk("number");
10424 Results.AddResult(Builder.TakeString());
10425
10426 // #line <number> "filename"
10427 Builder.AddTypedTextChunk("line");
10429 Builder.AddPlaceholderChunk("number");
10431 Builder.AddTextChunk("\"");
10432 Builder.AddPlaceholderChunk("filename");
10433 Builder.AddTextChunk("\"");
10434 Results.AddResult(Builder.TakeString());
10435
10436 // #error <message>
10437 Builder.AddTypedTextChunk("error");
10439 Builder.AddPlaceholderChunk("message");
10440 Results.AddResult(Builder.TakeString());
10441
10442 // #pragma <arguments>
10443 Builder.AddTypedTextChunk("pragma");
10445 Builder.AddPlaceholderChunk("arguments");
10446 Results.AddResult(Builder.TakeString());
10447
10448 if (getLangOpts().ObjC) {
10449 // #import "header"
10450 Builder.AddTypedTextChunk("import");
10452 Builder.AddTextChunk("\"");
10453 Builder.AddPlaceholderChunk("header");
10454 Builder.AddTextChunk("\"");
10455 Results.AddResult(Builder.TakeString());
10456
10457 // #import <header>
10458 Builder.AddTypedTextChunk("import");
10460 Builder.AddTextChunk("<");
10461 Builder.AddPlaceholderChunk("header");
10462 Builder.AddTextChunk(">");
10463 Results.AddResult(Builder.TakeString());
10464 }
10465
10466 // #include_next "header"
10467 Builder.AddTypedTextChunk("include_next");
10469 Builder.AddTextChunk("\"");
10470 Builder.AddPlaceholderChunk("header");
10471 Builder.AddTextChunk("\"");
10472 Results.AddResult(Builder.TakeString());
10473
10474 // #include_next <header>
10475 Builder.AddTypedTextChunk("include_next");
10477 Builder.AddTextChunk("<");
10478 Builder.AddPlaceholderChunk("header");
10479 Builder.AddTextChunk(">");
10480 Results.AddResult(Builder.TakeString());
10481
10482 // #warning <message>
10483 Builder.AddTypedTextChunk("warning");
10485 Builder.AddPlaceholderChunk("message");
10486 Results.AddResult(Builder.TakeString());
10487
10488 if (getLangOpts().C23) {
10489 // #embed "file"
10490 Builder.AddTypedTextChunk("embed");
10492 Builder.AddTextChunk("\"");
10493 Builder.AddPlaceholderChunk("file");
10494 Builder.AddTextChunk("\"");
10495 Results.AddResult(Builder.TakeString());
10496
10497 // #embed <file>
10498 Builder.AddTypedTextChunk("embed");
10500 Builder.AddTextChunk("<");
10501 Builder.AddPlaceholderChunk("file");
10502 Builder.AddTextChunk(">");
10503 Results.AddResult(Builder.TakeString());
10504 }
10505
10506 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
10507 // completions for them. And __include_macros is a Clang-internal extension
10508 // that we don't want to encourage anyone to use.
10509
10510 // FIXME: we don't support #assert or #unassert, so don't suggest them.
10511 Results.ExitScope();
10512
10514 Results.getCompletionContext(), Results.data(),
10515 Results.size());
10516}
10517
10524
10526 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10527 CodeCompleter->getCodeCompletionTUInfo(),
10530 if (!IsDefinition && CodeCompleter->includeMacros()) {
10531 // Add just the names of macros, not their arguments.
10532 CodeCompletionBuilder Builder(Results.getAllocator(),
10533 Results.getCodeCompletionTUInfo());
10534 Results.EnterNewScope();
10535 for (const auto &M : SemaRef.PP.macros()) {
10536 Builder.AddTypedTextChunk(
10537 Builder.getAllocator().CopyString(M.first->getName()));
10538 Results.AddResult(CodeCompletionResult(
10539 Builder.TakeString(), CCP_CodePattern, CXCursor_MacroDefinition));
10540 }
10541 Results.ExitScope();
10542 } else if (IsDefinition) {
10543 // FIXME: Can we detect when the user just wrote an include guard above?
10544 }
10545
10547 Results.getCompletionContext(), Results.data(),
10548 Results.size());
10549}
10550
10552 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10553 CodeCompleter->getCodeCompletionTUInfo(),
10555
10556 if (CodeCompleter->includeMacros())
10557 AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), true);
10558
10559 // defined (<macro>)
10560 Results.EnterNewScope();
10561 CodeCompletionBuilder Builder(Results.getAllocator(),
10562 Results.getCodeCompletionTUInfo());
10563 Builder.AddTypedTextChunk("defined");
10565 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
10566 Builder.AddPlaceholderChunk("macro");
10567 Builder.AddChunk(CodeCompletionString::CK_RightParen);
10568 Results.AddResult(Builder.TakeString());
10569 Results.ExitScope();
10570
10572 Results.getCompletionContext(), Results.data(),
10573 Results.size());
10574}
10575
10577 Scope *S, IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned Argument) {
10578 // FIXME: In the future, we could provide "overload" results, much like we
10579 // do for function calls.
10580
10581 // Now just ignore this. There will be another code-completion callback
10582 // for the expanded tokens.
10583}
10584
10585// This handles completion inside an #include filename, e.g. #include <foo/ba
10586// We look for the directory "foo" under each directory on the include path,
10587// list its files, and reassemble the appropriate #include.
10589 bool Angled) {
10590 // RelDir should use /, but unescaped \ is possible on windows!
10591 // Our completions will normalize to / for simplicity, this case is rare.
10592 std::string RelDir = llvm::sys::path::convert_to_slash(Dir);
10593 // We need the native slashes for the actual file system interactions.
10594 SmallString<128> NativeRelDir = StringRef(RelDir);
10595 llvm::sys::path::native(NativeRelDir);
10596 llvm::vfs::FileSystem &FS =
10597 SemaRef.getSourceManager().getFileManager().getVirtualFileSystem();
10598
10599 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10600 CodeCompleter->getCodeCompletionTUInfo(),
10602 llvm::DenseSet<StringRef> SeenResults; // To deduplicate results.
10603
10604 // Helper: adds one file or directory completion result.
10605 auto AddCompletion = [&](StringRef Filename, bool IsDirectory) {
10606 SmallString<64> TypedChunk = Filename;
10607 // Directory completion is up to the slash, e.g. <sys/
10608 TypedChunk.push_back(IsDirectory ? '/' : Angled ? '>' : '"');
10609 auto R = SeenResults.insert(TypedChunk);
10610 if (R.second) { // New completion
10611 const char *InternedTyped = Results.getAllocator().CopyString(TypedChunk);
10612 *R.first = InternedTyped; // Avoid dangling StringRef.
10613 CodeCompletionBuilder Builder(CodeCompleter->getAllocator(),
10614 CodeCompleter->getCodeCompletionTUInfo());
10615 Builder.AddTypedTextChunk(InternedTyped);
10616 // The result is a "Pattern", which is pretty opaque.
10617 // We may want to include the real filename to allow smart ranking.
10618 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
10619 }
10620 };
10621
10622 // Helper: scans IncludeDir for nice files, and adds results for each.
10623 auto AddFilesFromIncludeDir = [&](StringRef IncludeDir,
10624 bool IsSystem,
10625 DirectoryLookup::LookupType_t LookupType) {
10626 llvm::SmallString<128> Dir = IncludeDir;
10627 if (!NativeRelDir.empty()) {
10628 if (LookupType == DirectoryLookup::LT_Framework) {
10629 // For a framework dir, #include <Foo/Bar/> actually maps to
10630 // a path of Foo.framework/Headers/Bar/.
10631 auto Begin = llvm::sys::path::begin(NativeRelDir);
10632 auto End = llvm::sys::path::end(NativeRelDir);
10633
10634 llvm::sys::path::append(Dir, *Begin + ".framework", "Headers");
10635 llvm::sys::path::append(Dir, ++Begin, End);
10636 } else {
10637 llvm::sys::path::append(Dir, NativeRelDir);
10638 }
10639 }
10640
10641 const StringRef &Dirname = llvm::sys::path::filename(Dir);
10642 const bool isQt = Dirname.starts_with("Qt") || Dirname == "ActiveQt";
10643 const bool ExtensionlessHeaders =
10644 IsSystem || isQt || Dir.ends_with(".framework/Headers") ||
10645 IncludeDir.ends_with("/include") || IncludeDir.ends_with("\\include");
10646 std::error_code EC;
10647 unsigned Count = 0;
10648 for (auto It = FS.dir_begin(Dir, EC);
10649 !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
10650 if (++Count == 2500) // If we happen to hit a huge directory,
10651 break; // bail out early so we're not too slow.
10652 StringRef Filename = llvm::sys::path::filename(It->path());
10653
10654 // To know whether a symlink should be treated as file or a directory, we
10655 // have to stat it. This should be cheap enough as there shouldn't be many
10656 // symlinks.
10657 llvm::sys::fs::file_type Type = It->type();
10658 if (Type == llvm::sys::fs::file_type::symlink_file) {
10659 if (auto FileStatus = FS.status(It->path()))
10660 Type = FileStatus->getType();
10661 }
10662 switch (Type) {
10663 case llvm::sys::fs::file_type::directory_file:
10664 // All entries in a framework directory must have a ".framework" suffix,
10665 // but the suffix does not appear in the source code's include/import.
10666 if (LookupType == DirectoryLookup::LT_Framework &&
10667 NativeRelDir.empty() && !Filename.consume_back(".framework"))
10668 break;
10669
10670 AddCompletion(Filename, /*IsDirectory=*/true);
10671 break;
10672 case llvm::sys::fs::file_type::regular_file: {
10673 // Only files that really look like headers. (Except in special dirs).
10674 const bool IsHeader = Filename.ends_with_insensitive(".h") ||
10675 Filename.ends_with_insensitive(".hh") ||
10676 Filename.ends_with_insensitive(".hpp") ||
10677 Filename.ends_with_insensitive(".hxx") ||
10678 Filename.ends_with_insensitive(".inc") ||
10679 (ExtensionlessHeaders && !Filename.contains('.'));
10680 if (!IsHeader)
10681 break;
10682 AddCompletion(Filename, /*IsDirectory=*/false);
10683 break;
10684 }
10685 default:
10686 break;
10687 }
10688 }
10689 };
10690
10691 // Helper: adds results relative to IncludeDir, if possible.
10692 auto AddFilesFromDirLookup = [&](const DirectoryLookup &IncludeDir,
10693 bool IsSystem) {
10694 switch (IncludeDir.getLookupType()) {
10696 // header maps are not (currently) enumerable.
10697 break;
10699 AddFilesFromIncludeDir(IncludeDir.getDirRef()->getName(), IsSystem,
10701 break;
10703 AddFilesFromIncludeDir(IncludeDir.getFrameworkDirRef()->getName(),
10705 break;
10706 }
10707 };
10708
10709 // Finally with all our helpers, we can scan the include path.
10710 // Do this in standard order so deduplication keeps the right file.
10711 // (In case we decide to add more details to the results later).
10712 const auto &S = SemaRef.PP.getHeaderSearchInfo();
10713 using llvm::make_range;
10714 if (!Angled) {
10715 // The current directory is on the include path for "quoted" includes.
10716 if (auto CurFile = SemaRef.PP.getCurrentFileLexer()->getFileEntry())
10717 AddFilesFromIncludeDir(CurFile->getDir().getName(), false,
10719 for (const auto &D : make_range(S.quoted_dir_begin(), S.quoted_dir_end()))
10720 AddFilesFromDirLookup(D, false);
10721 }
10722 for (const auto &D : make_range(S.angled_dir_begin(), S.angled_dir_end()))
10723 AddFilesFromDirLookup(D, false);
10724 for (const auto &D : make_range(S.system_dir_begin(), S.system_dir_end()))
10725 AddFilesFromDirLookup(D, true);
10726
10728 Results.getCompletionContext(), Results.data(),
10729 Results.size());
10730}
10731
10737
10739 ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10740 CodeCompleter->getCodeCompletionTUInfo(),
10742 Results.EnterNewScope();
10743 static const char *Platforms[] = {"macOS", "iOS", "watchOS", "tvOS"};
10744 for (const char *Platform : llvm::ArrayRef(Platforms)) {
10745 Results.AddResult(CodeCompletionResult(Platform));
10746 Results.AddResult(CodeCompletionResult(Results.getAllocator().CopyString(
10747 Twine(Platform) + "ApplicationExtension")));
10748 }
10749 Results.ExitScope();
10751 Results.getCompletionContext(), Results.data(),
10752 Results.size());
10753}
10754
10756 CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
10758 ResultBuilder Builder(SemaRef, Allocator, CCTUInfo,
10760 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
10761 CodeCompletionDeclConsumer Consumer(
10762 Builder, getASTContext().getTranslationUnitDecl());
10763 SemaRef.LookupVisibleDecls(getASTContext().getTranslationUnitDecl(),
10764 Sema::LookupAnyName, Consumer,
10765 !CodeCompleter || CodeCompleter->loadExternal());
10766 }
10767
10768 if (!CodeCompleter || CodeCompleter->includeMacros())
10769 AddMacroResults(SemaRef.PP, Builder,
10770 !CodeCompleter || CodeCompleter->loadExternal(), true);
10771
10772 Results.clear();
10773 Results.insert(Results.end(), Builder.data(),
10774 Builder.data() + Builder.size());
10775}
10776
10778 CodeCompleteConsumer *CompletionConsumer)
10779 : SemaBase(S), CodeCompleter(CompletionConsumer),
10780 Resolver(S.getASTContext()) {}
This file provides AST data structures related to concepts.
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc)
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines Expressions and AST nodes for C++2a concepts.
bool Optional
Is optional and can be removed.
Token Tok
The Token.
Result
Implement __builtin_bit_cast and related operations.
#define X(type, name)
Definition Value.h:97
llvm::MachO::Record Record
Definition MachO.h:31
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines an enumeration for C++ overloaded operators.
Defines the clang::Preprocessor interface.
static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity, TemplateSpecCandidateSet *FailedTSC)
Determines whether the accessed entity is accessible.
CastType
Definition SemaCast.cpp:50
static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results, unsigned NumSelIdents)
Given a set of code-completion results for the argument of a message send, determine the preferred ty...
static void printOverrideString(const CodeCompletionString &CCS, std::string &BeforeName, std::string &NameAndSignature)
static bool isConstructor(const Decl *ND)
static void findTypeLocationForBlockDecl(const TypeSourceInfo *TSInfo, FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto, bool SuppressBlock=false)
Tries to find the most appropriate type location for an Objective-C block placeholder.
static bool isObjCReceiverType(ASTContext &C, QualType T)
static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results, bool LoadExternal, bool IncludeUndefined, bool TargetTypeIsPointer=false)
static std::string formatTemplateParameterPlaceholder(const NamedDecl *Param, bool &Optional, const PrintingPolicy &Policy)
static std::string formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl, FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto, bool SuppressBlockName=false, bool SuppressBlock=false, std::optional< ArrayRef< QualType > > ObjCSubsts=std::nullopt)
Returns a placeholder string that corresponds to an Objective-C block declaration.
static void AddQualifierToCompletionString(CodeCompletionBuilder &Result, NestedNameSpecifier Qualifier, bool QualifierIsInformative, ASTContext &Context, const PrintingPolicy &Policy)
Add a qualifier to the given code-completion string, if the provided nested-name-specifier is non-NUL...
static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt)
llvm::SmallPtrSet< const IdentifierInfo *, 16 > AddedPropertiesSet
The set of properties that have already been added, referenced by property name.
static bool argMatchesTemplateParams(const ParsedTemplateArgument &Arg, unsigned Index, const TemplateParameterList &Params)
static void setInBaseClass(ResultBuilder::Result &R)
static void AddObjCMethods(ObjCContainerDecl *Container, bool WantInstanceMethods, ObjCMethodKind WantKind, ArrayRef< const IdentifierInfo * > SelIdents, DeclContext *CurContext, VisitedSelectorSet &Selectors, bool AllowSameLength, ResultBuilder &Results, bool InOriginalClass=true, bool IsRootClass=false)
Add all of the Objective-C methods in the given Objective-C container to the set of results.
static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef)
static CodeCompletionString * createTemplateSignatureString(const TemplateDecl *TD, CodeCompletionBuilder &Builder, unsigned CurrentArg, const PrintingPolicy &Policy)
static QualType getParamType(Sema &SemaRef, ArrayRef< ResultCandidate > Candidates, unsigned N)
Get the type of the Nth parameter from a given set of overload candidates.
static void AddStorageSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC, const LangOptions &LangOpts, ResultBuilder &Results)
static const NamedDecl * extractFunctorCallOperator(const NamedDecl *ND)
static void AddFunctionSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC, const LangOptions &LangOpts, ResultBuilder &Results)
static QualType ProduceSignatureHelp(Sema &SemaRef, MutableArrayRef< ResultCandidate > Candidates, unsigned CurrentArg, SourceLocation OpenParLoc, bool Braced)
static std::string FormatFunctionParameter(const PrintingPolicy &Policy, const DeclaratorDecl *Param, bool SuppressName=false, bool SuppressBlock=false, std::optional< ArrayRef< QualType > > ObjCSubsts=std::nullopt)
static void AddFunctionParameterChunks(Preprocessor &PP, const PrintingPolicy &Policy, const FunctionDecl *Function, CodeCompletionBuilder &Result, unsigned Start=0, bool InOptional=false, bool FunctionCanBeCall=true, bool IsInDeclarationContext=false)
Add function parameter chunks to the given code completion string.
static RecordDecl * getAsRecordDecl(QualType BaseType, HeuristicResolver &Resolver)
static void AddOverrideResults(ResultBuilder &Results, const CodeCompletionContext &CCContext, CodeCompletionBuilder &Builder)
static std::string formatObjCParamQualifiers(unsigned ObjCQuals, QualType &Type)
llvm::SmallPtrSet< Selector, 16 > VisitedSelectorSet
A set of selectors, which is used to avoid introducing multiple completions with the same selector in...
static void AddOverloadAggregateChunks(const RecordDecl *RD, const PrintingPolicy &Policy, CodeCompletionBuilder &Result, unsigned CurrentArg)
static void AddTypedefResult(ResultBuilder &Results)
static void AddPrettyFunctionResults(const LangOptions &LangOpts, ResultBuilder &Results)
static void AddObjCPassingTypeChunk(QualType Type, unsigned ObjCDeclQuals, ASTContext &Context, const PrintingPolicy &Policy, CodeCompletionBuilder &Builder)
Add the parenthesized return or parameter type chunk to a code completion string.
static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, bool IsInstanceMethod, QualType ReturnType, ASTContext &Context, VisitedSelectorSet &KnownSelectors, ResultBuilder &Results)
Add code completions for Objective-C Key-Value Coding (KVC) and Key-Value Observing (KVO).
static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt)
static QualType getDesignatedType(ASTContext &Context, QualType BaseType, const Designation &Desig, HeuristicResolver &Resolver, llvm::function_ref< const FieldDecl *(RecordDecl *, const Designator &)> LookupField)
static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag)
Determine whether the addition of the given flag to an Objective-C property's attributes will cause a...
static void AddEnumerators(ResultBuilder &Results, ASTContext &Context, EnumDecl *Enum, DeclContext *CurContext, const CoveredEnumerators &Enumerators)
llvm::DenseMap< Selector, llvm::PointerIntPair< ObjCMethodDecl *, 1, bool > > KnownMethodsMap
static const FunctionProtoType * TryDeconstructFunctionLike(QualType T)
Try to find a corresponding FunctionProtoType for function-like types (e.g.
static DeclContext::lookup_result getConstructors(ASTContext &Context, const CXXRecordDecl *Record)
static void AddResultTypeChunk(ASTContext &Context, const PrintingPolicy &Policy, const NamedDecl *ND, QualType BaseType, CodeCompletionBuilder &Result)
If the given declaration has an associated type, add it as a result type chunk.
static void AddObjCVisibilityResults(const LangOptions &LangOpts, ResultBuilder &Results, bool NeedAt)
static void addThisCompletion(Sema &S, ResultBuilder &Results)
Add a completion for "this", if we're in a member function.
static NestedNameSpecifier getRequiredQualification(ASTContext &Context, const DeclContext *CurContext, const DeclContext *TargetContext)
Compute the qualification required to get from the current context (CurContext) to the target context...
static void AddObjCImplementationResults(const LangOptions &LangOpts, ResultBuilder &Results, bool NeedAt)
static ObjCMethodDecl * AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword, ArrayRef< const IdentifierInfo * > SelIdents, ResultBuilder &Results)
static void AddRecordMembersCompletionResults(Sema &SemaRef, ResultBuilder &Results, Scope *S, QualType BaseType, ExprValueKind BaseKind, RecordDecl *RD, std::optional< FixItHint > AccessOpFixIt)
static void AddObjCBlockCall(ASTContext &Context, const PrintingPolicy &Policy, CodeCompletionBuilder &Builder, const NamedDecl *BD, const FunctionTypeLoc &BlockLoc, const FunctionProtoTypeLoc &BlockProtoLoc)
Adds a block invocation code completion result for the given block declaration BD.
static void AddLambdaCompletion(ResultBuilder &Results, llvm::ArrayRef< QualType > Parameters, const LangOptions &LangOpts)
Adds a pattern completion for a lambda expression with the specified parameter types and placeholders...
static void AddTypeSpecifierResults(const LangOptions &LangOpts, ResultBuilder &Results)
Add type specifiers for the current language as keyword results.
static std::optional< unsigned > getNextAggregateIndexAfterDesignatedInit(const ResultCandidate &Aggregate, ArrayRef< Expr * > Args)
static std::string GetDefaultValueString(const ParmVarDecl *Param, const SourceManager &SM, const LangOptions &LangOpts)
static void AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result, const FunctionDecl *Function, bool AsInformativeChunks=true)
static CodeCompletionContext mapCodeCompletionContext(Sema &S, SemaCodeCompletion::ParserCompletionContext PCC)
static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext, bool OnlyForwardDeclarations, bool OnlyUnimplemented, ResultBuilder &Results)
Add all of the Objective-C interface declarations that we find in the given (translation unit) contex...
static OverloadCompare compareOverloads(const CXXMethodDecl &Candidate, const CXXMethodDecl &Incumbent, const Qualifiers &ObjectQuals, ExprValueKind ObjectKind, const ASTContext &Ctx)
static const FieldDecl * lookupDirectField(RecordDecl *RD, const Designator &D)
static void AddTemplateParameterChunks(ASTContext &Context, const PrintingPolicy &Policy, const TemplateDecl *Template, CodeCompletionBuilder &Result, unsigned MaxParameters=0, unsigned Start=0, bool InDefaultArg=false, bool AsInformativeChunk=false)
Add template parameter chunks to the given code completion string.
static void FindImplementableMethods(ASTContext &Context, ObjCContainerDecl *Container, std::optional< bool > WantInstanceMethods, QualType ReturnType, KnownMethodsMap &KnownMethods, bool InOriginalClass=true)
Find all of the methods that reside in the given container (and its superclasses, protocols,...
static bool anyNullArguments(ArrayRef< Expr * > Args)
static const char * noUnderscoreAttrScope(llvm::StringRef Scope)
static void AddFunctionTypeQuals(CodeCompletionBuilder &Result, const Qualifiers Quals, bool AsInformativeChunk=true)
static void MaybeAddSentinel(Preprocessor &PP, const NamedDecl *FunctionOrMethod, CodeCompletionBuilder &Result)
static void AddOverloadParameterChunks(ASTContext &Context, const PrintingPolicy &Policy, const FunctionDecl *Function, const FunctionProtoType *Prototype, FunctionProtoTypeLoc PrototypeLoc, CodeCompletionBuilder &Result, unsigned CurrentArg, unsigned Start=0, bool InOptional=false)
Add function overload parameter chunks to the given code completion string.
static void AddObjCProperties(const CodeCompletionContext &CCContext, ObjCContainerDecl *Container, bool AllowCategories, bool AllowNullaryMethods, DeclContext *CurContext, AddedPropertiesSet &AddedProperties, ResultBuilder &Results, bool IsBaseExprStatement=false, bool IsClassProperty=false, bool InOriginalClass=true)
static void HandleCodeCompleteResults(Sema *S, CodeCompleteConsumer *CodeCompleter, const CodeCompletionContext &Context, CodeCompletionResult *Results, unsigned NumResults)
static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results, const LangOptions &LangOpts)
static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, ResultBuilder &Results)
If we're in a C++ virtual member function, add completion results that invoke the functions we overri...
static ObjCContainerDecl * getContainerDef(ObjCContainerDecl *Container)
Retrieve the container definition, if any?
static const char * underscoreAttrScope(llvm::StringRef Scope)
static bool isAcceptableObjCMethod(ObjCMethodDecl *Method, ObjCMethodKind WantKind, ArrayRef< const IdentifierInfo * > SelIdents, bool AllowSameLength=true)
static void AddFunctionExceptSpecToCompletionString(std::string &NameAndSignature, const FunctionDecl *Function)
static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt)
static bool WantTypesInContext(SemaCodeCompletion::ParserCompletionContext CCC, const LangOptions &LangOpts)
CodeCompleteConsumer::OverloadCandidate ResultCandidate
static std::string templateResultType(const TemplateDecl *TD, const PrintingPolicy &Policy)
static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, const NamedDecl *ND, CodeCompletionBuilder &Result)
Add the name of the given declaration.
static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression, bool IsSuper, ResultBuilder &Results)
static const char * GetCompletionTypeString(QualType T, ASTContext &Context, const PrintingPolicy &Policy, CodeCompletionAllocator &Allocator)
Retrieve the string representation of the given type as a string that has the appropriate lifetime fo...
static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, StringRef Name)
Determine whether the given class is or inherits from a class by the given name.
#define OBJC_AT_KEYWORD_NAME(NeedAt, Keyword)
Macro that optionally prepends an "@" to the string literal passed in via Keyword,...
static bool isAcceptableObjCSelector(Selector Sel, ObjCMethodKind WantKind, ArrayRef< const IdentifierInfo * > SelIdents, bool AllowSameLength=true)
static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS, tok::TokenKind Op)
static void AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, Scope *S, Sema &SemaRef, ResultBuilder &Results)
Add language constructs that show up for "ordinary" names.
static QualType getPreferredTypeOfUnaryArg(Sema &S, QualType ContextType, tok::TokenKind Op)
Get preferred type for an argument of an unary expression.
static void AddUsingAliasResult(CodeCompletionBuilder &Builder, ResultBuilder &Results)
static ObjCInterfaceDecl * GetAssumedMessageSendExprType(Expr *E)
When we have an expression with type "id", we may assume that it has some more-specific class type ba...
ObjCMethodKind
Describes the kind of Objective-C method that we want to find via code completion.
@ MK_OneArgSelector
One-argument selector.
@ MK_ZeroArgSelector
Zero-argument (unary) selector.
@ MK_Any
Any kind of method, provided it means other specified criteria.
static void mergeCandidatesWithResults(Sema &SemaRef, SmallVectorImpl< ResultCandidate > &Results, OverloadCandidateSet &CandidateSet, SourceLocation Loc, size_t ArgSize)
static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext, bool OnlyForwardDeclarations, ResultBuilder &Results)
Add all of the protocol declarations that we find in the given (translation unit) context.
static void AddStaticAssertResult(CodeCompletionBuilder &Builder, ResultBuilder &Results, const LangOptions &LangOpts)
static void AddObjCInterfaceResults(const LangOptions &LangOpts, ResultBuilder &Results, bool NeedAt)
static bool isNamespaceScope(Scope *S)
Determine whether this scope denotes a namespace.
static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context, const Preprocessor &PP)
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
static TemplateDecl * getDescribedTemplate(Decl *Templated)
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
friend bool operator!=(const iterator &X, const iterator &Y)
iterator(const NamedDecl *SingleDecl, unsigned Index)
iterator(const DeclIndexPair *Iterator)
friend bool operator==(const iterator &X, const iterator &Y)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CanQualType BoolTy
CanQualType IntTy
QualType getTagType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TagDecl *TD, bool OwnsTag) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const RawComment * getRawCommentForAnyRedecl(RawCommentLookupKey Key, const Decl **OriginalDecl=nullptr) const
Return the documentation comment attached to a given declaration or macro.
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
bool isUsable() const
Definition Ownership.h:169
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3813
QualType getElementType() const
Definition TypeBase.h:3825
Syntax
The style used to specify an attribute.
Type source information for an attributed type.
Definition TypeLoc.h:1008
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4810
Wrapper for source info for block pointers.
Definition TypeLoc.h:1557
Pointer to a block type.
Definition TypeBase.h:3646
This class is used for builtin types like 'int'.
Definition TypeBase.h:3241
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents a C++ constructor within a class.
Definition DeclCXX.h:2642
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4022
DeclarationName getMember() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4061
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2150
overridden_method_range overridden_methods() const
Definition DeclCXX.cpp:2828
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
Definition DeclCXX.h:2343
Qualifiers getMethodQualifiers() const
Definition DeclCXX.h:2328
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isAggregate() const
Determine whether this class is an aggregate (C++ [dcl.init.aggr]), which is a class with no user-dec...
Definition DeclCXX.h:1153
base_class_range bases()
Definition DeclCXX.h:609
CXXRecordDecl * getDefinition() const
Definition DeclCXX.h:549
base_class_range vbases()
Definition DeclCXX.h:626
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:523
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Represents a C++ nested-name-specifier or a global scope specifier.
Definition DeclSpec.h:76
NestedNameSpecifier getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Definition DeclSpec.h:97
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition DeclSpec.h:186
bool isEmpty() const
No scope specifier.
Definition DeclSpec.h:181
Expr * getCallee()
Definition Expr.h:3134
arg_range arguments()
Definition Expr.h:3239
bool isNull() const
CaseStmt - Represent a case statement.
Definition Stmt.h:1932
Expr * getLHS()
Definition Stmt.h:2015
Represents a byte-granular source range.
static CharSourceRange getTokenRange(SourceRange R)
Declaration of a class template.
CodeCompletionString * CreateSignatureString(unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments, bool Braced) const
Create a new code-completion string that describes the function signature of this overload candidate.
const FunctionType * getFunctionType() const
Retrieve the function type of the entity, regardless of how the function is stored.
CandidateKind getKind() const
Determine the kind of overload candidate.
const RecordDecl * getAggregate() const
Retrieve the aggregate type being initialized.
FunctionDecl * getFunction() const
Retrieve the function overload candidate or the templated function declaration for a function templat...
const FunctionProtoTypeLoc getFunctionProtoTypeLoc() const
Retrieve the function ProtoTypeLoc candidate.
@ CK_Aggregate
The candidate is aggregate initialization of a record type.
@ CK_Template
The candidate is a template, template arguments are being completed.
unsigned getNumParams() const
Get the number of parameters in this signature.
Abstract interface for a consumer of code-completion information.
bool includeGlobals() const
Whether to include global (top-level) declaration results.
virtual void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, CodeCompletionResult *Results, unsigned NumResults)
Process the finalized code-completion results.
bool loadExternal() const
Hint whether to load data from the external AST in order to provide full results.
virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, unsigned NumCandidates, SourceLocation OpenParLoc, bool Braced)
An allocator used specifically for the purpose of code completion.
const char * CopyString(const Twine &String)
Copy the given string into this allocator.
A builder class used to construct new code-completion strings.
CodeCompletionString * TakeString()
Take the resulting completion string.
void AddPlaceholderChunk(const char *Placeholder)
Add a new placeholder chunk.
void AddTextChunk(const char *Text)
Add a new text chunk.
void AddCurrentParameterChunk(const char *CurrentParameter)
Add a new current-parameter chunk.
void AddOptionalChunk(CodeCompletionString *Optional)
Add a new optional chunk.
void AddTypedTextChunk(const char *Text)
Add a new typed-text chunk.
void AddChunk(CodeCompletionString::ChunkKind CK, const char *Text="")
Add a new chunk.
CodeCompletionAllocator & getAllocator() const
Retrieve the allocator into which the code completion strings should be allocated.
The context in which code completion occurred, so that the code-completion consumer can process the r...
Kind getKind() const
Retrieve the kind of code-completion context.
void setCXXScopeSpecifier(CXXScopeSpec SS)
Sets the scope specifier that comes before the completion token.
@ CCC_TypeQualifiers
Code completion within a type-qualifier list.
@ CCC_ObjCMessageReceiver
Code completion occurred where an Objective-C message receiver is expected.
@ CCC_PreprocessorExpression
Code completion occurred within a preprocessor expression.
@ CCC_ObjCCategoryName
Code completion where an Objective-C category name is expected.
@ CCC_ObjCIvarList
Code completion occurred within the instance variable list of an Objective-C interface,...
@ CCC_Statement
Code completion occurred where a statement (or declaration) is expected in a function,...
@ CCC_Type
Code completion occurred where a type name is expected.
@ CCC_ArrowMemberAccess
Code completion occurred on the right-hand side of a member access expression using the arrow operato...
@ CCC_ClassStructUnion
Code completion occurred within a class, struct, or union.
@ CCC_ObjCInterface
Code completion occurred within an Objective-C interface, protocol, or category interface.
@ CCC_ObjCPropertyAccess
Code completion occurred on the right-hand side of an Objective-C property access expression.
@ CCC_Expression
Code completion occurred where an expression is expected.
@ CCC_SelectorName
Code completion for a selector, as in an @selector expression.
@ CCC_TopLevelOrExpression
Code completion at a top level, i.e.
@ CCC_EnumTag
Code completion occurred after the "enum" keyword, to indicate an enumeration name.
@ CCC_UnionTag
Code completion occurred after the "union" keyword, to indicate a union name.
@ CCC_ParenthesizedExpression
Code completion in a parenthesized expression, which means that we may also have types here in C and ...
@ CCC_TopLevel
Code completion occurred within a "top-level" completion context, e.g., at namespace or global scope.
@ CCC_ClassOrStructTag
Code completion occurred after the "struct" or "class" keyword, to indicate a struct or class name.
@ CCC_ObjCClassMessage
Code completion where an Objective-C class message is expected.
@ CCC_ObjCImplementation
Code completion occurred within an Objective-C implementation or category implementation.
@ CCC_IncludedFile
Code completion inside the filename part of a include directive.
@ CCC_ObjCInstanceMessage
Code completion where an Objective-C instance message is expected.
@ CCC_SymbolOrNewName
Code completion occurred where both a new name and an existing symbol is permissible.
@ CCC_Recovery
An unknown context, in which we are recovering from a parsing error and don't know which completions ...
@ CCC_ObjCProtocolName
Code completion occurred where a protocol name is expected.
@ CCC_NewName
Code completion occurred where a new name is expected.
@ CCC_MacroNameUse
Code completion occurred where a macro name is expected (without any arguments, in the case of a func...
@ CCC_Symbol
Code completion occurred where an existing name(such as type, functionor variable) is expected.
@ CCC_Attribute
Code completion of an attribute name.
@ CCC_Other
An unspecified code-completion context.
@ CCC_DotMemberAccess
Code completion occurred on the right-hand side of a member access expression using the dot operator.
@ CCC_MacroName
Code completion occurred where an macro is being defined.
@ CCC_Namespace
Code completion occurred where a namespace or namespace alias is expected.
@ CCC_PreprocessorDirective
Code completion occurred where a preprocessor directive is expected.
@ CCC_NaturalLanguage
Code completion occurred in a context where natural language is expected, e.g., a comment or string l...
@ CCC_ObjCInterfaceName
Code completion where the name of an Objective-C class is expected.
QualType getBaseType() const
Retrieve the type of the base object in a member-access expression.
bool wantConstructorResults() const
Determines whether we want C++ constructors as results within this context.
Captures a result of code completion.
bool DeclaringEntity
Whether we're completing a declaration of the given entity, rather than a use of that entity.
ResultKind Kind
The kind of result stored here.
const char * Keyword
When Kind == RK_Keyword, the string representing the keyword or symbol's spelling.
CXAvailabilityKind Availability
The availability of this result.
CodeCompletionString * CreateCodeCompletionString(Sema &S, const CodeCompletionContext &CCContext, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments)
Create a new code-completion string that describes how to insert this result into a program.
bool QualifierIsInformative
Whether this result was found via lookup into a base class.
NestedNameSpecifier Qualifier
If the result should have a nested-name-specifier, this is it.
const NamedDecl * Declaration
When Kind == RK_Declaration or RK_Pattern, the declaration we are referring to.
CodeCompletionString * createCodeCompletionStringForDecl(Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, bool IncludeBriefComments, const CodeCompletionContext &CCContext, PrintingPolicy &Policy)
CodeCompletionString * CreateCodeCompletionStringForMacro(Preprocessor &PP, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo)
Creates a new code-completion string for the macro result.
unsigned StartParameter
Specifies which parameter (of a function, Objective-C method, macro, etc.) we should start with when ...
unsigned Priority
The priority of this particular code-completion result.
bool StartsNestedNameSpecifier
Whether this declaration is the beginning of a nested-name-specifier and, therefore,...
CodeCompletionString * Pattern
When Kind == RK_Pattern, the code-completion string that describes the completion text to insert.
bool FunctionCanBeCall
When completing a function, whether it can be a call.
bool AllParametersAreInformative
Whether all parameters (of a function, Objective-C method, etc.) should be considered "informative".
CodeCompletionString * createCodeCompletionStringForOverride(Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, bool IncludeBriefComments, const CodeCompletionContext &CCContext, PrintingPolicy &Policy)
const IdentifierInfo * Macro
When Kind == RK_Macro, the identifier that refers to a macro.
@ RK_Pattern
Refers to a precomputed pattern.
@ RK_Declaration
Refers to a declaration.
@ RK_Keyword
Refers to a keyword or symbol.
A "string" used to describe how code completion can be performed for an entity.
@ CK_Optional
A code completion string that is entirely optional.
@ CK_CurrentParameter
A piece of text that describes the parameter that corresponds to the code-completion location within ...
@ CK_Comma
A comma separator (',').
@ CK_Placeholder
A string that acts as a placeholder for, e.g., a function call argument.
@ CK_LeftParen
A left parenthesis ('(').
@ CK_HorizontalSpace
Horizontal whitespace (' ').
@ CK_RightAngle
A right angle bracket ('>').
@ CK_LeftBracket
A left bracket ('[').
@ CK_RightParen
A right parenthesis (')').
@ CK_RightBrace
A right brace ('}').
@ CK_VerticalSpace
Vertical whitespace ('\n' or '\r\n', depending on the platform).
@ CK_TypedText
The piece of text that the user is expected to type to match the code-completion string,...
@ CK_RightBracket
A right bracket (']').
@ CK_LeftAngle
A left angle bracket ('<').
Expr * getConstraintExpr() const
const TypeClass * getTypePtr() const
Definition TypeLoc.h:433
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition DeclBase.h:2443
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition DeclBase.h:2279
bool isRequiresExprBody() const
Definition DeclBase.h:2231
bool isFileContext() const
Definition DeclBase.h:2217
DeclContextLookupResult lookup_result
Definition DeclBase.h:2627
ASTContext & getParentASTContext() const
Definition DeclBase.h:2155
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isTranslationUnit() const
Definition DeclBase.h:2222
bool isRecord() const
Definition DeclBase.h:2226
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
decl_iterator decls_end() const
Definition DeclBase.h:2425
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition DeclBase.h:2423
bool isFunctionOrMethod() const
Returns true if this DeclContext is a function, Objective-C method, or block, or a DeclContext that c...
Definition DeclBase.h:2181
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context semantically encloses the declaration context DC.
decl_iterator decls_begin() const
iterator begin()
Definition DeclGroup.h:95
Captures information about "declaration specifiers".
Definition DeclSpec.h:220
static const TST TST_typename
Definition DeclSpec.h:279
TST getTypeSpecType() const
Definition DeclSpec.h:522
static const TST TST_interface
Definition DeclSpec.h:277
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
Definition DeclSpec.h:602
static const TST TST_union
Definition DeclSpec.h:275
TSC getTypeSpecComplex() const
Definition DeclSpec.h:518
ParsedType getRepAsType() const
Definition DeclSpec.h:532
static const TST TST_enum
Definition DeclSpec.h:274
static const TST TST_class
Definition DeclSpec.h:278
TypeSpecifierType TST
Definition DeclSpec.h:250
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
Definition DeclSpec.cpp:442
bool isTypeAltiVecVector() const
Definition DeclSpec.h:523
TypeSpecifierSign getTypeSpecSign() const
Definition DeclSpec.h:519
static const TST TST_struct
Definition DeclSpec.h:276
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
Definition DeclBase.h:1243
T * getAttr() const
Definition DeclBase.h:581
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
@ FOK_Undeclared
A friend of a previously-undeclared entity.
Definition DeclBase.h:1236
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition DeclBase.cpp:273
ObjCDeclQualifier
ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...
Definition DeclBase.h:198
@ OBJC_TQ_CSNullability
The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...
Definition DeclBase.h:210
unsigned getIdentifierNamespace() const
Definition DeclBase.h:906
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition DeclBase.h:567
SourceLocation getLocation() const
Definition DeclBase.h:447
@ IDNS_Ordinary
Ordinary names.
Definition DeclBase.h:144
@ IDNS_Member
Members, declared with object declarations within tag definitions.
Definition DeclBase.h:136
@ IDNS_ObjCProtocol
Objective C @protocol.
Definition DeclBase.h:147
@ IDNS_Namespace
Namespaces, declared with 'namespace foo {}'.
Definition DeclBase.h:140
@ IDNS_LocalExtern
This declaration is a function-local extern declaration of a variable or function.
Definition DeclBase.h:175
@ IDNS_Tag
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
Definition DeclBase.h:125
DeclContext * getDeclContext()
Definition DeclBase.h:456
AccessSpecifier getAccess() const
Definition DeclBase.h:515
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:935
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:995
Kind getKind() const
Definition DeclBase.h:450
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
QualType getCXXNameType() const
If this name is one of the C++ names (of a constructor, destructor, or conversion function),...
NameKind getNameKind() const
Determine what kind of name this is.
bool isIdentifier() const
Predicate functions for querying what type of name this is.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:781
Information about one declarator, including the parsed type information and the identifier.
Definition DeclSpec.h:1952
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
Definition DeclSpec.h:2508
DeclaratorContext getContext() const
Definition DeclSpec.h:2124
bool isCtorOrDtor()
Returns true if this declares a constructor or a destructor.
Definition DeclSpec.cpp:410
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
Definition DeclSpec.h:2118
bool isStaticMember()
Returns true if this declares a static member.
Definition DeclSpec.cpp:389
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
Definition DeclSpec.h:2539
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition ExprCXX.h:3615
DeclarationName getDeclName() const
Retrieve the name that this expression refers to.
Definition ExprCXX.h:3602
Designation - Represent a full designation, which is a sequence of designators.
Definition Designator.h:221
const Designator & getDesignator(unsigned Idx) const
Definition Designator.h:232
unsigned getNumDesignators() const
Definition Designator.h:231
Designator - A designator in a C99 designated initializer.
Definition Designator.h:38
const IdentifierInfo * getFieldDecl() const
Definition Designator.h:123
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
virtual bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Represents an enum.
Definition Decl.h:4146
This represents one expression.
Definition Expr.h:113
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition Expr.cpp:3128
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:195
QualType getType() const
Definition Expr.h:145
virtual Selector GetExternalSelector(uint32_t ID)
Resolve a selector ID into a selector.
virtual uint32_t GetNumExternalSelectors()
Returns the number of selectors known to the external AST source.
Represents a member of a struct/union/class.
Definition Decl.h:3295
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition Diagnostic.h:140
Represents a function declaration or definition.
Definition Decl.h:2059
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2928
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to call this function.
Definition Decl.cpp:3889
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2905
bool isVariadic() const
Whether this function is variadic.
Definition Decl.cpp:3119
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3868
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5409
ExceptionSpecInfo getExceptionSpecInfo() const
Return all the available information about this type's exception spec.
Definition TypeBase.h:5742
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5813
Declaration of a template function.
Wrapper for source info for functions.
Definition TypeLoc.h:1675
unsigned getNumParams() const
Definition TypeLoc.h:1747
ParmVarDecl * getParam(unsigned i) const
Definition TypeLoc.h:1753
TypeLoc getReturnLoc() const
Definition TypeLoc.h:1756
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4605
QualType getReturnType() const
Definition TypeBase.h:4945
QualType simplifyType(QualType Type, const Expr *E, bool UnwrapPointer)
TagDecl * resolveTypeToTagDecl(QualType T) const
QualType resolveExprToType(const Expr *E) const
One of these records is kept for each identifier that is lexed.
unsigned getLength() const
Efficiently return the length of this identifier info.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef deuglifiedName() const
If the identifier is an "uglified" reserved name, return a cleaned form.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
const TypeClass * getTypePtr() const
Definition TypeLoc.h:526
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Definition Lexer.cpp:1075
Represents the results of name lookup.
Definition Lookup.h:147
Encapsulates the data about a macro definition (e.g.
Definition MacroInfo.h:40
bool isC99Varargs() const
Definition MacroInfo.h:208
bool isFunctionLike() const
Definition MacroInfo.h:202
param_iterator param_begin() const
Definition MacroInfo.h:183
IdentifierInfo *const * param_iterator
Parameters - The list of parameters for a function-like macro.
Definition MacroInfo.h:181
bool isVariadic() const
Definition MacroInfo.h:210
param_iterator param_end() const
Definition MacroInfo.h:184
bool isUsedForHeaderGuard() const
Determine whether this macro was used for a header guard.
Definition MacroInfo.h:295
Describes a module or submodule.
Definition Module.h:340
@ AllVisible
All of the names in this module are visible.
Definition Module.h:647
ModuleKind Kind
The kind of this module.
Definition Module.h:385
llvm::iterator_range< submodule_iterator > submodules()
Definition Module.h:1067
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition Module.h:381
@ ModulePartitionInterface
This is a C++20 module partition interface.
Definition Module.h:366
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition Module.h:360
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition Module.h:376
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition Module.h:373
This represents a decl that may have a name.
Definition Decl.h:275
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition Decl.h:488
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:296
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:302
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Definition Decl.h:318
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine if the declaration obeys the reserved identifier rules of the given language.
Definition Decl.cpp:1133
Represent a C++ namespace.
Definition Decl.h:593
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
ObjCCategoryDecl - Represents a category declaration.
Definition DeclObjC.h:2335
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2551
ObjCContainerDecl - Represents a container for method declarations.
Definition DeclObjC.h:954
method_range methods() const
Definition DeclObjC.h:1022
instprop_range instance_properties() const
Definition DeclObjC.h:988
classprop_range class_properties() const
Definition DeclObjC.h:1005
Captures information about "declaration specifiers" specific to Objective-C.
Definition DeclSpec.h:911
ObjCPropertyAttribute::Kind getPropertyAttributes() const
Definition DeclSpec.h:945
ObjCDeclQualifier getObjCDeclQualifier() const
Definition DeclSpec.h:935
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2603
Represents an ObjC class declaration.
Definition DeclObjC.h:1160
bool hasDefinition() const
Determine whether this class has been defined.
Definition DeclObjC.h:1534
protocol_range protocols() const
Definition DeclObjC.h:1365
known_categories_range known_categories() const
Definition DeclObjC.h:1693
ObjCImplementationDecl * getImplementation() const
visible_categories_range visible_categories() const
Definition DeclObjC.h:1659
ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.cpp:349
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1958
ObjCList - This is a simple template class used to hold various lists of decls etc,...
Definition DeclObjC.h:82
iterator end() const
Definition DeclObjC.h:91
iterator begin() const
Definition DeclObjC.h:90
T *const * iterator
Definition DeclObjC.h:88
@ SuperInstance
The receiver is the instance of the superclass object.
Definition ExprObjC.h:986
@ Instance
The receiver is an object instance.
Definition ExprObjC.h:980
@ SuperClass
The receiver is a superclass.
Definition ExprObjC.h:983
@ Class
The receiver is a class.
Definition ExprObjC.h:977
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
unsigned param_size() const
Definition DeclObjC.h:350
param_const_iterator param_end() const
Definition DeclObjC.h:361
param_const_iterator param_begin() const
Definition DeclObjC.h:357
bool isVariadic() const
Definition DeclObjC.h:434
const ParmVarDecl *const * param_const_iterator
Definition DeclObjC.h:352
Selector getSelector() const
Definition DeclObjC.h:330
bool isInstanceMethod() const
Definition DeclObjC.h:429
ParmVarDecl *const * param_iterator
Definition DeclObjC.h:353
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
Definition TypeBase.h:8080
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
Definition TypeBase.h:8132
qual_range quals() const
Definition TypeBase.h:8199
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:734
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)
Lookup a property by name in the specified DeclContext.
Definition DeclObjC.cpp:176
Selector getGetterName() const
Definition DeclObjC.h:891
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2090
void * getAsOpaquePtr() const
Definition Ownership.h:91
PtrTy get() const
Definition Ownership.h:81
static OpaquePtr make(QualType P)
Definition Ownership.h:61
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
Definition Overload.h:1161
@ CSK_CodeCompletion
When doing overload resolution during code completion, we want to show all viable candidates,...
Definition Overload.h:1191
CandidateSetKind getKind() const
Definition Overload.h:1350
Represents a parameter to a function.
Definition Decl.h:1820
Represents the parsed form of a C++ template argument.
KindType getKind() const
Determine what kind of template argument we have.
@ Type
A template type parameter, stored as a type.
@ Template
A template template argument, stored as a template name.
@ NonType
A non-type template parameter, stored as an expression.
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3396
void enterFunctionArgument(SourceLocation Tok, llvm::function_ref< QualType()> ComputeType)
Computing a type for the function argument may require running overloading, so we postpone its comput...
void enterCondition(Sema &S, SourceLocation Tok)
void enterTypeCast(SourceLocation Tok, QualType CastType)
Handles all type casts, including C-style cast, C++ casts, etc.
void enterMemAccess(Sema &S, SourceLocation Tok, Expr *Base)
void enterSubscript(Sema &S, SourceLocation Tok, Expr *LHS)
void enterUnary(Sema &S, SourceLocation Tok, tok::TokenKind OpKind, SourceLocation OpLoc)
void enterReturn(Sema &S, SourceLocation Tok)
void enterDesignatedInitializer(SourceLocation Tok, QualType BaseType, const Designation &D)
Handles e.g. BaseType{ .D = Tok...
void enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, tok::TokenKind Op)
void enterParenExpr(SourceLocation Tok, SourceLocation LParLoc)
void enterVariableInit(SourceLocation Tok, Decl *D)
QualType get(SourceLocation Tok) const
Get the expected type associated with this location, if any.
Definition Sema.h:335
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
llvm::iterator_range< macro_iterator > macros(bool IncludeExternalMacros=true) const
SourceManager & getSourceManager() const
MacroDefinition getMacroDefinition(const IdentifierInfo *II)
bool isMacroDefined(StringRef Id)
const LangOptions & getLangOpts() const
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8439
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8624
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
Definition Type.cpp:1808
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition TypeBase.h:1348
Wrapper of type source information for a type with non-trivial direct qualifiers.
Definition TypeLoc.h:300
The collection of all-type qualifiers we support.
Definition TypeBase.h:332
bool hasOnlyConst() const
Definition TypeBase.h:459
bool hasConst() const
Definition TypeBase.h:458
bool compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const
Determines if these qualifiers compatibly include another set.
Definition TypeBase.h:728
bool hasRestrict() const
Definition TypeBase.h:478
bool hasVolatile() const
Definition TypeBase.h:468
bool hasOnlyVolatile() const
Definition TypeBase.h:469
bool hasOnlyRestrict() const
Definition TypeBase.h:479
Represents a struct/union/class.
Definition Decl.h:4460
bool isLambda() const
Determine whether this record is a class describing a lambda function object.
Definition Decl.cpp:5311
field_range fields() const
Definition Decl.h:4663
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3671
QualType getPointeeType() const
Definition TypeBase.h:3693
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
Definition Scope.h:414
const Scope * getFnParent() const
getFnParent - Return the closest scope that is a function body.
Definition Scope.h:284
unsigned getFlags() const
getFlags - Return the flags for this scope.
Definition Scope.h:269
Scope * getContinueParent()
getContinueParent - Return the closest scope that a continue statement would be affected by.
Definition Scope.h:294
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
Definition Scope.h:384
DeclContext * getEntity() const
Get the entity corresponding to this scope.
Definition Scope.h:387
bool isTemplateParamScope() const
isTemplateParamScope - Return true if this scope is a C++ template parameter scope.
Definition Scope.h:467
Scope * getBreakParent()
getBreakParent - Return the closest scope that a break statement would be affected by.
Definition Scope.h:308
decl_range decls() const
Definition Scope.h:342
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition Scope.h:280
bool isClassInheritanceScope() const
Determines whether this scope is between inheritance colon and the real class/struct definition.
Definition Scope.h:418
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
Definition Scope.h:85
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
Definition Scope.h:95
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
Definition Scope.h:81
@ ClassScope
The scope of a struct/union/class definition.
Definition Scope.h:69
@ DeclScope
This is a scope that can contain a declaration.
Definition Scope.h:63
This table allows us to fully hide how we implement multi-keyword caching.
Selector getNullarySelector(const IdentifierInfo *ID)
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Selector getUnarySelector(const IdentifierInfo *ID)
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
bool isUnarySelector() const
bool isNull() const
Determine whether this is the empty selector.
unsigned getNumArgs() const
SemaBase(Sema &S)
Definition SemaBase.cpp:7
ASTContext & getASTContext() const
Definition SemaBase.cpp:9
Sema & SemaRef
Definition SemaBase.h:40
const LangOptions & getLangOpts() const
Definition SemaBase.cpp:11
void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression, ObjCInterfaceDecl *Super=nullptr)
void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, IdentifierInfo *PropertyName)
void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)
QualType ProduceTemplateArgumentSignatureHelp(TemplateTy, ArrayRef< ParsedTemplateArgument >, SourceLocation LAngleLoc)
QualType ProduceCtorInitMemberSignatureHelp(Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy, ArrayRef< Expr * > ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc, bool Braced)
void CodeCompleteObjCClassForwardDecl(Scope *S)
void CodeCompleteNamespaceAliasDecl(Scope *S)
void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, SmallVectorImpl< CodeCompletionResult > &Results)
void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, bool IsUsingDeclaration, bool IsAddressOfOperand, bool IsInDeclarationContext, QualType BaseType, QualType PreferredType)
void CodeCompleteObjCAtStatement(Scope *S)
void CodeCompleteObjCMessageReceiver(Scope *S)
void CodeCompleteUsingDirective(Scope *S)
void CodeCompleteObjCProtocolDecl(Scope *S)
void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS)
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Condition
Code completion occurs within the condition of an if, while, switch, or for statement.
@ PCC_ParenthesizedExpression
Code completion occurs in a parenthesized expression, which might also be a type cast.
@ PCC_TopLevelOrExpression
Code completion occurs at top-level in a REPL session.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ForInit
Code completion occurs at the beginning of the initialization statement (or expression) in a for loop...
@ PCC_Type
Code completion occurs where only a type is permitted.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_ObjCInterface
Code completion occurs within an Objective-C interface, protocol, or category.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Expression
Code completion occurs within an expression.
@ PCC_RecoveryInFunction
Code completion occurs within the body of a function on a recovery path, where we do not have a speci...
@ PCC_ObjCInstanceVariableList
Code completion occurs within the list of instance variables in an Objective-C interface,...
@ PCC_Template
Code completion occurs following one or more template headers.
@ PCC_Statement
Code completion occurs within a statement, which may also be an expression or a declaration.
void CodeCompleteObjCAtDirective(Scope *S)
void CodeCompleteObjCPropertySetter(Scope *S)
void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, bool AfterAmpersand)
void CodeCompleteObjCImplementationCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
void CodeCompleteObjCInterfaceDecl(Scope *S)
void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, const VirtSpecifiers *VS=nullptr)
void CodeCompletePreprocessorMacroName(bool IsDefinition)
void CodeCompleteInPreprocessorConditionalExclusion(Scope *S)
void CodeCompleteObjCAtExpression(Scope *S)
void CodeCompleteTypeQualifiers(DeclSpec &DS)
void CodeCompleteObjCPropertyDefinition(Scope *S)
void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data, bool IsAddressOfOperand=false)
Perform code-completion in an expression context when we know what type we're looking for.
void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression)
CodeCompleteConsumer * CodeCompleter
Code-completion consumer.
void CodeCompleteAfterFunctionEquals(Declarator &D)
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
OpaquePtr< TemplateName > TemplateTy
QualType ProduceCallSignatureHelp(Expr *Fn, ArrayRef< Expr * > Args, SourceLocation OpenParLoc)
Determines the preferred type of the current function argument, by examining the signatures of all po...
void CodeCompleteObjCMethodDeclSelector(Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnType, ArrayRef< const IdentifierInfo * > SelIdents)
void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled)
void CodeCompletePreprocessorMacroArgument(Scope *S, IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned Argument)
void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path)
void CodeCompleteObjCInterfaceCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
void CodeCompleteObjCSelector(Scope *S, ArrayRef< const IdentifierInfo * > SelIdents)
void CodeCompleteConstructorInitializer(Decl *Constructor, ArrayRef< CXXCtorInitializer * > Initializers)
void CodeCompleteObjCImplementationDecl(Scope *S)
void CodeCompleteAfterIf(Scope *S, bool IsBracedThen)
void CodeCompleteObjCMethodDecl(Scope *S, std::optional< bool > IsInstanceMethod, ParsedType ReturnType)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
void CodeCompleteObjCClassPropertyRefExpr(Scope *S, const IdentifierInfo &ClassName, SourceLocation ClassNameLoc, bool IsBaseExprStatement)
void CodeCompleteInitializer(Scope *S, Decl *D)
void CodeCompleteObjCProtocolReferences(ArrayRef< IdentifierLoc > Protocols)
void CodeCompleteDesignator(const QualType BaseType, llvm::ArrayRef< Expr * > InitExprs, const Designation &D)
Trigger code completion for a record of BaseType.
void CodeCompletePreprocessorDirective(bool InConditional)
SemaCodeCompletion(Sema &S, CodeCompleteConsumer *CompletionConsumer)
void CodeCompleteOffsetOfDesignator(QualType BaseType, const Designation &D)
Trigger code completion for a position inside a __builtin_offsetof member designator (after the type'...
void CodeCompleteBracketDeclarator(Scope *S)
void CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
void CodeCompleteKeywordAfterIf(bool AfterExclaim) const
void CodeCompleteObjCAtVisibility(Scope *S)
void CodeCompleteTag(Scope *S, unsigned TagSpec)
void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression, bool IsSuper=false)
void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar)
void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase, SourceLocation OpLoc, bool IsArrow, bool IsBaseExprStatement, QualType PreferredType)
void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, bool IsParameter)
void CodeCompleteObjCPropertyGetter(Scope *S)
void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, bool AllowNonIdentifiers, bool AllowNestedNameSpecifiers)
void CodeCompletePostfixExpression(Scope *S, ExprResult LHS, QualType PreferredType)
GlobalMethodPool MethodPool
Method Pool - allows efficient lookup when typechecking messages to "id".
Definition SemaObjC.h:220
void ReadMethodPool(Selector Sel)
Read the contents of the method pool for a given selector from external storage.
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:863
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs=true)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h:9394
@ LookupNestedNameSpecifierName
Look up of a name that precedes the '::' scope resolution operator in C++.
Definition Sema.h:9413
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition Sema.h:9402
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
Definition Sema.h:9397
@ LookupAnyName
Look up any declaration with any name.
Definition Sema.h:9439
Preprocessor & getPreprocessor() const
Definition Sema.h:934
ASTContext & Context
Definition Sema.h:1304
SemaObjC & ObjC()
Definition Sema.h:1516
ASTContext & getASTContext() const
Definition Sema.h:935
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition Sema.h:1208
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition Sema.cpp:1773
const LangOptions & getLangOpts() const
Definition Sema.h:928
void LookupVisibleDecls(Scope *S, LookupNameKind Kind, VisibleDeclConsumer &Consumer, bool IncludeGlobalScope=true, bool LoadExternal=true)
SemaCodeCompletion & CodeCompletion()
Definition Sema.h:1466
Preprocessor & PP
Definition Sema.h:1303
sema::FunctionScopeInfo * getCurFunction() const
Definition Sema.h:1339
Module * getCurrentModule() const
Get the module unit whose scope we are currently within.
Definition Sema.h:9922
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
Definition Sema.cpp:2674
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition Sema.h:1444
ExternalSemaSource * getExternalSource() const
Definition Sema.h:938
bool isAcceptableNestedNameSpecifier(const NamedDecl *SD, bool *CanCorrect=nullptr)
Determines whether the given declaration is an valid acceptable result for name lookup of a nested-na...
SourceManager & SourceMgr
Definition Sema.h:1307
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
void MarkDeducedTemplateParameters(const FunctionTemplateDecl *FunctionTemplate, llvm::SmallBitVector &Deduced)
Definition Sema.h:13025
Encodes a location in the source.
This class handles loading and caching of source files into memory.
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SwitchStmt - This represents a 'switch' stmt.
Definition Stmt.h:2521
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3852
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3953
bool isUnion() const
Definition Decl.h:4063
A convenient class for passing around template argument information.
Represents a template argument.
QualType getAsType() const
Retrieve the type for a type template argument.
@ Type
The template argument is a type.
ArgKind getKind() const
Return the kind of stored template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
NamedDecl ** iterator
Iterates through the template parameters in this list.
bool hasParameterPack() const
Determine whether this template parameter list contains a parameter pack.
ArrayRef< NamedDecl * > asArray()
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
The top declaration context.
Definition Decl.h:106
void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const
Definition ASTConcept.h:282
Represents a declaration of a type.
Definition Decl.h:3648
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
UnqualTypeLoc getUnqualifiedLoc() const
Skips past any qualifiers, if this is qualified.
Definition TypeLoc.h:349
QualType getType() const
Get the type for which this source info wrapper provides information.
Definition TypeLoc.h:133
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:89
TypeLoc IgnoreParens() const
Definition TypeLoc.h:1468
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:2766
A container of type source information.
Definition TypeBase.h:8410
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
The base class of the type hierarchy.
Definition TypeBase.h:1879
bool isBlockPointerType() const
Definition TypeBase.h:8696
bool isVoidType() const
Definition TypeBase.h:9048
bool isBooleanType() const
Definition TypeBase.h:9185
const ObjCObjectPointerType * getAsObjCQualifiedIdType() const
Definition Type.cpp:2042
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isPointerType() const
Definition TypeBase.h:8676
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9092
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9342
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
Definition Type.cpp:2070
NestedNameSpecifier getPrefix() const
If this type represents a qualified-id, this returns its nested name specifier.
Definition Type.cpp:2097
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:883
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition TypeBase.h:9170
bool isObjCObjectOrInterfaceType() const
Definition TypeBase.h:8863
bool isMemberPointerType() const
Definition TypeBase.h:8757
bool isObjCIdType() const
Definition TypeBase.h:8888
bool isObjCObjectPointerType() const
Definition TypeBase.h:8855
bool isObjCQualifiedClassType() const
Definition TypeBase.h:8882
bool isObjCClassType() const
Definition TypeBase.h:8894
std::optional< ArrayRef< QualType > > getObjCSubstitutions(const DeclContext *dc) const
Retrieve the set of substitutions required when accessing a member of the Objective-C receiver type t...
Definition Type.cpp:1847
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9275
Wrapper for source info for typedefs.
Definition TypeLoc.h:777
Represents a C++ unqualified-id that has been parsed.
Definition DeclSpec.h:1039
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
Definition DeclSpec.h:1127
void append(iterator I, iterator E)
A set of unresolved declarations.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3429
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:713
QualType getType() const
Definition Decl.h:724
QualType getType() const
Definition Value.cpp:238
Represents a C++11 virt-specifier-seq.
Definition DeclSpec.h:2832
bool isOverrideSpecified() const
Definition DeclSpec.h:2851
bool isFinalSpecified() const
Definition DeclSpec.h:2854
Consumes visible declarations found when searching for all visible names within a given scope or cont...
Definition Lookup.h:838
Retains information about a block that is currently being parsed.
Definition ScopeInfo.h:791
QualType ReturnType
ReturnType - The target type of return statements in this context, or null if unknown.
Definition ScopeInfo.h:733
SmallVector< SwitchInfo, 8 > SwitchStack
SwitchStack - This is the current set of active switch statements in the block.
Definition ScopeInfo.h:214
@ CXCursor_ObjCInterfaceDecl
An Objective-C @interface.
Definition Index.h:1220
@ CXCursor_Namespace
A C++ namespace.
Definition Index.h:1242
@ CXCursor_TypedefDecl
A typedef.
Definition Index.h:1238
@ CXCursor_CXXAccessSpecifier
An access specifier.
Definition Index.h:1276
@ CXCursor_EnumConstantDecl
An enumerator constant.
Definition Index.h:1212
@ CXCursor_ConversionFunction
A C++ conversion function.
Definition Index.h:1250
@ CXCursor_ConceptDecl
a concept declaration.
Definition Index.h:2324
@ CXCursor_ClassTemplate
A C++ class template.
Definition Index.h:1260
@ CXCursor_UnionDecl
A C or C++ union.
Definition Index.h:1201
@ CXCursor_ObjCSynthesizeDecl
An Objective-C @synthesize definition.
Definition Index.h:1272
@ CXCursor_ParmDecl
A function or method parameter.
Definition Index.h:1218
@ CXCursor_FieldDecl
A field (in C) or non-static data member (in C++) in a struct, union, or C++ class.
Definition Index.h:1210
@ CXCursor_CXXMethod
A C++ class method.
Definition Index.h:1240
@ CXCursor_EnumDecl
An enumeration.
Definition Index.h:1205
@ CXCursor_ObjCClassMethodDecl
An Objective-C class method.
Definition Index.h:1232
@ CXCursor_TranslationUnit
Cursor that represents the translation unit itself.
Definition Index.h:2245
@ CXCursor_ClassTemplatePartialSpecialization
A C++ class template partial specialization.
Definition Index.h:1262
@ CXCursor_ObjCProtocolDecl
An Objective-C @protocol declaration.
Definition Index.h:1224
@ CXCursor_FunctionTemplate
A C++ function template.
Definition Index.h:1258
@ CXCursor_ObjCImplementationDecl
An Objective-C @implementation.
Definition Index.h:1234
@ CXCursor_NonTypeTemplateParameter
A C++ non-type template parameter.
Definition Index.h:1254
@ CXCursor_FunctionDecl
A function.
Definition Index.h:1214
@ CXCursor_ObjCPropertyDecl
An Objective-C @property declaration.
Definition Index.h:1226
@ CXCursor_Destructor
A C++ destructor.
Definition Index.h:1248
@ CXCursor_ObjCIvarDecl
An Objective-C instance variable.
Definition Index.h:1228
@ CXCursor_TypeAliasTemplateDecl
Definition Index.h:2312
@ CXCursor_ObjCCategoryImplDecl
An Objective-C @implementation for a category.
Definition Index.h:1236
@ CXCursor_ObjCDynamicDecl
An Objective-C @dynamic definition.
Definition Index.h:1274
@ CXCursor_MacroDefinition
Definition Index.h:2300
@ CXCursor_VarDecl
A variable.
Definition Index.h:1216
@ CXCursor_TemplateTypeParameter
A C++ template type parameter.
Definition Index.h:1252
@ CXCursor_TemplateTemplateParameter
A C++ template template parameter.
Definition Index.h:1256
@ CXCursor_UnexposedDecl
A declaration whose specific kind is not exposed via this interface.
Definition Index.h:1197
@ CXCursor_ObjCInstanceMethodDecl
An Objective-C instance method.
Definition Index.h:1230
@ CXCursor_StructDecl
A C or C++ struct.
Definition Index.h:1199
@ CXCursor_UsingDeclaration
A C++ using declaration.
Definition Index.h:1268
@ CXCursor_LinkageSpec
A linkage specification, e.g.
Definition Index.h:1244
@ CXCursor_ClassDecl
A C++ class.
Definition Index.h:1203
@ CXCursor_ObjCCategoryDecl
An Objective-C @interface for a category.
Definition Index.h:1222
@ CXCursor_StaticAssert
A static_assert or _Static_assert node.
Definition Index.h:2316
@ CXCursor_ModuleImportDecl
A module import declaration.
Definition Index.h:2311
@ CXCursor_MemberRef
A reference to a member of a struct, union, or class that occurs in some non-expression context,...
Definition Index.h:1316
@ CXCursor_NamespaceAlias
A C++ namespace alias declaration.
Definition Index.h:1264
@ CXCursor_Constructor
A C++ constructor.
Definition Index.h:1246
@ CXCursor_FriendDecl
a friend declaration.
Definition Index.h:2320
@ CXCursor_TypeAliasDecl
A C++ alias declaration.
Definition Index.h:1270
@ CXCursor_UsingDirective
A C++ using directive.
Definition Index.h:1266
@ CXAvailability_Available
The entity is available.
Definition Index.h:134
@ CXAvailability_Deprecated
The entity is available, but has been deprecated (and its use is not recommended).
Definition Index.h:139
@ CXAvailability_NotAvailable
The entity is not available; any use of it will be an error.
Definition Index.h:143
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
Definition Interp.h:3961
bool Add(InterpState &S, CodePtr OpPC)
Definition Interp.h:404
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition TokenKinds.h:33
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus23
@ CPlusPlus20
@ CPlusPlus
@ CPlusPlus11
@ CPlusPlus17
@ CCP_Type
Priority for a type.
@ CCP_ObjC_cmd
Priority for the Objective-C "_cmd" implicit parameter.
@ CCP_Keyword
Priority for a language keyword (that isn't any of the other categories).
@ CCP_Macro
Priority for a preprocessor macro.
@ CCP_LocalDeclaration
Priority for a declaration that is in the local scope.
@ CCP_Unlikely
Priority for a result that isn't likely to be what the user wants, but is included for completeness.
@ CCP_NestedNameSpecifier
Priority for a nested-name-specifier.
@ CCP_SuperCompletion
Priority for a send-to-super completion.
@ CCP_NextInitializer
Priority for the next initialization in a constructor initializer list.
@ CCP_Declaration
Priority for a non-type declaration.
@ CCP_Constant
Priority for a constant value (e.g., enumerator).
@ CCP_MemberDeclaration
Priority for a member declaration found from the current method or member function.
@ CCP_EnumInCase
Priority for an enumeration constant inside a switch whose condition is of the enumeration type.
@ CCP_CodePattern
Priority for a code pattern.
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
Definition Template.h:50
bool isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, const OverloadCandidate &Cand2, SourceLocation Loc, OverloadCandidateSet::CandidateSetKind Kind, bool PartialOverloading=false)
isBetterOverloadCandidate - Determines whether the first overload candidate is a better candidate tha...
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
@ Nullable
Values of this type can be null.
Definition Specifiers.h:351
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
Definition Specifiers.h:356
@ NonNull
Values of this type can never be null.
Definition Specifiers.h:349
CXCursorKind getCursorKindForDecl(const Decl *D)
Determine the libclang cursor kind associated with the given declaration.
RefQualifierKind
The kind of C++11 ref-qualifier associated with a function type.
Definition TypeBase.h:1799
@ RQ_None
No ref-qualifier was provided.
Definition TypeBase.h:1801
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1804
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1807
const RawComment * getParameterComment(const ASTContext &Ctx, const CodeCompleteConsumer::OverloadCandidate &Result, unsigned ArgIndex)
Get the documentation comment used to produce CodeCompletionString::BriefComment for OverloadCandidat...
@ LCK_This
Capturing the *this object by reference.
Definition Lambda.h:34
@ CCD_SelectorMatch
The selector of the given message exactly matches the selector of the current method,...
@ CCD_ObjectQualifierMatch
The result is a C++ non-static member function whose qualifiers exactly match the object type on whic...
@ CCD_bool_in_ObjC
Adjustment to the "bool" type in Objective-C, where the typedef "BOOL" is preferred.
@ CCD_InBaseClass
The result is in a base class.
@ CCD_ProbablyNotObjCCollection
Adjustment for KVC code pattern priorities when it doesn't look like the.
@ CCD_BlockPropertySetter
An Objective-C block property completed as a setter with a block placeholder.
@ CCD_MethodAsProperty
An Objective-C method being used as a property.
@ IK_ConstructorName
A constructor name.
Definition DeclSpec.h:1025
@ IK_DestructorName
A destructor name.
Definition DeclSpec.h:1029
@ IK_OperatorFunctionId
An overloaded operator name, e.g., operator+.
Definition DeclSpec.h:1019
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Property
The type of a property.
Definition TypeBase.h:912
@ Parameter
The parameter type of a method or function.
Definition TypeBase.h:909
@ Result
The result type of a method or function.
Definition TypeBase.h:906
SimplifiedTypeClass
A simplified classification of types used when determining "similar" types for code completion.
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
Definition Parser.h:81
const RawComment * getPatternCompletionComment(const ASTContext &Ctx, const NamedDecl *Decl)
Get the documentation comment used to produce CodeCompletionString::BriefComment for RK_Pattern.
@ Interface
The "__interface" keyword.
Definition TypeBase.h:6037
@ Struct
The "struct" keyword.
Definition TypeBase.h:6034
@ Class
The "class" keyword.
Definition TypeBase.h:6043
@ Union
The "union" keyword.
Definition TypeBase.h:6040
@ Enum
The "enum" keyword.
Definition TypeBase.h:6046
LLVM_READONLY char toUppercase(char c)
Converts the given ASCII character to its uppercase equivalent.
Definition CharInfo.h:233
@ NonType
The name was classified as a specific non-type, non-template declaration.
Definition Sema.h:562
@ Type
The name was classified as a type.
Definition Sema.h:558
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
Definition Sema.h:575
const RawComment * getCompletionComment(const ASTContext &Ctx, const NamedDecl *Decl)
Get the documentation comment used to produce CodeCompletionString::BriefComment for RK_Declaration.
@ CCF_ExactTypeMatch
Divide by this factor when a code-completion result's type exactly matches the type we expect.
@ CCF_SimilarTypeMatch
Divide by this factor when a code-completion result's type is similar to the type we expect (e....
SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T)
Determine the simplified type class of the given canonical type.
@ Deduced
The normal deduced case.
Definition TypeBase.h:1818
@ LCD_ByCopy
Definition Lambda.h:24
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition Specifiers.h:133
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
Definition Specifiers.h:145
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:140
unsigned getMacroUsagePriority(StringRef MacroName, const LangOptions &LangOpts, bool PreferredTypeIsPointer=false)
Determine the priority to be given to a macro code completion result with the given name.
bool shouldEnforceArgLimit(bool PartialOverloading, FunctionDecl *Function)
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:63
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Enumerator
Enumerator value with fixed underlying type.
Definition Sema.h:834
QualType getDeclUsageType(ASTContext &C, NestedNameSpecifier Qualifier, const NamedDecl *ND)
Determine the type that this declaration will have if it is used as a type or in an expression.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition Ownership.h:230
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6012
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:6028
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6018
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6021
ReservedIdentifierStatus
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
@ EST_BasicNoexcept
noexcept
@ EST_NoexceptTrue
noexcept(expression), evals to 'true'
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
#define false
Definition stdbool.h:26
CodeCompleteExpressionData(QualType PreferredType=QualType(), bool IsParenthesized=false)
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
Definition DeclSpec.h:1447
Represents a complete lambda introducer.
Definition DeclSpec.h:2884
SmallVector< LambdaCapture, 4 > Captures
Definition DeclSpec.h:2909
LambdaCaptureDefault Default
Definition DeclSpec.h:2908
a linked list of methods with the same selector name but different signatures.
OverloadCandidate - A single candidate in an overload set (C++ 13.3).
Definition Overload.h:934
static ArrayRef< const ParsedAttrInfo * > getAllBuiltin()
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressUnwrittenScope
Suppress printing parts of scope specifiers that are never written, e.g., for anonymous namespaces.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
@ Plain
E.g., (anonymous enum)/(unnamed struct)/etc.
unsigned SuppressTemplateArgsInCXXConstructors
When true, suppresses printing template arguments in names of C++ constructors.
unsigned ResolveDecltype
Use whitespace and punctuation like MSVC does.