CompoundVal now uses an ImmutableList<SVal> to store its set of SVals. This change was motivated by the need to allow state-splitting in GRExprEngine::VisitInitListExpr. As a side-benefit, we no longer need to perform any copies of SVals when creating a CompoundSVal, and the profiling of CompoundSVal is now constant time.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58437 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2008-10-30 17:44:46 +00:00
Родитель 56f6e3f3d2
Коммит 632e8b8497
4 изменённых файлов: 44 добавлений и 51 удалений

Просмотреть файл

@ -17,33 +17,26 @@
#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H #define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
#include "clang/Analysis/PathSensitive/SymbolManager.h" #include "clang/Analysis/PathSensitive/SymbolManager.h"
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/APSInt.h" #include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ImmutableList.h"
namespace llvm {
class BumpPtrAllocator;
}
namespace clang { namespace clang {
class SVal;
class CompoundValData : public llvm::FoldingSetNode { class CompoundValData : public llvm::FoldingSetNode {
QualType T; QualType T;
unsigned NumVals; llvm::ImmutableList<SVal> L;
SVal* Vals;
public: public:
CompoundValData(QualType t, const SVal* vals, unsigned n, CompoundValData(QualType t, llvm::ImmutableList<SVal> l)
llvm::BumpPtrAllocator& A); : T(t), L(l) {}
static void Profile(llvm::FoldingSetNodeID& ID, QualType T, unsigned N, static void Profile(llvm::FoldingSetNodeID& ID, QualType T,
const SVal* Vals); llvm::ImmutableList<SVal> L);
void Profile(llvm::FoldingSetNodeID& ID) { void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); }
Profile(ID, T, NumVals, Vals);
}
}; };
class BasicValueFactory { class BasicValueFactory {
@ -62,11 +55,13 @@ class BasicValueFactory {
void* PersistentSVals; void* PersistentSVals;
void* PersistentSValPairs; void* PersistentSValPairs;
llvm::FoldingSet<CompoundValData> CompoundValDataSet; llvm::ImmutableList<SVal>::Factory SValListFactory;
llvm::FoldingSet<CompoundValData> CompoundValDataSet;
public: public:
BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc) BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
: Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0) {} : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0),
SValListFactory(Alloc) {}
~BasicValueFactory(); ~BasicValueFactory();
@ -87,8 +82,16 @@ public:
const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op, const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
const llvm::APSInt& V); const llvm::APSInt& V);
const CompoundValData* getCompoundValData(QualType T, const SVal* Vals, const CompoundValData* getCompoundValData(QualType T,
unsigned NumVals); llvm::ImmutableList<SVal> Vals);
llvm::ImmutableList<SVal> getEmptySValList() {
return SValListFactory.GetEmptyList();
}
llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) {
return SValListFactory.Add(X, L);
}
const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op, const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1, const llvm::APSInt& V1,

Просмотреть файл

@ -15,15 +15,18 @@
#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H #ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
#define LLVM_CLANG_ANALYSIS_RVALUE_H #define LLVM_CLANG_ANALYSIS_RVALUE_H
#include "clang/Analysis/PathSensitive/BasicValueFactory.h" #include "clang/Analysis/PathSensitive/SymbolManager.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/ADT/ImmutableList.h"
//==------------------------------------------------------------------------==// //==------------------------------------------------------------------------==//
// Base SVal types. // Base SVal types.
//==------------------------------------------------------------------------==// //==------------------------------------------------------------------------==//
namespace clang { namespace clang {
class CompoundValData;
class BasicValueFactory;
class MemRegion; class MemRegion;
class GRStateManager; class GRStateManager;
@ -170,7 +173,7 @@ public:
static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b); static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
static NonLoc MakeCompoundVal(QualType T, SVal* Vals, unsigned NumSVals, static NonLoc MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
BasicValueFactory& BasicVals); BasicValueFactory& BasicVals);
// Implement isa<T> support. // Implement isa<T> support.
@ -312,10 +315,7 @@ public:
return V->getSubKind() == LocAsIntegerKind; return V->getSubKind() == LocAsIntegerKind;
} }
static inline LocAsInteger Make(BasicValueFactory& Vals, Loc V, static LocAsInteger Make(BasicValueFactory& Vals, Loc V, unsigned Bits);
unsigned Bits) {
return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
}
}; };
class CompoundVal : public NonLoc { class CompoundVal : public NonLoc {

Просмотреть файл

@ -14,34 +14,18 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/BasicValueFactory.h" #include "clang/Analysis/PathSensitive/BasicValueFactory.h"
#include "clang/Analysis/PathSensitive/SVals.h"
using namespace clang; 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, void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
unsigned N, const SVal* Vals) { llvm::ImmutableList<SVal> L) {
T.Profile(ID); T.Profile(ID);
ID.AddInteger(N); ID.AddPointer(L.getInternalPointer());
for (unsigned i = 0; i < N; ++i)
Vals[i].Profile(ID);
} }
typedef std::pair<SVal, uintptr_t> SValData; typedef std::pair<SVal, uintptr_t> SValData;
typedef std::pair<SVal, SVal> SValPair; typedef std::pair<SVal, SVal> SValPair;
namespace llvm { namespace llvm {
template<> struct FoldingSetTrait<SValData> { template<> struct FoldingSetTrait<SValData> {
static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) { static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
@ -127,17 +111,18 @@ BasicValueFactory::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
} }
const CompoundValData* const CompoundValData*
BasicValueFactory::getCompoundValData(QualType T, const SVal* Vals, BasicValueFactory::getCompoundValData(QualType T,
unsigned NumVals) { llvm::ImmutableList<SVal> Vals) {
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
CompoundValData::Profile(ID, T, NumVals, Vals); CompoundValData::Profile(ID, T, Vals);
void* InsertPos; void* InsertPos;
CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos); CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
if (!D) { if (!D) {
D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>(); D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
new (D) CompoundValData(T, Vals, NumVals, BPAlloc); new (D) CompoundValData(T, Vals);
CompoundValDataSet.InsertNode(D, InsertPos); CompoundValDataSet.InsertNode(D, InsertPos);
} }

Просмотреть файл

@ -245,9 +245,9 @@ NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
} }
NonLoc NonLoc::MakeCompoundVal(QualType T, SVal* Vals, unsigned NumSVals, NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
BasicValueFactory& BasicVals) { BasicValueFactory& BasicVals) {
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals, NumSVals)); return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
} }
SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) { SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
@ -260,6 +260,11 @@ SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
return nonloc::SymbolVal(SymMgr.getSymbol(D)); return nonloc::SymbolVal(SymMgr.getSymbol(D));
} }
nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V,
unsigned Bits) {
return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Utility methods for constructing Locs. // Utility methods for constructing Locs.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -353,7 +358,7 @@ void NonLoc::print(std::ostream& Out) const {
Out << " [as " << C.getNumBits() << " bit integer]"; Out << " [as " << C.getNumBits() << " bit integer]";
break; break;
} }
default: default:
assert (false && "Pretty-printed not implemented for this NonLoc."); assert (false && "Pretty-printed not implemented for this NonLoc.");
break; break;