Make store "Regions" and "Bindings" more abstract instead of concrete variants.

Their precise semantics will be implemented by a specific StoreManager.

Use function pointer to create the StoreManager in GRStateManager.  This matches how we create ConstraintsManager.

llvm-svn: 55514
This commit is contained in:
Ted Kremenek 2008-08-28 23:31:31 +00:00
parent 5888e603c3
commit e91874f71f
5 changed files with 108 additions and 29 deletions

View File

@ -16,14 +16,9 @@
#include "clang/Analysis/PathSensitive/Store.h"
namespace llvm {
class BumpPtrAllocator;
class ASTContext;
}
namespace clang {
StoreManager* CreateBasicStoreManager(llvm::BumpPtrAllocator& Alloc,
ASTContext& Ctx);
class GRStateManager;
StoreManager* CreateBasicStoreManager(GRStateManager& StMgr);
}
#endif

View File

@ -288,15 +288,17 @@ private:
const GRState* BindVar(const GRState* St, VarDecl* D, RVal V) {
return SetRVal(St, lval::DeclVal(D), V);
}
typedef ConstraintManager* (*ConstraintManagerCreater)(GRStateManager&);
public:
GRStateManager(ASTContext& Ctx, StoreManager* stmgr,
ConstraintManagerCreater CreateConstraintManager,
public:
typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&);
typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
GRStateManager(ASTContext& Ctx,
StoreManagerCreator CreateStoreManager,
ConstraintManagerCreator CreateConstraintManager,
llvm::BumpPtrAllocator& alloc, CFG& c, LiveVariables& L)
: EnvMgr(alloc),
StMgr(stmgr),
ISetFactory(alloc),
GDMFactory(alloc),
BasicVals(Ctx, alloc),
@ -304,7 +306,8 @@ public:
Alloc(alloc),
cfg(c),
Liveness(L) {
ConstraintMgr.reset((*CreateConstraintManager)(*this));
StMgr.reset((*CreateStoreManager)(*this));
ConstraintMgr.reset((*CreateConstraintManager)(*this));
}
~GRStateManager();

View File

@ -15,7 +15,6 @@
#define LLVM_CLANG_ANALYSIS_STORE_H
#include "clang/Analysis/PathSensitive/RValues.h"
#include "clang/Analysis/PathSensitive/Regions.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/DenseSet.h"
@ -25,6 +24,78 @@
namespace clang {
typedef const void* Store;
namespace store {
typedef const void* Binding;
typedef const void* Region;
class RegionExtent {
public:
enum Kind { Unknown = 0, Int = 0, Sym = 1 };
protected:
const uintptr_t Raw;
RegionExtent(uintptr_t raw, Kind k) : Raw(raw | k) {}
uintptr_t getData() const { return Raw & ~0x1; }
public:
// Folding-set profiling.
void Profile(llvm::FoldingSetNodeID& ID) const {
ID.AddPointer((void*) Raw);
}
// Comparing extents.
bool operator==(const RegionExtent& R) const {
return Raw == R.Raw;
}
bool operator!=(const RegionExtent& R) const {
return Raw != R.Raw;
}
// Implement isa<T> support.
Kind getKind() const { return Kind(Raw & 0x1); }
uintptr_t getRaw() const { return Raw; }
static inline bool classof(const RegionExtent*) {
return true;
}
};
class UnknownExtent : public RegionExtent {
public:
UnknownExtent() : RegionExtent(0,Unknown) {}
// Implement isa<T> support.
static inline bool classof(const RegionExtent* E) {
return E->getRaw() == 0;
}
};
class IntExtent : public RegionExtent {
public:
IntExtent(const llvm::APSInt& X) : RegionExtent((uintptr_t) &X, Int) {}
const llvm::APSInt& getInt() const {
return *((llvm::APSInt*) getData());
}
// Implement isa<T> support.
static inline bool classof(const RegionExtent* E) {
return E->getKind() == Int && E->getRaw() != 0;
}
};
class SymExtent : public RegionExtent {
public:
SymExtent(SymbolID S) : RegionExtent(S.getNumber() << 1, Sym) {}
SymbolID getSymbol() const { return SymbolID(getData() >> 1); }
// Implement isa<T> support.
static inline bool classof(const RegionExtent* E) {
return E->getKind() == Sym;
}
};
} // end store namespace
class GRStateManager;
class LiveVariables;
class Stmt;
@ -54,7 +125,7 @@ public:
const char* nl, const char *sep) = 0;
/// getExtent - Returns the size of the region in bits.
virtual RegionExtent getExtent(GRStateManager& SM, Region R) = 0;
virtual store::RegionExtent getExtent(store::Region R) =0;
};
} // end clang namespace

View File

@ -11,25 +11,26 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/PathSensitive/BasicStore.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/PathSensitive/GRState.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Streams.h"
using namespace clang;
using store::Region;
using store::RegionExtent;
namespace {
class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
VarBindingsTy::Factory VBFactory;
ASTContext& C;
GRStateManager& StMgr;
public:
BasicStoreManager(llvm::BumpPtrAllocator& A, ASTContext& c)
: VBFactory(A), C(c) {}
BasicStoreManager(GRStateManager& mgr) : StMgr(mgr) {}
virtual ~BasicStoreManager() {}
@ -55,24 +56,33 @@ public:
virtual void print(Store store, std::ostream& Out,
const char* nl, const char *sep);
virtual RegionExtent getExtent(GRStateManager& SM, Region R);
virtual RegionExtent getExtent(Region R);
};
} // end anonymous namespace
StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A,
ASTContext& C) {
return new BasicStoreManager(A, C);
StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
return new BasicStoreManager(StMgr);
}
RegionExtent BasicStoreManager::getExtent(GRStateManager& SM, Region R) {
if (VarRegion *VR = dyn_cast<VarRegion>(&R))
return VR->getExtent(SM.getBasicVals());
RegionExtent BasicStoreManager::getExtent(Region R) {
VarDecl* VD = (VarDecl*) R;
QualType T = VD->getType();
return UnknownExtent();
// FIXME: Add support for VLAs. This may require passing in additional
// information, or tracking a different region type.
if (!T.getTypePtr()->isConstantSizeType())
return store::UnknownExtent();
ASTContext& C = StMgr.getContext();
assert (!T->isObjCInterfaceType()); // @interface not a possible VarDecl type.
assert (T != C.VoidTy); // void not a possible VarDecl type.
return store::IntExtent(StMgr.getBasicVals().getValue(C.getTypeSize(T),
C.VoidPtrTy));
}
RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
if (isa<UnknownVal>(LV))

View File

@ -120,7 +120,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
G(CoreEngine.getGraph()),
Liveness(L),
Builder(NULL),
StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator(), Ctx),
StateMgr(G.getContext(), CreateBasicStoreManager,
CreateBasicConstraintManager, G.getAllocator(), G.getCFG(), L),
SymMgr(StateMgr.getSymbolManager()),
CurrentStmt(NULL),