Add CompoundVal and CompoundValData for representing the value of InitListExpr.

llvm-svn: 58418
This commit is contained in:
Zhongxing Xu 2008-10-30 04:58:00 +00:00
parent 51ac923ca3
commit ef5f25a05f
4 changed files with 92 additions and 4 deletions

View File

@ -28,7 +28,24 @@ namespace llvm {
namespace clang {
class SVal;
class CompoundValData : public llvm::FoldingSetNode {
QualType T;
unsigned NumVals;
SVal* Vals;
public:
CompoundValData(QualType t, const SVal* vals, unsigned n,
llvm::BumpPtrAllocator& A);
static void Profile(llvm::FoldingSetNodeID& ID, QualType T, unsigned N,
const SVal* Vals);
void Profile(llvm::FoldingSetNodeID& ID) {
Profile(ID, T, NumVals, Vals);
}
};
class BasicValueFactory {
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
APSIntSetTy;
@ -45,6 +62,8 @@ class BasicValueFactory {
void* PersistentSVals;
void* PersistentSValPairs;
llvm::FoldingSet<CompoundValData> CompoundValDataSet;
public:
BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
: Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0) {}
@ -68,6 +87,9 @@ public:
const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
const llvm::APSInt& V);
const CompoundValData* getCompoundValData(QualType T, const SVal* Vals,
unsigned NumVals);
const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1,
const llvm::APSInt& V2);

View File

@ -45,6 +45,7 @@ protected:
: Data(D), Kind(k) {}
public:
SVal() : Data(0), Kind(0) {}
~SVal() {};
/// BufferTy - A temporary buffer to hold a set of SVals.
@ -58,7 +59,7 @@ public:
ID.AddInteger((unsigned) getRawKind());
ID.AddPointer(reinterpret_cast<void*>(Data));
}
inline bool operator==(const SVal& R) const {
return getRawKind() == R.getRawKind() && Data == R.Data;
}
@ -168,7 +169,10 @@ public:
static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
static NonLoc MakeCompoundVal(QualType T, SVal* Vals, unsigned NumSVals,
BasicValueFactory& BasicVals);
// Implement isa<T> support.
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind;
@ -210,7 +214,7 @@ public:
namespace nonloc {
enum Kind { ConcreteIntKind, SymbolValKind, SymIntConstraintValKind,
LocAsIntegerKind };
LocAsIntegerKind, CompoundValKind };
class SymbolVal : public NonLoc {
public:
@ -313,6 +317,25 @@ public:
return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
}
};
class CompoundVal : public NonLoc {
friend class NonLoc;
CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
public:
const CompoundValData* getValue() {
return static_cast<CompoundValData*>(Data);
}
static bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
}
static bool classof(const NonLoc* V) {
return V->getSubKind() == CompoundValKind;
}
};
} // end namespace clang::nonloc

View File

@ -18,6 +18,26 @@
using namespace clang;
CompoundValData::CompoundValData(QualType t, const SVal* vals, unsigned n,
llvm::BumpPtrAllocator& A)
: T(t), NumVals(n) {
Vals = (SVal*) A.Allocate<SVal>(n);
new (Vals) SVal[n];
for (unsigned i = 0; i < n; ++i)
Vals[i] = vals[i];
}
void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
unsigned N, const SVal* Vals) {
T.Profile(ID);
ID.AddInteger(N);
for (unsigned i = 0; i < N; ++i)
Vals[i].Profile(ID);
}
typedef std::pair<SVal, uintptr_t> SValData;
typedef std::pair<SVal, SVal> SValPair;
@ -106,6 +126,24 @@ BasicValueFactory::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
return *C;
}
const CompoundValData*
BasicValueFactory::getCompoundValData(QualType T, const SVal* Vals,
unsigned NumVals) {
llvm::FoldingSetNodeID ID;
CompoundValData::Profile(ID, T, NumVals, Vals);
void* InsertPos;
CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
if (!D) {
D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
new (D) CompoundValData(T, Vals, NumVals, BPAlloc);
CompoundValDataSet.InsertNode(D, InsertPos);
}
return D;
}
const llvm::APSInt*
BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1, const llvm::APSInt& V2) {

View File

@ -245,6 +245,11 @@ NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
}
NonLoc NonLoc::MakeCompoundVal(QualType T, SVal* Vals, unsigned NumSVals,
BasicValueFactory& BasicVals) {
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals, NumSVals));
}
SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
QualType T = D->getType();