aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index a64debd6c1..0e09642931 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1176,12 +1176,11 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
case CK_FloatingComplexToReal:
case CK_IntegralComplexToReal:
- return CGF.EmitComplexExpr(E, false, true, false, true).first;
+ return CGF.EmitComplexExpr(E, false, true).first;
case CK_FloatingComplexToBoolean:
case CK_IntegralComplexToBoolean: {
- CodeGenFunction::ComplexPairTy V
- = CGF.EmitComplexExpr(E, false, false, false, false);
+ CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E);
// TODO: kill this function off, inline appropriate case here
return EmitComplexToScalarConversion(V, E->getType(), DestTy);
@@ -1471,21 +1470,38 @@ ScalarExprEmitter::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
Expr *Op = E->getSubExpr();
- if (Op->getType()->isAnyComplexType())
- return CGF.EmitComplexExpr(Op, false, true, false, true).first;
+ if (Op->getType()->isAnyComplexType()) {
+ // If it's an l-value, load through the appropriate subobject l-value.
+ // Note that we have to ask E because Op might be an l-value that
+ // this won't work for, e.g. an Obj-C property.
+ if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid)
+ return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType())
+ .getScalarVal();
+
+ // Otherwise, calculate and project.
+ return CGF.EmitComplexExpr(Op, false, true).first;
+ }
+
return Visit(Op);
}
+
Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
Expr *Op = E->getSubExpr();
- if (Op->getType()->isAnyComplexType())
- return CGF.EmitComplexExpr(Op, true, false, true, false).second;
+ if (Op->getType()->isAnyComplexType()) {
+ // If it's an l-value, load through the appropriate subobject l-value.
+ // Note that we have to ask E because Op might be an l-value that
+ // this won't work for, e.g. an Obj-C property.
+ if (Op->isLvalue(CGF.getContext()) == Expr::LV_Valid)
+ return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType())
+ .getScalarVal();
+
+ // Otherwise, calculate and project.
+ return CGF.EmitComplexExpr(Op, true, false).second;
+ }
// __imag on a scalar returns zero. Emit the subexpr to ensure side
// effects are evaluated, but not the actual value.
- if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid)
- CGF.EmitLValue(Op);
- else
- CGF.EmitScalarExpr(Op, true);
+ CGF.EmitScalarExpr(Op, true);
return llvm::Constant::getNullValue(ConvertType(E->getType()));
}
@@ -1562,6 +1578,10 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
if (Ignore)
return 0;
+ // The result of an assignment in C is the assigned r-value.
+ if (!CGF.getContext().getLangOptions().CPlusPlus)
+ return RHS;
+
// Objective-C property assignment never reloads the value following a store.
if (LHS.isPropertyRef() || LHS.isKVCRef())
return RHS;
@@ -2050,6 +2070,10 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
if (Ignore)
return 0;
+ // The result of an assignment in C is the assigned r-value.
+ if (!CGF.getContext().getLangOptions().CPlusPlus)
+ return RHS;
+
// Objective-C property assignment never reloads the value following a store.
if (LHS.isPropertyRef() || LHS.isKVCRef())
return RHS;