diff options
Diffstat (limited to 'lib/Analysis/BasicStore.cpp')
-rw-r--r-- | lib/Analysis/BasicStore.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 47e2905e02..f97f8b2c29 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -42,9 +42,12 @@ public: virtual MemRegionManager& getRegionManager() { return MRMgr; } + // FIXME: Investigate what is using this. This method should be removed. virtual LVal getLVal(const VarDecl* VD) { return lval::MemRegionVal(MRMgr.getVarRegion(VD)); } + + virtual RVal getLValue(const GRState* St, const Expr* Ex); virtual Store RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live, @@ -73,6 +76,35 @@ StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) { return new BasicStoreManager(StMgr); } +// FIXME: replace ArrayOffset and FieldOffset with some region value. +RVal BasicStoreManager::getLValue(const GRState* St, const Expr* Ex) { + if (const DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(Ex)) { + const VarDecl* VD = cast<VarDecl>(DRE->getDecl()); + QualType T = VD->getType(); + + // Array and struct variable have no lvalue. + assert(!T->isArrayType()); + + return lval::MemRegionVal(MRMgr.getVarRegion(VD)); + + } else if (const ArraySubscriptExpr* A = dyn_cast<ArraySubscriptExpr>(Ex)) { + const Expr* Base = A->getBase()->IgnoreParens(); + const Expr* Idx = A->getIdx()->IgnoreParens(); + RVal BaseV = StateMgr.GetRVal(St, Base); + RVal IdxV = StateMgr.GetRVal(St, Idx); + return lval::ArrayOffset::Make(StateMgr.getBasicVals(), BaseV, IdxV); + + } else if (const MemberExpr* M = dyn_cast<MemberExpr>(Ex)) { + Expr* Base = M->getBase()->IgnoreParens(); + RVal BaseV = StateMgr.GetRVal(St, Base); + return lval::FieldOffset::Make(StateMgr.getBasicVals(), BaseV, + M->getMemberDecl()); + } else { + Ex->dump(); + assert(0); + } +} + RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) { if (isa<UnknownVal>(LV)) |