llvm/clang/lib/CodeGen/CGExpr.cpp

//===--- CGExpr.cpp - Emit LLVM Code from 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 contains code to emit Expr nodes as LLVM code.
//
//===----------------------------------------------------------------------===//

#include "ABIInfoImpl.h"
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
#include "CGCall.h"
#include "CGCleanup.h"
#include "CGDebugInfo.h"
#include "CGObjCRuntime.h"
#include "CGOpenMPRuntime.h"
#include "CGRecordLayout.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/NSAPI.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/MatrixBuilder.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/xxhash.h"
#include "llvm/Transforms/Utils/SanitizerStats.h"

#include <optional>
#include <string>

usingnamespaceclang;
usingnamespaceCodeGen;

// Experiment to make sanitizers easier to debug
static llvm::cl::opt<bool> ClSanitizeDebugDeoptimization(
    "ubsan-unique-traps", llvm::cl::Optional,
    llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check."));

// TODO: Introduce frontend options to enabled per sanitizers, similar to
// `fsanitize-trap`.
static llvm::cl::opt<bool> ClSanitizeGuardChecks(
    "ubsan-guard-checks", llvm::cl::Optional,
    llvm::cl::desc("Guard UBSAN checks with `llvm.allow.ubsan.check()`."));

//===--------------------------------------------------------------------===//
//                        Defines for metadata
//===--------------------------------------------------------------------===//

// Those values are crucial to be the SAME as in ubsan runtime library.
enum VariableTypeDescriptorKind : uint16_t {};

//===--------------------------------------------------------------------===//
//                        Miscellaneous Helper Methods
//===--------------------------------------------------------------------===//

/// CreateTempAlloca - This creates a alloca and inserts it into the entry
/// block.
RawAddress
CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits Align,
                                             const Twine &Name,
                                             llvm::Value *ArraySize) {}

/// CreateTempAlloca - This creates a alloca and inserts it into the entry
/// block. The alloca is casted to default address space if necessary.
RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align,
                                             const Twine &Name,
                                             llvm::Value *ArraySize,
                                             RawAddress *AllocaAddr) {}

/// CreateTempAlloca - This creates an alloca and inserts it into the entry
/// block if \p ArraySize is nullptr, otherwise inserts it at the current
/// insertion point of the builder.
llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
                                                    const Twine &Name,
                                                    llvm::Value *ArraySize) {}

/// CreateDefaultAlignTempAlloca - This creates an alloca with the
/// default alignment of the corresponding LLVM type, which is *not*
/// guaranteed to be related in any way to the expected alignment of
/// an AST type that might have been lowered to Ty.
RawAddress CodeGenFunction::CreateDefaultAlignTempAlloca(llvm::Type *Ty,
                                                         const Twine &Name) {}

RawAddress CodeGenFunction::CreateIRTemp(QualType Ty, const Twine &Name) {}

RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name,
                                          RawAddress *Alloca) {}

RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align,
                                          const Twine &Name,
                                          RawAddress *Alloca) {}

RawAddress CodeGenFunction::CreateMemTempWithoutCast(QualType Ty,
                                                     CharUnits Align,
                                                     const Twine &Name) {}

RawAddress CodeGenFunction::CreateMemTempWithoutCast(QualType Ty,
                                                     const Twine &Name) {}

/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
/// expression and compare the result against zero, returning an Int1Ty value.
llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {}

/// EmitIgnoredExpr - Emit code to compute the specified expression,
/// ignoring the result.
void CodeGenFunction::EmitIgnoredExpr(const Expr *E) {}

/// EmitAnyExpr - Emit code to compute the specified expression which
/// can have any type.  The result is returned as an RValue struct.
/// If this is an aggregate expression, AggSlot indicates where the
/// result should be returned.
RValue CodeGenFunction::EmitAnyExpr(const Expr *E,
                                    AggValueSlot aggSlot,
                                    bool ignoreResult) {}

/// EmitAnyExprToTemp - Similar to EmitAnyExpr(), however, the result will
/// always be accessible even if no aggregate location is provided.
RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E) {}

/// EmitAnyExprToMem - Evaluate an expression into a given memory
/// location.
void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
                                       Address Location,
                                       Qualifiers Quals,
                                       bool IsInit) {}

void CodeGenFunction::EmitInitializationToLValue(
    const Expr *E, LValue LV, AggValueSlot::IsZeroed_t IsZeroed) {}

static void
pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
                     const Expr *E, Address ReferenceTemporary) {}

static RawAddress createReferenceTemporary(CodeGenFunction &CGF,
                                           const MaterializeTemporaryExpr *M,
                                           const Expr *Inner,
                                           RawAddress *Alloca = nullptr) {}

/// Helper method to check if the underlying ABI is AAPCS
static bool isAAPCS(const TargetInfo &TargetInfo) {}

LValue CodeGenFunction::
EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {}

RValue
CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E) {}


/// getAccessedFieldNo - Given an encoded value and a result number, return the
/// input field number being accessed.
unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
                                             const llvm::Constant *Elts) {}

static llvm::Value *emitHashMix(CGBuilderTy &Builder, llvm::Value *Acc,
                                llvm::Value *Ptr) {}

bool CodeGenFunction::isNullPointerAllowed(TypeCheckKind TCK) {}

bool CodeGenFunction::isVptrCheckRequired(TypeCheckKind TCK, QualType Ty) {}

bool CodeGenFunction::sanitizePerformTypeCheck() const {}

void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
                                    llvm::Value *Ptr, QualType Ty,
                                    CharUnits Alignment,
                                    SanitizerSet SkippedChecks,
                                    llvm::Value *ArraySize) {}

llvm::Value *CodeGenFunction::LoadPassedObjectSize(const Expr *E,
                                                   QualType EltTy) {}

/// If Base is known to point to the start of an array, return the length of
/// that array. Return 0 if the length cannot be determined.
static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
                                          const Expr *Base,
                                          QualType &IndexedType,
                                          LangOptions::StrictFlexArraysLevelKind
                                          StrictFlexArraysLevel) {}

namespace {

/// \p StructAccessBase returns the base \p Expr of a field access. It returns
/// either a \p DeclRefExpr, representing the base pointer to the struct, i.e.:
///
///     p in p-> a.b.c
///
/// or a \p MemberExpr, if the \p MemberExpr has the \p RecordDecl we're
/// looking for:
///
///     struct s {
///       struct s *ptr;
///       int count;
///       char array[] __attribute__((counted_by(count)));
///     };
///
/// If we have an expression like \p p->ptr->array[index], we want the
/// \p MemberExpr for \p p->ptr instead of \p p.
class StructAccessBase
    : public ConstStmtVisitor<StructAccessBase, const Expr *> {};

} // end anonymous namespace

RecIndicesTy;

static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD,
                                 const FieldDecl *Field,
                                 RecIndicesTy &Indices) {}

/// This method is typically called in contexts where we can't generate
/// side-effects, like in __builtin_dynamic_object_size. When finding
/// expressions, only choose those that have either already been emitted or can
/// be loaded without side-effects.
///
/// - \p FAMDecl: the \p Decl for the flexible array member. It may not be
///   within the top-level struct.
/// - \p CountDecl: must be within the same non-anonymous struct as \p FAMDecl.
llvm::Value *CodeGenFunction::EmitLoadOfCountedByField(
    const Expr *Base, const FieldDecl *FAMDecl, const FieldDecl *CountDecl) {}

void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
                                      llvm::Value *Index, QualType IndexType,
                                      bool Accessed) {}

void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
                                          llvm::Value *Index,
                                          QualType IndexType,
                                          QualType IndexedType, bool Accessed) {}

CodeGenFunction::ComplexPairTy CodeGenFunction::
EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
                         bool isInc, bool isPre) {}

void CodeGenModule::EmitExplicitCastExprType(const ExplicitCastExpr *E,
                                             CodeGenFunction *CGF) {}

//===----------------------------------------------------------------------===//
//                         LValue Expression Emission
//===----------------------------------------------------------------------===//

static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
                                        TBAAAccessInfo *TBAAInfo,
                                        KnownNonNull_t IsKnownNonNull,
                                        CodeGenFunction &CGF) {}

/// EmitPointerWithAlignment - Given an expression of pointer type, try to
/// derive a more accurate bound on the alignment of the pointer.
Address CodeGenFunction::EmitPointerWithAlignment(
    const Expr *E, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo,
    KnownNonNull_t IsKnownNonNull) {}

llvm::Value *CodeGenFunction::EmitNonNullRValueCheck(RValue RV, QualType T) {}

RValue CodeGenFunction::GetUndefRValue(QualType Ty) {}

RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E,
                                              const char *Name) {}

LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
                                              const char *Name) {}

bool CodeGenFunction::IsWrappedCXXThis(const Expr *Obj) {}

LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) {}

/// EmitLValue - Emit code to compute a designator that specifies the location
/// of the expression.
///
/// This can return one of two things: a simple address or a bitfield reference.
/// In either case, the LLVM Value* in the LValue structure is guaranteed to be
/// an LLVM pointer type.
///
/// If this returns a bitfield reference, nothing about the pointee type of the
/// LLVM value is known: For example, it may not be a pointer to an integer.
///
/// If this returns a normal address, and if the lvalue's C type is fixed size,
/// this method guarantees that the returned pointer type will point to an LLVM
/// type of the same size of the lvalue's type.  If the lvalue has a variable
/// length type, this is not possible.
///
LValue CodeGenFunction::EmitLValue(const Expr *E,
                                   KnownNonNull_t IsKnownNonNull) {}

static QualType getConstantExprReferredType(const FullExpr *E,
                                            const ASTContext &Ctx) {}

LValue CodeGenFunction::EmitLValueHelper(const Expr *E,
                                         KnownNonNull_t IsKnownNonNull) {}

/// Given an object of the given canonical type, can we safely copy a
/// value out of it based on its initializer?
static bool isConstantEmittableObjectType(QualType type) {}

/// Can we constant-emit a load of a reference to a variable of the
/// given type?  This is different from predicates like
/// Decl::mightBeUsableInConstantExpressions because we do want it to apply
/// in situations that don't necessarily satisfy the language's rules
/// for this (e.g. C++'s ODR-use rules).  For example, we want to able
/// to do this with const float variables even if those variables
/// aren't marked 'constexpr'.
enum ConstantEmissionKind {};
static ConstantEmissionKind checkVarTypeForConstantEmission(QualType type) {}

/// Try to emit a reference to the given value without producing it as
/// an l-value.  This is just an optimization, but it avoids us needing
/// to emit global copies of variables if they're named without triggering
/// a formal use in a context where we can't emit a direct reference to them,
/// for instance if a block or lambda or a member of a local class uses a
/// const int variable or constexpr variable from an enclosing function.
CodeGenFunction::ConstantEmission
CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {}

static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CodeGenFunction &CGF,
                                                        const MemberExpr *ME) {}

CodeGenFunction::ConstantEmission
CodeGenFunction::tryEmitAsConstant(const MemberExpr *ME) {}

llvm::Value *CodeGenFunction::emitScalarConstant(
    const CodeGenFunction::ConstantEmission &Constant, Expr *E) {}

llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue,
                                               SourceLocation Loc) {}

static bool hasBooleanRepresentation(QualType Ty) {}

static bool getRangeForType(CodeGenFunction &CGF, QualType Ty,
                            llvm::APInt &Min, llvm::APInt &End,
                            bool StrictEnums, bool IsBool) {}

llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {}

bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
                                           SourceLocation Loc) {}

llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
                                               QualType Ty,
                                               SourceLocation Loc,
                                               LValueBaseInfo BaseInfo,
                                               TBAAAccessInfo TBAAInfo,
                                               bool isNontemporal) {}

/// Converts a scalar value from its primary IR type (as returned
/// by ConvertType) to its load/store type (as returned by
/// convertTypeForLoadStore).
llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {}

/// Converts a scalar value from its load/store type (as returned
/// by convertTypeForLoadStore) to its primary IR type (as returned
/// by ConvertType).
llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {}

// Convert the pointer of \p Addr to a pointer to a vector (the value type of
// MatrixType), if it points to a array (the memory type of MatrixType).
static RawAddress MaybeConvertMatrixAddress(RawAddress Addr,
                                            CodeGenFunction &CGF,
                                            bool IsVector = true) {}

// Emit a store of a matrix LValue. This may require casting the original
// pointer to memory address (ArrayType) to a pointer to the value type
// (VectorType).
static void EmitStoreOfMatrixScalar(llvm::Value *value, LValue lvalue,
                                    bool isInit, CodeGenFunction &CGF) {}

void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
                                        bool Volatile, QualType Ty,
                                        LValueBaseInfo BaseInfo,
                                        TBAAAccessInfo TBAAInfo,
                                        bool isInit, bool isNontemporal) {}

void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,
                                        bool isInit) {}

// Emit a load of a LValue of matrix type. This may require casting the pointer
// to memory address (ArrayType) to a pointer to the value type (VectorType).
static RValue EmitLoadOfMatrixLValue(LValue LV, SourceLocation Loc,
                                     CodeGenFunction &CGF) {}

RValue CodeGenFunction::EmitLoadOfAnyValue(LValue LV, AggValueSlot Slot,
                                           SourceLocation Loc) {}

/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
/// method emits the address of the lvalue, then loads the result as an rvalue,
/// returning the rvalue.
RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) {}

RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
                                                 SourceLocation Loc) {}

// If this is a reference to a subset of the elements of a vector, create an
// appropriate shufflevector.
RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {}

/// Generates lvalue for partial ext_vector access.
Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) {}

/// Load of global named registers are always calls to intrinsics.
RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {}

/// EmitStoreThroughLValue - Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
                                             bool isInit) {}

void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
                                                     llvm::Value **Result) {}

void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
                                                               LValue Dst) {}

/// Store of global named registers are always calls to intrinsics.
void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {}

// setObjCGCLValueClass - sets class of the lvalue for the purpose of
// generating write-barries API. It is currently a global, ivar,
// or neither.
static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
                                 LValue &LV,
                                 bool IsMemberAccess=false) {}

static LValue EmitThreadPrivateVarDeclLValue(
    CodeGenFunction &CGF, const VarDecl *VD, QualType T, Address Addr,
    llvm::Type *RealVarTy, SourceLocation Loc) {}

static Address emitDeclTargetVarDeclLValue(CodeGenFunction &CGF,
                                           const VarDecl *VD, QualType T) {}

Address
CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
                                     LValueBaseInfo *PointeeBaseInfo,
                                     TBAAAccessInfo *PointeeTBAAInfo) {}

LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {}

Address CodeGenFunction::EmitLoadOfPointer(Address Ptr,
                                           const PointerType *PtrTy,
                                           LValueBaseInfo *BaseInfo,
                                           TBAAAccessInfo *TBAAInfo) {}

LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr,
                                                const PointerType *PtrTy) {}

static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
                                      const Expr *E, const VarDecl *VD) {}

llvm::Constant *CodeGenModule::getRawFunctionPointer(GlobalDecl GD,
                                                     llvm::Type *Ty) {}

static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF, const Expr *E,
                                     GlobalDecl GD) {}

static LValue EmitCapturedFieldLValue(CodeGenFunction &CGF, const FieldDecl *FD,
                                      llvm::Value *ThisValue) {}

/// Named Registers are named metadata pointing to the register name
/// which will be read from/written to as an argument to the intrinsic
/// @llvm.read/write_register.
/// So far, only the name is being passed down, but other options such as
/// register type, allocation type or even optimization options could be
/// passed down via the metadata node.
static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM) {}

/// Determine whether we can emit a reference to \p VD from the current
/// context, despite not necessarily having seen an odr-use of the variable in
/// this context.
static bool canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
                                               const DeclRefExpr *E,
                                               const VarDecl *VD) {}

LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {}

LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {}

LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {}

LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {}

LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {}

/// Emit a type description suitable for use by a runtime sanitizer library. The
/// format of a type descriptor is
///
/// \code
///   { i16 TypeKind, i16 TypeInfo }
/// \endcode
///
/// followed by an array of i8 containing the type name with extra information
/// for BitInt. TypeKind is TK_Integer(0) for an integer, TK_Float(1) for a
/// floating point value, TK_BitInt(2) for BitInt and TK_Unknown(0xFFFF) for
/// anything else.
llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {}

llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {}

/// Emit a representation of a SourceLocation for passing to a handler
/// in a sanitizer runtime library. The format for this data is:
/// \code
///   struct SourceLocation {
///     const char *Filename;
///     int32_t Line, Column;
///   };
/// \endcode
/// For an invalid SourceLocation, the Filename pointer is null.
llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {}

namespace {
/// Specify under what conditions this check can be recovered
enum class CheckRecoverableKind {};
}

static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) {}

namespace {
struct SanitizerHandlerInfo {};
}

const SanitizerHandlerInfo SanitizerHandlers[] =;

static void emitCheckHandlerCall(CodeGenFunction &CGF,
                                 llvm::FunctionType *FnType,
                                 ArrayRef<llvm::Value *> FnArgs,
                                 SanitizerHandler CheckHandler,
                                 CheckRecoverableKind RecoverKind, bool IsFatal,
                                 llvm::BasicBlock *ContBB) {}

void CodeGenFunction::EmitCheck(
    ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
    SanitizerHandler CheckHandler, ArrayRef<llvm::Constant *> StaticArgs,
    ArrayRef<llvm::Value *> DynamicArgs) {}

void CodeGenFunction::EmitCfiSlowPathCheck(
    SanitizerMask Kind, llvm::Value *Cond, llvm::ConstantInt *TypeId,
    llvm::Value *Ptr, ArrayRef<llvm::Constant *> StaticArgs) {}

// Emit a stub for __cfi_check function so that the linker knows about this
// symbol in LTO mode.
void CodeGenFunction::EmitCfiCheckStub() {}

// This function is basically a switch over the CFI failure kind, which is
// extracted from CFICheckFailData (1st function argument). Each case is either
// llvm.trap or a call to one of the two runtime handlers, based on
// -fsanitize-trap and -fsanitize-recover settings.  Default case (invalid
// failure kind) traps, but this should really never happen.  CFICheckFailData
// can be nullptr if the calling module has -fsanitize-trap behavior for this
// check kind; in this case __cfi_check_fail traps as well.
void CodeGenFunction::EmitCfiCheckFail() {}

void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {}

void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
                                    SanitizerHandler CheckHandlerID) {}

llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {}

Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E,
                                                 LValueBaseInfo *BaseInfo,
                                                 TBAAAccessInfo *TBAAInfo) {}

/// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an
/// array to pointer, return the array subexpression.
static const Expr *isSimpleArrayDecayOperand(const Expr *E) {}

static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF,
                                          llvm::Type *elemType,
                                          llvm::Value *ptr,
                                          ArrayRef<llvm::Value*> indices,
                                          bool inbounds,
                                          bool signedIndices,
                                          SourceLocation loc,
                                    const llvm::Twine &name = "arrayidx") {}

static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
                                     ArrayRef<llvm::Value *> indices,
                                     llvm::Type *elementType, bool inbounds,
                                     bool signedIndices, SourceLocation loc,
                                     CharUnits align,
                                     const llvm::Twine &name = "arrayidx") {}

static CharUnits getArrayElementAlign(CharUnits arrayAlign,
                                      llvm::Value *idx,
                                      CharUnits eltSize) {}

static QualType getFixedSizeElementType(const ASTContext &ctx,
                                        const VariableArrayType *vla) {}

static bool hasBPFPreserveStaticOffset(const RecordDecl *D) {}

static bool hasBPFPreserveStaticOffset(const Expr *E) {}

// Wraps Addr with a call to llvm.preserve.static.offset intrinsic.
static Address wrapWithBPFPreserveStaticOffset(CodeGenFunction &CGF,
                                               Address &Addr) {}

/// Given an array base, check whether its member access belongs to a record
/// with preserve_access_index attribute or not.
static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase) {}

static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
                                     ArrayRef<llvm::Value *> indices,
                                     QualType eltType, bool inbounds,
                                     bool signedIndices, SourceLocation loc,
                                     QualType *arrayType = nullptr,
                                     const Expr *Base = nullptr,
                                     const llvm::Twine &name = "arrayidx") {}

/// The offset of a field from the beginning of the record.
static bool getFieldOffsetInBits(CodeGenFunction &CGF, const RecordDecl *RD,
                                 const FieldDecl *Field, int64_t &Offset) {}

/// Returns the relative offset difference between \p FD1 and \p FD2.
/// \code
///   offsetof(struct foo, FD1) - offsetof(struct foo, FD2)
/// \endcode
/// Both fields must be within the same struct.
static std::optional<int64_t> getOffsetDifferenceInBits(CodeGenFunction &CGF,
                                                        const FieldDecl *FD1,
                                                        const FieldDecl *FD2) {}

LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
                                               bool Accessed) {}

llvm::Value *CodeGenFunction::EmitMatrixIndexExpr(const Expr *E) {}

LValue CodeGenFunction::EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E) {}

static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
                                       LValueBaseInfo &BaseInfo,
                                       TBAAAccessInfo &TBAAInfo,
                                       QualType BaseTy, QualType ElTy,
                                       bool IsLowerBound) {}

LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
                                             bool IsLowerBound) {}

LValue CodeGenFunction::
EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {}

LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {}

/// Given that we are currently emitting a lambda, emit an l-value for
/// one of its members.
///
LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field,
                                                 llvm::Value *ThisValue) {}

LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field) {}

/// Get the field index in the debug info. The debug info structure/union
/// will ignore the unnamed bitfields.
unsigned CodeGenFunction::getDebugInfoFIndex(const RecordDecl *Rec,
                                             unsigned FieldIndex) {}

/// Get the address of a zero-sized field within a record. The resulting
/// address doesn't necessarily have the right type.
static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base,
                                       const FieldDecl *Field) {}

/// Drill down to the storage of a field without walking into
/// reference types.
///
/// The resulting address doesn't necessarily have the right type.
static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
                                      const FieldDecl *field) {}

static Address emitPreserveStructAccess(CodeGenFunction &CGF, LValue base,
                                        Address addr, const FieldDecl *field) {}

static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {}

LValue CodeGenFunction::EmitLValueForField(LValue base,
                                           const FieldDecl *field) {}

LValue
CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
                                                  const FieldDecl *Field) {}

LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){}

LValue CodeGenFunction::EmitInitListLValue(const InitListExpr *E) {}

/// Emit the operand of a glvalue conditional operator. This is either a glvalue
/// or a (possibly-parenthesized) throw-expression. If this is a throw, no
/// LValue is returned and the current block has been terminated.
static std::optional<LValue> EmitLValueOrThrowExpression(CodeGenFunction &CGF,
                                                         const Expr *Operand) {}

namespace {
// Handle the case where the condition is a constant evaluatable simple integer,
// which means we don't have to separately handle the true/false blocks.
std::optional<LValue> HandleConditionalOperatorLValueSimpleCase(
    CodeGenFunction &CGF, const AbstractConditionalOperator *E) {}
struct ConditionalInfo {};

// Create and generate the 3 blocks for a conditional operator.
// Leaves the 'current block' in the continuation basic block.
template<typename FuncTy>
ConditionalInfo EmitConditionalBlocks(CodeGenFunction &CGF,
                                      const AbstractConditionalOperator *E,
                                      const FuncTy &BranchGenFunc) {}
} // namespace

void CodeGenFunction::EmitIgnoredConditionalOperator(
    const AbstractConditionalOperator *E) {}
LValue CodeGenFunction::EmitConditionalOperatorLValue(
    const AbstractConditionalOperator *expr) {}

/// EmitCastLValue - Casts are never lvalues unless that cast is to a reference
/// type. If the cast is to a reference, we can have the usual lvalue result,
/// otherwise if a cast is needed by the code generator in an lvalue context,
/// then it must mean that we need the address of an aggregate in order to
/// access one of its members.  This can happen for all the reasons that casts
/// are permitted with aggregate result, including noop aggregate casts, and
/// cast from scalar to union.
LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {}

LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) {}

void CodeGenFunction::EmitHLSLOutArgExpr(const HLSLOutArgExpr *E,
                                         CallArgList &Args, QualType Ty) {}

LValue
CodeGenFunction::getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e) {}

RValue
CodeGenFunction::getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e) {}

RValue CodeGenFunction::EmitRValueForField(LValue LV,
                                           const FieldDecl *FD,
                                           SourceLocation Loc) {}

//===--------------------------------------------------------------------===//
//                             Expression Emission
//===--------------------------------------------------------------------===//

RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
                                     ReturnValueSlot ReturnValue,
                                     llvm::CallBase **CallOrInvoke) {}

/// Emit a CallExpr without considering whether it might be a subclass.
RValue CodeGenFunction::EmitSimpleCallExpr(const CallExpr *E,
                                           ReturnValueSlot ReturnValue,
                                           llvm::CallBase **CallOrInvoke) {}

// Detect the unusual situation where an inline version is shadowed by a
// non-inline version. In that case we should pick the external one
// everywhere. That's GCC behavior too.
static bool OnlyHasInlineBuiltinDeclaration(const FunctionDecl *FD) {}

static CGCallee EmitDirectCallee(CodeGenFunction &CGF, GlobalDecl GD) {}

CGCallee CodeGenFunction::EmitCallee(const Expr *E) {}

LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {}

// This function implements trivial copy assignment for HLSL's
// assignable constant arrays.
LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {}

LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E,
                                           llvm::CallBase **CallOrInvoke) {}

LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {}

LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {}

LValue
CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {}

Address CodeGenFunction::EmitCXXUuidofExpr(const CXXUuidofExpr *E) {}

LValue CodeGenFunction::EmitCXXUuidofLValue(const CXXUuidofExpr *E) {}

LValue
CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {}

LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {}

LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) {}

llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
                                             const ObjCIvarDecl *Ivar) {}

llvm::Value *
CodeGenFunction::EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface,
                                             const ObjCIvarDecl *Ivar) {}

LValue CodeGenFunction::EmitLValueForIvar(QualType ObjectTy,
                                          llvm::Value *BaseValue,
                                          const ObjCIvarDecl *Ivar,
                                          unsigned CVRQualifiers) {}

LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {}

LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {}

RValue CodeGenFunction::EmitCall(QualType CalleeType,
                                 const CGCallee &OrigCallee, const CallExpr *E,
                                 ReturnValueSlot ReturnValue,
                                 llvm::Value *Chain,
                                 llvm::CallBase **CallOrInvoke,
                                 CGFunctionInfo const **ResolvedFnInfo) {}

LValue CodeGenFunction::
EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {}

/// Given the address of a temporary variable, produce an r-value of
/// its type.
RValue CodeGenFunction::convertTempToRValue(Address addr,
                                            QualType type,
                                            SourceLocation loc) {}

void CodeGenFunction::SetFPAccuracy(llvm::Value *Val, float Accuracy) {}

void CodeGenFunction::SetSqrtFPAccuracy(llvm::Value *Val) {}

void CodeGenFunction::SetDivFPAccuracy(llvm::Value *Val) {}

namespace {
  struct LValueOrRValue {};
}

static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF,
                                           const PseudoObjectExpr *E,
                                           bool forLValue,
                                           AggValueSlot slot) {}

RValue CodeGenFunction::EmitPseudoObjectRValue(const PseudoObjectExpr *E,
                                               AggValueSlot slot) {}

LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) {}