]> granicus.if.org Git - clang/commitdiff
Added "symbol iterators" for RValues, allowing easy iteration over the symbols
authorTed Kremenek <kremenek@apple.com>
Thu, 14 Feb 2008 23:25:54 +0000 (23:25 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 14 Feb 2008 23:25:54 +0000 (23:25 +0000)
referenced by an RValue, instead of having to query the type of the RValue.

Modified ValueState::RemoveDeadBindings to also prune dead symbols.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47142 91177308-0d34-0410-b5e6-96231b3b80d8

Analysis/RValues.cpp
Analysis/ValueState.cpp
Analysis/ValueState.h
include/clang/Analysis/PathSensitive/RValues.h

index 8d16f12d32eed9398b3870885ff6e53909e19bda..8eb607c9e5338bdc55f702878ff5f41519711c4a 100644 (file)
@@ -123,8 +123,32 @@ ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
   return *C;
 }
 
+//===----------------------------------------------------------------------===//
+// Symbol Iteration.
+//===----------------------------------------------------------------------===//
+
+RValue::symbol_iterator RValue::symbol_begin() const {
+  if (isa<LValue>(this)) {
+    if (isa<lval::SymbolVal>(this))
+      return (symbol_iterator) (&Data);
+  }
+  else {
+    if (isa<nonlval::SymbolVal>(this))
+      return (symbol_iterator) (&Data);
+    else if (isa<nonlval::SymIntConstraintVal>(this)) {
+      const SymIntConstraint& C =
+        cast<nonlval::SymIntConstraintVal>(this)->getConstraint();
+      return (symbol_iterator) &C.getSymbol();
+    }
+  }
+  
+  return NULL;
+}
 
+RValue::symbol_iterator RValue::symbol_end() const {
+  symbol_iterator X = symbol_begin();
+  return X ? X+1 : NULL;
+}
 
 //===----------------------------------------------------------------------===//
 // Transfer function dispatch for Non-LValues.
index c74c876b5121fd718390ddd0a411d97ee0cc36cc..27818efa343029f22f3f2da471da0a0ba55d73de 100644 (file)
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ValueState.h"
+#include "llvm/ADT/SmallSet.h"
 
 using namespace clang;
 
@@ -43,6 +44,8 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
   // for optimum performance.
   
   llvm::SmallVector<ValueDecl*, 10> WList;
+  llvm::SmallPtrSet<ValueDecl*, 10> Marked;  
+  llvm::SmallSet<SymbolID, 20> MarkedSymbols;
   
   ValueStateImpl NewSt = *St;
   
@@ -55,10 +58,16 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
     Expr* BlkExpr = I.getKey();
     
     if (Liveness.isLive(Loc, BlkExpr)) {
-      if (isa<lval::DeclVal>(I.getData())) {
-        lval::DeclVal LV = cast<lval::DeclVal>(I.getData());
+      RValue X = I.getData();
+      
+      if (isa<lval::DeclVal>(X)) {
+        lval::DeclVal LV = cast<lval::DeclVal>(X);
         WList.push_back(LV.getDecl());
       }
+      
+      for (RValue::symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end();
+                                   SI != SE; ++SI)
+        MarkedSymbols.insert(*SI);      
     }
     else
       NewSt.BlockExprBindings = Remove(NewSt, BlkExpr);
@@ -70,8 +79,7 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
   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());
-  
-  llvm::SmallPtrSet<ValueDecl*, 10> Marked;  
+
   
   while (!WList.empty()) {
     ValueDecl* V = WList.back();
@@ -83,7 +91,11 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
     Marked.insert(V);
     
     if (V->getType()->isPointerType()) {
-      const LValue& LV = cast<LValue>(GetValue(St, lval::DeclVal(V)));
+      const LValue& LV = cast<LValue>(GetValue(St, lval::DeclVal(V)));      
+      
+      for (RValue::symbol_iterator SI=LV.symbol_begin(), SE=LV.symbol_end();
+           SI != SE; ++SI)
+        MarkedSymbols.insert(*SI); 
       
       if (!isa<lval::DeclVal>(LV))
         continue;
@@ -93,10 +105,20 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
     }    
   }
   
+  // Remove dead variable bindings.
   for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
     if (!Marked.count(I.getKey()))
       NewSt.VarBindings = Remove(NewSt, I.getKey());
   
+  // Remove dead symbols.
+  for (ValueState::ce_iterator I = St.ce_begin(), E=St.ce_end(); I!=E; ++I)
+    if (!MarkedSymbols.count(I.getKey()))
+      NewSt.ConstantEq = CEFactory.Remove(NewSt.ConstantEq, I.getKey());
+  
+  for (ValueState::cne_iterator I = St.cne_begin(), E=St.cne_end(); I!=E; ++I)
+    if (!MarkedSymbols.count(I.getKey()))
+      NewSt.ConstantNotEq = CNEFactory.Remove(NewSt.ConstantNotEq, I.getKey());
+  
   return getPersistentState(NewSt);
 }
 
index c0bc81deda9a9b77f042b634c573078dba20c412..38c34cb84a3a1cf2c1f689a3adaf6d94cb08e49d 100644 (file)
@@ -153,6 +153,14 @@ public:
   beb_iterator beb_begin() const { return Data->BlockExprBindings.begin(); }
   beb_iterator beb_end() const { return Data->BlockExprBindings.end(); }
   
+  typedef ConstantNotEqTy::iterator cne_iterator;
+  cne_iterator cne_begin() const { return Data->ConstantNotEq.begin(); }
+  cne_iterator cne_end() const { return Data->ConstantNotEq.end(); }
+  
+  typedef ConstantEqTy::iterator ce_iterator;
+  ce_iterator ce_begin() const { return Data->ConstantEq.begin(); }
+  ce_iterator ce_end() const { return Data->ConstantEq.end(); }
+  
   // Profiling and equality testing.
   
   bool operator==(const ValueState& RHS) const {
index 3eb08ff37e386d49df21c6b941274e1d6a4611ec..acf841170d3cf1b6c3d355079308b163bff8e5f8 100644 (file)
@@ -137,7 +137,7 @@ public:
       Op(op), Val(V) {}
   
   BinaryOperator::Opcode getOpcode() const { return Op; }
-  SymbolID getSymbol() const { return Symbol; }
+  const SymbolID& getSymbol() const { return Symbol; }
   const llvm::APSInt& getInt() const { return Val; }
   
   static inline void Profile(llvm::FoldingSetNodeID& ID,
@@ -249,7 +249,7 @@ public:
   enum { BaseBits = 2, 
          BaseMask = 0x3 };
   
-private:
+protected:
   void* Data;
   unsigned Kind;
   
@@ -261,10 +261,6 @@ protected:
   explicit RValue(BaseKind k)
     : Data(0), Kind(k) {}
   
-  void* getRawPtr() const {
-    return reinterpret_cast<void*>(Data);
-  }
-  
 public:
   ~RValue() {};
   
@@ -293,6 +289,10 @@ public:
   void print(std::ostream& OS) const;
   void print() const;
   
+  typedef const SymbolID* symbol_iterator;
+  symbol_iterator symbol_begin() const;
+  symbol_iterator symbol_end() const;  
+  
   // Implement isa<T> support.
   static inline bool classof(const RValue*) { return true; }
 };
@@ -374,7 +374,7 @@ namespace nonlval {
                 reinterpret_cast<void*>((uintptr_t) SymID)) {}
     
     SymbolID getSymbol() const {
-      return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
+      return (SymbolID) reinterpret_cast<uintptr_t>(Data);
     }
     
     static inline bool classof(const RValue* V) {
@@ -388,7 +388,7 @@ namespace nonlval {
     : NonLValue(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
 
     const SymIntConstraint& getConstraint() const {
-      return *reinterpret_cast<SymIntConstraint*>(getRawPtr());
+      return *reinterpret_cast<SymIntConstraint*>(Data);
     }
     
     static inline bool classof(const RValue* V) {
@@ -401,7 +401,7 @@ namespace nonlval {
     ConcreteInt(const llvm::APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
     
     const llvm::APSInt& getValue() const {
-      return *static_cast<llvm::APSInt*>(getRawPtr());
+      return *static_cast<llvm::APSInt*>(Data);
     }
     
     // Transfer functions for binary/unary operations on ConcreteInts.
@@ -442,7 +442,7 @@ namespace lval {
     : LValue(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
     
     SymbolID getSymbol() const {
-      return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
+      return (SymbolID) reinterpret_cast<uintptr_t>(Data);
     }
     
     static inline bool classof(const RValue* V) {
@@ -459,7 +459,7 @@ namespace lval {
     GotoLabel(LabelStmt* Label) : LValue(GotoLabelKind, Label) {}
     
     LabelStmt* getLabel() const {
-      return static_cast<LabelStmt*>(getRawPtr());
+      return static_cast<LabelStmt*>(Data);
     }
     
     static inline bool classof(const RValue* V) {
@@ -477,7 +477,7 @@ namespace lval {
     DeclVal(const ValueDecl* vd) : LValue(DeclValKind,vd) {}
     
     ValueDecl* getDecl() const {
-      return static_cast<ValueDecl*>(getRawPtr());
+      return static_cast<ValueDecl*>(Data);
     }
     
     inline bool operator==(const DeclVal& R) const {
@@ -503,7 +503,7 @@ namespace lval {
     ConcreteInt(const llvm::APSInt& V) : LValue(ConcreteIntKind, &V) {}
     
     const llvm::APSInt& getValue() const {
-      return *static_cast<llvm::APSInt*>(getRawPtr());
+      return *static_cast<llvm::APSInt*>(Data);
     }