void CFG::buildCFG(CFGNode n) { ROSE_ASSERT(n.getNode()); if (explored_.count(n) > 0) return; explored_.insert(n); SgGraphNode* from = NULL; if (all_nodes_.count(n) > 0) { from = all_nodes_[n]; } else { from = new SgGraphNode; from->set_SgNode(n.getNode()); from->addNewAttribute("info", new CFGNodeAttribute(n.getIndex(), graph_)); all_nodes_[n] = from; graph_->addNode(from); } std::vector<VirtualCFG::CFGEdge> outEdges = n.outEdges(); foreach (const VirtualCFG::CFGEdge& edge, outEdges) { CFGNode tar = edge.target(); SgGraphNode* to = NULL; if (all_nodes_.count(tar) > 0) to = all_nodes_[tar]; else { to = new SgGraphNode; to->set_SgNode(tar.getNode()); to->addNewAttribute("info", new CFGNodeAttribute(tar.getIndex(), graph_)); all_nodes_[tar] = to; graph_->addNode(to); } graph_->addDirectedEdge(new SgDirectedGraphEdge(from, to)); }
// the default interesting filter bool defaultFilter (CFGNode cfgn) { SgNode * node = cfgn.getNode(); assert (node != NULL) ; //Keep the last index for initialized names. This way the definition of the variable doesn't //propagate to its assign initializer. if (isSgInitializedName(node)) { return (cfgn == node->cfgForEnd()); } else return (cfgn.isInteresting()); }
// the default interesting filter bool defaultFilter (CFGNode cfgn) { SgNode * node = cfgn.getNode(); assert (node != NULL) ; //Keep the last index for initialized names. This way the definition of the variable doesn't //propagate to its assign initializer. // if (isSgInitializedName(node)) // { // return (cfgn == node->cfgForEnd()); // } // else // return (cfgn.isInteresting()); switch(node->variantT()) { //Keep the last index for initialized names. This way the definition of the variable doesn't //propagate to its assign initializer. case V_SgInitializedName: return (cfgn == node->cfgForEnd()); // filter out this node type // abstract memory object cannot be created for these nodes case V_SgExprListExp: case V_SgNullStatement: case V_SgExprStatement: case V_SgFunctionRefExp: return false; case V_SgFunctionCallExp: return cfgn.getIndex()==2 || cfgn.getIndex()==3; case V_SgFunctionParameterList: return true; //return cfgn.getIndex()==1;*/ case V_SgFunctionDefinition: return cfgn.getIndex()==3; case V_SgReturnStmt: return cfgn.getIndex()==1; // Filter out intermediate dot expressions. We only care about the complete ones. case V_SgDotExp: //cout << "defaultFilter() node="<<cfgUtils::SgNode2Str(node)<<" node->get_parent()="<<cfgUtils::SgNode2Str(node->get_parent())<<" interesting="<<(!isSgDotExp(node->get_parent()))<<endl; return !isSgDotExp(node->get_parent()); /*case V_SgCastExp: return false;*/ default: return cfgn.isInteresting(); } }
bool isDataflowInteresting(CFGNode cn) { ROSE_ASSERT (cn.getNode()); return (cn.getNode()->cfgIsIndexInteresting(cn.getIndex()) && //!isSgFunctionRefExp(cn.getNode()) && !isSgExprListExp(cn.getNode()) && !isSgForInitStatement(cn.getNode()) && //!isSgVarRefExp(cn.getNode()) && //!isSgValueExp(cn.getNode()) && //!isSgExprStatement(cn.getNode()) && !(isSgInitializedName(cn.getNode()) && cn.getIndex()==0)) || (isSgIfStmt(cn.getNode()) && cn.getIndex()==1 || cn.getIndex()==2); }
bool gfilter (CFGNode cfgn) { SgNode *node = cfgn.getNode(); switch (node->variantT()) { //Keep the last index for initialized names. This way the def of the variable doesn't propagate to its assign //initializer. case V_SgInitializedName: return (cfgn == node->cfgForEnd()); #if 0 //For function calls, we only keep the last node. The function is actually called after all its parameters //are evaluated. // case V_SgFunctionCallExp: // return (cfgn == node->cfgForEnd()); // //For basic blocks and other "container" nodes, keep the node that appears before the contents are executed case V_SgBasicBlock: case V_SgExprStatement: case V_SgCommaOpExp: return (cfgn == node->cfgForBeginning()); // // case V_SgTryStmt: // return (cfgn == node->cfgForBeginning()); // // //We only want the middle appearance of the teritatry operator - after its conditional expression // //and before the true and false bodies. This makes it behave as an if statement for data flow // //purposes // case V_SgConditionalExp: // return (cfgn.getIndex() == 1); // // //Make these binary operators appear after their operands, because they are evaluated after their operands // case V_SgAndOp: // case V_SgOrOp: // return (cfgn == node->cfgForEnd()); #endif default: return cfgn.isInteresting(); } }
//! Constructor CFGEdge(CFGNode src, CFGNode tgt): src(src), tgt(tgt) { assert(src.getNode() != NULL && tgt.getNode() != NULL); }