зеркало из https://github.com/microsoft/clang.git
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:
Родитель
dda75cf84c
Коммит
590b6646ef
37
AST/Expr.cpp
37
AST/Expr.cpp
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче