[cfe-commits] r39700 - in /cfe/cfe/trunk: Sema/SemaExpr.cpp include/clang/AST/Expr.h

clattner at cs.uiuc.edu clattner at cs.uiuc.edu
Wed Jul 11 09:47:18 PDT 2007


Author: clattner
Date: Wed Jul 11 11:47:17 2007
New Revision: 39700

URL: http://llvm.org/viewvc/llvm-project?rev=39700&view=rev
Log:
Record the intermediate computation type for compound assignments in the AST.
For example, for:

int test(short S, long L) {
  return S /= L;
}

record that the division is done as a long, even though the result type is
short.

Modified:
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/AST/Expr.h

Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39700&r1=39699&r2=39700&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:47:17 2007
@@ -1158,97 +1158,95 @@
   assert((lhs != 0) && "ParseBinOp(): missing left expression");
   assert((rhs != 0) && "ParseBinOp(): missing right expression");
 
-  QualType result;
+  QualType ResultTy;  // Result type of the binary operator.
+  QualType CompTy;    // Computation type for compound assignments (e.g. '+=')
   
   switch (Opc) {
   default:
     assert(0 && "Unknown binary expr!");
   case BinaryOperator::Assign:
-    result = CheckAssignmentOperands(lhs, rhs, TokLoc, QualType());
+    ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, QualType());
     break;
   case BinaryOperator::Mul: 
   case BinaryOperator::Div:
-    result = CheckMultiplyDivideOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckMultiplyDivideOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::Rem:
-    result = CheckRemainderOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckRemainderOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::Add:
-    result = CheckAdditionOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckAdditionOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::Sub:
-    result = CheckSubtractionOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckSubtractionOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::Shl: 
   case BinaryOperator::Shr:
-    result = CheckShiftOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckShiftOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::LE:
   case BinaryOperator::LT:
   case BinaryOperator::GE:
   case BinaryOperator::GT:
-    result = CheckRelationalOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckRelationalOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::EQ:
   case BinaryOperator::NE:
-    result = CheckEqualityOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckEqualityOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::And:
   case BinaryOperator::Xor:
   case BinaryOperator::Or:
-    result = CheckBitwiseOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckBitwiseOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::LAnd:
   case BinaryOperator::LOr:
-    result = CheckLogicalOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckLogicalOperands(lhs, rhs, TokLoc);
     break;
   case BinaryOperator::MulAssign:
   case BinaryOperator::DivAssign:
-    result = CheckMultiplyDivideOperands(lhs, rhs, TokLoc);
-    if (result.isNull())
-      return true;
-    result = CheckAssignmentOperands(lhs, rhs, TokLoc, result);
+    CompTy = CheckMultiplyDivideOperands(lhs, rhs, TokLoc);
+    if (!CompTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
     break;
   case BinaryOperator::RemAssign:
-    result = CheckRemainderOperands(lhs, rhs, TokLoc);
-    if (result.isNull())
-      return true;
-    result = CheckAssignmentOperands(lhs, rhs, TokLoc, result);
+    CompTy = CheckRemainderOperands(lhs, rhs, TokLoc);
+    if (!CompTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
     break;
   case BinaryOperator::AddAssign:
-    result = CheckAdditionOperands(lhs, rhs, TokLoc);
-    if (result.isNull())
-      return true;
-    result = CheckAssignmentOperands(lhs, rhs, TokLoc, result);
+    CompTy = CheckAdditionOperands(lhs, rhs, TokLoc);
+    if (!CompTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
     break;
   case BinaryOperator::SubAssign:
-    result = CheckSubtractionOperands(lhs, rhs, TokLoc);
-    if (result.isNull())
-      return true;
-    result = CheckAssignmentOperands(lhs, rhs, TokLoc, result);
+    CompTy = CheckSubtractionOperands(lhs, rhs, TokLoc);
+    if (!CompTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
     break;
   case BinaryOperator::ShlAssign:
   case BinaryOperator::ShrAssign:
-    result = CheckShiftOperands(lhs, rhs, TokLoc);
-    if (result.isNull())
-      return true;
-    result = CheckAssignmentOperands(lhs, rhs, TokLoc, result);
+    CompTy = CheckShiftOperands(lhs, rhs, TokLoc);
+    if (!CompTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
     break;
   case BinaryOperator::AndAssign:
   case BinaryOperator::XorAssign:
   case BinaryOperator::OrAssign:
-    result = CheckBitwiseOperands(lhs, rhs, TokLoc);
-    if (result.isNull())
-      return true;
-    result = CheckAssignmentOperands(lhs, rhs, TokLoc, result);
+    CompTy = CheckBitwiseOperands(lhs, rhs, TokLoc);
+    if (!CompTy.isNull())
+      ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
     break;
   case BinaryOperator::Comma:
-    result = CheckCommaOperands(lhs, rhs, TokLoc);
+    ResultTy = CheckCommaOperands(lhs, rhs, TokLoc);
     break;
   }
-  if (result.isNull())
+  if (ResultTy.isNull())
     return true;
-  return new BinaryOperator(lhs, rhs, Opc, result);
+  if (CompTy.isNull())
+    return new BinaryOperator(lhs, rhs, Opc, ResultTy);
+  else
+    return new ArithAssignBinaryOperator(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=39700&r1=39699&r2=39700&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:47:17 2007
@@ -477,8 +477,11 @@
     Comma             // [C99 6.5.17] Comma operator.
   };
   
-  BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType t=QualType())
-    : Expr(BinaryOperatorClass, t), LHS(lhs), RHS(rhs), Opc(opc) {}
+  BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy)
+    : Expr(BinaryOperatorClass, ResTy), LHS(lhs), RHS(rhs), Opc(opc) {
+    assert(!isCompoundAssignmentOp() && 
+           "Use ArithAssignBinaryOperator for compound assignments");
+  }
 
   Opcode getOpcode() const { return Opc; }
   Expr *getLHS() const { return LHS; }
@@ -500,6 +503,7 @@
   bool isEqualityOp() const { return Opc == EQ || Opc == NE; }
   bool isLogicalOp() const { return Opc == LAnd || Opc == LOr; }
   bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
+  bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
   
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
@@ -509,6 +513,37 @@
 private:
   Expr *LHS, *RHS;
   Opcode Opc;
+protected:
+  BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, bool dead)
+    : Expr(BinaryOperatorClass, ResTy), LHS(lhs), RHS(rhs), Opc(opc) {
+  }
+};
+
+/// CompoundAssignmentOperator - 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 {
+  QualType ComputationType;
+public:
+  ArithAssignBinaryOperator(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");
+  }
+
+  QualType getComputationType() const { return ComputationType; }
+  
+  static bool classof(const ArithAssignBinaryOperator *) { return true; }
+  static bool classof(const BinaryOperator *B) { 
+    return B->isCompoundAssignmentOp(); 
+  }
+  static bool classof(const Stmt *S) { 
+    return isa<BinaryOperator>(S) && classof(cast<BinaryOperator>(S));
+  }
 };
 
 /// ConditionalOperator - The ?: operator.  Note that LHS may be null when the





More information about the cfe-commits mailing list