llvm/clang/lib/CodeGen/CGExprScalar.cpp

//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
//
// 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 with scalar LLVM types as LLVM code.
//
//===----------------------------------------------------------------------===//

#include "CGCXXABI.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/Expr.h"
#include "clang/AST/ParentMapContext.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/APFixedPoint.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/FixedPointBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GEPNoWrapFlags.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/MatrixBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/TypeSize.h"
#include <cstdarg>
#include <optional>

usingnamespaceclang;
usingnamespaceCodeGen;
Value;

//===----------------------------------------------------------------------===//
//                         Scalar Expression Emitter
//===----------------------------------------------------------------------===//

namespace llvm {
extern cl::opt<bool> EnableSingleByteCoverage;
} // namespace llvm

namespace {

/// Determine whether the given binary operation may overflow.
/// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul,
/// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem},
/// the returned overflow check is precise. The returned value is 'true' for
/// all other opcodes, to be conservative.
bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
                             BinaryOperator::Opcode Opcode, bool Signed,
                             llvm::APInt &Result) {}

struct BinOpInfo {};

static bool MustVisitNullValue(const Expr *E) {}

/// If \p E is a widened promoted integer, get its base (unpromoted) type.
static std::optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx,
                                                       const Expr *E) {}

/// Check if \p E is a widened promoted integer.
static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) {}

/// Check if we can skip the overflow check for \p Op.
static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {}

class ScalarExprEmitter
  : public StmtVisitor<ScalarExprEmitter, Value*> {}};
}  // end anonymous namespace.

//===----------------------------------------------------------------------===//
//                                Utilities
//===----------------------------------------------------------------------===//

/// EmitConversionToBool - Convert the specified expression value to a
/// boolean (i1) truth value.  This is equivalent to "Val != 0".
Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {}

void ScalarExprEmitter::EmitFloatConversionCheck(
    Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType,
    QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {}

// Should be called within CodeGenFunction::SanitizerScope RAII scope.
// Returns 'i1 false' when the truncation Src -> Dst was lossy.
static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
                 std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
                                 QualType DstType, CGBuilderTy &Builder) {}

static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
    QualType SrcType, QualType DstType) {}

void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
                                                   Value *Dst, QualType DstType,
                                                   SourceLocation Loc) {}

static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType,
                                             const char *Name,
                                             CGBuilderTy &Builder) {}

// Should be called within CodeGenFunction::SanitizerScope RAII scope.
// Returns 'i1 false' when the conversion Src -> Dst changed the sign.
static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
                 std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
                                 QualType DstType, CGBuilderTy &Builder) {}

void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
                                                   Value *Dst, QualType DstType,
                                                   SourceLocation Loc) {}

// Should be called within CodeGenFunction::SanitizerScope RAII scope.
// Returns 'i1 false' when the truncation Src -> Dst was lossy.
static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
                 std::pair<llvm::Value *, SanitizerMask>>
EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
                                  QualType DstType, CGBuilderTy &Builder) {}

// Should be called within CodeGenFunction::SanitizerScope RAII scope.
// Returns 'i1 false' when the conversion Src -> Dst changed the sign.
static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
                 std::pair<llvm::Value *, SanitizerMask>>
EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
                                  QualType DstType, CGBuilderTy &Builder) {}

void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
                                                  Value *Dst, QualType DstType,
                                                  const CGBitFieldInfo &Info,
                                                  SourceLocation Loc) {}

Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
                                         QualType DstType, llvm::Type *SrcTy,
                                         llvm::Type *DstTy,
                                         ScalarConversionOpts Opts) {}

/// Emit a conversion from the specified type to the specified destination type,
/// both of which are LLVM scalar types.
Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
                                               QualType DstType,
                                               SourceLocation Loc,
                                               ScalarConversionOpts Opts) {}

Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
                                                   QualType DstTy,
                                                   SourceLocation Loc) {}

/// Emit a conversion from the specified complex type to the specified
/// destination type, where the destination type is an LLVM scalar type.
Value *ScalarExprEmitter::EmitComplexToScalarConversion(
    CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy,
    SourceLocation Loc) {}

Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {}

/// Emit a sanitization check for the given "binary" operation (which
/// might actually be a unary increment which has been lowered to a binary
/// operation). The check passes if all values in \p Checks (which are \c i1),
/// are \c true.
void ScalarExprEmitter::EmitBinOpCheck(
    ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) {}

//===----------------------------------------------------------------------===//
//                            Visitor Methods
//===----------------------------------------------------------------------===//

Value *ScalarExprEmitter::VisitExpr(Expr *E) {}

Value *
ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {}

Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {}

Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {}

Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {}

Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {}

Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {}

Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {}

static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,
                      unsigned Off) {}

static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) {}

Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {}

bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) {}

// VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
// have to handle a more broad range of conversions than explicit casts, as they
// handle things like function to ptr-to-function decay etc.
Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {}

Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {}

Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {}

//===----------------------------------------------------------------------===//
//                             Unary Operators
//===----------------------------------------------------------------------===//

static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E,
                                           llvm::Value *InVal, bool IsInc,
                                           FPOptions FPFeatures) {}

llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
    const UnaryOperator *E, llvm::Value *InVal, bool IsInc) {}

/// For the purposes of overflow pattern exclusion, does this match the
/// "while(i--)" pattern?
static bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc,
                                   bool isPre, ASTContext &Ctx) {}

namespace {
/// Handles check and update for lastprivate conditional variables.
class OMPLastprivateConditionalUpdateRAII {};
} // namespace

llvm::Value *
ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
                                           bool isInc, bool isPre) {}


Value *ScalarExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
                                         QualType PromotionType) {}

Value *ScalarExprEmitter::VisitPlus(const UnaryOperator *E,
                                    QualType PromotionType) {}

Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
                                          QualType PromotionType) {}

Value *ScalarExprEmitter::VisitMinus(const UnaryOperator *E,
                                     QualType PromotionType) {}

Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {}

Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {}

Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {}

/// VisitUnaryExprOrTypeTraitExpr - Return the size or alignment of the type of
/// argument of the sizeof expression as an integer.
Value *
ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
                              const UnaryExprOrTypeTraitExpr *E) {}

Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E,
                                         QualType PromotionType) {}

Value *ScalarExprEmitter::VisitReal(const UnaryOperator *E,
                                    QualType PromotionType) {}

Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E,
                                         QualType PromotionType) {}

Value *ScalarExprEmitter::VisitImag(const UnaryOperator *E,
                                    QualType PromotionType) {}

//===----------------------------------------------------------------------===//
//                           Binary Operators
//===----------------------------------------------------------------------===//

Value *ScalarExprEmitter::EmitPromotedValue(Value *result,
                                            QualType PromotionType) {}

Value *ScalarExprEmitter::EmitUnPromotedValue(Value *result,
                                              QualType ExprType) {}

Value *ScalarExprEmitter::EmitPromoted(const Expr *E, QualType PromotionType) {}

BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E,
                                        QualType PromotionType) {}

LValue ScalarExprEmitter::EmitCompoundAssignLValue(
                                              const CompoundAssignOperator *E,
                        Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
                                                   Value *&Result) {}

Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
                      Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {}

void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
    const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {}

Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {}

Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {}

Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {}

/// Emit pointer + index arithmetic.
static Value *emitPointerArithmetic(CodeGenFunction &CGF,
                                    const BinOpInfo &op,
                                    bool isSubtraction) {}

// Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
// Addend. Use negMul and negAdd to negate the first operand of the Mul or
// the add operand respectively. This allows fmuladd to represent a*b-c, or
// c-a*b. Patterns in LLVM should catch the negated forms and translate them to
// efficient operations.
static Value* buildFMulAdd(llvm::Instruction *MulOp, Value *Addend,
                           const CodeGenFunction &CGF, CGBuilderTy &Builder,
                           bool negMul, bool negAdd) {}

// Check whether it would be legal to emit an fmuladd intrinsic call to
// represent op and if so, build the fmuladd.
//
// Checks that (a) the operation is fusable, and (b) -ffp-contract=on.
// Does NOT check the type of the operation - it's assumed that this function
// will be called from contexts where it's known that the type is contractable.
static Value* tryEmitFMulAdd(const BinOpInfo &op,
                         const CodeGenFunction &CGF, CGBuilderTy &Builder,
                         bool isSub=false) {}

Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {}

/// The resulting value must be calculated with exact precision, so the operands
/// may not be the same type.
Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) {}

Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {}

Value *ScalarExprEmitter::GetMaximumShiftAmount(Value *LHS, Value *RHS,
                                                bool RHSIsSigned) {}

Value *ScalarExprEmitter::ConstrainShiftValue(Value *LHS, Value *RHS,
                                              const Twine &Name) {}

Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {}

Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {}

enum IntrinsicType {};
// return corresponding comparison intrinsic for given vector type
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT,
                                        BuiltinType::Kind ElemKind) {}

Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
                                      llvm::CmpInst::Predicate UICmpOpc,
                                      llvm::CmpInst::Predicate SICmpOpc,
                                      llvm::CmpInst::Predicate FCmpOpc,
                                      bool IsSignaling) {}

llvm::Value *CodeGenFunction::EmitWithOriginalRHSBitfieldAssignment(
    const BinaryOperator *E, Value **Previous, QualType *SrcType) {}

Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {}

Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {}

Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {}

Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {}

//===----------------------------------------------------------------------===//
//                             Other Operators
//===----------------------------------------------------------------------===//

/// isCheapEnoughToEvaluateUnconditionally - Return true if the specified
/// expression is cheap enough and side-effect-free enough to evaluate
/// unconditionally instead of conditionally.  This is used to convert control
/// flow into selects in some cases.
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
                                                   CodeGenFunction &CGF) {}


Value *ScalarExprEmitter::
VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {}

Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {}

Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {}

Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {}

// Convert a vec3 to vec4, or vice versa.
static Value *ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF,
                                 Value *Src, unsigned NumElementsDst) {}

// Create cast instructions for converting LLVM value \p Src to LLVM type \p
// DstTy. \p Src has the same size as \p DstTy. Both are single value types
// but could be scalar or vectors of different lengths, and either can be
// pointer.
// There are 4 cases:
// 1. non-pointer -> non-pointer  : needs 1 bitcast
// 2. pointer -> pointer          : needs 1 bitcast or addrspacecast
// 3. pointer -> non-pointer
//   a) pointer -> intptr_t       : needs 1 ptrtoint
//   b) pointer -> non-intptr_t   : needs 1 ptrtoint then 1 bitcast
// 4. non-pointer -> pointer
//   a) intptr_t -> pointer       : needs 1 inttoptr
//   b) non-intptr_t -> pointer   : needs 1 bitcast then 1 inttoptr
// Note: for cases 3b and 4b two casts are required since LLVM casts do not
// allow casting directly between pointer types and non-integer non-pointer
// types.
static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder,
                                           const llvm::DataLayout &DL,
                                           Value *Src, llvm::Type *DstTy,
                                           StringRef Name = "") {}

Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {}

Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {}

//===----------------------------------------------------------------------===//
//                         Entry Point into this File
//===----------------------------------------------------------------------===//

/// Emit the computation of the specified expression of scalar type, ignoring
/// the result.
Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {}

/// Emit a conversion from the specified type to the specified destination type,
/// both of which are LLVM scalar types.
Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
                                             QualType DstTy,
                                             SourceLocation Loc) {}

/// Emit a conversion from the specified complex type to the specified
/// destination type, where the destination type is an LLVM scalar type.
Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
                                                      QualType SrcTy,
                                                      QualType DstTy,
                                                      SourceLocation Loc) {}


Value *
CodeGenFunction::EmitPromotedScalarExpr(const Expr *E,
                                        QualType PromotionType) {}


llvm::Value *CodeGenFunction::
EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
                        bool isInc, bool isPre) {}

LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {}


LValue CodeGenFunction::EmitCompoundAssignmentLValue(
                                            const CompoundAssignOperator *E) {}

struct GEPOffsetAndOverflow {};

/// Evaluate given GEPVal, which is either an inbounds GEP, or a constant,
/// and compute the total offset it applies from it's base pointer BasePtr.
/// Returns offset in bytes and a boolean flag whether an overflow happened
/// during evaluation.
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal,
                                                 llvm::LLVMContext &VMContext,
                                                 CodeGenModule &CGM,
                                                 CGBuilderTy &Builder) {}

Value *
CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
                                        ArrayRef<Value *> IdxList,
                                        bool SignedIndices, bool IsSubtraction,
                                        SourceLocation Loc, const Twine &Name) {}

Address CodeGenFunction::EmitCheckedInBoundsGEP(
    Address Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
    bool SignedIndices, bool IsSubtraction, SourceLocation Loc, CharUnits Align,
    const Twine &Name) {}