summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-11-16 23:07:28 +0000
committerJohn McCall <rjmccall@apple.com>2010-11-16 23:07:28 +0000
commit4f29b49de11e5815952c256bbe66ffe33f4e3d00 (patch)
tree385c3333a9c286d7b56336b5481a8652f2a74cbb /clang/lib
parentaeb5e6677269d0834b494eb5a2374097ec863f12 (diff)
downloadbcm5719-llvm-4f29b49de11e5815952c256bbe66ffe33f4e3d00.tar.gz
bcm5719-llvm-4f29b49de11e5815952c256bbe66ffe33f4e3d00.zip
Support compound complex operations as l-values in C++. Add a test
case based on CodeGen/volatile-1.c which tests the current C++ semantics, and note the many, many places we fall short of them. llvm-svn: 119402
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp18
-rw-r--r--clang/lib/CodeGen/CGExprComplex.cpp23
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h3
3 files changed, 39 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 0c24bf5d1a6..6bfafca857e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/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/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index df65d5a3ac9..26bda79898b 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/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/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index a3e1eac550f..560675e73fd 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/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);
OpenPOWER on IntegriCloud