diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/CGExprComplex.cpp | 23 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 3 |
3 files changed, 39 insertions, 5 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0c24bf5d1a..6bfafca857 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1981,19 +1981,27 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) { if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI) return EmitPointerToDataMemberBinaryExpr(E); - - // Can only get l-value for binary operator expressions which are a - // simple assignment of aggregate type. - if (E->getOpcode() != BO_Assign) - return EmitUnsupportedLValue(E, "binary l-value expression"); + assert(E->isAssignmentOp() && "unexpected binary l-value"); + if (!hasAggregateLLVMType(E->getType())) { + if (E->isCompoundAssignmentOp()) + return EmitCompoundAssignOperatorLValue(cast<CompoundAssignOperator>(E)); + + assert(E->getOpcode() == BO_Assign && "unexpected binary l-value"); + // Emit the LHS as an l-value. LValue LV = EmitLValue(E->getLHS()); // Store the value through the l-value. EmitStoreThroughLValue(EmitAnyExpr(E->getRHS()), LV, E->getType()); return LV; } + + if (E->getType()->isAnyComplexType()) + return EmitComplexAssignmentLValue(E); + + // The compound assignment operators are not used for aggregates. + assert(E->getOpcode() == BO_Assign && "aggregate compound assignment?"); return EmitAggExprToLValue(E); } diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index df65d5a3ac..26bda79898 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -760,3 +760,26 @@ ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile) { return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile); } + +LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { + ComplexPairTy Val; // ignored + + ComplexPairTy(ComplexExprEmitter::*Op)(const ComplexExprEmitter::BinOpInfo &); + + switch (E->getOpcode()) { + case BO_Assign: + return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val); + + 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; + + default: + llvm_unreachable("unexpected complex compound assignment"); + Op = 0; + } + + return ComplexExprEmitter(*this).EmitCompoundAssignLValue( + cast<CompoundAssignOperator>(E), Op, Val); +} diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index a3e1eac550..560675e73f 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1404,6 +1404,9 @@ public: void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, QualType Ty, llvm::Value **Result=0); + /// Emit an l-value for an assignment (simple or compound) of complex type. + LValue EmitComplexAssignmentLValue(const BinaryOperator *E); + // Note: only availabe for agg return types LValue EmitBinaryOperatorLValue(const BinaryOperator *E); LValue EmitCompoundAssignOperatorLValue(const CompoundAssignOperator *E); |