]> granicus.if.org Git - clang/commitdiff
Added "SymIntConstraint", a utility class to represent intermediate values for
authorTed Kremenek <kremenek@apple.com>
Tue, 5 Feb 2008 21:32:43 +0000 (21:32 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 5 Feb 2008 21:32:43 +0000 (21:32 +0000)
transfer function evaluation that represent constraints between symbolic values
and constant integers.

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

Analysis/RValues.cpp
Analysis/RValues.h

index 2854ee641447bcd1be90d98317bc873d98631ab2..8861f576f35360dfde3974806985db3088493267 100644 (file)
@@ -38,7 +38,7 @@ SymbolManager::SymbolManager() {}
 SymbolManager::~SymbolManager() {}
 
 //===----------------------------------------------------------------------===//
-// ValueManager.
+// Values and ValueManager.
 //===----------------------------------------------------------------------===//
 
 ValueManager::~ValueManager() {
@@ -49,7 +49,7 @@ ValueManager::~ValueManager() {
     I->getValue().~APSInt();
 }
 
-APSInt& ValueManager::getValue(const APSInt& X) {
+const APSInt& ValueManager::getValue(const APSInt& X) {
   llvm::FoldingSetNodeID ID;
   void* InsertPos;
   typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
@@ -66,19 +66,41 @@ APSInt& ValueManager::getValue(const APSInt& X) {
   return *P;
 }
 
-APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth, bool isUnsigned) {
+const APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
+                                     bool isUnsigned) {
   APSInt V(BitWidth, isUnsigned);
   V = X;  
   return getValue(V);
 }
 
-APSInt& ValueManager::getValue(uint64_t X, QualType T, SourceLocation Loc) {
+const APSInt& ValueManager::getValue(uint64_t X, QualType T,
+                                     SourceLocation Loc) {
+  
   unsigned bits = Ctx.getTypeSize(T, Loc);
   APSInt V(bits, T->isUnsignedIntegerType());
   V = X;
   return getValue(V);
 }
 
+const SymIntConstraint&
+ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
+                            const llvm::APSInt& V) {
+  
+  llvm::FoldingSetNodeID ID;
+  SymIntConstraint::Profile(ID, sym, Op, V);
+  void* InsertPos;
+  
+  SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
+  
+  if (!C) {
+    C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
+    new (C) SymIntConstraint(sym, Op, V);
+    SymIntCSet.InsertNode(C, InsertPos);
+  }
+  
+  return *C;
+}
+
 //===----------------------------------------------------------------------===//
 // Transfer function for Casts.
 //===----------------------------------------------------------------------===//
index c69a70a52d73280fbe60a5afc920045251f7b772..6980a9bba44d353c79e2af5a54d21e11764bd954 100644 (file)
@@ -37,7 +37,7 @@
 #include <functional>
 
 //==------------------------------------------------------------------------==//
-//  RValue "management" data structures.
+//  Values and ValueManager.
 //==------------------------------------------------------------------------==// 
 
 namespace clang {
@@ -51,7 +51,10 @@ public:
   bool isInitialized() const { return Data != (unsigned) ~0; }
   operator unsigned() const { assert (isInitialized()); return Data; }
 
-  void Profile(llvm::FoldingSetNodeID& ID) const { ID.AddInteger(Data); }
+  void Profile(llvm::FoldingSetNodeID& ID) const { 
+    assert (isInitialized());
+    ID.AddInteger(Data);
+  }
 
   static inline void Profile(llvm::FoldingSetNodeID& ID, SymbolID X) {
     X.Profile(ID);
@@ -70,6 +73,36 @@ public:
   inline void* getPtr() const { return reinterpret_cast<void*>(Data & ~Mask); }  
   inline bool operator==(const SymbolData& R) const { return Data == R.Data; }  
 };
+  
+
+class SymIntConstraint : public llvm::FoldingSetNode {
+  SymbolID Symbol;
+  BinaryOperator::Opcode Op;
+  const llvm::APSInt& Val;
+public:  
+  SymIntConstraint(SymbolID sym, BinaryOperator::Opcode op, 
+                   const llvm::APSInt& V)
+    : Symbol(sym),
+      Op(op), Val(V) {}
+  
+  BinaryOperator::Opcode getOpcode() const { return Op; }
+  SymbolID getSymbol() const { return Symbol; }
+  const llvm::APSInt& getInt() const { return Val; }
+  
+  static inline void Profile(llvm::FoldingSetNodeID& ID,
+                             const SymbolID& Symbol,
+                             BinaryOperator::Opcode Op,
+                             const llvm::APSInt& Val) {
+    Symbol.Profile(ID);
+    ID.AddInteger(Op);
+    ID.AddPointer(&Val);
+  }
+  
+  void Profile(llvm::FoldingSetNodeID& ID) {
+    Profile(ID, Symbol, Op, Val);
+  }
+};
+  
 
 class SymbolManager {
   std::vector<SymbolData> SymbolToData;
@@ -88,15 +121,22 @@ public:
   
   SymbolID getSymbol(ParmVarDecl* D);
 };
+  
 
 class ValueManager {
   typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
           APSIntSetTy;
   
+  typedef llvm::FoldingSet<SymIntConstraint>
+          SymIntCSetTy;
+  
+  
   ASTContext& Ctx;
-  APSIntSetTy APSIntSet;
   llvm::BumpPtrAllocator& BPAlloc;
   
+  APSIntSetTy   APSIntSet;
+  SymIntCSetTy  SymIntCSet;
+  
 public:
   ValueManager(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc) 
     : Ctx(ctx), BPAlloc(Alloc) {}
@@ -104,10 +144,13 @@ public:
   ~ValueManager();
   
   ASTContext& getContext() const { return Ctx; }  
-  llvm::APSInt& getValue(const llvm::APSInt& X);
-  llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
-  llvm::APSInt& getValue(uint64_t X, QualType T,
-                   SourceLocation Loc = SourceLocation());
+  const llvm::APSInt& getValue(const llvm::APSInt& X);
+  const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
+  const llvm::APSInt& getValue(uint64_t X, QualType T,
+                               SourceLocation Loc = SourceLocation());
+  
+  const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
+                                        const llvm::APSInt& V);
 };
 
 //==------------------------------------------------------------------------==//