[cfe-commits] r54835 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRState.h include/clang/Analysis/PathSensitive/GRTransferFuncs.h lib/Analysis/CFRefCount.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/GRState.cpp

Ted Kremenek kremenek at apple.com
Fri Aug 15 17:49:49 PDT 2008


Author: kremenek
Date: Fri Aug 15 19:49:49 2008
New Revision: 54835

URL: http://llvm.org/viewvc/llvm-project?rev=54835&view=rev
Log:
GRState:
- Remove ConstNotEq from GRState/GRStateManager (!= tracking uses GDM instead).
- GRStateManager now can book-keep "contexts" (e.g., factory objects) for uses
  with data elements stored into the GDM.
- Refactor pretty-printing of states to use GRState::Printer objects
  exclusively. This removed a huge amount of pretty-printing logic from
  GRExprEngine.

CFRefCount
- Simplified some API calls based on refinements to the GDM api.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/GRState.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h?rev=54835&r1=54834&r2=54835&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Fri Aug 15 19:49:49 2008
@@ -58,7 +58,6 @@
   // Typedefs.  
   typedef llvm::ImmutableSet<llvm::APSInt*>                IntSetTy;
   typedef llvm::ImmutableMap<void*, void*>                 GenericDataMap;  
-  typedef llvm::ImmutableMap<SymbolID,IntSetTy>            ConstNotEqTy;
   typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstEqTy;
   
   typedef GRStateManager ManagerTy;
@@ -74,18 +73,15 @@
   // FIXME: Make these private.
 public:
   GenericDataMap   GDM;
-  ConstNotEqTy     ConstNotEq;
   ConstEqTy        ConstEq;
   
 public:
   
   /// This ctor is used when creating the first GRState object.
-  GRState(const Environment& env,  Store st, GenericDataMap gdm,
-             ConstNotEqTy CNE, ConstEqTy  CE)
+  GRState(const Environment& env,  Store st, GenericDataMap gdm, ConstEqTy  CE)
     : Env(env),
       St(st),
       GDM(gdm),
-      ConstNotEq(CNE),
       ConstEq(CE) {}
   
   /// Copy ctor - We must explicitly define this or else the "Next" ptr
@@ -95,7 +91,6 @@
       Env(RHS.Env),
       St(RHS.St),
       GDM(RHS.GDM),
-      ConstNotEq(RHS.ConstNotEq),
       ConstEq(RHS.ConstEq) {}
   
   /// getEnvironment - Return the environment associated with this state.
@@ -115,7 +110,6 @@
     V->Env.Profile(ID);
     ID.AddPointer(V->St);
     V->GDM.Profile(ID);
-    V->ConstNotEq.Profile(ID);
     V->ConstEq.Profile(ID);
   }
 
@@ -138,7 +132,6 @@
   
   // Iterators.
 
-
   // FIXME: We'll be removing the VarBindings iterator very soon.  Right now
   //  it assumes that Store is a VarBindingsTy.
   typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
@@ -151,7 +144,6 @@
     VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
     return B.end();
   }
-
     
   typedef Environment::seb_iterator seb_iterator;
   seb_iterator seb_begin() const { return Env.seb_begin(); }
@@ -160,15 +152,7 @@
   typedef Environment::beb_iterator beb_iterator;
   beb_iterator beb_begin() const { return Env.beb_begin(); }
   beb_iterator beb_end() const { return Env.beb_end(); }
-  
-  typedef ConstNotEqTy::iterator cne_iterator;
-  cne_iterator cne_begin() const { return ConstNotEq.begin(); }
-  cne_iterator cne_end() const { return ConstNotEq.end(); }
-  
-  typedef ConstEqTy::iterator ce_iterator;
-  ce_iterator ce_begin() const { return ConstEq.begin(); }
-  ce_iterator ce_end() const { return ConstEq.end(); }
-  
+
   // Trait based GDM dispatch.  
   void* const* FindGDM(void* K) const;
   
@@ -193,10 +177,7 @@
   };
 
   void print(std::ostream& Out, Printer **Beg = 0, Printer **End = 0,
-             const char* nl = "\n", const char *sep = "") const;
-  
-  void printStdErr(Printer **Beg = 0, Printer **End = 0) const;  
-  void printDOT(std::ostream& Out, Printer **Beg = 0, Printer **End = 0) const;
+             const char* nl = "\n", const char *sep = "") const;  
 };
   
 template<> struct GRTrait<GRState*> {
@@ -246,17 +227,29 @@
 //===----------------------------------------------------------------------===//
 // GRStateManager - Factory object for GRStates.
 //===----------------------------------------------------------------------===//
+
+class GRStateRef;
   
 class GRStateManager {
   friend class GRExprEngine;
+  friend class GRStateRef;
   
 private:
   EnvironmentManager                   EnvMgr;
   llvm::OwningPtr<StoreManager>        StMgr;
-  GRState::IntSetTy::Factory        ISetFactory;
-  GRState::GenericDataMap::Factory  GDMFactory;
-  GRState::ConstNotEqTy::Factory    CNEFactory;
-  GRState::ConstEqTy::Factory       CEFactory;
+  GRState::IntSetTy::Factory           ISetFactory;
+  
+  GRState::GenericDataMap::Factory     GDMFactory;
+  
+  typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
+  GDMContextsTy GDMContexts;
+  
+  // FIXME: Refactor these elsewhere.
+  GRState::ConstEqTy::Factory          CEFactory;
+  
+  /// Printers - A set of printer objects used for pretty-printing a GRState.
+  ///  GRStateManager owns these objects.
+  std::vector<GRState::Printer*> Printers;
   
   /// StateSet - FoldingSet containing all the states created for analyzing
   ///  a particular function.  This is used to unique states.
@@ -304,12 +297,13 @@
     StMgr(stmgr),
     ISetFactory(alloc), 
     GDMFactory(alloc),
-    CNEFactory(alloc),
     CEFactory(alloc),
     BasicVals(Ctx, alloc),
     SymMgr(alloc),
     Alloc(alloc),
     cfg(c) {}
+  
+  ~GRStateManager();
 
   const GRState* getInitialState();
         
@@ -353,18 +347,21 @@
     return getPersistentState(NewSt);
   }
   
-  const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V) {
+  const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V,
+                         bool Invalidate = true) {
     
     bool isBlkExpr = false;
     
     if (Ex == CurrentStmt) {
+      // FIXME: Should this just be an assertion?  When would we want to set
+      // the value of a block-level expression if it wasn't CurrentStmt?
       isBlkExpr = cfg.isBlkExpr(Ex);
       
       if (!isBlkExpr)
         return St;
     }
     
-    return SetRVal(St, Ex, V, isBlkExpr, true);
+    return SetRVal(St, Ex, V, isBlkExpr, Invalidate);
   }
   
   // Methods that manipulate the GDM.
@@ -424,6 +421,20 @@
      GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C)));
   }
   
+
+  void* FindGDMContext(void* index,
+                       void* (*CreateContext)(llvm::BumpPtrAllocator&),
+                       void  (*DeleteContext)(void*));
+  
+  template <typename T>
+  typename GRStateTrait<T>::context_type get_context() {
+    void* p = FindGDMContext(GRStateTrait<T>::GDMIndex(),
+                             GRStateTrait<T>::CreateContext,
+                             GRStateTrait<T>::DeleteContext);
+    
+    return GRStateTrait<T>::MakeContext(p);
+  }
+  
   // Assumption logic.
   const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
                            bool& isFeasible) {
@@ -505,8 +516,8 @@
     return GRStateRef(Mgr->SetRVal(St, Ex, V, isBlkExpr, Invalidate), *Mgr);
   }
   
-  GRStateRef SetRVal(Expr* Ex, RVal V) {
-    return GRStateRef(Mgr->SetRVal(St, Ex, V), *Mgr);
+  GRStateRef SetRVal(Expr* Ex, RVal V, bool Invalidate = true) {
+    return GRStateRef(Mgr->SetRVal(St, Ex, V, Invalidate), *Mgr);
   }
   
   GRStateRef SetRVal(LVal LV, RVal V) {
@@ -539,7 +550,12 @@
   GRStateRef set(typename GRStateTrait<T>::data_type D) {
     return GRStateRef(Mgr->set<T>(St, D), *Mgr);
   }
-  
+
+  template <typename T>
+  typename GRStateTrait<T>::context_type get_context() {
+    return Mgr->get_context<T>();
+  }    
+
   template<typename T>
   GRStateRef set(typename GRStateTrait<T>::key_type K,
                  typename GRStateTrait<T>::value_type E,
@@ -548,10 +564,24 @@
   }
   
   template<typename T>
+  GRStateRef set(typename GRStateTrait<T>::key_type K,
+                 typename GRStateTrait<T>::value_type E) {
+    return GRStateRef(Mgr->set<T>(St, K, E, get_context<T>()), *Mgr);
+  }  
+  
+  template<typename T>
   GRStateRef remove(typename GRStateTrait<T>::key_type K,
                     typename GRStateTrait<T>::context_type C) {
     return GRStateRef(Mgr->remove<T>(St, K, C), *Mgr);
   }
+  
+  // Pretty-printing.
+  void print(std::ostream& Out, const char* nl = "\n",
+             const char *sep = "") const;
+  
+  void printStdErr() const; 
+  
+  void printDOT(std::ostream& Out) const;
 };
   
   

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h?rev=54835&r1=54834&r2=54835&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Fri Aug 15 19:49:49 2008
@@ -43,7 +43,7 @@
   GRTransferFuncs() {}
   virtual ~GRTransferFuncs() {}
   
-  virtual void getStatePrinters(std::vector<GRState::Printer*>& Printers) {}
+  virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {}
   virtual void RegisterChecks(GRExprEngine& Eng);
   
   // Casts.

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=54835&r1=54834&r2=54835&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Fri Aug 15 19:49:49 2008
@@ -1264,7 +1264,6 @@
   UseAfterReleasesTy   UseAfterReleases;
   ReleasesNotOwnedTy   ReleasesNotOwned;
   LeaksTy              Leaks;
-  BindingsPrinter      Printer;  
   
   RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E,
                      RefVal::Kind& hasErr);
@@ -1301,8 +1300,8 @@
   
   virtual void RegisterChecks(GRExprEngine& Eng);
  
-  virtual void getStatePrinters(std::vector<GRState::Printer*>& Printers) {
-    Printers.push_back(&Printer);
+  virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {
+    Printers.push_back(new BindingsPrinter());
   }
   
   bool isGCEnabled() const { return Summaries.isGCEnabled(); }
@@ -1598,7 +1597,7 @@
                ? cast<RVal>(lval::SymbolVal(Sym)) 
                : cast<RVal>(nonlval::SymbolVal(Sym));
         
-        state = state.SetRVal(Ex, X, Eng.getCFG().isBlkExpr(Ex), false);
+        state = state.SetRVal(Ex, X, false);
       }      
       
       break;
@@ -1608,14 +1607,14 @@
       assert (arg_end >= arg_beg);
       assert (idx < (unsigned) (arg_end - arg_beg));
       RVal V = state.GetRVal(*(arg_beg+idx));
-      state = state.SetRVal(Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
+      state = state.SetRVal(Ex, V, false);
       break;
     }
       
     case RetEffect::ReceiverAlias: {
       assert (Receiver);
       RVal V = state.GetRVal(Receiver);
-      state = state.SetRVal(Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
+      state = state.SetRVal(Ex, V, false);
       break;
     }
       
@@ -1626,15 +1625,13 @@
       QualType RetT = GetReturnType(Ex, Eng.getContext());
       
       state = state.set<RefBindings>(Sym, RefVal::makeOwned(RetT), RefBFactory);
-      state = state.SetRVal(Ex, lval::SymbolVal(Sym),
-                            Eng.getCFG().isBlkExpr(Ex), false);
+      state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
 
 #if 0
       RefBindings B = GetRefBindings(StImpl);
       SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned(RetT)));
 #endif 
 
-      
       // FIXME: Add a flag to the checker where allocations are allowed to fail.      
       if (RE.getKind() == RetEffect::OwnedAllocatedSymbol)
         state = state.AddNE(Sym, Eng.getBasicVals().getZeroWithPtrWidth());
@@ -1648,8 +1645,7 @@
       QualType RetT = GetReturnType(Ex, Eng.getContext());
       
       state = state.set<RefBindings>(Sym, RefVal::makeNotOwned(RetT), RefBFactory);
-      state = state.SetRVal(Ex, lval::SymbolVal(Sym),
-                            Eng.getCFG().isBlkExpr(Ex), false);
+      state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
       break;
     }
   }

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=54835&r1=54834&r2=54835&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Fri Aug 15 19:49:49 2008
@@ -177,7 +177,8 @@
 
 void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
   StateMgr.TF = tf;
-  getTF().RegisterChecks(*this);
+  tf->RegisterChecks(*this);
+  tf->RegisterPrinters(getStateManager().Printers);
 }
 
 void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
@@ -2266,109 +2267,12 @@
 #ifndef NDEBUG
 static GRExprEngine* GraphPrintCheckerState;
 static SourceManager* GraphPrintSourceManager;
-static GRState::Printer **GraphStatePrinterBeg, **GraphStatePrinterEnd;
 
 namespace llvm {
 template<>
 struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
   public DefaultDOTGraphTraits {
     
-  static void PrintVarBindings(std::ostream& Out, GRState* St) {
-
-    Out << "Variables:\\l";
-    
-    bool isFirst = true;
-    
-    for (GRState::vb_iterator I=St->vb_begin(), E=St->vb_end(); I!=E;++I) {        
-
-      if (isFirst)
-        isFirst = false;
-      else
-        Out << "\\l";
-      
-      Out << ' ' << I.getKey()->getName() << " : ";
-      I.getData().print(Out);
-    }
-    
-  }
-    
-    
-  static void PrintSubExprBindings(std::ostream& Out, GRState* St){
-    
-    bool isFirst = true;
-    
-    for (GRState::seb_iterator I=St->seb_begin(), E=St->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);
-    }
-  }
-    
-  static void PrintBlkExprBindings(std::ostream& Out, GRState* St){
-        
-    bool isFirst = true;
-
-    for (GRState::beb_iterator I=St->beb_begin(), E=St->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);
-    }
-  }
-    
-  static void PrintEQ(std::ostream& Out, GRState* St) {
-    GRState::ConstEqTy CE = St->ConstEq;
-    
-    if (CE.isEmpty())
-      return;
-    
-    Out << "\\l\\|'==' constraints:";
-
-    for (GRState::ConstEqTy::iterator I=CE.begin(), E=CE.end(); I!=E;++I)
-      Out << "\\l $" << I.getKey() << " : " << I.getData()->toString();
-  }
-    
-  static void PrintNE(std::ostream& Out, GRState* St) {
-    GRState::ConstNotEqTy NE = St->ConstNotEq;
-    
-    if (NE.isEmpty())
-      return;
-    
-    Out << "\\l\\|'!=' constraints:";
-    
-    for (GRState::ConstNotEqTy::iterator I=NE.begin(), EI=NE.end();
-         I != EI; ++I){
-      
-      Out << "\\l $" << I.getKey() << " : ";
-      bool isFirst = true;
-      
-      GRState::IntSetTy::iterator J=I.getData().begin(),
-                                    EJ=I.getData().end();      
-      for ( ; J != EJ; ++J) {        
-        if (isFirst) isFirst = false;
-        else Out << ", ";
-        
-        Out << (*J)->toString();
-      }    
-    }
-  }
-    
   static std::string getNodeAttributes(const GRExprEngine::NodeTy* N, void*) {
     
     if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
@@ -2509,7 +2413,8 @@
     
     Out << "\\|StateID: " << (void*) N->getState() << "\\|";
 
-    N->getState()->printDOT(Out, GraphStatePrinterBeg, GraphStatePrinterEnd);
+    GRStateRef state(N->getState(), GraphPrintCheckerState->getStateManager());
+    state.printDOT(Out);
       
     Out << "\\l";
     return Out.str();
@@ -2575,19 +2480,10 @@
     GraphPrintCheckerState = this;
     GraphPrintSourceManager = &getContext().getSourceManager();
 
-    // Get the state printers.
-    std::vector<GRState::Printer*> Printers;
-    getTF().getStatePrinters(Printers);   
-    GraphStatePrinterBeg = Printers.empty() ? 0 : &Printers[0];
-    GraphStatePrinterEnd = Printers.empty() ? 0 : &Printers[0]+Printers.size();
-    
-
     llvm::ViewGraph(*G.roots_begin(), "GRExprEngine");
     
     GraphPrintCheckerState = NULL;
     GraphPrintSourceManager = NULL;
-    GraphStatePrinterBeg = NULL;
-    GraphStatePrinterEnd = NULL;
   }
 #endif
 }
@@ -2596,13 +2492,7 @@
 #ifndef NDEBUG
   GraphPrintCheckerState = this;
   GraphPrintSourceManager = &getContext().getSourceManager();
-  
-  // Get the state printers.
-  std::vector<GRState::Printer*> Printers;
-  getTF().getStatePrinters(Printers);
-  GraphStatePrinterBeg = Printers.empty() ? 0 : &Printers[0];
-  GraphStatePrinterEnd = Printers.empty() ? 0 : &Printers[0]+Printers.size();
-  
+    
   GRExprEngine::GraphTy* TrimmedG = G.Trim(Beg, End);
 
   if (!TrimmedG)
@@ -2614,7 +2504,5 @@
   
   GraphPrintCheckerState = NULL;
   GraphPrintSourceManager = NULL;
-  GraphStatePrinterBeg = NULL;
-  GraphStatePrinterEnd = NULL;
 #endif
 }

Modified: cfe/trunk/lib/Analysis/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRState.cpp?rev=54835&r1=54834&r2=54835&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRState.cpp (original)
+++ cfe/trunk/lib/Analysis/GRState.cpp Fri Aug 15 19:49:49 2008
@@ -17,10 +17,71 @@
 
 using namespace clang;
 
+GRStateManager::~GRStateManager() {
+  for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
+        E=Printers.end(); I!=E; ++I)
+    delete *I;
+  
+  for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
+       I!=E; ++I)
+    I->second.second(I->second.first);
+}
+
+//===----------------------------------------------------------------------===//
+//  Basic symbolic analysis.  This will eventually be refactored into a
+//  separate component.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::ImmutableMap<SymbolID,GRState::IntSetTy> ConstNotEqTy;
+
+static int ConstNotEqTyIndex = 0;
+
+namespace clang {
+  template<> struct GRStateTrait<ConstNotEqTy> {
+    typedef ConstNotEqTy             data_type;
+    typedef ConstNotEqTy::Factory&   context_type;  
+    typedef SymbolID                 key_type;
+    typedef GRState::IntSetTy        value_type;
+    typedef const GRState::IntSetTy* lookup_type;
+    
+    static data_type MakeData(void* const* p) {
+      return p ? ConstNotEqTy((ConstNotEqTy::TreeTy*) *p) : ConstNotEqTy(0);
+    }  
+    static void* MakeVoidPtr(ConstNotEqTy B) {
+      return B.getRoot();
+    }  
+    static void* GDMIndex() {
+      return &ConstNotEqTyIndex;
+    }  
+    static lookup_type Lookup(ConstNotEqTy B, SymbolID K) {
+      return B.lookup(K);
+    }  
+    static data_type Set(data_type B, key_type K, value_type E,context_type F){
+      return F.Add(B, K, E);
+    }
+    
+    static data_type Remove(ConstNotEqTy B, SymbolID K, context_type F) {
+      return F.Remove(B, K);
+    }
+    
+    static context_type MakeContext(void* p) {
+      return *((ConstNotEqTy::Factory*) p);
+    }
+    
+    static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
+      return new ConstNotEqTy::Factory(Alloc);      
+    }
+    
+    static void DeleteContext(void* Ctx) {
+      delete (ConstNotEqTy::Factory*) Ctx;
+    }      
+  };
+}
+
 bool GRState::isNotEqual(SymbolID sym, const llvm::APSInt& V) const {
 
   // Retrieve the NE-set associated with the given symbol.
-  const ConstNotEqTy::data_type* T = ConstNotEq.lookup(sym);
+  const ConstNotEqTy::data_type* T = get<ConstNotEqTy>(sym);
 
   // See if V is present in the NE-set.
   return T ? T->contains(&V) : false;
@@ -42,8 +103,8 @@
 
 const GRState*
 GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc,
-                                      const LiveVariables& Liveness,
-                                      DeadSymbolsTy& DSymbols) {  
+                                   const LiveVariables& Liveness,
+                                   DeadSymbolsTy& DSymbols) {  
   
   // This code essentially performs a "mark-and-sweep" of the VariableBindings.
   // The roots are any Block-level exprs and Decls that our liveness algorithm
@@ -97,7 +158,9 @@
                                        LSymbols, DSymbols);
   
   // Remove the dead symbols from the symbol tracker.
-  for (GRState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) {
+  // FIXME: Refactor into something else that manages symbol values.
+  for (GRState::ConstEqTy::iterator I = St->ConstEq.begin(),
+       E=St->ConstEq.end(); I!=E; ++I) {
 
     SymbolID sym = I.getKey();    
     
@@ -107,17 +170,19 @@
     }
   }
   
-  for (GRState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E;++I){
-    
-    SymbolID sym = I.getKey();
-    
+  GRStateRef state(getPersistentState(NewSt), *this);
+  ConstNotEqTy CNE = state.get<ConstNotEqTy>();
+  ConstNotEqTy::Factory& CNEFactory = state.get_context<ConstNotEqTy>();
+
+  for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
+    SymbolID sym = I.getKey();    
     if (!LSymbols.count(sym)) {
       DSymbols.insert(sym);
-      NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, sym);
+      CNE = CNEFactory.Remove(CNE, sym);
     }
   }
   
-  return getPersistentState(NewSt);
+  return state.set<ConstNotEqTy>(CNE);
 }
 
 const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV,
@@ -148,21 +213,19 @@
 
 
 const GRState* GRStateManager::AddNE(const GRState* St, SymbolID sym,
-                                           const llvm::APSInt& V) {
+                                     const llvm::APSInt& V) {
+  
+  GRStateRef state(St, *this);
 
   // First, retrieve the NE-set associated with the given symbol.
-  GRState::ConstNotEqTy::data_type* T = St->ConstNotEq.lookup(sym);  
+  ConstNotEqTy::data_type* T = state.get<ConstNotEqTy>(sym);  
   GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
   
   // Now add V to the NE set.
   S = ISetFactory.Add(S, &V);
   
   // Create a new state with the old binding replaced.
-  GRState NewSt = *St;
-  NewSt.ConstNotEq = CNEFactory.Add(NewSt.ConstNotEq, sym, S);
-    
-  // Get the persistent copy.
-  return getPersistentState(NewSt);
+  return state.set<ConstNotEqTy>(sym, S);
 }
 
 const GRState* GRStateManager::AddEQ(const GRState* St, SymbolID sym,
@@ -179,7 +242,7 @@
 const GRState* GRStateManager::getInitialState() {
 
   GRState StateImpl(EnvMgr.getInitialEnvironment(), StMgr->getInitialStore(),
-                    GDMFactory.GetEmptyMap(), CNEFactory.GetEmptyMap(),
+                    GDMFactory.GetEmptyMap(),
                     CEFactory.GetEmptyMap());
   
   return getPersistentState(StateImpl);
@@ -200,14 +263,10 @@
   return I;
 }
 
-void GRState::printDOT(std::ostream& Out,
-                       Printer** Beg, Printer** End) const {
-  print(Out, Beg, End, "\\l", "\\|");
-}
 
-void GRState::printStdErr(Printer** Beg, Printer** End) const {
-  print(*llvm::cerr, Beg, End);
-}  
+//===----------------------------------------------------------------------===//
+//  State pretty-printing.
+//===----------------------------------------------------------------------===//
 
 void GRState::print(std::ostream& Out, Printer** Beg, Printer** End,
                     const char* nl, const char* sep) const {
@@ -279,14 +338,14 @@
 
   // Print != constraints.
   // FIXME: Make just another printer do this.
-    
-  if (!ConstNotEq.isEmpty()) {
+  
+  ConstNotEqTy CNE = get<ConstNotEqTy>();
+  
+  if (!CNE.isEmpty()) {
   
     Out << nl << sep << "'!=' constraints:";
   
-    for (ConstNotEqTy::iterator I  = ConstNotEq.begin(),
-                                EI = ConstNotEq.end();   I != EI; ++I) {
-    
+    for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
       Out << nl << " $" << I.getKey() << " : ";
       isFirst = true;
     
@@ -305,6 +364,20 @@
   for ( ; Beg != End ; ++Beg) (*Beg)->Print(Out, this, nl, sep);
 }
 
+void GRStateRef::printDOT(std::ostream& Out) const {
+  print(Out, "\\l", "\\|");
+}
+
+void GRStateRef::printStdErr() const {
+  print(*llvm::cerr);
+}  
+
+void GRStateRef::print(std::ostream& Out, const char* nl, const char* sep)const{
+  GRState::Printer **beg = Mgr->Printers.empty() ? 0 : &Mgr->Printers[0];
+  GRState::Printer **end = !beg ? 0 : beg + Mgr->Printers.size();  
+  St->print(Out, beg, end, nl, sep);
+}
+
 //===----------------------------------------------------------------------===//
 // Generic Data Map.
 //===----------------------------------------------------------------------===//
@@ -313,6 +386,20 @@
   return GDM.lookup(K);
 }
 
+void*
+GRStateManager::FindGDMContext(void* K,
+                               void* (*CreateContext)(llvm::BumpPtrAllocator&),
+                               void (*DeleteContext)(void*)) {
+  
+  std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
+  if (!p.first) {
+    p.first = CreateContext(Alloc);
+    p.second = DeleteContext;
+  }
+  
+  return p.first;
+}
+
 const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){  
   GRState::GenericDataMap M1 = St->getGDM();
   GRState::GenericDataMap M2 = GDMFactory.Add(M1, Key, Data);
@@ -330,7 +417,8 @@
 //===----------------------------------------------------------------------===//
 
 bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
-                                const llvm::APSInt& Y) {
+                             const llvm::APSInt& Y) {
+  
   RVal V = GetRVal(state, Ex);
   
   if (lval::ConcreteInt* X = dyn_cast<lval::ConcreteInt>(&V))
@@ -348,8 +436,7 @@
   return false;
 }
   
-bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
-                                uint64_t x) {
+bool GRStateManager::isEqual(const GRState* state, Expr* Ex, uint64_t x) {
   return isEqual(state, Ex, BasicVals.getValue(x, Ex->getType()));
 }
 
@@ -382,7 +469,6 @@
         return AssumeSymEQ(St, cast<lval::SymbolVal>(Cond).getSymbol(),
                            BasicVals.getZeroWithPtrWidth(), isFeasible);
       
-      
     case lval::DeclValKind:
     case lval::FuncValKind:
     case lval::GotoLabelKind:





More information about the cfe-commits mailing list