diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-01-29 17:27:31 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-01-29 17:27:31 +0000 |
commit | 68fd257ada1ed5a20728241962a21826ae36ef63 (patch) | |
tree | 58c5f598ce9709841d7a06a115292ea17ce09468 /Analysis/GRConstants.cpp | |
parent | 5a1deb8d9c0722beae28d693fa137bbb942bd11f (diff) |
Added "SymbolManager", which manages the set of symbolic values used
for analyzing a function.
The initial state for GRConstants now assigns symbolic values to parameters.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46517 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Analysis/GRConstants.cpp')
-rw-r--r-- | Analysis/GRConstants.cpp | 93 |
1 files changed, 89 insertions, 4 deletions
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index 46f828bac2..da1a0adfa4 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -48,8 +48,16 @@ using llvm::APSInt; //===----------------------------------------------------------------------===// namespace { -typedef unsigned SymbolID; +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. @@ -70,7 +78,7 @@ public: inline SymbolID getSymbolID() const { assert (getKind() == IsSymbol); - return (SymbolID) (Raw >> 2); + return Raw >> 2; } ValueKey(const ValueDecl* VD) @@ -141,6 +149,70 @@ namespace llvm { }; } // 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. //===----------------------------------------------------------------------===// @@ -295,6 +367,8 @@ public: static NonLValue GetValue(ValueManager& ValMgr, const APSInt& V); static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I); + + static NonLValue GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D); // Implement isa<T> support. static inline bool classof(const RValue* V) { @@ -479,6 +553,10 @@ NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) { I->getType()->isUnsignedIntegerType()))); } +NonLValue NonLValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) { + return SymbolicNonLValue(SymMgr.getSymbol(D)); +} + //===----------------------------------------------------------------------===// // Pretty-Printing. //===----------------------------------------------------------------------===// @@ -492,7 +570,7 @@ void RValue::print(std::ostream& Out) const { case NonLValueKind: cast<NonLValue>(this)->print(Out); break; - + case LValueKind: assert (false && "FIXME: LValue printing not implemented."); break; @@ -512,6 +590,10 @@ void NonLValue::print(std::ostream& Out) const { Out << cast<ConcreteInt>(this)->getValue().toString(); break; + case SymbolicNonLValueKind: + Out << "sym-" << cast<SymbolicNonLValue>(this)->getSymbolID(); + break; + default: assert (false && "Pretty-printed not implemented for this NonLValue."); break; @@ -591,6 +673,9 @@ protected: /// ValueMgr - Object that manages the data for all created RValues. ValueManager ValMgr; + /// SymMgr - Object that manages the symbol information. + SymbolManager SymMgr; + /// StmtEntryNode - The immediate predecessor node. NodeTy* StmtEntryNode; @@ -631,7 +716,7 @@ public: continue; // FIXME: Set these values to a symbol, not Uninitialized. - St = SetValue(St, LValueDecl(*I), UninitializedValue()); + St = SetValue(St, LValueDecl(*I), NonLValue::GetSymbolValue(SymMgr, *I)); } return St; |