VisitLocation(C, S, location);
}
+ void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
+ SymbolReaper &SymReaper, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ ProgramPoint::PostPurgeDeadSymbolsKind, Pred->getState());
+ EvalDeadSymbols(C, S, SymReaper);
+ }
+
public:
virtual ~Checker() {}
virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
const Stmt *StoreE, SVal location, SVal val) {}
+ virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
+ SymbolReaper &SymReaper) {}
};
} // end clang namespace
SaveAndRestore<bool> OldPurgeDeadSymbols(Builder->PurgingDeadSymbols);
Builder->PurgingDeadSymbols = true;
- getTF().EvalDeadSymbols(Tmp, *this, *Builder, EntryNode, S,
+ // FIXME: This should soon be removed.
+ ExplodedNodeSet Tmp2;
+ getTF().EvalDeadSymbols(Tmp2, *this, *Builder, EntryNode, S,
CleanedState, SymReaper);
+ if (Checkers.empty())
+ Tmp = Tmp2;
+ else {
+ ExplodedNodeSet Tmp3;
+ ExplodedNodeSet *SrcSet = &Tmp2;
+ for (CheckersOrdered::iterator I = Checkers.begin(), E = Checkers.end();
+ I != E; ++I) {
+ ExplodedNodeSet *DstSet = (I+1 == E) ? &Tmp
+ : (SrcSet == &Tmp2) ? &Tmp3
+ : &Tmp2;
+ void *tag = I->first;
+ Checker *checker = I->second;
+ for (ExplodedNodeSet::iterator NI = SrcSet->begin(), NE = SrcSet->end();
+ NI != NE; ++NI)
+ checker->GR_EvalDeadSymbols(*DstSet, *Builder, *this, S, *NI,
+ SymReaper, tag);
+ SrcSet = DstSet;
+ }
+ }
+
if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
Tmp.Add(EntryNode);
}