diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-09-03 03:06:11 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-09-03 03:06:11 +0000 |
commit | 60dbad831a35ba0f58256b9bcd2a085af98ff2ec (patch) | |
tree | fe49ff6a7826e53607a455c7e779ba6ddeeb36a0 /lib/Analysis/BasicStore.cpp | |
parent | 2307d312f779b204468ac36aab3b153e66a853c0 (diff) |
Store: (static analyzer)
- Change definition of store::Region and store::Binding (once again) to make
them real classes that just wrap pointers. This makes them more strictly
typed, and allows specific implementations of Regions/Bindings to just
subclass them.
- minor renamings to RegionExtent and its subclasses
- added a bunch of doxygen comments
StoreManager: (static analyzer)
- added 'iterBindings', an iteration method for iterating over the bindings of a
store. It that takes a callback object (acting like a poor man's closure).
- added 'getRVal' version for store::Binding. Will potentially phase the other
versions of GetRVal in StoreManager out.
- reimplemented 'getBindings' to be non-virtual and to use 'iterBindings'
BasicStoreManager: (static analyzer)
- implemented 'iterBindings' for BasicStoreManager
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55688 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BasicStore.cpp')
-rw-r--r-- | lib/Analysis/BasicStore.cpp | 116 |
1 files changed, 88 insertions, 28 deletions
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 867028dc19..97566798c0 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -21,10 +21,11 @@ using namespace clang; using store::Region; using store::RegionExtent; +typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy; + namespace { class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager { - typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy; VarBindingsTy::Factory VBFactory; GRStateManager& StMgr; @@ -44,6 +45,8 @@ public: DeclRootsTy& DRoots, LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols); + virtual void iterBindings(Store store, BindingsHandler& f); + virtual Store AddDecl(Store store, GRStateManager& StateMgr, const VarDecl* VD, Expr* Ex, RVal InitVal = UndefinedVal(), unsigned Count = 0); @@ -57,14 +60,38 @@ public: virtual RegionExtent getExtent(Region R); - /// getBindings - Returns all bindings in the specified store that bind - /// to the specified symbolic value. - virtual void getBindings(llvm::SmallVectorImpl<store::Binding>& bindings, - Store store, SymbolID Sym); - /// BindingAsString - Returns a string representing the given binding. virtual std::string BindingAsString(store::Binding binding); -}; + + /// getRVal - Returns the bound RVal for a given binding. + virtual RVal getRVal(Store store, store::Binding binding); +}; + +class VISIBILITY_HIDDEN VarRegion : public store::Region { +public: + VarRegion(VarDecl* VD) : Region(VD) {} + VarDecl* getDecl() const { return (VarDecl*) Data; } + static bool classof(const store::Region*) { return true; } +}; + +class VISIBILITY_HIDDEN VarBinding : public store::Binding { +public: + VarBinding(VarBindingsTy::value_type* T) : store::Binding(T) {} + + const VarBindingsTy::value_type_ref getValue() const { + return *static_cast<const VarBindingsTy::value_type*>(first); + } + + std::string getName() const { + return getValue().first->getName(); + } + + RVal getRVal() const { + return getValue().second; + } + + static inline bool classof(const store::Binding*) { return true; } +}; } // end anonymous namespace @@ -74,8 +101,7 @@ StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) { } RegionExtent BasicStoreManager::getExtent(Region R) { - VarDecl* VD = (VarDecl*) R; - QualType T = VD->getType(); + QualType T = cast<VarRegion>(&R)->getDecl()->getType(); // FIXME: Add support for VLAs. This may require passing in additional // information, or tracking a different region type. @@ -85,8 +111,8 @@ RegionExtent BasicStoreManager::getExtent(Region R) { ASTContext& C = StMgr.getContext(); assert (!T->isObjCInterfaceType()); // @interface not a possible VarDecl type. assert (T != C.VoidTy); // void not a possible VarDecl type. - return store::IntExtent(StMgr.getBasicVals().getValue(C.getTypeSize(T), - C.VoidPtrTy)); + return store::FixedExtent(StMgr.getBasicVals().getValue(C.getTypeSize(T), + C.VoidPtrTy)); } @@ -335,28 +361,62 @@ void BasicStoreManager::print(Store store, std::ostream& Out, } } -void -BasicStoreManager::getBindings(llvm::SmallVectorImpl<store::Binding>& bindings, - Store store, SymbolID Sym) { + +void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) { + VarBindingsTy B = GetVarBindings(store); - VarBindingsTy VB((VarBindingsTy::TreeTy*) store); + for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) { + VarBinding binding(&(*I)); + f.HandleBinding(*this, store, binding); + } +} + + +std::string BasicStoreManager::BindingAsString(store::Binding binding) { + return cast<VarBinding>(binding).getName(); +} + +RVal BasicStoreManager::getRVal(Store store, store::Binding binding) { + return cast<VarBinding>(binding).getRVal(); +} + +//==------------------------------------------------------------------------==// +// Generic store operations. +//==------------------------------------------------------------------------==// + +namespace { +class VISIBILITY_HIDDEN GetBindingsIterator : public StoreManager::BindingsHandler { + SymbolID Sym; + llvm::SmallVectorImpl<store::Binding>& bindings; +public: + GetBindingsIterator(SymbolID s, llvm::SmallVectorImpl<store::Binding>& b) + : Sym(s), bindings(b) {} - for (VarBindingsTy::iterator I=VB.begin(), E=VB.end(); I!=E; ++I) { - if (const lval::SymbolVal* SV=dyn_cast<lval::SymbolVal>(&I->second)) { - if (SV->getSymbol() == Sym) - bindings.push_back(I->first); - - continue; - } + virtual bool HandleBinding(StoreManager& SMgr, Store store, + store::Binding binding) { + + RVal V = SMgr.getRVal(store, binding); - if (const nonlval::SymbolVal* SV=dyn_cast<nonlval::SymbolVal>(&I->second)){ + if (const lval::SymbolVal* SV=dyn_cast<lval::SymbolVal>(&V)) { + if (SV->getSymbol() == Sym) + bindings.push_back(binding); + } + else if (const nonlval::SymbolVal* SV=dyn_cast<nonlval::SymbolVal>(&V)){ if (SV->getSymbol() == Sym) - bindings.push_back(I->first); + bindings.push_back(binding); } + + return true; } -} +}; +} // end anonymous namespace -std::string BasicStoreManager::BindingAsString(store::Binding binding) { - // A binding is just an VarDecl*. - return ((VarDecl*) binding)->getName(); +void StoreManager::getBindings(llvm::SmallVectorImpl<store::Binding>& bindings, + Store store, SymbolID Sym) { + + GetBindingsIterator BI(Sym, bindings); + iterBindings(store, BI); } + +StoreManager::BindingsHandler::~BindingsHandler() {} + |