diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-02-04 21:59:22 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-02-04 21:59:22 +0000 |
commit | f66ea2cd833253f5c79b68eea1c9f283a91979b5 (patch) | |
tree | 1ef0f4bf3a0b79cfc825bf4baf618aee9274a6aa /Analysis/ValueState.cpp | |
parent | e070a1df66aab6d4168fb28f7559fdf996df3567 (diff) |
Added file that should have been in my previous commit.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46722 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Analysis/ValueState.cpp')
-rw-r--r-- | Analysis/ValueState.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp new file mode 100644 index 0000000000..de286ae8cb --- /dev/null +++ b/Analysis/ValueState.cpp @@ -0,0 +1,116 @@ +#include "ValueState.h" + +using namespace clang; + +RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV) { + switch (LV.getSubKind()) { + case LValueDeclKind: { + StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl()); + return T ? T->getValue().second : InvalidValue(); + } + default: + assert (false && "Invalid LValue."); + break; + } + + return InvalidValue(); +} + +RValue ValueStateManager::GetValue(const StateTy& St, Stmt* S) { + for (;;) { + switch (S->getStmtClass()) { + + // ParenExprs are no-ops. + + case Stmt::ParenExprClass: + S = cast<ParenExpr>(S)->getSubExpr(); + continue; + + // DeclRefExprs can either evaluate to an LValue or a Non-LValue + // (assuming an implicit "load") depending on the context. In this + // context we assume that we are retrieving the value contained + // within the referenced variables. + + case Stmt::DeclRefExprClass: + return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl())); + + // Integer literals evaluate to an RValue. Simply retrieve the + // RValue for the literal. + + case Stmt::IntegerLiteralClass: + return NonLValue::GetValue(ValMgr, cast<IntegerLiteral>(S)); + + // Casts where the source and target type are the same + // are no-ops. We blast through these to get the descendant + // subexpression that has a value. + + case Stmt::ImplicitCastExprClass: { + ImplicitCastExpr* C = cast<ImplicitCastExpr>(S); + if (C->getType() == C->getSubExpr()->getType()) { + S = C->getSubExpr(); + continue; + } + break; + } + + case Stmt::CastExprClass: { + CastExpr* C = cast<CastExpr>(S); + if (C->getType() == C->getSubExpr()->getType()) { + S = C->getSubExpr(); + continue; + } + break; + } + + // Handle all other Stmt* using a lookup. + + default: + break; + }; + + break; + } + + StateTy::TreeTy* T = St.SlimFind(S); + + return T ? T->getValue().second : InvalidValue(); +} + +LValue ValueStateManager::GetLValue(const StateTy& St, Stmt* S) { + + while (ParenExpr* P = dyn_cast<ParenExpr>(S)) + S = P->getSubExpr(); + + if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) + return LValueDecl(DR->getDecl()); + + return cast<LValue>(GetValue(St, S)); +} + + +ValueStateManager::StateTy +ValueStateManager::SetValue(StateTy St, Stmt* S, bool isBlkExpr, + const RValue& V) { + + assert (S); + return V.isValid() ? Factory.Add(St, ValueKey(S, isBlkExpr), V) : St; +} + +ValueStateManager::StateTy +ValueStateManager::SetValue(StateTy St, const LValue& LV, const RValue& V) { + + switch (LV.getSubKind()) { + case LValueDeclKind: + return V.isValid() ? Factory.Add(St, cast<LValueDecl>(LV).getDecl(), V) + : Factory.Remove(St, cast<LValueDecl>(LV).getDecl()); + + default: + assert ("SetValue for given LValue type not yet implemented."); + return St; + } +} + +ValueStateManager::StateTy ValueStateManager::Remove(StateTy St, ValueKey K) { + return Factory.Remove(St, K); +} + |