Shuffle things around in preparation for integrating Eli's constant evaluator.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53074 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 58dadb0..de0c740 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -13,6 +13,7 @@
 
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/APValue.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/TargetInfo.h"
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
new file mode 100644
index 0000000..ea9b106
--- /dev/null
+++ b/lib/AST/ExprConstant.cpp
@@ -0,0 +1,60 @@
+//===--- Expr.cpp - Expression Constant Evaluator -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Expr constant evaluator.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+using namespace clang;
+
+
+static bool CalcFakeICEVal(const Expr* Expr,
+                           llvm::APSInt& Result,
+                           ASTContext& Context) {
+  // Calculate the value of an expression that has a calculatable
+  // value, but isn't an ICE. Currently, this only supports
+  // a very narrow set of extensions, but it can be expanded if needed.
+  if (const ParenExpr *PE = dyn_cast<ParenExpr>(Expr))
+    return CalcFakeICEVal(PE->getSubExpr(), Result, Context);
+  
+  if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
+    QualType CETy = CE->getType();
+    if ((CETy->isIntegralType() && !CETy->isBooleanType()) ||
+        CETy->isPointerType()) {
+      if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) {
+        Result.extOrTrunc(Context.getTypeSize(CETy));
+        // FIXME: This assumes pointers are signed.
+        Result.setIsSigned(CETy->isSignedIntegerType() ||
+                           CETy->isPointerType());
+        return true;
+      }
+    }
+  }
+  
+  if (Expr->getType()->isIntegralType())
+    return Expr->isIntegerConstantExpr(Result, Context);
+  
+  return false;
+}
+
+bool Expr::tryEvaluate(APValue& Result, ASTContext &Ctx) const
+{
+  llvm::APSInt sInt(1);
+  
+  if (CalcFakeICEVal(this, sInt, Ctx)) {
+    Result = APValue(sInt);
+    return true;
+  }
+  
+  return false;
+}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c0c3f09..80c37b9 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "clang/AST/APValue.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -1799,48 +1800,20 @@
   CollectIvars(Class, Decls);
 }
 
-
-static bool CalcFakeICEVal(const Expr* Expr,
-                           llvm::APSInt& Result,
-                           ASTContext& Context) {
-  // Calculate the value of an expression that has a calculatable
-  // value, but isn't an ICE. Currently, this only supports
-  // a very narrow set of extensions, but it can be expanded if needed.
-  if (const ParenExpr *PE = dyn_cast<ParenExpr>(Expr))
-    return CalcFakeICEVal(PE->getSubExpr(), Result, Context);
-
-  if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
-    QualType CETy = CE->getType();
-    if ((CETy->isIntegralType() && !CETy->isBooleanType()) ||
-        CETy->isPointerType()) {
-      if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) {
-        Result.extOrTrunc(Context.getTypeSize(CETy));
-        // FIXME: This assumes pointers are signed.
-        Result.setIsSigned(CETy->isSignedIntegerType() ||
-                           CETy->isPointerType());
-        return true;
-      }
-    }
-  }
-
-  if (Expr->getType()->isIntegralType())
-    return Expr->isIntegerConstantExpr(Result, Context);
-
-  return false;
-}
-
 QualType Sema::TryFixInvalidVariablyModifiedType(QualType T) {
   // This method tries to turn a variable array into a constant
   // array even when the size isn't an ICE.  This is necessary
   // for compatibility with code that depends on gcc's buggy
   // constant expression folding, like struct {char x[(int)(char*)2];}
   if (const VariableArrayType* VLATy = dyn_cast<VariableArrayType>(T)) {
-    llvm::APSInt Result(32);
+    APValue Result;
     if (VLATy->getSizeExpr() &&
-        CalcFakeICEVal(VLATy->getSizeExpr(), Result, Context) &&
-        Result > llvm::APSInt(Result.getBitWidth(), Result.isUnsigned())) {
+        VLATy->getSizeExpr()->tryEvaluate(Result, Context) && Result.isSInt() &&
+        Result.getSInt() > llvm::APSInt(Result.getSInt().getBitWidth(), 
+                                        Result.getSInt().isUnsigned())) {
       return Context.getConstantArrayType(VLATy->getElementType(),
-                                          Result, ArrayType::Normal, 0);
+                                          Result.getSInt(), 
+                                          ArrayType::Normal, 0);
     }
   }
   return QualType();