brintos

brintos / llvm-project-archived public Read only

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