[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