[cfe-commits] r46618 - in /cfe/trunk/Analysis: GRConstants.cpp RValues.cpp RValues.h ValueState.h

Ted Kremenek kremenek at apple.com
Thu Jan 31 11:34:24 PST 2008


Author: kremenek
Date: Thu Jan 31 13:34:24 2008
New Revision: 46618

URL: http://llvm.org/viewvc/llvm-project?rev=46618&view=rev
Log:
Moved RValue code in GRConstants.cpp to RValue.[h,cpp].
Moved ValueKey/ValueMap declaration to ValueState.h.

Added:
    cfe/trunk/Analysis/RValues.cpp
    cfe/trunk/Analysis/RValues.h
    cfe/trunk/Analysis/ValueState.h
Modified:
    cfe/trunk/Analysis/GRConstants.cpp

Modified: cfe/trunk/Analysis/GRConstants.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRConstants.cpp?rev=46618&r1=46617&r2=46618&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRConstants.cpp (original)
+++ cfe/trunk/Analysis/GRConstants.cpp Thu Jan 31 13:34:24 2008
@@ -15,6 +15,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "RValues.h"
+#include "ValueState.h"
+
 #include "clang/Analysis/PathSensitive/GREngine.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
@@ -44,726 +47,6 @@
 using llvm::APSInt;
 
 //===----------------------------------------------------------------------===//
-/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
-///  Stmt*.  Use cast<> or dyn_cast<> to get actual pointer type
-//===----------------------------------------------------------------------===//
-namespace {
-
-class SymbolID {
-  unsigned Data;
-public:
-  SymbolID() : Data(~0) {}
-  SymbolID(unsigned x) : Data(x) {}
-  
-  bool isInitialized() const { return Data != (unsigned) ~0; }
-  operator unsigned() const { assert (isInitialized()); return Data; }
-};
-
-class VISIBILITY_HIDDEN ValueKey {
-  uintptr_t Raw;  
-  void operator=(const ValueKey& RHS); // Do not implement.
-  
-public:
-  enum  Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, // L-Value Bindings.
-               IsSymbol=0x3, // Symbol Bindings.
-               Flags=0x3 };
-  
-  inline Kind getKind() const {
-    return (Kind) (Raw & Flags);
-  }
-  
-  inline void* getPtr() const { 
-    assert (getKind() != IsSymbol);
-    return reinterpret_cast<void*>(Raw & ~Flags);
-  }
-  
-  inline SymbolID getSymbolID() const {
-    assert (getKind() == IsSymbol);
-    return Raw >> 2;
-  }
-  
-  ValueKey(const ValueDecl* VD)
-    : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {
-      assert(VD && "ValueDecl cannot be NULL.");
-    }
-
-  ValueKey(Stmt* S, bool isBlkExpr = false) 
-    : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
-      assert(S && "Tracked statement cannot be NULL.");
-    }
-  
-  ValueKey(SymbolID V)
-    : Raw((V << 2) | IsSymbol) {}  
-  
-  bool isSymbol()  const { return getKind() == IsSymbol; }
-  bool isSubExpr() const { return getKind() == IsSubExpr; }
-  bool isBlkExpr() const { return getKind() == IsBlkExpr; }
-  bool isDecl()    const { return getKind() == IsDecl; }
-  bool isStmt()    const { return getKind() <= IsBlkExpr; }
-  
-  inline void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddInteger(isSymbol() ? 1 : 0);
-
-    if (isSymbol())
-      ID.AddInteger(getSymbolID());
-    else    
-      ID.AddPointer(getPtr());
-  }
-  
-  inline bool operator==(const ValueKey& X) const {
-    return isSymbol() ? getSymbolID() == X.getSymbolID()
-                      : getPtr() == X.getPtr();
-  }
-  
-  inline bool operator!=(const ValueKey& X) const {
-    return !operator==(X);
-  }
-  
-  inline bool operator<(const ValueKey& X) const { 
-    if (isSymbol())
-      return X.isSymbol() ? getSymbolID() < X.getSymbolID() : false;
-    
-    return getPtr() < X.getPtr();
-  }
-};
-} // end anonymous namespace
-
-// Machinery to get cast<> and dyn_cast<> working with ValueKey.
-namespace llvm {
-  template<> inline bool isa<ValueDecl,ValueKey>(const ValueKey& V) {
-    return V.getKind() == ValueKey::IsDecl;
-  }
-  template<> inline bool isa<Stmt,ValueKey>(const ValueKey& V) {
-    return ((unsigned) V.getKind()) < ValueKey::IsDecl;
-  }
-  template<> struct VISIBILITY_HIDDEN cast_retty_impl<ValueDecl,ValueKey> {
-    typedef const ValueDecl* ret_type;
-  };
-  template<> struct VISIBILITY_HIDDEN cast_retty_impl<Stmt,ValueKey> {
-    typedef const Stmt* ret_type;
-  };
-  template<> struct VISIBILITY_HIDDEN simplify_type<ValueKey> {
-    typedef void* SimpleType;
-    static inline SimpleType getSimplifiedValue(const ValueKey &V) {
-      return V.getPtr();
-    }
-  };
-} // end llvm namespace
-
-
-//===----------------------------------------------------------------------===//
-// SymbolManager.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN SymbolData {
-  uintptr_t Data;
-public:
-  enum Kind { ParmKind = 0x0, Mask = 0x3 };
-  
-  SymbolData(ParmVarDecl* D)
-    : Data(reinterpret_cast<uintptr_t>(D) | ParmKind) {}
-  
-  inline Kind getKind() const { return (Kind) (Data & Mask); }
-  inline void* getPtr() const { return reinterpret_cast<void*>(Data & ~Mask); }  
-  inline bool operator==(const SymbolData& R) const { return Data == R.Data; }  
-};
-}
-
-// Machinery to get cast<> and dyn_cast<> working with SymbolData.
-namespace llvm {
-  template<> inline bool isa<ParmVarDecl,SymbolData>(const SymbolData& V) {
-    return V.getKind() == SymbolData::ParmKind;
-  }
-  template<> struct VISIBILITY_HIDDEN cast_retty_impl<ParmVarDecl,SymbolData> {
-    typedef const ParmVarDecl* ret_type;
-  };
-  template<> struct VISIBILITY_HIDDEN simplify_type<SymbolData> {
-    typedef void* SimpleType;
-    static inline SimpleType getSimplifiedValue(const SymbolData &V) {
-      return V.getPtr();
-    }
-  };
-} // end llvm namespace
-
-namespace {
-class VISIBILITY_HIDDEN SymbolManager {
-  std::vector<SymbolData> SymbolToData;
-  
-  typedef llvm::DenseMap<void*,SymbolID> MapTy;
-  MapTy DataToSymbol;
-  
-public:
-  SymbolData getSymbolData(SymbolID id) const {
-    assert (id < SymbolToData.size());
-    return SymbolToData[id];
-  }
-  
-  SymbolID getSymbol(ParmVarDecl* D);
-};
-} // end anonymous namespace
-
-SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
-  SymbolID& X = DataToSymbol[D];
-
-  if (!X.isInitialized()) {
-    X = SymbolToData.size();
-    SymbolToData.push_back(D);
-  }
-  
-  return X;
-}
-
-//===----------------------------------------------------------------------===//
-// ValueManager.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-typedef llvm::ImmutableSet<APSInt > APSIntSetTy;
-
-  
-class VISIBILITY_HIDDEN ValueManager {
-  ASTContext& Ctx;
-  
-  typedef  llvm::FoldingSet<llvm::FoldingSetNodeWrapper<APSInt> > APSIntSetTy;
-  APSIntSetTy APSIntSet;
-  
-  llvm::BumpPtrAllocator BPAlloc;
-  
-public:
-  ValueManager(ASTContext& ctx) : Ctx(ctx) {}
-  ~ValueManager();
-  
-  ASTContext& getContext() const { return Ctx; }  
-  APSInt& getValue(const APSInt& X);
-  APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
-  APSInt& getValue(uint64_t X, QualType T,
-                   SourceLocation Loc = SourceLocation());
-};
-} // end anonymous namespace
-
-ValueManager::~ValueManager() {
-  // 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();
-}
-
-APSInt& ValueManager::getValue(const APSInt& X) {
-  llvm::FoldingSetNodeID ID;
-  void* InsertPos;
-  typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
-  
-  X.Profile(ID);
-  FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
-  
-  if (!P) {  
-    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
-    new (P) FoldNodeTy(X);
-    APSIntSet.InsertNode(P, InsertPos);
-  }
-  
-  return *P;
-}
-
-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) {
-  unsigned bits = Ctx.getTypeSize(T, Loc);
-  APSInt V(bits, T->isUnsignedIntegerType());
-  V = X;
-  return getValue(V);
-}
-
-//===----------------------------------------------------------------------===//
-// Expression Values.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-class VISIBILITY_HIDDEN RValue {
-public:
-  enum BaseKind { LValueKind=0x0, NonLValueKind=0x1,
-                  UninitializedKind=0x2, InvalidKind=0x3 };
-  
-  enum { BaseBits = 2, BaseMask = 0x3 };
-    
-private:
-  void* Data;
-  unsigned Kind;
-    
-protected:
-  RValue(const void* d, bool isLValue, unsigned ValKind)
-    : Data(const_cast<void*>(d)),
-      Kind((isLValue ? LValueKind : NonLValueKind) | (ValKind << BaseBits)) {}
-  
-  explicit RValue(BaseKind k)
-    : Data(0), Kind(k) {}
-
-  void* getRawPtr() const {
-    return reinterpret_cast<void*>(Data);
-  }
-  
-public:
-  ~RValue() {};
-
-  RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const;
-  
-  unsigned getRawKind() const { return Kind; }
-  BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
-  unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
-  
-  void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddInteger((unsigned) getRawKind());
-    ID.AddPointer(reinterpret_cast<void*>(Data));
-  }
-  
-  bool operator==(const RValue& RHS) const {
-    return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
-  }
-  
-  static RValue GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
-
-  inline bool isValid() const { return getRawKind() != InvalidKind; }
-  inline bool isInvalid() const { return getRawKind() == InvalidKind; }
-  
-  void print(std::ostream& OS) const;
-  void print() const { print(*llvm::cerr.stream()); }
-
-  // Implement isa<T> support.
-  static inline bool classof(const RValue*) { return true; }
-};
-
-class VISIBILITY_HIDDEN InvalidValue : public RValue {
-public:
-  InvalidValue() : RValue(InvalidKind) {}
-  
-  static inline bool classof(const RValue* V) {
-    return V->getBaseKind() == InvalidKind;
-  }  
-};
-  
-class VISIBILITY_HIDDEN UninitializedValue : public RValue {
-public:
-  UninitializedValue() : RValue(UninitializedKind) {}
-  
-  static inline bool classof(const RValue* V) {
-    return V->getBaseKind() == UninitializedKind;
-  }  
-};
-
-class VISIBILITY_HIDDEN NonLValue : public RValue {
-protected:
-  NonLValue(unsigned SubKind, const void* d) : RValue(d, false, SubKind) {}
-  
-public:
-  void print(std::ostream& Out) const;
-  
-  // Arithmetic operators.
-  NonLValue Add(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue Sub(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue Mul(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue Div(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue Rem(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const;
-  
-  // Equality operators.
-  NonLValue EQ(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue NE(ValueManager& ValMgr, const NonLValue& RHS) const;
-
-  // Utility methods to create NonLValues.
-  static NonLValue GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
-                            SourceLocation Loc = SourceLocation());
-  
-  static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I);
-  
-  static inline NonLValue GetIntTruthValue(ValueManager& ValMgr, bool X) {
-    return GetValue(ValMgr, X ? 1U : 0U, ValMgr.getContext().IntTy);
-  }
-    
-  // Implement isa<T> support.
-  static inline bool classof(const RValue* V) {
-    return V->getBaseKind() >= NonLValueKind;
-  }
-};
-  
-class VISIBILITY_HIDDEN LValue : public RValue {
-protected:
-  LValue(unsigned SubKind, void* D) : RValue(D, true, SubKind) {}
-  
-public:
-  void print(std::ostream& Out) const;
-  
-  // Equality operators.
-  NonLValue EQ(ValueManager& ValMgr, const LValue& RHS) const;
-  NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const;
-  
-  // Implement isa<T> support.
-  static inline bool classof(const RValue* V) {
-    return V->getBaseKind() == LValueKind;
-  }
-};
-    
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// LValues.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-enum { SymbolicLValueKind, LValueDeclKind, NumLValueKind };
-
-class VISIBILITY_HIDDEN SymbolicLValue : public LValue {
-public:
-  SymbolicLValue(unsigned SymID)
-   : LValue(SymbolicLValueKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
-  
-  SymbolID getSymbolID() const {
-    return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
-  }
-  
-  static inline bool classof(const RValue* V) {
-    return V->getSubKind() == SymbolicLValueKind;
-  }  
-};
-  
-class VISIBILITY_HIDDEN LValueDecl : public LValue {
-public:
-  LValueDecl(const ValueDecl* vd) 
-  : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
-  
-  ValueDecl* getDecl() const {
-    return static_cast<ValueDecl*>(getRawPtr());
-  }
-  
-  inline bool operator==(const LValueDecl& R) const {
-    return getDecl() == R.getDecl();
-  }
-
-  inline bool operator!=(const LValueDecl& R) const {
-    return getDecl() != R.getDecl();
-  }
-  
-  // Implement isa<T> support.
-  static inline bool classof(const RValue* V) {
-    return V->getSubKind() == LValueDeclKind;
-  }
-};
-  
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Non-LValues.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-enum { SymbolicNonLValueKind, ConcreteIntKind, ConstrainedIntegerKind,
-       NumNonLValueKind };
-
-class VISIBILITY_HIDDEN SymbolicNonLValue : public NonLValue {
-public:
-  SymbolicNonLValue(unsigned SymID)
-    : NonLValue(SymbolicNonLValueKind,
-                reinterpret_cast<void*>((uintptr_t) SymID)) {}
-  
-  SymbolID getSymbolID() const {
-    return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
-  }
-  
-  static inline bool classof(const RValue* V) {
-    return V->getSubKind() == SymbolicNonLValueKind;
-  }  
-};
-  
-class VISIBILITY_HIDDEN ConcreteInt : public NonLValue {
-public:
-  ConcreteInt(const APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
-  
-  const APSInt& getValue() const {
-    return *static_cast<APSInt*>(getRawPtr());
-  }
-
-  // Arithmetic operators.
-  
-  ConcreteInt Add(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() + V.getValue());
-  }
-  
-  ConcreteInt Sub(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() - V.getValue());
-  }
-  
-  ConcreteInt Mul(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() * V.getValue());
-  }
-  
-  ConcreteInt Div(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() / V.getValue());
-  }
-  
-  ConcreteInt Rem(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() % V.getValue());
-  }
-  
-  ConcreteInt UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
-    assert (U->getType() == U->getSubExpr()->getType());  
-    assert (U->getType()->isIntegerType());  
-    return ValMgr.getValue(-getValue()); 
-  }
-  
-  // Casting.
-  
-  ConcreteInt Cast(ValueManager& ValMgr, Expr* CastExpr) const {
-    assert (CastExpr->getType()->isIntegerType());
-    
-    APSInt X(getValue());  
-    X.extOrTrunc(ValMgr.getContext().getTypeSize(CastExpr->getType(),
-                                                 CastExpr->getLocStart()));
-    return ValMgr.getValue(X);
-  }
-  
-  // Equality operators.
-
-  ConcreteInt EQ(ValueManager& ValMgr, const ConcreteInt& V) const {
-    const APSInt& Val = getValue();    
-    return ValMgr.getValue(Val == V.getValue() ? 1U : 0U,
-                           Val.getBitWidth(), Val.isUnsigned());
-  }
-  
-  ConcreteInt NE(ValueManager& ValMgr, const ConcreteInt& V) const {
-    const APSInt& Val = getValue();    
-    return ValMgr.getValue(Val != V.getValue() ? 1U : 0U,
-                           Val.getBitWidth(), Val.isUnsigned());
-  }
-
-  // Implement isa<T> support.
-  static inline bool classof(const RValue* V) {
-    return V->getSubKind() == ConcreteIntKind;
-  }
-};
-  
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Transfer function dispatch for Non-LValues.
-//===----------------------------------------------------------------------===//
-
-RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
-  switch (getSubKind()) {
-    case ConcreteIntKind:
-      return cast<ConcreteInt>(this)->Cast(ValMgr, CastExpr);
-    default:
-      return InvalidValue();
-  }
-}
-
-NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
-  switch (getSubKind()) {
-    case ConcreteIntKind:
-      return cast<ConcreteInt>(this)->UnaryMinus(ValMgr, U);
-    default:
-      return cast<NonLValue>(InvalidValue());
-  }
-}
-
-#define NONLVALUE_DISPATCH_CASE(k1,k2,Op)\
-case (k1##Kind*NumNonLValueKind+k2##Kind):\
-  return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
-
-#define NONLVALUE_DISPATCH(Op)\
-switch (getSubKind()*NumNonLValueKind+RHS.getSubKind()){\
-  NONLVALUE_DISPATCH_CASE(ConcreteInt,ConcreteInt,Op)\
-  default:\
-    if (getBaseKind() == UninitializedKind ||\
-        RHS.getBaseKind() == UninitializedKind)\
-      return cast<NonLValue>(UninitializedValue());\
-    assert (!isValid() || !RHS.isValid() && "Missing case.");\
-    break;\
-}\
-return cast<NonLValue>(InvalidValue());
-
-NonLValue NonLValue::Add(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Add)
-}
-
-NonLValue NonLValue::Sub(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Sub)
-}
-
-NonLValue NonLValue::Mul(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Mul)
-}
-
-NonLValue NonLValue::Div(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Div)
-}
-
-NonLValue NonLValue::Rem(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Rem)
-}
-
-NonLValue NonLValue::EQ(ValueManager& ValMgr, const NonLValue& RHS) const {  
-  NONLVALUE_DISPATCH(EQ)
-}
-
-NonLValue NonLValue::NE(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(NE)
-}
-
-#undef NONLVALUE_DISPATCH_CASE
-#undef NONLVALUE_DISPATCH
-
-//===----------------------------------------------------------------------===//
-// Transfer function dispatch for LValues.
-//===----------------------------------------------------------------------===//
-
-
-NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
-  if (getSubKind() != RHS.getSubKind())
-    return NonLValue::GetIntTruthValue(ValMgr, false);
-  
-  switch (getSubKind()) {
-    default:
-      assert(false && "EQ not implemented for this LValue.");
-      return cast<NonLValue>(InvalidValue());
-      
-    case LValueDeclKind: {
-      bool b = cast<LValueDecl>(*this) == cast<LValueDecl>(RHS);
-      return NonLValue::GetIntTruthValue(ValMgr, b);
-    }
-  }
-}
-
-NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
-  if (getSubKind() != RHS.getSubKind())
-    return NonLValue::GetIntTruthValue(ValMgr, true);
-
-  switch (getSubKind()) {
-    default:
-      assert(false && "EQ not implemented for this LValue.");
-      return cast<NonLValue>(InvalidValue());
-      
-    case LValueDeclKind: {
-      bool b = cast<LValueDecl>(*this) != cast<LValueDecl>(RHS);
-      return NonLValue::GetIntTruthValue(ValMgr, b);
-    }
-  }
-}
-
-
-//===----------------------------------------------------------------------===//
-// Utility methods for constructing Non-LValues.
-//===----------------------------------------------------------------------===//
-
-NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
-                              SourceLocation Loc) {
-
-  return ConcreteInt(ValMgr.getValue(X, T, Loc));
-}
-
-NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
-  return ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
-                                       I->getType()->isUnsignedIntegerType())));
-}
-
-RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
-  QualType T = D->getType();
-  
-  if (T->isPointerType() || T->isReferenceType())
-    return SymbolicLValue(SymMgr.getSymbol(D));
-  else
-    return SymbolicNonLValue(SymMgr.getSymbol(D));
-}
-
-//===----------------------------------------------------------------------===//
-// Pretty-Printing.
-//===----------------------------------------------------------------------===//
-
-void RValue::print(std::ostream& Out) const {
-  switch (getBaseKind()) {
-    case InvalidKind:
-      Out << "Invalid";
-      break;
-      
-    case NonLValueKind:
-      cast<NonLValue>(this)->print(Out);
-      break;
-
-    case LValueKind:
-      cast<LValue>(this)->print(Out);
-      break;
-      
-    case UninitializedKind:
-      Out << "Uninitialized";
-      break;
-      
-    default:
-      assert (false && "Invalid RValue.");
-  }
-}
-
-void NonLValue::print(std::ostream& Out) const {
-  switch (getSubKind()) {  
-    case ConcreteIntKind:
-      Out << cast<ConcreteInt>(this)->getValue().toString();
-      break;
-      
-    case SymbolicNonLValueKind:
-      Out << '$' << cast<SymbolicNonLValue>(this)->getSymbolID();
-      break;
-      
-    default:
-      assert (false && "Pretty-printed not implemented for this NonLValue.");
-      break;
-  }
-}
-
-void LValue::print(std::ostream& Out) const {
-  switch (getSubKind()) {  
-    case SymbolicLValueKind:
-      Out << '$' << cast<SymbolicLValue>(this)->getSymbolID();
-      break;
-      
-    case LValueDeclKind:
-      Out << '&' 
-          << cast<LValueDecl>(this)->getDecl()->getIdentifier()->getName();
-      break;
-      
-    default:
-      assert (false && "Pretty-printed not implemented for this LValue.");
-      break;
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// ValueMapTy - A ImmutableMap type Stmt*/Decl*/Symbols to RValues.
-//===----------------------------------------------------------------------===//
-
-typedef llvm::ImmutableMap<ValueKey,RValue> ValueMapTy;
-
-namespace clang {
-  template<>
-  struct VISIBILITY_HIDDEN GRTrait<ValueMapTy> {
-    static inline void* toPtr(ValueMapTy M) {
-      return reinterpret_cast<void*>(M.getRoot());
-    }  
-    static inline ValueMapTy toState(void* P) {
-      return ValueMapTy(static_cast<ValueMapTy::TreeTy*>(P));
-    }
-  };
-}
-
-typedef ValueMapTy StateTy;
-
-//===----------------------------------------------------------------------===//
 // The Checker.
 //
 //  FIXME: This checker logic should be eventually broken into two components.
@@ -780,7 +63,7 @@
 class VISIBILITY_HIDDEN GRConstants {
     
 public:
-  typedef ValueMapTy StateTy;
+  typedef ValueState StateTy;
   typedef GRStmtNodeBuilder<GRConstants> StmtNodeBuilder;
   typedef GRBranchNodeBuilder<GRConstants> BranchNodeBuilder;
   typedef ExplodedGraph<GRConstants> GraphTy;
@@ -822,7 +105,7 @@
   StmtNodeBuilder* Builder;
   
   /// StateMgr - Object that manages the data for all created states.
-  ValueMapTy::Factory StateMgr;
+  StateTy::Factory StateMgr;
   
   /// ValueMgr - Object that manages the data for all created RValues.
   ValueManager ValMgr;
@@ -1493,13 +776,13 @@
 // "Assume" logic.
 //===----------------------------------------------------------------------===//
 
-StateTy GRConstants::Assume(StateTy St, LValue Cond, bool Assumption, 
-                            bool& isFeasible) {    
+GRConstants::StateTy GRConstants::Assume(StateTy St, LValue Cond, bool Assumption, 
+                                         bool& isFeasible) {    
   return St;
 }
 
-StateTy GRConstants::Assume(StateTy St, NonLValue Cond, bool Assumption, 
-                            bool& isFeasible) {
+GRConstants::StateTy GRConstants::Assume(StateTy St, NonLValue Cond, bool Assumption, 
+                                         bool& isFeasible) {
   
   switch (Cond.getSubKind()) {
     default:

Added: cfe/trunk/Analysis/RValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/RValues.cpp?rev=46618&view=auto

==============================================================================
--- cfe/trunk/Analysis/RValues.cpp (added)
+++ cfe/trunk/Analysis/RValues.cpp Thu Jan 31 13:34:24 2008
@@ -0,0 +1,272 @@
+//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines RValue, LValue, and NonLValue, classes that represent
+//  abstract r-values for use with path-sensitive value tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RValues.h"
+
+using namespace clang;
+using llvm::dyn_cast;
+using llvm::cast;
+using llvm::APSInt;
+
+//===----------------------------------------------------------------------===//
+// SymbolManager.
+//===----------------------------------------------------------------------===//
+
+SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
+  SymbolID& X = DataToSymbol[D];
+  
+  if (!X.isInitialized()) {
+    X = SymbolToData.size();
+    SymbolToData.push_back(D);
+  }
+  
+  return X;
+}
+
+SymbolManager::SymbolManager() {}
+SymbolManager::~SymbolManager() {}
+
+//===----------------------------------------------------------------------===//
+// ValueManager.
+//===----------------------------------------------------------------------===//
+
+ValueManager::~ValueManager() {
+  // 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();
+}
+
+APSInt& ValueManager::getValue(const APSInt& X) {
+  llvm::FoldingSetNodeID ID;
+  void* InsertPos;
+  typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
+  
+  X.Profile(ID);
+  FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
+  
+  if (!P) {  
+    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    new (P) FoldNodeTy(X);
+    APSIntSet.InsertNode(P, InsertPos);
+  }
+  
+  return *P;
+}
+
+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) {
+  unsigned bits = Ctx.getTypeSize(T, Loc);
+  APSInt V(bits, T->isUnsignedIntegerType());
+  V = X;
+  return getValue(V);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Transfer function dispatch for Non-LValues.
+//===----------------------------------------------------------------------===//
+
+RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
+  switch (getSubKind()) {
+    case ConcreteIntKind:
+      return cast<ConcreteInt>(this)->Cast(ValMgr, CastExpr);
+    default:
+      return InvalidValue();
+  }
+}
+
+NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
+  switch (getSubKind()) {
+    case ConcreteIntKind:
+      return cast<ConcreteInt>(this)->UnaryMinus(ValMgr, U);
+    default:
+      return cast<NonLValue>(InvalidValue());
+  }
+}
+
+#define NONLVALUE_DISPATCH_CASE(k1,k2,Op)\
+case (k1##Kind*NumNonLValueKind+k2##Kind):\
+return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
+
+#define NONLVALUE_DISPATCH(Op)\
+switch (getSubKind()*NumNonLValueKind+RHS.getSubKind()){\
+NONLVALUE_DISPATCH_CASE(ConcreteInt,ConcreteInt,Op)\
+default:\
+if (getBaseKind() == UninitializedKind ||\
+RHS.getBaseKind() == UninitializedKind)\
+return cast<NonLValue>(UninitializedValue());\
+assert (!isValid() || !RHS.isValid() && "Missing case.");\
+break;\
+}\
+return cast<NonLValue>(InvalidValue());
+
+NonLValue NonLValue::Add(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Add)
+}
+
+NonLValue NonLValue::Sub(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Sub)
+}
+
+NonLValue NonLValue::Mul(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Mul)
+}
+
+NonLValue NonLValue::Div(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Div)
+}
+
+NonLValue NonLValue::Rem(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Rem)
+}
+
+NonLValue NonLValue::EQ(ValueManager& ValMgr, const NonLValue& RHS) const {  
+  NONLVALUE_DISPATCH(EQ)
+}
+
+NonLValue NonLValue::NE(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(NE)
+}
+
+#undef NONLVALUE_DISPATCH_CASE
+#undef NONLVALUE_DISPATCH
+
+//===----------------------------------------------------------------------===//
+// Transfer function dispatch for LValues.
+//===----------------------------------------------------------------------===//
+
+
+NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
+  if (getSubKind() != RHS.getSubKind())
+    return NonLValue::GetIntTruthValue(ValMgr, false);
+  
+  switch (getSubKind()) {
+    default:
+      assert(false && "EQ not implemented for this LValue.");
+      return cast<NonLValue>(InvalidValue());
+      
+    case LValueDeclKind: {
+      bool b = cast<LValueDecl>(*this) == cast<LValueDecl>(RHS);
+      return NonLValue::GetIntTruthValue(ValMgr, b);
+    }
+  }
+}
+
+NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
+  if (getSubKind() != RHS.getSubKind())
+    return NonLValue::GetIntTruthValue(ValMgr, true);
+  
+  switch (getSubKind()) {
+    default:
+      assert(false && "EQ not implemented for this LValue.");
+      return cast<NonLValue>(InvalidValue());
+      
+    case LValueDeclKind: {
+      bool b = cast<LValueDecl>(*this) != cast<LValueDecl>(RHS);
+      return NonLValue::GetIntTruthValue(ValMgr, b);
+    }
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Utility methods for constructing Non-LValues.
+//===----------------------------------------------------------------------===//
+
+NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
+                              SourceLocation Loc) {
+  
+  return ConcreteInt(ValMgr.getValue(X, T, Loc));
+}
+
+NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
+  return ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
+                                            I->getType()->isUnsignedIntegerType())));
+}
+
+RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
+  QualType T = D->getType();
+  
+  if (T->isPointerType() || T->isReferenceType())
+    return SymbolicLValue(SymMgr.getSymbol(D));
+  else
+    return SymbolicNonLValue(SymMgr.getSymbol(D));
+}
+
+//===----------------------------------------------------------------------===//
+// Pretty-Printing.
+//===----------------------------------------------------------------------===//
+
+void RValue::print(std::ostream& Out) const {
+  switch (getBaseKind()) {
+    case InvalidKind:
+      Out << "Invalid";
+      break;
+      
+    case NonLValueKind:
+      cast<NonLValue>(this)->print(Out);
+      break;
+      
+    case LValueKind:
+      cast<LValue>(this)->print(Out);
+      break;
+      
+    case UninitializedKind:
+      Out << "Uninitialized";
+      break;
+      
+    default:
+      assert (false && "Invalid RValue.");
+  }
+}
+
+void NonLValue::print(std::ostream& Out) const {
+  switch (getSubKind()) {  
+    case ConcreteIntKind:
+      Out << cast<ConcreteInt>(this)->getValue().toString();
+      break;
+      
+    case SymbolicNonLValueKind:
+      Out << '$' << cast<SymbolicNonLValue>(this)->getSymbolID();
+      break;
+      
+    default:
+      assert (false && "Pretty-printed not implemented for this NonLValue.");
+      break;
+  }
+}
+
+void LValue::print(std::ostream& Out) const {
+  switch (getSubKind()) {  
+    case SymbolicLValueKind:
+      Out << '$' << cast<SymbolicLValue>(this)->getSymbolID();
+      break;
+      
+    case LValueDeclKind:
+      Out << '&' 
+      << cast<LValueDecl>(this)->getDecl()->getIdentifier()->getName();
+      break;
+      
+    default:
+      assert (false && "Pretty-printed not implemented for this LValue.");
+      break;
+  }
+}

Added: cfe/trunk/Analysis/RValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/RValues.h?rev=46618&view=auto

==============================================================================
--- cfe/trunk/Analysis/RValues.h (added)
+++ cfe/trunk/Analysis/RValues.h Thu Jan 31 13:34:24 2008
@@ -0,0 +1,393 @@
+//== RValues.h - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines RValue, LValue, and NonLValue, classes that represent
+//  abstract r-values for use with path-sensitive value tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
+#define LLVM_CLANG_ANALYSIS_RVALUE_H
+
+// FIXME: reduce the number of includes.
+
+#include "clang/Analysis/PathSensitive/GREngine.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
+
+#include <functional>
+
+//==------------------------------------------------------------------------==//
+//  RValue "management" data structures.
+//==------------------------------------------------------------------------==// 
+
+namespace clang {
+
+class SymbolID {
+  unsigned Data;
+public:
+  SymbolID() : Data(~0) {}
+  SymbolID(unsigned x) : Data(x) {}
+  
+  bool isInitialized() const { return Data != (unsigned) ~0; }
+  operator unsigned() const { assert (isInitialized()); return Data; }
+};
+  
+class SymbolData {
+  uintptr_t Data;
+public:
+  enum Kind { ParmKind = 0x0, Mask = 0x3 };
+  
+  SymbolData(ParmVarDecl* D)
+  : Data(reinterpret_cast<uintptr_t>(D) | ParmKind) {}
+  
+  inline Kind getKind() const { return (Kind) (Data & Mask); }
+  inline void* getPtr() const { return reinterpret_cast<void*>(Data & ~Mask); }  
+  inline bool operator==(const SymbolData& R) const { return Data == R.Data; }  
+};
+
+class SymbolManager {
+  std::vector<SymbolData> SymbolToData;
+  
+  typedef llvm::DenseMap<void*,SymbolID> MapTy;
+  MapTy DataToSymbol;
+  
+public:
+  SymbolManager();
+  ~SymbolManager();
+  
+  SymbolData getSymbolData(SymbolID id) const {
+    assert (id < SymbolToData.size());
+    return SymbolToData[id];
+  }
+  
+  SymbolID getSymbol(ParmVarDecl* D);
+};
+
+class ValueManager {
+  typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
+          APSIntSetTy;
+  
+  ASTContext& Ctx;
+  APSIntSetTy APSIntSet;
+  llvm::BumpPtrAllocator BPAlloc;
+  
+public:
+  ValueManager(ASTContext& ctx) : Ctx(ctx) {}
+  ~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());
+};
+
+//==------------------------------------------------------------------------==//
+//  Base RValue types.
+//==------------------------------------------------------------------------==// 
+
+class RValue {
+public:
+  enum BaseKind { LValueKind=0x0,
+                  NonLValueKind=0x1,
+                  UninitializedKind=0x2,
+                  InvalidKind=0x3 };
+  
+  enum { BaseBits = 2, 
+         BaseMask = 0x3 };
+  
+private:
+  void* Data;
+  unsigned Kind;
+  
+protected:
+  RValue(const void* d, bool isLValue, unsigned ValKind)
+  : Data(const_cast<void*>(d)),
+    Kind((isLValue ? LValueKind : NonLValueKind) | (ValKind << BaseBits)) {}
+  
+  explicit RValue(BaseKind k)
+    : Data(0), Kind(k) {}
+  
+  void* getRawPtr() const {
+    return reinterpret_cast<void*>(Data);
+  }
+  
+public:
+  ~RValue() {};
+  
+  RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const;
+  
+  unsigned getRawKind() const { return Kind; }
+  BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
+  unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
+  
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger((unsigned) getRawKind());
+    ID.AddPointer(reinterpret_cast<void*>(Data));
+  }
+  
+  bool operator==(const RValue& RHS) const {
+    return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
+  }
+  
+  static RValue GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
+  
+  inline bool isValid() const { return getRawKind() != InvalidKind; }
+  inline bool isInvalid() const { return getRawKind() == InvalidKind; }
+  
+  void print(std::ostream& OS) const;
+  void print() const { print(*llvm::cerr.stream()); }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue*) { return true; }
+};
+
+class InvalidValue : public RValue {
+public:
+  InvalidValue() : RValue(InvalidKind) {}
+  
+  static inline bool classof(const RValue* V) {
+    return V->getBaseKind() == InvalidKind;
+  }  
+};
+
+class UninitializedValue : public RValue {
+public:
+  UninitializedValue() : RValue(UninitializedKind) {}
+  
+  static inline bool classof(const RValue* V) {
+    return V->getBaseKind() == UninitializedKind;
+  }  
+};
+
+class NonLValue : public RValue {
+protected:
+  NonLValue(unsigned SubKind, const void* d) : RValue(d, false, SubKind) {}
+  
+public:
+  void print(std::ostream& Out) const;
+  
+  // Arithmetic operators.
+  NonLValue Add(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue Sub(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue Mul(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue Div(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue Rem(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const;
+  
+  // Equality operators.
+  NonLValue EQ(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue NE(ValueManager& ValMgr, const NonLValue& RHS) const;
+  
+  // Utility methods to create NonLValues.
+  static NonLValue GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
+                            SourceLocation Loc = SourceLocation());
+  
+  static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I);
+  
+  static inline NonLValue GetIntTruthValue(ValueManager& ValMgr, bool X) {
+    return GetValue(ValMgr, X ? 1U : 0U, ValMgr.getContext().IntTy);
+  }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue* V) {
+    return V->getBaseKind() >= NonLValueKind;
+  }
+};
+
+class LValue : public RValue {
+protected:
+  LValue(unsigned SubKind, void* D) : RValue(D, true, SubKind) {}
+  
+public:
+  void print(std::ostream& Out) const;
+  
+  // Equality operators.
+  NonLValue EQ(ValueManager& ValMgr, const LValue& RHS) const;
+  NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const;
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue* V) {
+    return V->getBaseKind() == LValueKind;
+  }
+};
+
+//==------------------------------------------------------------------------==//
+//  Subclasses of LValue.
+//==------------------------------------------------------------------------==// 
+  
+enum LValueKind { SymbolicLValueKind, LValueDeclKind, NumLValueKind };
+
+class SymbolicLValue : public LValue {
+public:
+  SymbolicLValue(unsigned SymID)
+  : LValue(SymbolicLValueKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
+  
+  SymbolID getSymbolID() const {
+    return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
+  }
+  
+  static inline bool classof(const RValue* V) {
+    return V->getSubKind() == SymbolicLValueKind;
+  }  
+};
+
+class LValueDecl : public LValue {
+public:
+  LValueDecl(const ValueDecl* vd) 
+  : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
+  
+  ValueDecl* getDecl() const {
+    return static_cast<ValueDecl*>(getRawPtr());
+  }
+  
+  inline bool operator==(const LValueDecl& R) const {
+    return getDecl() == R.getDecl();
+  }
+  
+  inline bool operator!=(const LValueDecl& R) const {
+    return getDecl() != R.getDecl();
+  }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue* V) {
+    return V->getSubKind() == LValueDeclKind;
+  }
+};
+  
+//==------------------------------------------------------------------------==//
+//  Subclasses of NonLValue.
+//==------------------------------------------------------------------------==// 
+
+enum NonLValueKind { SymbolicNonLValueKind, ConcreteIntKind,
+NumNonLValueKind };
+
+class SymbolicNonLValue : public NonLValue {
+public:
+  SymbolicNonLValue(unsigned SymID)
+  : NonLValue(SymbolicNonLValueKind,
+              reinterpret_cast<void*>((uintptr_t) SymID)) {}
+  
+  SymbolID getSymbolID() const {
+    return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
+  }
+  
+  static inline bool classof(const RValue* V) {
+    return V->getSubKind() == SymbolicNonLValueKind;
+  }  
+};
+
+class ConcreteInt : public NonLValue {
+public:
+  ConcreteInt(const llvm::APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
+  
+  const llvm::APSInt& getValue() const {
+    return *static_cast<llvm::APSInt*>(getRawPtr());
+  }
+  
+  // Arithmetic operators.
+  
+  ConcreteInt Add(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() + V.getValue());
+  }
+  
+  ConcreteInt Sub(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() - V.getValue());
+  }
+  
+  ConcreteInt Mul(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() * V.getValue());
+  }
+  
+  ConcreteInt Div(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() / V.getValue());
+  }
+  
+  ConcreteInt Rem(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() % V.getValue());
+  }
+  
+  ConcreteInt UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
+    assert (U->getType() == U->getSubExpr()->getType());  
+    assert (U->getType()->isIntegerType());  
+    return ValMgr.getValue(-getValue()); 
+  }
+  
+  // Casting.
+  
+  ConcreteInt Cast(ValueManager& ValMgr, Expr* CastExpr) const {
+    assert (CastExpr->getType()->isIntegerType());
+    
+    llvm::APSInt X(getValue());  
+    X.extOrTrunc(ValMgr.getContext().getTypeSize(CastExpr->getType(),
+                                                 CastExpr->getLocStart()));
+    return ValMgr.getValue(X);
+  }
+  
+  // Equality operators.
+  
+  ConcreteInt EQ(ValueManager& ValMgr, const ConcreteInt& V) const {
+    const llvm::APSInt& Val = getValue();    
+    return ValMgr.getValue(Val == V.getValue() ? 1U : 0U,
+                           Val.getBitWidth(), Val.isUnsigned());
+  }
+  
+  ConcreteInt NE(ValueManager& ValMgr, const ConcreteInt& V) const {
+    const llvm::APSInt& Val = getValue();    
+    return ValMgr.getValue(Val != V.getValue() ? 1U : 0U,
+                           Val.getBitWidth(), Val.isUnsigned());
+  }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue* V) {
+    return V->getSubKind() == ConcreteIntKind;
+  }
+};
+  
+} // end clang namespace  
+
+//==------------------------------------------------------------------------==//
+// Casting machinery to get cast<> and dyn_cast<> working with SymbolData.
+//==------------------------------------------------------------------------==//
+
+namespace llvm {
+
+template<> inline bool
+isa<clang::ParmVarDecl,clang::SymbolData>(const clang::SymbolData& V) {
+  return V.getKind() == clang::SymbolData::ParmKind;
+}
+
+template<> struct cast_retty_impl<clang::ParmVarDecl,clang::SymbolData> {
+  typedef const clang::ParmVarDecl* ret_type;
+};
+
+template<> struct simplify_type<clang::SymbolData> {
+  typedef void* SimpleType;
+  static inline SimpleType getSimplifiedValue(const clang::SymbolData &V) {
+    return V.getPtr();
+  }
+};
+
+} // end llvm namespace
+
+#endif

Added: cfe/trunk/Analysis/ValueState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ValueState.h?rev=46618&view=auto

==============================================================================
--- cfe/trunk/Analysis/ValueState.h (added)
+++ cfe/trunk/Analysis/ValueState.h Thu Jan 31 13:34:24 2008
@@ -0,0 +1,162 @@
+//== ValueState.h - Path-Sens. "State" for tracking valuues -----*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines SymbolID, ValueKey, and ValueState.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
+#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
+
+// FIXME: Reduce the number of includes.
+
+#include "RValues.h"
+
+#include "clang/Analysis/PathSensitive/GREngine.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
+
+#include <functional>
+
+namespace clang {  
+
+/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
+///  Stmt*.  Use cast<> or dyn_cast<> to get actual pointer type
+class ValueKey {
+  uintptr_t Raw;  
+  void operator=(const ValueKey& RHS); // Do not implement.
+  
+public:
+  enum  Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, // L-Value Bindings.
+               IsSymbol=0x3, // Symbol Bindings.
+               Mask=0x3 };
+  
+  inline Kind getKind() const {
+    return (Kind) (Raw & Mask);
+  }
+  
+  inline void* getPtr() const { 
+    assert (getKind() != IsSymbol);
+    return reinterpret_cast<void*>(Raw & ~Mask);
+  }
+  
+  inline SymbolID getSymbolID() const {
+    assert (getKind() == IsSymbol);
+    return Raw >> 2;
+  }
+  
+  ValueKey(const ValueDecl* VD)
+  : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {
+    assert(VD && "ValueDecl cannot be NULL.");
+  }
+  
+  ValueKey(Stmt* S, bool isBlkExpr = false) 
+  : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
+    assert(S && "Tracked statement cannot be NULL.");
+  }
+  
+  ValueKey(SymbolID V)
+  : Raw((V << 2) | IsSymbol) {}  
+  
+  bool isSymbol()  const { return getKind() == IsSymbol; }
+  bool isSubExpr() const { return getKind() == IsSubExpr; }
+  bool isBlkExpr() const { return getKind() == IsBlkExpr; }
+  bool isDecl()    const { return getKind() == IsDecl; }
+  bool isStmt()    const { return getKind() <= IsBlkExpr; }
+  
+  inline void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger(isSymbol() ? 1 : 0);
+    
+    if (isSymbol())
+      ID.AddInteger(getSymbolID());
+    else    
+      ID.AddPointer(getPtr());
+  }
+  
+  inline bool operator==(const ValueKey& X) const {
+    return isSymbol() ? getSymbolID() == X.getSymbolID()
+    : getPtr() == X.getPtr();
+  }
+  
+  inline bool operator!=(const ValueKey& X) const {
+    return !operator==(X);
+  }
+  
+  inline bool operator<(const ValueKey& X) const { 
+    if (isSymbol())
+      return X.isSymbol() ? getSymbolID() < X.getSymbolID() : false;
+    
+    return getPtr() < X.getPtr();
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// ValueState - An ImmutableMap type Stmt*/Decl*/Symbols to RValues.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::ImmutableMap<ValueKey,RValue> ValueState;
+
+template<>
+struct GRTrait<ValueState> {
+  static inline void* toPtr(ValueState M) {
+    return reinterpret_cast<void*>(M.getRoot());
+  }  
+  static inline ValueState toState(void* P) {
+    return ValueState(static_cast<ValueState::TreeTy*>(P));
+  }
+};
+  
+} // end clang namespace
+
+//==------------------------------------------------------------------------==//
+// Casting machinery to get cast<> and dyn_cast<> working with ValueKey.
+//==------------------------------------------------------------------------==//
+
+namespace llvm {
+  
+  template<> inline bool
+  isa<clang::ValueDecl,clang::ValueKey>(const clang::ValueKey& V) {
+    return V.getKind() == clang::ValueKey::IsDecl;
+  }
+  
+  template<> inline bool
+  isa<clang::Stmt,clang::ValueKey>(const clang::ValueKey& V) {
+    return ((unsigned) V.getKind()) < clang::ValueKey::IsDecl;
+  }
+  
+  template<> struct cast_retty_impl<clang::ValueDecl,clang::ValueKey> {
+    typedef const clang::ValueDecl* ret_type;
+  };
+  
+  template<> struct cast_retty_impl<clang::Stmt,clang::ValueKey> {
+    typedef const clang::Stmt* ret_type;
+  };
+  
+  template<> struct simplify_type<clang::ValueKey> {
+    typedef void* SimpleType;
+    static inline SimpleType getSimplifiedValue(const clang::ValueKey &V) {
+      return V.getPtr();
+    }
+  };
+} // end llvm namespace
+
+#endif





More information about the cfe-commits mailing list