31#include "llvm/ADT/APFixedPoint.h"
32#include "llvm/IR/CFG.h"
33#include "llvm/IR/Constants.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/DerivedTypes.h"
36#include "llvm/IR/FixedPointBuilder.h"
37#include "llvm/IR/Function.h"
38#include "llvm/IR/GetElementPtrTypeIterator.h"
39#include "llvm/IR/GlobalVariable.h"
40#include "llvm/IR/Intrinsics.h"
41#include "llvm/IR/IntrinsicsPowerPC.h"
42#include "llvm/IR/MatrixBuilder.h"
43#include "llvm/IR/Module.h"
44#include "llvm/Support/TypeSize.h"
49using namespace CodeGen;
67bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
69 llvm::APInt &Result) {
72 const auto &LHSAP = LHS->getValue();
73 const auto &RHSAP = RHS->getValue();
74 if (Opcode == BO_Add) {
75 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
76 : LHSAP.uadd_ov(RHSAP, Overflow);
77 }
else if (Opcode == BO_Sub) {
78 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
79 : LHSAP.usub_ov(RHSAP, Overflow);
80 }
else if (Opcode == BO_Mul) {
81 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
82 : LHSAP.umul_ov(RHSAP, Overflow);
83 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
84 if (
Signed && !RHS->isZero())
85 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
101 bool mayHaveIntegerOverflow()
const {
103 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
104 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
105 if (!LHSCI || !RHSCI)
109 return ::mayHaveIntegerOverflow(
114 bool isDivremOp()
const {
120 bool mayHaveIntegerDivisionByZero()
const {
122 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
128 bool mayHaveFloatDivisionByZero()
const {
130 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
131 return CFP->isZero();
138 bool isFixedPointOp()
const {
141 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
142 QualType LHSType = BinOp->getLHS()->getType();
143 QualType RHSType = BinOp->getRHS()->getType();
146 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
147 return UnOp->getSubExpr()->getType()->isFixedPointType();
152 bool rhsHasSignedIntegerRepresentation()
const {
153 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
154 QualType RHSType = BinOp->getRHS()->getType();
161static bool MustVisitNullValue(
const Expr *
E) {
169static std::optional<QualType> getUnwidenedIntegerType(
const ASTContext &Ctx,
185 return getUnwidenedIntegerType(Ctx,
E).has_value();
189static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
190 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
191 "Expected a unary or binary operator");
195 if (!Op.mayHaveIntegerOverflow())
199 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
200 return !UO->canOverflow();
204 const auto *BO = cast<BinaryOperator>(Op.E);
205 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
209 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
218 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
224 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
225 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
229class ScalarExprEmitter
233 bool IgnoreResultAssign;
234 llvm::LLVMContext &VMContext;
238 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
239 VMContext(cgf.getLLVMContext()) {
246 bool TestAndClearIgnoreResultAssign() {
247 bool I = IgnoreResultAssign;
248 IgnoreResultAssign =
false;
254 LValue EmitCheckedLValue(
const Expr *
E, CodeGenFunction::TypeCheckKind TCK) {
258 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
259 const BinOpInfo &Info);
265 void EmitLValueAlignmentAssumption(
const Expr *
E,
Value *
V) {
266 const AlignValueAttr *AVAttr =
nullptr;
267 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E)) {
271 if (
const auto *TTy =
273 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
280 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
283 AVAttr = VD->
getAttr<AlignValueAttr>();
289 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
295 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
303 Value *
V = EmitLoadOfLValue(EmitCheckedLValue(
E, CodeGenFunction::TCK_Load),
306 EmitLValueAlignmentAssumption(
E,
V);
316 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
323 enum ImplicitConversionCheckKind :
unsigned char {
324 ICCK_IntegerTruncation = 0,
325 ICCK_UnsignedIntegerTruncation = 1,
326 ICCK_SignedIntegerTruncation = 2,
327 ICCK_IntegerSignChange = 3,
328 ICCK_SignedIntegerTruncationOrSignChange = 4,
344 struct ScalarConversionOpts {
345 bool TreatBooleanAsSigned;
346 bool EmitImplicitIntegerTruncationChecks;
347 bool EmitImplicitIntegerSignChangeChecks;
349 ScalarConversionOpts()
350 : TreatBooleanAsSigned(
false),
351 EmitImplicitIntegerTruncationChecks(
false),
352 EmitImplicitIntegerSignChangeChecks(
false) {}
355 : TreatBooleanAsSigned(
false),
356 EmitImplicitIntegerTruncationChecks(
358 EmitImplicitIntegerSignChangeChecks(
362 llvm::Type *SrcTy, llvm::Type *DstTy,
363 ScalarConversionOpts Opts);
367 ScalarConversionOpts Opts = ScalarConversionOpts());
376 Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
386 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
387 return Builder.CreateFCmpUNE(
V, Zero,
"tobool");
394 return Builder.CreateICmpNE(
V, Zero,
"tobool");
401 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
402 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
403 Value *Result = ZI->getOperand(0);
408 ZI->eraseFromParent();
413 return Builder.CreateIsNotNull(
V,
"tobool");
427 llvm_unreachable(
"Stmt can't have complex result type!");
445 return Visit(
E->getSubExpr());
451 return Visit(
E->getReplacement());
454 return Visit(
GE->getResultExpr());
463 return Visit(
E->getSubExpr());
468 return Builder.getInt(
E->getValue());
471 return Builder.getInt(
E->getValue());
474 return llvm::ConstantFP::get(VMContext,
E->getValue());
477 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
480 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
483 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
498 return Builder.CreateBitCast(
V, ConvertType(
E->
getType()));
502 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getPackLength());
525 return EmitLoadOfLValue(
E);
535 return EmitLoadOfLValue(
E);
538 if (
E->getMethodDecl() &&
539 E->getMethodDecl()->getReturnType()->isReferenceType())
540 return EmitLoadOfLValue(
E);
551 VersionTuple Version =
E->getVersion();
556 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
566 Value *VisitExtVectorElementExpr(
Expr *
E) {
return EmitLoadOfLValue(
E); }
573 return EmitLoadOfLValue(
E);
580 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
589 return VisitCastExpr(
E);
594 if (
E->getCallReturnType(CGF.
getContext())->isReferenceType())
595 return EmitLoadOfLValue(
E);
599 EmitLValueAlignmentAssumption(
E,
V);
607 LValue LV = EmitLValue(
E->getSubExpr());
608 return EmitScalarPrePostIncDec(
E, LV,
false,
false);
611 LValue LV = EmitLValue(
E->getSubExpr());
612 return EmitScalarPrePostIncDec(
E, LV,
true,
false);
615 LValue LV = EmitLValue(
E->getSubExpr());
616 return EmitScalarPrePostIncDec(
E, LV,
false,
true);
619 LValue LV = EmitLValue(
E->getSubExpr());
620 return EmitScalarPrePostIncDec(
E, LV,
true,
true);
623 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *
E,
628 bool isInc,
bool isPre);
632 if (isa<MemberPointerType>(
E->
getType()))
635 return EmitLValue(
E->getSubExpr()).getPointer(CGF);
639 return Visit(
E->getSubExpr());
640 return EmitLoadOfLValue(
E);
659 return Visit(
E->getSubExpr());
664 return EmitLoadOfLValue(
E);
675 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
679 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
696 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
700 return Builder.getInt1(
E->isSatisfied());
704 return Builder.getInt1(
E->isSatisfied());
708 return llvm::ConstantInt::get(Builder.getInt32Ty(),
E->getValue());
712 return llvm::ConstantInt::get(Builder.getInt1Ty(),
E->getValue());
735 return Builder.getInt1(
E->getValue());
739 Value *EmitMul(
const BinOpInfo &Ops) {
740 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
741 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
743 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
744 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
747 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
748 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
751 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
752 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
753 return EmitOverflowCheckedBinOp(Ops);
757 if (Ops.Ty->isConstantMatrixType()) {
758 llvm::MatrixBuilder MB(Builder);
761 auto *BO = cast<BinaryOperator>(Ops.E);
762 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
763 BO->getLHS()->getType().getCanonicalType());
764 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
765 BO->getRHS()->getType().getCanonicalType());
766 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
767 if (LHSMatTy && RHSMatTy)
768 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
769 LHSMatTy->getNumColumns(),
770 RHSMatTy->getNumColumns());
771 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
774 if (Ops.Ty->isUnsignedIntegerType() &&
775 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
776 !CanElideOverflowCheck(CGF.
getContext(), Ops))
777 return EmitOverflowCheckedBinOp(Ops);
779 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
781 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
782 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
784 if (Ops.isFixedPointOp())
785 return EmitFixedPointBinOp(Ops);
786 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
790 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
793 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
794 llvm::Value *Zero,
bool isDiv);
796 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
802 Value *EmitDiv(
const BinOpInfo &Ops);
803 Value *EmitRem(
const BinOpInfo &Ops);
804 Value *EmitAdd(
const BinOpInfo &Ops);
805 Value *EmitSub(
const BinOpInfo &Ops);
806 Value *EmitShl(
const BinOpInfo &Ops);
807 Value *EmitShr(
const BinOpInfo &Ops);
808 Value *EmitAnd(
const BinOpInfo &Ops) {
809 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
811 Value *EmitXor(
const BinOpInfo &Ops) {
812 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
814 Value *EmitOr (
const BinOpInfo &Ops) {
815 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
819 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
829 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
833 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
838 QualType ElementType = CT->getElementType();
845 unsigned NumElements = VT->getNumElements();
855#define HANDLEBINOP(OP) \
856 Value *VisitBin##OP(const BinaryOperator *E) { \
857 QualType promotionTy = getPromotionType(E->getType()); \
858 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
859 if (result && !promotionTy.isNull()) \
860 result = EmitUnPromotedValue(result, E->getType()); \
863 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
864 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
880 llvm::CmpInst::Predicate SICmpOpc,
881 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
882#define VISITCOMP(CODE, UI, SI, FP, SIG) \
883 Value *VisitBin##CODE(const BinaryOperator *E) { \
884 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
885 llvm::FCmpInst::FP, SIG); }
900 Value *VisitBinPtrMemD(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
901 Value *VisitBinPtrMemI(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
904 return Visit(
E->getSemanticForm());
927 return Visit(
E->getSelectedExpr());
939 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
942 return EmitFloatToBoolConversion(Src);
948 "Unknown scalar type to convert");
950 if (isa<llvm::IntegerType>(Src->
getType()))
951 return EmitIntToBoolConversion(Src);
953 assert(isa<llvm::PointerType>(Src->
getType()));
954 return EmitPointerToBoolConversion(Src, SrcType);
957void ScalarExprEmitter::EmitFloatConversionCheck(
960 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
961 if (!isa<llvm::IntegerType>(DstTy))
964 CodeGenFunction::SanitizerScope SanScope(&CGF);
968 llvm::Value *Check =
nullptr;
969 const llvm::fltSemantics &SrcSema =
979 APFloat MinSrc(SrcSema, APFloat::uninitialized);
980 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
984 MinSrc = APFloat::getInf(SrcSema,
true);
988 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
991 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
992 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
996 MaxSrc = APFloat::getInf(SrcSema,
false);
1000 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1005 const llvm::fltSemantics &
Sema =
1008 MinSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1009 MaxSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1013 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1015 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1016 Check = Builder.CreateAnd(GE, LE);
1021 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
1022 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
1027static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1028 std::pair<llvm::Value *, SanitizerMask>>
1031 llvm::Type *SrcTy = Src->
getType();
1032 llvm::Type *DstTy = Dst->
getType();
1037 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1038 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1039 "non-integer llvm type");
1046 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1048 if (!SrcSigned && !DstSigned) {
1049 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1050 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
1052 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1053 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
1056 llvm::Value *Check =
nullptr;
1058 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1060 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1062 return std::make_pair(Kind, std::make_pair(Check, Mask));
1070void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1082 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1083 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1085 if (SrcBits <= DstBits)
1088 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1095 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1096 (!SrcSigned && DstSigned))
1099 CodeGenFunction::SanitizerScope SanScope(&CGF);
1101 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1102 std::pair<llvm::Value *, SanitizerMask>>
1111 llvm::Constant *StaticArgs[] = {
1114 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1115 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1117 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1125 llvm::Type *VTy =
V->getType();
1128 return llvm::ConstantInt::getFalse(VTy->getContext());
1130 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1131 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V, Zero,
1132 llvm::Twine(Name) +
"." +
V->getName() +
1133 ".negativitycheck");
1138static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1139 std::pair<llvm::Value *, SanitizerMask>>
1142 llvm::Type *SrcTy = Src->
getType();
1143 llvm::Type *DstTy = Dst->
getType();
1145 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1146 "non-integer llvm type");
1152 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1153 unsigned DstBits = DstTy->getScalarSizeInBits();
1157 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1158 "either the widths should be different, or the signednesses.");
1161 llvm::Value *SrcIsNegative =
1164 llvm::Value *DstIsNegative =
1170 llvm::Value *Check =
nullptr;
1171 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1173 return std::make_pair(
1174 ScalarExprEmitter::ICCK_IntegerSignChange,
1175 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1178void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1181 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1184 llvm::Type *SrcTy = Src->
getType();
1185 llvm::Type *DstTy = Dst->
getType();
1195 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1196 unsigned DstBits = DstTy->getScalarSizeInBits();
1203 if (SrcSigned == DstSigned && SrcBits == DstBits)
1207 if (!SrcSigned && !DstSigned)
1212 if ((DstBits > SrcBits) && DstSigned)
1214 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1215 (SrcBits > DstBits) && SrcSigned) {
1223 CodeGenFunction::SanitizerScope SanScope(&CGF);
1225 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1226 std::pair<llvm::Value *, SanitizerMask>>
1230 ImplicitConversionCheckKind CheckKind;
1236 CheckKind = Check.first;
1237 Checks.emplace_back(Check.second);
1239 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1240 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1246 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1247 Checks.emplace_back(Check.second);
1251 llvm::Constant *StaticArgs[] = {
1254 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1255 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1257 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1263static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1264 std::pair<llvm::Value *, SanitizerMask>>
1270 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1271 if (!SrcSigned && !DstSigned)
1272 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1274 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1276 llvm::Value *Check =
nullptr;
1278 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1280 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1283 return std::make_pair(
1284 Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1289static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1290 std::pair<llvm::Value *, SanitizerMask>>
1294 llvm::Value *SrcIsNegative =
1297 llvm::Value *DstIsNegative =
1303 llvm::Value *Check =
nullptr;
1305 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1307 return std::make_pair(
1308 ScalarExprEmitter::ICCK_IntegerSignChange,
1309 std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1312void CodeGenFunction::EmitBitfieldConversionCheck(
Value *Src,
QualType SrcType,
1317 if (!
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion))
1330 assert(isa<llvm::IntegerType>(Src->
getType()) &&
1331 isa<llvm::IntegerType>(Dst->
getType()) &&
"non-integer llvm type");
1335 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1336 unsigned DstBits = Info.
Size;
1341 CodeGenFunction::SanitizerScope SanScope(
this);
1343 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1344 std::pair<llvm::Value *, SanitizerMask>>
1348 bool EmitTruncation = DstBits < SrcBits;
1352 bool EmitTruncationFromUnsignedToSigned =
1353 EmitTruncation && DstSigned && !SrcSigned;
1355 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1356 bool BothUnsigned = !SrcSigned && !DstSigned;
1357 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1364 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1369 else if (EmitSignChange) {
1370 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1371 "either the widths should be different, or the signednesses.");
1377 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1378 if (EmitTruncationFromUnsignedToSigned)
1379 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1381 llvm::Constant *StaticArgs[] = {
1384 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1385 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1387 EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1392 QualType DstType, llvm::Type *SrcTy,
1394 ScalarConversionOpts Opts) {
1396 llvm::Type *SrcElementTy;
1397 llvm::Type *DstElementTy;
1401 SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1402 DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1407 "cannot cast between matrix and non-matrix types");
1408 SrcElementTy = SrcTy;
1409 DstElementTy = DstTy;
1410 SrcElementType = SrcType;
1411 DstElementType = DstType;
1414 if (isa<llvm::IntegerType>(SrcElementTy)) {
1416 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1420 if (isa<llvm::IntegerType>(DstElementTy))
1421 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1423 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1424 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1427 if (isa<llvm::IntegerType>(DstElementTy)) {
1428 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1435 llvm::Intrinsic::ID IID =
1436 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1437 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1441 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1442 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1445 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1446 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1447 return Builder.CreateFPExt(Src, DstTy,
"conv");
1455 ScalarConversionOpts Opts) {
1470 return Builder.CreateIsNotNull(Src,
"tobool");
1473 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1476 "Unhandled scalar conversion from a fixed point type to another type.");
1480 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1483 "Unhandled scalar conversion to a fixed point type from another type.");
1486 QualType NoncanonicalSrcType = SrcType;
1487 QualType NoncanonicalDstType = DstType;
1491 if (SrcType == DstType)
return Src;
1495 llvm::Value *OrigSrc = Src;
1497 llvm::Type *SrcTy = Src->
getType();
1501 return EmitConversionToBool(Src, SrcType);
1503 llvm::Type *DstTy = ConvertType(DstType);
1508 if (DstTy->isFloatingPointTy()) {
1510 return Builder.CreateCall(
1518 Src = Builder.CreateCall(
1523 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1531 if (SrcTy == DstTy) {
1532 if (Opts.EmitImplicitIntegerSignChangeChecks)
1533 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1534 NoncanonicalDstType,
Loc);
1542 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1544 if (isa<llvm::PointerType>(SrcTy))
1547 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1552 llvm::Value* IntResult =
1553 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1555 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1558 if (isa<llvm::PointerType>(SrcTy)) {
1560 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1561 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1570 "Splatted expr doesn't match with vector element type?");
1573 unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
1574 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1578 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1580 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1582 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1583 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1584 if (SrcSize == DstSize)
1585 return Builder.CreateBitCast(Src, DstTy,
"conv");
1594 llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1595 llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1598 assert(((SrcElementTy->isIntegerTy() &&
1599 DstElementTy->isIntegerTy()) ||
1600 (SrcElementTy->isFloatingPointTy() &&
1601 DstElementTy->isFloatingPointTy())) &&
1602 "unexpected conversion between a floating-point vector and an "
1606 if (SrcElementTy->isIntegerTy())
1607 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1610 if (SrcSize > DstSize)
1611 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1614 return Builder.CreateFPExt(Src, DstTy,
"conv");
1618 Value *Res =
nullptr;
1619 llvm::Type *ResTy = DstTy;
1626 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1628 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1634 if (SrcTy->isFloatingPointTy()) {
1638 return Builder.CreateCall(
1641 return Builder.CreateFPTrunc(Src, DstTy);
1646 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1648 if (DstTy != ResTy) {
1650 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1651 Res = Builder.CreateCall(
1655 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1659 if (Opts.EmitImplicitIntegerTruncationChecks)
1660 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1661 NoncanonicalDstType,
Loc);
1663 if (Opts.EmitImplicitIntegerSignChangeChecks)
1664 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1665 NoncanonicalDstType,
Loc);
1673 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1676 Result = FPBuilder.CreateFloatingToFixed(Src,
1679 Result = FPBuilder.CreateFixedToFloating(Src,
1681 ConvertType(DstTy));
1687 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1688 DstFPSema.getWidth(),
1689 DstFPSema.isSigned());
1691 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1694 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1701Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1710 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1711 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy,
Loc);
1712 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1719 return EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1730void ScalarExprEmitter::EmitBinOpCheck(
1731 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1743 if (UO && UO->
getOpcode() == UO_Minus) {
1744 Check = SanitizerHandler::NegateOverflow;
1746 DynamicData.push_back(Info.RHS);
1750 Check = SanitizerHandler::ShiftOutOfBounds;
1752 StaticData.push_back(
1754 StaticData.push_back(
1756 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1758 Check = SanitizerHandler::DivremOverflow;
1763 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1764 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1765 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1766 default: llvm_unreachable(
"unexpected opcode for bin op check");
1770 DynamicData.push_back(Info.LHS);
1771 DynamicData.push_back(Info.RHS);
1774 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1781Value *ScalarExprEmitter::VisitExpr(
Expr *
E) {
1791 unsigned AddrSpace =
1793 llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1794 E->ComputeName(Context),
"__usn_str", AddrSpace);
1796 llvm::Type *ExprTy = ConvertType(
E->
getType());
1797 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1802 assert(
E->getDataElementCount() == 1);
1803 auto It =
E->begin();
1804 return Builder.getInt((*It)->getValue());
1809 if (
E->getNumSubExprs() == 2) {
1814 auto *LTy = cast<llvm::FixedVectorType>(LHS->
getType());
1815 unsigned LHSElts = LTy->getNumElements();
1819 auto *MTy = cast<llvm::FixedVectorType>(Mask->
getType());
1823 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1824 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1832 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1833 MTy->getNumElements());
1834 Value* NewV = llvm::PoisonValue::get(RTy);
1835 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1836 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1837 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1839 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1840 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1849 for (
unsigned i = 2; i <
E->getNumSubExprs(); ++i) {
1850 llvm::APSInt Idx =
E->getShuffleMaskIdx(CGF.
getContext(), i-2);
1852 if (Idx.isSigned() && Idx.isAllOnes())
1853 Indices.push_back(-1);
1855 Indices.push_back(Idx.getZExtValue());
1858 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1869 if (SrcType == DstType)
return Src;
1872 "ConvertVector source type must be a vector");
1874 "ConvertVector destination type must be a vector");
1876 llvm::Type *SrcTy = Src->
getType();
1877 llvm::Type *DstTy = ConvertType(DstType);
1886 assert(SrcTy->isVectorTy() &&
1887 "ConvertVector source IR type must be a vector");
1888 assert(DstTy->isVectorTy() &&
1889 "ConvertVector destination IR type must be a vector");
1891 llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1892 *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
1894 if (DstEltType->isBooleanType()) {
1895 assert((SrcEltTy->isFloatingPointTy() ||
1896 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1898 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
1899 if (SrcEltTy->isFloatingPointTy()) {
1900 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1902 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1907 Value *Res =
nullptr;
1909 if (isa<llvm::IntegerType>(SrcEltTy)) {
1911 if (isa<llvm::IntegerType>(DstEltTy))
1912 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1913 else if (InputSigned)
1914 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1916 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1917 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1918 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1919 if (DstEltType->isSignedIntegerOrEnumerationType())
1920 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1922 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1924 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1925 "Unknown real conversion");
1926 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1927 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1929 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1944 return Builder.getInt(
Value);
1948 llvm::Value *
Result = EmitLoadOfLValue(
E);
1954 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
1955 if (llvm::GetElementPtrInst *GEP =
1956 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
1957 if (llvm::Instruction *
Pointer =
1958 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
1971 TestAndClearIgnoreResultAssign();
1979 return EmitLoadOfLValue(
E);
1984 Value *Idx = Visit(
E->getIdx());
1987 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1990 return Builder.CreateExtractElement(
Base, Idx,
"vecext");
1994 TestAndClearIgnoreResultAssign();
1998 Value *RowIdx = Visit(
E->getRowIdx());
1999 Value *ColumnIdx = Visit(
E->getColumnIdx());
2003 llvm::MatrixBuilder MB(Builder);
2004 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2006 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2008 Value *Matrix = Visit(
E->getBase());
2011 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2016 int MV = SVI->getMaskValue(Idx);
2023 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2024 "Index operand too large for shufflevector mask!");
2025 return C->getZExtValue();
2029 bool Ignore = TestAndClearIgnoreResultAssign();
2031 assert (Ignore ==
false &&
"init list ignored");
2032 unsigned NumInitElements =
E->getNumInits();
2034 if (
E->hadArrayRangeDesignator())
2037 llvm::VectorType *VType =
2038 dyn_cast<llvm::VectorType>(ConvertType(
E->
getType()));
2041 if (NumInitElements == 0) {
2043 return EmitNullValue(
E->
getType());
2046 return Visit(
E->getInit(0));
2049 if (isa<llvm::ScalableVectorType>(VType)) {
2050 if (NumInitElements == 0) {
2052 return EmitNullValue(
E->
getType());
2055 if (NumInitElements == 1) {
2056 Expr *InitVector =
E->getInit(0);
2060 return Visit(InitVector);
2063 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2066 unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
2073 unsigned CurIdx = 0;
2074 bool VIsPoisonShuffle =
false;
2075 llvm::Value *
V = llvm::PoisonValue::get(VType);
2076 for (
unsigned i = 0; i != NumInitElements; ++i) {
2077 Expr *IE =
E->getInit(i);
2081 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2087 if (isa<ExtVectorElementExpr>(IE)) {
2088 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(
Init);
2090 if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
2091 ->getNumElements() == ResElts) {
2092 llvm::ConstantInt *
C = cast<llvm::ConstantInt>(EI->getIndexOperand());
2093 Value *LHS =
nullptr, *RHS =
nullptr;
2098 Args.resize(ResElts, -1);
2100 LHS = EI->getVectorOperand();
2102 VIsPoisonShuffle =
true;
2103 }
else if (VIsPoisonShuffle) {
2105 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
2106 for (
unsigned j = 0; j != CurIdx; ++j)
2108 Args.push_back(ResElts +
C->getZExtValue());
2109 Args.resize(ResElts, -1);
2111 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2112 RHS = EI->getVectorOperand();
2113 VIsPoisonShuffle =
false;
2115 if (!Args.empty()) {
2116 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2122 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2124 VIsPoisonShuffle =
false;
2129 unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
2134 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2135 if (isa<ExtVectorElementExpr>(IE)) {
2136 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(
Init);
2137 Value *SVOp = SVI->getOperand(0);
2138 auto *OpTy = cast<llvm::FixedVectorType>(SVOp->
getType());
2140 if (OpTy->getNumElements() == ResElts) {
2141 for (
unsigned j = 0; j != CurIdx; ++j) {
2144 if (VIsPoisonShuffle) {
2145 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(
V), j, 0));
2150 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2152 Args.resize(ResElts, -1);
2154 if (VIsPoisonShuffle)
2155 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2164 for (
unsigned j = 0; j != InitElts; ++j)
2166 Args.resize(ResElts, -1);
2167 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2170 for (
unsigned j = 0; j != CurIdx; ++j)
2172 for (
unsigned j = 0; j != InitElts; ++j)
2173 Args.push_back(j + Offset);
2174 Args.resize(ResElts, -1);
2181 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2182 VIsPoisonShuffle = isa<llvm::PoisonValue>(
Init);
2188 llvm::Type *EltTy = VType->getElementType();
2191 for (; CurIdx < ResElts; ++CurIdx) {
2192 Value *Idx = Builder.getInt32(CurIdx);
2193 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2194 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2202 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2212 if (ICE->isGLValue())
2226 CodeGenFunction::CGFPOptionsRAII
FPOptions(CGF, CE);
2230 bool Ignored = TestAndClearIgnoreResultAssign();
2236 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2237 case CK_BuiltinFnToFnPtr:
2238 llvm_unreachable(
"builtin functions are handled elsewhere");
2240 case CK_LValueBitCast:
2241 case CK_ObjCObjectLValueCast: {
2242 Address Addr = EmitLValue(
E).getAddress();
2245 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2248 case CK_LValueToRValueBitCast: {
2254 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2257 case CK_CPointerToObjCPointerCast:
2258 case CK_BlockPointerToObjCPointerCast:
2259 case CK_AnyPointerToBlockPointerCast:
2262 llvm::Type *SrcTy = Src->
getType();
2263 llvm::Type *DstTy = ConvertType(DestTy);
2265 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2266 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2267 "Address-space cast must be used to convert address spaces");
2269 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2272 PT->getPointeeType(),
2288 Src = Builder.CreateLaunderInvariantGroup(Src);
2296 Src = Builder.CreateStripInvariantGroup(Src);
2301 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2302 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2303 !isa<CastExpr>(
E)) {
2305 if (!PointeeType.
isNull())
2314 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2315 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2318 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2319 ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
2320 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2321 ScalableDstTy = llvm::ScalableVectorType::get(
2322 FixedSrcTy->getElementType(),
2323 ScalableDstTy->getElementCount().getKnownMinValue() / 8);
2325 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2326 llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy);
2327 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2328 llvm::Value *
Result = Builder.CreateInsertVector(
2329 ScalableDstTy, UndefVec, Src, Zero,
"cast.scalable");
2330 if (
Result->getType() != DstTy)
2340 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2341 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2344 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2345 ScalableSrcTy->getElementCount().isKnownMultipleOf(8) &&
2346 FixedDstTy->getElementType()->isIntegerTy(8)) {
2347 ScalableSrcTy = llvm::ScalableVectorType::get(
2348 FixedDstTy->getElementType(),
2349 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2350 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2352 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType()) {
2353 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2354 return Builder.CreateExtractVector(DstTy, Src, Zero,
"cast.fixed");
2365 if ((isa<llvm::FixedVectorType>(SrcTy) &&
2366 isa<llvm::ScalableVectorType>(DstTy)) ||
2367 (isa<llvm::ScalableVectorType>(SrcTy) &&
2368 isa<llvm::FixedVectorType>(DstTy))) {
2375 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2378 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2381 case CK_AddressSpaceConversion: {
2384 Result.Val.isNullPointer()) {
2388 if (
Result.HasSideEffects)
2391 ConvertType(DestTy)), DestTy);
2399 case CK_AtomicToNonAtomic:
2400 case CK_NonAtomicToAtomic:
2401 case CK_UserDefinedConversion:
2402 return Visit(
const_cast<Expr*
>(
E));
2406 : Visit(const_cast<
Expr *>(
E));
2409 case CK_BaseToDerived: {
2411 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2425 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2433 case CK_UncheckedDerivedToBase:
2434 case CK_DerivedToBase: {
2447 case CK_ArrayToPointerDecay:
2450 case CK_FunctionToPointerDecay:
2451 return EmitLValue(
E).getPointer(CGF);
2453 case CK_NullToPointer:
2454 if (MustVisitNullValue(
E))
2460 case CK_NullToMemberPointer: {
2461 if (MustVisitNullValue(
E))
2468 case CK_ReinterpretMemberPointer:
2469 case CK_BaseToDerivedMemberPointer:
2470 case CK_DerivedToBaseMemberPointer: {
2482 case CK_ARCProduceObject:
2484 case CK_ARCConsumeObject:
2486 case CK_ARCReclaimReturnedObject:
2488 case CK_ARCExtendBlockObject:
2491 case CK_CopyAndAutoreleaseBlockObject:
2494 case CK_FloatingRealToComplex:
2495 case CK_FloatingComplexCast:
2496 case CK_IntegralRealToComplex:
2497 case CK_IntegralComplexCast:
2498 case CK_IntegralComplexToFloatingComplex:
2499 case CK_FloatingComplexToIntegralComplex:
2500 case CK_ConstructorConversion:
2502 case CK_HLSLArrayRValue:
2503 llvm_unreachable(
"scalar cast to non-scalar value");
2505 case CK_LValueToRValue:
2507 assert(
E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2508 return Visit(
const_cast<Expr*
>(
E));
2510 case CK_IntegralToPointer: {
2515 auto DestLLVMTy = ConvertType(DestTy);
2518 llvm::Value* IntResult =
2519 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2521 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2527 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2533 case CK_PointerToIntegral: {
2534 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2535 auto *PtrExpr = Visit(
E);
2543 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2547 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2553 case CK_MatrixCast: {
2554 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2557 case CK_VectorSplat: {
2558 llvm::Type *DstTy = ConvertType(DestTy);
2561 llvm::ElementCount NumElements =
2562 cast<llvm::VectorType>(DstTy)->getElementCount();
2563 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2566 case CK_FixedPointCast:
2567 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2570 case CK_FixedPointToBoolean:
2572 "Expected src type to be fixed point type");
2573 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2574 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2577 case CK_FixedPointToIntegral:
2579 "Expected src type to be fixed point type");
2580 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2581 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2584 case CK_IntegralToFixedPoint:
2586 "Expected src type to be an integer");
2588 "Expected dest type to be fixed point type");
2589 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2592 case CK_IntegralCast: {
2595 return Builder.CreateIntCast(Visit(
E), ConvertType(DestTy),
2599 ScalarConversionOpts Opts;
2600 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2601 if (!ICE->isPartOfExplicitCast())
2602 Opts = ScalarConversionOpts(CGF.
SanOpts);
2604 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2607 case CK_IntegralToFloating: {
2612 return Builder.CreateSIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2613 return Builder.CreateUIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2615 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2616 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2619 case CK_FloatingToIntegral: {
2624 return Builder.CreateFPToSI(Visit(
E), ConvertType(DestTy),
"conv");
2625 return Builder.CreateFPToUI(Visit(
E), ConvertType(DestTy),
"conv");
2627 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2628 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2631 case CK_FloatingCast: {
2638 return Builder.CreateFPTrunc(Visit(
E), ConvertType(DestTy),
"conv");
2639 return Builder.CreateFPExt(Visit(
E), ConvertType(DestTy),
"conv");
2641 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2642 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2645 case CK_FixedPointToFloating:
2646 case CK_FloatingToFixedPoint: {
2647 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2648 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2651 case CK_BooleanToSignedIntegral: {
2652 ScalarConversionOpts Opts;
2653 Opts.TreatBooleanAsSigned =
true;
2654 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2657 case CK_IntegralToBoolean:
2658 return EmitIntToBoolConversion(Visit(
E));
2659 case CK_PointerToBoolean:
2660 return EmitPointerToBoolConversion(Visit(
E),
E->
getType());
2661 case CK_FloatingToBoolean: {
2662 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2663 return EmitFloatToBoolConversion(Visit(
E));
2665 case CK_MemberPointerToBoolean: {
2666 llvm::Value *MemPtr = Visit(
E);
2671 case CK_FloatingComplexToReal:
2672 case CK_IntegralComplexToReal:
2675 case CK_FloatingComplexToBoolean:
2676 case CK_IntegralComplexToBoolean: {
2680 return EmitComplexToScalarConversion(
V,
E->
getType(), DestTy,
2684 case CK_ZeroToOCLOpaqueType: {
2687 "CK_ZeroToOCLEvent cast on non-event type");
2688 return llvm::Constant::getNullValue(ConvertType(DestTy));
2691 case CK_IntToOCLSampler:
2694 case CK_HLSLVectorTruncation: {
2695 assert(DestTy->
isVectorType() &&
"Expected dest type to be vector type");
2699 for (
unsigned I = 0; I != NumElts; ++I)
2702 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2707 llvm_unreachable(
"unknown scalar cast");
2711 CodeGenFunction::StmtExprEvaluation eval(CGF);
2721 CodeGenFunction::RunCleanupsScope
Scope(CGF);
2722 Value *
V = Visit(
E->getSubExpr());
2725 Scope.ForceCleanup({&
V});
2734 llvm::Value *InVal,
bool IsInc,
2738 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2740 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2741 BinOp.FPFeatures = FPFeatures;
2746llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2748 llvm::Value *Amount =
2749 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2750 StringRef Name = IsInc ?
"inc" :
"dec";
2751 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2753 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2754 return Builder.CreateAdd(InVal, Amount, Name);
2757 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2758 return Builder.CreateNSWAdd(InVal, Amount, Name);
2761 if (!
E->canOverflow())
2762 return Builder.CreateNSWAdd(InVal, Amount, Name);
2766 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2771class OMPLastprivateConditionalUpdateRAII {
2780 ~OMPLastprivateConditionalUpdateRAII() {
2783 CGF,
E->getSubExpr());
2790 bool isInc,
bool isPre) {
2791 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF,
E);
2793 llvm::PHINode *atomicPHI =
nullptr;
2799 int amount = (isInc ? 1 : -1);
2800 bool isSubtraction = !isInc;
2803 type = atomicTy->getValueType();
2804 if (isInc &&
type->isBooleanType()) {
2808 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2809 return Builder.getTrue();
2813 return Builder.CreateAtomicRMW(
2815 llvm::AtomicOrdering::SequentiallyConsistent);
2820 if (!
type->isBooleanType() &&
type->isIntegerType() &&
2821 !(
type->isUnsignedIntegerType() &&
2822 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2825 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2826 llvm::AtomicRMWInst::Sub;
2827 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2828 llvm::Instruction::Sub;
2830 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
2832 Builder.CreateAtomicRMW(aop, LV.
getAddress(), amt,
2833 llvm::AtomicOrdering::SequentiallyConsistent);
2834 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2837 if (
type->isFloatingType()) {
2838 llvm::AtomicRMWInst::BinOp aop =
2839 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
2840 llvm::Instruction::BinaryOps op =
2841 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
2842 llvm::Value *amt = llvm::ConstantFP::get(
2843 VMContext, llvm::APFloat(
static_cast<float>(1.0)));
2845 Builder.CreateAtomicRMW(aop, LV.
getAddress(), amt,
2846 llvm::AtomicOrdering::SequentiallyConsistent);
2847 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2852 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2855 Builder.CreateBr(opBB);
2856 Builder.SetInsertPoint(opBB);
2857 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2858 atomicPHI->addIncoming(value, startBB);
2872 if (isInc &&
type->isBooleanType()) {
2873 value = Builder.getTrue();
2876 }
else if (
type->isIntegerType()) {
2878 bool canPerformLossyDemotionCheck =
false;
2881 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
2882 canPerformLossyDemotionCheck =
true;
2883 canPerformLossyDemotionCheck &=
2886 canPerformLossyDemotionCheck &=
2888 type, promotedType);
2889 assert((!canPerformLossyDemotionCheck ||
2890 type->isSignedIntegerOrEnumerationType() ||
2892 ConvertType(
type)->getScalarSizeInBits() ==
2893 ConvertType(promotedType)->getScalarSizeInBits()) &&
2894 "The following check expects that if we do promotion to different "
2895 "underlying canonical type, at least one of the types (either "
2896 "base or promoted) will be signed, or the bitwidths will match.");
2899 SanitizerKind::ImplicitIntegerArithmeticValueChange |
2900 SanitizerKind::ImplicitBitfieldConversion) &&
2901 canPerformLossyDemotionCheck) {
2915 value = EmitScalarConversion(value,
type, promotedType,
E->
getExprLoc());
2916 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2917 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2921 ScalarConversionOpts Opts;
2923 Opts = ScalarConversionOpts(CGF.
SanOpts);
2924 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
2926 SrcType = promotedType;
2929 value = EmitScalarConversion(value, promotedType,
type,
E->
getExprLoc(),
2935 }
else if (
E->canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
2936 value = EmitIncDecConsiderOverflowBehavior(
E, value, isInc);
2937 }
else if (
E->canOverflow() &&
type->isUnsignedIntegerType() &&
2938 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2942 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2943 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2954 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2957 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
2960 elemTy, value, numElts,
false, isSubtraction,
2964 }
else if (
type->isFunctionType()) {
2965 llvm::Value *amt = Builder.getInt32(amount);
2968 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
2972 false, isSubtraction,
2977 llvm::Value *amt = Builder.getInt32(amount);
2980 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
2983 elemTy, value, amt,
false, isSubtraction,
2988 }
else if (
type->isVectorType()) {
2989 if (
type->hasIntegerRepresentation()) {
2990 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2992 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2994 value = Builder.CreateFAdd(
2996 llvm::ConstantFP::get(value->getType(), amount),
2997 isInc ?
"inc" :
"dec");
3001 }
else if (
type->isRealFloatingType()) {
3004 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF,
E);
3009 value = Builder.CreateCall(
3012 input,
"incdec.conv");
3014 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3018 if (value->getType()->isFloatTy())
3019 amt = llvm::ConstantFP::get(VMContext,
3020 llvm::APFloat(
static_cast<float>(amount)));
3021 else if (value->getType()->isDoubleTy())
3022 amt = llvm::ConstantFP::get(VMContext,
3023 llvm::APFloat(
static_cast<double>(amount)));
3027 llvm::APFloat F(
static_cast<float>(amount));
3029 const llvm::fltSemantics *FS;
3032 if (value->getType()->isFP128Ty())
3034 else if (value->getType()->isHalfTy())
3036 else if (value->getType()->isBFloatTy())
3038 else if (value->getType()->isPPC_FP128Ty())
3042 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3043 amt = llvm::ConstantFP::get(VMContext, F);
3045 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3049 value = Builder.CreateCall(
3052 value,
"incdec.conv");
3054 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3059 }
else if (
type->isFixedPointType()) {
3066 Info.Opcode = isInc ? BO_Add : BO_Sub;
3068 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3071 if (
type->isSignedFixedPointType()) {
3072 Info.Opcode = isInc ? BO_Sub : BO_Add;
3073 Info.RHS = Builder.CreateNeg(Info.RHS);
3078 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3080 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3081 value = EmitFixedPointBinOp(Info);
3088 if (!isInc) size = -size;
3089 llvm::Value *sizeValue =
3090 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3093 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3096 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3098 value = Builder.CreateBitCast(value, input->getType());
3102 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3107 llvm::Value *
success = Pair.second;
3108 atomicPHI->addIncoming(old, curBlock);
3109 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3110 Builder.SetInsertPoint(contBB);
3111 return isPre ? value : input;
3125 return isPre ? value : input;
3132 ? getPromotionType(
E->getSubExpr()->
getType())
3134 Value *result = VisitPlus(
E, promotionTy);
3135 if (result && !promotionTy.
isNull())
3136 result = EmitUnPromotedValue(result,
E->
getType());
3143 TestAndClearIgnoreResultAssign();
3144 if (!PromotionType.
isNull())
3146 return Visit(
E->getSubExpr());
3152 ? getPromotionType(
E->getSubExpr()->
getType())
3154 Value *result = VisitMinus(
E, promotionTy);
3155 if (result && !promotionTy.
isNull())
3156 result = EmitUnPromotedValue(result,
E->
getType());
3162 TestAndClearIgnoreResultAssign();
3164 if (!PromotionType.
isNull())
3167 Op = Visit(
E->getSubExpr());
3170 if (Op->
getType()->isFPOrFPVectorTy())
3171 return Builder.CreateFNeg(Op,
"fneg");
3176 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3178 BinOp.Opcode = BO_Sub;
3181 return EmitSub(BinOp);
3185 TestAndClearIgnoreResultAssign();
3186 Value *Op = Visit(
E->getSubExpr());
3187 return Builder.CreateNot(Op,
"not");
3195 Value *Oper = Visit(
E->getSubExpr());
3198 if (Oper->
getType()->isFPOrFPVectorTy()) {
3199 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3201 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
3203 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
3204 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
3213 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3216 return Builder.CreateZExt(BoolVal, ConvertType(
E->
getType()),
"lnot.ext");
3224 return Builder.getInt(
Value);
3228 unsigned n =
E->getNumComponents();
3229 llvm::Type* ResultType = ConvertType(
E->
getType());
3230 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3232 for (
unsigned i = 0; i != n; ++i) {
3234 llvm::Value *Offset =
nullptr;
3241 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3248 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3252 Offset = Builder.CreateMul(Idx, ElemSize);
3266 Field != FieldEnd; ++Field, ++i) {
3267 if (*Field == MemberDecl)
3270 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3275 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3278 CurrentType = MemberDecl->
getType();
3283 llvm_unreachable(
"dependent __builtin_offsetof");
3299 auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
3301 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3313ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3315 QualType TypeToSize =
E->getTypeOfArgument();
3316 if (
auto Kind =
E->getKind();
3317 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3320 if (
E->isArgumentType()) {
3330 llvm::Value *size = VlaSize.
NumElts;
3334 if (!eltSize.
isOne())
3339 }
else if (
E->getKind() == UETT_OpenMPRequiredSimdAlign) {
3343 E->getTypeOfArgument()->getPointeeType()))
3345 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3346 }
else if (
E->getKind() == UETT_VectorElements) {
3347 auto *VecTy = cast<llvm::VectorType>(ConvertType(
E->getTypeOfArgument()));
3348 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3359 ? getPromotionType(
E->getSubExpr()->
getType())
3361 Value *result = VisitReal(
E, promotionTy);
3362 if (result && !promotionTy.
isNull())
3363 result = EmitUnPromotedValue(result,
E->
getType());
3369 Expr *Op =
E->getSubExpr();
3375 if (!PromotionType.
isNull()) {
3377 Op, IgnoreResultAssign,
true);
3380 return result.first;
3390 if (!PromotionType.
isNull())
3398 ? getPromotionType(
E->getSubExpr()->
getType())
3400 Value *result = VisitImag(
E, promotionTy);
3401 if (result && !promotionTy.
isNull())
3402 result = EmitUnPromotedValue(result,
E->
getType());
3408 Expr *Op =
E->getSubExpr();
3414 if (!PromotionType.
isNull()) {
3416 Op,
true, IgnoreResultAssign);
3419 return result.second;
3433 else if (!PromotionType.
isNull())
3437 if (!PromotionType.
isNull())
3438 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3439 return llvm::Constant::getNullValue(ConvertType(
E->
getType()));
3446Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3448 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3451Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3453 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3458 if (
auto BO = dyn_cast<BinaryOperator>(
E)) {
3460#define HANDLE_BINOP(OP) \
3462 return Emit##OP(EmitBinOps(BO, PromotionType));
3471 }
else if (
auto UO = dyn_cast<UnaryOperator>(
E)) {
3474 return VisitImag(UO, PromotionType);
3476 return VisitReal(UO, PromotionType);
3478 return VisitMinus(UO, PromotionType);
3480 return VisitPlus(UO, PromotionType);
3485 auto result = Visit(
const_cast<Expr *
>(
E));
3487 if (!PromotionType.
isNull())
3488 return EmitPromotedValue(result, PromotionType);
3490 return EmitUnPromotedValue(result,
E->
getType());
3497 TestAndClearIgnoreResultAssign();
3501 if (!PromotionType.
isNull())
3502 Result.Ty = PromotionType;
3505 Result.Opcode =
E->getOpcode();
3511LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3513 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3518 if (
E->getComputationResultType()->isAnyComplexType())
3525 PromotionTypeCR = getPromotionType(
E->getComputationResultType());
3526 if (PromotionTypeCR.
isNull())
3527 PromotionTypeCR =
E->getComputationResultType();
3528 QualType PromotionTypeLHS = getPromotionType(
E->getComputationLHSType());
3530 if (!PromotionTypeRHS.
isNull())
3533 OpInfo.RHS = Visit(
E->getRHS());
3534 OpInfo.Ty = PromotionTypeCR;
3535 OpInfo.Opcode =
E->getOpcode();
3541 llvm::PHINode *atomicPHI =
nullptr;
3544 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3545 !(
type->isUnsignedIntegerType() &&
3546 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3549 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3550 llvm::Instruction::BinaryOps Op;
3551 switch (OpInfo.Opcode) {
3553 case BO_MulAssign:
case BO_DivAssign:
3559 AtomicOp = llvm::AtomicRMWInst::Add;
3560 Op = llvm::Instruction::Add;
3563 AtomicOp = llvm::AtomicRMWInst::Sub;
3564 Op = llvm::Instruction::Sub;
3567 AtomicOp = llvm::AtomicRMWInst::And;
3568 Op = llvm::Instruction::And;
3571 AtomicOp = llvm::AtomicRMWInst::Xor;
3572 Op = llvm::Instruction::Xor;
3575 AtomicOp = llvm::AtomicRMWInst::Or;
3576 Op = llvm::Instruction::Or;
3579 llvm_unreachable(
"Invalid compound assignment type");
3581 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3583 EmitScalarConversion(OpInfo.RHS,
E->getRHS()->
getType(), LHSTy,
3586 Value *OldVal = Builder.CreateAtomicRMW(
3588 llvm::AtomicOrdering::SequentiallyConsistent);
3592 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3598 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3600 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3602 Builder.CreateBr(opBB);
3603 Builder.SetInsertPoint(opBB);
3604 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3605 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3606 OpInfo.LHS = atomicPHI;
3609 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3611 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3613 if (!PromotionTypeLHS.
isNull())
3614 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3617 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3618 E->getComputationLHSType(),
Loc);
3633 ScalarConversionOpts(CGF.
SanOpts));
3636 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3640 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3641 llvm::Value *
success = Pair.second;
3642 atomicPHI->addIncoming(old, curBlock);
3643 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3644 Builder.SetInsertPoint(contBB);
3669 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3670 bool Ignore = TestAndClearIgnoreResultAssign();
3671 Value *RHS =
nullptr;
3672 LValue LHS = EmitCompoundAssignLValue(
E,
Func, RHS);
3690void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3691 const BinOpInfo &Ops, llvm::Value *Zero,
bool isDiv) {
3694 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3695 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3696 SanitizerKind::IntegerDivideByZero));
3699 const auto *BO = cast<BinaryOperator>(Ops.E);
3700 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3701 Ops.Ty->hasSignedIntegerRepresentation() &&
3703 Ops.mayHaveIntegerOverflow()) {
3704 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
3706 llvm::Value *IntMin =
3707 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3708 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3710 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3711 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3712 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3714 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3717 if (Checks.size() > 0)
3718 EmitBinOpCheck(Checks, Ops);
3721Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3723 CodeGenFunction::SanitizerScope SanScope(&CGF);
3724 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3725 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3726 Ops.Ty->isIntegerType() &&
3727 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3728 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3729 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3730 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3731 Ops.Ty->isRealFloatingType() &&
3732 Ops.mayHaveFloatDivisionByZero()) {
3733 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3734 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3735 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3740 if (Ops.Ty->isConstantMatrixType()) {
3741 llvm::MatrixBuilder MB(Builder);
3744 auto *BO = cast<BinaryOperator>(Ops.E);
3748 "first operand must be a matrix");
3750 "second operand must be an arithmetic type");
3751 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3752 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3753 Ops.Ty->hasUnsignedIntegerRepresentation());
3756 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3758 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3759 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3763 else if (Ops.isFixedPointOp())
3764 return EmitFixedPointBinOp(Ops);
3765 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3766 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3768 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3771Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3773 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3774 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3775 Ops.Ty->isIntegerType() &&
3776 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3777 CodeGenFunction::SanitizerScope SanScope(&CGF);
3778 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3779 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3782 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3783 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3785 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3788Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3793 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3794 switch (Ops.Opcode) {
3798 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3799 llvm::Intrinsic::uadd_with_overflow;
3800 OverflowKind = SanitizerHandler::AddOverflow;
3805 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3806 llvm::Intrinsic::usub_with_overflow;
3807 OverflowKind = SanitizerHandler::SubOverflow;
3812 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3813 llvm::Intrinsic::umul_with_overflow;
3814 OverflowKind = SanitizerHandler::MulOverflow;
3817 llvm_unreachable(
"Unsupported operation for overflow detection");
3823 CodeGenFunction::SanitizerScope SanScope(&CGF);
3828 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3829 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3830 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3833 const std::string *handlerName =
3835 if (handlerName->empty()) {
3838 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3839 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3841 : SanitizerKind::UnsignedIntegerOverflow;
3842 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3844 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
3849 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3850 llvm::BasicBlock *continueBB =
3854 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3858 Builder.SetInsertPoint(overflowBB);
3861 llvm::Type *Int8Ty = CGF.
Int8Ty;
3862 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
3863 llvm::FunctionType *handlerTy =
3864 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3865 llvm::FunctionCallee handler =
3870 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
3871 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
3875 llvm::Value *handlerArgs[] = {
3878 Builder.getInt8(OpID),
3879 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3881 llvm::Value *handlerResult =
3885 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3886 Builder.CreateBr(continueBB);
3888 Builder.SetInsertPoint(continueBB);
3889 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3890 phi->addIncoming(result, initialBB);
3891 phi->addIncoming(handlerResult, overflowBB);
3898 const BinOpInfo &op,
3899 bool isSubtraction) {
3904 Value *pointer = op.LHS;
3905 Expr *pointerOperand =
expr->getLHS();
3906 Value *index = op.RHS;
3907 Expr *indexOperand =
expr->getRHS();
3910 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
3911 std::swap(pointer, index);
3912 std::swap(pointerOperand, indexOperand);
3917 unsigned width = cast<llvm::IntegerType>(index->
getType())->getBitWidth();
3919 auto PtrTy = cast<llvm::PointerType>(pointer->
getType());
3944 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3947 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3953 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3955 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3965 llvm::Value *objectSize
3968 index = CGF.
Builder.CreateMul(index, objectSize);
3987 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3990 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3992 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4011 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4022 bool negMul,
bool negAdd) {
4023 Value *MulOp0 = MulOp->getOperand(0);
4024 Value *MulOp1 = MulOp->getOperand(1);
4026 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4028 Addend = Builder.CreateFNeg(Addend,
"neg");
4030 Value *FMulAdd =
nullptr;
4031 if (Builder.getIsFPConstrained()) {
4032 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
4033 "Only constrained operation should be created when Builder is in FP "
4034 "constrained mode");
4035 FMulAdd = Builder.CreateConstrainedFPCall(
4036 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4038 {MulOp0, MulOp1, Addend});
4040 FMulAdd = Builder.CreateCall(
4042 {MulOp0, MulOp1, Addend});
4044 MulOp->eraseFromParent();
4059 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4060 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4061 "Only fadd/fsub can be the root of an fmuladd.");
4064 if (!op.FPFeatures.allowFPContractWithinStatement())
4067 Value *LHS = op.LHS;
4068 Value *RHS = op.RHS;
4072 bool NegLHS =
false;
4073 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4074 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4075 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4076 LHS = LHSUnOp->getOperand(0);
4081 bool NegRHS =
false;
4082 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4083 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4084 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4085 RHS = RHSUnOp->getOperand(0);
4093 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4094 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4095 (LHSBinOp->use_empty() || NegLHS)) {
4098 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4099 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4102 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4103 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4104 (RHSBinOp->use_empty() || NegRHS)) {
4107 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4108 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4112 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4113 if (LHSBinOp->getIntrinsicID() ==
4114 llvm::Intrinsic::experimental_constrained_fmul &&
4115 (LHSBinOp->use_empty() || NegLHS)) {
4118 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4119 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4122 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4123 if (RHSBinOp->getIntrinsicID() ==
4124 llvm::Intrinsic::experimental_constrained_fmul &&
4125 (RHSBinOp->use_empty() || NegRHS)) {
4128 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4129 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4136Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4137 if (op.LHS->getType()->isPointerTy() ||
4138 op.RHS->getType()->isPointerTy())
4141 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4142 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4144 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4145 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4148 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4149 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4152 if (CanElideOverflowCheck(CGF.
getContext(), op))
4153 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4154 return EmitOverflowCheckedBinOp(op);
4159 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4160 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4166 if (op.Ty->isConstantMatrixType()) {
4167 llvm::MatrixBuilder MB(Builder);
4168 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4169 return MB.CreateAdd(op.LHS, op.RHS);
4172 if (op.Ty->isUnsignedIntegerType() &&
4173 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4174 !CanElideOverflowCheck(CGF.
getContext(), op))
4175 return EmitOverflowCheckedBinOp(op);
4177 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4178 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4179 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4182 if (op.isFixedPointOp())
4183 return EmitFixedPointBinOp(op);
4185 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4190Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4192 using llvm::ConstantInt;
4200 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4201 RHSTy = BinOp->getRHS()->getType();
4202 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4207 LHSTy = CAO->getComputationLHSType();
4208 ResultTy = CAO->getComputationResultType();
4210 LHSTy = BinOp->getLHS()->getType();
4211 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4212 LHSTy = UnOp->getSubExpr()->getType();
4213 RHSTy = UnOp->getSubExpr()->getType();
4216 Value *LHS = op.LHS;
4217 Value *RHS = op.RHS;
4222 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4226 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4227 switch (op.Opcode) {
4230 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4234 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4238 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4242 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4246 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4250 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4253 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4255 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4257 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4259 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4264 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4266 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4270 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4283 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4289 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4294Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4296 if (!op.LHS->getType()->isPointerTy()) {
4297 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4298 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4300 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4301 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4304 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4305 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4308 if (CanElideOverflowCheck(CGF.
getContext(), op))
4309 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4310 return EmitOverflowCheckedBinOp(op);
4315 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4316 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4322 if (op.Ty->isConstantMatrixType()) {
4323 llvm::MatrixBuilder MB(Builder);
4324 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4325 return MB.CreateSub(op.LHS, op.RHS);
4328 if (op.Ty->isUnsignedIntegerType() &&
4329 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4330 !CanElideOverflowCheck(CGF.
getContext(), op))
4331 return EmitOverflowCheckedBinOp(op);
4333 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4334 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4335 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4338 if (op.isFixedPointOp())
4339 return EmitFixedPointBinOp(op);
4341 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4346 if (!op.RHS->getType()->isPointerTy())
4353 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4355 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4356 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4360 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4362 llvm::Value *divisor =
nullptr;
4368 elementType = VlaSize.Type;
4369 divisor = VlaSize.NumElts;
4373 if (!eltSize.
isOne())
4389 if (elementSize.
isOne())
4398 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4401Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4403 llvm::IntegerType *Ty;
4404 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4405 Ty = cast<llvm::IntegerType>(VT->getElementType());
4407 Ty = cast<llvm::IntegerType>(LHS->
getType());
4412 llvm::Type *RHSTy = RHS->
getType();
4413 llvm::APInt RHSMax =
4414 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4415 :
llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4416 if (RHSMax.ult(Ty->getBitWidth()))
4417 return llvm::ConstantInt::get(RHSTy, RHSMax);
4418 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4422 const Twine &Name) {
4423 llvm::IntegerType *Ty;
4424 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4425 Ty = cast<llvm::IntegerType>(VT->getElementType());
4427 Ty = cast<llvm::IntegerType>(LHS->
getType());
4429 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4430 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4432 return Builder.CreateURem(
4433 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4436Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4438 if (Ops.isFixedPointOp())
4439 return EmitFixedPointBinOp(Ops);
4443 Value *RHS = Ops.RHS;
4444 if (Ops.LHS->getType() != RHS->
getType())
4445 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4447 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4448 Ops.Ty->hasSignedIntegerRepresentation() &&
4451 bool SanitizeUnsignedBase =
4452 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4453 Ops.Ty->hasUnsignedIntegerRepresentation();
4454 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4455 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4458 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4459 else if ((SanitizeBase || SanitizeExponent) &&
4460 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4461 CodeGenFunction::SanitizerScope SanScope(&CGF);
4463 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4464 llvm::Value *WidthMinusOne =
4465 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4466 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4468 if (SanitizeExponent) {
4470 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
4477 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4480 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4481 llvm::Value *PromotedWidthMinusOne =
4482 (RHS == Ops.RHS) ? WidthMinusOne
4483 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4485 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4486 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4489 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4495 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4496 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4498 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4499 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4501 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4502 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4503 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4504 Checks.push_back(std::make_pair(
4505 BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4506 : SanitizerKind::UnsignedShiftBase));
4509 assert(!Checks.empty());
4510 EmitBinOpCheck(Checks, Ops);
4513 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4516Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4518 if (Ops.isFixedPointOp())
4519 return EmitFixedPointBinOp(Ops);
4523 Value *RHS = Ops.RHS;
4524 if (Ops.LHS->getType() != RHS->
getType())
4525 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4529 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4530 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4531 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4532 CodeGenFunction::SanitizerScope SanScope(&CGF);
4533 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4534 llvm::Value *Valid = Builder.CreateICmpULE(
4535 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4536 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
4539 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4540 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4541 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4549 default: llvm_unreachable(
"unexpected element type");
4550 case BuiltinType::Char_U:
4551 case BuiltinType::UChar:
4552 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4553 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4554 case BuiltinType::Char_S:
4555 case BuiltinType::SChar:
4556 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4557 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4558 case BuiltinType::UShort:
4559 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4560 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4561 case BuiltinType::Short:
4562 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4563 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4564 case BuiltinType::UInt:
4565 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4566 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4567 case BuiltinType::Int:
4568 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4569 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4570 case BuiltinType::ULong:
4571 case BuiltinType::ULongLong:
4572 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4573 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4574 case BuiltinType::Long:
4575 case BuiltinType::LongLong:
4576 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4577 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4578 case BuiltinType::Float:
4579 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4580 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4581 case BuiltinType::Double:
4582 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4583 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4584 case BuiltinType::UInt128:
4585 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4586 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4587 case BuiltinType::Int128:
4588 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4589 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4594 llvm::CmpInst::Predicate UICmpOpc,
4595 llvm::CmpInst::Predicate SICmpOpc,
4596 llvm::CmpInst::Predicate FCmpOpc,
4598 TestAndClearIgnoreResultAssign();
4603 assert(
E->getOpcode() == BO_EQ ||
4604 E->getOpcode() == BO_NE);
4608 CGF, LHS, RHS, MPT,
E->getOpcode() == BO_NE);
4610 BinOpInfo BOInfo = EmitBinOps(
E);
4611 Value *LHS = BOInfo.LHS;
4612 Value *RHS = BOInfo.RHS;
4618 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4620 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4623 Value *FirstVecArg = LHS,
4624 *SecondVecArg = RHS;
4629 switch(
E->getOpcode()) {
4630 default: llvm_unreachable(
"is not a comparison operation");
4642 std::swap(FirstVecArg, SecondVecArg);
4649 if (ElementKind == BuiltinType::Float) {
4651 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4652 std::swap(FirstVecArg, SecondVecArg);
4660 if (ElementKind == BuiltinType::Float) {
4662 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4667 std::swap(FirstVecArg, SecondVecArg);
4672 Value *CR6Param = Builder.getInt32(CR6);
4674 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4681 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
4682 if (ResultTy->getBitWidth() > 1 &&
4684 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
4689 if (BOInfo.isFixedPointOp()) {
4690 Result = EmitFixedPointBinOp(BOInfo);
4691 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
4692 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4694 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
4696 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
4698 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
4703 !isa<llvm::ConstantPointerNull>(LHS) &&
4704 !isa<llvm::ConstantPointerNull>(RHS)) {
4713 LHS = Builder.CreateStripInvariantGroup(LHS);
4715 RHS = Builder.CreateStripInvariantGroup(RHS);
4718 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
4724 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
4732 CETy = CTy->getElementType();
4734 LHS.first = Visit(
E->getLHS());
4735 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
4741 CTy->getElementType()) &&
4742 "The element types must always match.");
4745 RHS.first = Visit(
E->getRHS());
4746 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
4748 "The element types must always match.");
4751 Value *ResultR, *ResultI;
4755 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
4756 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
4760 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
4761 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
4764 if (
E->getOpcode() == BO_EQ) {
4765 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
4767 assert(
E->getOpcode() == BO_NE &&
4768 "Complex comparison other than == or != ?");
4769 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
4781 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E->getRHS())) {
4783 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
4784 *SrcType = ICE->getSubExpr()->getType();
4796 bool Ignore = TestAndClearIgnoreResultAssign();
4815 RHS = Visit(
E->getRHS());
4831 RHS = Visit(
E->getRHS());
4874 Value *LHS = Visit(
E->getLHS());
4875 Value *RHS = Visit(
E->getRHS());
4877 if (LHS->
getType()->isFPOrFPVectorTy()) {
4878 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4880 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4881 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4883 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4884 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4886 Value *
And = Builder.CreateAnd(LHS, RHS);
4887 return Builder.CreateSExt(
And, ConvertType(
E->
getType()),
"sext");
4891 llvm::Type *ResTy = ConvertType(
E->
getType());
4912 if (InstrumentRegions &&
4917 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4930 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
4935 return llvm::Constant::getNullValue(ResTy);
4947 CodeGenFunction::ConditionalEvaluation eval(CGF);
4956 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
4958 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4960 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
4969 RHSBlock = Builder.GetInsertBlock();
4974 if (InstrumentRegions &&
4978 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4982 PN->addIncoming(RHSCond, RHSBlockCnt);
4992 PN->addIncoming(RHSCond, RHSBlock);
5002 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5006 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5014 Value *LHS = Visit(
E->getLHS());
5015 Value *RHS = Visit(
E->getRHS());
5017 if (LHS->
getType()->isFPOrFPVectorTy()) {
5018 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5020 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
5021 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
5023 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
5024 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
5026 Value *
Or = Builder.CreateOr(LHS, RHS);
5027 return Builder.CreateSExt(
Or, ConvertType(
E->
getType()),
"sext");
5031 llvm::Type *ResTy = ConvertType(
E->
getType());
5052 if (InstrumentRegions &&
5057 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5070 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5075 return llvm::ConstantInt::get(ResTy, 1);
5087 CodeGenFunction::ConditionalEvaluation eval(CGF);
5097 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5099 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5101 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5113 RHSBlock = Builder.GetInsertBlock();
5118 if (InstrumentRegions &&
5122 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5126 PN->addIncoming(RHSCond, RHSBlockCnt);
5132 PN->addIncoming(RHSCond, RHSBlock);
5140 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5146 return Visit(
E->getRHS());
5171Value *ScalarExprEmitter::
5173 TestAndClearIgnoreResultAssign();
5176 CodeGenFunction::OpaqueValueMapping binding(CGF,
E);
5178 Expr *condExpr =
E->getCond();
5179 Expr *lhsExpr =
E->getTrueExpr();
5180 Expr *rhsExpr =
E->getFalseExpr();
5186 Expr *live = lhsExpr, *dead = rhsExpr;
5187 if (!CondExprBool) std::swap(live, dead);
5217 llvm::Value *LHS = Visit(lhsExpr);
5218 llvm::Value *RHS = Visit(rhsExpr);
5220 llvm::Type *condType = ConvertType(condExpr->
getType());
5221 auto *vecTy = cast<llvm::FixedVectorType>(condType);
5223 unsigned numElem = vecTy->getNumElements();
5224 llvm::Type *elemType = vecTy->getElementType();
5226 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5227 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5228 llvm::Value *tmp = Builder.CreateSExt(
5229 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5230 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5233 llvm::Value *RHSTmp = RHS;
5234 llvm::Value *LHSTmp = LHS;
5235 bool wasCast =
false;
5236 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
5237 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5238 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5239 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5243 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5244 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5245 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5247 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5257 llvm::Value *LHS = Visit(lhsExpr);
5258 llvm::Value *RHS = Visit(rhsExpr);
5260 llvm::Type *CondType = ConvertType(condExpr->
getType());
5261 auto *VecTy = cast<llvm::VectorType>(CondType);
5262 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5264 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5265 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5274 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5283 llvm::Value *LHS = Visit(lhsExpr);
5284 llvm::Value *RHS = Visit(rhsExpr);
5287 assert(!RHS &&
"LHS and RHS types must match");
5290 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5301 CodeGenFunction::ConditionalEvaluation eval(CGF);
5319 Value *LHS = Visit(lhsExpr);
5322 LHSBlock = Builder.GetInsertBlock();
5323 Builder.CreateBr(ContBlock);
5337 Value *RHS = Visit(rhsExpr);
5340 RHSBlock = Builder.GetInsertBlock();
5350 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5351 PN->addIncoming(LHS, LHSBlock);
5352 PN->addIncoming(RHS, RHSBlock);
5363 return Visit(
E->getChosenSubExpr());
5378Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5384 Value *Src,
unsigned NumElementsDst) {
5385 static constexpr int Mask[] = {0, 1, 2, -1};
5386 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5406 const llvm::DataLayout &DL,
5407 Value *Src, llvm::Type *DstTy,
5408 StringRef Name =
"") {
5412 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5413 return Builder.CreateBitCast(Src, DstTy, Name);
5416 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5417 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5420 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5422 if (!DstTy->isIntegerTy())
5423 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5425 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5429 if (!SrcTy->isIntegerTy())
5430 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5432 return Builder.CreateIntToPtr(Src, DstTy, Name);
5437 llvm::Type *DstTy = ConvertType(
E->
getType());
5439 llvm::Type *SrcTy = Src->
getType();
5440 unsigned NumElementsSrc =
5441 isa<llvm::VectorType>(SrcTy)
5442 ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5444 unsigned NumElementsDst =
5445 isa<llvm::VectorType>(DstTy)
5446 ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5455 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5460 Src->setName(
"astype");
5467 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5468 auto *Vec4Ty = llvm::FixedVectorType::get(
5469 cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5474 Src->setName(
"astype");
5479 Src, DstTy,
"astype");
5494 "Invalid scalar expression to emit");
5496 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5497 .Visit(
const_cast<Expr *
>(
E));
5506 "Invalid scalar expression to emit");
5507 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy,
Loc);
5517 "Invalid complex -> scalar conversion");
5518 return ScalarExprEmitter(*
this)
5519 .EmitComplexToScalarConversion(Src, SrcTy, DstTy,
Loc);
5526 if (!PromotionType.
isNull())
5527 return ScalarExprEmitter(*this).EmitPromoted(
E, PromotionType);
5529 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(
E));
5535 bool isInc,
bool isPre) {
5536 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(
E, LV, isInc, isPre);
5543 Expr *BaseExpr =
E->getBase();
5546 llvm::Type *BaseTy =
5561 ScalarExprEmitter
Scalar(*
this);
5563 switch (
E->getOpcode()) {
5564#define COMPOUND_OP(Op) \
5565 case BO_##Op##Assign: \
5566 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5603 llvm_unreachable(
"Not valid compound assignment operators");
5606 llvm_unreachable(
"Unhandled compound assignment operator");
5621 llvm::LLVMContext &VMContext,
5627 llvm::Value *TotalOffset =
nullptr;
5630 if (isa<llvm::Constant>(GEPVal)) {
5633 Value *BasePtr_int =
5634 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
5636 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
5637 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5638 return {TotalOffset, Builder.getFalse()};
5641 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5642 assert(GEP->getPointerOperand() == BasePtr &&
5643 "BasePtr must be the base of the GEP.");
5644 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
5646 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
5649 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5650 auto *SAddIntrinsic =
5651 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
5652 auto *SMulIntrinsic =
5653 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
5656 llvm::Value *OffsetOverflows = Builder.getFalse();
5660 llvm::Value *RHS) -> llvm::Value * {
5661 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
5664 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
5665 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
5667 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
5670 OffsetOverflows = Builder.getTrue();
5671 return llvm::ConstantInt::get(VMContext, N);
5676 auto *ResultAndOverflow = Builder.CreateCall(
5677 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
5678 OffsetOverflows = Builder.CreateOr(
5679 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
5680 return Builder.CreateExtractValue(ResultAndOverflow, 0);
5684 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
5685 GTI != GTE; ++GTI) {
5686 llvm::Value *LocalOffset;
5687 auto *Index = GTI.getOperand();
5689 if (
auto *STy = GTI.getStructTypeOrNull()) {
5692 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
5693 LocalOffset = llvm::ConstantInt::get(
5694 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
5699 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
5700 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
5701 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
5706 if (!TotalOffset || TotalOffset == Zero)
5707 TotalOffset = LocalOffset;
5709 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
5712 return {TotalOffset, OffsetOverflows};
5718 bool SignedIndices,
bool IsSubtraction,
5720 llvm::Type *PtrTy = Ptr->
getType();
5724 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5728 bool PerformNullCheck = !NullPointerIsDefined(
5729 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5732 bool PerformOverflowCheck =
5733 !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5735 if (!(PerformNullCheck || PerformOverflowCheck))
5740 SanitizerScope SanScope(
this);
5741 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
5746 assert((!isa<llvm::Constant>(EvaluatedGEP.
TotalOffset) ||
5748 "If the offset got constant-folded, we don't expect that there was an "
5751 auto *
Zero = llvm::ConstantInt::getNullValue(
IntPtrTy);
5765 if (PerformNullCheck) {
5777 auto *BaseIsNotNullptr =
Builder.CreateIsNotNull(Ptr);
5778 auto *ResultIsNotNullptr =
Builder.CreateIsNotNull(ComputedGEP);
5781 ?
Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5782 :
Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5783 Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5786 if (PerformOverflowCheck) {
5791 llvm::Value *ValidGEP;
5793 if (SignedIndices) {
5799 auto *PosOrZeroValid =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5800 auto *PosOrZeroOffset =
5802 llvm::Value *NegValid =
Builder.CreateICmpULT(ComputedGEP, IntPtr);
5804 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5810 ValidGEP =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5816 ValidGEP =
Builder.CreateICmpULE(ComputedGEP, IntPtr);
5818 ValidGEP =
Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5819 Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5822 assert(!Checks.empty() &&
"Should have produced some checks.");
5826 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5827 EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
5835 const Twine &Name) {
5836 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5842 elementType, Align);
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
CodeGenFunction::ComplexPairTy ComplexPairTy
#define VISITCOMP(CODE, UI, SI, FP, SIG)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static Value * emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, CodeGenFunction &CGF)
isCheapEnoughToEvaluateUnconditionally - Return true if the specified expression is cheap enough and ...
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
QualType getElementType() const
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
bool isShiftAssignOp() const
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
This class is used for builtin types like 'int'.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
A boolean literal, per ([C++ lex.bool] Boolean literals).
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a delete expression for memory deallocation and destructor calls, e.g.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Represents a C++ struct/union/class.
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Represents a 'co_await' expression.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
SanitizerSet SanOpts
Sanitizers enabled for this function.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
static bool hasScalarEvaluationKind(QualType T)
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
const TargetInfo & getTarget() const
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
CGDebugInfo * getDebugInfo()
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
llvm::Type * ConvertType(QualType T)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot())
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
RValue EmitAtomicExpr(AtomicExpr *E)
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
void setTBAAInfo(TBAAAccessInfo Info)
Address getAddress() const
const CGBitFieldInfo & getBitFieldInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
An abstract representation of an aligned address.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
CompoundLiteralExpr - [C99 6.5.2.5].
Represents the specialization of a concept - evaluates to a prvalue of type bool.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumRows() const
Returns the number of rows in the matrix.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents a 'co_yield' expression.
const Expr * getDefaultExpr() const
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
A reference to a declared variable, function, enum, etc.
Represents a reference to #emded data.
ExplicitCastExpr - An explicit cast written in the source code.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
bool isSignedOverflowDefined() const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Represents a matrix type, as defined in the Matrix Types clang extensions.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
A runtime availability query.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Represents a struct/union/class.
field_iterator field_end() const
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Scope - A scope is a transient data structure that is used while parsing the program.
Sema - This implements semantic analysis and AST building for C.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
RetTy Visit(PTR(Stmt) S, ParamTys... P)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a reference to a non-type template parameter that has been substituted with a template arg...
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a call to the builtin function __builtin_va_arg.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
VectorKind getVectorKind() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool LE(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
const FunctionProtoType * T
@ Generic
not a target-specific vector type
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.