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();