Evaluate result into an explicit destination. No functionality change.

llvm-svn: 39402
This commit is contained in:
Chris Lattner 2007-04-10 07:07:11 +00:00
parent 9e2fcccc33
commit 9cc755d535
1 changed files with 39 additions and 29 deletions

View File

@ -422,6 +422,7 @@ static bool EvaluateDirectiveSubExpr(APSInt &LHS, unsigned MinPrec,
// FIXME: All of these should detect and report overflow?? // FIXME: All of these should detect and report overflow??
bool Overflow = false; bool Overflow = false;
APSInt Res(LHS.getBitWidth());
switch (Operator) { switch (Operator) {
default: assert(0 && "Unknown operator token!"); default: assert(0 && "Unknown operator token!");
case tok::percent: case tok::percent:
@ -429,17 +430,17 @@ static bool EvaluateDirectiveSubExpr(APSInt &LHS, unsigned MinPrec,
if (ValueLive) PP.Diag(OpToken, diag::err_pp_remainder_by_zero); if (ValueLive) PP.Diag(OpToken, diag::err_pp_remainder_by_zero);
return true; return true;
} }
LHS %= RHS; Res = LHS % RHS;
break; break;
case tok::slash: case tok::slash:
if (RHS == 0) { if (RHS == 0) {
if (ValueLive) PP.Diag(OpToken, diag::err_pp_division_by_zero); if (ValueLive) PP.Diag(OpToken, diag::err_pp_division_by_zero);
return true; return true;
} }
LHS /= RHS; Res = LHS / RHS;
break; break;
case tok::star: case tok::star:
LHS *= RHS; Res = LHS * RHS;
break; break;
case tok::lessless: { case tok::lessless: {
// Determine whether overflow is about to happen. // Determine whether overflow is about to happen.
@ -453,7 +454,7 @@ static bool EvaluateDirectiveSubExpr(APSInt &LHS, unsigned MinPrec,
else else
Overflow = ShAmt >= LHS.countLeadingOnes(); Overflow = ShAmt >= LHS.countLeadingOnes();
LHS <<= ShAmt; Res = LHS << ShAmt;
break; break;
} }
case tok::greatergreater: { case tok::greatergreater: {
@ -461,53 +462,59 @@ static bool EvaluateDirectiveSubExpr(APSInt &LHS, unsigned MinPrec,
unsigned ShAmt = RHS.getLimitedValue(); unsigned ShAmt = RHS.getLimitedValue();
if (ShAmt >= LHS.getBitWidth()) if (ShAmt >= LHS.getBitWidth())
Overflow = true, ShAmt = LHS.getBitWidth()-1; Overflow = true, ShAmt = LHS.getBitWidth()-1;
LHS >>= ShAmt; Res = LHS >> ShAmt;
break; break;
} }
case tok::plus: case tok::plus:
LHS += RHS; Res = LHS + RHS;
break; break;
case tok::minus: case tok::minus:
LHS -= RHS; Res = LHS - RHS;
break; break;
case tok::lessequal: case tok::lessequal:
LHS = LHS <= RHS; Res = LHS <= RHS;
LHS.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed) Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
break; break;
case tok::less: case tok::less:
LHS = LHS < RHS; Res = LHS < RHS;
LHS.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed) Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
break; break;
case tok::greaterequal: case tok::greaterequal:
LHS = LHS >= RHS; Res = LHS >= RHS;
LHS.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed) Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
break; break;
case tok::greater: case tok::greater:
LHS = LHS > RHS; Res = LHS > RHS;
LHS.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed) Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
break; break;
case tok::exclaimequal: case tok::exclaimequal:
LHS = LHS != RHS; Res = LHS != RHS;
LHS.setIsUnsigned(false); // C99 6.5.9p3, result is always int (signed) Res.setIsUnsigned(false); // C99 6.5.9p3, result is always int (signed)
break; break;
case tok::equalequal: case tok::equalequal:
LHS = LHS == RHS; Res = LHS == RHS;
LHS.setIsUnsigned(false); // C99 6.5.9p3, result is always int (signed) Res.setIsUnsigned(false); // C99 6.5.9p3, result is always int (signed)
break;
case tok::amp:
Res = LHS & RHS;
break;
case tok::caret:
Res = LHS ^ RHS;
break;
case tok::pipe:
Res = LHS | RHS;
break; break;
case tok::amp: LHS &= RHS; break;
case tok::caret: LHS ^= RHS; break;
case tok::pipe: LHS |= RHS; break;
case tok::ampamp: case tok::ampamp:
LHS = LHS != 0 && RHS != 0; Res = (LHS != 0 && RHS != 0);
LHS.setIsUnsigned(false); // C99 6.5.13p3, result is always int (signed) Res.setIsUnsigned(false); // C99 6.5.13p3, result is always int (signed)
break; break;
case tok::pipepipe: case tok::pipepipe:
LHS = LHS != 0 || RHS != 0; Res = (LHS != 0 || RHS != 0);
LHS.setIsUnsigned(false); // C99 6.5.14p3, result is always int (signed) Res.setIsUnsigned(false); // C99 6.5.14p3, result is always int (signed)
break; break;
case tok::comma: case tok::comma:
PP.Diag(OpToken, diag::ext_pp_comma_expr); PP.Diag(OpToken, diag::ext_pp_comma_expr);
LHS = RHS; // LHS = LHS,RHS -> RHS. Res = RHS; // LHS = LHS,RHS -> RHS.
break; break;
case tok::question: { case tok::question: {
// Parse the : part of the expression. // Parse the : part of the expression.
@ -531,11 +538,11 @@ static bool EvaluateDirectiveSubExpr(APSInt &LHS, unsigned MinPrec,
return true; return true;
// Now that we have the condition, the LHS and the RHS of the :, evaluate. // Now that we have the condition, the LHS and the RHS of the :, evaluate.
LHS = LHS != 0 ? RHS : AfterColonVal; Res = LHS != 0 ? RHS : AfterColonVal;
// Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
// either operand is unsigned. // either operand is unsigned.
LHS.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned()); Res.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned());
// Figure out the precedence of the token after the : part. // Figure out the precedence of the token after the : part.
PeekPrec = getPrecedence(PeekTok.getKind()); PeekPrec = getPrecedence(PeekTok.getKind());
@ -550,6 +557,9 @@ static bool EvaluateDirectiveSubExpr(APSInt &LHS, unsigned MinPrec,
// If this operator is live and overflowed, report the issue. // If this operator is live and overflowed, report the issue.
if (Overflow && ValueLive) if (Overflow && ValueLive)
PP.Diag(OpToken, diag::warn_pp_expr_overflow); PP.Diag(OpToken, diag::warn_pp_expr_overflow);
// Put the result back into 'LHS' for our next iteration.
LHS = Res;
} }
return false; return false;