28 #include "llvm/ADT/Optional.h" 29 #include "llvm/IR/CFG.h" 30 #include "llvm/IR/Constants.h" 31 #include "llvm/IR/DataLayout.h" 32 #include "llvm/IR/Function.h" 33 #include "llvm/IR/GetElementPtrTypeIterator.h" 34 #include "llvm/IR/GlobalVariable.h" 35 #include "llvm/IR/Intrinsics.h" 36 #include "llvm/IR/Module.h" 39 using namespace clang;
40 using namespace CodeGen;
54 bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
56 llvm::APInt &Result) {
59 const auto &LHSAP = LHS->getValue();
60 const auto &RHSAP = RHS->getValue();
61 if (Opcode == BO_Add) {
63 Result = LHSAP.sadd_ov(RHSAP, Overflow);
65 Result = LHSAP.uadd_ov(RHSAP, Overflow);
66 }
else if (Opcode == BO_Sub) {
68 Result = LHSAP.ssub_ov(RHSAP, Overflow);
70 Result = LHSAP.usub_ov(RHSAP, Overflow);
71 }
else if (Opcode == BO_Mul) {
73 Result = LHSAP.smul_ov(RHSAP, Overflow);
75 Result = LHSAP.umul_ov(RHSAP, Overflow);
76 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
77 if (Signed && !RHS->isZero())
78 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
94 bool mayHaveIntegerOverflow()
const {
96 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
97 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
102 return ::mayHaveIntegerOverflow(
107 bool isDivremOp()
const {
108 return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
109 Opcode == BO_RemAssign;
113 bool mayHaveIntegerDivisionByZero()
const {
115 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
121 bool mayHaveFloatDivisionByZero()
const {
123 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
124 return CFP->isZero();
129 static bool MustVisitNullValue(
const Expr *E) {
152 static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
153 return getUnwidenedIntegerType(Ctx, E).hasValue();
157 static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
158 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
159 "Expected a unary or binary operator");
163 if (!Op.mayHaveIntegerOverflow())
167 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
168 return !UO->canOverflow();
172 const auto *BO = cast<BinaryOperator>(Op.E);
173 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
177 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
186 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
192 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
193 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
198 static void updateFastMathFlags(llvm::FastMathFlags &FMF,
204 static Value *propagateFMFlags(
Value *V,
const BinOpInfo &Op) {
205 if (
auto *I = dyn_cast<llvm::Instruction>(V)) {
206 llvm::FastMathFlags FMF = I->getFastMathFlags();
207 updateFastMathFlags(FMF, Op.FPFeatures);
208 I->setFastMathFlags(FMF);
213 class ScalarExprEmitter
217 bool IgnoreResultAssign;
218 llvm::LLVMContext &VMContext;
222 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
223 VMContext(cgf.getLLVMContext()) {
230 bool TestAndClearIgnoreResultAssign() {
231 bool I = IgnoreResultAssign;
232 IgnoreResultAssign =
false;
242 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
243 const BinOpInfo &Info);
249 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *V) {
250 const AlignValueAttr *AVAttr =
nullptr;
251 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
255 if (
const auto *TTy =
257 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
261 if (isa<ParmVarDecl>(VD))
264 AVAttr = VD->
getAttr<AlignValueAttr>();
269 if (
const auto *TTy =
270 dyn_cast<TypedefType>(E->
getType()))
271 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
277 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
288 EmitLValueAlignmentAssumption(E, V);
298 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
304 enum ImplicitConversionCheckKind :
unsigned char {
305 ICCK_IntegerTruncation = 0,
315 struct ScalarConversionOpts {
316 bool TreatBooleanAsSigned;
317 bool EmitImplicitIntegerTruncationChecks;
319 ScalarConversionOpts()
320 : TreatBooleanAsSigned(
false),
321 EmitImplicitIntegerTruncationChecks(
false) {}
326 ScalarConversionOpts Opts = ScalarConversionOpts());
340 llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
341 return Builder.CreateFCmpUNE(V, Zero,
"tobool");
348 return Builder.CreateICmpNE(V, Zero,
"tobool");
355 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
356 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
357 Value *Result = ZI->getOperand(0);
362 ZI->eraseFromParent();
367 return Builder.CreateIsNotNull(V,
"tobool");
381 llvm_unreachable(
"Stmt can't have complex result type!");
406 return Builder.getInt(E->
getValue());
409 return Builder.getInt(E->
getValue());
412 return llvm::ConstantFP::get(VMContext, E->
getValue());
415 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
418 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
421 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
424 return EmitNullValue(E->
getType());
427 return EmitNullValue(E->
getType());
455 assert(Constant &&
"not a constant");
465 return emitConstant(Constant, E);
466 return EmitLoadOfLValue(E);
476 return EmitLoadOfLValue(E);
481 return EmitLoadOfLValue(E);
497 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
501 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Version.getMajor()),
502 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Min ? *Min : 0),
503 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, SMin ? *SMin : 0),
513 Value *VisitExtVectorElementExpr(
Expr *E) {
return EmitLoadOfLValue(E); }
515 return EmitLoadOfLValue(E);
522 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
527 return EmitNullValue(E->
getType());
531 return VisitCastExpr(E);
537 return EmitLoadOfLValue(E);
541 EmitLValueAlignmentAssumption(E, V);
550 return EmitScalarPrePostIncDec(E, LV,
false,
false);
554 return EmitScalarPrePostIncDec(E, LV,
true,
false);
558 return EmitScalarPrePostIncDec(E, LV,
false,
true);
562 return EmitScalarPrePostIncDec(E, LV,
true,
true);
570 bool isInc,
bool isPre);
574 if (isa<MemberPointerType>(E->
getType()))
577 return EmitLValue(E->
getSubExpr()).getPointer();
582 return EmitLoadOfLValue(E);
586 TestAndClearIgnoreResultAssign();
600 return EmitLoadOfLValue(E);
624 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
628 return llvm::ConstantInt::get(Builder.getInt32Ty(), E->
getValue());
632 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
646 return EmitNullValue(E->
getType());
655 return Builder.getInt1(E->
getValue());
659 Value *EmitMul(
const BinOpInfo &Ops) {
660 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
661 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
663 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
665 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
666 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
669 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
670 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
671 return EmitOverflowCheckedBinOp(Ops);
675 if (Ops.Ty->isUnsignedIntegerType() &&
676 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
677 !CanElideOverflowCheck(CGF.
getContext(), Ops))
678 return EmitOverflowCheckedBinOp(Ops);
680 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
681 Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
682 return propagateFMFlags(V, Ops);
684 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
688 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
691 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
695 Value *EmitDiv(
const BinOpInfo &Ops);
696 Value *EmitRem(
const BinOpInfo &Ops);
697 Value *EmitAdd(
const BinOpInfo &Ops);
698 Value *EmitSub(
const BinOpInfo &Ops);
699 Value *EmitShl(
const BinOpInfo &Ops);
700 Value *EmitShr(
const BinOpInfo &Ops);
701 Value *EmitAnd(
const BinOpInfo &Ops) {
702 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
704 Value *EmitXor(
const BinOpInfo &Ops) {
705 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
707 Value *EmitOr (
const BinOpInfo &Ops) {
708 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
713 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
717 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
720 #define HANDLEBINOP(OP) \ 721 Value *VisitBin ## OP(const BinaryOperator *E) { \ 722 return Emit ## OP(EmitBinOps(E)); \ 724 Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \ 725 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \ 741 llvm::CmpInst::Predicate SICmpOpc,
742 llvm::CmpInst::Predicate FCmpOpc);
743 #define VISITCOMP(CODE, UI, SI, FP) \ 744 Value *VisitBin##CODE(const BinaryOperator *E) { \ 745 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \ 746 llvm::FCmpInst::FP); } 747 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT)
748 VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT)
749 VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE)
750 VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE)
751 VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ)
752 VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE)
761 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
762 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
793 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
796 return EmitFloatToBoolConversion(Src);
801 assert((SrcType->
isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
802 "Unknown scalar type to convert");
804 if (isa<llvm::IntegerType>(Src->getType()))
805 return EmitIntToBoolConversion(Src);
807 assert(isa<llvm::PointerType>(Src->getType()));
808 return EmitPointerToBoolConversion(Src, SrcType);
811 void ScalarExprEmitter::EmitFloatConversionCheck(
821 if (llvm::IntegerType *IntTy = dyn_cast<llvm::IntegerType>(SrcTy)) {
827 APFloat LargestFloat =
829 APSInt LargestInt(IntTy->getBitWidth(), SrcIsUnsigned);
832 if (LargestFloat.convertToInteger(LargestInt, APFloat::rmTowardZero,
833 &IsExact) != APFloat::opOK)
838 llvm::Value *Max = llvm::ConstantInt::get(VMContext, LargestInt);
840 Check = Builder.CreateICmpULE(Src, Max);
842 llvm::Value *Min = llvm::ConstantInt::get(VMContext, -LargestInt);
845 Check = Builder.CreateAnd(GE, LE);
848 const llvm::fltSemantics &SrcSema =
850 if (isa<llvm::IntegerType>(DstTy)) {
857 APSInt Min = APSInt::getMinValue(Width, Unsigned);
858 APFloat MinSrc(SrcSema, APFloat::uninitialized);
859 if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
863 MinSrc = APFloat::getInf(SrcSema,
true);
867 MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
869 APSInt Max = APSInt::getMaxValue(Width, Unsigned);
870 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
871 if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
875 MaxSrc = APFloat::getInf(SrcSema,
false);
879 MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
884 const llvm::fltSemantics &
Sema =
887 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
888 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
892 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
894 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
895 Check = Builder.CreateAnd(GE, LE);
916 "should not check conversion from __half, it has the lowest rank");
918 const llvm::fltSemantics &DstSema =
920 APFloat MinBad = APFloat::getLargest(DstSema,
false);
921 APFloat MaxBad = APFloat::getInf(DstSema,
false);
924 MinBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
925 MaxBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
930 Builder.CreateFCmpOGT(AbsSrc, llvm::ConstantFP::get(VMContext, MinBad));
932 Builder.CreateFCmpOLT(AbsSrc, llvm::ConstantFP::get(VMContext, MaxBad));
933 Check = Builder.CreateNot(Builder.CreateAnd(GE, LE));
940 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
941 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
944 void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
947 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerTruncation))
958 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
959 "clang integer type lowered to non-integer llvm type");
961 unsigned SrcBits = SrcTy->getScalarSizeInBits();
962 unsigned DstBits = DstTy->getScalarSizeInBits();
964 if (SrcBits <= DstBits)
967 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
975 Check = Builder.CreateIntCast(Dst, SrcTy, InputSigned,
"anyext");
977 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
980 llvm::Constant *StaticArgs[] = {
983 llvm::ConstantInt::get(Builder.getInt8Ty(), ICCK_IntegerTruncation)};
984 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::ImplicitIntegerTruncation),
985 SanitizerHandler::ImplicitConversion, StaticArgs, {Src, Dst});
993 ScalarConversionOpts Opts) {
994 QualType NoncanonicalSrcType = SrcType;
995 QualType NoncanonicalDstType = DstType;
999 if (SrcType == DstType)
return Src;
1009 return EmitConversionToBool(Src, SrcType);
1016 if (DstTy->isFloatingPointTy()) {
1018 return Builder.CreateCall(
1026 Src = Builder.CreateCall(
1031 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1045 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1047 if (isa<llvm::PointerType>(SrcTy))
1050 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1056 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1058 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1061 if (isa<llvm::PointerType>(SrcTy)) {
1063 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1064 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1073 "Splatted expr doesn't match with vector element type?");
1076 unsigned NumElements = DstTy->getVectorNumElements();
1077 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1080 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1082 unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
1083 unsigned DstSize = DstTy->getPrimitiveSizeInBits();
1084 if (SrcSize == DstSize)
1094 llvm::Type *SrcElementTy = SrcTy->getVectorElementType();
1095 llvm::Type *DstElementTy = DstTy->getVectorElementType();
1098 assert(((SrcElementTy->isIntegerTy() &&
1099 DstElementTy->isIntegerTy()) ||
1100 (SrcElementTy->isFloatingPointTy() &&
1101 DstElementTy->isFloatingPointTy())) &&
1102 "unexpected conversion between a floating-point vector and an " 1106 if (SrcElementTy->isIntegerTy())
1107 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1110 if (SrcSize > DstSize)
1111 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1114 return Builder.CreateFPExt(Src, DstTy,
"conv");
1118 Value *Res =
nullptr;
1123 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1125 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1131 if (SrcTy->isFloatingPointTy()) {
1135 return Builder.CreateCall(
1138 return Builder.CreateFPTrunc(Src, DstTy);
1143 if (isa<llvm::IntegerType>(SrcTy)) {
1145 if (SrcType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1148 if (isa<llvm::IntegerType>(DstTy))
1149 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1150 else if (InputSigned)
1151 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1153 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1154 }
else if (isa<llvm::IntegerType>(DstTy)) {
1155 assert(SrcTy->isFloatingPointTy() &&
"Unknown real conversion");
1157 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1159 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1161 assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() &&
1162 "Unknown real conversion");
1163 if (DstTy->getTypeID() < SrcTy->getTypeID())
1164 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1166 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1169 if (DstTy != ResTy) {
1171 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1172 Res = Builder.CreateCall(
1176 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1180 if (Opts.EmitImplicitIntegerTruncationChecks)
1181 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1182 NoncanonicalDstType, Loc);
1189 Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1198 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1199 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1200 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1207 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1218 void ScalarExprEmitter::EmitBinOpCheck(
1219 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1231 if (UO && UO->
getOpcode() == UO_Minus) {
1232 Check = SanitizerHandler::NegateOverflow;
1234 DynamicData.push_back(Info.RHS);
1238 Check = SanitizerHandler::ShiftOutOfBounds;
1240 StaticData.push_back(
1242 StaticData.push_back(
1244 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1246 Check = SanitizerHandler::DivremOverflow;
1251 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1252 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1253 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1254 default: llvm_unreachable(
"unexpected opcode for bin op check");
1258 DynamicData.push_back(Info.LHS);
1259 DynamicData.push_back(Info.RHS);
1262 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1269 Value *ScalarExprEmitter::VisitExpr(
Expr *E) {
1283 llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType());
1284 unsigned LHSElts = LTy->getNumElements();
1288 llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType());
1292 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1293 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1301 llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(),
1302 MTy->getNumElements());
1303 Value* NewV = llvm::UndefValue::get(RTy);
1304 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1305 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1306 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1308 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1309 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1321 if (Idx.isSigned() && Idx.isAllOnesValue())
1322 indices.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
1324 indices.push_back(Builder.getInt32(Idx.getZExtValue()));
1327 Value *SV = llvm::ConstantVector::get(indices);
1328 return Builder.CreateShuffleVector(V1, V2, SV,
"shuffle");
1339 if (SrcType == DstType)
return Src;
1342 "ConvertVector source type must be a vector");
1344 "ConvertVector destination type must be a vector");
1356 assert(SrcTy->isVectorTy() &&
1357 "ConvertVector source IR type must be a vector");
1358 assert(DstTy->isVectorTy() &&
1359 "ConvertVector destination IR type must be a vector");
1361 llvm::Type *SrcEltTy = SrcTy->getVectorElementType(),
1362 *DstEltTy = DstTy->getVectorElementType();
1364 if (DstEltType->isBooleanType()) {
1365 assert((SrcEltTy->isFloatingPointTy() ||
1366 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1368 llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
1369 if (SrcEltTy->isFloatingPointTy()) {
1370 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1372 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1377 Value *Res =
nullptr;
1379 if (isa<llvm::IntegerType>(SrcEltTy)) {
1381 if (isa<llvm::IntegerType>(DstEltTy))
1382 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1383 else if (InputSigned)
1384 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1386 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1387 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1388 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1389 if (DstEltType->isSignedIntegerOrEnumerationType())
1390 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1392 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1394 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1395 "Unknown real conversion");
1396 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1397 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1399 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1408 return emitConstant(Constant, E);
1413 return Builder.getInt(Value);
1417 return EmitLoadOfLValue(E);
1421 TestAndClearIgnoreResultAssign();
1428 return EmitLoadOfLValue(E);
1432 Value *Base = Visit(E->
getBase());
1433 Value *Idx = Visit(E->
getIdx());
1436 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1439 return Builder.CreateExtractElement(Base, Idx,
"vecext");
1442 static llvm::Constant *
getMaskElt(llvm::ShuffleVectorInst *SVI,
unsigned Idx,
1444 int MV = SVI->getMaskValue(Idx);
1446 return llvm::UndefValue::get(I32Ty);
1447 return llvm::ConstantInt::get(I32Ty, Off+MV);
1451 if (C->getBitWidth() != 32) {
1452 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
1453 C->getZExtValue()) &&
1454 "Index operand too large for shufflevector mask!");
1455 return llvm::ConstantInt::get(I32Ty, C->getZExtValue());
1460 Value *ScalarExprEmitter::VisitInitListExpr(
InitListExpr *E) {
1461 bool Ignore = TestAndClearIgnoreResultAssign();
1463 assert (Ignore ==
false &&
"init list ignored");
1469 llvm::VectorType *VType =
1470 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
1473 if (NumInitElements == 0) {
1475 return EmitNullValue(E->
getType());
1481 unsigned ResElts = VType->getNumElements();
1488 unsigned CurIdx = 0;
1489 bool VIsUndefShuffle =
false;
1491 for (
unsigned i = 0; i != NumInitElements; ++i) {
1493 Value *Init = Visit(IE);
1496 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
1502 if (isa<ExtVectorElementExpr>(IE)) {
1503 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
1505 if (EI->getVectorOperandType()->getNumElements() == ResElts) {
1506 llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
1507 Value *LHS =
nullptr, *RHS =
nullptr;
1512 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1514 LHS = EI->getVectorOperand();
1516 VIsUndefShuffle =
true;
1517 }
else if (VIsUndefShuffle) {
1519 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
1520 for (
unsigned j = 0; j != CurIdx; ++j)
1522 Args.push_back(Builder.getInt32(ResElts + C->getZExtValue()));
1523 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1525 LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
1526 RHS = EI->getVectorOperand();
1527 VIsUndefShuffle =
false;
1529 if (!Args.empty()) {
1530 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1531 V = Builder.CreateShuffleVector(LHS, RHS, Mask);
1537 V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
1539 VIsUndefShuffle =
false;
1544 unsigned InitElts = VVT->getNumElements();
1549 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
1550 if (isa<ExtVectorElementExpr>(IE)) {
1551 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
1552 Value *SVOp = SVI->getOperand(0);
1553 llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType());
1555 if (OpTy->getNumElements() == ResElts) {
1556 for (
unsigned j = 0; j != CurIdx; ++j) {
1559 if (VIsUndefShuffle) {
1560 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0,
1563 Args.push_back(Builder.getInt32(j));
1566 for (
unsigned j = 0, je = InitElts; j != je; ++j)
1568 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1570 if (VIsUndefShuffle)
1571 V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
1580 for (
unsigned j = 0; j != InitElts; ++j)
1581 Args.push_back(Builder.getInt32(j));
1582 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1583 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1584 Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT),
1588 for (
unsigned j = 0; j != CurIdx; ++j)
1589 Args.push_back(Builder.getInt32(j));
1590 for (
unsigned j = 0; j != InitElts; ++j)
1591 Args.push_back(Builder.getInt32(j+Offset));
1592 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1599 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1600 V = Builder.CreateShuffleVector(V, Init, Mask,
"vecinit");
1601 VIsUndefShuffle = isa<llvm::UndefValue>(Init);
1610 for (; CurIdx < ResElts; ++CurIdx) {
1611 Value *Idx = Builder.getInt32(CurIdx);
1612 llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
1613 V = Builder.CreateInsertElement(V, Init, Idx,
"vecinit");
1621 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
1641 Value *ScalarExprEmitter::VisitCastExpr(
CastExpr *CE) {
1648 bool Ignored = TestAndClearIgnoreResultAssign();
1654 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
1655 case CK_BuiltinFnToFnPtr:
1656 llvm_unreachable(
"builtin functions are handled elsewhere");
1658 case CK_LValueBitCast:
1659 case CK_ObjCObjectLValueCast: {
1660 Address Addr = EmitLValue(E).getAddress();
1663 return EmitLoadOfLValue(LV, CE->
getExprLoc());
1666 case CK_CPointerToObjCPointerCast:
1667 case CK_BlockPointerToObjCPointerCast:
1668 case CK_AnyPointerToBlockPointerCast:
1670 Value *Src = Visit(const_cast<Expr*>(E));
1673 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
1674 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
1675 llvm_unreachable(
"wrong cast for pointers in different address spaces" 1676 "(must be an address space cast)!");
1679 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
1693 Src = Builder.CreateLaunderInvariantGroup(Src);
1701 Src = Builder.CreateStripInvariantGroup(Src);
1707 case CK_AddressSpaceConversion: {
1717 ConvertType(DestTy)), DestTy);
1725 case CK_AtomicToNonAtomic:
1726 case CK_NonAtomicToAtomic:
1728 case CK_UserDefinedConversion:
1729 return Visit(const_cast<Expr*>(E));
1731 case CK_BaseToDerived: {
1733 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
1747 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
1756 case CK_UncheckedDerivedToBase:
1757 case CK_DerivedToBase: {
1769 case CK_ArrayToPointerDecay:
1771 case CK_FunctionToPointerDecay:
1772 return EmitLValue(E).getPointer();
1774 case CK_NullToPointer:
1775 if (MustVisitNullValue(E))
1781 case CK_NullToMemberPointer: {
1782 if (MustVisitNullValue(E))
1789 case CK_ReinterpretMemberPointer:
1790 case CK_BaseToDerivedMemberPointer:
1791 case CK_DerivedToBaseMemberPointer: {
1792 Value *Src = Visit(E);
1803 case CK_ARCProduceObject:
1805 case CK_ARCConsumeObject:
1807 case CK_ARCReclaimReturnedObject:
1809 case CK_ARCExtendBlockObject:
1812 case CK_CopyAndAutoreleaseBlockObject:
1815 case CK_FloatingRealToComplex:
1816 case CK_FloatingComplexCast:
1817 case CK_IntegralRealToComplex:
1818 case CK_IntegralComplexCast:
1819 case CK_IntegralComplexToFloatingComplex:
1820 case CK_FloatingComplexToIntegralComplex:
1821 case CK_ConstructorConversion:
1823 llvm_unreachable(
"scalar cast to non-scalar value");
1825 case CK_LValueToRValue:
1827 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
1828 return Visit(const_cast<Expr*>(E));
1830 case CK_IntegralToPointer: {
1831 Value *Src = Visit(const_cast<Expr*>(E));
1835 auto DestLLVMTy = ConvertType(DestTy);
1839 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1841 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
1847 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
1851 case CK_PointerToIntegral: {
1852 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
1853 auto *PtrExpr = Visit(E);
1861 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
1864 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
1870 case CK_VectorSplat: {
1872 Value *Elt = Visit(const_cast<Expr*>(E));
1874 unsigned NumElements = DstTy->getVectorNumElements();
1875 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
1878 case CK_IntegralCast: {
1879 ScalarConversionOpts Opts;
1880 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerTruncation)) {
1881 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE))
1882 Opts.EmitImplicitIntegerTruncationChecks = !ICE->isPartOfExplicitCast();
1884 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
1887 case CK_IntegralToFloating:
1888 case CK_FloatingToIntegral:
1889 case CK_FloatingCast:
1890 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
1892 case CK_BooleanToSignedIntegral: {
1893 ScalarConversionOpts Opts;
1894 Opts.TreatBooleanAsSigned =
true;
1895 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
1898 case CK_IntegralToBoolean:
1899 return EmitIntToBoolConversion(Visit(E));
1900 case CK_PointerToBoolean:
1901 return EmitPointerToBoolConversion(Visit(E), E->
getType());
1902 case CK_FloatingToBoolean:
1903 return EmitFloatToBoolConversion(Visit(E));
1904 case CK_MemberPointerToBoolean: {
1910 case CK_FloatingComplexToReal:
1911 case CK_IntegralComplexToReal:
1914 case CK_FloatingComplexToBoolean:
1915 case CK_IntegralComplexToBoolean: {
1919 return EmitComplexToScalarConversion(V, E->
getType(), DestTy,
1923 case CK_ZeroToOCLEvent: {
1924 assert(DestTy->
isEventT() &&
"CK_ZeroToOCLEvent cast on non-event type");
1925 return llvm::Constant::getNullValue(ConvertType(DestTy));
1928 case CK_ZeroToOCLQueue: {
1929 assert(DestTy->
isQueueT() &&
"CK_ZeroToOCLQueue cast on non queue_t type");
1930 return llvm::Constant::getNullValue(ConvertType(DestTy));
1933 case CK_IntToOCLSampler:
1938 llvm_unreachable(
"unknown scalar cast");
1941 Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
1969 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
1971 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
1977 llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
1980 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
1981 StringRef Name = IsInc ?
"inc" :
"dec";
1982 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
1984 return Builder.CreateAdd(InVal, Amount, Name);
1986 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
1987 return Builder.CreateNSWAdd(InVal, Amount, Name);
1991 return Builder.CreateNSWAdd(InVal, Amount, Name);
1994 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
1999 bool isInc,
bool isPre) {
2002 llvm::PHINode *atomicPHI =
nullptr;
2006 int amount = (isInc ? 1 : -1);
2007 bool isSubtraction = !isInc;
2010 type = atomicTy->getValueType();
2015 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2016 return Builder.getTrue();
2020 return Builder.CreateAtomicRMW(
2021 llvm::AtomicRMWInst::Xchg, LV.
getPointer(), True,
2022 llvm::AtomicOrdering::SequentiallyConsistent);
2029 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2032 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2033 llvm::AtomicRMWInst::Sub;
2034 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2035 llvm::Instruction::Sub;
2037 llvm::ConstantInt::get(ConvertType(type), 1,
true), type);
2039 LV.
getPointer(), amt, llvm::AtomicOrdering::SequentiallyConsistent);
2040 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2042 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2045 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2048 Builder.CreateBr(opBB);
2049 Builder.SetInsertPoint(opBB);
2050 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2051 atomicPHI->addIncoming(value, startBB);
2054 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2066 value = Builder.getTrue();
2073 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
2075 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2079 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2080 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2091 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2093 value = Builder.CreateGEP(value, numElts,
"vla.inc");
2096 value, numElts,
false, isSubtraction,
2105 value = Builder.CreateGEP(value, amt,
"incdec.funcptr");
2116 value = Builder.CreateGEP(value, amt,
"incdec.ptr");
2126 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2128 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2130 value = Builder.CreateFAdd(
2132 llvm::ConstantFP::get(value->getType(), amount),
2133 isInc ?
"inc" :
"dec");
2144 value = Builder.CreateCall(
2147 input,
"incdec.conv");
2149 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2153 if (value->getType()->isFloatTy())
2154 amt = llvm::ConstantFP::get(VMContext,
2155 llvm::APFloat(static_cast<float>(amount)));
2156 else if (value->getType()->isDoubleTy())
2157 amt = llvm::ConstantFP::get(VMContext,
2158 llvm::APFloat(static_cast<double>(amount)));
2161 llvm::APFloat F(static_cast<float>(amount));
2163 const llvm::fltSemantics *FS;
2166 if (value->getType()->isFP128Ty())
2168 else if (value->getType()->isHalfTy())
2172 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
2173 amt = llvm::ConstantFP::get(VMContext, F);
2175 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
2179 value = Builder.CreateCall(
2182 value,
"incdec.conv");
2184 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
2194 if (!isInc) size = -size;
2199 value = Builder.CreateGEP(value, sizeValue,
"incdec.objptr");
2202 false, isSubtraction,
2208 llvm::BasicBlock *opBB = Builder.GetInsertBlock();
2214 atomicPHI->addIncoming(old, opBB);
2215 Builder.CreateCondBr(success, contBB, opBB);
2216 Builder.SetInsertPoint(contBB);
2217 return isPre ? value : input;
2228 return isPre ? value : input;
2233 Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E) {
2234 TestAndClearIgnoreResultAssign();
2239 if (BinOp.RHS->getType()->isFPOrFPVectorTy())
2240 BinOp.LHS = llvm::ConstantFP::getZeroValueForNegation(BinOp.RHS->getType());
2242 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
2244 BinOp.Opcode = BO_Sub;
2247 return EmitSub(BinOp);
2250 Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
2251 TestAndClearIgnoreResultAssign();
2253 return Builder.CreateNot(Op,
"neg");
2256 Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
2260 Value *Zero = llvm::Constant::getNullValue(Oper->getType());
2262 if (Oper->getType()->isFPOrFPVectorTy())
2263 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
2265 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
2266 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
2275 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
2278 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
2281 Value *ScalarExprEmitter::VisitOffsetOfExpr(
OffsetOfExpr *E) {
2285 return Builder.getInt(Value);
2290 llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
2292 for (
unsigned i = 0; i != n; ++i) {
2301 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
2308 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
2312 Offset = Builder.CreateMul(Idx, ElemSize);
2326 Field != FieldEnd; ++Field, ++i) {
2327 if (*Field == MemberDecl)
2330 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
2335 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
2338 CurrentType = MemberDecl->
getType();
2343 llvm_unreachable(
"dependent __builtin_offsetof");
2361 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
2365 Result = Builder.CreateAdd(Result, Offset);
2373 ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
2393 if (!eltSize.
isOne())
2404 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
2412 Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E) {
2429 Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E) {
2449 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
2456 BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E) {
2457 TestAndClearIgnoreResultAssign();
2459 Result.LHS = Visit(E->
getLHS());
2460 Result.RHS = Visit(E->
getRHS());
2468 LValue ScalarExprEmitter::EmitCompoundAssignLValue(
2470 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &),
2480 OpInfo.RHS = Visit(E->
getRHS());
2488 llvm::PHINode *atomicPHI =
nullptr;
2493 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2496 llvm::AtomicRMWInst::BinOp aop = llvm::AtomicRMWInst::BAD_BINOP;
2497 switch (OpInfo.Opcode) {
2499 case BO_MulAssign:
case BO_DivAssign:
2505 aop = llvm::AtomicRMWInst::Add;
2508 aop = llvm::AtomicRMWInst::Sub;
2514 aop = llvm::AtomicRMWInst::Xor;
2517 aop = llvm::AtomicRMWInst::Or;
2520 llvm_unreachable(
"Invalid compound assignment type");
2522 if (aop != llvm::AtomicRMWInst::BAD_BINOP) {
2524 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
2527 Builder.CreateAtomicRMW(aop, LHSLV.
getPointer(), amt,
2528 llvm::AtomicOrdering::SequentiallyConsistent);
2534 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2536 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2538 Builder.CreateBr(opBB);
2539 Builder.SetInsertPoint(opBB);
2540 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
2541 atomicPHI->addIncoming(OpInfo.LHS, startBB);
2542 OpInfo.LHS = atomicPHI;
2545 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2552 Result = (this->*Func)(OpInfo);
2559 llvm::BasicBlock *opBB = Builder.GetInsertBlock();
2565 atomicPHI->addIncoming(old, opBB);
2566 Builder.CreateCondBr(success, contBB, opBB);
2567 Builder.SetInsertPoint(contBB);
2584 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &)) {
2585 bool Ignore = TestAndClearIgnoreResultAssign();
2587 LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
2602 return EmitLoadOfLValue(LHS, E->
getExprLoc());
2605 void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
2606 const BinOpInfo &Ops,
llvm::Value *Zero,
bool isDiv) {
2609 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
2610 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
2611 SanitizerKind::IntegerDivideByZero));
2614 const auto *BO = cast<BinaryOperator>(Ops.E);
2615 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
2616 Ops.Ty->hasSignedIntegerRepresentation() &&
2618 Ops.mayHaveIntegerOverflow()) {
2619 llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
2622 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
2623 llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
2625 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
2626 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
2627 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
2629 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
2632 if (Checks.size() > 0)
2633 EmitBinOpCheck(Checks, Ops);
2636 Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
2639 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
2640 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
2641 Ops.Ty->isIntegerType() &&
2642 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
2643 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2644 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
2645 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
2646 Ops.Ty->isRealFloatingType() &&
2647 Ops.mayHaveFloatDivisionByZero()) {
2648 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2649 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
2650 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
2655 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
2656 llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
2665 if (ValTy->isFloatTy() ||
2666 (isa<llvm::VectorType>(ValTy) &&
2667 cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy()))
2672 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
2673 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
2675 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
2678 Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
2680 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
2681 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
2682 Ops.Ty->isIntegerType() &&
2683 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
2685 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2686 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
2689 if (Ops.Ty->hasUnsignedIntegerRepresentation())
2690 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
2692 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
2695 Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
2699 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
2700 switch (Ops.Opcode) {
2704 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
2705 llvm::Intrinsic::uadd_with_overflow;
2710 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
2711 llvm::Intrinsic::usub_with_overflow;
2716 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
2717 llvm::Intrinsic::umul_with_overflow;
2720 llvm_unreachable(
"Unsupported operation for overflow detection");
2731 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
2732 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
2733 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
2736 const std::string *handlerName =
2738 if (handlerName->empty()) {
2741 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
2742 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
2744 : SanitizerKind::UnsignedIntegerOverflow;
2745 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
2752 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
2753 llvm::BasicBlock *continueBB =
2757 Builder.CreateCondBr(overflow, overflowBB, continueBB);
2761 Builder.SetInsertPoint(overflowBB);
2766 llvm::FunctionType *handlerTy =
2767 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
2780 Builder.getInt8(OpID),
2781 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
2787 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
2788 Builder.CreateBr(continueBB);
2790 Builder.SetInsertPoint(continueBB);
2791 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
2792 phi->addIncoming(result, initialBB);
2793 phi->addIncoming(handlerResult, overflowBB);
2800 const BinOpInfo &op,
2801 bool isSubtraction) {
2806 Value *pointer = op.LHS;
2808 Value *index = op.RHS;
2812 if (!isSubtraction && !pointer->getType()->isPointerTy()) {
2813 std::swap(pointer, index);
2814 std::swap(pointerOperand, indexOperand);
2819 unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
2821 auto PtrTy = cast<llvm::PointerType>(pointer->getType());
2844 return CGF.
Builder.CreateIntToPtr(index, pointer->getType());
2846 if (width != DL.getTypeSizeInBits(PtrTy)) {
2849 index = CGF.
Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned,
2855 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
2857 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2870 index = CGF.
Builder.CreateMul(index, objectSize);
2873 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
2888 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
2889 pointer = CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
2891 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
2894 op.E->getExprLoc(),
"add.ptr");
2904 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
2909 return CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
2912 op.E->getExprLoc(),
"add.ptr");
2922 bool negMul,
bool negAdd) {
2923 assert(!(negMul && negAdd) &&
"Only one of negMul and negAdd should be set.");
2925 Value *MulOp0 = MulOp->getOperand(0);
2926 Value *MulOp1 = MulOp->getOperand(1);
2930 llvm::ConstantFP::getZeroValueForNegation(MulOp0->getType()), MulOp0,
2932 }
else if (negAdd) {
2935 llvm::ConstantFP::getZeroValueForNegation(Addend->getType()), Addend,
2939 Value *FMulAdd = Builder.CreateCall(
2941 {MulOp0, MulOp1, Addend});
2942 MulOp->eraseFromParent();
2957 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
2958 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
2959 "Only fadd/fsub can be the root of an fmuladd.");
2962 if (!op.FPFeatures.allowFPContractWithinStatement())
2968 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) {
2969 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
2970 LHSBinOp->use_empty())
2971 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder,
false, isSub);
2973 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) {
2974 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
2975 RHSBinOp->use_empty())
2976 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub,
false);
2982 Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
2983 if (op.LHS->getType()->isPointerTy() ||
2984 op.RHS->getType()->isPointerTy())
2987 if (op.Ty->isSignedIntegerOrEnumerationType()) {
2988 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2990 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
2992 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2993 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
2996 if (CanElideOverflowCheck(CGF.
getContext(), op))
2997 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
2998 return EmitOverflowCheckedBinOp(op);
3002 if (op.Ty->isUnsignedIntegerType() &&
3003 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3004 !CanElideOverflowCheck(CGF.
getContext(), op))
3005 return EmitOverflowCheckedBinOp(op);
3007 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3012 Value *V = Builder.CreateFAdd(op.LHS, op.RHS,
"add");
3013 return propagateFMFlags(V, op);
3016 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3019 Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
3021 if (!op.LHS->getType()->isPointerTy()) {
3022 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3023 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3025 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
3027 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3028 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
3031 if (CanElideOverflowCheck(CGF.
getContext(), op))
3032 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
3033 return EmitOverflowCheckedBinOp(op);
3037 if (op.Ty->isUnsignedIntegerType() &&
3038 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3039 !CanElideOverflowCheck(CGF.
getContext(), op))
3040 return EmitOverflowCheckedBinOp(op);
3042 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3046 Value *V = Builder.CreateFSub(op.LHS, op.RHS,
"sub");
3047 return propagateFMFlags(V, op);
3050 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
3055 if (!op.RHS->getType()->isPointerTy())
3062 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
3064 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
3065 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
3077 elementType = VlaSize.
Type;
3078 divisor = VlaSize.NumElts;
3082 if (!eltSize.
isOne())
3092 if (elementType->isVoidType() || elementType->isFunctionType())
3098 if (elementSize.
isOne())
3107 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
3110 Value *ScalarExprEmitter::GetWidthMinusOneValue(Value* LHS,Value* RHS) {
3111 llvm::IntegerType *Ty;
3112 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
3113 Ty = cast<llvm::IntegerType>(VT->getElementType());
3115 Ty = cast<llvm::IntegerType>(LHS->getType());
3116 return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
3119 Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
3122 Value *RHS = Ops.RHS;
3123 if (Ops.LHS->getType() != RHS->getType())
3124 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3126 bool SanitizeBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
3127 Ops.Ty->hasSignedIntegerRepresentation() &&
3129 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
3133 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shl.mask");
3134 else if ((SanitizeBase || SanitizeExponent) &&
3135 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3138 llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
3139 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
3141 if (SanitizeExponent) {
3143 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
3150 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
3153 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
3155 (RHS == Ops.RHS) ? WidthMinusOne
3156 : GetWidthMinusOneValue(Ops.LHS, RHS);
3159 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
3167 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
3168 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
3170 llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
3171 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
3173 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
3174 BaseCheck->addIncoming(Builder.getTrue(), Orig);
3175 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
3176 Checks.push_back(std::make_pair(BaseCheck, SanitizerKind::ShiftBase));
3179 assert(!Checks.empty());
3180 EmitBinOpCheck(Checks, Ops);
3183 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
3186 Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
3189 Value *RHS = Ops.RHS;
3190 if (Ops.LHS->getType() != RHS->getType())
3191 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3196 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shr.mask");
3197 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
3198 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3201 Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
3202 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
3205 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3206 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
3207 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
3215 default: llvm_unreachable(
"unexpected element type");
3216 case BuiltinType::Char_U:
3217 case BuiltinType::UChar:
3218 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3219 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
3220 case BuiltinType::Char_S:
3221 case BuiltinType::SChar:
3222 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3223 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
3224 case BuiltinType::UShort:
3225 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3226 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
3227 case BuiltinType::Short:
3228 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3229 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
3230 case BuiltinType::UInt:
3231 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3232 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
3233 case BuiltinType::Int:
3234 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3235 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
3236 case BuiltinType::ULong:
3237 case BuiltinType::ULongLong:
3238 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3239 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
3240 case BuiltinType::Long:
3241 case BuiltinType::LongLong:
3242 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3243 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
3244 case BuiltinType::Float:
3245 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
3246 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
3247 case BuiltinType::Double:
3248 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
3249 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
3254 llvm::CmpInst::Predicate UICmpOpc,
3255 llvm::CmpInst::Predicate SICmpOpc,
3256 llvm::CmpInst::Predicate FCmpOpc) {
3257 TestAndClearIgnoreResultAssign();
3267 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
3269 Value *LHS = Visit(E->
getLHS());
3270 Value *RHS = Visit(E->
getRHS());
3276 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
3281 Value *FirstVecArg = LHS,
3282 *SecondVecArg = RHS;
3289 default: llvm_unreachable(
"is not a comparison operation");
3301 std::swap(FirstVecArg, SecondVecArg);
3308 if (ElementKind == BuiltinType::Float) {
3310 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3311 std::swap(FirstVecArg, SecondVecArg);
3319 if (ElementKind == BuiltinType::Float) {
3321 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3326 std::swap(FirstVecArg, SecondVecArg);
3331 Value *CR6Param = Builder.getInt32(CR6);
3333 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
3340 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
3341 if (ResultTy->getBitWidth() > 1 &&
3343 Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
3348 if (LHS->getType()->isFPOrFPVectorTy()) {
3349 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
3351 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
3356 !isa<llvm::ConstantPointerNull>(LHS) &&
3357 !isa<llvm::ConstantPointerNull>(RHS)) {
3366 LHS = Builder.CreateStripInvariantGroup(LHS);
3368 RHS = Builder.CreateStripInvariantGroup(RHS);
3371 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
3377 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
3385 CETy = CTy->getElementType();
3387 LHS.first = Visit(E->
getLHS());
3388 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
3394 CTy->getElementType()) &&
3395 "The element types must always match.");
3398 RHS.first = Visit(E->
getRHS());
3399 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
3401 "The element types must always match.");
3404 Value *ResultR, *ResultI;
3406 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
3407 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
3411 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
3412 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
3416 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
3419 "Complex comparison other than == or != ?");
3420 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
3428 Value *ScalarExprEmitter::VisitBinAssign(
const BinaryOperator *E) {
3429 bool Ignore = TestAndClearIgnoreResultAssign();
3448 RHS = Visit(E->
getRHS());
3456 RHS = Visit(E->
getRHS());
3463 if (LHS.isBitField()) {
3484 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3487 Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
3492 Value *LHS = Visit(E->
getLHS());
3493 Value *RHS = Visit(E->
getRHS());
3494 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3495 if (LHS->getType()->isFPOrFPVectorTy()) {
3496 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
3497 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
3499 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
3500 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
3502 Value *
And = Builder.CreateAnd(LHS, RHS);
3503 return Builder.CreateSExt(And, ConvertType(E->
getType()),
"sext");
3517 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
3522 return llvm::Constant::getNullValue(ResTy);
3539 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
3541 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
3550 RHSBlock = Builder.GetInsertBlock();
3559 PN->addIncoming(RHSCond, RHSBlock);
3564 PN->setDebugLoc(Builder.getCurrentDebugLocation());
3568 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
3576 Value *LHS = Visit(E->
getLHS());
3577 Value *RHS = Visit(E->
getRHS());
3578 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3579 if (LHS->getType()->isFPOrFPVectorTy()) {
3580 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
3581 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
3583 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
3584 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
3586 Value *Or = Builder.CreateOr(LHS, RHS);
3587 return Builder.CreateSExt(Or, ConvertType(E->
getType()),
"sext");
3601 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
3606 return llvm::ConstantInt::get(ResTy, 1);
3624 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
3626 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
3638 RHSBlock = Builder.GetInsertBlock();
3643 PN->addIncoming(RHSCond, RHSBlock);
3646 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
3649 Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
3652 return Visit(E->
getRHS());
3677 Value *ScalarExprEmitter::
3679 TestAndClearIgnoreResultAssign();
3692 Expr *live = lhsExpr, *dead = rhsExpr;
3693 if (!CondExprBool) std::swap(live, dead);
3699 Value *Result = Visit(live);
3722 llvm::VectorType *vecTy = cast<llvm::VectorType>(condType);
3724 unsigned numElem = vecTy->getNumElements();
3725 llvm::Type *elemType = vecTy->getElementType();
3727 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
3728 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
3730 llvm::VectorType::get(elemType,
3738 bool wasCast =
false;
3739 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
3740 if (rhsVTy->getElementType()->isFloatingPointTy()) {
3746 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
3747 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
3748 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
3769 assert(!RHS &&
"LHS and RHS types must match");
3772 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
3786 Value *LHS = Visit(lhsExpr);
3789 LHSBlock = Builder.GetInsertBlock();
3790 Builder.CreateBr(ContBlock);
3794 Value *RHS = Visit(rhsExpr);
3797 RHSBlock = Builder.GetInsertBlock();
3807 llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2,
"cond");
3808 PN->addIncoming(LHS, LHSBlock);
3809 PN->addIncoming(RHS, RHSBlock);
3813 Value *ScalarExprEmitter::VisitChooseExpr(
ChooseExpr *E) {
3817 Value *ScalarExprEmitter::VisitVAArgExpr(
VAArgExpr *VE) {
3831 return llvm::UndefValue::get(ArgTy);
3838 if (ArgTy != Val->getType()) {
3839 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
3840 Val = Builder.CreateIntToPtr(Val, ArgTy);
3842 Val = Builder.CreateTrunc(Val, ArgTy);
3848 Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
3854 Value *Src,
unsigned NumElementsDst) {
3855 llvm::Value *UnV = llvm::UndefValue::get(Src->getType());
3857 Args.push_back(Builder.getInt32(0));
3858 Args.push_back(Builder.getInt32(1));
3859 Args.push_back(Builder.getInt32(2));
3860 if (NumElementsDst == 4)
3861 Args.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
3862 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
3863 return Builder.CreateShuffleVector(Src, UnV, Mask);
3883 const llvm::DataLayout &DL,
3885 StringRef Name =
"") {
3886 auto SrcTy = Src->getType();
3889 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
3893 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
3897 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
3899 if (!DstTy->isIntegerTy())
3900 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
3902 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
3906 if (!SrcTy->isIntegerTy())
3909 return Builder.CreateIntToPtr(Src, DstTy, Name);
3912 Value *ScalarExprEmitter::VisitAsTypeExpr(
AsTypeExpr *E) {
3917 unsigned NumElementsSrc = isa<llvm::VectorType>(SrcTy) ?
3918 cast<llvm::VectorType>(SrcTy)->getNumElements() : 0;
3919 unsigned NumElementsDst = isa<llvm::VectorType>(DstTy) ?
3920 cast<llvm::VectorType>(DstTy)->getNumElements() : 0;
3924 if (NumElementsSrc == 3 && NumElementsDst != 3) {
3932 Src->setName(
"astype");
3939 if (NumElementsSrc != 3 && NumElementsDst == 3) {
3941 auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4);
3947 Src->setName(
"astype");
3952 Src, DstTy,
"astype");
3955 Value *ScalarExprEmitter::VisitAtomicExpr(
AtomicExpr *E) {
3966 assert(E && hasScalarEvaluationKind(E->
getType()) &&
3967 "Invalid scalar expression to emit");
3969 return ScalarExprEmitter(*
this, IgnoreResultAssign)
3970 .Visit(const_cast<Expr *>(E));
3978 assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
3979 "Invalid scalar expression to emit");
3980 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
3990 "Invalid complex -> scalar conversion");
3991 return ScalarExprEmitter(*
this)
3992 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
3998 bool isInc,
bool isPre) {
3999 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
4009 Addr =
Address(EmitScalarExpr(BaseExpr), getPointerAlign());
4011 Addr = EmitLValue(BaseExpr).getAddress();
4016 return MakeAddrLValue(Addr, E->
getType());
4022 ScalarExprEmitter Scalar(*
this);
4023 Value *Result =
nullptr;
4025 #define COMPOUND_OP(Op) \ 4026 case BO_##Op##Assign: \ 4027 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \ 4064 llvm_unreachable(
"Not valid compound assignment operators");
4067 llvm_unreachable(
"Unhandled compound assignment operator");
4075 const Twine &Name) {
4076 Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name);
4079 if (!SanOpts.has(SanitizerKind::PointerOverflow))
4083 if (isa<llvm::Constant>(GEPVal))
4087 if (GEPVal->getType()->getPointerAddressSpace())
4090 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
4091 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
4094 auto &VMContext = getLLVMContext();
4095 const auto &DL = CGM.getDataLayout();
4096 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
4099 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
4100 auto *SAddIntrinsic =
4101 CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
4102 auto *SMulIntrinsic =
4103 CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
4108 llvm::Value *OffsetOverflows = Builder.getFalse();
4113 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
4116 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
4117 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
4119 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
4122 OffsetOverflows = Builder.getTrue();
4123 return llvm::ConstantInt::get(VMContext, N);
4128 auto *ResultAndOverflow = Builder.CreateCall(
4129 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
4130 OffsetOverflows = Builder.CreateOr(
4131 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
4132 return Builder.CreateExtractValue(ResultAndOverflow, 0);
4136 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
4137 GTI != GTE; ++GTI) {
4139 auto *Index = GTI.getOperand();
4141 if (
auto *STy = GTI.getStructTypeOrNull()) {
4144 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
4145 LocalOffset = llvm::ConstantInt::get(
4146 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
4150 auto *ElementSize = llvm::ConstantInt::get(
4151 IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
4152 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
4153 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
4158 if (!TotalOffset || TotalOffset == Zero)
4159 TotalOffset = LocalOffset;
4161 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
4165 if (TotalOffset == Zero)
4170 auto *IntPtr = Builder.CreatePtrToInt(GEP->getPointerOperand(), IntPtrTy);
4171 auto *ComputedGEP = Builder.CreateAdd(IntPtr, TotalOffset);
4178 auto *NoOffsetOverflow = Builder.CreateNot(OffsetOverflows);
4179 if (SignedIndices) {
4180 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4181 auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero);
4182 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
4183 ValidGEP = Builder.CreateAnd(
4184 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid),
4186 }
else if (!SignedIndices && !IsSubtraction) {
4187 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4188 ValidGEP = Builder.CreateAnd(PosOrZeroValid, NoOffsetOverflow);
4190 auto *NegOrZeroValid = Builder.CreateICmpULE(ComputedGEP, IntPtr);
4191 ValidGEP = Builder.CreateAnd(NegOrZeroValid, NoOffsetOverflow);
4194 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
4196 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4197 EmitCheck(std::make_pair(ValidGEP, SanitizerKind::PointerOverflow),
4198 SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
const llvm::DataLayout & getDataLayout() 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.
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
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...
LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const
bool isSignedOverflowDefined() const
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
llvm::Constant * getValue() 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
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...
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
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 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...
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.
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...
bool EvaluateAsInt(llvm::APSInt &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...
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
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
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.
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.
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.
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.
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.
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 * 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 ...
Expr - 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>.
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::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
void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment, llvm::Value *OffsetValue=nullptr)
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.
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 ...
SourceLocation getExprLoc() const LLVM_READONLY
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)"...
SourceLocation getLocStart() const LLVM_READONLY
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())
void enterFullExpression(const ExprWithCleanups *E)
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="")
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.
SourceLocation getExprLoc() const LLVM_READONLY
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...
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)
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...
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.
bool isCompoundAssignmentOp() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
QualType getType() const
Retrieves the type of the base class.