1f22ef01cSRoman Divacky //===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky // 10f22ef01cSRoman Divacky // This contains code to emit Expr nodes with complex types as LLVM code. 11f22ef01cSRoman Divacky // 12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 13f22ef01cSRoman Divacky 14f22ef01cSRoman Divacky #include "CodeGenFunction.h" 15f22ef01cSRoman Divacky #include "CodeGenModule.h" 16f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h" 17f22ef01cSRoman Divacky #include "clang/AST/StmtVisitor.h" 18f22ef01cSRoman Divacky #include "llvm/Constants.h" 19f22ef01cSRoman Divacky #include "llvm/Function.h" 20f22ef01cSRoman Divacky #include "llvm/ADT/SmallString.h" 21f22ef01cSRoman Divacky using namespace clang; 22f22ef01cSRoman Divacky using namespace CodeGen; 23f22ef01cSRoman Divacky 24f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 25f22ef01cSRoman Divacky // Complex Expression Emitter 26f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 27f22ef01cSRoman Divacky 28f22ef01cSRoman Divacky typedef CodeGenFunction::ComplexPairTy ComplexPairTy; 29f22ef01cSRoman Divacky 30f22ef01cSRoman Divacky namespace { 31f22ef01cSRoman Divacky class ComplexExprEmitter 32f22ef01cSRoman Divacky : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { 33f22ef01cSRoman Divacky CodeGenFunction &CGF; 34f22ef01cSRoman Divacky CGBuilderTy &Builder; 35f22ef01cSRoman Divacky // True is we should ignore the value of a 36f22ef01cSRoman Divacky bool IgnoreReal; 37f22ef01cSRoman Divacky bool IgnoreImag; 38f22ef01cSRoman Divacky public: 392754fe60SDimitry Andric ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false) 402754fe60SDimitry Andric : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) { 41f22ef01cSRoman Divacky } 42f22ef01cSRoman Divacky 43f22ef01cSRoman Divacky 44f22ef01cSRoman Divacky //===--------------------------------------------------------------------===// 45f22ef01cSRoman Divacky // Utilities 46f22ef01cSRoman Divacky //===--------------------------------------------------------------------===// 47f22ef01cSRoman Divacky 48f22ef01cSRoman Divacky bool TestAndClearIgnoreReal() { 49f22ef01cSRoman Divacky bool I = IgnoreReal; 50f22ef01cSRoman Divacky IgnoreReal = false; 51f22ef01cSRoman Divacky return I; 52f22ef01cSRoman Divacky } 53f22ef01cSRoman Divacky bool TestAndClearIgnoreImag() { 54f22ef01cSRoman Divacky bool I = IgnoreImag; 55f22ef01cSRoman Divacky IgnoreImag = false; 56f22ef01cSRoman Divacky return I; 57f22ef01cSRoman Divacky } 58f22ef01cSRoman Divacky 59f22ef01cSRoman Divacky /// EmitLoadOfLValue - Given an expression with complex type that represents a 60f22ef01cSRoman Divacky /// value l-value, this method emits the address of the l-value, then loads 61f22ef01cSRoman Divacky /// and returns the result. 62f22ef01cSRoman Divacky ComplexPairTy EmitLoadOfLValue(const Expr *E) { 632754fe60SDimitry Andric return EmitLoadOfLValue(CGF.EmitLValue(E)); 642754fe60SDimitry Andric } 652754fe60SDimitry Andric 662754fe60SDimitry Andric ComplexPairTy EmitLoadOfLValue(LValue LV) { 67dff0c46cSDimitry Andric assert(LV.isSimple() && "complex l-value must be simple"); 68f22ef01cSRoman Divacky return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); 69f22ef01cSRoman Divacky } 70f22ef01cSRoman Divacky 71f22ef01cSRoman Divacky /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load 72f22ef01cSRoman Divacky /// the real and imaginary pieces. 73f22ef01cSRoman Divacky ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile); 74f22ef01cSRoman Divacky 752754fe60SDimitry Andric /// EmitStoreThroughLValue - Given an l-value of complex type, store 762754fe60SDimitry Andric /// a complex number into it. 772754fe60SDimitry Andric void EmitStoreThroughLValue(ComplexPairTy Val, LValue LV) { 78dff0c46cSDimitry Andric assert(LV.isSimple() && "complex l-value must be simple"); 792754fe60SDimitry Andric return EmitStoreOfComplex(Val, LV.getAddress(), LV.isVolatileQualified()); 802754fe60SDimitry Andric } 812754fe60SDimitry Andric 82f22ef01cSRoman Divacky /// EmitStoreOfComplex - Store the specified real/imag parts into the 83f22ef01cSRoman Divacky /// specified value pointer. 84f22ef01cSRoman Divacky void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol); 85f22ef01cSRoman Divacky 86f22ef01cSRoman Divacky /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. 87f22ef01cSRoman Divacky ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, 88f22ef01cSRoman Divacky QualType DestType); 89f22ef01cSRoman Divacky 90f22ef01cSRoman Divacky //===--------------------------------------------------------------------===// 91f22ef01cSRoman Divacky // Visitor Methods 92f22ef01cSRoman Divacky //===--------------------------------------------------------------------===// 93f22ef01cSRoman Divacky 942754fe60SDimitry Andric ComplexPairTy Visit(Expr *E) { 952754fe60SDimitry Andric return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E); 962754fe60SDimitry Andric } 972754fe60SDimitry Andric 98f22ef01cSRoman Divacky ComplexPairTy VisitStmt(Stmt *S) { 99f22ef01cSRoman Divacky S->dump(CGF.getContext().getSourceManager()); 1006122f3e6SDimitry Andric llvm_unreachable("Stmt can't have complex result type!"); 101f22ef01cSRoman Divacky } 102f22ef01cSRoman Divacky ComplexPairTy VisitExpr(Expr *S); 103f22ef01cSRoman Divacky ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} 1043b0f4066SDimitry Andric ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { 1053b0f4066SDimitry Andric return Visit(GE->getResultExpr()); 1063b0f4066SDimitry Andric } 107f22ef01cSRoman Divacky ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL); 10817a519f9SDimitry Andric ComplexPairTy 10917a519f9SDimitry Andric VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) { 11017a519f9SDimitry Andric return Visit(PE->getReplacement()); 11117a519f9SDimitry Andric } 112f22ef01cSRoman Divacky 113f22ef01cSRoman Divacky // l-values. 114dff0c46cSDimitry Andric ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) { 115dff0c46cSDimitry Andric if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) { 116dff0c46cSDimitry Andric if (result.isReference()) 117dff0c46cSDimitry Andric return EmitLoadOfLValue(result.getReferenceLValue(CGF, E)); 118dff0c46cSDimitry Andric 119dff0c46cSDimitry Andric llvm::ConstantStruct *pair = 120dff0c46cSDimitry Andric cast<llvm::ConstantStruct>(result.getValue()); 121dff0c46cSDimitry Andric return ComplexPairTy(pair->getOperand(0), pair->getOperand(1)); 122dff0c46cSDimitry Andric } 123f22ef01cSRoman Divacky return EmitLoadOfLValue(E); 124f22ef01cSRoman Divacky } 125dff0c46cSDimitry Andric ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 126f22ef01cSRoman Divacky return EmitLoadOfLValue(E); 127f22ef01cSRoman Divacky } 128f22ef01cSRoman Divacky ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { 129f22ef01cSRoman Divacky return CGF.EmitObjCMessageExpr(E).getComplexVal(); 130f22ef01cSRoman Divacky } 131f22ef01cSRoman Divacky ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } 132f22ef01cSRoman Divacky ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); } 1332754fe60SDimitry Andric ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) { 1342754fe60SDimitry Andric if (E->isGLValue()) 1352754fe60SDimitry Andric return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E)); 1362754fe60SDimitry Andric return CGF.getOpaqueRValueMapping(E).getComplexVal(); 1372754fe60SDimitry Andric } 138f22ef01cSRoman Divacky 139dff0c46cSDimitry Andric ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) { 140dff0c46cSDimitry Andric return CGF.EmitPseudoObjectRValue(E).getComplexVal(); 141dff0c46cSDimitry Andric } 142dff0c46cSDimitry Andric 143f22ef01cSRoman Divacky // FIXME: CompoundLiteralExpr 144f22ef01cSRoman Divacky 145ffd1746dSEd Schouten ComplexPairTy EmitCast(CastExpr::CastKind CK, Expr *Op, QualType DestTy); 146f22ef01cSRoman Divacky ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { 147f22ef01cSRoman Divacky // Unlike for scalars, we don't have to worry about function->ptr demotion 148f22ef01cSRoman Divacky // here. 149ffd1746dSEd Schouten return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 150f22ef01cSRoman Divacky } 151f22ef01cSRoman Divacky ComplexPairTy VisitCastExpr(CastExpr *E) { 152ffd1746dSEd Schouten return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 153f22ef01cSRoman Divacky } 154f22ef01cSRoman Divacky ComplexPairTy VisitCallExpr(const CallExpr *E); 155f22ef01cSRoman Divacky ComplexPairTy VisitStmtExpr(const StmtExpr *E); 156f22ef01cSRoman Divacky 157f22ef01cSRoman Divacky // Operators. 158f22ef01cSRoman Divacky ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, 159f22ef01cSRoman Divacky bool isInc, bool isPre) { 160f22ef01cSRoman Divacky LValue LV = CGF.EmitLValue(E->getSubExpr()); 161f22ef01cSRoman Divacky return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre); 162f22ef01cSRoman Divacky } 163f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) { 164f22ef01cSRoman Divacky return VisitPrePostIncDec(E, false, false); 165f22ef01cSRoman Divacky } 166f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) { 167f22ef01cSRoman Divacky return VisitPrePostIncDec(E, true, false); 168f22ef01cSRoman Divacky } 169f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) { 170f22ef01cSRoman Divacky return VisitPrePostIncDec(E, false, true); 171f22ef01cSRoman Divacky } 172f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) { 173f22ef01cSRoman Divacky return VisitPrePostIncDec(E, true, true); 174f22ef01cSRoman Divacky } 175f22ef01cSRoman Divacky ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } 176f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) { 177f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 178f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 179f22ef01cSRoman Divacky return Visit(E->getSubExpr()); 180f22ef01cSRoman Divacky } 181f22ef01cSRoman Divacky ComplexPairTy VisitUnaryMinus (const UnaryOperator *E); 182f22ef01cSRoman Divacky ComplexPairTy VisitUnaryNot (const UnaryOperator *E); 183f22ef01cSRoman Divacky // LNot,Real,Imag never return complex. 184f22ef01cSRoman Divacky ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { 185f22ef01cSRoman Divacky return Visit(E->getSubExpr()); 186f22ef01cSRoman Divacky } 187f22ef01cSRoman Divacky ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { 188f22ef01cSRoman Divacky return Visit(DAE->getExpr()); 189f22ef01cSRoman Divacky } 1902754fe60SDimitry Andric ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) { 191dff0c46cSDimitry Andric CGF.enterFullExpression(E); 192dff0c46cSDimitry Andric CodeGenFunction::RunCleanupsScope Scope(CGF); 193dff0c46cSDimitry Andric return Visit(E->getSubExpr()); 194f22ef01cSRoman Divacky } 195ffd1746dSEd Schouten ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 196f22ef01cSRoman Divacky assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 197f22ef01cSRoman Divacky QualType Elem = E->getType()->getAs<ComplexType>()->getElementType(); 198f22ef01cSRoman Divacky llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 199f22ef01cSRoman Divacky return ComplexPairTy(Null, Null); 200f22ef01cSRoman Divacky } 201f22ef01cSRoman Divacky ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { 202f22ef01cSRoman Divacky assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 203f22ef01cSRoman Divacky QualType Elem = E->getType()->getAs<ComplexType>()->getElementType(); 204f22ef01cSRoman Divacky llvm::Constant *Null = 205f22ef01cSRoman Divacky llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 206f22ef01cSRoman Divacky return ComplexPairTy(Null, Null); 207f22ef01cSRoman Divacky } 208f22ef01cSRoman Divacky 209f22ef01cSRoman Divacky struct BinOpInfo { 210f22ef01cSRoman Divacky ComplexPairTy LHS; 211f22ef01cSRoman Divacky ComplexPairTy RHS; 212f22ef01cSRoman Divacky QualType Ty; // Computation Type. 213f22ef01cSRoman Divacky }; 214f22ef01cSRoman Divacky 215f22ef01cSRoman Divacky BinOpInfo EmitBinOps(const BinaryOperator *E); 2162754fe60SDimitry Andric LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, 2172754fe60SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func) 2182754fe60SDimitry Andric (const BinOpInfo &), 2192754fe60SDimitry Andric ComplexPairTy &Val); 220f22ef01cSRoman Divacky ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E, 221f22ef01cSRoman Divacky ComplexPairTy (ComplexExprEmitter::*Func) 222f22ef01cSRoman Divacky (const BinOpInfo &)); 223f22ef01cSRoman Divacky 224f22ef01cSRoman Divacky ComplexPairTy EmitBinAdd(const BinOpInfo &Op); 225f22ef01cSRoman Divacky ComplexPairTy EmitBinSub(const BinOpInfo &Op); 226f22ef01cSRoman Divacky ComplexPairTy EmitBinMul(const BinOpInfo &Op); 227f22ef01cSRoman Divacky ComplexPairTy EmitBinDiv(const BinOpInfo &Op); 228f22ef01cSRoman Divacky 229f22ef01cSRoman Divacky ComplexPairTy VisitBinAdd(const BinaryOperator *E) { 230f22ef01cSRoman Divacky return EmitBinAdd(EmitBinOps(E)); 231f22ef01cSRoman Divacky } 232f22ef01cSRoman Divacky ComplexPairTy VisitBinSub(const BinaryOperator *E) { 233f22ef01cSRoman Divacky return EmitBinSub(EmitBinOps(E)); 234f22ef01cSRoman Divacky } 2352754fe60SDimitry Andric ComplexPairTy VisitBinMul(const BinaryOperator *E) { 2362754fe60SDimitry Andric return EmitBinMul(EmitBinOps(E)); 2372754fe60SDimitry Andric } 238f22ef01cSRoman Divacky ComplexPairTy VisitBinDiv(const BinaryOperator *E) { 239f22ef01cSRoman Divacky return EmitBinDiv(EmitBinOps(E)); 240f22ef01cSRoman Divacky } 241f22ef01cSRoman Divacky 242f22ef01cSRoman Divacky // Compound assignments. 243f22ef01cSRoman Divacky ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) { 244f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd); 245f22ef01cSRoman Divacky } 246f22ef01cSRoman Divacky ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) { 247f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub); 248f22ef01cSRoman Divacky } 249f22ef01cSRoman Divacky ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) { 250f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul); 251f22ef01cSRoman Divacky } 252f22ef01cSRoman Divacky ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) { 253f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv); 254f22ef01cSRoman Divacky } 255f22ef01cSRoman Divacky 256f22ef01cSRoman Divacky // GCC rejects rem/and/or/xor for integer complex. 257f22ef01cSRoman Divacky // Logical and/or always return int, never complex. 258f22ef01cSRoman Divacky 259f22ef01cSRoman Divacky // No comparisons produce a complex result. 2602754fe60SDimitry Andric 2612754fe60SDimitry Andric LValue EmitBinAssignLValue(const BinaryOperator *E, 2622754fe60SDimitry Andric ComplexPairTy &Val); 263f22ef01cSRoman Divacky ComplexPairTy VisitBinAssign (const BinaryOperator *E); 264f22ef01cSRoman Divacky ComplexPairTy VisitBinComma (const BinaryOperator *E); 265f22ef01cSRoman Divacky 266f22ef01cSRoman Divacky 2672754fe60SDimitry Andric ComplexPairTy 2682754fe60SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); 269f22ef01cSRoman Divacky ComplexPairTy VisitChooseExpr(ChooseExpr *CE); 270f22ef01cSRoman Divacky 271f22ef01cSRoman Divacky ComplexPairTy VisitInitListExpr(InitListExpr *E); 272f22ef01cSRoman Divacky 273dff0c46cSDimitry Andric ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 274dff0c46cSDimitry Andric return EmitLoadOfLValue(E); 275dff0c46cSDimitry Andric } 276dff0c46cSDimitry Andric 277f22ef01cSRoman Divacky ComplexPairTy VisitVAArgExpr(VAArgExpr *E); 2786122f3e6SDimitry Andric 2796122f3e6SDimitry Andric ComplexPairTy VisitAtomicExpr(AtomicExpr *E) { 2806122f3e6SDimitry Andric return CGF.EmitAtomicExpr(E).getComplexVal(); 2816122f3e6SDimitry Andric } 282f22ef01cSRoman Divacky }; 283f22ef01cSRoman Divacky } // end anonymous namespace. 284f22ef01cSRoman Divacky 285f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 286f22ef01cSRoman Divacky // Utilities 287f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 288f22ef01cSRoman Divacky 289f22ef01cSRoman Divacky /// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to 290f22ef01cSRoman Divacky /// load the real and imaginary pieces, returning them as Real/Imag. 291f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr, 292f22ef01cSRoman Divacky bool isVolatile) { 293f22ef01cSRoman Divacky llvm::Value *Real=0, *Imag=0; 294f22ef01cSRoman Divacky 2952754fe60SDimitry Andric if (!IgnoreReal || isVolatile) { 296f22ef01cSRoman Divacky llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0, 297f22ef01cSRoman Divacky SrcPtr->getName() + ".realp"); 298f22ef01cSRoman Divacky Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr->getName() + ".real"); 299f22ef01cSRoman Divacky } 300f22ef01cSRoman Divacky 3012754fe60SDimitry Andric if (!IgnoreImag || isVolatile) { 302f22ef01cSRoman Divacky llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1, 303f22ef01cSRoman Divacky SrcPtr->getName() + ".imagp"); 304f22ef01cSRoman Divacky Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr->getName() + ".imag"); 305f22ef01cSRoman Divacky } 306f22ef01cSRoman Divacky return ComplexPairTy(Real, Imag); 307f22ef01cSRoman Divacky } 308f22ef01cSRoman Divacky 309f22ef01cSRoman Divacky /// EmitStoreOfComplex - Store the specified real/imag parts into the 310f22ef01cSRoman Divacky /// specified value pointer. 311f22ef01cSRoman Divacky void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr, 312f22ef01cSRoman Divacky bool isVolatile) { 313f22ef01cSRoman Divacky llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real"); 314f22ef01cSRoman Divacky llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag"); 315f22ef01cSRoman Divacky 316f22ef01cSRoman Divacky Builder.CreateStore(Val.first, RealPtr, isVolatile); 317f22ef01cSRoman Divacky Builder.CreateStore(Val.second, ImagPtr, isVolatile); 318f22ef01cSRoman Divacky } 319f22ef01cSRoman Divacky 320f22ef01cSRoman Divacky 321f22ef01cSRoman Divacky 322f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 323f22ef01cSRoman Divacky // Visitor Methods 324f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 325f22ef01cSRoman Divacky 326f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { 327f22ef01cSRoman Divacky CGF.ErrorUnsupported(E, "complex expression"); 3286122f3e6SDimitry Andric llvm::Type *EltTy = 329f22ef01cSRoman Divacky CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType()); 330f22ef01cSRoman Divacky llvm::Value *U = llvm::UndefValue::get(EltTy); 331f22ef01cSRoman Divacky return ComplexPairTy(U, U); 332f22ef01cSRoman Divacky } 333f22ef01cSRoman Divacky 334f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter:: 335f22ef01cSRoman Divacky VisitImaginaryLiteral(const ImaginaryLiteral *IL) { 336f22ef01cSRoman Divacky llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr()); 3372754fe60SDimitry Andric return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag); 338f22ef01cSRoman Divacky } 339f22ef01cSRoman Divacky 340f22ef01cSRoman Divacky 341f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { 342f22ef01cSRoman Divacky if (E->getCallReturnType()->isReferenceType()) 343f22ef01cSRoman Divacky return EmitLoadOfLValue(E); 344f22ef01cSRoman Divacky 345f22ef01cSRoman Divacky return CGF.EmitCallExpr(E).getComplexVal(); 346f22ef01cSRoman Divacky } 347f22ef01cSRoman Divacky 348f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) { 3492754fe60SDimitry Andric CodeGenFunction::StmtExprEvaluation eval(CGF); 350f22ef01cSRoman Divacky return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal(); 351f22ef01cSRoman Divacky } 352f22ef01cSRoman Divacky 353f22ef01cSRoman Divacky /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. 354f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, 355f22ef01cSRoman Divacky QualType SrcType, 356f22ef01cSRoman Divacky QualType DestType) { 357f22ef01cSRoman Divacky // Get the src/dest element type. 358f22ef01cSRoman Divacky SrcType = SrcType->getAs<ComplexType>()->getElementType(); 359f22ef01cSRoman Divacky DestType = DestType->getAs<ComplexType>()->getElementType(); 360f22ef01cSRoman Divacky 361f22ef01cSRoman Divacky // C99 6.3.1.6: When a value of complex type is converted to another 362f22ef01cSRoman Divacky // complex type, both the real and imaginary parts follow the conversion 363f22ef01cSRoman Divacky // rules for the corresponding real types. 364f22ef01cSRoman Divacky Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType); 365f22ef01cSRoman Divacky Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType); 366f22ef01cSRoman Divacky return Val; 367f22ef01cSRoman Divacky } 368f22ef01cSRoman Divacky 369ffd1746dSEd Schouten ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op, 370ffd1746dSEd Schouten QualType DestTy) { 3712754fe60SDimitry Andric switch (CK) { 37217a519f9SDimitry Andric case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); 37317a519f9SDimitry Andric 374dff0c46cSDimitry Andric // Atomic to non-atomic casts may be more than a no-op for some platforms and 375dff0c46cSDimitry Andric // for some types. 376dff0c46cSDimitry Andric case CK_AtomicToNonAtomic: 377dff0c46cSDimitry Andric case CK_NonAtomicToAtomic: 3782754fe60SDimitry Andric case CK_NoOp: 3792754fe60SDimitry Andric case CK_LValueToRValue: 38017a519f9SDimitry Andric case CK_UserDefinedConversion: 3812754fe60SDimitry Andric return Visit(Op); 3822754fe60SDimitry Andric 38317a519f9SDimitry Andric case CK_LValueBitCast: { 384ffd1746dSEd Schouten llvm::Value *V = CGF.EmitLValue(Op).getAddress(); 385ffd1746dSEd Schouten V = Builder.CreateBitCast(V, 386ffd1746dSEd Schouten CGF.ConvertType(CGF.getContext().getPointerType(DestTy))); 387ffd1746dSEd Schouten // FIXME: Are the qualifiers correct here? 388ffd1746dSEd Schouten return EmitLoadOfComplex(V, DestTy.isVolatileQualified()); 389ffd1746dSEd Schouten } 390ffd1746dSEd Schouten 39117a519f9SDimitry Andric case CK_BitCast: 39217a519f9SDimitry Andric case CK_BaseToDerived: 39317a519f9SDimitry Andric case CK_DerivedToBase: 39417a519f9SDimitry Andric case CK_UncheckedDerivedToBase: 39517a519f9SDimitry Andric case CK_Dynamic: 39617a519f9SDimitry Andric case CK_ToUnion: 39717a519f9SDimitry Andric case CK_ArrayToPointerDecay: 39817a519f9SDimitry Andric case CK_FunctionToPointerDecay: 39917a519f9SDimitry Andric case CK_NullToPointer: 40017a519f9SDimitry Andric case CK_NullToMemberPointer: 40117a519f9SDimitry Andric case CK_BaseToDerivedMemberPointer: 40217a519f9SDimitry Andric case CK_DerivedToBaseMemberPointer: 40317a519f9SDimitry Andric case CK_MemberPointerToBoolean: 404dff0c46cSDimitry Andric case CK_ReinterpretMemberPointer: 40517a519f9SDimitry Andric case CK_ConstructorConversion: 40617a519f9SDimitry Andric case CK_IntegralToPointer: 40717a519f9SDimitry Andric case CK_PointerToIntegral: 40817a519f9SDimitry Andric case CK_PointerToBoolean: 40917a519f9SDimitry Andric case CK_ToVoid: 41017a519f9SDimitry Andric case CK_VectorSplat: 41117a519f9SDimitry Andric case CK_IntegralCast: 41217a519f9SDimitry Andric case CK_IntegralToBoolean: 41317a519f9SDimitry Andric case CK_IntegralToFloating: 41417a519f9SDimitry Andric case CK_FloatingToIntegral: 41517a519f9SDimitry Andric case CK_FloatingToBoolean: 41617a519f9SDimitry Andric case CK_FloatingCast: 4176122f3e6SDimitry Andric case CK_CPointerToObjCPointerCast: 4186122f3e6SDimitry Andric case CK_BlockPointerToObjCPointerCast: 41917a519f9SDimitry Andric case CK_AnyPointerToBlockPointerCast: 42017a519f9SDimitry Andric case CK_ObjCObjectLValueCast: 42117a519f9SDimitry Andric case CK_FloatingComplexToReal: 42217a519f9SDimitry Andric case CK_FloatingComplexToBoolean: 42317a519f9SDimitry Andric case CK_IntegralComplexToReal: 42417a519f9SDimitry Andric case CK_IntegralComplexToBoolean: 4256122f3e6SDimitry Andric case CK_ARCProduceObject: 4266122f3e6SDimitry Andric case CK_ARCConsumeObject: 4276122f3e6SDimitry Andric case CK_ARCReclaimReturnedObject: 4286122f3e6SDimitry Andric case CK_ARCExtendBlockObject: 429dff0c46cSDimitry Andric case CK_CopyAndAutoreleaseBlockObject: 43017a519f9SDimitry Andric llvm_unreachable("invalid cast kind for complex value"); 43117a519f9SDimitry Andric 43217a519f9SDimitry Andric case CK_FloatingRealToComplex: 43317a519f9SDimitry Andric case CK_IntegralRealToComplex: { 434f22ef01cSRoman Divacky llvm::Value *Elt = CGF.EmitScalarExpr(Op); 435f22ef01cSRoman Divacky 436f22ef01cSRoman Divacky // Convert the input element to the element type of the complex. 437f22ef01cSRoman Divacky DestTy = DestTy->getAs<ComplexType>()->getElementType(); 438f22ef01cSRoman Divacky Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy); 439f22ef01cSRoman Divacky 440f22ef01cSRoman Divacky // Return (realval, 0). 441f22ef01cSRoman Divacky return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType())); 442f22ef01cSRoman Divacky } 443f22ef01cSRoman Divacky 44417a519f9SDimitry Andric case CK_FloatingComplexCast: 44517a519f9SDimitry Andric case CK_FloatingComplexToIntegralComplex: 44617a519f9SDimitry Andric case CK_IntegralComplexCast: 44717a519f9SDimitry Andric case CK_IntegralComplexToFloatingComplex: 44817a519f9SDimitry Andric return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy); 44917a519f9SDimitry Andric } 45017a519f9SDimitry Andric 45117a519f9SDimitry Andric llvm_unreachable("unknown cast resulting in complex value"); 45217a519f9SDimitry Andric } 45317a519f9SDimitry Andric 454f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { 455f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 456f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 457f22ef01cSRoman Divacky ComplexPairTy Op = Visit(E->getSubExpr()); 458f22ef01cSRoman Divacky 459f22ef01cSRoman Divacky llvm::Value *ResR, *ResI; 460f22ef01cSRoman Divacky if (Op.first->getType()->isFloatingPointTy()) { 461f22ef01cSRoman Divacky ResR = Builder.CreateFNeg(Op.first, "neg.r"); 462f22ef01cSRoman Divacky ResI = Builder.CreateFNeg(Op.second, "neg.i"); 463f22ef01cSRoman Divacky } else { 464f22ef01cSRoman Divacky ResR = Builder.CreateNeg(Op.first, "neg.r"); 465f22ef01cSRoman Divacky ResI = Builder.CreateNeg(Op.second, "neg.i"); 466f22ef01cSRoman Divacky } 467f22ef01cSRoman Divacky return ComplexPairTy(ResR, ResI); 468f22ef01cSRoman Divacky } 469f22ef01cSRoman Divacky 470f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) { 471f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 472f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 473f22ef01cSRoman Divacky // ~(a+ib) = a + i*-b 474f22ef01cSRoman Divacky ComplexPairTy Op = Visit(E->getSubExpr()); 475f22ef01cSRoman Divacky llvm::Value *ResI; 476f22ef01cSRoman Divacky if (Op.second->getType()->isFloatingPointTy()) 477f22ef01cSRoman Divacky ResI = Builder.CreateFNeg(Op.second, "conj.i"); 478f22ef01cSRoman Divacky else 479f22ef01cSRoman Divacky ResI = Builder.CreateNeg(Op.second, "conj.i"); 480f22ef01cSRoman Divacky 481f22ef01cSRoman Divacky return ComplexPairTy(Op.first, ResI); 482f22ef01cSRoman Divacky } 483f22ef01cSRoman Divacky 484f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) { 485f22ef01cSRoman Divacky llvm::Value *ResR, *ResI; 486f22ef01cSRoman Divacky 487f22ef01cSRoman Divacky if (Op.LHS.first->getType()->isFloatingPointTy()) { 488f22ef01cSRoman Divacky ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); 489f22ef01cSRoman Divacky ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i"); 490f22ef01cSRoman Divacky } else { 491f22ef01cSRoman Divacky ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); 492f22ef01cSRoman Divacky ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i"); 493f22ef01cSRoman Divacky } 494f22ef01cSRoman Divacky return ComplexPairTy(ResR, ResI); 495f22ef01cSRoman Divacky } 496f22ef01cSRoman Divacky 497f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) { 498f22ef01cSRoman Divacky llvm::Value *ResR, *ResI; 499f22ef01cSRoman Divacky if (Op.LHS.first->getType()->isFloatingPointTy()) { 500f22ef01cSRoman Divacky ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r"); 501f22ef01cSRoman Divacky ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i"); 502f22ef01cSRoman Divacky } else { 503f22ef01cSRoman Divacky ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r"); 504f22ef01cSRoman Divacky ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i"); 505f22ef01cSRoman Divacky } 506f22ef01cSRoman Divacky return ComplexPairTy(ResR, ResI); 507f22ef01cSRoman Divacky } 508f22ef01cSRoman Divacky 509f22ef01cSRoman Divacky 510f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { 511f22ef01cSRoman Divacky using llvm::Value; 512f22ef01cSRoman Divacky Value *ResR, *ResI; 513f22ef01cSRoman Divacky 514f22ef01cSRoman Divacky if (Op.LHS.first->getType()->isFloatingPointTy()) { 515f22ef01cSRoman Divacky Value *ResRl = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 516f22ef01cSRoman Divacky Value *ResRr = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,"mul.rr"); 517f22ef01cSRoman Divacky ResR = Builder.CreateFSub(ResRl, ResRr, "mul.r"); 518f22ef01cSRoman Divacky 519f22ef01cSRoman Divacky Value *ResIl = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il"); 520f22ef01cSRoman Divacky Value *ResIr = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 521f22ef01cSRoman Divacky ResI = Builder.CreateFAdd(ResIl, ResIr, "mul.i"); 522f22ef01cSRoman Divacky } else { 523f22ef01cSRoman Divacky Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 524f22ef01cSRoman Divacky Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr"); 525f22ef01cSRoman Divacky ResR = Builder.CreateSub(ResRl, ResRr, "mul.r"); 526f22ef01cSRoman Divacky 527f22ef01cSRoman Divacky Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il"); 528f22ef01cSRoman Divacky Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 529f22ef01cSRoman Divacky ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i"); 530f22ef01cSRoman Divacky } 531f22ef01cSRoman Divacky return ComplexPairTy(ResR, ResI); 532f22ef01cSRoman Divacky } 533f22ef01cSRoman Divacky 534f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { 535f22ef01cSRoman Divacky llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; 536f22ef01cSRoman Divacky llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; 537f22ef01cSRoman Divacky 538f22ef01cSRoman Divacky 539f22ef01cSRoman Divacky llvm::Value *DSTr, *DSTi; 540f22ef01cSRoman Divacky if (Op.LHS.first->getType()->isFloatingPointTy()) { 541f22ef01cSRoman Divacky // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 5426122f3e6SDimitry Andric llvm::Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr); // a*c 5436122f3e6SDimitry Andric llvm::Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi); // b*d 5446122f3e6SDimitry Andric llvm::Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2); // ac+bd 545f22ef01cSRoman Divacky 5466122f3e6SDimitry Andric llvm::Value *Tmp4 = Builder.CreateFMul(RHSr, RHSr); // c*c 5476122f3e6SDimitry Andric llvm::Value *Tmp5 = Builder.CreateFMul(RHSi, RHSi); // d*d 5486122f3e6SDimitry Andric llvm::Value *Tmp6 = Builder.CreateFAdd(Tmp4, Tmp5); // cc+dd 549f22ef01cSRoman Divacky 5506122f3e6SDimitry Andric llvm::Value *Tmp7 = Builder.CreateFMul(LHSi, RHSr); // b*c 5516122f3e6SDimitry Andric llvm::Value *Tmp8 = Builder.CreateFMul(LHSr, RHSi); // a*d 5526122f3e6SDimitry Andric llvm::Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8); // bc-ad 553f22ef01cSRoman Divacky 5546122f3e6SDimitry Andric DSTr = Builder.CreateFDiv(Tmp3, Tmp6); 5556122f3e6SDimitry Andric DSTi = Builder.CreateFDiv(Tmp9, Tmp6); 556f22ef01cSRoman Divacky } else { 557f22ef01cSRoman Divacky // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 5586122f3e6SDimitry Andric llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c 5596122f3e6SDimitry Andric llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d 5606122f3e6SDimitry Andric llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd 561f22ef01cSRoman Divacky 5626122f3e6SDimitry Andric llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c 5636122f3e6SDimitry Andric llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d 5646122f3e6SDimitry Andric llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd 565f22ef01cSRoman Divacky 5666122f3e6SDimitry Andric llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c 5676122f3e6SDimitry Andric llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d 5686122f3e6SDimitry Andric llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad 569f22ef01cSRoman Divacky 570f22ef01cSRoman Divacky if (Op.Ty->getAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) { 5716122f3e6SDimitry Andric DSTr = Builder.CreateUDiv(Tmp3, Tmp6); 5726122f3e6SDimitry Andric DSTi = Builder.CreateUDiv(Tmp9, Tmp6); 573f22ef01cSRoman Divacky } else { 5746122f3e6SDimitry Andric DSTr = Builder.CreateSDiv(Tmp3, Tmp6); 5756122f3e6SDimitry Andric DSTi = Builder.CreateSDiv(Tmp9, Tmp6); 576f22ef01cSRoman Divacky } 577f22ef01cSRoman Divacky } 578f22ef01cSRoman Divacky 579f22ef01cSRoman Divacky return ComplexPairTy(DSTr, DSTi); 580f22ef01cSRoman Divacky } 581f22ef01cSRoman Divacky 582f22ef01cSRoman Divacky ComplexExprEmitter::BinOpInfo 583f22ef01cSRoman Divacky ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) { 584f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 585f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 586f22ef01cSRoman Divacky BinOpInfo Ops; 587f22ef01cSRoman Divacky Ops.LHS = Visit(E->getLHS()); 588f22ef01cSRoman Divacky Ops.RHS = Visit(E->getRHS()); 589f22ef01cSRoman Divacky Ops.Ty = E->getType(); 590f22ef01cSRoman Divacky return Ops; 591f22ef01cSRoman Divacky } 592f22ef01cSRoman Divacky 593f22ef01cSRoman Divacky 5942754fe60SDimitry Andric LValue ComplexExprEmitter:: 5952754fe60SDimitry Andric EmitCompoundAssignLValue(const CompoundAssignOperator *E, 5962754fe60SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&), 5972754fe60SDimitry Andric ComplexPairTy &Val) { 598f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 599f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 6002754fe60SDimitry Andric QualType LHSTy = E->getLHS()->getType(); 601f22ef01cSRoman Divacky 602f22ef01cSRoman Divacky BinOpInfo OpInfo; 603f22ef01cSRoman Divacky 604f22ef01cSRoman Divacky // Load the RHS and LHS operands. 605f22ef01cSRoman Divacky // __block variables need to have the rhs evaluated first, plus this should 6062754fe60SDimitry Andric // improve codegen a little. 607f22ef01cSRoman Divacky OpInfo.Ty = E->getComputationResultType(); 6082754fe60SDimitry Andric 6092754fe60SDimitry Andric // The RHS should have been converted to the computation type. 6102754fe60SDimitry Andric assert(OpInfo.Ty->isAnyComplexType()); 6112754fe60SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(OpInfo.Ty, 6122754fe60SDimitry Andric E->getRHS()->getType())); 6132754fe60SDimitry Andric OpInfo.RHS = Visit(E->getRHS()); 614f22ef01cSRoman Divacky 615ffd1746dSEd Schouten LValue LHS = CGF.EmitLValue(E->getLHS()); 6162754fe60SDimitry Andric 6172754fe60SDimitry Andric // Load from the l-value. 6182754fe60SDimitry Andric ComplexPairTy LHSComplexPair = EmitLoadOfLValue(LHS); 619f22ef01cSRoman Divacky 620f22ef01cSRoman Divacky OpInfo.LHS = EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty); 621f22ef01cSRoman Divacky 622f22ef01cSRoman Divacky // Expand the binary operator. 623f22ef01cSRoman Divacky ComplexPairTy Result = (this->*Func)(OpInfo); 624f22ef01cSRoman Divacky 625f22ef01cSRoman Divacky // Truncate the result back to the LHS type. 626f22ef01cSRoman Divacky Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy); 6272754fe60SDimitry Andric Val = Result; 628f22ef01cSRoman Divacky 629f22ef01cSRoman Divacky // Store the result value into the LHS lvalue. 6302754fe60SDimitry Andric EmitStoreThroughLValue(Result, LHS); 631ffd1746dSEd Schouten 6322754fe60SDimitry Andric return LHS; 633f22ef01cSRoman Divacky } 634f22ef01cSRoman Divacky 6352754fe60SDimitry Andric // Compound assignments. 6362754fe60SDimitry Andric ComplexPairTy ComplexExprEmitter:: 6372754fe60SDimitry Andric EmitCompoundAssign(const CompoundAssignOperator *E, 6382754fe60SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ 6392754fe60SDimitry Andric ComplexPairTy Val; 6402754fe60SDimitry Andric LValue LV = EmitCompoundAssignLValue(E, Func, Val); 6412754fe60SDimitry Andric 6422754fe60SDimitry Andric // The result of an assignment in C is the assigned r-value. 643dff0c46cSDimitry Andric if (!CGF.getContext().getLangOpts().CPlusPlus) 6442754fe60SDimitry Andric return Val; 6452754fe60SDimitry Andric 6462754fe60SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 6472754fe60SDimitry Andric if (!LV.isVolatileQualified()) 6482754fe60SDimitry Andric return Val; 6492754fe60SDimitry Andric 6502754fe60SDimitry Andric return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); 6512754fe60SDimitry Andric } 6522754fe60SDimitry Andric 6532754fe60SDimitry Andric LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, 6542754fe60SDimitry Andric ComplexPairTy &Val) { 655ffd1746dSEd Schouten assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 656ffd1746dSEd Schouten E->getRHS()->getType()) && 657f22ef01cSRoman Divacky "Invalid assignment"); 6582754fe60SDimitry Andric TestAndClearIgnoreReal(); 6592754fe60SDimitry Andric TestAndClearIgnoreImag(); 6602754fe60SDimitry Andric 6612754fe60SDimitry Andric // Emit the RHS. __block variables need the RHS evaluated first. 6622754fe60SDimitry Andric Val = Visit(E->getRHS()); 663f22ef01cSRoman Divacky 664f22ef01cSRoman Divacky // Compute the address to store into. 665f22ef01cSRoman Divacky LValue LHS = CGF.EmitLValue(E->getLHS()); 666f22ef01cSRoman Divacky 667ffd1746dSEd Schouten // Store the result value into the LHS lvalue. 6682754fe60SDimitry Andric EmitStoreThroughLValue(Val, LHS); 669f22ef01cSRoman Divacky 6702754fe60SDimitry Andric return LHS; 6712754fe60SDimitry Andric } 672ffd1746dSEd Schouten 6732754fe60SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { 6742754fe60SDimitry Andric ComplexPairTy Val; 6752754fe60SDimitry Andric LValue LV = EmitBinAssignLValue(E, Val); 6762754fe60SDimitry Andric 6772754fe60SDimitry Andric // The result of an assignment in C is the assigned r-value. 678dff0c46cSDimitry Andric if (!CGF.getContext().getLangOpts().CPlusPlus) 6792754fe60SDimitry Andric return Val; 6802754fe60SDimitry Andric 6812754fe60SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 6822754fe60SDimitry Andric if (!LV.isVolatileQualified()) 6832754fe60SDimitry Andric return Val; 6842754fe60SDimitry Andric 6852754fe60SDimitry Andric return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); 686f22ef01cSRoman Divacky } 687f22ef01cSRoman Divacky 688f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { 6892754fe60SDimitry Andric CGF.EmitIgnoredExpr(E->getLHS()); 690f22ef01cSRoman Divacky return Visit(E->getRHS()); 691f22ef01cSRoman Divacky } 692f22ef01cSRoman Divacky 693f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter:: 6942754fe60SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 695f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 696f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 697f22ef01cSRoman Divacky llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); 698f22ef01cSRoman Divacky llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); 699f22ef01cSRoman Divacky llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); 700f22ef01cSRoman Divacky 7012754fe60SDimitry Andric // Bind the common expression if necessary. 7022754fe60SDimitry Andric CodeGenFunction::OpaqueValueMapping binding(CGF, E); 7032754fe60SDimitry Andric 7042754fe60SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF); 705f22ef01cSRoman Divacky CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); 706f22ef01cSRoman Divacky 7072754fe60SDimitry Andric eval.begin(CGF); 708f22ef01cSRoman Divacky CGF.EmitBlock(LHSBlock); 7092754fe60SDimitry Andric ComplexPairTy LHS = Visit(E->getTrueExpr()); 710f22ef01cSRoman Divacky LHSBlock = Builder.GetInsertBlock(); 711f22ef01cSRoman Divacky CGF.EmitBranch(ContBlock); 7122754fe60SDimitry Andric eval.end(CGF); 713f22ef01cSRoman Divacky 7142754fe60SDimitry Andric eval.begin(CGF); 715f22ef01cSRoman Divacky CGF.EmitBlock(RHSBlock); 7162754fe60SDimitry Andric ComplexPairTy RHS = Visit(E->getFalseExpr()); 717f22ef01cSRoman Divacky RHSBlock = Builder.GetInsertBlock(); 718f22ef01cSRoman Divacky CGF.EmitBlock(ContBlock); 7192754fe60SDimitry Andric eval.end(CGF); 720f22ef01cSRoman Divacky 721f22ef01cSRoman Divacky // Create a PHI node for the real part. 7223b0f4066SDimitry Andric llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r"); 723f22ef01cSRoman Divacky RealPN->addIncoming(LHS.first, LHSBlock); 724f22ef01cSRoman Divacky RealPN->addIncoming(RHS.first, RHSBlock); 725f22ef01cSRoman Divacky 726f22ef01cSRoman Divacky // Create a PHI node for the imaginary part. 7273b0f4066SDimitry Andric llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i"); 728f22ef01cSRoman Divacky ImagPN->addIncoming(LHS.second, LHSBlock); 729f22ef01cSRoman Divacky ImagPN->addIncoming(RHS.second, RHSBlock); 730f22ef01cSRoman Divacky 731f22ef01cSRoman Divacky return ComplexPairTy(RealPN, ImagPN); 732f22ef01cSRoman Divacky } 733f22ef01cSRoman Divacky 734f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { 735f22ef01cSRoman Divacky return Visit(E->getChosenSubExpr(CGF.getContext())); 736f22ef01cSRoman Divacky } 737f22ef01cSRoman Divacky 738f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { 739f22ef01cSRoman Divacky bool Ignore = TestAndClearIgnoreReal(); 740f22ef01cSRoman Divacky (void)Ignore; 741f22ef01cSRoman Divacky assert (Ignore == false && "init list ignored"); 742f22ef01cSRoman Divacky Ignore = TestAndClearIgnoreImag(); 743f22ef01cSRoman Divacky (void)Ignore; 744f22ef01cSRoman Divacky assert (Ignore == false && "init list ignored"); 7456122f3e6SDimitry Andric 7466122f3e6SDimitry Andric if (E->getNumInits() == 2) { 7476122f3e6SDimitry Andric llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0)); 7486122f3e6SDimitry Andric llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1)); 7496122f3e6SDimitry Andric return ComplexPairTy(Real, Imag); 7506122f3e6SDimitry Andric } else if (E->getNumInits() == 1) { 751f22ef01cSRoman Divacky return Visit(E->getInit(0)); 7526122f3e6SDimitry Andric } 753f22ef01cSRoman Divacky 754f22ef01cSRoman Divacky // Empty init list intializes to null 7556122f3e6SDimitry Andric assert(E->getNumInits() == 0 && "Unexpected number of inits"); 756f22ef01cSRoman Divacky QualType Ty = E->getType()->getAs<ComplexType>()->getElementType(); 7576122f3e6SDimitry Andric llvm::Type* LTy = CGF.ConvertType(Ty); 758f22ef01cSRoman Divacky llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); 759f22ef01cSRoman Divacky return ComplexPairTy(zeroConstant, zeroConstant); 760f22ef01cSRoman Divacky } 761f22ef01cSRoman Divacky 762f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { 763f22ef01cSRoman Divacky llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr()); 764f22ef01cSRoman Divacky llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType()); 765f22ef01cSRoman Divacky 766f22ef01cSRoman Divacky if (!ArgPtr) { 767f22ef01cSRoman Divacky CGF.ErrorUnsupported(E, "complex va_arg expression"); 7686122f3e6SDimitry Andric llvm::Type *EltTy = 769f22ef01cSRoman Divacky CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType()); 770f22ef01cSRoman Divacky llvm::Value *U = llvm::UndefValue::get(EltTy); 771f22ef01cSRoman Divacky return ComplexPairTy(U, U); 772f22ef01cSRoman Divacky } 773f22ef01cSRoman Divacky 774f22ef01cSRoman Divacky // FIXME Volatility. 775f22ef01cSRoman Divacky return EmitLoadOfComplex(ArgPtr, false); 776f22ef01cSRoman Divacky } 777f22ef01cSRoman Divacky 778f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 779f22ef01cSRoman Divacky // Entry Point into this File 780f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 781f22ef01cSRoman Divacky 782f22ef01cSRoman Divacky /// EmitComplexExpr - Emit the computation of the specified expression of 783f22ef01cSRoman Divacky /// complex type, ignoring the result. 784f22ef01cSRoman Divacky ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, 7852754fe60SDimitry Andric bool IgnoreImag) { 786f22ef01cSRoman Divacky assert(E && E->getType()->isAnyComplexType() && 787f22ef01cSRoman Divacky "Invalid complex expression to emit"); 788f22ef01cSRoman Divacky 7892754fe60SDimitry Andric return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag) 790f22ef01cSRoman Divacky .Visit(const_cast<Expr*>(E)); 791f22ef01cSRoman Divacky } 792f22ef01cSRoman Divacky 793f22ef01cSRoman Divacky /// EmitComplexExprIntoAddr - Emit the computation of the specified expression 794f22ef01cSRoman Divacky /// of complex type, storing into the specified Value*. 795f22ef01cSRoman Divacky void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E, 796f22ef01cSRoman Divacky llvm::Value *DestAddr, 797f22ef01cSRoman Divacky bool DestIsVolatile) { 798f22ef01cSRoman Divacky assert(E && E->getType()->isAnyComplexType() && 799f22ef01cSRoman Divacky "Invalid complex expression to emit"); 800f22ef01cSRoman Divacky ComplexExprEmitter Emitter(*this); 801f22ef01cSRoman Divacky ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E)); 802f22ef01cSRoman Divacky Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile); 803f22ef01cSRoman Divacky } 804f22ef01cSRoman Divacky 805f22ef01cSRoman Divacky /// StoreComplexToAddr - Store a complex number into the specified address. 806f22ef01cSRoman Divacky void CodeGenFunction::StoreComplexToAddr(ComplexPairTy V, 807f22ef01cSRoman Divacky llvm::Value *DestAddr, 808f22ef01cSRoman Divacky bool DestIsVolatile) { 809f22ef01cSRoman Divacky ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile); 810f22ef01cSRoman Divacky } 811f22ef01cSRoman Divacky 812f22ef01cSRoman Divacky /// LoadComplexFromAddr - Load a complex number from the specified address. 813f22ef01cSRoman Divacky ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr, 814f22ef01cSRoman Divacky bool SrcIsVolatile) { 815f22ef01cSRoman Divacky return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile); 816f22ef01cSRoman Divacky } 8172754fe60SDimitry Andric 8182754fe60SDimitry Andric LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { 8192754fe60SDimitry Andric assert(E->getOpcode() == BO_Assign); 8202754fe60SDimitry Andric ComplexPairTy Val; // ignored 8212754fe60SDimitry Andric return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val); 8222754fe60SDimitry Andric } 8232754fe60SDimitry Andric 8242754fe60SDimitry Andric LValue CodeGenFunction:: 8252754fe60SDimitry Andric EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { 8262754fe60SDimitry Andric ComplexPairTy(ComplexExprEmitter::*Op)(const ComplexExprEmitter::BinOpInfo &); 8272754fe60SDimitry Andric switch (E->getOpcode()) { 8282754fe60SDimitry Andric case BO_MulAssign: Op = &ComplexExprEmitter::EmitBinMul; break; 8292754fe60SDimitry Andric case BO_DivAssign: Op = &ComplexExprEmitter::EmitBinDiv; break; 8302754fe60SDimitry Andric case BO_SubAssign: Op = &ComplexExprEmitter::EmitBinSub; break; 8312754fe60SDimitry Andric case BO_AddAssign: Op = &ComplexExprEmitter::EmitBinAdd; break; 8322754fe60SDimitry Andric 8332754fe60SDimitry Andric default: 8342754fe60SDimitry Andric llvm_unreachable("unexpected complex compound assignment"); 8352754fe60SDimitry Andric } 8362754fe60SDimitry Andric 8372754fe60SDimitry Andric ComplexPairTy Val; // ignored 8382754fe60SDimitry Andric return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 8392754fe60SDimitry Andric } 840