summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExprComplex.cpp2
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp79
2 files changed, 18 insertions, 63 deletions
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 3e4410611c5..3e28490f6ff 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -419,7 +419,7 @@ EmitCompoundAssign(const CompoundAssignOperator *E,
LValue LHSLV = CGF.EmitLValue(E->getLHS());
BinOpInfo OpInfo;
- OpInfo.Ty = E->getComputationType();
+ OpInfo.Ty = E->getComputationResultType();
// We know the LHS is a complex lvalue.
OpInfo.LHS = EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified());
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 89f28bea6d3..4f2371c4a18 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -768,76 +768,31 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
BinOpInfo OpInfo;
- // Load the LHS and RHS operands.
- LValue LHSLV = EmitLValue(E->getLHS());
- OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
-
- // Determine the computation type. If the RHS is complex, then this is one of
- // the add/sub/mul/div operators. All of these operators can be computed in
- // with just their real component even though the computation domain really is
- // complex.
- QualType ComputeType = E->getComputationType();
-
- // If the computation type is complex, then the RHS is complex. Emit the RHS.
- if (const ComplexType *CT = ComputeType->getAsComplexType()) {
- ComputeType = CT->getElementType();
-
- // Emit the RHS, only keeping the real component.
- OpInfo.RHS = CGF.EmitComplexExpr(E->getRHS()).first;
- RHSTy = RHSTy->getAsComplexType()->getElementType();
- } else {
- // Otherwise the RHS is a simple scalar value.
- OpInfo.RHS = Visit(E->getRHS());
- }
-
- QualType LComputeTy, RComputeTy, ResultTy;
-
- // Compound assignment does not contain enough information about all
- // the types involved for pointer arithmetic cases. Figure it out
- // here for now.
- if (E->getLHS()->getType()->isPointerType()) {
- // Pointer arithmetic cases: ptr +=,-= int and ptr -= ptr,
- assert((E->getOpcode() == BinaryOperator::AddAssign ||
- E->getOpcode() == BinaryOperator::SubAssign) &&
- "Invalid compound assignment operator on pointer type.");
- LComputeTy = E->getLHS()->getType();
-
- if (E->getRHS()->getType()->isPointerType()) {
- // Degenerate case of (ptr -= ptr) allowed by GCC implicit cast
- // extension, the conversion from the pointer difference back to
- // the LHS type is handled at the end.
- assert(E->getOpcode() == BinaryOperator::SubAssign &&
- "Invalid compound assignment operator on pointer type.");
- RComputeTy = E->getLHS()->getType();
- ResultTy = CGF.getContext().getPointerDiffType();
- } else {
- RComputeTy = E->getRHS()->getType();
- ResultTy = LComputeTy;
- }
- } else if (E->getRHS()->getType()->isPointerType()) {
- // Degenerate case of (int += ptr) allowed by GCC implicit cast
- // extension.
- assert(E->getOpcode() == BinaryOperator::AddAssign &&
- "Invalid compound assignment operator on pointer type.");
- LComputeTy = E->getLHS()->getType();
- RComputeTy = E->getRHS()->getType();
- ResultTy = RComputeTy;
- } else {
- LComputeTy = RComputeTy = ResultTy = ComputeType;
+ if (E->getComputationResultType()->isAnyComplexType()) {
+ // FIXME: This needs to go through the complex expression emitter, but
+ // it's a tad complicated to do that... I'm leaving it out for now.
+ // (Note that we do actually need the imaginary part of the RHS for
+ // multiplication and division.)
+ CGF.ErrorUnsupported(E, "complex compound assignment");
+ return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
}
- // Convert the LHS/RHS values to the computation type.
- OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, LComputeTy);
- OpInfo.RHS = EmitScalarConversion(OpInfo.RHS, RHSTy, RComputeTy);
- OpInfo.Ty = ResultTy;
+ // Load/convert the LHS.
+ LValue LHSLV = EmitLValue(E->getLHS());
+ OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
+ OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
+ E->getComputationLHSType());
+ // Emit the RHS.
+ OpInfo.RHS = Visit(E->getRHS());
+ OpInfo.Ty = E->getComputationResultType();
OpInfo.E = E;
// Expand the binary operator.
Value *Result = (this->*Func)(OpInfo);
// Convert the result back to the LHS type.
- Result = EmitScalarConversion(Result, ResultTy, LHSTy);
-
+ Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy);
+
// Store the result value into the LHS lvalue. Bit-fields are
// handled specially because the result is altered by the store,
// i.e., [C99 6.5.16p1] 'An assignment expression has the value of
OpenPOWER on IntegriCloud