Add skeleton for handling other kinds of CFGElements.

llvm-svn: 119135
This commit is contained in:
Zhongxing Xu 2010-11-15 08:48:43 +00:00
parent efacb9ee42
commit 5d30c69813
6 changed files with 53 additions and 19 deletions

View File

@ -49,7 +49,7 @@ public:
Statement, Statement,
StatementAsLValue, StatementAsLValue,
Initializer, Initializer,
Dtor, ImplicitDtor,
// dtor kind // dtor kind
AutomaticObjectDtor, AutomaticObjectDtor,
BaseDtor, BaseDtor,
@ -74,7 +74,7 @@ public:
Kind getKind() const { return static_cast<Kind>(Data1.getInt()); } Kind getKind() const { return static_cast<Kind>(Data1.getInt()); }
Kind getDtorKind() const { Kind getDtorKind() const {
assert(getKind() == Dtor); assert(getKind() == ImplicitDtor);
return static_cast<Kind>(Data2.getInt() + DTOR_BEGIN); return static_cast<Kind>(Data2.getInt() + DTOR_BEGIN);
} }
@ -132,13 +132,13 @@ public:
class CFGImplicitDtor : public CFGElement { class CFGImplicitDtor : public CFGElement {
protected: protected:
CFGImplicitDtor(unsigned K, void* P, void* S) CFGImplicitDtor(unsigned K, void* P, void* S)
: CFGElement(P, Dtor, S, K - DTOR_BEGIN) {} : CFGElement(P, ImplicitDtor, S, K - DTOR_BEGIN) {}
public: public:
CFGImplicitDtor() {} CFGImplicitDtor() {}
static bool classof(const CFGElement *E) { static bool classof(const CFGElement *E) {
return E->getKind() == Dtor; return E->getKind() == ImplicitDtor;
} }
}; };
@ -161,7 +161,8 @@ public:
} }
static bool classof(const CFGElement *E) { static bool classof(const CFGElement *E) {
return E->getKind() == Dtor && E->getDtorKind() == AutomaticObjectDtor; return E->getKind() == ImplicitDtor &&
E->getDtorKind() == AutomaticObjectDtor;
} }
}; };
@ -178,7 +179,7 @@ public:
} }
static bool classof(const CFGElement *E) { static bool classof(const CFGElement *E) {
return E->getKind() == Dtor && E->getDtorKind() == BaseDtor; return E->getKind() == ImplicitDtor && E->getDtorKind() == BaseDtor;
} }
}; };
@ -195,7 +196,7 @@ public:
} }
static bool classof(const CFGElement *E) { static bool classof(const CFGElement *E) {
return E->getKind() == Dtor && E->getDtorKind() == MemberDtor; return E->getKind() == ImplicitDtor && E->getDtorKind() == MemberDtor;
} }
}; };
@ -212,7 +213,7 @@ public:
} }
static bool classof(const CFGElement *E) { static bool classof(const CFGElement *E) {
return E->getKind() == Dtor && E->getDtorKind() == TemporaryDtor; return E->getKind() == ImplicitDtor && E->getDtorKind() == TemporaryDtor;
} }
}; };

View File

@ -90,8 +90,8 @@ private:
SubEngine.ProcessEndPath(Builder); SubEngine.ProcessEndPath(Builder);
} }
void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& Builder) { void ProcessElement(const CFGElement E, GRStmtNodeBuilder& Builder) {
SubEngine.ProcessStmt(E, Builder); SubEngine.ProcessElement(E, Builder);
} }
bool ProcessBlockEntrance(const CFGBlock* Blk, const ExplodedNode *Pred, bool ProcessBlockEntrance(const CFGBlock* Blk, const ExplodedNode *Pred,

View File

@ -175,9 +175,15 @@ public:
return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag())); return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
} }
/// ProcessStmt - Called by GRCoreEngine. Used to generate new successor /// ProcessElement - Called by GRCoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a block-level statement. /// nodes by processing the 'effects' of a CFG element.
void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& builder); void ProcessElement(const CFGElement E, GRStmtNodeBuilder& builder);
void ProcessStmt(const CFGStmt S, GRStmtNodeBuilder &builder);
void ProcessInitializer(const CFGInitializer I, GRStmtNodeBuilder &builder);
void ProcessImplicitDtor(const CFGImplicitDtor D, GRStmtNodeBuilder &builder);
/// ProcessBlockEntrance - Called by GRCoreEngine when start processing /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
/// a CFGBlock. This method returns true if the analysis should continue /// a CFGBlock. This method returns true if the analysis should continue

View File

@ -47,7 +47,7 @@ public:
/// Called by GRCoreEngine. Used to generate new successor /// Called by GRCoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a block-level statement. /// nodes by processing the 'effects' of a block-level statement.
virtual void ProcessStmt(const CFGElement E, GRStmtNodeBuilder& builder) = 0; virtual void ProcessElement(const CFGElement E, GRStmtNodeBuilder& builder)=0;
/// Called by GRCoreEngine when start processing /// Called by GRCoreEngine when start processing
/// a CFGBlock. This method returns true if the analysis should continue /// a CFGBlock. This method returns true if the analysis should continue

View File

@ -309,7 +309,7 @@ void GRCoreEngine::HandleBlockEntrance(const BlockEntrance& L,
if (CFGElement E = L.getFirstElement()) { if (CFGElement E = L.getFirstElement()) {
GRStmtNodeBuilder Builder(L.getBlock(), 0, Pred, this, GRStmtNodeBuilder Builder(L.getBlock(), 0, Pred, this,
SubEngine.getStateManager()); SubEngine.getStateManager());
ProcessStmt(E, Builder); ProcessElement(E, Builder);
} }
else else
HandleBlockExit(L.getBlock(), Pred); HandleBlockExit(L.getBlock(), Pred);
@ -423,7 +423,7 @@ void GRCoreEngine::HandlePostStmt(const PostStmt& L, const CFGBlock* B,
else { else {
GRStmtNodeBuilder Builder(B, StmtIdx, Pred, this, GRStmtNodeBuilder Builder(B, StmtIdx, Pred, this,
SubEngine.getStateManager()); SubEngine.getStateManager());
ProcessStmt((*B)[StmtIdx], Builder); ProcessElement((*B)[StmtIdx], Builder);
} }
} }

View File

@ -552,8 +552,27 @@ void GRExprEngine::ProcessEndWorklist(bool hasWorkRemaining) {
} }
} }
void GRExprEngine::ProcessStmt(const CFGElement CE,GRStmtNodeBuilder& builder) { void GRExprEngine::ProcessElement(const CFGElement E,
CurrentStmt = CE.getAs<CFGStmt>(); GRStmtNodeBuilder& builder) {
switch (E.getKind()) {
case CFGElement::Statement:
case CFGElement::StatementAsLValue:
ProcessStmt(E.getAs<CFGStmt>(), builder);
break;
case CFGElement::Initializer:
ProcessInitializer(E.getAs<CFGInitializer>(), builder);
break;
case CFGElement::ImplicitDtor:
ProcessImplicitDtor(E.getAs<CFGImplicitDtor>(), builder);
break;
default:
// Suppress compiler warning.
llvm_unreachable("Unexpected CFGElement kind.");
}
}
void GRExprEngine::ProcessStmt(const CFGStmt S, GRStmtNodeBuilder& builder) {
CurrentStmt = S.getStmt();
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
CurrentStmt->getLocStart(), CurrentStmt->getLocStart(),
"Error evaluating statement"); "Error evaluating statement");
@ -636,7 +655,7 @@ void GRExprEngine::ProcessStmt(const CFGElement CE,GRStmtNodeBuilder& builder) {
Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I)); Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
// Visit the statement. // Visit the statement.
if (CE.getAs<CFGStmt>().asLValue()) if (S.asLValue())
VisitLValue(cast<Expr>(CurrentStmt), *I, Dst); VisitLValue(cast<Expr>(CurrentStmt), *I, Dst);
else else
Visit(CurrentStmt, *I, Dst); Visit(CurrentStmt, *I, Dst);
@ -660,6 +679,14 @@ void GRExprEngine::ProcessStmt(const CFGElement CE,GRStmtNodeBuilder& builder) {
Builder = NULL; Builder = NULL;
} }
void GRExprEngine::ProcessInitializer(const CFGInitializer I,
GRStmtNodeBuilder &builder) {
}
void GRExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
GRStmtNodeBuilder &builder) {
}
void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
ExplodedNodeSet& Dst) { ExplodedNodeSet& Dst) {
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),