diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-11-24 05:28:59 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-11-24 05:28:59 +0000 |
commit | fb8a93fe1db76f0afa5daa3b038020feda080836 (patch) | |
tree | f511aa59deaa662816338801e0b153228389495f /clang/lib/AST | |
parent | 0ade9715f228ce4121c4935f75a856ed03dd1fa3 (diff) | |
download | bcm5719-llvm-fb8a93fe1db76f0afa5daa3b038020feda080836.tar.gz bcm5719-llvm-fb8a93fe1db76f0afa5daa3b038020feda080836.zip |
Teach Evaluate to handle member expressions referring to enum constants and
static member constants. No significant visible difference at the moment
because it conservatively assumes the base has side effects. I'm planning to
use this for CodeGen.
llvm-svn: 89738
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d738afdd81b..9c31ac936d4 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -776,7 +776,20 @@ public: T1.getUnqualifiedType()), E); } - bool VisitDeclRefExpr(const DeclRefExpr *E); + + bool CheckReferencedDecl(const Expr *E, const Decl *D); + bool VisitDeclRefExpr(const DeclRefExpr *E) { + return CheckReferencedDecl(E, E->getDecl()); + } + bool VisitMemberExpr(const MemberExpr *E) { + if (CheckReferencedDecl(E, E->getMemberDecl())) { + // Conservatively assume a MemberExpr will have side-effects + Info.EvalResult.HasSideEffects = true; + return true; + } + return false; + } + bool VisitCallExpr(const CallExpr *E); bool VisitBinaryOperator(const BinaryOperator *E); bool VisitUnaryOperator(const UnaryOperator *E); @@ -834,12 +847,12 @@ static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) { return true; } -bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { +bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) { // Enums are integer constant exprs. - if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) { + if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) { // FIXME: This is an ugly hack around the fact that enums don't set their // signedness consistently; see PR3173. - APSInt SI = D->getInitVal(); + APSInt SI = ECD->getInitVal(); SI.setIsUnsigned(!E->getType()->isSignedIntegerType()); // FIXME: This is an ugly hack around the fact that enums don't // set their width (!?!) consistently; see PR3173. @@ -851,15 +864,15 @@ bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { // In C, they can also be folded, although they are not ICEs. if (Info.Ctx.getCanonicalType(E->getType()).getCVRQualifiers() == Qualifiers::Const) { - if (const VarDecl *D = dyn_cast<VarDecl>(E->getDecl())) { + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { const VarDecl *Def = 0; - if (const Expr *Init = D->getDefinition(Def)) { - if (APValue *V = D->getEvaluatedValue()) + if (const Expr *Init = VD->getDefinition(Def)) { + if (APValue *V = VD->getEvaluatedValue()) return Success(V->getInt(), E); if (Visit(const_cast<Expr*>(Init))) { // Cache the evaluated value in the variable declaration. - D->setEvaluatedValue(Info.Ctx, Result); + VD->setEvaluatedValue(Info.Ctx, Result); return true; } |