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;
void* PersistentSVals;
void* PersistentSValPairs;
+ llvm::FoldingSet<CompoundValData> CompoundValDataSet;
+
public:
BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
: Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0) {}
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);
: Data(D), Kind(k) {}
public:
+ SVal() : Data(0), Kind(0) {}
~SVal() {};
/// BufferTy - A temporary buffer to hold a set of SVals.
ID.AddInteger((unsigned) getRawKind());
ID.AddPointer(reinterpret_cast<void*>(Data));
}
-
+
inline bool operator==(const SVal& R) const {
return getRawKind() == R.getRawKind() && Data == R.Data;
}
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;
namespace nonloc {
enum Kind { ConcreteIntKind, SymbolValKind, SymIntConstraintValKind,
- LocAsIntegerKind };
+ LocAsIntegerKind, CompoundValKind };
class SymbolVal : public NonLoc {
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
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;
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) {
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();