]> granicus.if.org Git - clang/commitdiff
Add StoreManager::getSubRegionMap(). This method returns an opaque mapping for clien...
authorTed Kremenek <kremenek@apple.com>
Tue, 3 Mar 2009 01:35:36 +0000 (01:35 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 3 Mar 2009 01:35:36 +0000 (01:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65914 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/Store.h
lib/Analysis/BasicStore.cpp
lib/Analysis/RegionStore.cpp

index ed30a8bca535e4df23c2725f99f2c9b73c2eec99..2f7920ac6b5c8978651569650b74546ece3e8bf0 100644 (file)
@@ -31,7 +31,8 @@ class GRStateManager;
 class Stmt;
 class Expr;
 class ObjCIvarDecl;
-
+class SubRegionMap;
+  
 class StoreManager {
 protected:
   /// MRMgr - Manages region objects associated with this StoreManager.
@@ -71,8 +72,17 @@ public:
                                              const CompoundLiteralExpr* CL,
                                              SVal V) = 0;
   
+  /// getInitialStore - Returns the initial "empty" store representing the
+  ///  value bindings upon entry to an analyzed function.
   virtual Store getInitialStore() = 0;
+  
+  /// getRegionManager - Returns the internal RegionManager object that is
+  ///  used to query and manipulate MemRegion objects.
   MemRegionManager& getRegionManager() { return MRMgr; }
+  
+  /// getSubRegionMap - Returns an opaque map object that clients can query
+  ///  to get the subregions of a given MemRegion object.
+  virtual std::auto_ptr<SubRegionMap> getSubRegionMap(const GRState *state) = 0;
 
   virtual SVal getLValueVar(const GRState* St, const VarDecl* VD) = 0;
 
@@ -151,6 +161,21 @@ public:
   /// iterBindings - Iterate over the bindings in the Store.
   virtual void iterBindings(Store store, BindingsHandler& f) = 0;  
 };
+
+/// SubRegionMap - An abstract interface that represents a queryable map
+///  between MemRegion objects and their subregions.
+class SubRegionMap {
+public:
+  virtual ~SubRegionMap() {}
+  
+  class Visitor {
+  public:
+    virtual ~Visitor() {}
+    virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion);    
+  };
+  
+  virtual void iterSubRegions(const MemRegion* R, Visitor& V) const = 0;  
+};
   
 StoreManager* CreateBasicStoreManager(GRStateManager& StMgr);
 StoreManager* CreateRegionStoreManager(GRStateManager& StMgr);
index 85d96c4780eeef3d1b87e5de3f586028bbce248f..31408c02445f29a9564efc84916c2113009aff6b 100644 (file)
@@ -23,6 +23,15 @@ typedef llvm::ImmutableMap<const VarDecl*,SVal> VarBindingsTy;
 
 namespace {
   
+class VISIBILITY_HIDDEN BasicStoreSubRegionMap : public SubRegionMap {
+public:
+  BasicStoreSubRegionMap() {}
+
+  void iterSubRegions(const MemRegion* R, Visitor& V) const {
+    // Do nothing.  No subregions.
+  }
+};
+  
 class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
   VarBindingsTy::Factory VBFactory;
   GRStateManager& StateMgr;
@@ -37,6 +46,10 @@ public:
   
   ~BasicStoreManager() {}
 
+  std::auto_ptr<SubRegionMap> getSubRegionMap(const GRState *state) {
+    return std::auto_ptr<SubRegionMap>(new BasicStoreSubRegionMap());
+  }
+
   SVal Retrieve(const GRState *state, Loc loc, QualType T = QualType());  
 
   const GRState* Bind(const GRState* St, Loc L, SVal V) {
index a76a870eb445ec0092019986c491c7856b325c28..0671a806d2200d2a6a33fd16e528f7d90db97b67 100644 (file)
@@ -105,6 +105,37 @@ namespace clang {
 
 namespace {
 
+class VISIBILITY_HIDDEN RegionStoreSubRegionMap : public SubRegionMap {
+  typedef llvm::DenseMap<const MemRegion*,
+                         llvm::ImmutableSet<const MemRegion*> > Map;
+  
+  llvm::ImmutableSet<const MemRegion*>::Factory F;
+  Map M;
+
+public:
+  void add(const MemRegion* Parent, const MemRegion* SubRegion) {
+    Map::iterator I = M.find(Parent);
+    M.insert(std::make_pair(Parent, 
+             F.Add(I == M.end() ? F.GetEmptySet() : I->second, SubRegion)));
+  }
+    
+  ~RegionStoreSubRegionMap() {}
+  
+  void iterSubRegions(const MemRegion* Parent, Visitor& V) const {
+    Map::iterator I = M.find(Parent);
+
+    if (I == M.end())
+      return;
+    
+    llvm::ImmutableSet<const MemRegion*> S = I->second;
+    for (llvm::ImmutableSet<const MemRegion*>::iterator SI=S.begin(),SE=S.end();
+         SI != SE; ++SI) {
+      if (!V.Visit(Parent, *SI))
+        return;
+    }
+  }
+};  
+
 class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
   RegionBindingsTy::Factory RBFactory;
   RegionViews::Factory RVFactory;
@@ -128,6 +159,8 @@ public:
 
   MemRegionManager& getRegionManager() { return MRMgr; }
   
+  std::auto_ptr<SubRegionMap> getSubRegionMap(const GRState *state);
+  
   const GRState* BindCompoundLiteral(const GRState* St, 
                                      const CompoundLiteralExpr* CL, SVal V);
 
@@ -268,6 +301,18 @@ StoreManager* clang::CreateRegionStoreManager(GRStateManager& StMgr) {
   return new RegionStoreManager(StMgr);
 }
 
+std::auto_ptr<SubRegionMap>
+RegionStoreManager::getSubRegionMap(const GRState *state) {
+  RegionBindingsTy B = GetRegionBindings(state->getStore());
+  RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
+  
+  for (RegionBindingsTy::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
+    if (const SubRegion* R = dyn_cast<SubRegion>(I.getKey()))
+      M->add(R->getSuperRegion(), R);
+  }
+  
+  return std::auto_ptr<SubRegionMap>(M);
+}
 
 /// getLValueString - Returns an SVal representing the lvalue of a
 ///  StringLiteral.  Within RegionStore a StringLiteral has an