private static Statement DetectStatement(Statement head) { Statement res; if ((res = DoStatement.IsHead(head)) != null) { return(res); } if ((res = SwitchStatement.IsHead(head)) != null) { return(res); } if ((res = IfStatement.IsHead(head)) != null) { return(res); } // synchronized statements will be identified later // right now they are recognized as catchall if ((res = SequenceStatement.IsHead2Block(head)) != null) { return(res); } if ((res = CatchStatement.IsHead(head)) != null) { return(res); } if ((res = CatchAllStatement.IsHead(head)) != null) { return(res); } return(null); }
internal StackEntry(CatchAllStatement catchstatement, bool state, int edgetype, Statement destination, Statement finallyShortRangeEntry, Statement finallyLongRangeEntry, DirectNode finallyShortRangeSource, DirectNode finallyLongRangeSource, bool isFinallyExceptionPath ) { this.catchstatement = catchstatement; this.state = state; this.edgetype = edgetype; this.isFinallyExceptionPath = isFinallyExceptionPath; this.destination = destination; this.finallyShortRangeEntry = finallyShortRangeEntry; this.finallyLongRangeEntry = finallyLongRangeEntry; this.finallyShortRangeSource = finallyShortRangeSource; this.finallyLongRangeSource = finallyLongRangeSource; }
internal StackEntry(CatchAllStatement catchstatement, bool state) : this(catchstatement, state, -1, null, null, null, null, null, false) { }
private void FlattenStatement() { LinkedList <_T2081736913> lstStackStatements = new LinkedList <_T2081736913>(); lstStackStatements.AddLast(new _T2081736913(this, root, new LinkedList <FlattenStatementsHelper.StackEntry >(), null)); while (!(lstStackStatements.Count == 0)) { _T2081736913 statEntry = Sharpen.Collections.RemoveFirst(lstStackStatements); Statement stat = statEntry.statement; LinkedList <FlattenStatementsHelper.StackEntry> stackFinally = statEntry.stackFinally; int statementBreakIndex = statEntry.statementIndex; DirectNode node; DirectNode nd; List <StatEdge> lstSuccEdges = new List <StatEdge>(); DirectNode sourcenode = null; if (statEntry.succEdges == null) { switch (stat.type) { case Statement.Type_Basicblock: { node = new DirectNode(DirectNode.Node_Direct, stat, (BasicBlockStatement)stat); if (stat.GetExprents() != null) { node.exprents = stat.GetExprents(); } graph.nodes.PutWithKey(node, node.id); Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, null }); Sharpen.Collections.AddAll(lstSuccEdges, stat.GetSuccessorEdges(Statement.Statedge_Direct_All )); sourcenode = node; List <Exprent> tailExprentList = statEntry.tailExprents; if (tailExprentList != null) { DirectNode tail = new DirectNode(DirectNode.Node_Tail, stat, stat.id + "_tail"); tail.exprents = tailExprentList; graph.nodes.PutWithKey(tail, tail.id); Sharpen.Collections.Put(mapDestinationNodes, -stat.id, new string[] { tail.id, null }); listEdges.Add(new FlattenStatementsHelper.Edge(node.id, -stat.id, StatEdge.Type_Regular )); sourcenode = tail; } // 'if' statement: record positive branch if (stat.GetLastBasicType() == Statement.Lastbasictype_If) { Sharpen.Collections.Put(mapPosIfBranch, sourcenode.id, lstSuccEdges[0].GetDestination ().id); } break; } case Statement.Type_Catchall: case Statement.Type_Trycatch: { DirectNode firstnd = new DirectNode(DirectNode.Node_Try, stat, stat.id + "_try"); Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { firstnd.id, null }); graph.nodes.PutWithKey(firstnd, firstnd.id); LinkedList <_T2081736913> lst = new LinkedList <_T2081736913>(); foreach (Statement st in stat.GetStats()) { listEdges.Add(new FlattenStatementsHelper.Edge(firstnd.id, st.id, StatEdge.Type_Regular )); LinkedList <FlattenStatementsHelper.StackEntry> stack = stackFinally; if (stat.type == Statement.Type_Catchall && ((CatchAllStatement)stat).IsFinally()) { stack = new LinkedList <FlattenStatementsHelper.StackEntry>(stackFinally); if (st == stat.GetFirst()) { // catch head stack.AddLast(new FlattenStatementsHelper.StackEntry((CatchAllStatement)stat, false)); } else { // handler stack.AddLast(new FlattenStatementsHelper.StackEntry((CatchAllStatement)stat, true, StatEdge .Type_Break, root.GetDummyExit(), st, st, firstnd, firstnd, true)); } } lst.AddLast(new _T2081736913(this, st, stack, null)); } lstStackStatements = new LinkedList <_T2081736913>(lst.Concat(lstStackStatements)); break; } case Statement.Type_Do: { if (statementBreakIndex == 0) { statEntry.statementIndex = 1; lstStackStatements.AddFirst(statEntry); lstStackStatements.AddFirst(new _T2081736913(this, stat.GetFirst(), stackFinally, null)); goto mainloop_continue; } nd = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(stat.GetFirst().id)[0]); DoStatement dostat = (DoStatement)stat; int looptype = dostat.GetLooptype(); if (looptype == DoStatement.Loop_Do) { Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nd.id, nd.id }); break; } lstSuccEdges.Add(stat.GetSuccessorEdges(Statement.Statedge_Direct_All)[0]); switch (looptype) { case DoStatement.Loop_While: case DoStatement.Loop_Dowhile: { // exactly one edge node = new DirectNode(DirectNode.Node_Condition, stat, stat.id + "_cond"); node.exprents = dostat.GetConditionExprentList(); graph.nodes.PutWithKey(node, node.id); listEdges.Add(new FlattenStatementsHelper.Edge(node.id, stat.GetFirst().id, StatEdge .Type_Regular)); if (looptype == DoStatement.Loop_While) { Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, node .id }); } else { Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nd.id, node. id }); bool found = false; foreach (FlattenStatementsHelper.Edge edge in listEdges) { if (edge.statid.Equals(stat.id) && edge.edgetype == StatEdge.Type_Continue) { found = true; break; } } if (!found) { listEdges.Add(new FlattenStatementsHelper.Edge(nd.id, stat.id, StatEdge.Type_Continue )); } } sourcenode = node; break; } case DoStatement.Loop_For: { DirectNode nodeinit = new DirectNode(DirectNode.Node_Init, stat, stat.id + "_init" ); if (dostat.GetInitExprent() != null) { nodeinit.exprents = dostat.GetInitExprentList(); } graph.nodes.PutWithKey(nodeinit, nodeinit.id); DirectNode nodecond = new DirectNode(DirectNode.Node_Condition, stat, stat.id + "_cond" ); nodecond.exprents = dostat.GetConditionExprentList(); graph.nodes.PutWithKey(nodecond, nodecond.id); DirectNode nodeinc = new DirectNode(DirectNode.Node_Increment, stat, stat.id + "_inc" ); nodeinc.exprents = dostat.GetIncExprentList(); graph.nodes.PutWithKey(nodeinc, nodeinc.id); Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nodeinit.id, nodeinc.id }); Sharpen.Collections.Put(mapDestinationNodes, -stat.id, new string[] { nodecond.id , null }); listEdges.Add(new FlattenStatementsHelper.Edge(nodecond.id, stat.GetFirst().id, StatEdge .Type_Regular)); listEdges.Add(new FlattenStatementsHelper.Edge(nodeinit.id, -stat.id, StatEdge.Type_Regular )); listEdges.Add(new FlattenStatementsHelper.Edge(nodeinc.id, -stat.id, StatEdge.Type_Regular )); bool found_1 = false; foreach (FlattenStatementsHelper.Edge edge in listEdges) { if (edge.statid.Equals(stat.id) && edge.edgetype == StatEdge.Type_Continue) { found_1 = true; break; } } if (!found_1) { listEdges.Add(new FlattenStatementsHelper.Edge(nd.id, stat.id, StatEdge.Type_Continue )); } sourcenode = nodecond; break; } } break; } case Statement.Type_Syncronized: case Statement.Type_Switch: case Statement.Type_If: case Statement.Type_Sequence: case Statement.Type_Root: { int statsize = stat.GetStats().Count; if (stat.type == Statement.Type_Syncronized) { statsize = 2; } // exclude the handler if synchronized if (statementBreakIndex <= statsize) { List <Exprent> tailexprlst = null; switch (stat.type) { case Statement.Type_Syncronized: { tailexprlst = ((SynchronizedStatement)stat).GetHeadexprentList(); break; } case Statement.Type_Switch: { tailexprlst = ((SwitchStatement)stat).GetHeadexprentList(); break; } case Statement.Type_If: { tailexprlst = ((IfStatement)stat).GetHeadexprentList(); break; } } for (int i = statementBreakIndex; i < statsize; i++) { statEntry.statementIndex = i + 1; lstStackStatements.AddFirst(statEntry); lstStackStatements.AddFirst(new _T2081736913(this, stat.GetStats()[i], stackFinally , (i == 0 && tailexprlst != null && tailexprlst[0] != null) ? tailexprlst : null )); goto mainloop_continue; } node = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(stat.GetFirst().id)[0 ]); Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, null }); if (stat.type == Statement.Type_If && ((IfStatement)stat).iftype == IfStatement.Iftype_If) { lstSuccEdges.Add(stat.GetSuccessorEdges(Statement.Statedge_Direct_All)[0]); // exactly one edge sourcenode = tailexprlst[0] == null ? node : graph.nodes.GetWithKey(node.id + "_tail" ); } } break; } } } // no successor edges if (sourcenode != null) { if (statEntry.succEdges != null) { lstSuccEdges = statEntry.succEdges; } for (int edgeindex = statEntry.edgeIndex; edgeindex < lstSuccEdges.Count; edgeindex ++) { StatEdge edge = lstSuccEdges[edgeindex]; LinkedList <FlattenStatementsHelper.StackEntry> stack = new LinkedList <FlattenStatementsHelper.StackEntry >(stackFinally); int edgetype = edge.GetType(); Statement destination = edge.GetDestination(); DirectNode finallyShortRangeSource = sourcenode; DirectNode finallyLongRangeSource = sourcenode; Statement finallyShortRangeEntry = null; Statement finallyLongRangeEntry = null; bool isFinallyMonitorExceptionPath = false; bool isFinallyExit = false; while (true) { FlattenStatementsHelper.StackEntry entry = null; if (!(stack.Count == 0)) { entry = stack.Last(); } bool created = true; if (entry == null) { SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath); } else { CatchAllStatement catchall = entry.catchstatement; if (entry.state) { // finally handler statement if (edgetype == StatEdge.Type_Finallyexit) { Sharpen.Collections.RemoveLast(stack); destination = entry.destination; edgetype = entry.edgetype; finallyShortRangeSource = entry.finallyShortRangeSource; finallyLongRangeSource = entry.finallyLongRangeSource; finallyShortRangeEntry = entry.finallyShortRangeEntry; finallyLongRangeEntry = entry.finallyLongRangeEntry; isFinallyExit = true; isFinallyMonitorExceptionPath = (catchall.GetMonitor() != null) & entry.isFinallyExceptionPath; created = false; } else if (!catchall.ContainsStatementStrict(destination)) { Sharpen.Collections.RemoveLast(stack); created = false; } else { SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath); } } else if (!catchall.ContainsStatementStrict(destination)) { // finally protected try statement SaveEdge(sourcenode, catchall.GetHandler(), StatEdge.Type_Regular, isFinallyExit ? finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath); Sharpen.Collections.RemoveLast(stack); stack.AddLast(new FlattenStatementsHelper.StackEntry(catchall, true, edgetype, destination , catchall.GetHandler(), finallyLongRangeEntry == null ? catchall.GetHandler() : finallyLongRangeEntry, sourcenode, finallyLongRangeSource, false)); statEntry.edgeIndex = edgeindex + 1; statEntry.succEdges = lstSuccEdges; lstStackStatements.AddFirst(statEntry); lstStackStatements.AddFirst(new _T2081736913(this, catchall.GetHandler(), stack, null)); goto mainloop_continue; } else { SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath); } } if (created) { break; } } } } mainloop_continue :; } mainloop_break :; }
private static void BuildSynchronized(Statement stat) { foreach (Statement st in stat.GetStats()) { BuildSynchronized(st); } if (stat.type == Statement.Type_Sequence) { while (true) { bool found = false; List <Statement> lst = stat.GetStats(); for (int i = 0; i < lst.Count - 1; i++) { Statement current = lst[i]; // basic block if (current.IsMonitorEnter()) { Statement next = lst[i + 1]; Statement nextDirect = next; while (next.type == Statement.Type_Sequence) { next = next.GetFirst(); } if (next.type == Statement.Type_Catchall) { CatchAllStatement ca = (CatchAllStatement)next; if (ca.GetFirst().IsContainsMonitorExit() && ca.GetHandler().IsContainsMonitorExit ()) { // remove the head block from sequence current.RemoveSuccessor(current.GetSuccessorEdges(Statement.Statedge_Direct_All)[ 0]); foreach (StatEdge edge in current.GetPredecessorEdges(Statement.Statedge_Direct_All )) { current.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, nextDirect); nextDirect.AddPredecessor(edge); } stat.GetStats().RemoveWithKey(current.id); stat.SetFirst(stat.GetStats()[0]); // new statement SynchronizedStatement sync = new SynchronizedStatement(current, ca.GetFirst(), ca .GetHandler()); sync.SetAllParent(); foreach (StatEdge edge in new HashSet <StatEdge>(ca.GetLabelEdges())) { sync.AddLabeledEdge(edge); } current.AddSuccessor(new StatEdge(StatEdge.Type_Regular, current, ca.GetFirst())); ca.GetParent().ReplaceStatement(ca, sync); found = true; break; } } } } if (!found) { break; } } } }
private bool VerifyFinallyEx(ControlFlowGraph graph, CatchAllStatement fstat, FinallyProcessor.Record information) { HashSet <BasicBlock> tryBlocks = GetAllBasicBlocks(fstat.GetFirst()); HashSet <BasicBlock> catchBlocks = GetAllBasicBlocks(fstat.GetHandler()); int finallytype = information.firstCode; Dictionary <BasicBlock, bool> mapLast = information.mapLast; BasicBlock first = fstat.GetHandler().GetBasichead().GetBlock(); bool skippedFirst = false; if (finallytype == 3) { // empty finally RemoveExceptionInstructionsEx(first, 3, finallytype); if (mapLast.ContainsKey(first)) { graph.GetFinallyExits().Add(first); } return(true); } else if (first.GetSeq().Length() == 1 && finallytype > 0) { BasicBlock firstsuc = first.GetSuccs()[0]; if (catchBlocks.Contains(firstsuc)) { first = firstsuc; skippedFirst = true; } } // identify start blocks HashSet <BasicBlock> startBlocks = new HashSet <BasicBlock>(); foreach (BasicBlock block in tryBlocks) { Sharpen.Collections.AddAll(startBlocks, block.GetSuccs()); } // throw in the try body will point directly to the dummy exit // so remove dummy exit startBlocks.Remove(graph.GetLast()); startBlocks.RemoveAll(tryBlocks); List <FinallyProcessor.Area> lstAreas = new List <FinallyProcessor.Area>(); foreach (BasicBlock start in startBlocks) { FinallyProcessor.Area arr = CompareSubgraphsEx(graph, start, catchBlocks, first, finallytype, mapLast, skippedFirst); if (arr == null) { return(false); } lstAreas.Add(arr); } // try { // DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true); // } catch(Exception ex){ex.printStackTrace();} // delete areas foreach (FinallyProcessor.Area area in lstAreas) { DeleteArea(graph, area); } // try { // DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true); // } catch(Exception ex){ex.printStackTrace();} // INFO: empty basic blocks may remain in the graph! foreach (KeyValuePair <BasicBlock, bool> entry in mapLast) { BasicBlock last = entry.Key; if (entry.Value) { RemoveExceptionInstructionsEx(last, 2, finallytype); graph.GetFinallyExits().Add(last); } } RemoveExceptionInstructionsEx(fstat.GetHandler().GetBasichead().GetBlock(), 1, finallytype ); return(true); }
private bool ProcessStatementEx(StructMethod mt, RootStatement root, ControlFlowGraph graph) { int bytecode_version = mt.GetClassStruct().GetBytecodeVersion(); LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement stat = Sharpen.Collections.RemoveLast(stack); Statement parent = stat.GetParent(); if (parent != null && parent.type == Statement.Type_Catchall && stat == parent.GetFirst () && !parent.IsCopied()) { CatchAllStatement fin = (CatchAllStatement)parent; BasicBlock head = fin.GetBasichead().GetBlock(); BasicBlock handler = fin.GetHandler().GetBasichead().GetBlock(); if (catchallBlockIDs.ContainsKey(handler.id)) { } else if (finallyBlockIDs.ContainsKey(handler.id)) { // do nothing fin.SetFinally(true); int?var = finallyBlockIDs.GetOrNullable(handler.id); fin.SetMonitor(var == null ? null : new VarExprent(var.Value, VarType.Vartype_Int , varProcessor)); } else { FinallyProcessor.Record inf = GetFinallyInformation(mt, root, fin); if (inf == null) { // inconsistent finally Sharpen.Collections.Put(catchallBlockIDs, handler.id, null); } else { if (DecompilerContext.GetOption(IFernflowerPreferences.Finally_Deinline) && VerifyFinallyEx (graph, fin, inf)) { Sharpen.Collections.Put(finallyBlockIDs, handler.id, null); } else { int varindex = DecompilerContext.GetCounterContainer().GetCounterAndIncrement(CounterContainer .Var_Counter); InsertSemaphore(graph, GetAllBasicBlocks(fin.GetFirst()), head, handler, varindex , inf, bytecode_version); Sharpen.Collections.Put(finallyBlockIDs, handler.id, varindex); } DeadCodeHelper.RemoveDeadBlocks(graph); // e.g. multiple return blocks after a nested finally DeadCodeHelper.RemoveEmptyBlocks(graph); DeadCodeHelper.MergeBasicBlocks(graph); } return(true); } } Sharpen.Collections.AddAll(stack, stat.GetStats()); } return(false); }
private FinallyProcessor.Record GetFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) { Dictionary <BasicBlock, bool> mapLast = new Dictionary <BasicBlock, bool>(); BasicBlockStatement firstBlockStatement = fstat.GetHandler().GetBasichead(); BasicBlock firstBasicBlock = firstBlockStatement.GetBlock(); Instruction instrFirst = firstBasicBlock.GetInstruction(0); int firstcode = 0; switch (instrFirst.opcode) { case ICodeConstants.opc_pop: { firstcode = 1; break; } case ICodeConstants.opc_astore: { firstcode = 2; break; } } ExprProcessor proc = new ExprProcessor(methodDescriptor, varProcessor); proc.ProcessStatement(root, mt.GetClassStruct()); SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); ssa.SplitVariables(root, mt); List <Exprent> lstExprents = firstBlockStatement.GetExprents(); VarVersionPair varpaar = new VarVersionPair((VarExprent)((AssignmentExprent)lstExprents [firstcode == 2 ? 1 : 0]).GetLeft()); FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.BuildDirectGraph(root); LinkedList <DirectNode> stack = new LinkedList <DirectNode>(); stack.AddLast(dgraph.first); HashSet <DirectNode> setVisited = new HashSet <DirectNode>(); while (!(stack.Count == 0)) { DirectNode node = Sharpen.Collections.RemoveFirst(stack); if (setVisited.Contains(node)) { continue; } setVisited.Add(node); BasicBlockStatement blockStatement = null; if (node.block != null) { blockStatement = node.block; } else if (node.preds.Count == 1) { blockStatement = node.preds[0].block; } bool isTrueExit = true; if (firstcode != 1) { isTrueExit = false; for (int i = 0; i < node.exprents.Count; i++) { Exprent exprent = node.exprents[i]; if (firstcode == 0) { List <Exprent> lst = exprent.GetAllExprents(); lst.Add(exprent); bool found = false; foreach (Exprent expr in lst) { if (expr.type == Exprent.Exprent_Var && new VarVersionPair((VarExprent)expr).Equals (varpaar)) { found = true; break; } } if (found) { found = false; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)exprent; if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent .Exprent_Var) { found = true; } } if (!found) { return(null); } else { isTrueExit = true; } } } else if (firstcode == 2) { // search for a load instruction if (exprent.type == Exprent.Exprent_Assignment) { AssignmentExprent assexpr = (AssignmentExprent)exprent; if (assexpr.GetRight().type == Exprent.Exprent_Var && new VarVersionPair((VarExprent )assexpr.GetRight()).Equals(varpaar)) { Exprent next = null; if (i == node.exprents.Count - 1) { if (node.succs.Count == 1) { DirectNode nd = node.succs[0]; if (!(nd.exprents.Count == 0)) { next = nd.exprents[0]; } } } else { next = node.exprents[i + 1]; } bool found = false; if (next != null && next.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)next; if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent .Exprent_Var && assexpr.GetLeft().Equals(exexpr.GetValue())) { found = true; } } if (!found) { return(null); } else { isTrueExit = true; } } } } } } // find finally exits if (blockStatement != null && blockStatement.GetBlock() != null) { Statement handler = fstat.GetHandler(); foreach (StatEdge edge in blockStatement.GetSuccessorEdges(Statement.Statedge_Direct_All )) { if (edge.GetType() != StatEdge.Type_Regular && handler.ContainsStatement(blockStatement ) && !handler.ContainsStatement(edge.GetDestination())) { bool?existingFlag = mapLast.GetOrNullable(blockStatement.GetBlock()); // note: the dummy node is also processed! if (existingFlag == null || !existingFlag.Value) { Sharpen.Collections.Put(mapLast, blockStatement.GetBlock(), isTrueExit); break; } } } } Sharpen.Collections.AddAll(stack, node.succs); } // empty finally block? if (fstat.GetHandler().type == Statement.Type_Basicblock) { bool isEmpty = false; bool isFirstLast = mapLast.ContainsKey(firstBasicBlock); InstructionSequence seq = firstBasicBlock.GetSeq(); switch (firstcode) { case 0: { isEmpty = isFirstLast && seq.Length() == 1; break; } case 1: { isEmpty = seq.Length() == 1; break; } case 2: { isEmpty = isFirstLast ? seq.Length() == 3 : seq.Length() == 1; break; } } if (isEmpty) { firstcode = 3; } } return(new FinallyProcessor.Record(firstcode, mapLast)); }
private HashSet <int> InitStatement(Statement stat) { Dictionary <int, int> mapCount = new Dictionary <int, int>(); List <VarExprent> condlst; if (stat.GetExprents() == null) { // recurse on children statements List <int> childVars = new List <int>(); List <Exprent> currVars = new List <Exprent>(); foreach (object obj in stat.GetSequentialObjects()) { if (obj is Statement) { Statement st = (Statement)obj; Sharpen.Collections.AddAll(childVars, InitStatement(st)); if (st.type == DoStatement.Type_Do) { DoStatement dost = (DoStatement)st; if (dost.GetLooptype() != DoStatement.Loop_For && dost.GetLooptype() != DoStatement .Loop_Do) { currVars.Add(dost.GetConditionExprent()); } } else if (st.type == DoStatement.Type_Catchall) { CatchAllStatement fin = (CatchAllStatement)st; if (fin.IsFinally() && fin.GetMonitor() != null) { currVars.Add(fin.GetMonitor()); } } } else if (obj is Exprent) { currVars.Add((Exprent)obj); } } // children statements foreach (int index in childVars) { int?count = mapCount.GetOrNullable(index); if (count == null) { count = 0; } Sharpen.Collections.Put(mapCount, index, count.Value + 1); } condlst = GetAllVars(currVars); } else { condlst = GetAllVars(stat.GetExprents()); } // this statement foreach (VarExprent var in condlst) { Sharpen.Collections.Put(mapCount, var.GetIndex(), 2); } HashSet <int> set = new HashSet <int>(mapCount.Keys); // put all variables defined in this statement into the set foreach (KeyValuePair <int, int> en in mapCount) { if (en.Value > 1) { Sharpen.Collections.Put(mapVarDefStatements, en.Key, stat); } } Sharpen.Collections.Put(mapStatementVars, stat.id, set); return(set); }