forked from OSchip/llvm-project
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:
parent
a8dc3e6b52
commit
b6056cfea4
|
@ -48,7 +48,15 @@ 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;
|
||||
|
@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -296,6 +368,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) {
|
||||
return V->getBaseKind() >= NonLValueKind;
|
||||
|
@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue