From: Ted Kremenek Date: Tue, 5 Feb 2008 21:32:43 +0000 (+0000) Subject: Added "SymIntConstraint", a utility class to represent intermediate values for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1fbdb020311efa1b5b7de2758985287418018fac;p=clang 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 --- 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 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(); + 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 //==------------------------------------------------------------------------==// -// 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(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 SymbolToData; @@ -88,15 +121,22 @@ public: SymbolID getSymbol(ParmVarDecl* D); }; + class ValueManager { typedef llvm::FoldingSet > APSIntSetTy; + typedef llvm::FoldingSet + 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); }; //==------------------------------------------------------------------------==//