/// <summary> /// Block pretty-printer. /// </summary> /// <param name="tw">Where to print.</param> /// <param name="block">What to print</param> /// <param name="get_stat_info">Provider of statement specific information; /// if non-null, it will be called after printing each statement, and its result /// printed too.</param> /// <param name="b2id">Map block -> int identifier; if <c>null</c>, then the block /// UniqueKey is used as block id.</param> public static void PrintBlock(TextWriter tw, Block block, DGetStatInfo get_stat_info, Hashtable /*<Block,int>*/ b2id) { string bn = b2s(block, b2id) + ": "; // hack to make it look nicer! tab is more elegant, but it's also too long. // we just hope that methods with more that 99 blocks are not that frequent. if (bn.Length < 5) { bn += " "; } string buff = ""; for (int i = 0; i < bn.Length; i++) { buff += " "; } if (block.Statements.Count == 0) { tw.WriteLine(bn + "EMPTY BLOCK"); } for (int i = 0, n = block.Statements.Count; i < n; i++) { tw.Write((i == 0) ? bn : buff); Statement stat = block.Statements[i]; if (stat is Block) { throw new ApplicationException("nested blocks"); } tw.Write(StatementToString(stat, b2id)); tw.WriteLine(";"); if (get_stat_info != null) { tw.WriteLine(get_stat_info(stat)); } } }
public static void PrintBlock(TextWriter tw, Block block, DGetStatInfo get_stat_info) { PrintBlock(tw, block, get_stat_info, null); }
/// <summary> /// Block pretty-printer. /// </summary> /// <param name="tw">Where to print.</param> /// <param name="block">What to print</param> /// <param name="get_stat_info">Provider of statement specific information; /// if non-null, it will be called after printing each statement, and its result /// printed too.</param> /// <param name="b2id">Map block -> int identifier; if <c>null</c>, then the block /// UniqueKey is used as block id.</param> public static void PrintBlock(TextWriter tw, Block block, DGetStatInfo get_stat_info, Hashtable/*<Block,int>*/ b2id) { string bn = b2s(block, b2id) + ": "; // hack to make it look nicer! tab is more elegant, but it's also too long. // we just hope that methods with more that 99 blocks are not that frequent. if(bn.Length < 5) bn += " "; string buff = ""; for(int i = 0; i < bn.Length; i++) buff += " "; if(block.Statements.Count == 0) tw.WriteLine(bn + "EMPTY BLOCK"); for(int i = 0, n = block.Statements.Count; i < n; i++) { tw.Write((i == 0) ? bn : buff); Statement stat = block.Statements[i]; if(stat is Block) throw new ApplicationException("nested blocks"); tw.Write(StatementToString(stat, b2id)); tw.WriteLine(";"); if(get_stat_info != null) tw.WriteLine(get_stat_info(stat)); } }
/// <summary> /// CFG pretty-printer. For each block, this method /// calls <c>pre_printer</c>c(if non-null), /// prints the normal/excp. successors, /// the code of the block, the normal/excp. predecessors and finally calls /// <c>post_printer</c>. A useful use of the pre and post printers is the /// debugging of a flow-sensitive analysis. /// </summary> /// <param name="tw">Where to print.</param> public void Display( TextWriter tw, CfgBlock[] blocks, DGetBlockInfo get_pre_block_info, DGetBlockInfo get_post_block_info, DGetStatInfo get_stat_info ) { Hashtable b2id = new Hashtable(); for(int i = 0; i < blocks.Length; i++) b2id[blocks[i]] = i; for(int i = 0; i < blocks.Length; i++) { CfgBlock block = blocks[i]; tw.WriteLine("BLOCK " + (block is ISpecialBlock ? "*" : "") + CodePrinter.b2s(block, b2id)); if (get_pre_block_info != null) tw.WriteLine(get_pre_block_info(block)); print_block_array(" Normal pred: ", NormalPred(block), b2id, tw); print_block_array(" Protected blocks: ", ExcpPred(block), b2id, tw); if (ExcpPred(block).Length != 0) { ExceptionHandler eh = HandlerThatStartsAtBlock(block); if (eh != null) tw.WriteLine(" Handler {0} [{1},{2})", eh.HandlerType, CodePrinter.b2s(eh.HandlerStartBlock, b2id), CodePrinter.b2s(eh.BlockAfterHandlerEnd, b2id)); } CodePrinter.PrintBlock(tw, block, get_stat_info, b2id); print_block_array(" Normal succ: ", NormalSucc(block), b2id, tw); print_block_array(" Excp succ: ", this.ExcpSucc(block), b2id, tw); print_block(" Handler: ", ExceptionHandler(block), b2id, tw); print_block_list(" Finallies: ", (FList)b2_enclosing_finally[block], b2id, tw); ExceptionHandler ceh = (ExceptionHandler)b2_containing_handler[block]; if (ceh != null) print_block(" Containing handler", ceh.HandlerStartBlock, b2id, tw); if (get_post_block_info != null) tw.WriteLine(get_post_block_info(block)); tw.WriteLine(); } tw.WriteLine("Entry = " + CodePrinter.b2s(Entry, b2id)); tw.WriteLine("NormalExit = " + CodePrinter.b2s(NormalExit, b2id)); tw.WriteLine("ExcptExit = " + CodePrinter.b2s(ExceptionExit, b2id)); tw.WriteLine("Exit = " + CodePrinter.b2s(Exit, b2id)); }
public void Display( TextWriter tw, DGetBlockInfo get_pre_block_info, DGetBlockInfo get_post_block_info, DGetStatInfo get_stat_info ) { Display(tw, this.Blocks(), get_pre_block_info, get_post_block_info, get_stat_info); }