From: Ted Kremenek Date: Mon, 11 Feb 2008 19:21:59 +0000 (+0000) Subject: Separate bindings for subexpressions to be in a separate map for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e7d2211429b85d0dcee8aab271e31e8b6f150440;p=clang Separate bindings for subexpressions to be in a separate map for bindings for block-level expressions. Moved pretty-printing logic (DOT) for ValueStates to ValueState.cpp. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46965 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index eba0619b24..4ae90770c9 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -348,43 +348,8 @@ GRConstants::SetValue(StateTy St, const LValue& LV, const RValue& V) { void GRConstants::ProcessBranch(Expr* Condition, Stmt* Term, BranchNodeBuilder& builder) { - StateTy PrevState = builder.getState(); - - // Remove old bindings for subexpressions. - for (StateTy::eb_iterator I=PrevState.eb_begin(), E=PrevState.eb_end(); I!=E; ++I) - if (I.getKey().isSubExpr()) - PrevState = StateMgr.Remove(PrevState, I.getKey()); - - // Remove terminator-specific bindings. - switch (Term->getStmtClass()) { - default: break; - - case Stmt::BinaryOperatorClass: { // '&&', '||' - BinaryOperator* B = cast(Term); - // FIXME: Liveness analysis should probably remove these automatically. - // Verify later when we converge to an 'optimization' stage. - PrevState = StateMgr.Remove(PrevState, B->getRHS()); - break; - } - - case Stmt::ConditionalOperatorClass: { // '?' operator - ConditionalOperator* C = cast(Term); - // FIXME: Liveness analysis should probably remove these automatically. - // Verify later when we converge to an 'optimization' stage. - if (Expr* L = C->getLHS()) PrevState = StateMgr.Remove(PrevState, L); - PrevState = StateMgr.Remove(PrevState, C->getRHS()); - break; - } - - case Stmt::ChooseExprClass: { // __builtin_choose_expr - ChooseExpr* C = cast(Term); - // FIXME: Liveness analysis should probably remove these automatically. - // Verify later when we converge to an 'optimization' stage. - PrevState = StateMgr.Remove(PrevState, C->getRHS()); - PrevState = StateMgr.Remove(PrevState, C->getRHS()); - break; - } - } + // Remove old bindings for subexpressions. + StateTy PrevState = StateMgr.RemoveSubExprBindings(builder.getState()); RValue V = GetValue(PrevState, Condition); @@ -1119,15 +1084,6 @@ namespace llvm { template<> struct VISIBILITY_HIDDEN DOTGraphTraits : public DefaultDOTGraphTraits { - - static void PrintKindLabel(std::ostream& Out, ExprBindKey::Kind kind) { - switch (kind) { - case ExprBindKey::IsSubExpr: Out << "Sub-Expressions:\\l"; break; - case ExprBindKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break; - default: assert (false && "Unknown ExprBindKey type."); - } - } - static void PrintVarBindings(std::ostream& Out, GRConstants::StateTy St) { @@ -1149,26 +1105,43 @@ struct VISIBILITY_HIDDEN DOTGraphTraits : } - static void PrintExprBindings(std::ostream& Out, GRConstants::StateTy St, - ExprBindKey::Kind kind) { + + static void PrintSubExprBindings(std::ostream& Out, GRConstants::StateTy St) { + bool isFirst = true; - - for (GRConstants::StateTy::eb_iterator I=St.eb_begin(), - E=St.eb_end(); I!=E;++I) { + + for (GRConstants::StateTy::seb_iterator I=St.seb_begin(), E=St.seb_end(); + I != E;++I) { - if (I.getKey().getKind() != kind) - continue; + if (isFirst) { + Out << "\\l\\lSub-Expressions:\\l"; + isFirst = false; + } + else + Out << "\\l"; + + Out << " (" << (void*) I.getKey() << ") "; + I.getKey()->printPretty(Out); + Out << " : "; + I.getData().print(Out); + } + } + static void PrintBlkExprBindings(std::ostream& Out, GRConstants::StateTy St) { + + bool isFirst = true; + + for (GRConstants::StateTy::beb_iterator I=St.beb_begin(), E=St.beb_end(); + I != E; ++I) { if (isFirst) { - Out << "\\l\\l"; - PrintKindLabel(Out, kind); + Out << "\\l\\lBlock-level Expressions:\\l"; isFirst = false; } else Out << "\\l"; - Out << " (" << (void*) I.getKey().getExpr() << ") "; - I.getKey().getExpr()->printPretty(Out); + Out << " (" << (void*) I.getKey() << ") "; + I.getKey()->printPretty(Out); Out << " : "; I.getData().print(Out); } @@ -1275,12 +1248,7 @@ struct VISIBILITY_HIDDEN DOTGraphTraits : Out << "\\|StateID: " << (void*) N->getState().getImpl() << "\\|"; - PrintVarBindings(Out, N->getState()); - PrintExprBindings(Out, N->getState(), ExprBindKey::IsBlkExpr); - PrintExprBindings(Out, N->getState(), ExprBindKey::IsSubExpr); - - PrintEQ(Out, N->getState()); - PrintNE(Out, N->getState()); + N->getState().printDOT(Out); Out << "\\l"; return Out.str(); diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp index 6a9023af64..724f64f04f 100644 --- a/Analysis/ValueState.cpp +++ b/Analysis/ValueState.cpp @@ -43,32 +43,31 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc, // for optimum performance. llvm::SmallVector WList; - - for (StateTy::eb_iterator I = St.eb_begin(), E = St.eb_end(); I!=E ; ++I) { - - ExprBindKey K = I.getKey(); - - // Remove old bindings for subexpressions. - if (K.isSubExpr()) { - St = Remove(St, K); - continue; - } + + ValueStateImpl NewSt = *St; + + // Drop bindings for subexpressions. + NewSt.SubExprBindings = EXFactory.GetEmptyMap(); + + // Iterate over the block-expr bindings. + for (ValueState::beb_iterator I=St.beb_begin(), E=St.beb_end(); I!=E ; ++I) { - assert (I.getKey().isBlkExpr()); + Expr* BlkExpr = I.getKey(); - if (Liveness.isLive(Loc, K.getExpr())) { + if (Liveness.isLive(Loc, BlkExpr)) { if (isa(I.getData())) { lval::DeclVal LV = cast(I.getData()); WList.push_back(LV.getDecl()); } } else - St = Remove(St, K); + NewSt.BlockExprBindings = Remove(NewSt, BlkExpr); continue; } - for (StateTy::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I) + // Iterate over the variable bindings. + for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I) if (Liveness.isLive(Loc, I.getKey())) WList.push_back(I.getKey()); @@ -94,24 +93,24 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc, } } - for (StateTy::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I) + for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I) if (!Marked.count(I.getKey())) - St = Remove(St, I.getKey()); + NewSt.VarBindings = Remove(NewSt, I.getKey()); - return St; + return getPersistentState(NewSt); } -RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV, +RValue ValueStateManager::GetValue(ValueState St, const LValue& LV, QualType* T) { if (isa(LV)) return UnknownVal(); switch (LV.getSubKind()) { case lval::DeclValKind: { - StateTy::VarBindingsTy::TreeTy* T = + ValueState::VarBindingsTy::TreeTy* T = // FIXME: We should make lval::DeclVal only contain VarDecl - St.getImpl()->VarBindings.SlimFind( + St->VarBindings.SlimFind( cast(cast(LV).getDecl())); return T ? T->getValue().second : UnknownVal(); @@ -137,11 +136,10 @@ RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV, return UnknownVal(); } -ValueStateManager::StateTy -ValueStateManager::AddNE(StateTy St, SymbolID sym, const llvm::APSInt& V) { +ValueState +ValueStateManager::AddNE(ValueState St, SymbolID sym, const llvm::APSInt& V) { // First, retrieve the NE-set associated with the given symbol. - ValueState::ConstantNotEqTy::TreeTy* T = - St.getImpl()->ConstantNotEq.SlimFind(sym); + ValueState::ConstantNotEqTy::TreeTy* T = St->ConstantNotEq.SlimFind(sym); ValueState::IntSetTy S = T ? T->getValue().second : ISetFactory.GetEmptySet(); @@ -149,25 +147,25 @@ ValueStateManager::AddNE(StateTy St, SymbolID sym, const llvm::APSInt& V) { S = ISetFactory.Add(S, &V); // Create a new state with the old binding replaced. - ValueStateImpl NewStateImpl = *St.getImpl(); - NewStateImpl.ConstantNotEq = CNEFactory.Add(NewStateImpl.ConstantNotEq, + ValueStateImpl NewSt = *St; + NewSt.ConstantNotEq = CNEFactory.Add(NewSt.ConstantNotEq, sym, S); // Get the persistent copy. - return getPersistentState(NewStateImpl); + return getPersistentState(NewSt); } -ValueStateManager::StateTy -ValueStateManager::AddEQ(StateTy St, SymbolID sym, const llvm::APSInt& V) { +ValueState +ValueStateManager::AddEQ(ValueState St, SymbolID sym, const llvm::APSInt& V) { // Create a new state with the old binding replaced. - ValueStateImpl NewStateImpl = *St.getImpl(); - NewStateImpl.ConstantEq = CEFactory.Add(NewStateImpl.ConstantEq, sym, &V); + ValueStateImpl NewSt = *St; + NewSt.ConstantEq = CEFactory.Add(NewSt.ConstantEq, sym, &V); // Get the persistent copy. - return getPersistentState(NewStateImpl); + return getPersistentState(NewSt); } -RValue ValueStateManager::GetValue(const StateTy& St, Expr* S, bool* hasVal) { +RValue ValueStateManager::GetValue(ValueState St, Expr* S, bool* hasVal) { for (;;) { switch (S->getStmtClass()) { @@ -222,8 +220,14 @@ RValue ValueStateManager::GetValue(const StateTy& St, Expr* S, bool* hasVal) { break; } - StateTy::ExprBindingsTy::TreeTy* T = - St.getImpl()->ExprBindings.SlimFind(S); + ValueState::ExprBindingsTy::TreeTy* T = St->SubExprBindings.SlimFind(S); + + if (T) { + if (hasVal) *hasVal = true; + return T->getValue().second; + } + + T = St->BlockExprBindings.SlimFind(S); if (T) { if (hasVal) *hasVal = true; @@ -235,7 +239,7 @@ RValue ValueStateManager::GetValue(const StateTy& St, Expr* S, bool* hasVal) { } } -LValue ValueStateManager::GetLValue(const StateTy& St, Expr* E) { +LValue ValueStateManager::GetLValue(ValueState St, Expr* E) { while (ParenExpr* P = dyn_cast(E)) E = P->getSubExpr(); @@ -251,22 +255,33 @@ LValue ValueStateManager::GetLValue(const StateTy& St, Expr* E) { } -ValueStateManager::StateTy -ValueStateManager::SetValue(StateTy St, Expr* E, bool isBlkExpr, +ValueState +ValueStateManager::SetValue(ValueState St, Expr* E, bool isBlkExpr, const RValue& V) { assert (E); - return V.isKnown() ? Add(St, ExprBindKey(E, isBlkExpr), V) : St; + + if (V.isUnknown()) + return St; + + ValueStateImpl NewSt = *St; + + if (isBlkExpr) + NewSt.BlockExprBindings = EXFactory.Add(NewSt.BlockExprBindings, E, V); + else + NewSt.SubExprBindings = EXFactory.Add(NewSt.SubExprBindings, E, V); + + return getPersistentState(NewSt); } -ValueStateManager::StateTy -ValueStateManager::SetValue(StateTy St, const LValue& LV, const RValue& V) { +ValueState +ValueStateManager::SetValue(ValueState St, const LValue& LV, const RValue& V) { switch (LV.getSubKind()) { case lval::DeclValKind: return V.isKnown() // FIXME: Have DeclVal only contain VarDecl - ? Add(St, cast(cast(LV).getDecl()), V) - : Remove(St, cast(cast(LV).getDecl())); + ? BindVar(St, cast(cast(LV).getDecl()), V) + : UnbindVar(St, cast(cast(LV).getDecl())); default: assert ("SetValue for given LValue type not yet implemented."); @@ -274,55 +289,29 @@ ValueStateManager::SetValue(StateTy St, const LValue& LV, const RValue& V) { } } -ValueStateManager::StateTy -ValueStateManager::Add(StateTy St, ExprBindKey K, const RValue& V) { - - // Create a new state with the old binding removed. - ValueStateImpl NewStateImpl = *St.getImpl(); - NewStateImpl.ExprBindings = - EXFactory.Add(NewStateImpl.ExprBindings, K, V); - - // Get the persistent copy. - return getPersistentState(NewStateImpl); -} - -ValueStateManager::StateTy -ValueStateManager::Remove(StateTy St, ExprBindKey K) { - - // Create a new state with the old binding removed. - ValueStateImpl NewStateImpl = *St.getImpl(); - NewStateImpl.ExprBindings = - EXFactory.Remove(NewStateImpl.ExprBindings, K); - - // Get the persistent copy. - return getPersistentState(NewStateImpl); -} - -ValueStateManager::StateTy -ValueStateManager::Add(StateTy St, VarDecl* D, const RValue& V) { +ValueState +ValueStateManager::BindVar(ValueState St, VarDecl* D, const RValue& V) { // Create a new state with the old binding removed. - ValueStateImpl NewStateImpl = *St.getImpl(); - NewStateImpl.VarBindings = - VBFactory.Add(NewStateImpl.VarBindings, D, V); + ValueStateImpl NewSt = *St; + NewSt.VarBindings = VBFactory.Add(NewSt.VarBindings, D, V); // Get the persistent copy. - return getPersistentState(NewStateImpl); + return getPersistentState(NewSt); } -ValueStateManager::StateTy -ValueStateManager::Remove(StateTy St, VarDecl* D) { +ValueState +ValueStateManager::UnbindVar(ValueState St, VarDecl* D) { // Create a new state with the old binding removed. - ValueStateImpl NewStateImpl = *St.getImpl(); - NewStateImpl.VarBindings = - VBFactory.Remove(NewStateImpl.VarBindings, D); + ValueStateImpl NewSt = *St; + NewSt.VarBindings = VBFactory.Remove(NewSt.VarBindings, D); // Get the persistent copy. - return getPersistentState(NewStateImpl); + return getPersistentState(NewSt); } -ValueStateManager::StateTy +ValueState ValueStateManager::getInitialState() { // Create a state with empty variable bindings. @@ -334,12 +323,12 @@ ValueStateManager::getInitialState() { return getPersistentState(StateImpl); } -ValueStateManager::StateTy +ValueState ValueStateManager::getPersistentState(const ValueStateImpl &State) { llvm::FoldingSetNodeID ID; State.Profile(ID); - void* InsertPos; + void* InsertPos; if (ValueStateImpl* I = StateSet.FindNodeOrInsertPos(ID, InsertPos)) return I; @@ -349,3 +338,94 @@ ValueStateManager::getPersistentState(const ValueStateImpl &State) { StateSet.InsertNode(I, InsertPos); return I; } + +void ValueState::printDOT(std::ostream& Out) const { + // Print Variable Bindings + Out << "Variables:\\l"; + + bool isFirst = true; + + for (vb_iterator I=vb_begin(), E=vb_end(); I!=E; ++I) { + + if (isFirst) + isFirst = false; + else + Out << "\\l"; + + Out << ' ' << I.getKey()->getName() << " : "; + I.getData().print(Out); + } + + // Print Subexpression bindings. + + isFirst = true; + + for (seb_iterator I=seb_begin(), E=seb_end(); I != E;++I) { + + if (isFirst) { + Out << "\\l\\lSub-Expressions:\\l"; + isFirst = false; + } + else + Out << "\\l"; + + Out << " (" << (void*) I.getKey() << ") "; + I.getKey()->printPretty(Out); + Out << " : "; + I.getData().print(Out); + } + + // Print block-expression bindings. + + isFirst = true; + + for (beb_iterator I=beb_begin(), E=beb_end(); I != E; ++I) { + + if (isFirst) { + Out << "\\l\\lBlock-level Expressions:\\l"; + isFirst = false; + } + else + Out << "\\l"; + + Out << " (" << (void*) I.getKey() << ") "; + I.getKey()->printPretty(Out); + Out << " : "; + I.getData().print(Out); + } + + // Print equality constraints. + + if (!Data->ConstantEq.isEmpty()) { + + Out << "\\l\\|'==' constraints:"; + + for (ConstantEqTy::iterator I=Data->ConstantEq.begin(), + E=Data->ConstantEq.end(); I!=E;++I) + Out << "\\l $" << I.getKey() << " : " << I.getData()->toString(); + } + + + // Print != constraints. + + if (!Data->ConstantNotEq.isEmpty()) { + + Out << "\\l\\|'!=' constraints:"; + + for (ConstantNotEqTy::iterator I=Data->ConstantNotEq.begin(), + EI=Data->ConstantNotEq.end(); I != EI; ++I) { + + Out << "\\l $" << I.getKey() << " : "; + isFirst = true; + + IntSetTy::iterator J=I.getData().begin(), EJ=I.getData().end(); + + for ( ; J != EJ; ++J) { + if (isFirst) isFirst = false; + else Out << ", "; + + Out << (*J)->toString(); + } + } + } +} diff --git a/Analysis/ValueState.h b/Analysis/ValueState.h index 3d7a2e6bef..5f2b58c18c 100644 --- a/Analysis/ValueState.h +++ b/Analysis/ValueState.h @@ -37,51 +37,7 @@ #include -namespace clang { - -class ExprBindKey { - uintptr_t Raw; - void operator=(const ExprBindKey& RHS); // Do not implement. - - inline void* getPtr() const { - return reinterpret_cast(Raw & ~Mask); - } - -public: - enum Kind { IsSubExpr=0x0, IsBlkExpr=0x1, Mask=0x1 }; - - inline Kind getKind() const { - return (Kind) (Raw & Mask); - } - - inline Expr* getExpr() const { - return (Expr*) getPtr(); - } - - ExprBindKey(Expr* E, bool isBlkExpr = false) - : Raw(reinterpret_cast(E) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){ - assert(E && "Tracked statement cannot be NULL."); - } - - bool isSubExpr() const { return getKind() == IsSubExpr; } - bool isBlkExpr() const { return getKind() == IsBlkExpr; } - - inline void Profile(llvm::FoldingSetNodeID& ID) const { - ID.AddPointer(getPtr()); - } - - inline bool operator==(const ExprBindKey& X) const { - return getPtr() == X.getPtr(); - } - - inline bool operator!=(const ExprBindKey& X) const { - return !operator==(X); - } - - inline bool operator<(const ExprBindKey& X) const { - return getPtr() < X.getPtr(); - } -}; +namespace clang { //===----------------------------------------------------------------------===// // ValueState - An ImmutableMap type Stmt*/Decl*/Symbols to RValues. @@ -90,7 +46,7 @@ public: namespace vstate { typedef llvm::ImmutableSet IntSetTy; - typedef llvm::ImmutableMap ExprBindingsTy; + typedef llvm::ImmutableMap ExprBindingsTy; typedef llvm::ImmutableMap VarBindingsTy; typedef llvm::ImmutableMap ConstantNotEqTy; typedef llvm::ImmutableMap ConstantEqTy; @@ -105,7 +61,8 @@ private: void operator=(const ValueStateImpl& R) const; public: - vstate::ExprBindingsTy ExprBindings; + vstate::ExprBindingsTy SubExprBindings; + vstate::ExprBindingsTy BlockExprBindings; vstate::VarBindingsTy VarBindings; vstate::ConstantNotEqTy ConstantNotEq; vstate::ConstantEqTy ConstantEq; @@ -115,13 +72,18 @@ public: vstate::VarBindingsTy VB, vstate::ConstantNotEqTy CNE, vstate::ConstantEqTy CE) - : ExprBindings(EB), VarBindings(VB), ConstantNotEq(CNE), ConstantEq(CE) {} + : SubExprBindings(EB), + BlockExprBindings(EB), + VarBindings(VB), + ConstantNotEq(CNE), + ConstantEq(CE) {} /// Copy ctor - We must explicitly define this or else the "Next" ptr /// in FoldingSetNode will also get copied. ValueStateImpl(const ValueStateImpl& RHS) : llvm::FoldingSetNode(), - ExprBindings(RHS.ExprBindings), + SubExprBindings(RHS.SubExprBindings), + BlockExprBindings(RHS.BlockExprBindings), VarBindings(RHS.VarBindings), ConstantNotEq(RHS.ConstantNotEq), ConstantEq(RHS.ConstantEq) {} @@ -131,7 +93,8 @@ public: /// Profile - Profile the contents of a ValueStateImpl object for use /// in a FoldingSet. static void Profile(llvm::FoldingSetNodeID& ID, const ValueStateImpl& V) { - V.ExprBindings.Profile(ID); + V.SubExprBindings.Profile(ID); + V.BlockExprBindings.Profile(ID); V.VarBindings.Profile(ID); V.ConstantNotEq.Profile(ID); V.ConstantEq.Profile(ID); @@ -160,6 +123,8 @@ public: // Accessors. ValueStateImpl* getImpl() const { return Data; } + ValueStateImpl& operator*() { return *Data; } + ValueStateImpl* operator->() { return Data; } // Typedefs. typedef vstate::IntSetTy IntSetTy; @@ -177,13 +142,17 @@ public: // Iterators. - typedef VarBindingsTy::iterator vb_iterator; - vb_iterator vb_begin() { return Data->VarBindings.begin(); } - vb_iterator vb_end() { return Data->VarBindings.end(); } + typedef VarBindingsTy::iterator vb_iterator; + vb_iterator vb_begin() const { return Data->VarBindings.begin(); } + vb_iterator vb_end() const { return Data->VarBindings.end(); } + + typedef ExprBindingsTy::iterator seb_iterator; + seb_iterator seb_begin() const { return Data->SubExprBindings.begin(); } + seb_iterator seb_end() const { return Data->SubExprBindings.end(); } - typedef ExprBindingsTy::iterator eb_iterator; - eb_iterator eb_begin() { return Data->ExprBindings.begin(); } - eb_iterator eb_end() { return Data->ExprBindings.end(); } + typedef ExprBindingsTy::iterator beb_iterator; + beb_iterator beb_begin() const { return Data->BlockExprBindings.begin(); } + beb_iterator beb_end() const { return Data->BlockExprBindings.end(); } // Profiling and equality testing. @@ -198,6 +167,11 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const { Profile(ID, *this); } + + void printDOT(std::ostream& Out) const; + void print(std::ostream& Out) const; + void print() const { print(*llvm::cerr); } + }; template<> struct GRTrait { @@ -233,38 +207,58 @@ private: /// Alloc - A BumpPtrAllocator to allocate states. llvm::BumpPtrAllocator& Alloc; + +private: + + ValueState::ExprBindingsTy Remove(ValueState::ExprBindingsTy B, Expr* E) { + return EXFactory.Remove(B, E); + } + + ValueState::VarBindingsTy Remove(ValueState::VarBindingsTy B, VarDecl* V) { + return VBFactory.Remove(B, V); + } - StateTy getPersistentState(const ValueState& St); + inline ValueState::ExprBindingsTy Remove(const ValueStateImpl& V, Expr* E) { + return Remove(V.BlockExprBindings, E); + } + + inline ValueState::VarBindingsTy Remove(const ValueStateImpl& V, VarDecl* D) { + return Remove(V.VarBindings, D); + } + + ValueState BindVar(ValueState St, VarDecl* D, const RValue& V); + ValueState UnbindVar(ValueState St, VarDecl* D); public: ValueStateManager(ASTContext& Ctx, llvm::BumpPtrAllocator& alloc) : ValMgr(Ctx, alloc), Alloc(alloc) {} - StateTy getInitialState(); + ValueState getInitialState(); ValueManager& getValueManager() { return ValMgr; } SymbolManager& getSymbolManager() { return SymMgr; } - StateTy RemoveDeadBindings(StateTy St, Stmt* Loc, - const LiveVariables& Liveness); + ValueState RemoveDeadBindings(ValueState St, Stmt* Loc, + const LiveVariables& Liveness); - StateTy SetValue(StateTy St, Expr* S, bool isBlkExpr, const RValue& V); - StateTy SetValue(StateTy St, const LValue& LV, const RValue& V); - - RValue GetValue(const StateTy& St, Expr* S, bool* hasVal = NULL); - RValue GetValue(const StateTy& St, const LValue& LV, QualType* T = NULL); - LValue GetLValue(const StateTy& St, Expr* S); - - StateTy Add(StateTy St, ExprBindKey K, const RValue& V); - StateTy Remove(StateTy St, ExprBindKey K); + ValueState RemoveSubExprBindings(ValueState St) { + ValueStateImpl NewSt = *St; + NewSt.SubExprBindings = EXFactory.GetEmptyMap(); + return getPersistentState(NewSt); + } + - StateTy Add(StateTy St, VarDecl* D, const RValue& V); - StateTy Remove(StateTy St, VarDecl* D); + ValueState SetValue(ValueState St, Expr* S, bool isBlkExpr, const RValue& V); + ValueState SetValue(ValueState St, const LValue& LV, const RValue& V); + + RValue GetValue(ValueState St, Expr* S, bool* hasVal = NULL); + RValue GetValue(ValueState St, const LValue& LV, QualType* T = NULL); + LValue GetLValue(ValueState St, Expr* S); - StateTy getPersistentState(const ValueStateImpl& Impl); + ValueState getPersistentState(const ValueStateImpl& Impl); - StateTy AddEQ(StateTy St, SymbolID sym, const llvm::APSInt& V); - StateTy AddNE(StateTy St, SymbolID sym, const llvm::APSInt& V); + ValueState AddEQ(ValueState St, SymbolID sym, const llvm::APSInt& V); + ValueState AddNE(ValueState St, SymbolID sym, const llvm::APSInt& V); }; } // end clang namespace