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