Remove an extraneous QualType from CastExpr, it's type is always

the result type of the expr node.

Implement isIntegerConstantExpr for ImplicitCastExpr nodes the same
was as for CastExpr nodes.

Implement proper sign/zero extension as well as truncation and noop
conversion in the i-c-e evaluator.  This allows us to correctly
handle i-c-e's like these:

char array[1024/(sizeof (long))];
int x['\xBb' == (char) 187 ? 1: -1];

this implements test/Sema/i-c-e2.c

llvm-svn: 39888
This commit is contained in:
Chris Lattner 2007-07-15 23:54:50 +00:00
parent 48f84b85b7
commit 51aff8bd7c
4 changed files with 31 additions and 19 deletions

View File

@ -279,9 +279,6 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
default:
if (Loc) *Loc = getLocStart();
return false;
case ImplicitCastExprClass:
return cast<ImplicitCastExpr>(this)->getSubExpr()->
isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()->
isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
@ -455,27 +452,44 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
break;
}
case ImplicitCastExprClass:
case CastExprClass: {
const CastExpr *Exp = cast<CastExpr>(this);
const Expr *SubExpr;
SourceLocation CastLoc;
if (const CastExpr *C = dyn_cast<CastExpr>(this)) {
SubExpr = C->getSubExpr();
CastLoc = C->getLParenLoc();
} else {
SubExpr = cast<ImplicitCastExpr>(this)->getSubExpr();
CastLoc = getLocStart();
}
// C99 6.6p6: shall only convert arithmetic types to integer types.
if (!Exp->getSubExpr()->getType()->isArithmeticType() ||
!Exp->getDestType()->isIntegerType()) {
if (Loc) *Loc = Exp->getSubExpr()->getLocStart();
if (!SubExpr->getType()->isArithmeticType() ||
!getType()->isIntegerType()) {
if (Loc) *Loc = SubExpr->getLocStart();
return false;
}
// Handle simple integer->integer casts.
if (Exp->getSubExpr()->getType()->isIntegerType()) {
if (!Exp->getSubExpr()->isIntegerConstantExpr(Result, Ctx,
Loc, isEvaluated))
if (SubExpr->getType()->isIntegerType()) {
if (!SubExpr->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
return false;
// FIXME: do the conversion on Result.
// Figure out if this is a truncate, extend or noop cast.
unsigned DestWidth = Ctx.getTypeSize(getType(), CastLoc);
// If the input is signed, do a sign extend, noop, or truncate.
if (SubExpr->getType()->isSignedIntegerType())
Result.sextOrTrunc(DestWidth);
else // If the input is unsigned, do a zero extend, noop, or truncate.
Result.zextOrTrunc(DestWidth);
break;
}
// Allow floating constants that are the immediate operands of casts or that
// are parenthesized.
const Expr *Operand = Exp->getSubExpr();
const Expr *Operand = SubExpr;
while (const ParenExpr *PE = dyn_cast<ParenExpr>(Operand))
Operand = PE->getSubExpr();

View File

@ -420,7 +420,7 @@ void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
OS << Field->getName();
}
void StmtPrinter::VisitCastExpr(CastExpr *Node) {
OS << "(" << Node->getDestType().getAsString() << ")";
OS << "(" << Node->getType().getAsString() << ")";
PrintExpr(Node->getSubExpr());
}
void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {

View File

@ -456,16 +456,14 @@ public:
/// CastExpr - [C99 6.5.4] Cast Operators.
///
class CastExpr : public Expr {
QualType Ty;
Expr *Op;
SourceLocation Loc; // the location of the left paren
public:
CastExpr(QualType ty, Expr *op, SourceLocation l) :
Expr(CastExprClass, ty), Ty(ty), Op(op), Loc(l) {}
Expr(CastExprClass, ty), Op(op), Loc(l) {}
SourceLocation getLParenLoc() const { return Loc; }
QualType getDestType() const { return Ty; }
Expr *getSubExpr() const { return Op; }
virtual SourceRange getSourceRange() const {

View File

@ -1,6 +1,6 @@
// RUN: clang %s -fsyntax-only
// FIXME: This fails until conversions are fully explicit in the ast and i-c-e is updated to handle this.
// XFAIL: *
char array[1024/(sizeof (long))];
int x['\xBb' == (char) 187 ? 1: -1];