aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-02-27 06:44:11 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-02-27 06:44:11 +0000
commit35183aca180a2b9b2c637cd625a40a7e147d6a32 (patch)
tree64fb42bccd90eeec474659c00ef7ef9da8791e4a /lib/AST/ExprConstant.cpp
parent5de4092946373af0c8caca64a281e8080c9d8a34 (diff)
Change the AST generated for offsetof a bit so that it looks like a
normal expression, and change Evaluate and IRGen to evaluate it like a normal expression. This simplifies the code significantly, and fixes PR3396. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65622 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp12
1 files changed, 10 insertions, 2 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 4f55f8d764..68818dbf7b 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1064,8 +1064,16 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
// Special case unary operators that do not need their subexpression
// evaluated. offsetof/sizeof/alignof are all special.
- if (E->isOffsetOfOp())
- return Success(E->evaluateOffsetOf(Info.Ctx), E);
+ if (E->isOffsetOfOp()) {
+ // The AST for offsetof is defined in such a way that we can just
+ // directly Evaluate it as an l-value.
+ APValue LV;
+ if (!EvaluateLValue(E->getSubExpr(), LV, Info))
+ return false;
+ if (LV.getLValueBase())
+ return false;
+ return Success(LV.getLValueOffset(), E);
+ }
if (E->getOpcode() == UnaryOperator::LNot) {
// LNot's operand isn't necessarily an integer, so we handle it specially.