/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
QualType DestType);
+ /// EmitComplexToComplexCast - Emit a cast from scalar value Val to DestType.
+ ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,
+ QualType DestType);
//===--------------------------------------------------------------------===//
// Visitor Methods
LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
ComplexPairTy (ComplexExprEmitter::*Func)
(const BinOpInfo &),
- ComplexPairTy &Val);
+ RValue &Val);
ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
ComplexPairTy (ComplexExprEmitter::*Func)
(const BinOpInfo &));
return Val;
}
+ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
+ QualType SrcType,
+ QualType DestType) {
+ // Convert the input element to the element type of the complex.
+ DestType = DestType->castAs<ComplexType>()->getElementType();
+ Val = CGF.EmitScalarConversion(Val, SrcType, DestType);
+
+ // Return (realval, 0).
+ return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
+}
+
ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
QualType DestTy) {
switch (CK) {
llvm_unreachable("invalid cast kind for complex value");
case CK_FloatingRealToComplex:
- case CK_IntegralRealToComplex: {
- llvm::Value *Elt = CGF.EmitScalarExpr(Op);
-
- // Convert the input element to the element type of the complex.
- DestTy = DestTy->castAs<ComplexType>()->getElementType();
- Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
-
- // Return (realval, 0).
- return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
- }
+ case CK_IntegralRealToComplex:
+ return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op),
+ Op->getType(), DestTy);
case CK_FloatingComplexCast:
case CK_FloatingComplexToIntegralComplex:
LValue ComplexExprEmitter::
EmitCompoundAssignLValue(const CompoundAssignOperator *E,
ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&),
- ComplexPairTy &Val) {
+ RValue &Val) {
TestAndClearIgnoreReal();
TestAndClearIgnoreImag();
QualType LHSTy = E->getLHS()->getType();
LValue LHS = CGF.EmitLValue(E->getLHS());
- // Load from the l-value.
- ComplexPairTy LHSComplexPair = EmitLoadOfLValue(LHS);
-
- OpInfo.LHS = EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty);
+ // Load from the l-value and convert it.
+ if (LHSTy->isAnyComplexType()) {
+ ComplexPairTy LHSVal = EmitLoadOfLValue(LHS);
+ OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
+ } else {
+ llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS);
+ OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
+ }
// Expand the binary operator.
ComplexPairTy Result = (this->*Func)(OpInfo);
- // Truncate the result back to the LHS type.
- Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
- Val = Result;
-
- // Store the result value into the LHS lvalue.
- EmitStoreOfComplex(Result, LHS, /*isInit*/ false);
+ // Truncate the result and store it into the LHS lvalue.
+ if (LHSTy->isAnyComplexType()) {
+ ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
+ EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false);
+ Val = RValue::getComplex(ResVal);
+ } else {
+ llvm::Value *ResVal =
+ CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy);
+ CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
+ Val = RValue::get(ResVal);
+ }
return LHS;
}
ComplexPairTy ComplexExprEmitter::
EmitCompoundAssign(const CompoundAssignOperator *E,
ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
- ComplexPairTy Val;
+ RValue Val;
LValue LV = EmitCompoundAssignLValue(E, Func, Val);
// The result of an assignment in C is the assigned r-value.
if (!CGF.getLangOpts().CPlusPlus)
- return Val;
+ return Val.getComplexVal();
// If the lvalue is non-volatile, return the computed value of the assignment.
if (!LV.isVolatileQualified())
- return Val;
+ return Val.getComplexVal();
return EmitLoadOfLValue(LV);
}
return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
}
-LValue CodeGenFunction::
-EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
- ComplexPairTy(ComplexExprEmitter::*Op)(const ComplexExprEmitter::BinOpInfo &);
- switch (E->getOpcode()) {
- case BO_MulAssign: Op = &ComplexExprEmitter::EmitBinMul; break;
- case BO_DivAssign: Op = &ComplexExprEmitter::EmitBinDiv; break;
- case BO_SubAssign: Op = &ComplexExprEmitter::EmitBinSub; break;
- case BO_AddAssign: Op = &ComplexExprEmitter::EmitBinAdd; break;
+typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)(
+ const ComplexExprEmitter::BinOpInfo &);
+static CompoundFunc getComplexOp(BinaryOperatorKind Op) {
+ switch (Op) {
+ case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul;
+ case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv;
+ case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub;
+ case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd;
default:
llvm_unreachable("unexpected complex compound assignment");
}
+}
- ComplexPairTy Val; // ignored
+LValue CodeGenFunction::
+EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
+ CompoundFunc Op = getComplexOp(E->getOpcode());
+ RValue Val;
return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
}
+
+LValue CodeGenFunction::
+EmitScalarCompooundAssignWithComplex(const CompoundAssignOperator *E,
+ llvm::Value *&Result) {
+ CompoundFunc Op = getComplexOp(E->getOpcode());
+ RValue Val;
+ LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
+ Result = Val.getScalarVal();
+ return Ret;
+}