18#include "llvm/ADT/STLExtras.h"
19#include "llvm/IR/Constants.h"
20#include "llvm/IR/Instructions.h"
21#include "llvm/IR/MDBuilder.h"
22#include "llvm/IR/Metadata.h"
25using namespace CodeGen;
39 return cast<ComplexType>(cast<AtomicType>(
type)->getValueType());
44class ComplexExprEmitter
45 :
public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
52 : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) {
60 bool TestAndClearIgnoreReal() {
65 bool TestAndClearIgnoreImag() {
102 llvm_unreachable(
"Stmt can't have complex result type!");
106 if (llvm::Constant *Result =
ConstantEmitter(CGF).tryEmitConstantExpr(E))
108 Result->getAggregateElement(1U));
113 return Visit(
GE->getResultExpr());
130 ComplexPairTy emitConstant(
const CodeGenFunction::ConstantEmission &Constant,
132 assert(Constant &&
"not a constant");
133 if (Constant.isReference())
134 return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E),
137 llvm::Constant *pair = Constant.getValue();
139 pair->getAggregateElement(1U));
145 return emitConstant(Constant, E);
146 return EmitLoadOfLValue(E);
149 return EmitLoadOfLValue(E);
156 if (CodeGenFunction::ConstantEmission Constant =
159 return emitConstant(Constant, ME);
161 return EmitLoadOfLValue(ME);
183 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
192 bool isInc,
bool isPre) {
197 return VisitPrePostIncDec(E,
false,
false);
200 return VisitPrePostIncDec(E,
true,
false);
203 return VisitPrePostIncDec(E,
false,
true);
206 return VisitPrePostIncDec(E,
true,
true);
222 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
226 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
230 CodeGenFunction::RunCleanupsScope
Scope(CGF);
234 Scope.ForceCleanup({&Vals.first, &Vals.second});
240 llvm::Constant *
Null = llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
246 llvm::Constant *
Null =
247 llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
268 (
const BinOpInfo &));
276 const BinOpInfo &Op);
280 QualType ElementType = CT->getElementType();
289#define HANDLEBINOP(OP) \
290 ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
291 QualType promotionTy = getPromotionType(E->getType()); \
292 ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
293 if (!promotionTy.isNull()) \
295 CGF.EmitUnPromotedValue(result, E->getType()); \
311 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
314 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
317 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
320 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
341 return EmitLoadOfLValue(E);
370 assert(lvalue.
isSimple() &&
"non-simple complex l-value?");
377 llvm::Value *Real =
nullptr, *Imag =
nullptr;
379 if (!IgnoreReal || isVolatile) {
381 Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.
getName() +
".real");
384 if (!IgnoreImag || isVolatile) {
386 Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.
getName() +
".imag");
418 llvm::Value *
U = llvm::UndefValue::get(EltTy);
425 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
431 return EmitLoadOfLValue(E);
437 CodeGenFunction::StmtExprEvaluation eval(CGF);
439 assert(RetAlloca.
isValid() &&
"Expected complex return value");
463ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
472 return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
478 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
482 case CK_AtomicToNonAtomic:
483 case CK_NonAtomicToAtomic:
485 case CK_LValueToRValue:
486 case CK_UserDefinedConversion:
489 case CK_LValueBitCast: {
492 V = Builder.CreateElementBitCast(
V, CGF.
ConvertType(DestTy));
496 case CK_LValueToRValueBitCast: {
502 return EmitLoadOfLValue(DestLV, Op->
getExprLoc());
506 case CK_BaseToDerived:
507 case CK_DerivedToBase:
508 case CK_UncheckedDerivedToBase:
511 case CK_ArrayToPointerDecay:
512 case CK_FunctionToPointerDecay:
513 case CK_NullToPointer:
514 case CK_NullToMemberPointer:
515 case CK_BaseToDerivedMemberPointer:
516 case CK_DerivedToBaseMemberPointer:
517 case CK_MemberPointerToBoolean:
518 case CK_ReinterpretMemberPointer:
519 case CK_ConstructorConversion:
520 case CK_IntegralToPointer:
521 case CK_PointerToIntegral:
522 case CK_PointerToBoolean:
525 case CK_IntegralCast:
526 case CK_BooleanToSignedIntegral:
527 case CK_IntegralToBoolean:
528 case CK_IntegralToFloating:
529 case CK_FloatingToIntegral:
530 case CK_FloatingToBoolean:
531 case CK_FloatingCast:
532 case CK_CPointerToObjCPointerCast:
533 case CK_BlockPointerToObjCPointerCast:
534 case CK_AnyPointerToBlockPointerCast:
535 case CK_ObjCObjectLValueCast:
536 case CK_FloatingComplexToReal:
537 case CK_FloatingComplexToBoolean:
538 case CK_IntegralComplexToReal:
539 case CK_IntegralComplexToBoolean:
540 case CK_ARCProduceObject:
541 case CK_ARCConsumeObject:
542 case CK_ARCReclaimReturnedObject:
543 case CK_ARCExtendBlockObject:
544 case CK_CopyAndAutoreleaseBlockObject:
545 case CK_BuiltinFnToFnPtr:
546 case CK_ZeroToOCLOpaqueType:
547 case CK_AddressSpaceConversion:
548 case CK_IntToOCLSampler:
549 case CK_FloatingToFixedPoint:
550 case CK_FixedPointToFloating:
551 case CK_FixedPointCast:
552 case CK_FixedPointToBoolean:
553 case CK_FixedPointToIntegral:
554 case CK_IntegralToFixedPoint:
556 llvm_unreachable(
"invalid cast kind for complex value");
558 case CK_FloatingRealToComplex:
559 case CK_IntegralRealToComplex: {
560 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
565 case CK_FloatingComplexCast:
566 case CK_FloatingComplexToIntegralComplex:
567 case CK_IntegralComplexCast:
568 case CK_IntegralComplexToFloatingComplex: {
569 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
570 return EmitComplexToComplexCast(Visit(Op), Op->
getType(), DestTy,
575 llvm_unreachable(
"unknown cast resulting in complex value");
584 if (!promotionTy.
isNull())
591 TestAndClearIgnoreReal();
592 TestAndClearIgnoreImag();
593 if (!PromotionType.
isNull())
604 if (!promotionTy.
isNull())
610 TestAndClearIgnoreReal();
611 TestAndClearIgnoreImag();
613 if (!PromotionType.
isNull())
618 llvm::Value *ResR, *ResI;
619 if (Op.first->getType()->isFloatingPointTy()) {
620 ResR = Builder.CreateFNeg(Op.first,
"neg.r");
621 ResI = Builder.CreateFNeg(Op.second,
"neg.i");
623 ResR = Builder.CreateNeg(Op.first,
"neg.r");
624 ResI = Builder.CreateNeg(Op.second,
"neg.i");
630 TestAndClearIgnoreReal();
631 TestAndClearIgnoreImag();
635 if (Op.second->getType()->isFloatingPointTy())
636 ResI = Builder.CreateFNeg(Op.second,
"conj.i");
638 ResI = Builder.CreateNeg(Op.second,
"conj.i");
643ComplexPairTy ComplexExprEmitter::EmitBinAdd(
const BinOpInfo &Op) {
644 llvm::Value *ResR, *ResI;
646 if (Op.LHS.first->getType()->isFloatingPointTy()) {
647 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
648 ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first,
"add.r");
649 if (Op.LHS.second && Op.RHS.second)
650 ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second,
"add.i");
652 ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;
653 assert(ResI &&
"Only one operand may be real!");
655 ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first,
"add.r");
656 assert(Op.LHS.second && Op.RHS.second &&
657 "Both operands of integer complex operators must be complex!");
658 ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second,
"add.i");
663ComplexPairTy ComplexExprEmitter::EmitBinSub(
const BinOpInfo &Op) {
664 llvm::Value *ResR, *ResI;
665 if (Op.LHS.first->getType()->isFloatingPointTy()) {
666 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
667 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first,
"sub.r");
668 if (Op.LHS.second && Op.RHS.second)
669 ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second,
"sub.i");
671 ResI = Op.LHS.second ? Op.LHS.second
672 : Builder.CreateFNeg(Op.RHS.second,
"sub.i");
673 assert(ResI &&
"Only one operand may be real!");
675 ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first,
"sub.r");
676 assert(Op.LHS.second && Op.RHS.second &&
677 "Both operands of integer complex operators must be complex!");
678 ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second,
"sub.i");
684ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
685 const BinOpInfo &Op) {
709 Args, cast<FunctionType>(FQTy.
getTypePtr()),
false);
713 FTy, LibCallName, llvm::AttributeList(),
true);
716 llvm::CallBase *
Call;
725 switch (Ty->getTypeID()) {
727 llvm_unreachable(
"Unsupported floating point type!");
728 case llvm::Type::HalfTyID:
730 case llvm::Type::FloatTyID:
732 case llvm::Type::DoubleTyID:
734 case llvm::Type::PPC_FP128TyID:
736 case llvm::Type::X86_FP80TyID:
738 case llvm::Type::FP128TyID:
745ComplexPairTy ComplexExprEmitter::EmitBinMul(
const BinOpInfo &Op) {
750 if (Op.LHS.first->getType()->isFloatingPointTy()) {
759 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
760 if (Op.LHS.second && Op.RHS.second) {
771 Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul_ac");
772 Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,
"mul_bd");
773 Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul_ad");
774 Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul_bc");
778 ResR = Builder.CreateFSub(AC, BD,
"mul_r");
779 ResI = Builder.CreateFAdd(AD, BC,
"mul_i");
783 Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR,
"isnan_cmp");
786 llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);
787 llvm::BasicBlock *OrigBB = Branch->getParent();
791 llvm::MDNode *BrWeight = MDHelper.createBranchWeights(1, (1U << 20) - 1);
792 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
796 Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI,
"isnan_cmp");
798 Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);
799 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
803 Value *LibCallR, *LibCallI;
804 std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
806 Builder.CreateBr(ContBB);
811 llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3,
"real_mul_phi");
812 RealPHI->addIncoming(ResR, OrigBB);
813 RealPHI->addIncoming(ResR, INaNBB);
814 RealPHI->addIncoming(LibCallR, LibCallBB);
815 llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3,
"imag_mul_phi");
816 ImagPHI->addIncoming(ResI, OrigBB);
817 ImagPHI->addIncoming(ResI, INaNBB);
818 ImagPHI->addIncoming(LibCallI, LibCallBB);
821 assert((Op.LHS.second || Op.RHS.second) &&
822 "At least one operand must be complex!");
827 ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
830 ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul.il")
831 : Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
833 assert(Op.LHS.second && Op.RHS.second &&
834 "Both operands of integer complex operators must be complex!");
835 Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
836 Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,
"mul.rr");
837 ResR = Builder.CreateSub(ResRl, ResRr,
"mul.r");
839 Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first,
"mul.il");
840 Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
841 ResI = Builder.CreateAdd(ResIl, ResIr,
"mul.i");
848ComplexPairTy ComplexExprEmitter::EmitBinDiv(
const BinOpInfo &Op) {
849 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
850 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
852 llvm::Value *DSTr, *DSTi;
853 if (LHSr->getType()->isFloatingPointTy()) {
861 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
863 BinOpInfo LibCallOp = Op;
866 LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());
868 switch (LHSr->getType()->getTypeID()) {
870 llvm_unreachable(
"Unsupported floating point type!");
871 case llvm::Type::HalfTyID:
872 return EmitComplexBinOpLibCall(
"__divhc3", LibCallOp);
873 case llvm::Type::FloatTyID:
874 return EmitComplexBinOpLibCall(
"__divsc3", LibCallOp);
875 case llvm::Type::DoubleTyID:
876 return EmitComplexBinOpLibCall(
"__divdc3", LibCallOp);
877 case llvm::Type::PPC_FP128TyID:
878 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
879 case llvm::Type::X86_FP80TyID:
880 return EmitComplexBinOpLibCall(
"__divxc3", LibCallOp);
881 case llvm::Type::FP128TyID:
882 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
886 LHSi = llvm::Constant::getNullValue(RHSi->getType());
889 llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr);
890 llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi);
891 llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD);
893 llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr);
894 llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi);
895 llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD);
897 llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr);
898 llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi);
899 llvm::Value *BCmAD = Builder.CreateFSub(BC, AD);
901 DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
902 DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
904 assert(LHSi &&
"Can have at most one non-complex operand!");
906 DSTr = Builder.CreateFDiv(LHSr, RHSr);
907 DSTi = Builder.CreateFDiv(LHSi, RHSr);
910 assert(Op.LHS.second && Op.RHS.second &&
911 "Both operands of integer complex operators must be complex!");
913 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr);
914 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi);
915 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2);
917 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr);
918 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi);
919 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5);
921 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr);
922 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi);
923 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8);
926 DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
927 DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
929 DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
930 DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
939 llvm::Type *ComplexElementTy =
943 Builder.CreateFPTrunc(result.first, ComplexElementTy,
"unpromotion");
946 Builder.CreateFPTrunc(result.second, ComplexElementTy,
"unpromotion");
952 llvm::Type *ComplexElementTy =
955 result.first =
Builder.CreateFPExt(result.first, ComplexElementTy,
"ext");
957 result.second =
Builder.CreateFPExt(result.second, ComplexElementTy,
"ext");
965 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
966 switch (BO->getOpcode()) {
967#define HANDLE_BINOP(OP) \
969 return EmitBin##OP(EmitBinOps(BO, PromotionType));
978 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
979 switch (UO->getOpcode()) {
981 return VisitMinus(UO, PromotionType);
983 return VisitPlus(UO, PromotionType);
988 auto result = Visit(
const_cast<Expr *
>(E));
989 if (!PromotionType.
isNull())
997 return ComplexExprEmitter(*this).EmitPromoted(E, DstTy);
1001ComplexExprEmitter::EmitPromotedComplexOperand(
const Expr *E,
1004 if (!OverallPromotionType.
isNull())
1007 return Visit(
const_cast<Expr *
>(E));
1009 if (!OverallPromotionType.
isNull()) {
1020ComplexExprEmitter::BinOpInfo
1023 TestAndClearIgnoreReal();
1024 TestAndClearIgnoreImag();
1027 Ops.LHS = EmitPromotedComplexOperand(E->
getLHS(), PromotionType);
1028 Ops.RHS = EmitPromotedComplexOperand(E->
getRHS(), PromotionType);
1029 if (!PromotionType.
isNull())
1030 Ops.Ty = PromotionType;
1038LValue ComplexExprEmitter::
1040 ComplexPairTy (ComplexExprEmitter::*Func)(
const BinOpInfo&),
1042 TestAndClearIgnoreReal();
1043 TestAndClearIgnoreImag();
1046 LHSTy = AT->getValueType();
1050 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
1057 if (PromotionTypeCR.
isNull())
1059 OpInfo.Ty = PromotionTypeCR;
1066 if (!PromotionTypeRHS.
isNull())
1076 if (!PromotionTypeRHS.
isNull()) {
1082 OpInfo.RHS = Visit(E->
getRHS());
1093 if (!PromotionTypeLHS.
isNull())
1095 EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc);
1097 OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1104 if (!PromotionTypeLHS.
isNull()) {
1105 PromotedComplexElementTy =
1106 cast<ComplexType>(PromotionTypeLHS)->getElementType();
1110 PromotedComplexElementTy, Loc);
1118 OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1128 EmitComplexToComplexCast(
Result, OpInfo.Ty, LHSTy, Loc);
1129 EmitStoreOfComplex(ResVal, LHS,
false);
1132 llvm::Value *ResVal =
1144 ComplexPairTy (ComplexExprEmitter::*Func)(
const BinOpInfo&)){
1146 LValue LV = EmitCompoundAssignLValue(E, Func, Val);
1156 return EmitLoadOfLValue(LV, E->
getExprLoc());
1163 "Invalid assignment");
1164 TestAndClearIgnoreReal();
1165 TestAndClearIgnoreImag();
1168 Val = Visit(E->
getRHS());
1174 EmitStoreOfComplex(Val, LHS,
false);
1181 LValue LV = EmitBinAssignLValue(E, Val);
1191 return EmitLoadOfLValue(LV, E->
getExprLoc());
1196 return Visit(E->
getRHS());
1201 TestAndClearIgnoreReal();
1202 TestAndClearIgnoreImag();
1208 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
1211 CodeGenFunction::ConditionalEvaluation eval(CGF);
1219 LHSBlock = Builder.GetInsertBlock();
1226 RHSBlock = Builder.GetInsertBlock();
1231 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.r");
1232 RealPN->addIncoming(LHS.first, LHSBlock);
1233 RealPN->addIncoming(RHS.first, RHSBlock);
1236 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.i");
1237 ImagPN->addIncoming(LHS.second, LHSBlock);
1238 ImagPN->addIncoming(RHS.second, RHSBlock);
1248 bool Ignore = TestAndClearIgnoreReal();
1250 assert (Ignore ==
false &&
"init list ignored");
1251 Ignore = TestAndClearIgnoreImag();
1253 assert (Ignore ==
false &&
"init list ignored");
1264 assert(E->
getNumInits() == 0 &&
"Unexpected number of inits");
1267 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
1279 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1296 "Invalid complex expression to emit");
1298 return ComplexExprEmitter(*
this, IgnoreReal, IgnoreImag)
1299 .Visit(
const_cast<Expr *
>(E));
1305 "Invalid complex expression to emit");
1306 ComplexExprEmitter
Emitter(*
this);
1308 Emitter.EmitStoreOfComplex(Val, dest, isInit);
1314 ComplexExprEmitter(*this).EmitStoreOfComplex(
V, dest, isInit);
1320 return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
1326 LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
1334 const ComplexExprEmitter::BinOpInfo &);
1338 case BO_MulAssign:
return &ComplexExprEmitter::EmitBinMul;
1339 case BO_DivAssign:
return &ComplexExprEmitter::EmitBinDiv;
1340 case BO_SubAssign:
return &ComplexExprEmitter::EmitBinSub;
1341 case BO_AddAssign:
return &ComplexExprEmitter::EmitBinAdd;
1343 llvm_unreachable(
"unexpected complex compound assignment");
1351 return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
1359 LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
ComplexPairTy(ComplexExprEmitter::* CompoundFunc)(const ComplexExprEmitter::BinOpInfo &)
static const ComplexType * getComplexType(QualType type)
Return the complex type that we are meant to emit.
CodeGenFunction::ComplexPairTy ComplexPairTy
static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty)
Lookup the libcall name for a given floating point type complex multiply.
static CompoundFunc getComplexOp(BinaryOperatorKind Op)
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getTrueExpr() const
Expr * getFalseExpr() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
SourceLocation getExprLoc() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
A rewritten comparison expression that was originally written using operator syntax.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Represents a 'co_await' expression.
llvm::StringRef getName() const
Return the IR name of the pointer value.
A scoped helper to set the current debug location to the specified location or preferred location of ...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
ComplexPairTy EmitPromotedComplexExpr(const Expr *E, QualType PromotionType)
ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
LValue EmitComplexAssignmentLValue(const BinaryOperator *E)
Emit an l-value for an assignment (simple or compound) of complex type.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
Address emitAddrOfImagComponent(Address complex, QualType complexType)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
ASTContext & getContext() const
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...
ComplexPairTy EmitUnPromotedValue(ComplexPairTy result, QualType PromotionType)
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
llvm::Type * ConvertType(QualType T)
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr)
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
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...
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot())
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
bool LValueIsSuitableForInlineAtomic(LValue Src)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
Address emitAddrOfRealComponent(Address complex, QualType complexType)
LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
RValue EmitAtomicExpr(AtomicExpr *E)
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenTypes & getTypes()
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
Figure out the rules for calling a function with the given formal type using the given arguments.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
void setTBAAInfo(TBAAAccessInfo Info)
Address getAddress(CodeGenFunction &CGF) const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
CompoundLiteralExpr - [C99 6.5.2.5].
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Represents a 'co_yield' expression.
A reference to a declared variable, function, enum, etc.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const Expr * getSubExpr() const
Represents a prototype with parameter type info, e.g.
Represents a C11 generic selection.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
unsigned getNumInits() const
const Expr * getInit(unsigned Init) const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
SourceLocation getExprLoc() const LLVM_READONLY
ParenExpr - This represents a parethesized expression, e.g.
const Expr * getSubExpr() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool UseExcessPrecision(const ASTContext &Ctx)
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
CompoundStmt * getSubStmt()
RetTy Visit(PTR(Stmt) S, ParamTys... P)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isAnyComplexType() const
bool isAtomicType() const
bool isRealFloatingType() const
Floating point categories.
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a call to the builtin function __builtin_va_arg.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ComplexType > complexType
Matches C99 complex types.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
bool Null(InterpState &S, CodePtr OpPC)
bool Call(InterpState &S, CodePtr &PC, const Function *Func)
bool GE(InterpState &S, CodePtr OpPC)
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
@ EST_BasicNoexcept
noexcept
llvm::CallingConv::ID getRuntimeCC() const
static TBAAAccessInfo getMayAliasInfo()
Holds information about the various types of exception specification.
Extra information about a function prototype.
ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI)