[cfe-commits] r39710 - in /cfe/cfe/trunk: CodeGen/CGExpr.cpp CodeGen/CodeGenFunction.h Sema/SemaExpr.cpp include/clang/AST/Expr.h
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:47:24 PDT 2007
Author: clattner
Date: Wed Jul 11 11:47:23 2007
New Revision: 39710
URL: http://llvm.org/viewvc/llvm-project?rev=39710&view=rev
Log:
Rename ArithAssignBinaryOperator -> CompoundAssignOperator, implement
codegen support for +=.
Modified:
cfe/cfe/trunk/CodeGen/CGExpr.cpp
cfe/cfe/trunk/CodeGen/CodeGenFunction.h
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/AST/Expr.h
Modified: cfe/cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGExpr.cpp?rev=39710&r1=39709&r2=39710&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGExpr.cpp Wed Jul 11 11:47:23 2007
@@ -256,10 +256,8 @@
/// EmitLoadOfLValue - Given an expression that represents a value lvalue,
/// this method emits the address of the lvalue, then loads the result as an
/// rvalue, returning the rvalue.
-RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) {
- LValue LV = EmitLValue(E);
-
- QualType ExprTy = E->getType().getCanonicalType();
+RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
+ ExprType = ExprType.getCanonicalType();
// FIXME: this is silly and obviously wrong for non-scalars.
assert(!LV.isBitfield());
@@ -275,6 +273,11 @@
return RValue::getAggregate(Ptr);
}
+RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) {
+ return EmitLoadOfLValue(EmitLValue(E), E->getType());
+}
+
+
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
@@ -745,7 +748,9 @@
return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_NE,
llvm::ICmpInst::ICMP_NE,
llvm::FCmpInst::FCMP_UNE);
- case BinaryOperator::Assign: return EmitBinaryAssign(E);
+ case BinaryOperator::Assign: return EmitBinaryAssign(E);
+ case BinaryOperator::AddAssign:
+ return EmitBinaryAddAssign(cast<CompoundAssignOperator>(E));
// FIXME: Assignment.
case BinaryOperator::Comma: return EmitBinaryComma(E);
}
@@ -1000,6 +1005,44 @@
return RHS;
}
+/// Compound assignment operations have different promotion rules than the other
+/// binary operators. In particular, the LHS and RHS are promoted to a new type
+/// (specified by E->getComputationType()), the binary operator is evaluated,
+/// the result is truncated to the type of LHS, then the result is stored back
+/// through the LHS.
+///
+RValue CodeGenFunction::EmitBinaryAddAssign(const CompoundAssignOperator *E) {
+ LValue LHSLV = EmitLValue(E->getLHS());
+
+ // Load the LHS and RHS operands.
+ QualType LHSTy = E->getLHS()->getType();
+ RValue LHS = EmitLoadOfLValue(LHSLV, LHSTy);
+ QualType RHSTy;
+ RValue RHS = EmitExprWithUsualUnaryConversions(E->getRHS(), RHSTy);
+
+ // Convert the LHS and RHS to the common evaluation type.
+ LHS = EmitConversion(LHS, LHSTy, E->getComputationType());
+ RHS = EmitConversion(RHS, RHSTy, E->getComputationType());
+
+ // Emit the operation itself.
+ RValue Res;
+ if (LHS.isScalar()) {
+ Res = RValue::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "add"));
+ } else {
+ assert(0 && "FIXME: Complex add unimp!");
+ }
+
+ // Truncate back to the destination type.
+ if (E->getComputationType() != E->getType())
+ Res = EmitConversion(Res, E->getComputationType(), E->getType());
+
+ // Store the result value into the LHS.
+ EmitStoreThroughLValue(Res, LHSLV, E->getType());
+
+ // Return the result.
+ return Res;
+}
+
RValue CodeGenFunction::EmitBinaryComma(const BinaryOperator *E) {
EmitExpr(E->getLHS());
return EmitExpr(E->getRHS());
Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39710&r1=39709&r2=39710&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:47:23 2007
@@ -49,6 +49,7 @@
class CallExpr;
class UnaryOperator;
class BinaryOperator;
+ class CompoundAssignOperator;
class ArraySubscriptExpr;
class BlockVarDecl;
@@ -250,7 +251,8 @@
/// this method emits the address of the lvalue, then loads the result as an
/// rvalue, returning the rvalue.
RValue EmitLoadOfLValue(const Expr *E);
-
+ RValue EmitLoadOfLValue(LValue V, QualType LVType);
+
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
@@ -304,6 +306,7 @@
RValue EmitBinaryLOr(const BinaryOperator *E);
RValue EmitBinaryAssign(const BinaryOperator *E);
+ RValue EmitBinaryAddAssign(const CompoundAssignOperator *E);
// FIXME: Assignment.
RValue EmitBinaryComma(const BinaryOperator *E);
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39710&r1=39709&r2=39710&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:47:23 2007
@@ -1246,7 +1246,7 @@
if (CompTy.isNull())
return new BinaryOperator(lhs, rhs, Opc, ResultTy);
else
- return new ArithAssignBinaryOperator(lhs, rhs, Opc, ResultTy, CompTy);
+ return new CompoundAssignOperator(lhs, rhs, Opc, ResultTy, CompTy);
}
// Unary Operators. 'Tok' is the token for the operator.
Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39710&r1=39709&r2=39710&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:47:23 2007
@@ -519,17 +519,17 @@
}
};
-/// CompoundAssignmentOperator - For compound assignments (e.g. +=), we keep
+/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
/// track of the type the operation is performed in. Due to the semantics of
/// these operators, the operands are promoted, the aritmetic performed, an
/// implicit conversion back to the result type done, then the assignment takes
/// place. This captures the intermediate type which the computation is done
/// in.
-class ArithAssignBinaryOperator : public BinaryOperator {
+class CompoundAssignOperator : public BinaryOperator {
QualType ComputationType;
public:
- ArithAssignBinaryOperator(Expr *lhs, Expr *rhs, Opcode opc,
- QualType ResType, QualType CompType)
+ CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc,
+ QualType ResType, QualType CompType)
: BinaryOperator(lhs, rhs, opc, ResType, true), ComputationType(CompType) {
assert(isCompoundAssignmentOp() &&
"Only should be used for compound assignments");
@@ -537,7 +537,7 @@
QualType getComputationType() const { return ComputationType; }
- static bool classof(const ArithAssignBinaryOperator *) { return true; }
+ static bool classof(const CompoundAssignOperator *) { return true; }
static bool classof(const BinaryOperator *B) {
return B->isCompoundAssignmentOp();
}
More information about the cfe-commits
mailing list