[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