From: Chris Lattner Date: Sun, 15 Jul 2007 23:26:56 +0000 (+0000) Subject: Refactor code so that isIntegerConstantExpr has an ASTContext available. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=590b6646ef747d2f7b42e5f40487ff07642d7b6f;p=clang 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 --- diff --git a/AST/Expr.cpp b/AST/Expr.cpp index 7638d21ed5..f7bf8e58a5 100644 --- a/AST/Expr.cpp +++ b/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(this)->getSubExpr()-> - isIntegerConstantExpr(Result, Loc, isEvaluated); + isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated); case ParenExprClass: return cast(this)->getSubExpr()-> - isIntegerConstantExpr(Result, Loc, isEvaluated); + isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated); case IntegerLiteralClass: Result = cast(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(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(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(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(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(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; } diff --git a/AST/Type.cpp b/AST/Type.cpp index a2dcac22f9..5bcc19c2a3 100644 --- a/AST/Type.cpp +++ b/AST/Type.cpp @@ -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(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; } diff --git a/CodeGen/CGDecl.cpp b/CodeGen/CGDecl.cpp index d86f305151..63b9d6f881 100644 --- a/CodeGen/CGDecl.cpp +++ b/CodeGen/CGDecl.cpp @@ -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 { diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index 58ed48e899..3ec0f25064 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -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")); } diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index 262469e34b..a1a498b082 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -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!"); diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index 5bae791080..22ee504662 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -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 { diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index aebc266970..baa54649a2 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -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(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(); diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index cde73ce7d6..8029e822ba 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -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()); diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp index 7333dd507b..ce3f750dda 100644 --- a/Sema/SemaStmt.cpp +++ b/Sema/SemaStmt.cpp @@ -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()); diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 7e288110f5..410c650958 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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); diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index a4f596cf3b..c84f8ebf46 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -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