void CoreEngine::dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc, const WorkListUnit& WU) { // Dispatch on the location type. switch (Loc.getKind()) { case ProgramPoint::BlockEdgeKind: HandleBlockEdge(cast<BlockEdge>(Loc), Pred); break; case ProgramPoint::BlockEntranceKind: HandleBlockEntrance(cast<BlockEntrance>(Loc), Pred); break; case ProgramPoint::BlockExitKind: assert (false && "BlockExit location never occur in forward analysis."); break; case ProgramPoint::CallEnterKind: { CallEnter CEnter = cast<CallEnter>(Loc); if (AnalyzedCallees) if (const CallExpr* CE = dyn_cast_or_null<CallExpr>(CEnter.getCallExpr())) if (const Decl *CD = CE->getCalleeDecl()) AnalyzedCallees->insert(CD); SubEng.processCallEnter(CEnter, Pred); break; } case ProgramPoint::CallExitBeginKind: SubEng.processCallExit(Pred); break; case ProgramPoint::EpsilonKind: { assert(Pred->hasSinglePred() && "Assume epsilon has exactly one predecessor by construction"); ExplodedNode *PNode = Pred->getFirstPred(); dispatchWorkItem(Pred, PNode->getLocation(), WU); break; } default: assert(isa<PostStmt>(Loc) || isa<PostInitializer>(Loc) || isa<CallExitEnd>(Loc)); HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred); break; } }
void CoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block, unsigned Index, ExplodedNode *Pred) { CallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), L.getCalleeContext(), Block, Index); SubEng.processCallEnter(Builder); }