llvm/clang/lib/Sema/SemaExpr.cpp

//===--- SemaExpr.cpp - Semantic Analysis for Expressions -----------------===//
//
// 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 implements semantic analysis for expressions.
//
//===----------------------------------------------------------------------===//

#include "CheckExprLifetime.h"
#include "TreeTransform.h"
#include "UsedDeclVisitor.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/MangleNumberingContext.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ParentMapContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TypeTraits.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/AnalysisBasedWarnings.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/DelayedDiagnostic.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaFixItUtils.h"
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/SemaPseudoObject.h"
#include "clang/Sema/Template.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/TypeSize.h"
#include <optional>

usingnamespaceclang;
usingnamespacesema;

bool Sema::CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid) {}

static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) {}

void Sema::NoteDeletedFunction(FunctionDecl *Decl) {}

/// Determine whether a FunctionDecl was ever declared with an
/// explicit storage class.
static bool hasAnyExplicitStorageClass(const FunctionDecl *D) {}

/// Check whether we're in an extern inline function and referring to a
/// variable or function with internal linkage (C11 6.7.4p3).
///
/// This is only a warning because we used to silently accept this code, but
/// in many cases it will not behave correctly. This is not enabled in C++ mode
/// because the restriction language is a bit weaker (C++11 [basic.def.odr]p6)
/// and so while there may still be user mistakes, most of the time we can't
/// prove that there are errors.
static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S,
                                                      const NamedDecl *D,
                                                      SourceLocation Loc) {}

void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) {}

bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
                             const ObjCInterfaceDecl *UnknownObjCClass,
                             bool ObjCPropertyAccess,
                             bool AvoidPartialAvailabilityChecks,
                             ObjCInterfaceDecl *ClassReceiver,
                             bool SkipTrailingRequiresClause) {}

void Sema::DiagnoseSentinelCalls(const NamedDecl *D, SourceLocation Loc,
                                 ArrayRef<Expr *> Args) {}

SourceRange Sema::getExprRange(Expr *E) const {}

//===----------------------------------------------------------------------===//
//  Standard Promotions and Conversions
//===----------------------------------------------------------------------===//

/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {}

static void CheckForNullPointerDereference(Sema &S, Expr *E) {}

static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
                                    SourceLocation AssignLoc,
                                    const Expr* RHS) {}

ExprResult Sema::DefaultLvalueConversion(Expr *E) {}

ExprResult Sema::DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose) {}

ExprResult Sema::CallExprUnaryConversions(Expr *E) {}

/// UsualUnaryConversions - Performs various conversions that are common to most
/// operators (C99 6.3). The conversions of array and function types are
/// sometimes suppressed. For example, the array->pointer conversion doesn't
/// apply if the array is an argument to the sizeof or address (&) operators.
/// In these instances, this routine should *not* be called.
ExprResult Sema::UsualUnaryConversions(Expr *E) {}

/// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
/// do not have a prototype. Arguments that have type float or __fp16
/// are promoted to double. All other argument types are converted by
/// UsualUnaryConversions().
ExprResult Sema::DefaultArgumentPromotion(Expr *E) {}

Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) {}

void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) {}

ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
                                                  FunctionDecl *FDecl) {}

/// Convert complex integers to complex floats and real integers to
/// real floats as required for complex arithmetic. Helper function of
/// UsualArithmeticConversions()
///
/// \return false if the integer expression is an integer type and is
/// successfully converted to the (complex) float type.
static bool handleComplexIntegerToFloatConversion(Sema &S, ExprResult &IntExpr,
                                                  ExprResult &ComplexExpr,
                                                  QualType IntTy,
                                                  QualType ComplexTy,
                                                  bool SkipCast) {}

// This handles complex/complex, complex/float, or float/complex.
// When both operands are complex, the shorter operand is converted to the
// type of the longer, and that is the type of the result. This corresponds
// to what is done when combining two real floating-point operands.
// The fun begins when size promotion occur across type domains.
// From H&S 6.3.4: When one operand is complex and the other is a real
// floating-point type, the less precise type is converted, within it's
// real or complex domain, to the precision of the other type. For example,
// when combining a "long double" with a "double _Complex", the
// "double _Complex" is promoted to "long double _Complex".
static QualType handleComplexFloatConversion(Sema &S, ExprResult &Shorter,
                                             QualType ShorterType,
                                             QualType LongerType,
                                             bool PromotePrecision) {}

/// Handle arithmetic conversion with complex types.  Helper function of
/// UsualArithmeticConversions()
static QualType handleComplexConversion(Sema &S, ExprResult &LHS,
                                        ExprResult &RHS, QualType LHSType,
                                        QualType RHSType, bool IsCompAssign) {}

/// Handle arithmetic conversion from integer to float.  Helper function
/// of UsualArithmeticConversions()
static QualType handleIntToFloatConversion(Sema &S, ExprResult &FloatExpr,
                                           ExprResult &IntExpr,
                                           QualType FloatTy, QualType IntTy,
                                           bool ConvertFloat, bool ConvertInt) {}

/// Handle arithmethic conversion with floating point types.  Helper
/// function of UsualArithmeticConversions()
static QualType handleFloatConversion(Sema &S, ExprResult &LHS,
                                      ExprResult &RHS, QualType LHSType,
                                      QualType RHSType, bool IsCompAssign) {}

/// Diagnose attempts to convert between __float128, __ibm128 and
/// long double if there is no support for such conversion.
/// Helper function of UsualArithmeticConversions().
static bool unsupportedTypeConversion(const Sema &S, QualType LHSType,
                                      QualType RHSType) {}

PerformCastFn;

namespace {
/// These helper callbacks are placed in an anonymous namespace to
/// permit their use as function template parameters.
ExprResult doIntegralCast(Sema &S, Expr *op, QualType toType) {}

ExprResult doComplexIntegralCast(Sema &S, Expr *op, QualType toType) {}
}

/// Handle integer arithmetic conversions.  Helper function of
/// UsualArithmeticConversions()
template <PerformCastFn doLHSCast, PerformCastFn doRHSCast>
static QualType handleIntegerConversion(Sema &S, ExprResult &LHS,
                                        ExprResult &RHS, QualType LHSType,
                                        QualType RHSType, bool IsCompAssign) {}

/// Handle conversions with GCC complex int extension.  Helper function
/// of UsualArithmeticConversions()
static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS,
                                           ExprResult &RHS, QualType LHSType,
                                           QualType RHSType,
                                           bool IsCompAssign) {}

/// Return the rank of a given fixed point or integer type. The value itself
/// doesn't matter, but the values must be increasing with proper increasing
/// rank as described in N1169 4.1.1.
static unsigned GetFixedPointRank(QualType Ty) {}

/// handleFixedPointConversion - Fixed point operations between fixed
/// point types and integers or other fixed point types do not fall under
/// usual arithmetic conversion since these conversions could result in loss
/// of precsision (N1169 4.1.4). These operations should be calculated with
/// the full precision of their result type (N1169 4.1.6.2.1).
static QualType handleFixedPointConversion(Sema &S, QualType LHSTy,
                                           QualType RHSTy) {}

/// Check that the usual arithmetic conversions can be performed on this pair of
/// expressions that might be of enumeration type.
static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS,
                                           SourceLocation Loc,
                                           Sema::ArithConvKind ACK) {}

/// UsualArithmeticConversions - Performs various conversions that are common to
/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
/// routine returns the first non-arithmetic type found. The client is
/// responsible for emitting appropriate error diagnostics.
QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
                                          SourceLocation Loc,
                                          ArithConvKind ACK) {}

//===----------------------------------------------------------------------===//
//  Semantic Analysis for various Expression Types
//===----------------------------------------------------------------------===//


ExprResult Sema::ActOnGenericSelectionExpr(
    SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc,
    bool PredicateIsExpr, void *ControllingExprOrType,
    ArrayRef<ParsedType> ArgTypes, ArrayRef<Expr *> ArgExprs) {}

ExprResult Sema::CreateGenericSelectionExpr(
    SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc,
    bool PredicateIsExpr, void *ControllingExprOrType,
    ArrayRef<TypeSourceInfo *> Types, ArrayRef<Expr *> Exprs) {}

static PredefinedIdentKind getPredefinedExprKind(tok::TokenKind Kind) {}

/// getPredefinedExprDecl - Returns Decl of a given DeclContext that can be used
/// to determine the value of a PredefinedExpr. This can be either a
/// block, lambda, captured statement, function, otherwise a nullptr.
static Decl *getPredefinedExprDecl(DeclContext *DC) {}

/// getUDSuffixLoc - Create a SourceLocation for a ud-suffix, given the
/// location of the token and the offset of the ud-suffix within it.
static SourceLocation getUDSuffixLoc(Sema &S, SourceLocation TokLoc,
                                     unsigned Offset) {}

/// BuildCookedLiteralOperatorCall - A user-defined literal was found. Look up
/// the corresponding cooked (non-raw) literal operator, and build a call to it.
static ExprResult BuildCookedLiteralOperatorCall(Sema &S, Scope *Scope,
                                                 IdentifierInfo *UDSuffix,
                                                 SourceLocation UDSuffixLoc,
                                                 ArrayRef<Expr*> Args,
                                                 SourceLocation LitEndLoc) {}

ExprResult Sema::ActOnUnevaluatedStringLiteral(ArrayRef<Token> StringToks) {}

std::vector<Token>
Sema::ExpandFunctionLocalPredefinedMacros(ArrayRef<Token> Toks) {}

ExprResult
Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {}

DeclRefExpr *
Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
                       SourceLocation Loc,
                       const CXXScopeSpec *SS) {}

DeclRefExpr *
Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
                       const DeclarationNameInfo &NameInfo,
                       const CXXScopeSpec *SS, NamedDecl *FoundD,
                       SourceLocation TemplateKWLoc,
                       const TemplateArgumentListInfo *TemplateArgs) {}

// CUDA/HIP: Check whether a captured reference variable is referencing a
// host variable in a device or host device lambda.
static bool isCapturingReferenceToHostVarInCUDADeviceLambda(const Sema &S,
                                                            VarDecl *VD) {}

NonOdrUseReason Sema::getNonOdrUseReasonInCurrentContext(ValueDecl *D) {}

DeclRefExpr *
Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
                       const DeclarationNameInfo &NameInfo,
                       NestedNameSpecifierLoc NNS, NamedDecl *FoundD,
                       SourceLocation TemplateKWLoc,
                       const TemplateArgumentListInfo *TemplateArgs) {}

void
Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id,
                             TemplateArgumentListInfo &Buffer,
                             DeclarationNameInfo &NameInfo,
                             const TemplateArgumentListInfo *&TemplateArgs) {}

static void emitEmptyLookupTypoDiagnostic(
    const TypoCorrection &TC, Sema &SemaRef, const CXXScopeSpec &SS,
    DeclarationName Typo, SourceLocation TypoLoc, ArrayRef<Expr *> Args,
    unsigned DiagnosticID, unsigned DiagnosticSuggestID) {}

bool Sema::DiagnoseDependentMemberLookup(const LookupResult &R) {}

bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
                               CorrectionCandidateCallback &CCC,
                               TemplateArgumentListInfo *ExplicitTemplateArgs,
                               ArrayRef<Expr *> Args, DeclContext *LookupCtx,
                               TypoExpr **Out) {}

/// In Microsoft mode, if we are inside a template class whose parent class has
/// dependent base classes, and we can't resolve an unqualified identifier, then
/// assume the identifier is a member of a dependent base class.  We can only
/// recover successfully in static methods, instance methods, and other contexts
/// where 'this' is available.  This doesn't precisely match MSVC's
/// instantiation model, but it's close enough.
static Expr *
recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context,
                               DeclarationNameInfo &NameInfo,
                               SourceLocation TemplateKWLoc,
                               const TemplateArgumentListInfo *TemplateArgs) {}

ExprResult
Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
                        SourceLocation TemplateKWLoc, UnqualifiedId &Id,
                        bool HasTrailingLParen, bool IsAddressOfOperand,
                        CorrectionCandidateCallback *CCC,
                        bool IsInlineAsmIdentifier, Token *KeywordReplacement) {}

ExprResult Sema::BuildQualifiedDeclarationNameExpr(
    CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo,
    bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI) {}

ExprResult
Sema::PerformObjectMemberConversion(Expr *From,
                                    NestedNameSpecifier *Qualifier,
                                    NamedDecl *FoundDecl,
                                    NamedDecl *Member) {}

bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS,
                                      const LookupResult &R,
                                      bool HasTrailingLParen) {}


/// Diagnoses obvious problems with the use of the given declaration
/// as an expression.  This is only actually called for lookups that
/// were not overloaded, and it doesn't promise that the declaration
/// will in fact be used.
static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D,
                            bool AcceptInvalid) {}

// Certain multiversion types should be treated as overloaded even when there is
// only one result.
static bool ShouldLookupResultBeMultiVersionOverload(const LookupResult &R) {}

ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
                                          LookupResult &R, bool NeedsADL,
                                          bool AcceptInvalidDecl) {}

static void diagnoseUncapturableValueReferenceOrBinding(Sema &S,
                                                        SourceLocation loc,
                                                        ValueDecl *var);

ExprResult Sema::BuildDeclarationNameExpr(
    const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
    NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs,
    bool AcceptInvalidDecl) {}

static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
                                    SmallString<32> &Target) {}

ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
                                     PredefinedIdentKind IK) {}

ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {}

ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {}

ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {}

static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,
                                  QualType Ty, SourceLocation Loc) {}

bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc, bool AllowZero) {}

ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {}

ExprResult Sema::ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E) {}

static bool CheckVecStepTraitOperandType(Sema &S, QualType T,
                                         SourceLocation Loc,
                                         SourceRange ArgRange) {}

static bool CheckVectorElementsTraitOperandType(Sema &S, QualType T,
                                                SourceLocation Loc,
                                                SourceRange ArgRange) {}

static bool checkPtrAuthTypeDiscriminatorOperandType(Sema &S, QualType T,
                                                     SourceLocation Loc,
                                                     SourceRange ArgRange) {}

static bool CheckExtensionTraitOperandType(Sema &S, QualType T,
                                           SourceLocation Loc,
                                           SourceRange ArgRange,
                                           UnaryExprOrTypeTrait TraitKind) {}

static bool CheckObjCTraitOperandConstraints(Sema &S, QualType T,
                                             SourceLocation Loc,
                                             SourceRange ArgRange,
                                             UnaryExprOrTypeTrait TraitKind) {}

/// Check whether E is a pointer from a decayed array type (the decayed
/// pointer type is equal to T) and emit a warning if it is.
static void warnOnSizeofOnArrayDecay(Sema &S, SourceLocation Loc, QualType T,
                                     const Expr *E) {}

bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
                                            UnaryExprOrTypeTrait ExprKind) {}

static bool CheckAlignOfExpr(Sema &S, Expr *E, UnaryExprOrTypeTrait ExprKind) {}

bool Sema::CheckVecStepExpr(Expr *E) {}

static void captureVariablyModifiedType(ASTContext &Context, QualType T,
                                        CapturingScopeInfo *CSI) {}

bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
                                            SourceLocation OpLoc,
                                            SourceRange ExprRange,
                                            UnaryExprOrTypeTrait ExprKind,
                                            StringRef KWName) {}

ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
                                                SourceLocation OpLoc,
                                                UnaryExprOrTypeTrait ExprKind,
                                                SourceRange R) {}

ExprResult
Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
                                     UnaryExprOrTypeTrait ExprKind) {}

ExprResult
Sema::ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc,
                                    UnaryExprOrTypeTrait ExprKind, bool IsType,
                                    void *TyOrEx, SourceRange ArgRange) {}

bool Sema::CheckAlignasTypeArgument(StringRef KWName, TypeSourceInfo *TInfo,
                                    SourceLocation OpLoc, SourceRange R) {}

bool Sema::ActOnAlignasTypeArgument(StringRef KWName, ParsedType Ty,
                                    SourceLocation OpLoc, SourceRange R) {}

static QualType CheckRealImagOperand(Sema &S, ExprResult &V, SourceLocation Loc,
                                     bool IsReal) {}



ExprResult
Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
                          tok::TokenKind Kind, Expr *Input) {}

/// Diagnose if arithmetic on the given ObjC pointer is illegal.
///
/// \return true on error
static bool checkArithmeticOnObjCPointer(Sema &S,
                                         SourceLocation opLoc,
                                         Expr *op) {}

static bool isMSPropertySubscriptExpr(Sema &S, Expr *Base) {}

// Returns the type used for LHS[RHS], given one of LHS, RHS is type-dependent.
// Typically this is DependentTy, but can sometimes be more precise.
//
// There are cases when we could determine a non-dependent type:
//  - LHS and RHS may have non-dependent types despite being type-dependent
//    (e.g. unbounded array static members of the current instantiation)
//  - one may be a dependent-sized array with known element type
//  - one may be a dependent-typed valid index (enum in current instantiation)
//
// We *always* return a dependent type, in such cases it is DependentTy.
// This avoids creating type-dependent expressions with non-dependent types.
// FIXME: is this important to avoid? See https://reviews.llvm.org/D107275
static QualType getDependentArraySubscriptType(Expr *LHS, Expr *RHS,
                                               const ASTContext &Ctx) {}

ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base,
                                         SourceLocation lbLoc,
                                         MultiExprArg ArgExprs,
                                         SourceLocation rbLoc) {}

ExprResult Sema::tryConvertExprToType(Expr *E, QualType Ty) {}

ExprResult Sema::CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
                                                  Expr *ColumnIdx,
                                                  SourceLocation RBLoc) {}

void Sema::CheckAddressOfNoDeref(const Expr *E) {}

void Sema::CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E) {}

ExprResult
Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
                                      Expr *Idx, SourceLocation RLoc) {}

bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
                                  ParmVarDecl *Param, Expr *RewrittenInit,
                                  bool SkipImmediateInvocations) {}

struct ImmediateCallVisitor : public RecursiveASTVisitor<ImmediateCallVisitor> {};

struct EnsureImmediateInvocationInDefaultArgs
    : TreeTransform<EnsureImmediateInvocationInDefaultArgs> {};

ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
                                        FunctionDecl *FD, ParmVarDecl *Param,
                                        Expr *Init) {}

ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {}

Sema::VariadicCallType
Sema::getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto,
                          Expr *Fn) {}

namespace {
class FunctionCallCCC final : public FunctionCallFilterCCC {};
}

static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn,
                                               FunctionDecl *FDecl,
                                               ArrayRef<Expr *> Args) {}

// [C++26][[expr.unary.op]/p4
// A pointer to member is only formed when an explicit &
// is used and its operand is a qualified-id not enclosed in parentheses.
static bool isParenthetizedAndQualifiedAddressOfExpr(Expr *Fn) {}

bool
Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
                              FunctionDecl *FDecl,
                              const FunctionProtoType *Proto,
                              ArrayRef<Expr *> Args,
                              SourceLocation RParenLoc,
                              bool IsExecConfig) {}

bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
                                  const FunctionProtoType *Proto,
                                  unsigned FirstParam, ArrayRef<Expr *> Args,
                                  SmallVectorImpl<Expr *> &AllArgs,
                                  VariadicCallType CallType, bool AllowExplicit,
                                  bool IsListInitialization) {}

static void DiagnoseCalleeStaticArrayParam(Sema &S, ParmVarDecl *PVD) {}

void
Sema::CheckStaticArrayArgument(SourceLocation CallLoc,
                               ParmVarDecl *Param,
                               const Expr *ArgExpr) {}

/// Given a function expression of unknown-any type, try to rebuild it
/// to have a function type.
static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn);

/// Is the given type a placeholder that we need to lower out
/// immediately during argument processing?
static bool isPlaceholderToRemoveAsArg(QualType type) {}

bool Sema::CheckArgsForPlaceholders(MultiExprArg args) {}

/// If a builtin function has a pointer argument with no explicit address
/// space, then it should be able to accept a pointer to any address
/// space as input.  In order to do this, we need to replace the
/// standard builtin declaration with one that uses the same address space
/// as the call.
///
/// \returns nullptr If this builtin is not a candidate for a rewrite i.e.
///                  it does not contain any pointer arguments without
///                  an address space qualifer.  Otherwise the rewritten
///                  FunctionDecl is returned.
/// TODO: Handle pointer return types.
static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context,
                                                FunctionDecl *FDecl,
                                                MultiExprArg ArgExprs) {}

static void checkDirectCallValidity(Sema &S, const Expr *Fn,
                                    FunctionDecl *Callee,
                                    MultiExprArg ArgExprs) {}

static bool enclosingClassIsRelatedToClassInWhichMembersWereFound(
    const UnresolvedMemberExpr *const UME, Sema &S) {}

static void
tryImplicitlyCaptureThisIfImplicitMemberFunctionAccessWithDependentArgs(
    Sema &S, const UnresolvedMemberExpr *const UME, SourceLocation CallLoc) {}

// Once a call is fully resolved, warn for unqualified calls to specific
// C++ standard functions, like move and forward.
static void DiagnosedUnqualifiedCallsToStdFunctions(Sema &S,
                                                    const CallExpr *Call) {}

ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
                               MultiExprArg ArgExprs, SourceLocation RParenLoc,
                               Expr *ExecConfig) {}

ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
                               MultiExprArg ArgExprs, SourceLocation RParenLoc,
                               Expr *ExecConfig, bool IsExecConfig,
                               bool AllowRecovery) {}

Expr *Sema::BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id,
                                 MultiExprArg CallArgs) {}

ExprResult Sema::ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy,
                                 SourceLocation BuiltinLoc,
                                 SourceLocation RParenLoc) {}

ExprResult Sema::BuildAsTypeExpr(Expr *E, QualType DestTy,
                                 SourceLocation BuiltinLoc,
                                 SourceLocation RParenLoc) {}

ExprResult Sema::ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy,
                                        SourceLocation BuiltinLoc,
                                        SourceLocation RParenLoc) {}

ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
                                       SourceLocation LParenLoc,
                                       ArrayRef<Expr *> Args,
                                       SourceLocation RParenLoc, Expr *Config,
                                       bool IsExecConfig, ADLCallKind UsesADL) {}

ExprResult
Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
                           SourceLocation RParenLoc, Expr *InitExpr) {}

ExprResult
Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
                               SourceLocation RParenLoc, Expr *LiteralExpr) {}

ExprResult
Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
                    SourceLocation RBraceLoc) {}

ExprResult
Sema::BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
                    SourceLocation RBraceLoc) {}

void Sema::maybeExtendBlockObject(ExprResult &E) {}

CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {}

static bool breakDownVectorType(QualType type, uint64_t &len,
                                QualType &eltType) {}

bool Sema::isValidSveBitcast(QualType srcTy, QualType destTy) {}

bool Sema::areMatrixTypesOfTheSameDimension(QualType srcTy, QualType destTy) {}

bool Sema::areVectorTypesSameSize(QualType SrcTy, QualType DestTy) {}

bool Sema::anyAltivecTypes(QualType SrcTy, QualType DestTy) {}

bool Sema::areLaxCompatibleVectorTypes(QualType srcTy, QualType destTy) {}

bool Sema::isLaxVectorConversion(QualType srcTy, QualType destTy) {}

bool Sema::CheckMatrixCast(SourceRange R, QualType DestTy, QualType SrcTy,
                           CastKind &Kind) {}

bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
                           CastKind &Kind) {}

ExprResult Sema::prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr) {}

ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy,
                                    Expr *CastExpr, CastKind &Kind) {}

ExprResult
Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
                    Declarator &D, ParsedType &Ty,
                    SourceLocation RParenLoc, Expr *CastExpr) {}

ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,
                                    SourceLocation RParenLoc, Expr *E,
                                    TypeSourceInfo *TInfo) {}

ExprResult
Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {}

ExprResult Sema::ActOnParenListExpr(SourceLocation L,
                                    SourceLocation R,
                                    MultiExprArg Val) {}

bool Sema::DiagnoseConditionalForNull(const Expr *LHSExpr, const Expr *RHSExpr,
                                      SourceLocation QuestionLoc) {}

/// Return false if the condition expression is valid, true otherwise.
static bool checkCondition(Sema &S, const Expr *Cond,
                           SourceLocation QuestionLoc) {}

/// Return false if the NullExpr can be promoted to PointerTy,
/// true otherwise.
static bool checkConditionalNullPointer(Sema &S, ExprResult &NullExpr,
                                        QualType PointerTy) {}

/// Checks compatibility between two pointers and return the resulting
/// type.
static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
                                                     ExprResult &RHS,
                                                     SourceLocation Loc) {}

/// Return the resulting type when the operands are both block pointers.
static QualType checkConditionalBlockPointerCompatibility(Sema &S,
                                                          ExprResult &LHS,
                                                          ExprResult &RHS,
                                                          SourceLocation Loc) {}

/// Return the resulting type when the operands are both pointers.
static QualType
checkConditionalObjectPointersCompatibility(Sema &S, ExprResult &LHS,
                                            ExprResult &RHS,
                                            SourceLocation Loc) {}

/// Return false if the first expression is not an integer and the second
/// expression is not a pointer, true otherwise.
static bool checkPointerIntegerMismatch(Sema &S, ExprResult &Int,
                                        Expr* PointerExpr, SourceLocation Loc,
                                        bool IsIntFirstExpr) {}

/// Simple conversion between integer and floating point types.
///
/// Used when handling the OpenCL conditional operator where the
/// condition is a vector while the other operands are scalar.
///
/// OpenCL v1.1 s6.3.i and s6.11.6 together require that the scalar
/// types are either integer or floating type. Between the two
/// operands, the type with the higher rank is defined as the "result
/// type". The other operand needs to be promoted to the same type. No
/// other type promotion is allowed. We cannot use
/// UsualArithmeticConversions() for this purpose, since it always
/// promotes promotable types.
static QualType OpenCLArithmeticConversions(Sema &S, ExprResult &LHS,
                                            ExprResult &RHS,
                                            SourceLocation QuestionLoc) {}

/// Convert scalar operands to a vector that matches the
///        condition in length.
///
/// Used when handling the OpenCL conditional operator where the
/// condition is a vector while the other operands are scalar.
///
/// We first compute the "result type" for the scalar operands
/// according to OpenCL v1.1 s6.3.i. Both operands are then converted
/// into a vector of that type where the length matches the condition
/// vector type. s6.11.6 requires that the element types of the result
/// and the condition must have the same number of bits.
static QualType
OpenCLConvertScalarsToVectors(Sema &S, ExprResult &LHS, ExprResult &RHS,
                              QualType CondTy, SourceLocation QuestionLoc) {}

/// Return false if this is a valid OpenCL condition vector
static bool checkOpenCLConditionVector(Sema &S, Expr *Cond,
                                       SourceLocation QuestionLoc) {}

/// Return false if the vector condition type and the vector
///        result type are compatible.
///
/// OpenCL v1.1 s6.11.6 requires that both vector types have the same
/// number of elements, and their element types have the same number
/// of bits.
static bool checkVectorResult(Sema &S, QualType CondTy, QualType VecResTy,
                              SourceLocation QuestionLoc) {}

/// Return the resulting type for the conditional operator in
///        OpenCL (aka "ternary selection operator", OpenCL v1.1
///        s6.3.i) when the condition is a vector type.
static QualType
OpenCLCheckVectorConditional(Sema &S, ExprResult &Cond,
                             ExprResult &LHS, ExprResult &RHS,
                             SourceLocation QuestionLoc) {}

/// Return true if the Expr is block type
static bool checkBlockType(Sema &S, const Expr *E) {}

/// Note that LHS is not null here, even if this is the gnu "x ?: y" extension.
/// In that case, LHS = cond.
/// C99 6.5.15
QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
                                        ExprResult &RHS, ExprValueKind &VK,
                                        ExprObjectKind &OK,
                                        SourceLocation QuestionLoc) {}

/// SuggestParentheses - Emit a note with a fixit hint that wraps
/// ParenRange in parentheses.
static void SuggestParentheses(Sema &Self, SourceLocation Loc,
                               const PartialDiagnostic &Note,
                               SourceRange ParenRange) {}

static bool IsArithmeticOp(BinaryOperatorKind Opc) {}

/// IsArithmeticBinaryExpr - Returns true if E is an arithmetic binary
/// expression, either using a built-in or overloaded operator,
/// and sets *OpCode to the opcode and *RHSExprs to the right-hand side
/// expression.
static bool IsArithmeticBinaryExpr(const Expr *E, BinaryOperatorKind *Opcode,
                                   const Expr **RHSExprs) {}

/// ExprLooksBoolean - Returns true if E looks boolean, i.e. it has boolean type
/// or is a logical expression such as (x==y) which has int type, but is
/// commonly interpreted as boolean.
static bool ExprLooksBoolean(const Expr *E) {}

/// DiagnoseConditionalPrecedence - Emit a warning when a conditional operator
/// and binary operator are mixed in a way that suggests the programmer assumed
/// the conditional operator has higher precedence, for example:
/// "int x = a + someBinaryCondition ? 1 : 2".
static void DiagnoseConditionalPrecedence(Sema &Self, SourceLocation OpLoc,
                                          Expr *Condition, const Expr *LHSExpr,
                                          const Expr *RHSExpr) {}

/// Compute the nullability of a conditional expression.
static QualType computeConditionalNullability(QualType ResTy, bool IsBin,
                                              QualType LHSTy, QualType RHSTy,
                                              ASTContext &Ctx) {}

ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
                                    SourceLocation ColonLoc,
                                    Expr *CondExpr, Expr *LHSExpr,
                                    Expr *RHSExpr) {}

bool Sema::IsInvalidSMECallConversion(QualType FromType, QualType ToType) {}

// Check if we have a conversion between incompatible cmse function pointer
// types, that is, a conversion between a function pointer with the
// cmse_nonsecure_call attribute and one without.
static bool IsInvalidCmseNSCallConversion(Sema &S, QualType FromType,
                                          QualType ToType) {}

// checkPointerTypesForAssignment - This is a very tricky routine (despite
// being closely modeled after the C99 spec:-). The odd characteristic of this
// routine is it effectively iqnores the qualifiers on the top level pointee.
// This circumvents the usual type rules specified in 6.2.7p1 & 6.7.5.[1-3].
// FIXME: add a couple examples in this comment.
static Sema::AssignConvertType
checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType,
                               SourceLocation Loc) {}

/// checkBlockPointerTypesForAssignment - This routine determines whether two
/// block pointer types are compatible or whether a block and normal pointer
/// are compatible. It is more restrict than comparing two function pointer
// types.
static Sema::AssignConvertType
checkBlockPointerTypesForAssignment(Sema &S, QualType LHSType,
                                    QualType RHSType) {}

/// checkObjCPointerTypesForAssignment - Compares two objective-c pointer types
/// for assignment compatibility.
static Sema::AssignConvertType
checkObjCPointerTypesForAssignment(Sema &S, QualType LHSType,
                                   QualType RHSType) {}

Sema::AssignConvertType
Sema::CheckAssignmentConstraints(SourceLocation Loc,
                                 QualType LHSType, QualType RHSType) {}

/// This helper function returns true if QT is a vector type that has element
/// type ElementType.
static bool isVector(QualType QT, QualType ElementType) {}

/// CheckAssignmentConstraints (C99 6.5.16) - This routine currently
/// has code to accommodate several GCC extensions when type checking
/// pointers. Here are some objectionable examples that GCC considers warnings:
///
///  int a, *pint;
///  short *pshort;
///  struct foo *pfoo;
///
///  pint = pshort; // warning: assignment from incompatible pointer type
///  a = pint; // warning: assignment makes integer from pointer without a cast
///  pint = a; // warning: assignment makes pointer from integer without a cast
///  pint = pfoo; // warning: assignment from incompatible pointer type
///
/// As a result, the code for dealing with pointers is more complex than the
/// C99 spec dictates.
///
/// Sets 'Kind' for any result kind except Incompatible.
Sema::AssignConvertType
Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
                                 CastKind &Kind, bool ConvertRHS) {}

/// Constructs a transparent union from an expression that is
/// used to initialize the transparent union.
static void ConstructTransparentUnion(Sema &S, ASTContext &C,
                                      ExprResult &EResult, QualType UnionType,
                                      FieldDecl *Field) {}

Sema::AssignConvertType
Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType,
                                               ExprResult &RHS) {}

Sema::AssignConvertType
Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
                                       bool Diagnose,
                                       bool DiagnoseCFAudited,
                                       bool ConvertRHS) {}

namespace {
/// The original operand to an operator, prior to the application of the usual
/// arithmetic conversions and converting the arguments of a builtin operator
/// candidate.
struct OriginalOperand {};
}

QualType Sema::InvalidOperands(SourceLocation Loc, ExprResult &LHS,
                               ExprResult &RHS) {}

QualType Sema::InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS,
                                            ExprResult &RHS) {}

/// Try to convert a value of non-vector type to a vector type by converting
/// the type to the element type of the vector and then performing a splat.
/// If the language is OpenCL, we only use conversions that promote scalar
/// rank; for C, Obj-C, and C++ we allow any real scalar conversion except
/// for float->int.
///
/// OpenCL V2.0 6.2.6.p2:
/// An error shall occur if any scalar operand type has greater rank
/// than the type of the vector element.
///
/// \param scalar - if non-null, actually perform the conversions
/// \return true if the operation fails (but without diagnosing the failure)
static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
                                     QualType scalarTy,
                                     QualType vectorEltTy,
                                     QualType vectorTy,
                                     unsigned &DiagID) {}

/// Convert vector E to a vector with the same number of elements but different
/// element type.
static ExprResult convertVector(Expr *E, QualType ElementType, Sema &S) {}

/// Test if a (constant) integer Int can be casted to another integer type
/// IntTy without losing precision.
static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
                                      QualType OtherIntTy) {}

/// Test if a (constant) integer Int can be casted to floating point type
/// FloatTy without losing precision.
static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,
                                     QualType FloatTy) {}

/// Attempt to convert and splat Scalar into a vector whose types matches
/// Vector following GCC conversion rules. The rule is that implicit
/// conversion can occur when Scalar can be casted to match Vector's element
/// type without causing truncation of Scalar.
static bool tryGCCVectorConvertAndSplat(Sema &S, ExprResult *Scalar,
                                        ExprResult *Vector) {}

QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
                                   SourceLocation Loc, bool IsCompAssign,
                                   bool AllowBothBool,
                                   bool AllowBoolConversions,
                                   bool AllowBoolOperation,
                                   bool ReportInvalid) {}

QualType Sema::CheckSizelessVectorOperands(ExprResult &LHS, ExprResult &RHS,
                                           SourceLocation Loc,
                                           bool IsCompAssign,
                                           ArithConvKind OperationKind) {}

// checkArithmeticNull - Detect when a NULL constant is used improperly in an
// expression.  These are mainly cases where the null pointer is used as an
// integer instead of a pointer.
static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS,
                                SourceLocation Loc, bool IsCompare) {}

static void DiagnoseDivisionSizeofPointerOrArray(Sema &S, Expr *LHS, Expr *RHS,
                                          SourceLocation Loc) {}

static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS,
                                               ExprResult &RHS,
                                               SourceLocation Loc, bool IsDiv) {}

QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS,
                                           SourceLocation Loc,
                                           bool IsCompAssign, bool IsDiv) {}

QualType Sema::CheckRemainderOperands(
  ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) {}

/// Diagnose invalid arithmetic on two void pointers.
static void diagnoseArithmeticOnTwoVoidPointers(Sema &S, SourceLocation Loc,
                                                Expr *LHSExpr, Expr *RHSExpr) {}

/// Diagnose invalid arithmetic on a void pointer.
static void diagnoseArithmeticOnVoidPointer(Sema &S, SourceLocation Loc,
                                            Expr *Pointer) {}

/// Diagnose invalid arithmetic on a null pointer.
///
/// If \p IsGNUIdiom is true, the operation is using the 'p = (i8*)nullptr + n'
/// idiom, which we recognize as a GNU extension.
///
static void diagnoseArithmeticOnNullPointer(Sema &S, SourceLocation Loc,
                                            Expr *Pointer, bool IsGNUIdiom) {}

/// Diagnose invalid subraction on a null pointer.
///
static void diagnoseSubtractionOnNullPointer(Sema &S, SourceLocation Loc,
                                             Expr *Pointer, bool BothNull) {}

/// Diagnose invalid arithmetic on two function pointers.
static void diagnoseArithmeticOnTwoFunctionPointers(Sema &S, SourceLocation Loc,
                                                    Expr *LHS, Expr *RHS) {}

/// Diagnose invalid arithmetic on a function pointer.
static void diagnoseArithmeticOnFunctionPointer(Sema &S, SourceLocation Loc,
                                                Expr *Pointer) {}

/// Emit error if Operand is incomplete pointer type
///
/// \returns True if pointer has incomplete type
static bool checkArithmeticIncompletePointerType(Sema &S, SourceLocation Loc,
                                                 Expr *Operand) {}

/// Check the validity of an arithmetic pointer operand.
///
/// If the operand has pointer type, this code will check for pointer types
/// which are invalid in arithmetic operations. These will be diagnosed
/// appropriately, including whether or not the use is supported as an
/// extension.
///
/// \returns True when the operand is valid to use (even if as an extension).
static bool checkArithmeticOpPointerOperand(Sema &S, SourceLocation Loc,
                                            Expr *Operand) {}

/// Check the validity of a binary arithmetic operation w.r.t. pointer
/// operands.
///
/// This routine will diagnose any invalid arithmetic on pointer operands much
/// like \see checkArithmeticOpPointerOperand. However, it has special logic
/// for emitting a single diagnostic even for operations where both LHS and RHS
/// are (potentially problematic) pointers.
///
/// \returns True when the operand is valid to use (even if as an extension).
static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc,
                                                Expr *LHSExpr, Expr *RHSExpr) {}

/// diagnoseStringPlusInt - Emit a warning when adding an integer to a string
/// literal.
static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc,
                                  Expr *LHSExpr, Expr *RHSExpr) {}

/// Emit a warning when adding a char literal to a string.
static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc,
                                   Expr *LHSExpr, Expr *RHSExpr) {}

/// Emit error when two pointers are incompatible.
static void diagnosePointerIncompatibility(Sema &S, SourceLocation Loc,
                                           Expr *LHSExpr, Expr *RHSExpr) {}

// C99 6.5.6
QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
                                     SourceLocation Loc, BinaryOperatorKind Opc,
                                     QualType* CompLHSTy) {}

// C99 6.5.6
QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
                                        SourceLocation Loc,
                                        QualType* CompLHSTy) {}

static bool isScopedEnumerationType(QualType T) {}

static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
                                   SourceLocation Loc, BinaryOperatorKind Opc,
                                   QualType LHSType) {}

/// Return the resulting type when a vector is shifted
///        by a scalar or vector shift amount.
static QualType checkVectorShift(Sema &S, ExprResult &LHS, ExprResult &RHS,
                                 SourceLocation Loc, bool IsCompAssign) {}

static QualType checkSizelessVectorShift(Sema &S, ExprResult &LHS,
                                         ExprResult &RHS, SourceLocation Loc,
                                         bool IsCompAssign) {}

// C99 6.5.7
QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
                                  SourceLocation Loc, BinaryOperatorKind Opc,
                                  bool IsCompAssign) {}

/// Diagnose bad pointer comparisons.
static void diagnoseDistinctPointerComparison(Sema &S, SourceLocation Loc,
                                              ExprResult &LHS, ExprResult &RHS,
                                              bool IsError) {}

/// Returns false if the pointers are converted to a composite type,
/// true otherwise.
static bool convertPointersToCompositeType(Sema &S, SourceLocation Loc,
                                           ExprResult &LHS, ExprResult &RHS) {}

static void diagnoseFunctionPointerToVoidComparison(Sema &S, SourceLocation Loc,
                                                    ExprResult &LHS,
                                                    ExprResult &RHS,
                                                    bool IsError) {}

static bool isObjCObjectLiteral(ExprResult &E) {}

static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) {}

static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc,
                                          ExprResult &LHS, ExprResult &RHS,
                                          BinaryOperator::Opcode Opc){}

/// Warns on !x < y, !x & y where !(x < y), !(x & y) was probably intended.
static void diagnoseLogicalNotOnLHSofCheck(Sema &S, ExprResult &LHS,
                                           ExprResult &RHS, SourceLocation Loc,
                                           BinaryOperatorKind Opc) {}

// Returns true if E refers to a non-weak array.
static bool checkForArray(const Expr *E) {}

/// Diagnose some forms of syntactically-obvious tautological comparison.
static void diagnoseTautologicalComparison(Sema &S, SourceLocation Loc,
                                           Expr *LHS, Expr *RHS,
                                           BinaryOperatorKind Opc) {}

static ImplicitConversionKind castKindToImplicitConversionKind(CastKind CK) {}

static bool checkThreeWayNarrowingConversion(Sema &S, QualType ToType, Expr *E,
                                             QualType FromType,
                                             SourceLocation Loc) {}

static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
                                                         ExprResult &LHS,
                                                         ExprResult &RHS,
                                                         SourceLocation Loc) {}

static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS,
                                                 ExprResult &RHS,
                                                 SourceLocation Loc,
                                                 BinaryOperatorKind Opc) {}

void Sema::CheckPtrComparisonWithNullChar(ExprResult &E, ExprResult &NullE) {}

// C99 6.5.8, C++ [expr.rel]
QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
                                    SourceLocation Loc,
                                    BinaryOperatorKind Opc) {}

QualType Sema::GetSignedVectorType(QualType V) {}

QualType Sema::GetSignedSizelessVectorType(QualType V) {}

QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
                                          SourceLocation Loc,
                                          BinaryOperatorKind Opc) {}

QualType Sema::CheckSizelessVectorCompareOperands(ExprResult &LHS,
                                                  ExprResult &RHS,
                                                  SourceLocation Loc,
                                                  BinaryOperatorKind Opc) {}

static void diagnoseXorMisusedAsPow(Sema &S, const ExprResult &XorLHS,
                                    const ExprResult &XorRHS,
                                    const SourceLocation Loc) {}

QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
                                          SourceLocation Loc) {}

QualType Sema::CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS,
                                              SourceLocation Loc,
                                              bool IsCompAssign) {}

QualType Sema::CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS,
                                           SourceLocation Loc,
                                           bool IsCompAssign) {}

static bool isLegalBoolVectorBinaryOp(BinaryOperatorKind Opc) {}

inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
                                           SourceLocation Loc,
                                           BinaryOperatorKind Opc) {}

// C99 6.5.[13,14]
inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
                                           SourceLocation Loc,
                                           BinaryOperatorKind Opc) {}

static bool IsReadonlyMessage(Expr *E, Sema &S) {}

/// Is the given expression (which must be 'const') a reference to a
/// variable which was originally non-const, but which has become
/// 'const' due to being captured within a block?
enum NonConstCaptureKind {};
static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {}

static bool IsTypeModifiable(QualType Ty, bool IsDereference) {}

// Update err_typecheck_assign_const and note_typecheck_assign_const
// when this enum is changed.
enum {};

/// Emit the "read-only variable not assignable" error and print notes to give
/// more information about why the variable is not assignable, such as pointing
/// to the declaration of a const variable, showing that a method is const, or
/// that the function is returning a const reference.
static void DiagnoseConstAssignment(Sema &S, const Expr *E,
                                    SourceLocation Loc) {}

enum OriginalExprKind {};

static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD,
                                         const RecordType *Ty,
                                         SourceLocation Loc, SourceRange Range,
                                         OriginalExprKind OEK,
                                         bool &DiagnosticEmitted) {}

/// Emit an error for the case where a record we are trying to assign to has a
/// const-qualified field somewhere in its hierarchy.
static void DiagnoseRecursiveConstFields(Sema &S, const Expr *E,
                                         SourceLocation Loc) {}

/// CheckForModifiableLvalue - Verify that E is a modifiable lvalue.  If not,
/// emit an error and return true.  If so, return false.
static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {}

static void CheckIdentityFieldAssignment(Expr *LHSExpr, Expr *RHSExpr,
                                         SourceLocation Loc,
                                         Sema &Sema) {}

// C99 6.5.16.1
QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
                                       SourceLocation Loc,
                                       QualType CompoundType,
                                       BinaryOperatorKind Opc) {}

// Scenarios to ignore if expression E is:
// 1. an explicit cast expression into void
// 2. a function call expression that returns void
static bool IgnoreCommaOperand(const Expr *E, const ASTContext &Context) {}

void Sema::DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc) {}

// C99 6.5.17
static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,
                                   SourceLocation Loc) {}

/// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
/// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
                                               ExprValueKind &VK,
                                               ExprObjectKind &OK,
                                               SourceLocation OpLoc, bool IsInc,
                                               bool IsPrefix) {}

/// getPrimaryDecl - Helper function for CheckAddressOfOperand().
/// This routine allows us to typecheck complex/recursive expressions
/// where the declaration is needed for type checking. We only need to
/// handle cases when the expression references a function designator
/// or is an lvalue. Here are some examples:
///  - &(x) => x
///  - &*****f => f for f a function designator.
///  - &s.xx => s
///  - &s.zz[1].yy -> s, if zz is an array
///  - *(x + 1) -> x, if x is an array
///  - &"123"[2] -> 0
///  - & __real__ x -> x
///
/// FIXME: We don't recurse to the RHS of a comma, nor handle pointers to
/// members.
static ValueDecl *getPrimaryDecl(Expr *E) {}

namespace {
enum {};
}
/// Diagnose invalid operand for address of operations.
///
/// \param Type The type of operand which cannot have its address taken.
static void diagnoseAddressOfInvalidType(Sema &S, SourceLocation Loc,
                                         Expr *E, unsigned Type) {}

bool Sema::CheckUseOfCXXMethodAsAddressOfOperand(SourceLocation OpLoc,
                                                 const Expr *Op,
                                                 const CXXMethodDecl *MD) {}

QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {}

static void RecordModifiableNonNullParam(Sema &S, const Expr *Exp) {}

/// CheckIndirectionOperand - Type check unary indirection (prefix '*').
static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
                                        SourceLocation OpLoc,
                                        bool IsAfterAmp = false) {}

BinaryOperatorKind Sema::ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind) {}

static inline UnaryOperatorKind ConvertTokenKindToUnaryOpcode(
  tok::TokenKind Kind) {}

const FieldDecl *
Sema::getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned) {}

/// DiagnoseSelfAssignment - Emits a warning if a value is assigned to itself.
/// This warning suppressed in the event of macro expansions.
static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr,
                                   SourceLocation OpLoc, bool IsBuiltin) {}

/// Check if a bitwise-& is performed on an Objective-C pointer.  This
/// is usually indicative of introspection within the Objective-C pointer.
static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R,
                                          SourceLocation OpLoc) {}

static NamedDecl *getDeclFromExpr(Expr *E) {}

// This helper function promotes a binary operator's operands (which are of a
// half vector type) to a vector of floats and then truncates the result to
// a vector of either half or short.
static ExprResult convertHalfVecBinOp(Sema &S, ExprResult LHS, ExprResult RHS,
                                      BinaryOperatorKind Opc, QualType ResultTy,
                                      ExprValueKind VK, ExprObjectKind OK,
                                      bool IsCompAssign, SourceLocation OpLoc,
                                      FPOptionsOverride FPFeatures) {}

static std::pair<ExprResult, ExprResult>
CorrectDelayedTyposInBinOp(Sema &S, BinaryOperatorKind Opc, Expr *LHSExpr,
                           Expr *RHSExpr) {}

/// Returns true if conversion between vectors of halfs and vectors of floats
/// is needed.
static bool needsConversionOfHalfVec(bool OpRequiresConversion, ASTContext &Ctx,
                                     Expr *E0, Expr *E1 = nullptr) {}

ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
                                    BinaryOperatorKind Opc,
                                    Expr *LHSExpr, Expr *RHSExpr) {}

/// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
/// operators are mixed in a way that suggests that the programmer forgot that
/// comparison operators have higher precedence. The most typical example of
/// such code is "flags & 0x0020 != 0", which is equivalent to "flags & 1".
static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
                                      SourceLocation OpLoc, Expr *LHSExpr,
                                      Expr *RHSExpr) {}

/// It accepts a '&&' expr that is inside a '||' one.
/// Emit a diagnostic together with a fixit hint that wraps the '&&' expression
/// in parentheses.
static void
EmitDiagnosticForLogicalAndInLogicalOr(Sema &Self, SourceLocation OpLoc,
                                       BinaryOperator *Bop) {}

/// Look for '&&' in the left hand of a '||' expr.
static void DiagnoseLogicalAndInLogicalOrLHS(Sema &S, SourceLocation OpLoc,
                                             Expr *LHSExpr, Expr *RHSExpr) {}

/// Look for '&&' in the right hand of a '||' expr.
static void DiagnoseLogicalAndInLogicalOrRHS(Sema &S, SourceLocation OpLoc,
                                             Expr *LHSExpr, Expr *RHSExpr) {}

/// Look for bitwise op in the left or right hand of a bitwise op with
/// lower precedence and emit a diagnostic together with a fixit hint that wraps
/// the '&' expression in parentheses.
static void DiagnoseBitwiseOpInBitwiseOp(Sema &S, BinaryOperatorKind Opc,
                                         SourceLocation OpLoc, Expr *SubExpr) {}

static void DiagnoseAdditionInShift(Sema &S, SourceLocation OpLoc,
                                    Expr *SubExpr, StringRef Shift) {}

static void DiagnoseShiftCompare(Sema &S, SourceLocation OpLoc,
                                 Expr *LHSExpr, Expr *RHSExpr) {}

/// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky
/// precedence.
static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
                                    SourceLocation OpLoc, Expr *LHSExpr,
                                    Expr *RHSExpr){}

ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
                            tok::TokenKind Kind,
                            Expr *LHSExpr, Expr *RHSExpr) {}

void Sema::LookupBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc,
                       UnresolvedSetImpl &Functions) {}

/// Build an overloaded binary operator expression in the given scope.
static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc,
                                       BinaryOperatorKind Opc,
                                       Expr *LHS, Expr *RHS) {}

ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
                            BinaryOperatorKind Opc,
                            Expr *LHSExpr, Expr *RHSExpr) {}

static bool isOverflowingIntegerType(ASTContext &Ctx, QualType T) {}

ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
                                      UnaryOperatorKind Opc, Expr *InputExpr,
                                      bool IsAfterAmp) {}

bool Sema::isQualifiedMemberAccess(Expr *E) {}

ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
                              UnaryOperatorKind Opc, Expr *Input,
                              bool IsAfterAmp) {}

ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op,
                              Expr *Input, bool IsAfterAmp) {}

ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
                                LabelDecl *TheDecl) {}

void Sema::ActOnStartStmtExpr() {}

void Sema::ActOnStmtExprError() {}

ExprResult Sema::ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt,
                               SourceLocation RPLoc) {}

ExprResult Sema::BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
                               SourceLocation RPLoc, unsigned TemplateDepth) {}

ExprResult Sema::ActOnStmtExprResult(ExprResult ER) {}

ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
                                      TypeSourceInfo *TInfo,
                                      ArrayRef<OffsetOfComponent> Components,
                                      SourceLocation RParenLoc) {}

ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
                                      SourceLocation BuiltinLoc,
                                      SourceLocation TypeLoc,
                                      ParsedType ParsedArgTy,
                                      ArrayRef<OffsetOfComponent> Components,
                                      SourceLocation RParenLoc) {}


ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
                                 Expr *CondExpr,
                                 Expr *LHSExpr, Expr *RHSExpr,
                                 SourceLocation RPLoc) {}

//===----------------------------------------------------------------------===//
// Clang Extensions.
//===----------------------------------------------------------------------===//

void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {}

void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
                               Scope *CurScope) {}

void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {}

ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
                                    Stmt *Body, Scope *CurScope) {}

ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty,
                            SourceLocation RPLoc) {}

ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
                                Expr *E, TypeSourceInfo *TInfo,
                                SourceLocation RPLoc) {}

ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {}

static CXXRecordDecl *LookupStdSourceLocationImpl(Sema &S, SourceLocation Loc) {}

ExprResult Sema::ActOnSourceLocExpr(SourceLocIdentKind Kind,
                                    SourceLocation BuiltinLoc,
                                    SourceLocation RPLoc) {}

ExprResult Sema::BuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
                                    SourceLocation BuiltinLoc,
                                    SourceLocation RPLoc,
                                    DeclContext *ParentContext) {}

ExprResult Sema::ActOnEmbedExpr(SourceLocation EmbedKeywordLoc,
                                StringLiteral *BinaryData) {}

static bool maybeDiagnoseAssignmentToFunction(Sema &S, QualType DstType,
                                              const Expr *SrcExpr) {}

bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
                                    SourceLocation Loc,
                                    QualType DstType, QualType SrcType,
                                    Expr *SrcExpr, AssignmentAction Action,
                                    bool *Complained) {}

ExprResult Sema::VerifyIntegerConstantExpression(Expr *E,
                                                 llvm::APSInt *Result,
                                                 AllowFoldKind CanFold) {}

ExprResult Sema::VerifyIntegerConstantExpression(Expr *E,
                                                 llvm::APSInt *Result,
                                                 unsigned DiagID,
                                                 AllowFoldKind CanFold) {}

Sema::SemaDiagnosticBuilder
Sema::VerifyICEDiagnoser::diagnoseNotICEType(Sema &S, SourceLocation Loc,
                                             QualType T) {}

Sema::SemaDiagnosticBuilder
Sema::VerifyICEDiagnoser::diagnoseFold(Sema &S, SourceLocation Loc) {}

ExprResult
Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
                                      VerifyICEDiagnoser &Diagnoser,
                                      AllowFoldKind CanFold) {}

namespace {
  // Handle the case where we conclude a expression which we speculatively
  // considered to be unevaluated is actually evaluated.
  class TransformToPE : public TreeTransform<TransformToPE> {};
}

ExprResult Sema::TransformToPotentiallyEvaluated(Expr *E) {}

TypeSourceInfo *Sema::TransformToPotentiallyEvaluated(TypeSourceInfo *TInfo) {}

void
Sema::PushExpressionEvaluationContext(
    ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl,
    ExpressionEvaluationContextRecord::ExpressionKind ExprContext) {}

void
Sema::PushExpressionEvaluationContext(
    ExpressionEvaluationContext NewContext, ReuseLambdaContextDecl_t,
    ExpressionEvaluationContextRecord::ExpressionKind ExprContext) {}

namespace {

const DeclRefExpr *CheckPossibleDeref(Sema &S, const Expr *PossibleDeref) {}

} // namespace

void Sema::WarnOnPendingNoDerefs(ExpressionEvaluationContextRecord &Rec) {}

void Sema::CheckUnusedVolatileAssignment(Expr *E) {}

void Sema::MarkExpressionAsImmediateEscalating(Expr *E) {}

ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {}

static void EvaluateAndDiagnoseImmediateInvocation(
    Sema &SemaRef, Sema::ImmediateInvocationCandidate Candidate) {}

static void RemoveNestedImmediateInvocation(
    Sema &SemaRef, Sema::ExpressionEvaluationContextRecord &Rec,
    SmallVector<Sema::ImmediateInvocationCandidate, 4>::reverse_iterator It) {}

static void
HandleImmediateInvocations(Sema &SemaRef,
                           Sema::ExpressionEvaluationContextRecord &Rec) {}

void Sema::PopExpressionEvaluationContext() {}

void Sema::DiscardCleanupsInEvaluationContext() {}

ExprResult Sema::HandleExprEvaluationContextForTypeof(Expr *E) {}

/// Are we in a context that is potentially constant evaluated per C++20
/// [expr.const]p12?
static bool isPotentiallyConstantEvaluatedContext(Sema &SemaRef) {}

/// Return true if this function has a calling convention that requires mangling
/// in the size of the parameter pack.
static bool funcHasParameterSizeMangling(Sema &S, FunctionDecl *FD) {}

/// Require that all of the parameter types of function be complete. Normally,
/// parameter types are only required to be complete when a function is called
/// or defined, but to mangle functions with certain calling conventions, the
/// mangler needs to know the size of the parameter list. In this situation,
/// MSVC doesn't emit an error or instantiate templates. Instead, MSVC mangles
/// the function as _foo@0, i.e. zero bytes of parameters, which will usually
/// result in a linker error. Clang doesn't implement this behavior, and instead
/// attempts to error at compile time.
static void CheckCompleteParameterTypesForMangler(Sema &S, FunctionDecl *FD,
                                                  SourceLocation Loc) {}

namespace {
enum class OdrUseContext {};
}

/// Are we within a context in which references to resolved functions or to
/// variables result in odr-use?
static OdrUseContext isOdrUseContext(Sema &SemaRef) {}

static bool isImplicitlyDefinableConstexprFunction(FunctionDecl *Func) {}

void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
                                  bool MightBeOdrUse) {}

/// Directly mark a variable odr-used. Given a choice, prefer to use
/// MarkVariableReferenced since it does additional checks and then
/// calls MarkVarDeclODRUsed.
/// If the variable must be captured:
///  - if FunctionScopeIndexToStopAt is null, capture it in the CurContext
///  - else capture it in the DeclContext that maps to the
///    *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.
static void
MarkVarDeclODRUsed(ValueDecl *V, SourceLocation Loc, Sema &SemaRef,
                   const unsigned *const FunctionScopeIndexToStopAt = nullptr) {}

void Sema::MarkCaptureUsedInEnclosingContext(ValueDecl *Capture,
                                             SourceLocation Loc,
                                             unsigned CapturingScopeIndex) {}

void diagnoseUncapturableValueReferenceOrBinding(Sema &S, SourceLocation loc,
                                                 ValueDecl *var) {}

static bool isVariableAlreadyCapturedInScopeInfo(CapturingScopeInfo *CSI,
                                                 ValueDecl *Var,
                                                 bool &SubCapturesAreNested,
                                                 QualType &CaptureType,
                                                 QualType &DeclRefType) {}

// Only block literals, captured statements, and lambda expressions can
// capture; other scopes don't work.
static DeclContext *getParentOfCapturingContextOrNull(DeclContext *DC,
                                                      ValueDecl *Var,
                                                      SourceLocation Loc,
                                                      const bool Diagnose,
                                                      Sema &S) {}

// Certain capturing entities (lambdas, blocks etc.) are not allowed to capture
// certain types of variables (unnamed, variably modified types etc.)
// so check for eligibility.
static bool isVariableCapturable(CapturingScopeInfo *CSI, ValueDecl *Var,
                                 SourceLocation Loc, const bool Diagnose,
                                 Sema &S) {}

// Returns true if the capture by block was successful.
static bool captureInBlock(BlockScopeInfo *BSI, ValueDecl *Var,
                           SourceLocation Loc, const bool BuildAndDiagnose,
                           QualType &CaptureType, QualType &DeclRefType,
                           const bool Nested, Sema &S, bool Invalid) {}

/// Capture the given variable in the captured region.
static bool captureInCapturedRegion(
    CapturedRegionScopeInfo *RSI, ValueDecl *Var, SourceLocation Loc,
    const bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType,
    const bool RefersToCapturedVariable, Sema::TryCaptureKind Kind,
    bool IsTopScope, Sema &S, bool Invalid) {}

/// Capture the given variable in the lambda.
static bool captureInLambda(LambdaScopeInfo *LSI, ValueDecl *Var,
                            SourceLocation Loc, const bool BuildAndDiagnose,
                            QualType &CaptureType, QualType &DeclRefType,
                            const bool RefersToCapturedVariable,
                            const Sema::TryCaptureKind Kind,
                            SourceLocation EllipsisLoc, const bool IsTopScope,
                            Sema &S, bool Invalid) {}

static bool canCaptureVariableByCopy(ValueDecl *Var,
                                     const ASTContext &Context) {}

/// Create up to 4 fix-its for explicit reference and value capture of \p Var or
/// default capture. Fixes may be omitted if they aren't allowed by the
/// standard, for example we can't emit a default copy capture fix-it if we
/// already explicitly copy capture capture another variable.
static void buildLambdaCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI,
                                    ValueDecl *Var) {}

bool Sema::tryCaptureVariable(
    ValueDecl *Var, SourceLocation ExprLoc, TryCaptureKind Kind,
    SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType,
    QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt) {}

bool Sema::tryCaptureVariable(ValueDecl *Var, SourceLocation Loc,
                              TryCaptureKind Kind, SourceLocation EllipsisLoc) {}

bool Sema::NeedToCaptureVariable(ValueDecl *Var, SourceLocation Loc) {}

QualType Sema::getCapturedDeclRefType(ValueDecl *Var, SourceLocation Loc) {}

namespace {
// Helper to copy the template arguments from a DeclRefExpr or MemberExpr.
// The produced TemplateArgumentListInfo* points to data stored within this
// object, so should only be used in contexts where the pointer will not be
// used after the CopiedTemplateArgs object is destroyed.
class CopiedTemplateArgs {};
}

/// Walk the set of potential results of an expression and mark them all as
/// non-odr-uses if they satisfy the side-conditions of the NonOdrUseReason.
///
/// \return A new expression if we found any potential results, ExprEmpty() if
///         not, and ExprError() if we diagnosed an error.
static ExprResult rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E,
                                                      NonOdrUseReason NOUR) {}

ExprResult Sema::CheckLValueToRValueConversionOperand(Expr *E) {}

ExprResult Sema::ActOnConstantExpression(ExprResult Res) {}

void Sema::CleanupVarDeclMarking() {}

static void DoMarkPotentialCapture(Sema &SemaRef, SourceLocation Loc,
                                   ValueDecl *Var, Expr *E) {}

static void DoMarkVarDeclReferenced(
    Sema &SemaRef, SourceLocation Loc, VarDecl *Var, Expr *E,
    llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {}

static void DoMarkBindingDeclReferenced(Sema &SemaRef, SourceLocation Loc,
                                        BindingDecl *BD, Expr *E) {}

void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) {}

// C++ [temp.dep.expr]p3:
//   An id-expression is type-dependent if it contains:
//     - an identifier associated by name lookup with an entity captured by copy
//       in a lambda-expression that has an explicit object parameter whose type
//       is dependent ([dcl.fct]),
static void FixDependencyOfIdExpressionsInLambdaWithDependentObjectParameter(
    Sema &SemaRef, ValueDecl *D, Expr *E) {}

static void
MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, Decl *D, Expr *E,
                   bool MightBeOdrUse,
                   llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {}

void Sema::MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base) {}

void Sema::MarkMemberReferenced(MemberExpr *E) {}

void Sema::MarkFunctionParmPackReferenced(FunctionParmPackExpr *E) {}

/// Perform marking for a reference to an arbitrary declaration.  It
/// marks the declaration referenced, and performs odr-use checking for
/// functions and variables. This method should not be used when building a
/// normal expression which refers to a variable.
void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D,
                                 bool MightBeOdrUse) {}

namespace {
  // Mark all of the declarations used by a type as referenced.
  // FIXME: Not fully implemented yet! We need to have a better understanding
  // of when we're entering a context we should not recurse into.
  // FIXME: This is and EvaluatedExprMarker are more-or-less equivalent to
  // TreeTransforms rebuilding the type in a new context. Rather than
  // duplicating the TreeTransform logic, we should consider reusing it here.
  // Currently that causes problems when rebuilding LambdaExprs.
  class MarkReferencedDecls : public RecursiveASTVisitor<MarkReferencedDecls> {};
}

bool MarkReferencedDecls::TraverseTemplateArgument(
    const TemplateArgument &Arg) {}

void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {}

namespace {
/// Helper class that marks all of the declarations referenced by
/// potentially-evaluated subexpressions as "referenced".
class EvaluatedExprMarker : public UsedDeclVisitor<EvaluatedExprMarker> {};
} // namespace

void Sema::MarkDeclarationsReferencedInExpr(Expr *E,
                                            bool SkipLocalVariables,
                                            ArrayRef<const Expr*> StopAt) {}

/// Emit a diagnostic when statements are reachable.
/// FIXME: check for reachability even in expressions for which we don't build a
///        CFG (eg, in the initializer of a global or in a constant expression).
///        For example,
///        namespace { auto *p = new double[3][false ? (1, 2) : 3]; }
bool Sema::DiagIfReachable(SourceLocation Loc, ArrayRef<const Stmt *> Stmts,
                           const PartialDiagnostic &PD) {}

/// Emit a diagnostic that describes an effect on the run-time behavior
/// of the program being compiled.
///
/// This routine emits the given diagnostic when the code currently being
/// type-checked is "potentially evaluated", meaning that there is a
/// possibility that the code will actually be executable. Code in sizeof()
/// expressions, code used only during overload resolution, etc., are not
/// potentially evaluated. This routine will suppress such diagnostics or,
/// in the absolutely nutty case of potentially potentially evaluated
/// expressions (C++ typeid), queue the diagnostic to potentially emit it
/// later.
///
/// This routine should be used for all diagnostics that describe the run-time
/// behavior of a program, such as passing a non-POD value through an ellipsis.
/// Failure to do so will likely result in spurious diagnostics or failures
/// during overload resolution or within sizeof/alignof/typeof/typeid.
bool Sema::DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts,
                               const PartialDiagnostic &PD) {}

bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
                               const PartialDiagnostic &PD) {}

bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
                               CallExpr *CE, FunctionDecl *FD) {}

// Diagnose the s/=/==/ and s/\|=/!=/ typos. Note that adding parentheses
// will prevent this condition from triggering, which is what we want.
void Sema::DiagnoseAssignmentAsCondition(Expr *E) {}

void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) {}

ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E,
                                       bool IsConstexpr) {}

Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc,
                                           Expr *SubExpr, ConditionKind CK,
                                           bool MissingOK) {}

namespace {
  /// A visitor for rebuilding a call to an __unknown_any expression
  /// to have an appropriate type.
  struct RebuildUnknownAnyFunction
    : StmtVisitor<RebuildUnknownAnyFunction, ExprResult> {};
}

/// Given a function expression of unknown-any type, try to rebuild it
/// to have a function type.
static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *FunctionExpr) {}

namespace {
  /// A visitor for rebuilding an expression of type __unknown_anytype
  /// into one which resolves the type directly on the referring
  /// expression.  Strict preservation of the original source
  /// structure is not a goal.
  struct RebuildUnknownAnyExpr
    : StmtVisitor<RebuildUnknownAnyExpr, ExprResult> {};
}

/// Rebuilds a call expression which yielded __unknown_anytype.
ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) {}

ExprResult RebuildUnknownAnyExpr::VisitObjCMessageExpr(ObjCMessageExpr *E) {}

ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *E) {}

ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {}

ExprResult Sema::checkUnknownAnyCast(SourceRange TypeRange, QualType CastType,
                                     Expr *CastExpr, CastKind &CastKind,
                                     ExprValueKind &VK, CXXCastPath &Path) {}

ExprResult Sema::forceUnknownAnyToType(Expr *E, QualType ToType) {}

ExprResult Sema::checkUnknownAnyArg(SourceLocation callLoc,
                                    Expr *arg, QualType &paramType) {}

static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {}

ExprResult Sema::CheckPlaceholderExpr(Expr *E) {}

bool Sema::CheckCaseExpression(Expr *E) {}

ExprResult Sema::CreateRecoveryExpr(SourceLocation Begin, SourceLocation End,
                                    ArrayRef<Expr *> SubExprs, QualType T) {}