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.

llvm-svn: 46517
This commit is contained in:
Ted Kremenek 2008-01-29 17:27:31 +00:00
parent a8dc3e6b52
commit b6056cfea4
1 changed files with 89 additions and 4 deletions

View File

@ -48,8 +48,16 @@ using llvm::APSInt;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
namespace { 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 { class VISIBILITY_HIDDEN ValueKey {
uintptr_t Raw; uintptr_t Raw;
void operator=(const ValueKey& RHS); // Do not implement. void operator=(const ValueKey& RHS); // Do not implement.
@ -70,7 +78,7 @@ public:
inline SymbolID getSymbolID() const { inline SymbolID getSymbolID() const {
assert (getKind() == IsSymbol); assert (getKind() == IsSymbol);
return (SymbolID) (Raw >> 2); return Raw >> 2;
} }
ValueKey(const ValueDecl* VD) ValueKey(const ValueDecl* VD)
@ -141,6 +149,70 @@ namespace llvm {
}; };
} // end llvm namespace } // 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. // ValueManager.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -295,6 +367,8 @@ public:
static NonLValue GetValue(ValueManager& ValMgr, const APSInt& V); static NonLValue GetValue(ValueManager& ValMgr, const APSInt& V);
static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I); static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I);
static NonLValue GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
// Implement isa<T> support. // Implement isa<T> support.
static inline bool classof(const RValue* V) { static inline bool classof(const RValue* V) {
@ -479,6 +553,10 @@ NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
I->getType()->isUnsignedIntegerType()))); I->getType()->isUnsignedIntegerType())));
} }
NonLValue NonLValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
return SymbolicNonLValue(SymMgr.getSymbol(D));
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Pretty-Printing. // Pretty-Printing.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -492,7 +570,7 @@ void RValue::print(std::ostream& Out) const {
case NonLValueKind: case NonLValueKind:
cast<NonLValue>(this)->print(Out); cast<NonLValue>(this)->print(Out);
break; break;
case LValueKind: case LValueKind:
assert (false && "FIXME: LValue printing not implemented."); assert (false && "FIXME: LValue printing not implemented.");
break; break;
@ -512,6 +590,10 @@ void NonLValue::print(std::ostream& Out) const {
Out << cast<ConcreteInt>(this)->getValue().toString(); Out << cast<ConcreteInt>(this)->getValue().toString();
break; break;
case SymbolicNonLValueKind:
Out << "sym-" << cast<SymbolicNonLValue>(this)->getSymbolID();
break;
default: default:
assert (false && "Pretty-printed not implemented for this NonLValue."); assert (false && "Pretty-printed not implemented for this NonLValue.");
break; break;
@ -591,6 +673,9 @@ protected:
/// ValueMgr - Object that manages the data for all created RValues. /// ValueMgr - Object that manages the data for all created RValues.
ValueManager ValMgr; ValueManager ValMgr;
/// SymMgr - Object that manages the symbol information.
SymbolManager SymMgr;
/// StmtEntryNode - The immediate predecessor node. /// StmtEntryNode - The immediate predecessor node.
NodeTy* StmtEntryNode; NodeTy* StmtEntryNode;
@ -631,7 +716,7 @@ public:
continue; continue;
// FIXME: Set these values to a symbol, not Uninitialized. // 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; return St;