aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-11-16 19:01:22 +0000
committerAnders Carlsson <andersca@mac.com>2008-11-16 19:01:22 +0000
commit3068d117951a8df54bae9db039b56201ab10962b (patch)
treeec12eff33b13f827f8a969d0454118da3ca2f538 /lib/AST/ExprConstant.cpp
parent58ace88985b920971b052de8a9a7b89de0654dc0 (diff)
More work on the constant evaluator. Eli, it would be great if you could have a look at this.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59420 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp66
1 files changed, 65 insertions, 1 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 08236836a7..4a67956749 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -124,6 +124,7 @@ public:
APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
APValue VisitMemberExpr(MemberExpr *E);
APValue VisitStringLiteral(StringLiteral *E) { return APValue(E, 0); }
+ APValue VisitArraySubscriptExpr(ArraySubscriptExpr *E);
};
} // end anonymous namespace
@@ -169,6 +170,24 @@ APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
return result;
}
+APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E)
+{
+ APValue Result;
+
+ if (!EvaluatePointer(E->getBase(), Result, Info))
+ return APValue();
+
+ APSInt Index;
+ if (!EvaluateInteger(E->getIdx(), Index, Info))
+ return APValue();
+
+ uint64_t ElementSize = Info.Ctx.getTypeSize(E->getType()) / 8;
+
+ uint64_t Offset = Index.getSExtValue() * ElementSize;
+ Result.setLValue(Result.getLValueBase(),
+ Result.getLValueOffset() + Offset);
+ return Result;
+}
//===----------------------------------------------------------------------===//
// Pointer Evaluation
@@ -384,6 +403,18 @@ public:
}
bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
+ bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
+ Result = E->getValue();
+ Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
+ return true;
+ }
+
+ bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
+ Result = APSInt::getNullValue(getIntTypeSizeInBits(E->getType()));
+ Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
+ return true;
+ }
+
private:
bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType);
};
@@ -572,6 +603,40 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
return true;
}
+ if (E->getOpcode() == BinaryOperator::Sub) {
+ if (LHSTy->isPointerType()) {
+ if (RHSTy->isIntegralType()) {
+ // pointer - int.
+ // FIXME: Implement.
+ }
+
+ assert(RHSTy->isPointerType() && "RHS not pointer!");
+
+ APValue LHSValue;
+ if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
+ return false;
+
+ APValue RHSValue;
+ if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
+ return false;
+
+ // FIXME: Is this correct? What if only one of the operands has a base?
+ if (LHSValue.getLValueBase() || RHSValue.getLValueBase())
+ return false;
+
+ const QualType Type = E->getLHS()->getType();
+ const QualType ElementType = Type->getAsPointerType()->getPointeeType();
+
+ uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
+ D /= Info.Ctx.getTypeSize(ElementType) / 8;
+
+ Result = D;
+ Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
+ Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
+
+ return true;
+ }
+ }
if (!LHSTy->isIntegralType() ||
!RHSTy->isIntegralType()) {
// We can't continue from here for non-integral types, and they
@@ -586,7 +651,6 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
return false; // error in subexpression.
}
- // FIXME: Handle pointer subtraction
// FIXME Maybe we want to succeed even where we can't evaluate the
// right side of LAnd/LOr?