]> granicus.if.org Git - clang/commitdiff
Add a Expr::isEvaluatable method, eliminate isBuiltinConstantExpr
authorChris Lattner <sabre@nondot.org>
Mon, 6 Oct 2008 06:49:02 +0000 (06:49 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 6 Oct 2008 06:49:02 +0000 (06:49 +0000)
which is checking for something that can be inconsistent with
what we can constant fold.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57159 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/AST/Expr.cpp
lib/AST/ExprConstant.cpp
lib/Sema/SemaDecl.cpp

index df7a83bcbfb33b797cc28e5a78bae8cca98f7d9d..2b42424803dbdf9076277b4054e266c949ec6ab7 100644 (file)
@@ -124,6 +124,10 @@ public:
   /// we want to.  If this function returns true, it returns the folded constant
   /// in Result.
   bool tryEvaluate(APValue& Result, ASTContext &Ctx) const;
+  
+  /// isEvaluatable - Call tryEvaluate to see if this expression can be constant
+  /// folded, but discard the result.
+  bool isEvaluatable(ASTContext &Ctx) const;
 
   /// hasGlobalStorage - Return true if this expression has static storage
   /// duration.  This means that the address of this expression is a link-time
@@ -709,10 +713,6 @@ public:
   /// not, return 0.
   unsigned isBuiltinCall() const;
   
-  
-  /// isBuiltinConstantExpr - Return true if this built-in call is constant.
-  bool isBuiltinConstantExpr(ASTContext &Ctx) const;
-  
   SourceLocation getRParenLoc() const { return RParenLoc; }
 
   virtual SourceRange getSourceRange() const { 
index 45363d69925fc7b39b9257ef2633fd8546e81112..6cdaacd6897903b935a2b199de83486a56ac11c5 100644 (file)
@@ -162,12 +162,6 @@ unsigned CallExpr::isBuiltinCall() const {
 }
 
 
-bool CallExpr::isBuiltinConstantExpr(ASTContext &Ctx) const {
-  unsigned BID = isBuiltinCall();
-  if (!BID) return false;
-  return Ctx.BuiltinInfo.isConstantExpr(BID);
-}
-
 /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
 /// corresponds to, e.g. "<<=".
 const char *BinaryOperator::getOpcodeStr(Opcode Op) {
@@ -519,8 +513,11 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
     return true;
   case CallExprClass: {
     const CallExpr *CE = cast<CallExpr>(this);
-    if (CE->isBuiltinConstantExpr(Ctx))
+
+    // Allow any constant foldable calls to builtins.
+    if (CE->isBuiltinCall() && CE->isEvaluatable(Ctx))
       return true;
+    
     if (Loc) *Loc = getLocStart();
     return false;
   }
index 1506f448aa091b0a54f5a34941232f4c948c4b11..af30ceb96c3ed1b3599be1e67e6e171bea6a3c53 100644 (file)
@@ -693,3 +693,10 @@ bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
       
   return false;
 }
+
+/// isEvaluatable - Call tryEvaluate to see if this expression can be constant
+/// folded, but discard the result.
+bool Expr::isEvaluatable(ASTContext &Ctx) const {
+  APValue V;
+  return tryEvaluate(V, Ctx);
+}
index 74ce855add5baecb277f541dfe7f139d7163ed8f..125d91cdbafbd1dbe15b3d4fdc52afaeb8b7cb58 100644 (file)
@@ -879,14 +879,6 @@ bool Sema::CheckAddressConstantExpression(const Expr* Init) {
   case Expr::StringLiteralClass:
   case Expr::ObjCStringLiteralClass:
     return false;
-  case Expr::CallExprClass: {
-    const CallExpr *CE = cast<CallExpr>(Init);
-    if (CE->isBuiltinConstantExpr(Context))
-      return false;
-    Diag(Init->getExprLoc(),
-         diag::err_init_element_not_constant, Init->getSourceRange());
-    return true;
-  }
   case Expr::UnaryOperatorClass: {
     const UnaryOperator *Exp = cast<UnaryOperator>(Init);
 
@@ -1080,8 +1072,11 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) {
     return false;
   case Expr::CallExprClass: {
     const CallExpr *CE = cast<CallExpr>(Init);
-    if (CE->isBuiltinConstantExpr(Context))
+
+    // Allow any constant foldable calls to builtins.
+    if (CE->isBuiltinCall() && CE->isEvaluatable(Context))
       return false;
+    
     Diag(Init->getExprLoc(),
          diag::err_init_element_not_constant, Init->getSourceRange());
     return true;
@@ -1226,7 +1221,7 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) {
     // Okay, the evaluated side evaluates to a constant, so we accept this.
     // Check to see if the other side is obviously not a constant.  If so, 
     // emit a warning that this is a GNU extension.
-    if (FalseSide && !FalseSide->tryEvaluate(Val, Context))
+    if (FalseSide && !FalseSide->isEvaluatable(Context))
       Diag(Init->getExprLoc(), 
            diag::ext_typecheck_expression_not_constant_but_accepted,
            FalseSide->getSourceRange());