// cfg.ast // AST extension to cc.ast for storing and computing a CFG // the methods declared here are defined in cfg.cc verbatim { #define CFG_EXTENSION // this extension module is active #include "cfg.h" // NextPtr } class Statement { // control flow successor edge; interpretation depends on the exact // kind of statement this is, however, so that's best left to // 'getSuccessors()', and this is therefore protected protected NextPtr next; public friend class CFGEnv; // allow CFGEnv to write 'next' // retrieve all successors of this node, given how we got to this // node ('isContinue'), and put them into 'dest'; this can only // be called after 'computeCFG' has finished; if this returns an // empty set, it means that after the statement, the function returns public void getSuccessors(NextPtrList &dest, bool isContinue); public string successorsToString() const; custom debugPrint { ind(os, indent) << "succ=" << successorsToString() << endl; } // compute the CFG within this statement (e.g. a compound statement that // is a function body) public void computeCFG(CFGEnv &env); pure_virtual void icfg(CFGEnv &env); // TODO: make this private (must modify astgen) // switch has many outgoing edges, so it needs more than just 'next' -> S_switch { // pointers to all of the cases (& default) in this switch; when // interpreted as a NextPtr, all 'continue' flags are false private SObjList cases; public friend class CFGEnv; // allow CFGEnv to write 'cases' public friend class Statement; // for Statement::getSuccessors } } // EOF