Added "nonlval::LValAsInteger" to represent abstract LVals casted to integers, allowing us to track lvals when they are casted back to pointers.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50108 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicValueFactory.cpp b/lib/Analysis/BasicValueFactory.cpp
index 88b360d..22fb2d1 100644
--- a/lib/Analysis/BasicValueFactory.cpp
+++ b/lib/Analysis/BasicValueFactory.cpp
@@ -14,15 +14,32 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/PathSensitive/BasicValueFactory.h"
+#include "clang/Analysis/PathSensitive/RValues.h"
 
 using namespace clang;
 
+typedef std::pair<RVal, unsigned> SizedRVal;
+
+namespace llvm {
+template<> struct FoldingSetTrait<SizedRVal> {
+  static inline void Profile(const SizedRVal& X, llvm::FoldingSetNodeID& ID) {
+    X.first.Profile(ID);
+    ID.AddInteger(X.second);
+  }
+};
+}
+
+typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SizedRVal> >
+  PersistentRValsTy;
+
 BasicValueFactory::~BasicValueFactory() {
   // Note that the dstor for the contents of APSIntSet will never be called,
   // so we iterate over the set and invoke the dstor for each APSInt.  This
   // frees an aux. memory allocated to represent very large constants.
   for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
     I->getValue().~APSInt();
+  
+  delete (PersistentRValsTy*) PersistentRVals;  
 }
 
 const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
@@ -165,3 +182,29 @@
       return &getValue( V1 ^ V2 );
   }
 }
+
+
+const std::pair<RVal, unsigned>&
+BasicValueFactory::getPersistentSizedRVal(const RVal& V, unsigned Bits) {
+  
+  // Lazily create the folding set.
+  if (!PersistentRVals) PersistentRVals = new PersistentRValsTy();
+    
+  llvm::FoldingSetNodeID ID;
+  void* InsertPos;
+  V.Profile(ID);
+  ID.AddInteger(Bits);
+  
+  PersistentRValsTy& Map = *((PersistentRValsTy*) PersistentRVals);
+  
+  typedef llvm::FoldingSetNodeWrapper<SizedRVal> FoldNodeTy;
+  FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
+  
+  if (!P) {  
+    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    new (P) FoldNodeTy(std::make_pair(V, Bits));
+    Map.InsertNode(P, InsertPos);
+  }
+
+  return *P;
+}