llvm/clang/lib/Sema/SemaExprCXX.cpp

//===--- SemaExprCXX.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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Implements semantic analysis for C++ expressions.
///
//===----------------------------------------------------------------------===//

#include "TreeTransform.h"
#include "TypeLocBuilder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/AlignedAllocation.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Basic/TypeTraits.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaLambda.h"
#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/SemaPPC.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TypeSize.h"
#include <optional>
usingnamespaceclang;
usingnamespacesema;

ParsedType Sema::getInheritingConstructorName(CXXScopeSpec &SS,
                                              SourceLocation NameLoc,
                                              const IdentifierInfo &Name) {}

ParsedType Sema::getConstructorName(const IdentifierInfo &II,
                                    SourceLocation NameLoc, Scope *S,
                                    CXXScopeSpec &SS, bool EnteringContext) {}

ParsedType Sema::getDestructorName(const IdentifierInfo &II,
                                   SourceLocation NameLoc, Scope *S,
                                   CXXScopeSpec &SS, ParsedType ObjectTypePtr,
                                   bool EnteringContext) {}

ParsedType Sema::getDestructorTypeForDecltype(const DeclSpec &DS,
                                              ParsedType ObjectType) {}

bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
                                  const UnqualifiedId &Name, bool IsUDSuffix) {}

ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
                                SourceLocation TypeidLoc,
                                TypeSourceInfo *Operand,
                                SourceLocation RParenLoc) {}

ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
                                SourceLocation TypeidLoc,
                                Expr *E,
                                SourceLocation RParenLoc) {}

/// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
ExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
                     bool isType, void *TyOrExpr, SourceLocation RParenLoc) {}

/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
/// a single GUID.
static void
getUuidAttrOfType(Sema &SemaRef, QualType QT,
                  llvm::SmallSetVector<const UuidAttr *, 1> &UuidAttrs) {}

ExprResult Sema::BuildCXXUuidof(QualType Type,
                                SourceLocation TypeidLoc,
                                TypeSourceInfo *Operand,
                                SourceLocation RParenLoc) {}

ExprResult Sema::BuildCXXUuidof(QualType Type, SourceLocation TypeidLoc,
                                Expr *E, SourceLocation RParenLoc) {}

/// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
ExprResult
Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc,
                     bool isType, void *TyOrExpr, SourceLocation RParenLoc) {}

ExprResult
Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {}

ExprResult
Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {}

ExprResult
Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) {}

ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
                               bool IsThrownVarInScope) {}

static void
collectPublicBases(CXXRecordDecl *RD,
                   llvm::DenseMap<CXXRecordDecl *, unsigned> &SubobjectsSeen,
                   llvm::SmallPtrSetImpl<CXXRecordDecl *> &VBases,
                   llvm::SetVector<CXXRecordDecl *> &PublicSubobjectsSeen,
                   bool ParentIsPublic) {}

static void getUnambiguousPublicSubobjects(
    CXXRecordDecl *RD, llvm::SmallVectorImpl<CXXRecordDecl *> &Objects) {}

bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc,
                                QualType ExceptionObjectTy, Expr *E) {}

static QualType adjustCVQualifiersForCXXThisWithinLambda(
    ArrayRef<FunctionScopeInfo *> FunctionScopes, QualType ThisTy,
    DeclContext *CurSemaContext, ASTContext &ASTCtx) {}

QualType Sema::getCurrentThisType() {}

Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S,
                                         Decl *ContextDecl,
                                         Qualifiers CXXThisTypeQuals,
                                         bool Enabled)
  :{}


Sema::CXXThisScopeRAII::~CXXThisScopeRAII() {}

static void buildLambdaThisCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI) {}

bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
    bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt,
    const bool ByCopy) {}

ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {}

bool Sema::CheckCXXThisType(SourceLocation Loc, QualType Type) {}

Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type,
                             bool IsImplicit) {}

void Sema::MarkThisReferenced(CXXThisExpr *This) {}

bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {}

ExprResult
Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
                                SourceLocation LParenOrBraceLoc,
                                MultiExprArg exprs,
                                SourceLocation RParenOrBraceLoc,
                                bool ListInitialization) {}

ExprResult
Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
                                SourceLocation LParenOrBraceLoc,
                                MultiExprArg Exprs,
                                SourceLocation RParenOrBraceLoc,
                                bool ListInitialization) {}

bool Sema::isUsualDeallocationFunction(const CXXMethodDecl *Method) {}

/// Determine whether the given function is a non-placement
/// deallocation function.
static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) {}

namespace {
  struct UsualDeallocFnInfo {};
}

/// Determine whether a type has new-extended alignment. This may be called when
/// the type is incomplete (for a delete-expression with an incomplete pointee
/// type), in which case it will conservatively return false if the alignment is
/// not known.
static bool hasNewExtendedAlignment(Sema &S, QualType AllocType) {}

/// Select the correct "usual" deallocation function to use from a selection of
/// deallocation functions (either global or class-scope).
static UsualDeallocFnInfo resolveDeallocationOverload(
    Sema &S, LookupResult &R, bool WantSize, bool WantAlign,
    llvm::SmallVectorImpl<UsualDeallocFnInfo> *BestFns = nullptr) {}

/// Determine whether a given type is a class for which 'delete[]' would call
/// a member 'operator delete[]' with a 'size_t' parameter. This implies that
/// we need to store the array size (even if the type is
/// trivially-destructible).
static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc,
                                         QualType allocType) {}

ExprResult
Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
                  SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
                  SourceLocation PlacementRParen, SourceRange TypeIdParens,
                  Declarator &D, Expr *Initializer) {}

static bool isLegalArrayNewInitializer(CXXNewInitializationStyle Style,
                                       Expr *Init, bool IsCPlusPlus20) {}

bool
Sema::isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const {}

// Emit a diagnostic if an aligned allocation/deallocation function that is not
// implemented in the standard library is selected.
void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
                                                SourceLocation Loc) {}

ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
                             SourceLocation PlacementLParen,
                             MultiExprArg PlacementArgs,
                             SourceLocation PlacementRParen,
                             SourceRange TypeIdParens, QualType AllocType,
                             TypeSourceInfo *AllocTypeInfo,
                             std::optional<Expr *> ArraySize,
                             SourceRange DirectInitRange, Expr *Initializer) {}

bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
                              SourceRange R) {}

static bool resolveAllocationOverload(
    Sema &S, LookupResult &R, SourceRange Range, SmallVectorImpl<Expr *> &Args,
    bool &PassAlignment, FunctionDecl *&Operator,
    OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose) {}

bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
                                   AllocationFunctionScope NewScope,
                                   AllocationFunctionScope DeleteScope,
                                   QualType AllocType, bool IsArray,
                                   bool &PassAlignment, MultiExprArg PlaceArgs,
                                   FunctionDecl *&OperatorNew,
                                   FunctionDecl *&OperatorDelete,
                                   bool Diagnose) {}

void Sema::DeclareGlobalNewDelete() {}

/// DeclareGlobalAllocationFunction - Declares a single implicit global
/// allocation function if it doesn't already exist.
void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
                                           QualType Return,
                                           ArrayRef<QualType> Params) {}

FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc,
                                                  bool CanProvideSize,
                                                  bool Overaligned,
                                                  DeclarationName Name) {}

FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc,
                                                          CXXRecordDecl *RD) {}

bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
                                    DeclarationName Name,
                                    FunctionDecl *&Operator, bool Diagnose,
                                    bool WantSize, bool WantAligned) {}

namespace {
/// Checks whether delete-expression, and new-expression used for
///  initializing deletee have the same array form.
class MismatchingNewDeleteDetector {};
}

MismatchingNewDeleteDetector::MismatchResult
MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) {}

const CXXNewExpr *
MismatchingNewDeleteDetector::getNewExprFromInitListOrExpr(const Expr *E) {}

bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit(
    const CXXCtorInitializer *CI) {}

bool MismatchingNewDeleteDetector::hasMatchingNewInCtor(
    const CXXConstructorDecl *CD) {}

MismatchingNewDeleteDetector::MismatchResult
MismatchingNewDeleteDetector::analyzeInClassInitializer() {}

MismatchingNewDeleteDetector::MismatchResult
MismatchingNewDeleteDetector::analyzeField(FieldDecl *Field,
                                           bool DeleteWasArrayForm) {}

MismatchingNewDeleteDetector::MismatchResult
MismatchingNewDeleteDetector::analyzeMemberExpr(const MemberExpr *ME) {}

bool MismatchingNewDeleteDetector::hasMatchingVarInit(const DeclRefExpr *D) {}

static void
DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc,
                            const MismatchingNewDeleteDetector &Detector) {}

void Sema::AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE) {}

void Sema::AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
                                     bool DeleteWasArrayForm) {}

ExprResult
Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
                     bool ArrayForm, Expr *ExE) {}

static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall,
                                            bool IsDelete,
                                            FunctionDecl *&Operator) {}

ExprResult Sema::BuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,
                                                    bool IsDelete) {}

void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc,
                                bool IsDelete, bool CallCanBeVirtual,
                                bool WarnOnNonAbstractTypes,
                                SourceLocation DtorLoc) {}

Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar,
                                                   SourceLocation StmtLoc,
                                                   ConditionKind CK) {}

ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
                                        SourceLocation StmtLoc,
                                        ConditionKind CK) {}

ExprResult Sema::CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr) {}

bool
Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {}

static ExprResult BuildCXXCastArgument(Sema &S,
                                       SourceLocation CastLoc,
                                       QualType Ty,
                                       CastKind Kind,
                                       CXXMethodDecl *Method,
                                       DeclAccessPair FoundDecl,
                                       bool HadMultipleCandidates,
                                       Expr *From) {}

ExprResult
Sema::PerformImplicitConversion(Expr *From, QualType ToType,
                                const ImplicitConversionSequence &ICS,
                                AssignmentAction Action,
                                CheckedConversionKind CCK) {}

// adjustVectorType - Compute the intermediate cast type casting elements of the
// from type to the elements of the to type without resizing the vector.
static QualType adjustVectorType(ASTContext &Context, QualType FromTy,
                                 QualType ToType, QualType *ElTy = nullptr) {}

ExprResult
Sema::PerformImplicitConversion(Expr *From, QualType ToType,
                                const StandardConversionSequence& SCS,
                                AssignmentAction Action,
                                CheckedConversionKind CCK) {}

/// Checks that type T is not a VLA.
///
/// @returns @c true if @p T is VLA and a diagnostic was emitted,
/// @c false otherwise.
static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,
                                      clang::tok::TokenKind TypeTraitID) {}

/// Checks that type T is not an atomic type (_Atomic).
///
/// @returns @c true if @p T is VLA and a diagnostic was emitted,
/// @c false otherwise.
static bool DiagnoseAtomicInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,
                                         clang::tok::TokenKind TypeTraitID) {}

/// Check the completeness of a type in a unary type trait.
///
/// If the particular type trait requires a complete type, tries to complete
/// it. If completing the type fails, a diagnostic is emitted and false
/// returned. If completing the type succeeds or no completion was required,
/// returns true.
static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
                                                SourceLocation Loc,
                                                QualType ArgTy) {}

static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
                               Sema &Self, SourceLocation KeyLoc, ASTContext &C,
                               bool (CXXRecordDecl::*HasTrivial)() const,
                               bool (CXXRecordDecl::*HasNonTrivial)() const,
                               bool (CXXMethodDecl::*IsDesiredOp)() const)
{}

static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,
                                                     const CXXRecordDecl *Decl,
                                                     SourceLocation KeyLoc) {}

static bool isTriviallyEqualityComparableType(Sema &S, QualType Type, SourceLocation KeyLoc) {}

static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
                                   SourceLocation KeyLoc,
                                   TypeSourceInfo *TInfo) {}

static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs,
                                    const TypeSourceInfo *Rhs, SourceLocation KeyLoc);

static ExprResult CheckConvertibilityForTypeTraits(
    Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs,
    SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {}

static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
                                     SourceLocation KWLoc,
                                     ArrayRef<TypeSourceInfo *> Args,
                                     SourceLocation RParenLoc,
                                     bool IsDependent) {}

namespace {
void DiagnoseBuiltinDeprecation(Sema& S, TypeTrait Kind,
                                SourceLocation KWLoc) {}
}

bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {}

enum class TypeTraitReturnType {};

static TypeTraitReturnType GetReturnType(TypeTrait Kind) {}

ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
                                ArrayRef<TypeSourceInfo *> Args,
                                SourceLocation RParenLoc) {}

ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
                                ArrayRef<ParsedType> Args,
                                SourceLocation RParenLoc) {}

static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs,
                                    const TypeSourceInfo *Rhs, SourceLocation KeyLoc) {}

ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT,
                                     SourceLocation KWLoc,
                                     ParsedType Ty,
                                     Expr* DimExpr,
                                     SourceLocation RParen) {}

static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,
                                           QualType T, Expr *DimExpr,
                                           SourceLocation KeyLoc) {}

ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT,
                                     SourceLocation KWLoc,
                                     TypeSourceInfo *TSInfo,
                                     Expr* DimExpr,
                                     SourceLocation RParen) {}

ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
                                      SourceLocation KWLoc,
                                      Expr *Queried,
                                      SourceLocation RParen) {}

static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) {}

ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET,
                                      SourceLocation KWLoc,
                                      Expr *Queried,
                                      SourceLocation RParen) {}

QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
                                            ExprValueKind &VK,
                                            SourceLocation Loc,
                                            bool isIndirect) {}

/// Try to convert a type to another according to C++11 5.16p3.
///
/// This is part of the parameter validation for the ? operator. If either
/// value operand is a class type, the two operands are attempted to be
/// converted to each other. This function does the conversion in one direction.
/// It returns true if the program is ill-formed and has already been diagnosed
/// as such.
static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
                                SourceLocation QuestionLoc,
                                bool &HaveConversion,
                                QualType &ToType) {}

/// Try to find a common type for two according to C++0x 5.16p5.
///
/// This is part of the parameter validation for the ? operator. If either
/// value operand is a class type, overload resolution is used to find a
/// conversion to a common type.
static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS,
                                    SourceLocation QuestionLoc) {}

/// Perform an "extended" implicit conversion as returned by
/// TryClassUnification.
static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) {}

// Check the condition operand of ?: to see if it is valid for the GCC
// extension.
static bool isValidVectorForConditionalCondition(ASTContext &Ctx,
                                                 QualType CondTy) {}

static bool isValidSizelessVectorForConditionalCondition(ASTContext &Ctx,
                                                         QualType CondTy) {}

QualType Sema::CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
                                           ExprResult &RHS,
                                           SourceLocation QuestionLoc) {}

QualType Sema::CheckSizelessVectorConditionalTypes(ExprResult &Cond,
                                                   ExprResult &LHS,
                                                   ExprResult &RHS,
                                                   SourceLocation QuestionLoc) {}

QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
                                           ExprResult &RHS, ExprValueKind &VK,
                                           ExprObjectKind &OK,
                                           SourceLocation QuestionLoc) {}

QualType Sema::FindCompositePointerType(SourceLocation Loc,
                                        Expr *&E1, Expr *&E2,
                                        bool ConvertArgs) {}

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

ExprResult
Sema::MaybeCreateExprWithCleanups(ExprResult SubExpr) {}

Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {}

Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {}

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

/// Note a set of 'operator->' functions that were used for a member access.
static void noteOperatorArrows(Sema &S,
                               ArrayRef<FunctionDecl *> OperatorArrows) {}

ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
                                              SourceLocation OpLoc,
                                              tok::TokenKind OpKind,
                                              ParsedType &ObjectType,
                                              bool &MayBePseudoDestructor) {}

static bool CheckArrow(Sema &S, QualType &ObjectType, Expr *&Base,
                       tok::TokenKind &OpKind, SourceLocation OpLoc) {}

/// Check if it's ok to try and recover dot pseudo destructor calls on
/// pointer objects.
static bool
canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef,
                                                   QualType DestructedType) {}

ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
                                           SourceLocation OpLoc,
                                           tok::TokenKind OpKind,
                                           const CXXScopeSpec &SS,
                                           TypeSourceInfo *ScopeTypeInfo,
                                           SourceLocation CCLoc,
                                           SourceLocation TildeLoc,
                                         PseudoDestructorTypeStorage Destructed) {}

ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
                                           SourceLocation OpLoc,
                                           tok::TokenKind OpKind,
                                           CXXScopeSpec &SS,
                                           UnqualifiedId &FirstTypeName,
                                           SourceLocation CCLoc,
                                           SourceLocation TildeLoc,
                                           UnqualifiedId &SecondTypeName) {}

ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
                                           SourceLocation OpLoc,
                                           tok::TokenKind OpKind,
                                           SourceLocation TildeLoc,
                                           const DeclSpec& DS) {}

ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
                                      SourceLocation RParen) {}

ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
                                   Expr *Operand, SourceLocation RParen) {}

static void MaybeDecrementCount(
    Expr *E, llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {}

/// Perform the conversions required for an expression used in a
/// context that ignores the result.
ExprResult Sema::IgnoredValueConversions(Expr *E) {}

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

// If we can unambiguously determine whether Var can never be used
// in a constant expression, return true.
//  - if the variable and its initializer are non-dependent, then
//    we can unambiguously check if the variable is a constant expression.
//  - if the initializer is not value dependent - we can determine whether
//    it can be used to initialize a constant expression.  If Init can not
//    be used to initialize a constant expression we conclude that Var can
//    never be a constant expression.
//  - FXIME: if the initializer is dependent, we can still do some analysis and
//    identify certain cases unambiguously as non-const by using a Visitor:
//      - such as those that involve odr-use of a ParmVarDecl, involve a new
//        delete, lambda-expr, dynamic-cast, reinterpret-cast etc...
static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var,
    ASTContext &Context) {}

/// Check if the current lambda has any potential captures
/// that must be captured by any of its enclosing lambdas that are ready to
/// capture. If there is a lambda that can capture a nested
/// potential-capture, go ahead and do so.  Also, check to see if any
/// variables are uncaptureable or do not involve an odr-use so do not
/// need to be captured.

static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
    Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) {}

static ExprResult attemptRecovery(Sema &SemaRef,
                                  const TypoCorrectionConsumer &Consumer,
                                  const TypoCorrection &TC) {}

namespace {
class FindTypoExprs : public RecursiveASTVisitor<FindTypoExprs> {};

class TransformTypos : public TreeTransform<TransformTypos> {};
}

ExprResult
Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl,
                                bool RecoverUncorrectedTypos,
                                llvm::function_ref<ExprResult(Expr *)> Filter) {}

ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
                                     bool DiscardedValue, bool IsConstexpr,
                                     bool IsTemplateArgument) {}

StmtResult Sema::ActOnFinishFullStmt(Stmt *FullStmt) {}

Sema::IfExistsResult
Sema::CheckMicrosoftIfExistsSymbol(Scope *S,
                                   CXXScopeSpec &SS,
                                   const DeclarationNameInfo &TargetNameInfo) {}

Sema::IfExistsResult
Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
                                   bool IsIfExists, CXXScopeSpec &SS,
                                   UnqualifiedId &Name) {}

concepts::Requirement *Sema::ActOnSimpleRequirement(Expr *E) {}

concepts::Requirement *Sema::ActOnTypeRequirement(
    SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc,
    const IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId) {}

concepts::Requirement *
Sema::ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc) {}

concepts::Requirement *
Sema::ActOnCompoundRequirement(
    Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS,
    TemplateIdAnnotation *TypeConstraint, unsigned Depth) {}

concepts::ExprRequirement *
Sema::BuildExprRequirement(
    Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
    concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {}

concepts::ExprRequirement *
Sema::BuildExprRequirement(
    concepts::Requirement::SubstitutionDiagnostic *ExprSubstitutionDiagnostic,
    bool IsSimple, SourceLocation NoexceptLoc,
    concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {}

concepts::TypeRequirement *
Sema::BuildTypeRequirement(TypeSourceInfo *Type) {}

concepts::TypeRequirement *
Sema::BuildTypeRequirement(
    concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {}

concepts::Requirement *Sema::ActOnNestedRequirement(Expr *Constraint) {}

concepts::NestedRequirement *
Sema::BuildNestedRequirement(Expr *Constraint) {}

concepts::NestedRequirement *
Sema::BuildNestedRequirement(StringRef InvalidConstraintEntity,
                       const ASTConstraintSatisfaction &Satisfaction) {}

RequiresExprBodyDecl *
Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
                             ArrayRef<ParmVarDecl *> LocalParameters,
                             Scope *BodyScope) {}

void Sema::ActOnFinishRequiresExpr() {}

ExprResult Sema::ActOnRequiresExpr(
    SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body,
    SourceLocation LParenLoc, ArrayRef<ParmVarDecl *> LocalParameters,
    SourceLocation RParenLoc, ArrayRef<concepts::Requirement *> Requirements,
    SourceLocation ClosingBraceLoc) {}