blob: f323fd4f90f7f093151107032e1b39292dae6ebc [file] [log] [blame]
Ted Kremenek0eb0afa2008-02-04 21:59:22 +00001#include "ValueState.h"
2
3using namespace clang;
4
5RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV) {
6 switch (LV.getSubKind()) {
7 case LValueDeclKind: {
8 StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl());
9 return T ? T->getValue().second : InvalidValue();
10 }
11 default:
12 assert (false && "Invalid LValue.");
13 break;
14 }
15
16 return InvalidValue();
17}
18
Ted Kremenek1f0eb992008-02-05 00:26:40 +000019RValue ValueStateManager::GetValue(const StateTy& St, Stmt* S, bool* hasVal) {
Ted Kremenek0eb0afa2008-02-04 21:59:22 +000020 for (;;) {
21 switch (S->getStmtClass()) {
22
23 // ParenExprs are no-ops.
24
25 case Stmt::ParenExprClass:
26 S = cast<ParenExpr>(S)->getSubExpr();
27 continue;
28
29 // DeclRefExprs can either evaluate to an LValue or a Non-LValue
30 // (assuming an implicit "load") depending on the context. In this
31 // context we assume that we are retrieving the value contained
32 // within the referenced variables.
33
34 case Stmt::DeclRefExprClass:
35 return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl()));
36
37 // Integer literals evaluate to an RValue. Simply retrieve the
38 // RValue for the literal.
39
40 case Stmt::IntegerLiteralClass:
41 return NonLValue::GetValue(ValMgr, cast<IntegerLiteral>(S));
42
43 // Casts where the source and target type are the same
44 // are no-ops. We blast through these to get the descendant
45 // subexpression that has a value.
46
47 case Stmt::ImplicitCastExprClass: {
48 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
49 if (C->getType() == C->getSubExpr()->getType()) {
50 S = C->getSubExpr();
51 continue;
52 }
53 break;
54 }
55
56 case Stmt::CastExprClass: {
57 CastExpr* C = cast<CastExpr>(S);
58 if (C->getType() == C->getSubExpr()->getType()) {
59 S = C->getSubExpr();
60 continue;
61 }
62 break;
63 }
64
65 // Handle all other Stmt* using a lookup.
66
67 default:
68 break;
69 };
70
71 break;
72 }
73
74 StateTy::TreeTy* T = St.SlimFind(S);
75
Ted Kremenek1f0eb992008-02-05 00:26:40 +000076 if (T) {
77 if (hasVal) *hasVal = true;
78 return T->getValue().second;
79 }
80 else {
81 if (hasVal) *hasVal = false;
82 return InvalidValue();
83 }
Ted Kremenek0eb0afa2008-02-04 21:59:22 +000084}
85
86LValue ValueStateManager::GetLValue(const StateTy& St, Stmt* S) {
87
88 while (ParenExpr* P = dyn_cast<ParenExpr>(S))
89 S = P->getSubExpr();
90
91 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
92 return LValueDecl(DR->getDecl());
93
94 return cast<LValue>(GetValue(St, S));
95}
96
97
98ValueStateManager::StateTy
99ValueStateManager::SetValue(StateTy St, Stmt* S, bool isBlkExpr,
100 const RValue& V) {
101
102 assert (S);
103 return V.isValid() ? Factory.Add(St, ValueKey(S, isBlkExpr), V) : St;
104}
105
106ValueStateManager::StateTy
107ValueStateManager::SetValue(StateTy St, const LValue& LV, const RValue& V) {
108
109 switch (LV.getSubKind()) {
110 case LValueDeclKind:
111 return V.isValid() ? Factory.Add(St, cast<LValueDecl>(LV).getDecl(), V)
112 : Factory.Remove(St, cast<LValueDecl>(LV).getDecl());
113
114 default:
115 assert ("SetValue for given LValue type not yet implemented.");
116 return St;
117 }
118}
119
120ValueStateManager::StateTy ValueStateManager::Remove(StateTy St, ValueKey K) {
121 return Factory.Remove(St, K);
122}
123