summaryrefslogtreecommitdiffstats
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
commit9f9e4249cc90ed4476b9c79dd8772e265dd30035 (patch)
tree4d04835e63283a6342f8f757bd77ca490676cfeb
parent962b4eed9d3aee8ae0fee915662648bd0fcd3677 (diff)
downloadbcm5719-llvm-9f9e4249cc90ed4476b9c79dd8772e265dd30035.tar.gz
bcm5719-llvm-9f9e4249cc90ed4476b9c79dd8772e265dd30035.zip
More work on the constant evaluator. Eli, it would be great if you could have a look at this.
llvm-svn: 59420
-rw-r--r--clang/lib/AST/ExprConstant.cpp66
1 files changed, 65 insertions, 1 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 08236836a70..4a679567498 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/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?
OpenPOWER on IntegriCloud