aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-11-16 10:08:07 +0000
committerJohn McCall <rjmccall@apple.com>2010-11-16 10:08:07 +0000
commitb418d74c11498b7e1044103131e2e3be4d63512e (patch)
tree36330e02a9b184864d87e3dff7fcbe0ffe68961d /lib/CodeGen/CGExprScalar.cpp
parentac21a21a49131544777f3bd56d2351a4072954ca (diff)
Simplify some complex emission and implement correct semantics for
assignment to volatiles in C. This in effect reverts some of mjs's work in and around r72572. Basically, the C++ standard is quite clear, except that it lies about volatile behavior approximating C's, whereas the C standard is almost actively misleading. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119344 91177308-0d34-0410-b5e6-96231b3b80d8
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;