diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-02-05 21:32:43 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-02-05 21:32:43 +0000 |
commit | 1fbdb020311efa1b5b7de2758985287418018fac (patch) | |
tree | 8e0c058b79b5c1796d94f888d69e2e99a62825d0 | |
parent | 64515f31850024a263e8f55f81e9ea4b39925cfa (diff) |
Added "SymIntConstraint", a utility class to represent intermediate values for
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
-rw-r--r-- | Analysis/RValues.cpp | 30 | ||||
-rw-r--r-- | Analysis/RValues.h | 57 |
2 files changed, 76 insertions, 11 deletions
diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp index 2854ee6414..8861f576f3 100644 --- a/Analysis/RValues.cpp +++ b/Analysis/RValues.cpp @@ -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. //===----------------------------------------------------------------------===// diff --git a/Analysis/RValues.h b/Analysis/RValues.h index c69a70a52d..6980a9bba4 100644 --- a/Analysis/RValues.h +++ b/Analysis/RValues.h @@ -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); }; //==------------------------------------------------------------------------==// |