llvm/clang/lib/Sema/SemaCodeComplete.cpp

//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file defines the code-completion semantic actions.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTConcept.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/QualTypeNames.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaObjC.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <list>
#include <map>
#include <optional>
#include <string>
#include <vector>

usingnamespaceclang;
usingnamespacesema;

namespace {
/// A container of code-completion results.
class ResultBuilder {};
} // namespace

void PreferredTypeBuilder::enterReturn(Sema &S, SourceLocation Tok) {}

void PreferredTypeBuilder::enterVariableInit(SourceLocation Tok, Decl *D) {}

static QualType getDesignatedType(QualType BaseType, const Designation &Desig);

void PreferredTypeBuilder::enterDesignatedInitializer(SourceLocation Tok,
                                                      QualType BaseType,
                                                      const Designation &D) {}

void PreferredTypeBuilder::enterFunctionArgument(
    SourceLocation Tok, llvm::function_ref<QualType()> ComputeType) {}

void PreferredTypeBuilder::enterParenExpr(SourceLocation Tok,
                                          SourceLocation LParLoc) {}

static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS,
                                            tok::TokenKind Op) {}

/// Get preferred type for an argument of an unary expression. \p ContextType is
/// preferred type of the whole unary expression.
static QualType getPreferredTypeOfUnaryArg(Sema &S, QualType ContextType,
                                           tok::TokenKind Op) {}

void PreferredTypeBuilder::enterBinary(Sema &S, SourceLocation Tok, Expr *LHS,
                                       tok::TokenKind Op) {}

void PreferredTypeBuilder::enterMemAccess(Sema &S, SourceLocation Tok,
                                          Expr *Base) {}

void PreferredTypeBuilder::enterUnary(Sema &S, SourceLocation Tok,
                                      tok::TokenKind OpKind,
                                      SourceLocation OpLoc) {}

void PreferredTypeBuilder::enterSubscript(Sema &S, SourceLocation Tok,
                                          Expr *LHS) {}

void PreferredTypeBuilder::enterTypeCast(SourceLocation Tok,
                                         QualType CastType) {}

void PreferredTypeBuilder::enterCondition(Sema &S, SourceLocation Tok) {}

class ResultBuilder::ShadowMapEntry::iterator {};

ResultBuilder::ShadowMapEntry::iterator
ResultBuilder::ShadowMapEntry::begin() const {}

ResultBuilder::ShadowMapEntry::iterator
ResultBuilder::ShadowMapEntry::end() const {}

/// Compute the qualification required to get from the current context
/// (\p CurContext) to the target context (\p TargetContext).
///
/// \param Context the AST context in which the qualification will be used.
///
/// \param CurContext the context where an entity is being named, which is
/// typically based on the current scope.
///
/// \param TargetContext the context in which the named entity actually
/// resides.
///
/// \returns a nested name specifier that refers into the target context, or
/// NULL if no qualification is needed.
static NestedNameSpecifier *
getRequiredQualification(ASTContext &Context, const DeclContext *CurContext,
                         const DeclContext *TargetContext) {}

// Some declarations have reserved names that we don't want to ever show.
// Filter out names reserved for the implementation if they come from a
// system header.
static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) {}

bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
                                      bool &AsNestedNameSpecifier) const {}

bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
                                      const NamedDecl *Hiding) {}

/// A simplified classification of types used to determine whether two
/// types are "similar enough" when adjusting priorities.
SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {}

/// Get the type that a given expression will have if this declaration
/// is used as an expression in its "typical" code-completion form.
QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {}

unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) {}

void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {}

static DeclContext::lookup_result getConstructors(ASTContext &Context,
                                                  const CXXRecordDecl *Record) {}

void ResultBuilder::MaybeAddConstructorResults(Result R) {}

static bool isConstructor(const Decl *ND) {}

void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {}

static void setInBaseClass(ResultBuilder::Result &R) {}

enum class OverloadCompare {};
// Will Candidate ever be called on the object, when overloaded with Incumbent?
// Returns Dominates if Candidate is always called, Dominated if Incumbent is
// always called, BothViable if either may be called depending on arguments.
// Precondition: must actually be overloads!
static OverloadCompare compareOverloads(const CXXMethodDecl &Candidate,
                                        const CXXMethodDecl &Incumbent,
                                        const Qualifiers &ObjectQuals,
                                        ExprValueKind ObjectKind) {}

bool ResultBuilder::canCxxMethodBeCalled(const CXXMethodDecl *Method,
                                         QualType BaseExprType) const {}

bool ResultBuilder::canFunctionBeCalled(const NamedDecl *ND,
                                        QualType BaseExprType) const {}

void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
                              NamedDecl *Hiding, bool InBaseClass = false,
                              QualType BaseExprType = QualType()) {}

void ResultBuilder::AddResult(Result R) {}

/// Enter into a new scope.
void ResultBuilder::EnterNewScope() {}

/// Exit from the current scope.
void ResultBuilder::ExitScope() {}

/// Determines whether this given declaration will be found by
/// ordinary name lookup.
bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {}

/// Determines whether this given declaration will be found by
/// ordinary name lookup but is not a type name.
bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {}

bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {}

/// Determines whether this given declaration will be found by
/// ordinary name lookup.
bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {}

/// Determines whether the given declaration is suitable as the
/// start of a C++ nested-name-specifier, e.g., a class or namespace.
bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {}

/// Determines whether the given declaration is an enumeration.
bool ResultBuilder::IsEnum(const NamedDecl *ND) const {}

/// Determines whether the given declaration is a class or struct.
bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {}

/// Determines whether the given declaration is a union.
bool ResultBuilder::IsUnion(const NamedDecl *ND) const {}

/// Determines whether the given declaration is a namespace.
bool ResultBuilder::IsNamespace(const NamedDecl *ND) const {}

/// Determines whether the given declaration is a namespace or
/// namespace alias.
bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {}

/// Determines whether the given declaration is a type.
bool ResultBuilder::IsType(const NamedDecl *ND) const {}

/// Determines which members of a class should be visible via
/// "." or "->".  Only value declarations, nested name specifiers, and
/// using declarations thereof should show up.
bool ResultBuilder::IsMember(const NamedDecl *ND) const {}

static bool isObjCReceiverType(ASTContext &C, QualType T) {}

bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {}

bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(
    const NamedDecl *ND) const {}

bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {}

bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {}

/// Determines whether the given declaration is an Objective-C
/// instance variable.
bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {}

namespace {

/// Visible declaration consumer that adds a code-completion result
/// for each visible declaration.
class CodeCompletionDeclConsumer : public VisibleDeclConsumer {};
} // namespace

/// Add type specifiers for the current language as keyword results.
static void AddTypeSpecifierResults(const LangOptions &LangOpts,
                                    ResultBuilder &Results) {}

static void
AddStorageSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC,
                     const LangOptions &LangOpts, ResultBuilder &Results) {}

static void
AddFunctionSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC,
                      const LangOptions &LangOpts, ResultBuilder &Results) {}

static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
static void AddObjCVisibilityResults(const LangOptions &LangOpts,
                                     ResultBuilder &Results, bool NeedAt);
static void AddObjCImplementationResults(const LangOptions &LangOpts,
                                         ResultBuilder &Results, bool NeedAt);
static void AddObjCInterfaceResults(const LangOptions &LangOpts,
                                    ResultBuilder &Results, bool NeedAt);
static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);

static void AddTypedefResult(ResultBuilder &Results) {}

// using name = type
static void AddUsingAliasResult(CodeCompletionBuilder &Builder,
                                ResultBuilder &Results) {}

static bool WantTypesInContext(SemaCodeCompletion::ParserCompletionContext CCC,
                               const LangOptions &LangOpts) {}

static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
                                                  const Preprocessor &PP) {}

/// Retrieve a printing policy suitable for code completion.
static PrintingPolicy getCompletionPrintingPolicy(Sema &S) {}

/// Retrieve the string representation of the given type as a string
/// that has the appropriate lifetime for code completion.
///
/// This routine provides a fast path where we provide constant strings for
/// common type names.
static const char *GetCompletionTypeString(QualType T, ASTContext &Context,
                                           const PrintingPolicy &Policy,
                                           CodeCompletionAllocator &Allocator) {}

/// Add a completion for "this", if we're in a member function.
static void addThisCompletion(Sema &S, ResultBuilder &Results) {}

static void AddStaticAssertResult(CodeCompletionBuilder &Builder,
                                  ResultBuilder &Results,
                                  const LangOptions &LangOpts) {}

static void AddOverrideResults(ResultBuilder &Results,
                               const CodeCompletionContext &CCContext,
                               CodeCompletionBuilder &Builder) {}

/// Add language constructs that show up for "ordinary" names.
static void
AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC,
                       Scope *S, Sema &SemaRef, ResultBuilder &Results) {}

/// If the given declaration has an associated type, add it as a result
/// type chunk.
static void AddResultTypeChunk(ASTContext &Context,
                               const PrintingPolicy &Policy,
                               const NamedDecl *ND, QualType BaseType,
                               CodeCompletionBuilder &Result) {}

static void MaybeAddSentinel(Preprocessor &PP,
                             const NamedDecl *FunctionOrMethod,
                             CodeCompletionBuilder &Result) {}

static std::string formatObjCParamQualifiers(unsigned ObjCQuals,
                                             QualType &Type) {}

/// Tries to find the most appropriate type location for an Objective-C
/// block placeholder.
///
/// This function ignores things like typedefs and qualifiers in order to
/// present the most relevant and accurate block placeholders in code completion
/// results.
static void findTypeLocationForBlockDecl(const TypeSourceInfo *TSInfo,
                                         FunctionTypeLoc &Block,
                                         FunctionProtoTypeLoc &BlockProto,
                                         bool SuppressBlock = false) {}

static std::string formatBlockPlaceholder(
    const PrintingPolicy &Policy, const NamedDecl *BlockDecl,
    FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto,
    bool SuppressBlockName = false, bool SuppressBlock = false,
    std::optional<ArrayRef<QualType>> ObjCSubsts = std::nullopt);

static std::string FormatFunctionParameter(
    const PrintingPolicy &Policy, const DeclaratorDecl *Param,
    bool SuppressName = false, bool SuppressBlock = false,
    std::optional<ArrayRef<QualType>> ObjCSubsts = std::nullopt) {}

/// Returns a placeholder string that corresponds to an Objective-C block
/// declaration.
///
/// \param BlockDecl A declaration with an Objective-C block type.
///
/// \param Block The most relevant type location for that block type.
///
/// \param SuppressBlockName Determines whether or not the name of the block
/// declaration is included in the resulting string.
static std::string
formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl,
                       FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto,
                       bool SuppressBlockName, bool SuppressBlock,
                       std::optional<ArrayRef<QualType>> ObjCSubsts) {}

static std::string GetDefaultValueString(const ParmVarDecl *Param,
                                         const SourceManager &SM,
                                         const LangOptions &LangOpts) {}

/// Add function parameter chunks to the given code completion string.
static void AddFunctionParameterChunks(Preprocessor &PP,
                                       const PrintingPolicy &Policy,
                                       const FunctionDecl *Function,
                                       CodeCompletionBuilder &Result,
                                       unsigned Start = 0,
                                       bool InOptional = false) {}

/// Add template parameter chunks to the given code completion string.
static void AddTemplateParameterChunks(
    ASTContext &Context, const PrintingPolicy &Policy,
    const TemplateDecl *Template, CodeCompletionBuilder &Result,
    unsigned MaxParameters = 0, unsigned Start = 0, bool InDefaultArg = false) {}

/// Add a qualifier to the given code-completion string, if the
/// provided nested-name-specifier is non-NULL.
static void AddQualifierToCompletionString(CodeCompletionBuilder &Result,
                                           NestedNameSpecifier *Qualifier,
                                           bool QualifierIsInformative,
                                           ASTContext &Context,
                                           const PrintingPolicy &Policy) {}

static void
AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
                                       const FunctionDecl *Function) {}

/// Add the name of the given declaration
static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
                              const NamedDecl *ND,
                              CodeCompletionBuilder &Result) {}

CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(
    Sema &S, const CodeCompletionContext &CCContext,
    CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
    bool IncludeBriefComments) {}

CodeCompletionString *CodeCompletionResult::CreateCodeCompletionStringForMacro(
    Preprocessor &PP, CodeCompletionAllocator &Allocator,
    CodeCompletionTUInfo &CCTUInfo) {}

/// If possible, create a new code completion string for the given
/// result.
///
/// \returns Either a new, heap-allocated code completion string describing
/// how to use this result, or NULL to indicate that the string or name of the
/// result is all that is needed.
CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(
    ASTContext &Ctx, Preprocessor &PP, const CodeCompletionContext &CCContext,
    CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
    bool IncludeBriefComments) {}

static void printOverrideString(const CodeCompletionString &CCS,
                                std::string &BeforeName,
                                std::string &NameAndSignature) {}

CodeCompletionString *
CodeCompletionResult::createCodeCompletionStringForOverride(
    Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
    bool IncludeBriefComments, const CodeCompletionContext &CCContext,
    PrintingPolicy &Policy) {}

// FIXME: Right now this works well with lambdas. Add support for other functor
// types like std::function.
static const NamedDecl *extractFunctorCallOperator(const NamedDecl *ND) {}

CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl(
    Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
    bool IncludeBriefComments, const CodeCompletionContext &CCContext,
    PrintingPolicy &Policy) {}

const RawComment *clang::getCompletionComment(const ASTContext &Ctx,
                                              const NamedDecl *ND) {}

const RawComment *clang::getPatternCompletionComment(const ASTContext &Ctx,
                                                     const NamedDecl *ND) {}

const RawComment *clang::getParameterComment(
    const ASTContext &Ctx,
    const CodeCompleteConsumer::OverloadCandidate &Result, unsigned ArgIndex) {}

static void AddOverloadAggregateChunks(const RecordDecl *RD,
                                       const PrintingPolicy &Policy,
                                       CodeCompletionBuilder &Result,
                                       unsigned CurrentArg) {}

/// Add function overload parameter chunks to the given code completion
/// string.
static void AddOverloadParameterChunks(
    ASTContext &Context, const PrintingPolicy &Policy,
    const FunctionDecl *Function, const FunctionProtoType *Prototype,
    FunctionProtoTypeLoc PrototypeLoc, CodeCompletionBuilder &Result,
    unsigned CurrentArg, unsigned Start = 0, bool InOptional = false) {}

static std::string
formatTemplateParameterPlaceholder(const NamedDecl *Param, bool &Optional,
                                   const PrintingPolicy &Policy) {}

static std::string templateResultType(const TemplateDecl *TD,
                                      const PrintingPolicy &Policy) {}

static CodeCompletionString *createTemplateSignatureString(
    const TemplateDecl *TD, CodeCompletionBuilder &Builder, unsigned CurrentArg,
    const PrintingPolicy &Policy) {}

CodeCompletionString *
CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
    unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator,
    CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments,
    bool Braced) const {}

unsigned clang::getMacroUsagePriority(StringRef MacroName,
                                      const LangOptions &LangOpts,
                                      bool PreferredTypeIsPointer) {}

CXCursorKind clang::getCursorKindForDecl(const Decl *D) {}

static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
                            bool LoadExternal, bool IncludeUndefined,
                            bool TargetTypeIsPointer = false) {}

static void AddPrettyFunctionResults(const LangOptions &LangOpts,
                                     ResultBuilder &Results) {}

static void HandleCodeCompleteResults(Sema *S,
                                      CodeCompleteConsumer *CodeCompleter,
                                      const CodeCompletionContext &Context,
                                      CodeCompletionResult *Results,
                                      unsigned NumResults) {}

static CodeCompletionContext
mapCodeCompletionContext(Sema &S,
                         SemaCodeCompletion::ParserCompletionContext PCC) {}

/// If we're in a C++ virtual member function, add completion results
/// that invoke the functions we override, since it's common to invoke the
/// overridden function as well as adding new functionality.
///
/// \param S The semantic analysis object for which we are generating results.
///
/// \param InContext This context in which the nested-name-specifier preceding
/// the code-completion point
static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
                                  ResultBuilder &Results) {}

void SemaCodeCompletion::CodeCompleteModuleImport(SourceLocation ImportLoc,
                                                  ModuleIdPath Path) {}

void SemaCodeCompletion::CodeCompleteOrdinaryName(
    Scope *S, SemaCodeCompletion::ParserCompletionContext CompletionContext) {}

static void
AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver,
                           ArrayRef<const IdentifierInfo *> SelIdents,
                           bool AtArgumentExpression, bool IsSuper,
                           ResultBuilder &Results);

void SemaCodeCompletion::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
                                              bool AllowNonIdentifiers,
                                              bool AllowNestedNameSpecifiers) {}

static const char *underscoreAttrScope(llvm::StringRef Scope) {}

static const char *noUnderscoreAttrScope(llvm::StringRef Scope) {}

void SemaCodeCompletion::CodeCompleteAttribute(
    AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion,
    const IdentifierInfo *InScope) {}

struct SemaCodeCompletion::CodeCompleteExpressionData {};

namespace {
/// Information that allows to avoid completing redundant enumerators.
struct CoveredEnumerators {};
} // namespace

static void AddEnumerators(ResultBuilder &Results, ASTContext &Context,
                           EnumDecl *Enum, DeclContext *CurContext,
                           const CoveredEnumerators &Enumerators) {}

/// Try to find a corresponding FunctionProtoType for function-like types (e.g.
/// function pointers, std::function, etc).
static const FunctionProtoType *TryDeconstructFunctionLike(QualType T) {}

/// Adds a pattern completion for a lambda expression with the specified
/// parameter types and placeholders for parameter names.
static void AddLambdaCompletion(ResultBuilder &Results,
                                llvm::ArrayRef<QualType> Parameters,
                                const LangOptions &LangOpts) {}

/// Perform code-completion in an expression context when we know what
/// type we're looking for.
void SemaCodeCompletion::CodeCompleteExpression(
    Scope *S, const CodeCompleteExpressionData &Data) {}

void SemaCodeCompletion::CodeCompleteExpression(Scope *S,
                                                QualType PreferredType,
                                                bool IsParenthesized) {}

void SemaCodeCompletion::CodeCompletePostfixExpression(Scope *S, ExprResult E,
                                                       QualType PreferredType) {}

/// The set of properties that have already been added, referenced by
/// property name.
AddedPropertiesSet;

/// Retrieve the container definition, if any?
static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {}

/// Adds a block invocation code completion result for the given block
/// declaration \p BD.
static void AddObjCBlockCall(ASTContext &Context, const PrintingPolicy &Policy,
                             CodeCompletionBuilder &Builder,
                             const NamedDecl *BD,
                             const FunctionTypeLoc &BlockLoc,
                             const FunctionProtoTypeLoc &BlockProtoLoc) {}

static void
AddObjCProperties(const CodeCompletionContext &CCContext,
                  ObjCContainerDecl *Container, bool AllowCategories,
                  bool AllowNullaryMethods, DeclContext *CurContext,
                  AddedPropertiesSet &AddedProperties, ResultBuilder &Results,
                  bool IsBaseExprStatement = false,
                  bool IsClassProperty = false, bool InOriginalClass = true) {}

static void
AddRecordMembersCompletionResults(Sema &SemaRef, ResultBuilder &Results,
                                  Scope *S, QualType BaseType,
                                  ExprValueKind BaseKind, RecordDecl *RD,
                                  std::optional<FixItHint> AccessOpFixIt) {}

// Returns the RecordDecl inside the BaseType, falling back to primary template
// in case of specializations. Since we might not have a decl for the
// instantiation/specialization yet, e.g. dependent code.
static RecordDecl *getAsRecordDecl(QualType BaseType) {}

namespace {
// Collects completion-relevant information about a concept-constrainted type T.
// In particular, examines the constraint expressions to find members of T.
//
// The design is very simple: we walk down each constraint looking for
// expressions of the form T.foo().
// If we're extra lucky, the return type is specified.
// We don't do any clever handling of && or || in constraint expressions, we
// take members from both branches.
//
// For example, given:
//   template <class T> concept X = requires (T t, string& s) { t.print(s); };
//   template <X U> void foo(U u) { u.^ }
// We want to suggest the inferred member function 'print(string)'.
// We see that u has type U, so X<U> holds.
// X<U> requires t.print(s) to be valid, where t has type U (substituted for T).
// By looking at the CallExpr we find the signature of print().
//
// While we tend to know in advance which kind of members (access via . -> ::)
// we want, it's simpler just to gather them all and post-filter.
//
// FIXME: some of this machinery could be used for non-concept type-parms too,
// enabling completion for type parameters based on other uses of that param.
//
// FIXME: there are other cases where a type can be constrained by a concept,
// e.g. inside `if constexpr(ConceptSpecializationExpr) { ... }`
class ConceptInfo {};

// Returns a type for E that yields acceptable member completions.
// In particular, when E->getType() is DependentTy, try to guess a likely type.
// We accept some lossiness (like dropping parameters).
// We only try to handle common expressions on the LHS of MemberExpr.
QualType getApproximateType(const Expr *E) {}

// If \p Base is ParenListExpr, assume a chain of comma operators and pick the
// last expr. We expect other ParenListExprs to be resolved to e.g. constructor
// calls before here. (So the ParenListExpr should be nonempty, but check just
// in case)
Expr *unwrapParenList(Expr *Base) {}

} // namespace

void SemaCodeCompletion::CodeCompleteMemberReferenceExpr(
    Scope *S, Expr *Base, Expr *OtherOpBase, SourceLocation OpLoc, bool IsArrow,
    bool IsBaseExprStatement, QualType PreferredType) {}

void SemaCodeCompletion::CodeCompleteObjCClassPropertyRefExpr(
    Scope *S, const IdentifierInfo &ClassName, SourceLocation ClassNameLoc,
    bool IsBaseExprStatement) {}

void SemaCodeCompletion::CodeCompleteTag(Scope *S, unsigned TagSpec) {}

static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results,
                                    const LangOptions &LangOpts) {}

void SemaCodeCompletion::CodeCompleteTypeQualifiers(DeclSpec &DS) {}

void SemaCodeCompletion::CodeCompleteFunctionQualifiers(
    DeclSpec &DS, Declarator &D, const VirtSpecifiers *VS) {}

void SemaCodeCompletion::CodeCompleteBracketDeclarator(Scope *S) {}

void SemaCodeCompletion::CodeCompleteCase(Scope *S) {}

static bool anyNullArguments(ArrayRef<Expr *> Args) {}

ResultCandidate;

static void mergeCandidatesWithResults(
    Sema &SemaRef, SmallVectorImpl<ResultCandidate> &Results,
    OverloadCandidateSet &CandidateSet, SourceLocation Loc, size_t ArgSize) {}

/// Get the type of the Nth parameter from a given set of overload
/// candidates.
static QualType getParamType(Sema &SemaRef,
                             ArrayRef<ResultCandidate> Candidates, unsigned N) {}

static QualType
ProduceSignatureHelp(Sema &SemaRef, MutableArrayRef<ResultCandidate> Candidates,
                     unsigned CurrentArg, SourceLocation OpenParLoc,
                     bool Braced) {}

// Given a callee expression `Fn`, if the call is through a function pointer,
// try to find the declaration of the corresponding function pointer type,
// so that we can recover argument names from it.
static FunctionProtoTypeLoc GetPrototypeLoc(Expr *Fn) {}

QualType
SemaCodeCompletion::ProduceCallSignatureHelp(Expr *Fn, ArrayRef<Expr *> Args,
                                             SourceLocation OpenParLoc) {}

// Determine which param to continue aggregate initialization from after
// a designated initializer.
//
// Given struct S { int a,b,c,d,e; }:
//   after `S{.b=1,`       we want to suggest c to continue
//   after `S{.b=1, 2,`    we continue with d (this is legal C and ext in C++)
//   after `S{.b=1, .a=2,` we continue with b (this is legal C and ext in C++)
//
// Possible outcomes:
//   - we saw a designator for a field, and continue from the returned index.
//     Only aggregate initialization is allowed.
//   - we saw a designator, but it was complex or we couldn't find the field.
//     Only aggregate initialization is possible, but we can't assist with it.
//     Returns an out-of-range index.
//   - we saw no designators, just positional arguments.
//     Returns std::nullopt.
static std::optional<unsigned>
getNextAggregateIndexAfterDesignatedInit(const ResultCandidate &Aggregate,
                                         ArrayRef<Expr *> Args) {}

QualType SemaCodeCompletion::ProduceConstructorSignatureHelp(
    QualType Type, SourceLocation Loc, ArrayRef<Expr *> Args,
    SourceLocation OpenParLoc, bool Braced) {}

QualType SemaCodeCompletion::ProduceCtorInitMemberSignatureHelp(
    Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy,
    ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc,
    bool Braced) {}

static bool argMatchesTemplateParams(const ParsedTemplateArgument &Arg,
                                     unsigned Index,
                                     const TemplateParameterList &Params) {}

QualType SemaCodeCompletion::ProduceTemplateArgumentSignatureHelp(
    TemplateTy ParsedTemplate, ArrayRef<ParsedTemplateArgument> Args,
    SourceLocation LAngleLoc) {}

static QualType getDesignatedType(QualType BaseType, const Designation &Desig) {}

void SemaCodeCompletion::CodeCompleteDesignator(
    QualType BaseType, llvm::ArrayRef<Expr *> InitExprs, const Designation &D) {}

void SemaCodeCompletion::CodeCompleteInitializer(Scope *S, Decl *D) {}

void SemaCodeCompletion::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {}

void SemaCodeCompletion::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
                                                 bool EnteringContext,
                                                 bool IsUsingDeclaration,
                                                 QualType BaseType,
                                                 QualType PreferredType) {}

void SemaCodeCompletion::CodeCompleteUsing(Scope *S) {}

void SemaCodeCompletion::CodeCompleteUsingDirective(Scope *S) {}

void SemaCodeCompletion::CodeCompleteNamespaceDecl(Scope *S) {}

void SemaCodeCompletion::CodeCompleteNamespaceAliasDecl(Scope *S) {}

void SemaCodeCompletion::CodeCompleteOperatorName(Scope *S) {}

void SemaCodeCompletion::CodeCompleteConstructorInitializer(
    Decl *ConstructorD, ArrayRef<CXXCtorInitializer *> Initializers) {}

/// Determine whether this scope denotes a namespace.
static bool isNamespaceScope(Scope *S) {}

void SemaCodeCompletion::CodeCompleteLambdaIntroducer(Scope *S,
                                                      LambdaIntroducer &Intro,
                                                      bool AfterAmpersand) {}

void SemaCodeCompletion::CodeCompleteAfterFunctionEquals(Declarator &D) {}

/// Macro that optionally prepends an "@" to the string literal passed in via
/// Keyword, depending on whether NeedAt is true or false.
#define OBJC_AT_KEYWORD_NAME(NeedAt, Keyword)

static void AddObjCImplementationResults(const LangOptions &LangOpts,
                                         ResultBuilder &Results, bool NeedAt) {}

static void AddObjCInterfaceResults(const LangOptions &LangOpts,
                                    ResultBuilder &Results, bool NeedAt) {}

static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {}

void SemaCodeCompletion::CodeCompleteObjCAtDirective(Scope *S) {}

static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {}

static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {}

static void AddObjCVisibilityResults(const LangOptions &LangOpts,
                                     ResultBuilder &Results, bool NeedAt) {}

void SemaCodeCompletion::CodeCompleteObjCAtVisibility(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCAtStatement(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCAtExpression(Scope *S) {}

/// Determine whether the addition of the given flag to an Objective-C
/// property's attributes will cause a conflict.
static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {}

void SemaCodeCompletion::CodeCompleteObjCPropertyFlags(Scope *S,
                                                       ObjCDeclSpec &ODS) {}

/// Describes the kind of Objective-C method that we want to find
/// via code completion.
enum ObjCMethodKind {};

static bool isAcceptableObjCSelector(Selector Sel, ObjCMethodKind WantKind,
                                     ArrayRef<const IdentifierInfo *> SelIdents,
                                     bool AllowSameLength = true) {}

static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
                                   ObjCMethodKind WantKind,
                                   ArrayRef<const IdentifierInfo *> SelIdents,
                                   bool AllowSameLength = true) {}

/// A set of selectors, which is used to avoid introducing multiple
/// completions with the same selector into the result set.
VisitedSelectorSet;

/// Add all of the Objective-C methods in the given Objective-C
/// container to the set of results.
///
/// The container will be a class, protocol, category, or implementation of
/// any of the above. This mether will recurse to include methods from
/// the superclasses of classes along with their categories, protocols, and
/// implementations.
///
/// \param Container the container in which we'll look to find methods.
///
/// \param WantInstanceMethods Whether to add instance methods (only); if
/// false, this routine will add factory methods (only).
///
/// \param CurContext the context in which we're performing the lookup that
/// finds methods.
///
/// \param AllowSameLength Whether we allow a method to be added to the list
/// when it has the same number of parameters as we have selector identifiers.
///
/// \param Results the structure into which we'll add results.
static void AddObjCMethods(ObjCContainerDecl *Container,
                           bool WantInstanceMethods, ObjCMethodKind WantKind,
                           ArrayRef<const IdentifierInfo *> SelIdents,
                           DeclContext *CurContext,
                           VisitedSelectorSet &Selectors, bool AllowSameLength,
                           ResultBuilder &Results, bool InOriginalClass = true,
                           bool IsRootClass = false) {}

void SemaCodeCompletion::CodeCompleteObjCPropertyGetter(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCPropertySetter(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
                                                     bool IsParameter) {}

/// When we have an expression with type "id", we may assume
/// that it has some more-specific class type based on knowledge of
/// common uses of Objective-C. This routine returns that class type,
/// or NULL if no better result could be determined.
static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {}

// Add a special completion for a message send to "super", which fills in the
// most likely case of forwarding all of our arguments to the superclass
// function.
///
/// \param S The semantic analysis object.
///
/// \param NeedSuperKeyword Whether we need to prefix this completion with
/// the "super" keyword. Otherwise, we just need to provide the arguments.
///
/// \param SelIdents The identifiers in the selector that have already been
/// provided as arguments for a send to "super".
///
/// \param Results The set of results to augment.
///
/// \returns the Objective-C method declaration that would be invoked by
/// this "super" completion. If NULL, no completion was added.
static ObjCMethodDecl *
AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
                       ArrayRef<const IdentifierInfo *> SelIdents,
                       ResultBuilder &Results) {}

void SemaCodeCompletion::CodeCompleteObjCMessageReceiver(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCSuperMessage(
    Scope *S, SourceLocation SuperLoc,
    ArrayRef<const IdentifierInfo *> SelIdents, bool AtArgumentExpression) {}

/// Given a set of code-completion results for the argument of a message
/// send, determine the preferred type (if any) for that argument expression.
static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
                                                       unsigned NumSelIdents) {}

static void
AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver,
                           ArrayRef<const IdentifierInfo *> SelIdents,
                           bool AtArgumentExpression, bool IsSuper,
                           ResultBuilder &Results) {}

void SemaCodeCompletion::CodeCompleteObjCClassMessage(
    Scope *S, ParsedType Receiver, ArrayRef<const IdentifierInfo *> SelIdents,
    bool AtArgumentExpression, bool IsSuper) {}

void SemaCodeCompletion::CodeCompleteObjCInstanceMessage(
    Scope *S, Expr *Receiver, ArrayRef<const IdentifierInfo *> SelIdents,
    bool AtArgumentExpression, ObjCInterfaceDecl *Super) {}

void SemaCodeCompletion::CodeCompleteObjCForCollection(
    Scope *S, DeclGroupPtrTy IterationVar) {}

void SemaCodeCompletion::CodeCompleteObjCSelector(
    Scope *S, ArrayRef<const IdentifierInfo *> SelIdents) {}

/// Add all of the protocol declarations that we find in the given
/// (translation unit) context.
static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
                               bool OnlyForwardDeclarations,
                               ResultBuilder &Results) {}

void SemaCodeCompletion::CodeCompleteObjCProtocolReferences(
    ArrayRef<IdentifierLocPair> Protocols) {}

void SemaCodeCompletion::CodeCompleteObjCProtocolDecl(Scope *) {}

/// Add all of the Objective-C interface declarations that we find in
/// the given (translation unit) context.
static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
                                bool OnlyForwardDeclarations,
                                bool OnlyUnimplemented,
                                ResultBuilder &Results) {}

void SemaCodeCompletion::CodeCompleteObjCInterfaceDecl(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCClassForwardDecl(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCSuperclass(
    Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {}

void SemaCodeCompletion::CodeCompleteObjCImplementationDecl(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCInterfaceCategory(
    Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {}

void SemaCodeCompletion::CodeCompleteObjCImplementationCategory(
    Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {}

void SemaCodeCompletion::CodeCompleteObjCPropertyDefinition(Scope *S) {}

void SemaCodeCompletion::CodeCompleteObjCPropertySynthesizeIvar(
    Scope *S, IdentifierInfo *PropertyName) {}

// Mapping from selectors to the methods that implement that selector, along
// with the "in original class" flag.
KnownMethodsMap;

/// Find all of the methods that reside in the given container
/// (and its superclasses, protocols, etc.) that meet the given
/// criteria. Insert those methods into the map of known methods,
/// indexed by selector so they can be easily found.
static void FindImplementableMethods(ASTContext &Context,
                                     ObjCContainerDecl *Container,
                                     std::optional<bool> WantInstanceMethods,
                                     QualType ReturnType,
                                     KnownMethodsMap &KnownMethods,
                                     bool InOriginalClass = true) {}

/// Add the parenthesized return or parameter type chunk to a code
/// completion string.
static void AddObjCPassingTypeChunk(QualType Type, unsigned ObjCDeclQuals,
                                    ASTContext &Context,
                                    const PrintingPolicy &Policy,
                                    CodeCompletionBuilder &Builder) {}

/// Determine whether the given class is or inherits from a class by
/// the given name.
static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, StringRef Name) {}

/// Add code completions for Objective-C Key-Value Coding (KVC) and
/// Key-Value Observing (KVO).
static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
                                       bool IsInstanceMethod,
                                       QualType ReturnType, ASTContext &Context,
                                       VisitedSelectorSet &KnownSelectors,
                                       ResultBuilder &Results) {}

void SemaCodeCompletion::CodeCompleteObjCMethodDecl(
    Scope *S, std::optional<bool> IsInstanceMethod, ParsedType ReturnTy) {}

void SemaCodeCompletion::CodeCompleteObjCMethodDeclSelector(
    Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnTy,
    ArrayRef<const IdentifierInfo *> SelIdents) {}

void SemaCodeCompletion::CodeCompletePreprocessorDirective(bool InConditional) {}

void SemaCodeCompletion::CodeCompleteInPreprocessorConditionalExclusion(
    Scope *S) {}

void SemaCodeCompletion::CodeCompletePreprocessorMacroName(bool IsDefinition) {}

void SemaCodeCompletion::CodeCompletePreprocessorExpression() {}

void SemaCodeCompletion::CodeCompletePreprocessorMacroArgument(
    Scope *S, IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned Argument) {}

// This handles completion inside an #include filename, e.g. #include <foo/ba
// We look for the directory "foo" under each directory on the include path,
// list its files, and reassemble the appropriate #include.
void SemaCodeCompletion::CodeCompleteIncludedFile(llvm::StringRef Dir,
                                                  bool Angled) {}

void SemaCodeCompletion::CodeCompleteNaturalLanguage() {}

void SemaCodeCompletion::CodeCompleteAvailabilityPlatformName() {}

void SemaCodeCompletion::GatherGlobalCodeCompletions(
    CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
    SmallVectorImpl<CodeCompletionResult> &Results) {}

SemaCodeCompletion::SemaCodeCompletion(Sema &S,
                                       CodeCompleteConsumer *CompletionConsumer)
    :{}