Move the handling of DeclStmt from GRExprEngine to BasicStoreManager.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55144 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zhongxing Xu 2008-08-21 22:34:01 +00:00
Родитель dbc933701d
Коммит bbe8ff48be
5 изменённых файлов: 97 добавлений и 72 удалений

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

@ -310,7 +310,10 @@ public:
LiveVariables& getLiveVariables() { return Liveness; }
typedef StoreManager::DeadSymbolsTy DeadSymbolsTy;
const GRState* AddDecl(const GRState* St, const VarDecl* VD, Expr* Ex,
unsigned Count);
const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
const LiveVariables& Liveness,
DeadSymbolsTy& DeadSyms);

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

@ -44,7 +44,11 @@ public:
const LiveVariables& Live,
DeclRootsTy& DRoots, LiveSymbolsTy& LSymbols,
DeadSymbolsTy& DSymbols) = 0;
virtual Store AddDecl(Store store, BasicValueFactory& BasicVals,
SymbolManager& SymMgr, const VarDecl* VD, Expr* Ex,
RVal InitVal = UndefinedVal(), unsigned Count = 0) = 0;
virtual void print(Store store, std::ostream& Out,
const char* nl, const char *sep) = 0;
};

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

@ -40,7 +40,11 @@ public:
const LiveVariables& Live,
DeclRootsTy& DRoots, LiveSymbolsTy& LSymbols,
DeadSymbolsTy& DSymbols);
virtual Store AddDecl(Store store, BasicValueFactory& BasicVals,
SymbolManager& SymMgr, const VarDecl* VD, Expr* Ex,
RVal InitVal = UndefinedVal(), unsigned Count = 0);
static inline VarBindingsTy GetVarBindings(Store store) {
return VarBindingsTy(static_cast<const VarBindingsTy::TreeTy*>(store));
}
@ -239,6 +243,69 @@ Store BasicStoreManager::getInitialStore(GRStateManager& StateMgr) {
return St;
}
Store BasicStoreManager::AddDecl(Store store, BasicValueFactory& BasicVals,
SymbolManager& SymMgr, const VarDecl* VD,
Expr* Ex, RVal InitVal, unsigned Count) {
// BasicStore does not model arrays and structs.
if (VD->getType()->isArrayType() || VD->getType()->isStructureType())
return store;
if (VD->hasGlobalStorage()) {
// Handle variables with global storage: extern, static, PrivateExtern.
// FIXME:: static variables may have an initializer, but the second time a
// function is called those values may not be current. Currently, a function
// will not be called more than once.
// Static global variables should not be visited here.
assert(!(VD->getStorageClass() == VarDecl::Static &&
VD->isFileVarDecl()));
// Process static variables.
if (VD->getStorageClass() == VarDecl::Static) {
// C99: 6.7.8 Initialization
// If an object that has static storage duration is not initialized
// explicitly, then:
// —if it has pointer type, it is initialized to a null pointer;
// —if it has arithmetic type, it is initialized to (positive or
// unsigned) zero;
if (!Ex) {
QualType T = VD->getType();
if (LVal::IsLValType(T))
store = SetRVal(store, lval::DeclVal(VD),
lval::ConcreteInt(BasicVals.getValue(0, T)));
else if (T->isIntegerType())
store = SetRVal(store, lval::DeclVal(VD),
nonlval::ConcreteInt(BasicVals.getValue(0, T)));
else {
// assert(0 && "ignore other types of variables");
}
} else {
store = SetRVal(store, lval::DeclVal(VD), InitVal);
}
}
} else {
// Process local scalar variables.
QualType T = VD->getType();
if (LVal::IsLValType(T) || T->isIntegerType()) {
RVal V = Ex ? InitVal : UndefinedVal();
if (Ex && InitVal.isUnknown()) {
// EXPERIMENTAL: "Conjured" symbols.
SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
V = LVal::IsLValType(Ex->getType())
? cast<RVal>(lval::SymbolVal(Sym))
: cast<RVal>(nonlval::SymbolVal(Sym));
}
store = SetRVal(store, lval::DeclVal(VD), V);
}
}
return store;
}
void BasicStoreManager::print(Store store, std::ostream& Out,
const char* nl, const char *sep) {

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

@ -1484,76 +1484,9 @@ void GRExprEngine::VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D,
if (Tmp.empty()) Tmp.Add(Pred);
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* St = GetState(*I);
if (!Ex && VD->hasGlobalStorage()) {
// Handle variables with global storage and no initializers.
// FIXME: static variables may have an initializer, but the second
// time a function is called those values may not be current.
// In this context, Static => Local variable.
assert (!VD->getStorageClass() == VarDecl::Static ||
!VD->isFileVarDecl());
// If there is no initializer, set the value of the
// variable to "Undefined".
if (VD->getStorageClass() == VarDecl::Static) {
// C99: 6.7.8 Initialization
// If an object that has static storage duration is not initialized
// explicitly, then:
// —if it has pointer type, it is initialized to a null pointer;
// —if it has arithmetic type, it is initialized to (positive or
// unsigned) zero;
// FIXME: Handle structs. Now we treat their values as unknown.
QualType T = VD->getType();
if (LVal::IsLValType(T))
St = SetRVal(St, lval::DeclVal(VD),
lval::ConcreteInt(getBasicVals().getValue(0, T)));
else if (T->isIntegerType())
St = SetRVal(St, lval::DeclVal(VD),
nonlval::ConcreteInt(getBasicVals().getValue(0, T)));
// FIXME: Handle structs. Now we treat them as unknown. What
// we need to do is treat their members as unknown.
}
}
else {
// FIXME: Handle structs. Now we treat them as unknown. What
// we need to do is treat their members as unknown.
QualType T = VD->getType();
if (LVal::IsLValType(T) || T->isIntegerType()) {
RVal V = Ex ? GetRVal(St, Ex) : UndefinedVal();
if (Ex && V.isUnknown()) {
// EXPERIMENTAL: "Conjured" symbols.
unsigned Count = Builder->getCurrentBlockCount();
SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
V = LVal::IsLValType(Ex->getType())
? cast<RVal>(lval::SymbolVal(Sym))
: cast<RVal>(nonlval::SymbolVal(Sym));
}
St = SetRVal(St, lval::DeclVal(VD), V);
}
}
St = StateMgr.AddDecl(St, VD, Ex, Builder->getCurrentBlockCount());
// Create a new node. We don't really need to create a new NodeSet
// here, but it simplifies things and doesn't cost much.
NodeSet Tmp2;

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

@ -142,6 +142,24 @@ const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV,
return getPersistentState(NewSt);
}
const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD,
Expr* Ex, unsigned Count) {
Store OldStore = St->getStore();
Store NewStore;
if (Ex)
NewStore = StMgr->AddDecl(OldStore, BasicVals, SymMgr, VD, Ex,
GetRVal(St, Ex), Count);
else
NewStore = StMgr->AddDecl(OldStore, BasicVals, SymMgr, VD, Ex);
if (NewStore == OldStore)
return St;
GRState NewSt = *St;
NewSt.St = NewStore;
return getPersistentState(NewSt);
}
const GRState* GRStateManager::Unbind(const GRState* St, LVal LV) {
Store OldStore = St->getStore();
Store NewStore = StMgr->Remove(OldStore, LV);