29 #include "llvm/ADT/Optional.h" 30 #include "llvm/IR/CFG.h" 31 #include "llvm/IR/Constants.h" 32 #include "llvm/IR/DataLayout.h" 33 #include "llvm/IR/Function.h" 34 #include "llvm/IR/GetElementPtrTypeIterator.h" 35 #include "llvm/IR/GlobalVariable.h" 36 #include "llvm/IR/Intrinsics.h" 37 #include "llvm/IR/Module.h" 40 using namespace clang;
41 using namespace CodeGen;
55 bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
57 llvm::APInt &Result) {
60 const auto &LHSAP = LHS->getValue();
61 const auto &RHSAP = RHS->getValue();
62 if (Opcode == BO_Add) {
64 Result = LHSAP.sadd_ov(RHSAP, Overflow);
66 Result = LHSAP.uadd_ov(RHSAP, Overflow);
67 }
else if (Opcode == BO_Sub) {
69 Result = LHSAP.ssub_ov(RHSAP, Overflow);
71 Result = LHSAP.usub_ov(RHSAP, Overflow);
72 }
else if (Opcode == BO_Mul) {
74 Result = LHSAP.smul_ov(RHSAP, Overflow);
76 Result = LHSAP.umul_ov(RHSAP, Overflow);
77 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
78 if (Signed && !RHS->isZero())
79 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
95 bool mayHaveIntegerOverflow()
const {
97 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
98 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
103 return ::mayHaveIntegerOverflow(
108 bool isDivremOp()
const {
109 return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
110 Opcode == BO_RemAssign;
114 bool mayHaveIntegerDivisionByZero()
const {
116 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
122 bool mayHaveFloatDivisionByZero()
const {
124 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
125 return CFP->isZero();
130 static bool MustVisitNullValue(
const Expr *E) {
153 static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
154 return getUnwidenedIntegerType(Ctx, E).hasValue();
158 static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
159 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
160 "Expected a unary or binary operator");
164 if (!Op.mayHaveIntegerOverflow())
168 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
169 return !UO->canOverflow();
173 const auto *BO = cast<BinaryOperator>(Op.E);
174 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
178 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
187 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
193 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
194 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
199 static void updateFastMathFlags(llvm::FastMathFlags &FMF,
205 static Value *propagateFMFlags(
Value *V,
const BinOpInfo &Op) {
206 if (
auto *I = dyn_cast<llvm::Instruction>(V)) {
207 llvm::FastMathFlags FMF = I->getFastMathFlags();
208 updateFastMathFlags(FMF, Op.FPFeatures);
209 I->setFastMathFlags(FMF);
214 class ScalarExprEmitter
218 bool IgnoreResultAssign;
219 llvm::LLVMContext &VMContext;
223 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
224 VMContext(cgf.getLLVMContext()) {
231 bool TestAndClearIgnoreResultAssign() {
232 bool I = IgnoreResultAssign;
233 IgnoreResultAssign =
false;
243 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
244 const BinOpInfo &Info);
250 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *V) {
251 const AlignValueAttr *AVAttr =
nullptr;
252 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
256 if (
const auto *TTy =
258 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
265 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
268 AVAttr = VD->
getAttr<AlignValueAttr>();
273 if (
const auto *TTy =
274 dyn_cast<TypedefType>(E->
getType()))
275 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
281 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
283 AlignmentCI->getZExtValue());
293 EmitLValueAlignmentAssumption(E, V);
303 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
309 enum ImplicitConversionCheckKind :
unsigned char {
310 ICCK_IntegerTruncation = 0,
311 ICCK_UnsignedIntegerTruncation = 1,
312 ICCK_SignedIntegerTruncation = 2,
313 ICCK_IntegerSignChange = 3,
314 ICCK_SignedIntegerTruncationOrSignChange = 4,
330 struct ScalarConversionOpts {
331 bool TreatBooleanAsSigned;
332 bool EmitImplicitIntegerTruncationChecks;
333 bool EmitImplicitIntegerSignChangeChecks;
335 ScalarConversionOpts()
336 : TreatBooleanAsSigned(
false),
337 EmitImplicitIntegerTruncationChecks(
false),
338 EmitImplicitIntegerSignChangeChecks(
false) {}
341 : TreatBooleanAsSigned(
false),
342 EmitImplicitIntegerTruncationChecks(
343 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
344 EmitImplicitIntegerSignChangeChecks(
345 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)) {}
350 ScalarConversionOpts Opts = ScalarConversionOpts());
367 llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
368 return Builder.CreateFCmpUNE(V, Zero,
"tobool");
375 return Builder.CreateICmpNE(V, Zero,
"tobool");
382 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
383 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
384 Value *Result = ZI->getOperand(0);
389 ZI->eraseFromParent();
394 return Builder.CreateIsNotNull(V,
"tobool");
408 llvm_unreachable(
"Stmt can't have complex result type!");
436 return Builder.getInt(E->
getValue());
439 return Builder.getInt(E->
getValue());
442 return llvm::ConstantFP::get(VMContext, E->
getValue());
445 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
448 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
451 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
454 return EmitNullValue(E->
getType());
457 return EmitNullValue(E->
getType());
487 return EmitLoadOfLValue(E);
497 return EmitLoadOfLValue(E);
502 return EmitLoadOfLValue(E);
518 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
522 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Version.getMajor()),
523 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Min ? *Min : 0),
524 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, SMin ? *SMin : 0),
534 Value *VisitExtVectorElementExpr(
Expr *E) {
return EmitLoadOfLValue(E); }
536 return EmitLoadOfLValue(E);
543 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
548 return EmitNullValue(E->
getType());
552 return VisitCastExpr(E);
558 return EmitLoadOfLValue(E);
562 EmitLValueAlignmentAssumption(E, V);
571 return EmitScalarPrePostIncDec(E, LV,
false,
false);
575 return EmitScalarPrePostIncDec(E, LV,
true,
false);
579 return EmitScalarPrePostIncDec(E, LV,
false,
true);
583 return EmitScalarPrePostIncDec(E, LV,
true,
true);
591 bool isInc,
bool isPre);
595 if (isa<MemberPointerType>(E->
getType()))
598 return EmitLValue(E->
getSubExpr()).getPointer();
603 return EmitLoadOfLValue(E);
607 TestAndClearIgnoreResultAssign();
621 return EmitLoadOfLValue(E);
645 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
649 return llvm::ConstantInt::get(Builder.getInt32Ty(), E->
getValue());
653 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
667 return EmitNullValue(E->
getType());
676 return Builder.getInt1(E->
getValue());
680 Value *EmitMul(
const BinOpInfo &Ops) {
681 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
682 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
684 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
686 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
687 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
690 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
691 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
692 return EmitOverflowCheckedBinOp(Ops);
696 if (Ops.Ty->isUnsignedIntegerType() &&
697 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
698 !CanElideOverflowCheck(CGF.
getContext(), Ops))
699 return EmitOverflowCheckedBinOp(Ops);
701 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
702 Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
703 return propagateFMFlags(V, Ops);
705 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
709 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
712 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
716 Value *EmitDiv(
const BinOpInfo &Ops);
717 Value *EmitRem(
const BinOpInfo &Ops);
718 Value *EmitAdd(
const BinOpInfo &Ops);
719 Value *EmitSub(
const BinOpInfo &Ops);
720 Value *EmitShl(
const BinOpInfo &Ops);
721 Value *EmitShr(
const BinOpInfo &Ops);
722 Value *EmitAnd(
const BinOpInfo &Ops) {
723 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
725 Value *EmitXor(
const BinOpInfo &Ops) {
726 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
728 Value *EmitOr (
const BinOpInfo &Ops) {
729 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
734 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
738 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
741 #define HANDLEBINOP(OP) \ 742 Value *VisitBin ## OP(const BinaryOperator *E) { \ 743 return Emit ## OP(EmitBinOps(E)); \ 745 Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \ 746 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \ 762 llvm::CmpInst::Predicate SICmpOpc,
763 llvm::CmpInst::Predicate FCmpOpc);
764 #define VISITCOMP(CODE, UI, SI, FP) \ 765 Value *VisitBin##CODE(const BinaryOperator *E) { \ 766 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \ 767 llvm::FCmpInst::FP); } 769 VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT)
770 VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE)
771 VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE)
772 VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ)
773 VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE)
782 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
783 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
814 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
817 return EmitFloatToBoolConversion(Src);
822 assert((SrcType->
isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
823 "Unknown scalar type to convert");
825 if (isa<llvm::IntegerType>(Src->getType()))
826 return EmitIntToBoolConversion(Src);
828 assert(isa<llvm::PointerType>(Src->getType()));
829 return EmitPointerToBoolConversion(Src, SrcType);
832 void ScalarExprEmitter::EmitFloatConversionCheck(
842 if (llvm::IntegerType *IntTy = dyn_cast<llvm::IntegerType>(SrcTy)) {
848 APFloat LargestFloat =
850 APSInt LargestInt(IntTy->getBitWidth(), SrcIsUnsigned);
853 if (LargestFloat.convertToInteger(LargestInt, APFloat::rmTowardZero,
854 &IsExact) != APFloat::opOK)
859 llvm::Value *Max = llvm::ConstantInt::get(VMContext, LargestInt);
861 Check = Builder.CreateICmpULE(Src, Max);
863 llvm::Value *Min = llvm::ConstantInt::get(VMContext, -LargestInt);
866 Check = Builder.CreateAnd(GE, LE);
869 const llvm::fltSemantics &SrcSema =
871 if (isa<llvm::IntegerType>(DstTy)) {
878 APSInt Min = APSInt::getMinValue(Width, Unsigned);
879 APFloat MinSrc(SrcSema, APFloat::uninitialized);
880 if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
884 MinSrc = APFloat::getInf(SrcSema,
true);
888 MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
890 APSInt Max = APSInt::getMaxValue(Width, Unsigned);
891 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
892 if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
896 MaxSrc = APFloat::getInf(SrcSema,
false);
900 MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
905 const llvm::fltSemantics &
Sema =
908 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
909 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
913 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
915 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
916 Check = Builder.CreateAnd(GE, LE);
937 "should not check conversion from __half, it has the lowest rank");
939 const llvm::fltSemantics &DstSema =
941 APFloat MinBad = APFloat::getLargest(DstSema,
false);
942 APFloat MaxBad = APFloat::getInf(DstSema,
false);
945 MinBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
946 MaxBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
951 Builder.CreateFCmpOGT(AbsSrc, llvm::ConstantFP::get(VMContext, MinBad));
953 Builder.CreateFCmpOLT(AbsSrc, llvm::ConstantFP::get(VMContext, MaxBad));
954 Check = Builder.CreateNot(Builder.CreateAnd(GE, LE));
961 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
962 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
967 static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
968 std::pair<llvm::Value *, SanitizerMask>>
977 assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits());
978 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
979 "non-integer llvm type");
986 ScalarExprEmitter::ImplicitConversionCheckKind
Kind;
988 if (!SrcSigned && !DstSigned) {
989 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
990 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
992 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
993 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
998 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1000 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1002 return std::make_pair(Kind, std::make_pair(Check, Mask));
1005 void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1016 unsigned SrcBits = Src->getType()->getScalarSizeInBits();
1017 unsigned DstBits = Dst->getType()->getScalarSizeInBits();
1019 if (SrcBits <= DstBits)
1022 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1029 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1030 (!SrcSigned && DstSigned))
1035 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1036 std::pair<llvm::Value *, SanitizerMask>>
1045 llvm::Constant *StaticArgs[] = {
1048 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)};
1049 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1055 static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1056 std::pair<llvm::Value *, SanitizerMask>>
1062 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1063 "non-integer llvm type");
1069 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1070 unsigned DstBits = DstTy->getScalarSizeInBits();
1074 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1075 "either the widths should be different, or the signednesses.");
1078 auto EmitIsNegativeTest = [&Builder](
Value *V,
QualType VType,
1079 const char *Name) ->
Value * {
1081 bool VSigned = VType->isSignedIntegerOrEnumerationType();
1086 return llvm::ConstantInt::getFalse(VTy->getContext());
1089 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1092 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
1093 llvm::Twine(Name) +
"." + V->getName() +
1094 ".negativitycheck");
1098 llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType,
"src");
1100 llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType,
"dst");
1106 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1108 return std::make_pair(
1109 ScalarExprEmitter::ICCK_IntegerSignChange,
1110 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1113 void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1116 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1129 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1130 unsigned DstBits = DstTy->getScalarSizeInBits();
1137 if (SrcSigned == DstSigned && SrcBits == DstBits)
1141 if (!SrcSigned && !DstSigned)
1146 if ((DstBits > SrcBits) && DstSigned)
1148 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1149 (SrcBits > DstBits) && SrcSigned) {
1159 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1160 std::pair<llvm::Value *, SanitizerMask>>
1164 ImplicitConversionCheckKind CheckKind;
1170 CheckKind = Check.first;
1171 Checks.emplace_back(Check.second);
1173 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1174 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1180 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1181 Checks.emplace_back(Check.second);
1185 llvm::Constant *StaticArgs[] = {
1188 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)};
1190 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1199 ScalarConversionOpts Opts) {
1209 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1214 return Builder.CreateIsNotNull(Src,
"tobool");
1218 "Unhandled scalar conversion involving a fixed point type.");
1221 QualType NoncanonicalSrcType = SrcType;
1222 QualType NoncanonicalDstType = DstType;
1226 if (SrcType == DstType)
return Src;
1236 return EmitConversionToBool(Src, SrcType);
1243 if (DstTy->isFloatingPointTy()) {
1245 return Builder.CreateCall(
1253 Src = Builder.CreateCall(
1258 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1266 if (SrcTy == DstTy) {
1267 if (Opts.EmitImplicitIntegerSignChangeChecks)
1268 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1269 NoncanonicalDstType, Loc);
1277 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1279 if (isa<llvm::PointerType>(SrcTy))
1282 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1288 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1290 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1293 if (isa<llvm::PointerType>(SrcTy)) {
1295 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1296 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1305 "Splatted expr doesn't match with vector element type?");
1308 unsigned NumElements = DstTy->getVectorNumElements();
1309 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1312 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1314 unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
1315 unsigned DstSize = DstTy->getPrimitiveSizeInBits();
1316 if (SrcSize == DstSize)
1326 llvm::Type *SrcElementTy = SrcTy->getVectorElementType();
1327 llvm::Type *DstElementTy = DstTy->getVectorElementType();
1330 assert(((SrcElementTy->isIntegerTy() &&
1331 DstElementTy->isIntegerTy()) ||
1332 (SrcElementTy->isFloatingPointTy() &&
1333 DstElementTy->isFloatingPointTy())) &&
1334 "unexpected conversion between a floating-point vector and an " 1338 if (SrcElementTy->isIntegerTy())
1339 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1342 if (SrcSize > DstSize)
1343 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1346 return Builder.CreateFPExt(Src, DstTy,
"conv");
1350 Value *Res =
nullptr;
1355 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1357 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1363 if (SrcTy->isFloatingPointTy()) {
1367 return Builder.CreateCall(
1370 return Builder.CreateFPTrunc(Src, DstTy);
1375 if (isa<llvm::IntegerType>(SrcTy)) {
1377 if (SrcType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1380 if (isa<llvm::IntegerType>(DstTy))
1381 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1382 else if (InputSigned)
1383 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1385 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1386 }
else if (isa<llvm::IntegerType>(DstTy)) {
1387 assert(SrcTy->isFloatingPointTy() &&
"Unknown real conversion");
1389 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1391 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1393 assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() &&
1394 "Unknown real conversion");
1395 if (DstTy->getTypeID() < SrcTy->getTypeID())
1396 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1398 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1401 if (DstTy != ResTy) {
1403 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1404 Res = Builder.CreateCall(
1408 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1412 if (Opts.EmitImplicitIntegerTruncationChecks)
1413 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1414 NoncanonicalDstType, Loc);
1416 if (Opts.EmitImplicitIntegerSignChangeChecks)
1417 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1418 NoncanonicalDstType, Loc);
1427 using llvm::ConstantInt;
1437 unsigned SrcWidth = SrcFPSema.
getWidth();
1438 unsigned DstWidth = DstFPSema.
getWidth();
1439 unsigned SrcScale = SrcFPSema.getScale();
1440 unsigned DstScale = DstFPSema.
getScale();
1441 bool SrcIsSigned = SrcFPSema.isSigned();
1442 bool DstIsSigned = DstFPSema.
isSigned();
1444 llvm::Type *DstIntTy = Builder.getIntNTy(DstWidth);
1446 Value *Result = Src;
1447 unsigned ResultWidth = SrcWidth;
1451 if (DstScale < SrcScale)
1452 Result = SrcIsSigned ?
1453 Builder.CreateAShr(Result, SrcScale - DstScale,
"downscale") :
1454 Builder.CreateLShr(Result, SrcScale - DstScale,
"downscale");
1457 Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
1460 if (DstScale > SrcScale)
1461 Result = Builder.CreateShl(Result, DstScale - SrcScale,
"upscale");
1464 if (DstScale > SrcScale) {
1465 ResultWidth = SrcWidth + DstScale - SrcScale;
1466 llvm::Type *UpscaledTy = Builder.getIntNTy(ResultWidth);
1467 Result = Builder.CreateIntCast(Result, UpscaledTy, SrcIsSigned,
"resize");
1468 Result = Builder.CreateShl(Result, DstScale - SrcScale,
"upscale");
1469 }
else if (DstScale < SrcScale) {
1470 Result = SrcIsSigned ?
1471 Builder.CreateAShr(Result, SrcScale - DstScale,
"downscale") :
1472 Builder.CreateLShr(Result, SrcScale - DstScale,
"downscale");
1476 bool LessIntBits = DstFPSema.
getIntegralBits() < SrcFPSema.getIntegralBits();
1478 Value *Max = ConstantInt::get(
1481 Value *TooHigh = SrcIsSigned ? Builder.CreateICmpSGT(Result, Max)
1482 : Builder.CreateICmpUGT(Result, Max);
1483 Result = Builder.CreateSelect(TooHigh, Max, Result,
"satmax");
1487 if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {
1488 Value *Min = ConstantInt::get(
1491 Value *TooLow = Builder.CreateICmpSLT(Result, Min);
1492 Result = Builder.CreateSelect(TooLow, Min, Result,
"satmin");
1496 Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned,
"resize");
1503 Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1512 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1513 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1514 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1521 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1532 void ScalarExprEmitter::EmitBinOpCheck(
1533 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1545 if (UO && UO->
getOpcode() == UO_Minus) {
1546 Check = SanitizerHandler::NegateOverflow;
1548 DynamicData.push_back(Info.RHS);
1552 Check = SanitizerHandler::ShiftOutOfBounds;
1554 StaticData.push_back(
1556 StaticData.push_back(
1558 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1560 Check = SanitizerHandler::DivremOverflow;
1565 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1566 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1567 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1568 default: llvm_unreachable(
"unexpected opcode for bin op check");
1572 DynamicData.push_back(Info.LHS);
1573 DynamicData.push_back(Info.RHS);
1576 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1583 Value *ScalarExprEmitter::VisitExpr(
Expr *E) {
1597 llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType());
1598 unsigned LHSElts = LTy->getNumElements();
1602 llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType());
1606 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1607 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1615 llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(),
1616 MTy->getNumElements());
1617 Value* NewV = llvm::UndefValue::get(RTy);
1618 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1619 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1620 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1622 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1623 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1635 if (Idx.isSigned() && Idx.isAllOnesValue())
1636 indices.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
1638 indices.push_back(Builder.getInt32(Idx.getZExtValue()));
1641 Value *SV = llvm::ConstantVector::get(indices);
1642 return Builder.CreateShuffleVector(V1, V2, SV,
"shuffle");
1653 if (SrcType == DstType)
return Src;
1656 "ConvertVector source type must be a vector");
1658 "ConvertVector destination type must be a vector");
1670 assert(SrcTy->isVectorTy() &&
1671 "ConvertVector source IR type must be a vector");
1672 assert(DstTy->isVectorTy() &&
1673 "ConvertVector destination IR type must be a vector");
1675 llvm::Type *SrcEltTy = SrcTy->getVectorElementType(),
1676 *DstEltTy = DstTy->getVectorElementType();
1678 if (DstEltType->isBooleanType()) {
1679 assert((SrcEltTy->isFloatingPointTy() ||
1680 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1682 llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
1683 if (SrcEltTy->isFloatingPointTy()) {
1684 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1686 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1691 Value *Res =
nullptr;
1693 if (isa<llvm::IntegerType>(SrcEltTy)) {
1695 if (isa<llvm::IntegerType>(DstEltTy))
1696 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1697 else if (InputSigned)
1698 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1700 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1701 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1702 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1703 if (DstEltType->isSignedIntegerOrEnumerationType())
1704 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1706 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1708 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1709 "Unknown real conversion");
1710 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1711 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1713 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1728 return Builder.getInt(Value);
1732 return EmitLoadOfLValue(E);
1736 TestAndClearIgnoreResultAssign();
1743 return EmitLoadOfLValue(E);
1751 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1754 return Builder.CreateExtractElement(Base, Idx,
"vecext");
1757 static llvm::Constant *
getMaskElt(llvm::ShuffleVectorInst *SVI,
unsigned Idx,
1759 int MV = SVI->getMaskValue(Idx);
1761 return llvm::UndefValue::get(I32Ty);
1762 return llvm::ConstantInt::get(I32Ty, Off+MV);
1766 if (C->getBitWidth() != 32) {
1767 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
1768 C->getZExtValue()) &&
1769 "Index operand too large for shufflevector mask!");
1770 return llvm::ConstantInt::get(I32Ty, C->getZExtValue());
1776 bool Ignore = TestAndClearIgnoreResultAssign();
1778 assert (Ignore ==
false &&
"init list ignored");
1784 llvm::VectorType *VType =
1785 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
1788 if (NumInitElements == 0) {
1790 return EmitNullValue(E->
getType());
1796 unsigned ResElts = VType->getNumElements();
1803 unsigned CurIdx = 0;
1804 bool VIsUndefShuffle =
false;
1806 for (
unsigned i = 0; i != NumInitElements; ++i) {
1808 Value *Init = Visit(IE);
1811 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
1817 if (isa<ExtVectorElementExpr>(IE)) {
1818 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
1820 if (EI->getVectorOperandType()->getNumElements() == ResElts) {
1821 llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
1822 Value *LHS =
nullptr, *RHS =
nullptr;
1827 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1829 LHS = EI->getVectorOperand();
1831 VIsUndefShuffle =
true;
1832 }
else if (VIsUndefShuffle) {
1834 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
1835 for (
unsigned j = 0; j != CurIdx; ++j)
1837 Args.push_back(Builder.getInt32(ResElts + C->getZExtValue()));
1838 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1840 LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
1841 RHS = EI->getVectorOperand();
1842 VIsUndefShuffle =
false;
1844 if (!Args.empty()) {
1845 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1846 V = Builder.CreateShuffleVector(LHS, RHS, Mask);
1852 V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
1854 VIsUndefShuffle =
false;
1859 unsigned InitElts = VVT->getNumElements();
1864 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
1865 if (isa<ExtVectorElementExpr>(IE)) {
1866 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
1867 Value *SVOp = SVI->getOperand(0);
1868 llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType());
1870 if (OpTy->getNumElements() == ResElts) {
1871 for (
unsigned j = 0; j != CurIdx; ++j) {
1874 if (VIsUndefShuffle) {
1875 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0,
1878 Args.push_back(Builder.getInt32(j));
1881 for (
unsigned j = 0, je = InitElts; j != je; ++j)
1883 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1885 if (VIsUndefShuffle)
1886 V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
1895 for (
unsigned j = 0; j != InitElts; ++j)
1896 Args.push_back(Builder.getInt32(j));
1897 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1898 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1899 Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT),
1903 for (
unsigned j = 0; j != CurIdx; ++j)
1904 Args.push_back(Builder.getInt32(j));
1905 for (
unsigned j = 0; j != InitElts; ++j)
1906 Args.push_back(Builder.getInt32(j+Offset));
1907 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1914 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1915 V = Builder.CreateShuffleVector(V, Init, Mask,
"vecinit");
1916 VIsUndefShuffle = isa<llvm::UndefValue>(Init);
1925 for (; CurIdx < ResElts; ++CurIdx) {
1926 Value *Idx = Builder.getInt32(CurIdx);
1927 llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
1928 V = Builder.CreateInsertElement(V, Init, Idx,
"vecinit");
1936 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
1963 bool Ignored = TestAndClearIgnoreResultAssign();
1969 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
1970 case CK_BuiltinFnToFnPtr:
1971 llvm_unreachable(
"builtin functions are handled elsewhere");
1973 case CK_LValueBitCast:
1974 case CK_ObjCObjectLValueCast: {
1975 Address Addr = EmitLValue(E).getAddress();
1978 return EmitLoadOfLValue(LV, CE->
getExprLoc());
1981 case CK_CPointerToObjCPointerCast:
1982 case CK_BlockPointerToObjCPointerCast:
1983 case CK_AnyPointerToBlockPointerCast:
1985 Value *Src = Visit(const_cast<Expr*>(E));
1988 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
1989 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
1990 llvm_unreachable(
"wrong cast for pointers in different address spaces" 1991 "(must be an address space cast)!");
1994 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2008 Src = Builder.CreateLaunderInvariantGroup(Src);
2016 Src = Builder.CreateStripInvariantGroup(Src);
2022 case CK_AddressSpaceConversion: {
2032 ConvertType(DestTy)), DestTy);
2040 case CK_AtomicToNonAtomic:
2041 case CK_NonAtomicToAtomic:
2043 case CK_UserDefinedConversion:
2044 return Visit(const_cast<Expr*>(E));
2046 case CK_BaseToDerived: {
2048 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2062 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2070 case CK_UncheckedDerivedToBase:
2071 case CK_DerivedToBase: {
2083 case CK_ArrayToPointerDecay:
2085 case CK_FunctionToPointerDecay:
2086 return EmitLValue(E).getPointer();
2088 case CK_NullToPointer:
2089 if (MustVisitNullValue(E))
2095 case CK_NullToMemberPointer: {
2096 if (MustVisitNullValue(E))
2103 case CK_ReinterpretMemberPointer:
2104 case CK_BaseToDerivedMemberPointer:
2105 case CK_DerivedToBaseMemberPointer: {
2106 Value *Src = Visit(E);
2117 case CK_ARCProduceObject:
2119 case CK_ARCConsumeObject:
2121 case CK_ARCReclaimReturnedObject:
2123 case CK_ARCExtendBlockObject:
2126 case CK_CopyAndAutoreleaseBlockObject:
2129 case CK_FloatingRealToComplex:
2130 case CK_FloatingComplexCast:
2131 case CK_IntegralRealToComplex:
2132 case CK_IntegralComplexCast:
2133 case CK_IntegralComplexToFloatingComplex:
2134 case CK_FloatingComplexToIntegralComplex:
2135 case CK_ConstructorConversion:
2137 llvm_unreachable(
"scalar cast to non-scalar value");
2139 case CK_LValueToRValue:
2141 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2142 return Visit(const_cast<Expr*>(E));
2144 case CK_IntegralToPointer: {
2145 Value *Src = Visit(const_cast<Expr*>(E));
2149 auto DestLLVMTy = ConvertType(DestTy);
2153 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2155 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2161 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2165 case CK_PointerToIntegral: {
2166 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2167 auto *PtrExpr = Visit(E);
2175 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2178 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2184 case CK_VectorSplat: {
2186 Value *Elt = Visit(const_cast<Expr*>(E));
2188 unsigned NumElements = DstTy->getVectorNumElements();
2189 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2192 case CK_FixedPointCast:
2193 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2196 case CK_FixedPointToBoolean:
2198 "Expected src type to be fixed point type");
2199 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2200 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2203 case CK_IntegralCast: {
2204 ScalarConversionOpts Opts;
2205 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2206 if (!ICE->isPartOfExplicitCast())
2207 Opts = ScalarConversionOpts(CGF.
SanOpts);
2209 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2212 case CK_IntegralToFloating:
2213 case CK_FloatingToIntegral:
2214 case CK_FloatingCast:
2215 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2217 case CK_BooleanToSignedIntegral: {
2218 ScalarConversionOpts Opts;
2219 Opts.TreatBooleanAsSigned =
true;
2220 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2223 case CK_IntegralToBoolean:
2224 return EmitIntToBoolConversion(Visit(E));
2225 case CK_PointerToBoolean:
2226 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2227 case CK_FloatingToBoolean:
2228 return EmitFloatToBoolConversion(Visit(E));
2229 case CK_MemberPointerToBoolean: {
2235 case CK_FloatingComplexToReal:
2236 case CK_IntegralComplexToReal:
2239 case CK_FloatingComplexToBoolean:
2240 case CK_IntegralComplexToBoolean: {
2244 return EmitComplexToScalarConversion(V, E->
getType(), DestTy,
2248 case CK_ZeroToOCLOpaqueType: {
2251 "CK_ZeroToOCLEvent cast on non-event type");
2252 return llvm::Constant::getNullValue(ConvertType(DestTy));
2255 case CK_IntToOCLSampler:
2260 llvm_unreachable(
"unknown scalar cast");
2263 Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
2291 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2293 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2299 llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2302 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2303 StringRef Name = IsInc ?
"inc" :
"dec";
2304 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2306 return Builder.CreateAdd(InVal, Amount, Name);
2308 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2309 return Builder.CreateNSWAdd(InVal, Amount, Name);
2313 return Builder.CreateNSWAdd(InVal, Amount, Name);
2316 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2321 bool isInc,
bool isPre) {
2324 llvm::PHINode *atomicPHI =
nullptr;
2328 int amount = (isInc ? 1 : -1);
2329 bool isSubtraction = !isInc;
2332 type = atomicTy->getValueType();
2337 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2338 return Builder.getTrue();
2342 return Builder.CreateAtomicRMW(
2343 llvm::AtomicRMWInst::Xchg, LV.
getPointer(), True,
2344 llvm::AtomicOrdering::SequentiallyConsistent);
2351 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2354 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2355 llvm::AtomicRMWInst::Sub;
2356 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2357 llvm::Instruction::Sub;
2359 llvm::ConstantInt::get(ConvertType(type), 1,
true), type);
2361 LV.
getPointer(), amt, llvm::AtomicOrdering::SequentiallyConsistent);
2362 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2364 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2367 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2370 Builder.CreateBr(opBB);
2371 Builder.SetInsertPoint(opBB);
2372 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2373 atomicPHI->addIncoming(value, startBB);
2376 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2388 value = Builder.getTrue();
2395 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
2397 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2401 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2402 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2413 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2415 value = Builder.CreateGEP(value, numElts,
"vla.inc");
2418 value, numElts,
false, isSubtraction,
2427 value = Builder.CreateGEP(value, amt,
"incdec.funcptr");
2438 value = Builder.CreateGEP(value, amt,
"incdec.ptr");
2448 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2450 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2452 value = Builder.CreateFAdd(
2454 llvm::ConstantFP::get(value->getType(), amount),
2455 isInc ?
"inc" :
"dec");
2466 value = Builder.CreateCall(
2469 input,
"incdec.conv");
2471 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2475 if (value->getType()->isFloatTy())
2476 amt = llvm::ConstantFP::get(VMContext,
2477 llvm::APFloat(static_cast<float>(amount)));
2478 else if (value->getType()->isDoubleTy())
2479 amt = llvm::ConstantFP::get(VMContext,
2480 llvm::APFloat(static_cast<double>(amount)));
2483 llvm::APFloat F(static_cast<float>(amount));
2485 const llvm::fltSemantics *FS;
2488 if (value->getType()->isFP128Ty())
2490 else if (value->getType()->isHalfTy())
2494 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
2495 amt = llvm::ConstantFP::get(VMContext, F);
2497 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
2501 value = Builder.CreateCall(
2504 value,
"incdec.conv");
2506 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
2516 if (!isInc) size = -size;
2521 value = Builder.CreateGEP(value, sizeValue,
"incdec.objptr");
2524 false, isSubtraction,
2530 llvm::BasicBlock *opBB = Builder.GetInsertBlock();
2536 atomicPHI->addIncoming(old, opBB);
2537 Builder.CreateCondBr(success, contBB, opBB);
2538 Builder.SetInsertPoint(contBB);
2539 return isPre ? value : input;
2550 return isPre ? value : input;
2556 TestAndClearIgnoreResultAssign();
2561 if (BinOp.RHS->getType()->isFPOrFPVectorTy())
2562 BinOp.LHS = llvm::ConstantFP::getZeroValueForNegation(BinOp.RHS->getType());
2564 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
2566 BinOp.Opcode = BO_Sub;
2569 return EmitSub(BinOp);
2573 TestAndClearIgnoreResultAssign();
2575 return Builder.CreateNot(Op,
"neg");
2582 Value *Zero = llvm::Constant::getNullValue(Oper->getType());
2584 if (Oper->getType()->isFPOrFPVectorTy())
2585 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
2587 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
2588 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
2597 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
2600 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
2608 return Builder.getInt(Value);
2614 llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
2616 for (
unsigned i = 0; i != n; ++i) {
2625 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
2632 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
2636 Offset = Builder.CreateMul(Idx, ElemSize);
2650 Field != FieldEnd; ++Field, ++i) {
2651 if (*Field == MemberDecl)
2654 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
2659 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
2662 CurrentType = MemberDecl->
getType();
2667 llvm_unreachable(
"dependent __builtin_offsetof");
2685 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
2689 Result = Builder.CreateAdd(Result, Offset);
2697 ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
2717 if (!eltSize.
isOne())
2728 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
2773 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
2780 BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E) {
2781 TestAndClearIgnoreResultAssign();
2783 Result.LHS = Visit(E->
getLHS());
2784 Result.RHS = Visit(E->
getRHS());
2792 LValue ScalarExprEmitter::EmitCompoundAssignLValue(
2794 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &),
2804 OpInfo.RHS = Visit(E->
getRHS());
2812 llvm::PHINode *atomicPHI =
nullptr;
2817 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2820 llvm::AtomicRMWInst::BinOp aop = llvm::AtomicRMWInst::BAD_BINOP;
2821 switch (OpInfo.Opcode) {
2823 case BO_MulAssign:
case BO_DivAssign:
2829 aop = llvm::AtomicRMWInst::Add;
2832 aop = llvm::AtomicRMWInst::Sub;
2838 aop = llvm::AtomicRMWInst::Xor;
2841 aop = llvm::AtomicRMWInst::Or;
2844 llvm_unreachable(
"Invalid compound assignment type");
2846 if (aop != llvm::AtomicRMWInst::BAD_BINOP) {
2848 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
2851 Builder.CreateAtomicRMW(aop, LHSLV.
getPointer(), amt,
2852 llvm::AtomicOrdering::SequentiallyConsistent);
2858 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2860 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2862 Builder.CreateBr(opBB);
2863 Builder.SetInsertPoint(opBB);
2864 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
2865 atomicPHI->addIncoming(OpInfo.LHS, startBB);
2866 OpInfo.LHS = atomicPHI;
2869 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2876 Result = (this->*Func)(OpInfo);
2881 Loc, ScalarConversionOpts(CGF.
SanOpts));
2884 llvm::BasicBlock *opBB = Builder.GetInsertBlock();
2890 atomicPHI->addIncoming(old, opBB);
2891 Builder.CreateCondBr(success, contBB, opBB);
2892 Builder.SetInsertPoint(contBB);
2909 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &)) {
2910 bool Ignore = TestAndClearIgnoreResultAssign();
2912 LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
2927 return EmitLoadOfLValue(LHS, E->
getExprLoc());
2930 void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
2931 const BinOpInfo &Ops,
llvm::Value *Zero,
bool isDiv) {
2934 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
2935 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
2936 SanitizerKind::IntegerDivideByZero));
2939 const auto *BO = cast<BinaryOperator>(Ops.E);
2940 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
2941 Ops.Ty->hasSignedIntegerRepresentation() &&
2942 !IsWidenedIntegerOp(CGF.
getContext(), BO->getLHS()) &&
2943 Ops.mayHaveIntegerOverflow()) {
2944 llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
2947 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
2948 llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
2950 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
2951 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
2952 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
2954 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
2957 if (Checks.size() > 0)
2958 EmitBinOpCheck(Checks, Ops);
2961 Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
2964 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
2965 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
2966 Ops.Ty->isIntegerType() &&
2967 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
2968 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2969 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
2970 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
2971 Ops.Ty->isRealFloatingType() &&
2972 Ops.mayHaveFloatDivisionByZero()) {
2973 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2974 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
2975 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
2980 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
2981 llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
2990 if (ValTy->isFloatTy() ||
2991 (isa<llvm::VectorType>(ValTy) &&
2992 cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy()))
2997 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
2998 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3000 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3003 Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3005 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3006 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3007 Ops.Ty->isIntegerType() &&
3008 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3010 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3011 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3014 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3015 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3017 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3020 Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3024 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3025 switch (Ops.Opcode) {
3029 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3030 llvm::Intrinsic::uadd_with_overflow;
3035 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3036 llvm::Intrinsic::usub_with_overflow;
3041 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3042 llvm::Intrinsic::umul_with_overflow;
3045 llvm_unreachable(
"Unsupported operation for overflow detection");
3056 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3057 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3058 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3061 const std::string *handlerName =
3063 if (handlerName->empty()) {
3066 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3067 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3069 : SanitizerKind::UnsignedIntegerOverflow;
3070 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3077 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3078 llvm::BasicBlock *continueBB =
3082 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3086 Builder.SetInsertPoint(overflowBB);
3091 llvm::FunctionType *handlerTy =
3092 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3105 Builder.getInt8(OpID),
3106 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3112 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3113 Builder.CreateBr(continueBB);
3115 Builder.SetInsertPoint(continueBB);
3116 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3117 phi->addIncoming(result, initialBB);
3118 phi->addIncoming(handlerResult, overflowBB);
3125 const BinOpInfo &op,
3126 bool isSubtraction) {
3131 Value *pointer = op.LHS;
3133 Value *index = op.RHS;
3137 if (!isSubtraction && !pointer->getType()->isPointerTy()) {
3138 std::swap(pointer, index);
3139 std::swap(pointerOperand, indexOperand);
3144 unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
3146 auto PtrTy = cast<llvm::PointerType>(pointer->getType());
3169 return CGF.
Builder.CreateIntToPtr(index, pointer->getType());
3171 if (width != DL.getTypeSizeInBits(PtrTy)) {
3174 index = CGF.
Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned,
3180 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3182 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3195 index = CGF.
Builder.CreateMul(index, objectSize);
3198 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
3213 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3214 pointer = CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
3216 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3219 op.E->getExprLoc(),
"add.ptr");
3229 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
3234 return CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
3237 op.E->getExprLoc(),
"add.ptr");
3247 bool negMul,
bool negAdd) {
3248 assert(!(negMul && negAdd) &&
"Only one of negMul and negAdd should be set.");
3250 Value *MulOp0 = MulOp->getOperand(0);
3251 Value *MulOp1 = MulOp->getOperand(1);
3255 llvm::ConstantFP::getZeroValueForNegation(MulOp0->getType()), MulOp0,
3257 }
else if (negAdd) {
3260 llvm::ConstantFP::getZeroValueForNegation(Addend->getType()), Addend,
3264 Value *FMulAdd = Builder.CreateCall(
3266 {MulOp0, MulOp1, Addend});
3267 MulOp->eraseFromParent();
3282 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
3283 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
3284 "Only fadd/fsub can be the root of an fmuladd.");
3287 if (!op.FPFeatures.allowFPContractWithinStatement())
3293 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) {
3294 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3295 LHSBinOp->use_empty())
3296 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder,
false, isSub);
3298 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) {
3299 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3300 RHSBinOp->use_empty())
3301 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub,
false);
3307 Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
3308 if (op.LHS->getType()->isPointerTy() ||
3309 op.RHS->getType()->isPointerTy())
3312 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3313 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3315 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3317 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3318 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3321 if (CanElideOverflowCheck(CGF.
getContext(), op))
3322 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3323 return EmitOverflowCheckedBinOp(op);
3327 if (op.Ty->isUnsignedIntegerType() &&
3328 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3329 !CanElideOverflowCheck(CGF.
getContext(), op))
3330 return EmitOverflowCheckedBinOp(op);
3332 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3337 Value *V = Builder.CreateFAdd(op.LHS, op.RHS,
"add");
3338 return propagateFMFlags(V, op);
3341 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3344 Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
3346 if (!op.LHS->getType()->isPointerTy()) {
3347 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3348 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3350 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
3352 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3353 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
3356 if (CanElideOverflowCheck(CGF.
getContext(), op))
3357 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
3358 return EmitOverflowCheckedBinOp(op);
3362 if (op.Ty->isUnsignedIntegerType() &&
3363 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3364 !CanElideOverflowCheck(CGF.
getContext(), op))
3365 return EmitOverflowCheckedBinOp(op);
3367 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3371 Value *V = Builder.CreateFSub(op.LHS, op.RHS,
"sub");
3372 return propagateFMFlags(V, op);
3375 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
3380 if (!op.RHS->getType()->isPointerTy())
3387 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
3389 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
3390 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
3402 elementType = VlaSize.
Type;
3403 divisor = VlaSize.NumElts;
3407 if (!eltSize.
isOne())
3417 if (elementType->isVoidType() || elementType->isFunctionType())
3423 if (elementSize.
isOne())
3432 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
3435 Value *ScalarExprEmitter::GetWidthMinusOneValue(
Value* LHS,
Value* RHS) {
3436 llvm::IntegerType *Ty;
3437 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
3438 Ty = cast<llvm::IntegerType>(VT->getElementType());
3440 Ty = cast<llvm::IntegerType>(LHS->getType());
3441 return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
3444 Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
3447 Value *RHS = Ops.RHS;
3448 if (Ops.LHS->getType() != RHS->getType())
3449 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3451 bool SanitizeBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
3452 Ops.Ty->hasSignedIntegerRepresentation() &&
3454 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
3458 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shl.mask");
3459 else if ((SanitizeBase || SanitizeExponent) &&
3460 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3463 llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
3464 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
3466 if (SanitizeExponent) {
3468 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
3475 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
3478 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
3480 (RHS == Ops.RHS) ? WidthMinusOne
3481 : GetWidthMinusOneValue(Ops.LHS, RHS);
3484 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
3492 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
3493 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
3495 llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
3496 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
3498 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
3499 BaseCheck->addIncoming(Builder.getTrue(), Orig);
3500 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
3501 Checks.push_back(std::make_pair(BaseCheck, SanitizerKind::ShiftBase));
3504 assert(!Checks.empty());
3505 EmitBinOpCheck(Checks, Ops);
3508 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
3511 Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
3514 Value *RHS = Ops.RHS;
3515 if (Ops.LHS->getType() != RHS->getType())
3516 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3521 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shr.mask");
3522 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
3523 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3526 Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
3527 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
3530 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3531 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
3532 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
3540 default: llvm_unreachable(
"unexpected element type");
3541 case BuiltinType::Char_U:
3542 case BuiltinType::UChar:
3543 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3544 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
3545 case BuiltinType::Char_S:
3546 case BuiltinType::SChar:
3547 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3548 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
3549 case BuiltinType::UShort:
3550 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3551 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
3552 case BuiltinType::Short:
3553 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3554 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
3555 case BuiltinType::UInt:
3556 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3557 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
3558 case BuiltinType::Int:
3559 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3560 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
3561 case BuiltinType::ULong:
3562 case BuiltinType::ULongLong:
3563 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3564 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
3565 case BuiltinType::Long:
3566 case BuiltinType::LongLong:
3567 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3568 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
3569 case BuiltinType::Float:
3570 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
3571 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
3572 case BuiltinType::Double:
3573 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
3574 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
3579 llvm::CmpInst::Predicate UICmpOpc,
3580 llvm::CmpInst::Predicate SICmpOpc,
3581 llvm::CmpInst::Predicate FCmpOpc) {
3582 TestAndClearIgnoreResultAssign();
3592 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
3601 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
3606 Value *FirstVecArg = LHS,
3607 *SecondVecArg = RHS;
3614 default: llvm_unreachable(
"is not a comparison operation");
3626 std::swap(FirstVecArg, SecondVecArg);
3633 if (ElementKind == BuiltinType::Float) {
3635 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3636 std::swap(FirstVecArg, SecondVecArg);
3644 if (ElementKind == BuiltinType::Float) {
3646 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3651 std::swap(FirstVecArg, SecondVecArg);
3656 Value *CR6Param = Builder.getInt32(CR6);
3658 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
3665 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
3666 if (ResultTy->getBitWidth() > 1 &&
3668 Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
3673 if (LHS->getType()->isFPOrFPVectorTy()) {
3674 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
3676 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
3681 !isa<llvm::ConstantPointerNull>(LHS) &&
3682 !isa<llvm::ConstantPointerNull>(RHS)) {
3691 LHS = Builder.CreateStripInvariantGroup(LHS);
3693 RHS = Builder.CreateStripInvariantGroup(RHS);
3696 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
3702 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
3710 CETy = CTy->getElementType();
3712 LHS.first = Visit(E->
getLHS());
3713 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
3719 CTy->getElementType()) &&
3720 "The element types must always match.");
3723 RHS.first = Visit(E->
getRHS());
3724 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
3726 "The element types must always match.");
3729 Value *ResultR, *ResultI;
3731 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
3732 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
3736 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
3737 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
3741 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
3744 "Complex comparison other than == or != ?");
3745 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
3754 bool Ignore = TestAndClearIgnoreResultAssign();
3773 RHS = Visit(E->
getRHS());
3781 RHS = Visit(E->
getRHS());
3788 if (LHS.isBitField()) {
3809 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3819 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3820 if (LHS->getType()->isFPOrFPVectorTy()) {
3821 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
3822 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
3824 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
3825 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
3827 Value *
And = Builder.CreateAnd(LHS, RHS);
3828 return Builder.CreateSExt(And, ConvertType(E->
getType()),
"sext");
3842 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
3847 return llvm::Constant::getNullValue(ResTy);
3864 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
3866 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
3875 RHSBlock = Builder.GetInsertBlock();
3884 PN->addIncoming(RHSCond, RHSBlock);
3889 PN->setDebugLoc(Builder.getCurrentDebugLocation());
3893 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
3903 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3904 if (LHS->getType()->isFPOrFPVectorTy()) {
3905 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
3906 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
3908 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
3909 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
3911 Value *Or = Builder.CreateOr(LHS, RHS);
3912 return Builder.CreateSExt(Or, ConvertType(E->
getType()),
"sext");
3926 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
3931 return llvm::ConstantInt::get(ResTy, 1);
3949 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
3951 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
3963 RHSBlock = Builder.GetInsertBlock();
3968 PN->addIncoming(RHSCond, RHSBlock);
3971 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
3977 return Visit(E->
getRHS());
4002 Value *ScalarExprEmitter::
4004 TestAndClearIgnoreResultAssign();
4017 Expr *live = lhsExpr, *dead = rhsExpr;
4018 if (!CondExprBool) std::swap(live, dead);
4024 Value *Result = Visit(live);
4047 llvm::VectorType *vecTy = cast<llvm::VectorType>(condType);
4049 unsigned numElem = vecTy->getNumElements();
4050 llvm::Type *elemType = vecTy->getElementType();
4052 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
4053 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
4055 llvm::VectorType::get(elemType,
4063 bool wasCast =
false;
4064 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
4065 if (rhsVTy->getElementType()->isFloatingPointTy()) {
4071 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
4072 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
4073 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
4094 assert(!RHS &&
"LHS and RHS types must match");
4097 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
4111 Value *LHS = Visit(lhsExpr);
4114 LHSBlock = Builder.GetInsertBlock();
4115 Builder.CreateBr(ContBlock);
4119 Value *RHS = Visit(rhsExpr);
4122 RHSBlock = Builder.GetInsertBlock();
4132 llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2,
"cond");
4133 PN->addIncoming(LHS, LHSBlock);
4134 PN->addIncoming(RHS, RHSBlock);
4156 return llvm::UndefValue::get(ArgTy);
4163 if (ArgTy != Val->getType()) {
4164 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
4165 Val = Builder.CreateIntToPtr(Val, ArgTy);
4167 Val = Builder.CreateTrunc(Val, ArgTy);
4173 Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
4179 Value *Src,
unsigned NumElementsDst) {
4180 llvm::Value *UnV = llvm::UndefValue::get(Src->getType());
4182 Args.push_back(Builder.getInt32(0));
4183 Args.push_back(Builder.getInt32(1));
4184 Args.push_back(Builder.getInt32(2));
4185 if (NumElementsDst == 4)
4186 Args.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
4187 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
4188 return Builder.CreateShuffleVector(Src, UnV, Mask);
4208 const llvm::DataLayout &DL,
4210 StringRef Name =
"") {
4211 auto SrcTy = Src->getType();
4214 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
4218 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
4222 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
4224 if (!DstTy->isIntegerTy())
4225 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
4227 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
4231 if (!SrcTy->isIntegerTy())
4234 return Builder.CreateIntToPtr(Src, DstTy, Name);
4242 unsigned NumElementsSrc = isa<llvm::VectorType>(SrcTy) ?
4243 cast<llvm::VectorType>(SrcTy)->getNumElements() : 0;
4244 unsigned NumElementsDst = isa<llvm::VectorType>(DstTy) ?
4245 cast<llvm::VectorType>(DstTy)->getNumElements() : 0;
4249 if (NumElementsSrc == 3 && NumElementsDst != 3) {
4257 Src->setName(
"astype");
4264 if (NumElementsSrc != 3 && NumElementsDst == 3) {
4266 auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4);
4272 Src->setName(
"astype");
4277 Src, DstTy,
"astype");
4291 assert(E && hasScalarEvaluationKind(E->
getType()) &&
4292 "Invalid scalar expression to emit");
4294 return ScalarExprEmitter(*
this, IgnoreResultAssign)
4295 .Visit(const_cast<Expr *>(E));
4303 assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
4304 "Invalid scalar expression to emit");
4305 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
4315 "Invalid complex -> scalar conversion");
4316 return ScalarExprEmitter(*
this)
4317 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
4323 bool isInc,
bool isPre) {
4324 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
4334 Addr =
Address(EmitScalarExpr(BaseExpr), getPointerAlign());
4336 Addr = EmitLValue(BaseExpr).getAddress();
4341 return MakeAddrLValue(Addr, E->
getType());
4347 ScalarExprEmitter Scalar(*
this);
4348 Value *Result =
nullptr;
4350 #define COMPOUND_OP(Op) \ 4351 case BO_##Op##Assign: \ 4352 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \ 4389 llvm_unreachable(
"Not valid compound assignment operators");
4392 llvm_unreachable(
"Unhandled compound assignment operator");
4400 const Twine &Name) {
4401 Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name);
4404 if (!SanOpts.has(SanitizerKind::PointerOverflow))
4408 if (isa<llvm::Constant>(GEPVal))
4412 if (GEPVal->getType()->getPointerAddressSpace())
4415 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
4416 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
4419 auto &VMContext = getLLVMContext();
4420 const auto &DL = CGM.getDataLayout();
4421 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
4424 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
4425 auto *SAddIntrinsic =
4426 CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
4427 auto *SMulIntrinsic =
4428 CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
4433 llvm::Value *OffsetOverflows = Builder.getFalse();
4438 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
4441 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
4442 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
4444 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
4447 OffsetOverflows = Builder.getTrue();
4448 return llvm::ConstantInt::get(VMContext, N);
4453 auto *ResultAndOverflow = Builder.CreateCall(
4454 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
4455 OffsetOverflows = Builder.CreateOr(
4456 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
4457 return Builder.CreateExtractValue(ResultAndOverflow, 0);
4461 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
4462 GTI != GTE; ++GTI) {
4464 auto *Index = GTI.getOperand();
4466 if (
auto *STy = GTI.getStructTypeOrNull()) {
4469 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
4470 LocalOffset = llvm::ConstantInt::get(
4471 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
4475 auto *ElementSize = llvm::ConstantInt::get(
4476 IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
4477 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
4478 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
4483 if (!TotalOffset || TotalOffset == Zero)
4484 TotalOffset = LocalOffset;
4486 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
4490 if (TotalOffset == Zero)
4495 auto *IntPtr = Builder.CreatePtrToInt(GEP->getPointerOperand(), IntPtrTy);
4496 auto *ComputedGEP = Builder.CreateAdd(IntPtr, TotalOffset);
4503 auto *NoOffsetOverflow = Builder.CreateNot(OffsetOverflows);
4504 if (SignedIndices) {
4505 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4506 auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero);
4507 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
4508 ValidGEP = Builder.CreateAnd(
4509 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid),
4511 }
else if (!SignedIndices && !IsSubtraction) {
4512 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4513 ValidGEP = Builder.CreateAnd(PosOrZeroValid, NoOffsetOverflow);
4515 auto *NegOrZeroValid = Builder.CreateICmpULE(ComputedGEP, IntPtr);
4516 ValidGEP = Builder.CreateAnd(NegOrZeroValid, NoOffsetOverflow);
4519 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
4521 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4522 EmitCheck(std::make_pair(ValidGEP, SanitizerKind::PointerOverflow),
4523 SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
const llvm::DataLayout & getDataLayout() const
const Expr * getSubExpr() const
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Defines the clang::ASTContext interface.
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())
Emit a compare-and-exchange op for atomic type.
The null pointer literal (C++11 [lex.nullptr])
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
static APFixedPoint getMax(const FixedPointSemantics &Sema)
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
void end(CodeGenFunction &CGF)
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc)
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled...
bool isSignedOverflowDefined() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
uint64_t getValue() const
CodeGenTypes & getTypes()
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
static Opcode getOpForCompoundAssignment(Opcode Opc)
const CodeGenOptions & getCodeGenOpts() const
SourceLocation getExprLoc() const
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler...
void enterFullExpression(const FullExpr *E)
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
llvm::APSInt getValue() const
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
CompoundStmt * getSubStmt()
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const Expr * getInit(unsigned Init) const
static llvm::Constant * getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
Stmt - This represents one statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
bool isRealFloatingType() const
Floating point categories.
The fixed point semantics work similarly to llvm::fltSemantics.
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr)
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::APFloat getValue() const
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, QualType Type, CharUnits Alignment=CharUnits::Zero(), SanitizerSet SkippedChecks=SanitizerSet())
Emit a check that V is the address of storage of the appropriate size and alignment for an object of ...
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
bool isExtVectorType() const
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
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 call a handler function in a sanitizer runtime with the provided argum...
ParenExpr - This represents a parethesized expression, e.g.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Expr * getFalseExpr() const
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
FPOptions getFPFeatures() const
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent...
const TargetInfo & getTargetInfo() const
Floating point control options.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
const Expr * getResultExpr() const
The generic selection's result expression.
static Value * buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant, or if it does but contains a label, return false.
QualType getElementType() const
Expr * getIndexExpr(unsigned Idx)
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
CompoundLiteralExpr - [C99 6.5.2.5].
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>'.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
const llvm::fltSemantics & getHalfFormat() const
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::Value * getPointer() const
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
A C++ throw-expression (C++ [except.throw]).
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
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.
Represents a struct/union/class.
const TargetInfo & getTarget() const
An object to manage conditionally-evaluated expressions.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
FieldDecl * getField() const
For a field offsetof node, returns the field.
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Address getAddress() const
QualType getComputationResultType() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
llvm::IntegerType * Int64Ty
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVolatileQualified() const
Represents a member of a struct/union/class.
llvm::IntegerType * SizeTy
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
unsigned getIntegralBits() const
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
bool isReferenceType() const
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method...
bool hadArrayRangeDesignator() const
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
Describes an C or C++ initializer list.
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
static APFixedPoint getMin(const FixedPointSemantics &Sema)
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
APValue Val
Val - This is the value the expression can be folded to.
bool isOne() const
isOne - Test whether the quantity equals one.
path_iterator path_begin()
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::PointerType * VoidPtrTy
A builtin binary operation expression such as "x + y" or "x <= y".
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
ObjCStringLiteral, used for Objective-C string literals i.e.
static llvm::Constant * getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off, llvm::Type *I32Ty)
Scope - A scope is a transient data structure that is used while parsing the program.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
unsigned getScale() const
field_iterator field_begin() const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a best-effort attempt to peephole expressions that naturally produce retained objects.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Helper class for OffsetOfExpr.
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
RValue EmitAtomicExpr(AtomicExpr *E)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
QualType getReturnType() const
A default argument (C++ [dcl.fct.default]).
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void begin(CodeGenFunction &CGF)
Checking the operand of a load. Must be suitably sized and aligned.
This object can be modified without requiring retains or releases.
Represents the this expression in C++.
virtual llvm::Value * performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, llvm::Value *V, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Perform address space cast of an expression of pointer type.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, Expr *LHS, Expr *RHS)
const Expr * getExpr() const
Get the initialization expression that will be used.
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...
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
VersionTuple getVersion()
Sema - This implements semantic analysis and AST building for C.
bool isPromotableIntegerType() const
More type predicates useful for type checking/promotion.
static CharUnits One()
One - Construct a CharUnits quantity of one.
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ASTContext & getContext() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
const TargetCodeGenInfo & getTargetCodeGenInfo()
QualType getComputationLHSType() const
CastKind
CastKind - The kind of operation required for a conversion.
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ConstantExpr - An expression that occurs in a constant context.
Represents a call to the builtin function __builtin_va_arg.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
const llvm::fltSemantics & getLongDoubleFormat() const
unsigned getValue() const
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
Allow any unmodeled side effect.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type, where the destination type is an LLVM scalar type.
SourceLocation getExprLoc() const LLVM_READONLY
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to...
unsigned getPackLength() const
Retrieve the length of the parameter pack.
const T * castAs() const
Member-template castAs<specific type>.
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
unsigned getNumInits() const
bool isNullPtrType() const
void SetFPAccuracy(llvm::Value *Val, float Accuracy)
SetFPAccuracy - Set the minimum required accuracy of the given floating point operation, expressed as the maximum relative error in ulp.
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements, of a variable length array type, plus that largest non-variably-sized element type.
field_iterator field_end() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation...
bool isAnyComplexType() const
ObjCSelectorExpr used for @selector in Objective-C.
TypeSourceInfo * getTypeSourceInfo() const
Represents an expression that computes the length of a parameter pack.
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
llvm::LLVMContext & getLLVMContext()
llvm::IntegerType * Int32Ty
Kind getKind() const
Determine what kind of offsetof node this is.
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...
An RAII object to record that we're evaluating a statement expression.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
An expression that sends a message to the given Objective-C object or class.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Represents a GCC generic vector type.
bool isNullPointer() const
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
Try to emit a reference to the given value without producing it as an l-value.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
The scope of a CXXDefaultInitExpr.
const OffsetOfNode & getComponent(unsigned Idx) const
const TargetInfo & getTarget() const
Expr * getTrueExpr() const
const Expr * getSubExpr() const
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
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...
There is no lifetime qualification on this type.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
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. ...
Assigning into this object requires the old value to be released and the new value to be retained...
A field in a dependent type, known only by its name.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Encodes a location in the source.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go...
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
LangAS getAddressSpace() const
Return the address space of this type.
bool allowFPContractAcrossStatement() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
Expr * getSubExpr() const
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior...
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation...
CastKind getCastKind() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
QualType getElementType() const
A scoped helper to set the current debug location to the specified location or preferred location of ...
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
SanitizerSet SanOpts
Sanitizers enabled for this function.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>, and corresponding __opencl_atomic_* for OpenCL 2.0.
UnaryExprOrTypeTrait getKind() const
ObjCProtocolExpr used for protocol expression in Objective-C.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
An expression trait intrinsic.
const ObjCMethodDecl * getMethodDecl() const
bool isVectorType() const
Assigning into this object requires a lifetime extension.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
ObjCBoxedExpr - used for generalized expression boxing.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
bool isArgumentType() const
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot())
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.
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
Defines the fixed point number interface.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
CompoundAssignOperator - For compound assignments (e.g.
const llvm::fltSemantics & getFloat128Format() const
Represents a C11 generic selection.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
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.
AddrLabelExpr - The GNU address of label extension, representing &&label.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
SourceLocation getExprLoc() const LLVM_READONLY
Dataflow Directional Tag Classes.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i...
void EmitVTablePtrCheckForCast(QualType T, llvm::Value *Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
EvalResult is a struct with detailed info about an evaluated expression.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one...
A runtime availability query.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Represents a 'co_yield' expression.
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static Value * emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
bool isBooleanType() const
const Expr * getExpr() const
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Checking the destination of a store. Must be suitably sized and aligned.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type *> Tys=None)
A pointer to member type per C++ 8.3.3 - Pointers to members.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
ExplicitCastExpr - An explicit cast written in the source code.
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
llvm::APInt getValue() const
LabelDecl * getLabel() const
#define VISITCOMP(CODE, UI, SI, FP)
Represents a pointer to an Objective C object.
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
unsigned getIntWidth(QualType T) const
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
bool HasSideEffects
Whether the evaluated expression has side effects.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Complex values, per C99 6.2.5p11.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Checking the operand of a static_cast to a derived pointer type.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
An implicit indirection through a C++ base class, when the field found is in a base class...
uint64_t getCharWidth() const
Return the size of the character type, in bits.
bool isFunctionType() const
llvm::Value * EmitCheckedInBoundsGEP(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...
Represents a 'co_await' expression.
Expr * getReplacement() const
ExtVectorType - Extended vector type.
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
unsigned getWidth() const
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type, returning the result.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Reading or writing from this object requires a barrier call.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet...
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Represents a C++ struct/union/class.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
llvm::Type * ConvertType(QualType T)
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
void EmitTrapCheck(llvm::Value *Checked)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it...
ASTImporterLookupTable & LT
This class is used for builtin types like 'int'.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
bool isOCLIntelSubgroupAVCType() const
RetTy Visit(PTR(Stmt) S, ParamTys... P)
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...
CGCXXABI & getCXXABI() const
const VariableArrayType * getAsVariableArrayType(QualType T) const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
unsigned getNumComponents() const
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 mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
bool isFloatingType() const
LValue - This represents an lvalue references.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
A boolean literal, per ([C++ lex.bool] Boolean literals).
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type, member-designator).
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
Represents a C array with a specified size that is not an integer-constant-expression.
const LangOptions & getLangOpts() const
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, CodeGenFunction &CGF)
isCheapEnoughToEvaluateUnconditionally - Return true if the specified expression is cheap enough and ...
const LangOptions & getLangOpts() const
llvm::Value * getPointer() const
Represents an implicitly-generated value initialization of an object of a given type.
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
QualType getType() const
Return the type wrapped by this type source info.
llvm::Value * EmitBuiltinAvailable(ArrayRef< llvm::Value *> Args)
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
SourceLocation getExprLoc() const
bool isCompoundAssignmentOp() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
QualType getType() const
Retrieves the type of the base class.