Refactor code so that isIntegerConstantExpr has an ASTContext available.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39884 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-07-15 23:26:56 +00:00
Родитель dda75cf84c
Коммит 590b6646ef
11 изменённых файлов: 48 добавлений и 43 удалений

Просмотреть файл

@ -272,18 +272,18 @@ Expr::isModifiableLvalueResult Expr::isModifiableLvalue() {
///
/// FIXME: This should ext-warn on overflow during evaluation! ISO C does not
/// permit this.
bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
bool isEvaluated) const {
bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc, bool isEvaluated) const {
switch (getStmtClass()) {
default:
if (Loc) *Loc = getLocStart();
return false;
case ImplicitCastExprClass:
return cast<ImplicitCastExpr>(this)->getSubExpr()->
isIntegerConstantExpr(Result, Loc, isEvaluated);
isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()->
isIntegerConstantExpr(Result, Loc, isEvaluated);
isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
case IntegerLiteralClass:
Result = cast<IntegerLiteral>(this)->getValue();
break;
@ -306,7 +306,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
// Get the operand value. If this is sizeof/alignof, do not evalute the
// operand. This affects C99 6.6p3.
if (Exp->isSizeOfAlignOfOp()) isEvaluated = false;
if (!Exp->getSubExpr()->isIntegerConstantExpr(Result, Loc, isEvaluated))
if (!Exp->getSubExpr()->isIntegerConstantExpr(Result, Ctx,Loc, isEvaluated))
return false;
switch (Exp->getOpcode()) {
@ -320,7 +320,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
case UnaryOperator::SizeOf:
case UnaryOperator::AlignOf:
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
if (!Exp->getSubExpr()->getType()->isConstantSizeType(Loc))
if (!Exp->getSubExpr()->getType()->isConstantSizeType(Ctx, Loc))
return false;
// FIXME: Evaluate sizeof/alignof.
@ -350,7 +350,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
case SizeOfAlignOfTypeExprClass: {
const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
// alignof always evaluates to a constant.
if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType(Loc))
if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType(Ctx,Loc))
return false;
// FIXME: Evaluate sizeof/alignof.
@ -362,7 +362,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
const BinaryOperator *Exp = cast<BinaryOperator>(this);
// The LHS of a constant expr is always evaluated and needed.
if (!Exp->getLHS()->isIntegerConstantExpr(Result, Loc, isEvaluated))
if (!Exp->getLHS()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
return false;
llvm::APSInt RHS(Result);
@ -378,11 +378,11 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
RHSEval = Result == 0;
}
if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Loc,
if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Ctx, Loc,
isEvaluated & RHSEval))
return false;
} else {
if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Loc, isEvaluated))
if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Ctx, Loc, isEvaluated))
return false;
}
@ -463,7 +463,8 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
// Handle simple integer->integer casts.
if (Exp->getSubExpr()->getType()->isIntegerType()) {
if (!Exp->getSubExpr()->isIntegerConstantExpr(Result, Loc, isEvaluated))
if (!Exp->getSubExpr()->isIntegerConstantExpr(Result, Ctx,
Loc, isEvaluated))
return false;
// FIXME: do the conversion on Result.
break;
@ -486,7 +487,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
case ConditionalOperatorClass: {
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
if (!Exp->getCond()->isIntegerConstantExpr(Result, Loc, isEvaluated))
if (!Exp->getCond()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
return false;
const Expr *TrueExp = Exp->getLHS();
@ -494,10 +495,10 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
if (Result == 0) std::swap(TrueExp, FalseExp);
// Evaluate the false one first, discard the result.
if (!FalseExp->isIntegerConstantExpr(Result, Loc, false))
if (!FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))
return false;
// Evalute the true one, capture the result.
if (!TrueExp->isIntegerConstantExpr(Result, Loc, isEvaluated))
if (!TrueExp->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
return false;
// FIXME: promotions on result.
break;
@ -513,7 +514,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
/// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an
/// integer constant expression with the value zero, or if this is one that is
/// cast to void*.
bool Expr::isNullPointerConstant() const {
bool Expr::isNullPointerConstant(ASTContext &Ctx) const {
// Strip off a cast to void*, if it exists.
if (const CastExpr *CE = dyn_cast<CastExpr>(this)) {
// Check that it is a cast to void*.
@ -521,12 +522,12 @@ bool Expr::isNullPointerConstant() const {
QualType Pointee = PT->getPointeeType();
if (Pointee.getQualifiers() == 0 && Pointee->isVoidType() && // to void*
CE->getSubExpr()->getType()->isIntegerType()) // from int.
return CE->getSubExpr()->isNullPointerConstant();
return CE->getSubExpr()->isNullPointerConstant(Ctx);
}
} else if (const ParenExpr *PE = dyn_cast<ParenExpr>(this)) {
// Accept ((void*)0) as a null pointer constant, as many other
// implementations do.
return PE->getSubExpr()->isNullPointerConstant();
return PE->getSubExpr()->isNullPointerConstant(Ctx);
}
// This expression must be an integer type.
@ -536,5 +537,5 @@ bool Expr::isNullPointerConstant() const {
// If we have an integer constant expression, we need to *evaluate* it and
// test for the value 0.
llvm::APSInt Val(32);
return isIntegerConstantExpr(Val, 0, true) && Val == 0;
return isIntegerConstantExpr(Val, Ctx, 0, true) && Val == 0;
}

Просмотреть файл

@ -328,11 +328,11 @@ bool Type::isAggregateType() const {
// The only variable size types are auto arrays within a function. Structures
// cannot contain a VLA member. They can have a flexible array member, however
// the structure is still constant size (C99 6.7.2.1p16).
bool Type::isConstantSizeType(SourceLocation *loc) const {
bool Type::isConstantSizeType(ASTContext &Ctx, SourceLocation *loc) const {
if (const ArrayType *Ary = dyn_cast<ArrayType>(CanonicalType)) {
assert(Ary->getSizeExpr() && "Incomplete types don't have a size at all!");
// Variable Length Array?
return Ary->getSizeExpr()->isIntegerConstantExpr(loc);
return Ary->getSizeExpr()->isIntegerConstantExpr(Ctx, loc);
}
return true;
}

Просмотреть файл

@ -69,7 +69,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const BlockVarDecl &D) {
QualType Ty = D.getCanonicalType();
llvm::Value *DeclPtr;
if (Ty->isConstantSizeType()) {
if (Ty->isConstantSizeType(getContext())) {
// A normal fixed sized variable becomes an alloca in the entry block.
const llvm::Type *LTy = ConvertType(Ty);
// TODO: Alignment
@ -93,7 +93,7 @@ void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) {
QualType Ty = D.getCanonicalType();
llvm::Value *DeclPtr;
if (!Ty->isConstantSizeType()) {
if (!Ty->isConstantSizeType(getContext())) {
// Variable sized values always are passed by-reference.
DeclPtr = Arg;
} else {

Просмотреть файл

@ -429,7 +429,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
// We know that the pointer points to a type of the correct size, unless the
// size is a VLA.
if (!E->getType()->isConstantSizeType())
if (!E->getType()->isConstantSizeType(getContext()))
assert(0 && "VLA idx not implemented");
return LValue::MakeAddr(Builder.CreateGEP(Base, Idx, "arrayidx"));
}

Просмотреть файл

@ -70,7 +70,7 @@ void CodeGenModule::EmitGlobalVar(const FileVarDecl *D) {
} else if (D->getType()->isIntegerType()) {
llvm::APSInt Value(getContext().getTypeSize(D->getInit()->getType(),
SourceLocation()));
if (D->getInit()->isIntegerConstantExpr(Value))
if (D->getInit()->isIntegerConstantExpr(Value, Context))
Init = llvm::ConstantInt::get(Value);
}
assert(Init && "FIXME: Global variable initializers unimp!");

Просмотреть файл

@ -85,7 +85,8 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
"FIXME: We only handle trivial array types so far!");
llvm::APSInt Size(32);
if (A.getSizeExpr() && A.getSizeExpr()->isIntegerConstantExpr(Size)) {
if (A.getSizeExpr() &&
A.getSizeExpr()->isIntegerConstantExpr(Size, Context)) {
const llvm::Type *EltTy = ConvertType(A.getElementType());
return llvm::ArrayType::get(EltTy, Size.getZExtValue());
} else {

Просмотреть файл

@ -41,7 +41,7 @@ bool Sema::VerifyConstantArrayType(const ArrayType *Array,
// Verify that the size of the array is an integer constant expr.
SourceLocation Loc;
llvm::APSInt SizeVal(32);
if (!Size->isIntegerConstantExpr(SizeVal, &Loc)) {
if (!Size->isIntegerConstantExpr(SizeVal, Context, &Loc)) {
// FIXME: This emits the diagnostic to enforce 6.7.2.1p8, but the message
// is wrong. It is also wrong for static variables.
// FIXME: This is also wrong for:
@ -879,7 +879,7 @@ Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *theEnumDecl,
if (Val) {
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
SourceLocation ExpLoc;
if (!Val->isIntegerConstantExpr(EnumVal, &ExpLoc)) {
if (!Val->isIntegerConstantExpr(EnumVal, Context, &ExpLoc)) {
Diag(ExpLoc, diag::err_enum_value_not_integer_constant_expr,
Id->getName());
// FIXME: Don't leak memory: delete Val;
@ -981,7 +981,7 @@ QualType Sema::HandleVectorTypeAttribute(QualType curType,
}
Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
llvm::APSInt vecSize(32);
if (!sizeExpr->isIntegerConstantExpr(vecSize)) {
if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
sizeExpr->getSourceRange());
return QualType();

Просмотреть файл

@ -439,7 +439,7 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
break;
case PointerFromInt:
// check for null pointer constant (C99 6.3.2.3p3)
if (!argExpr->isNullPointerConstant()) {
if (!argExpr->isNullPointerConstant(Context)) {
Diag(l, diag::ext_typecheck_passing_pointer_int,
lhsType.getAsString(), rhsType.getAsString(),
funcExpr->getSourceRange(), argExpr->getSourceRange());
@ -513,9 +513,10 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
return QualType();
}
}
if (lexT->isPointerType() && rex->isNullPointerConstant()) // C99 6.5.15p3
// C99 6.5.15p3
if (lexT->isPointerType() && rex->isNullPointerConstant(Context))
return lexT;
if (rexT->isPointerType() && lex->isNullPointerConstant())
if (rexT->isPointerType() && lex->isNullPointerConstant(Context))
return rexT;
if (lexT->isPointerType() && rexT->isPointerType()) { // C99 6.5.15p3,6
@ -885,14 +886,14 @@ inline QualType Sema::CheckRelationalOperands( // C99 6.5.8
if (rType->isPointerType())
return Context.IntTy;
if (rType->isIntegerType()) {
if (!rex->isNullPointerConstant())
if (!rex->isNullPointerConstant(Context))
Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
lex->getSourceRange(), rex->getSourceRange());
return Context.IntTy; // the previous diagnostic is a GCC extension.
}
} else if (rType->isPointerType()) {
if (lType->isIntegerType()) {
if (!lex->isNullPointerConstant())
if (!lex->isNullPointerConstant(Context))
Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
lex->getSourceRange(), rex->getSourceRange());
return Context.IntTy; // the previous diagnostic is a GCC extension.
@ -915,14 +916,14 @@ inline QualType Sema::CheckEqualityOperands( // C99 6.5.9
if (rType->isPointerType())
return Context.IntTy;
if (rType->isIntegerType()) {
if (!rex->isNullPointerConstant())
if (!rex->isNullPointerConstant(Context))
Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
lex->getSourceRange(), rex->getSourceRange());
return Context.IntTy; // the previous diagnostic is a GCC extension.
}
} else if (rType->isPointerType()) {
if (lType->isIntegerType()) {
if (!lex->isNullPointerConstant())
if (!lex->isNullPointerConstant(Context))
Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
lex->getSourceRange(), rex->getSourceRange());
return Context.IntTy; // the previous diagnostic is a GCC extension.
@ -1015,7 +1016,7 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1
break;
case PointerFromInt:
// check for null pointer constant (C99 6.3.2.3p3)
if (compoundType.isNull() && !rex->isNullPointerConstant()) {
if (compoundType.isNull() && !rex->isNullPointerConstant(Context)) {
Diag(loc, diag::ext_typecheck_assign_pointer_int,
lhsType.getAsString(), rhsType.getAsString(),
lex->getSourceRange(), rex->getSourceRange());

Просмотреть файл

@ -58,7 +58,7 @@ Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval,
SourceLocation ExpLoc;
// C99 6.8.4.2p3: The expression shall be an integer constant.
if (!LHSVal->isIntegerConstantExpr(&ExpLoc))
if (!LHSVal->isIntegerConstantExpr(Context, &ExpLoc))
return Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
LHSVal->getSourceRange());
@ -269,7 +269,7 @@ Sema::ParseReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) {
break;
case PointerFromInt:
// check for null pointer constant (C99 6.3.2.3p3)
if (!RetValExp->isNullPointerConstant()) {
if (!RetValExp->isNullPointerConstant(Context)) {
Diag(ReturnLoc, diag::ext_typecheck_return_pointer_int,
lhsType.getAsString(), rhsType.getAsString(),
RetValExp->getSourceRange());

Просмотреть файл

@ -22,6 +22,7 @@
namespace clang {
class IdentifierInfo;
class Decl;
class ASTContext;
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
@ -85,17 +86,18 @@ public:
};
isModifiableLvalueResult isModifiableLvalue();
bool isNullPointerConstant() const;
bool isNullPointerConstant(ASTContext &Ctx) const;
/// isIntegerConstantExpr - Return true if this expression is a valid integer
/// constant expression, and, if so, return its value in Result. If not a
/// valid i-c-e, return false and fill in Loc (if specified) with the location
/// of the invalid expression.
bool isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc = 0,
bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc = 0,
bool isEvaluated = true) const;
bool isIntegerConstantExpr(SourceLocation *Loc = 0) const {
bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const {
llvm::APSInt X(32);
return isIntegerConstantExpr(X, Loc);
return isIntegerConstantExpr(X, Ctx, Loc);
}
virtual void visit(StmtVisitor &Visitor);

Просмотреть файл

@ -257,7 +257,7 @@ public:
/// according to the rules of C99 6.7.5p3. If Loc is non-null, it is set to
/// the location of the subexpression that makes it a vla type. It is not
/// legal to call this on incomplete types.
bool isConstantSizeType(SourceLocation *Loc = 0) const;
bool isConstantSizeType(ASTContext &Ctx, SourceLocation *Loc = 0) const;
/// Compatibility predicates used to check assignment expressions.
static bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1