forked from OSchip/llvm-project
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:
parent
5888e603c3
commit
e91874f71f
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue