/// <summary> /// Constructs a using block. /// </summary> /// <param name="stmtList">List of statements</param> /// <param name="successor">ControlFlowNode</param> /// <param name="innerLoopHead">LoopHeadControlFlowNode</param> private void ConstructUsingBlock(List <StatementSyntax> stmtList, ControlFlowNode successor, LoopHeadControlFlowNode innerLoopHead) { var usingStmt = stmtList[0] as UsingStatementSyntax; stmtList.RemoveAt(0); var usingNode = new ControlFlowNode(this.Graph, this.Summary); if (usingStmt.Declaration != null) { usingNode.Statements.Add(Statement.Create(usingStmt.Declaration, usingNode, this.Summary)); } else { usingNode.Statements.Add(Statement.Create(usingStmt.Expression, usingNode, this.Summary)); } var afterUsingNode = new ControlFlowNode(this.Graph, this.Summary); afterUsingNode.Construct(stmtList, successor, innerLoopHead); var bodyNode = new ControlFlowNode(this.Graph, this.Summary); bodyNode.Construct(this.GetStatements(usingStmt.Statement), afterUsingNode, innerLoopHead); this.ISuccessors.Add(usingNode); usingNode.IPredecessors.Add(this); usingNode.ISuccessors.Add(bodyNode); bodyNode.IPredecessors.Add(usingNode); }
/// <summary> /// Constructs a switch block. /// </summary> /// <param name="stmtList">List of statements</param> /// <param name="successor">ControlFlowNode</param> /// <param name="innerLoopHead">LoopHeadControlFlowNode</param> private void ConstructSwitchBlock(List <StatementSyntax> stmtList, ControlFlowNode successor, LoopHeadControlFlowNode innerLoopHead) { var switchStmt = stmtList[0] as SwitchStatementSyntax; stmtList.RemoveAt(0); var switchNode = new ControlFlowNode(this.Graph, this.Summary); switchNode.Statements.Add(Statement.Create(switchStmt.Expression, switchNode, this.Summary)); var afterSwitchNode = new ControlFlowNode(this.Graph, this.Summary); afterSwitchNode.Construct(stmtList, successor, innerLoopHead); foreach (var section in switchStmt.Sections) { var sectionNode = new ControlFlowNode(this.Graph, this.Summary); sectionNode.Construct(section.Statements.ToList(), afterSwitchNode, null); switchNode.ISuccessors.Add(sectionNode); sectionNode.IPredecessors.Add(switchNode); } this.ISuccessors.Add(switchNode); switchNode.IPredecessors.Add(this); }
/// <summary> /// Constructs a do-while loop. /// </summary> /// <param name="stmtList">List of statements</param> /// <param name="successor">ControlFlowNode</param> /// <param name="innerLoopHead">LoopHeadControlFlowNode</param> private void ConstructDoWhileLoop(List <StatementSyntax> stmtList, ControlFlowNode successor, LoopHeadControlFlowNode innerLoopHead) { var loopHeadStmt = stmtList[0] as DoStatementSyntax; stmtList.RemoveAt(0); var falseNode = new ControlFlowNode(this.Graph, this.Summary); var trueNode = new ControlFlowNode(this.Graph, this.Summary); var loopHeadNode = new LoopHeadControlFlowNode(this.Graph, this.Summary, falseNode); trueNode.Construct(this.GetStatements(loopHeadStmt.Statement), loopHeadNode, loopHeadNode); loopHeadNode.Statements.Add(Statement.Create(loopHeadStmt.Condition, loopHeadNode, this.Summary)); falseNode.Construct(stmtList, successor, innerLoopHead); this.ISuccessors.Add(trueNode); trueNode.IPredecessors.Add(this); loopHeadNode.ISuccessors.Add(falseNode); falseNode.IPredecessors.Add(loopHeadNode); loopHeadNode.ISuccessors.Add(trueNode); trueNode.IPredecessors.Add(loopHeadNode); }
/// <summary> /// Creates the control-flow graph nodes of the /// specified method summary. /// </summary> /// <param name="cfg">ControlFlowGraph</param> /// <param name="summary">MethodSummary</param> /// <returns>IControlFlowNode</returns> internal static IControlFlowNode Create(ControlFlowGraph cfg, MethodSummary summary) { var entryNode = new ControlFlowNode(cfg, summary); entryNode.Statements.Add(Statement.Create(summary.Method.ParameterList, entryNode, summary)); entryNode.Construct(entryNode.GetStatements(summary.Method.Body), null, null); return(entryNode); }
/// <summary> /// Constructs an if-then-else branch. /// </summary> /// <param name="stmtList">List of statements</param> /// <param name="successor">ControlFlowNode</param> /// <param name="innerLoopHead">LoopHeadControlFlowNode</param> private void ConstructIfThenElseBranch(List <StatementSyntax> stmtList, ControlFlowNode successor, LoopHeadControlFlowNode innerLoopHead) { var ifStmt = stmtList[0] as IfStatementSyntax; stmtList.RemoveAt(0); var ifBranchNode = new ControlFlowNode(this.Graph, this.Summary); ifBranchNode.Statements.Add(Statement.Create(ifStmt.Condition, ifBranchNode, this.Summary)); this.ISuccessors.Add(ifBranchNode); ifBranchNode.IPredecessors.Add(this); ControlFlowNode elseBranchNode = null; ControlFlowNode falseNode = null; if (ifStmt.Else != null) { elseBranchNode = new ControlFlowNode(this.Graph, this.Summary); falseNode = new ControlFlowNode(this.Graph, this.Summary); falseNode.Construct(stmtList, successor, innerLoopHead); elseBranchNode.Construct(this.GetStatements(ifStmt.Else.Statement), falseNode, innerLoopHead); ifBranchNode.ISuccessors.Add(elseBranchNode); elseBranchNode.IPredecessors.Add(ifBranchNode); } else { falseNode = new ControlFlowNode(this.Graph, this.Summary); falseNode.Construct(stmtList, successor, innerLoopHead); ifBranchNode.ISuccessors.Add(falseNode); falseNode.IPredecessors.Add(ifBranchNode); } var trueNode = new ControlFlowNode(this.Graph, this.Summary); trueNode.Construct(this.GetStatements(ifStmt.Statement), falseNode, innerLoopHead); ifBranchNode.ISuccessors.Add(trueNode); trueNode.IPredecessors.Add(ifBranchNode); }
/// <summary> /// Constructs a loop from the specified loop guard and body. /// </summary> /// <param name="loopGuard">ExpressionSyntax</param> /// <param name="loopBody">StatementSyntax</param> /// <param name="stmtList">List of statements</param> /// <param name="successor">ControlFlowNode</param> /// <param name="innerLoopHead">LoopHeadControlFlowNode</param> private void ConstructLoop(ExpressionSyntax loopGuard, StatementSyntax loopBody, List <StatementSyntax> stmtList, ControlFlowNode successor, LoopHeadControlFlowNode innerLoopHead) { var falseNode = new ControlFlowNode(this.Graph, this.Summary); var trueNode = new ControlFlowNode(this.Graph, this.Summary); var loopHeadNode = new LoopHeadControlFlowNode(this.Graph, this.Summary, falseNode); loopHeadNode.Statements.Add(Statement.Create(loopGuard, loopHeadNode, this.Summary)); falseNode.Construct(stmtList, successor, innerLoopHead); trueNode.Construct(this.GetStatements(loopBody), loopHeadNode, loopHeadNode); this.ISuccessors.Add(loopHeadNode); loopHeadNode.IPredecessors.Add(this); loopHeadNode.ISuccessors.Add(falseNode); falseNode.IPredecessors.Add(loopHeadNode); loopHeadNode.ISuccessors.Add(trueNode); trueNode.IPredecessors.Add(loopHeadNode); }
/// <summary> /// Constructs the control-flow graph of the node. /// </summary> /// <param name="stmtList">List of statements</param> /// <param name="successor">ControlFlowNode</param> /// <param name="innerLoopHead">LoopHeadControlFlowNode</param> private void Construct(List <StatementSyntax> stmtList, ControlFlowNode successor, LoopHeadControlFlowNode innerLoopHead) { while (stmtList.Count > 0) { if (stmtList[0] is IfStatementSyntax) { this.ConstructIfThenElseBranch(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is ForStatementSyntax) { this.ConstructForLoop(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is WhileStatementSyntax) { this.ConstructWhileLoop(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is ForEachStatementSyntax) { this.ConstructForeachLoop(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is DoStatementSyntax) { this.ConstructDoWhileLoop(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is SwitchStatementSyntax) { this.ConstructSwitchBlock(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is UsingStatementSyntax) { this.ConstructUsingBlock(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is BlockSyntax) { this.ConstructNakedCodeBlock(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is ReturnStatementSyntax) { this.Statements.Add(Statement.Create(stmtList[0], this, this.Summary)); stmtList.RemoveAt(0); return; } else if (stmtList[0] is ContinueStatementSyntax) { stmtList.RemoveAt(0); this.ISuccessors.Add(innerLoopHead); innerLoopHead.IPredecessors.Add(this); return; } else if (stmtList[0] is BreakStatementSyntax) { stmtList.RemoveAt(0); if (innerLoopHead != null) { this.ISuccessors.Add(innerLoopHead.LoopExitNode); innerLoopHead.LoopExitNode.IPredecessors.Add(this); return; } else { stmtList.Clear(); } } else if (stmtList[0] is ExpressionStatementSyntax || stmtList[0] is LocalDeclarationStatementSyntax) { this.Statements.Add(Statement.Create(stmtList[0], this, this.Summary)); stmtList.RemoveAt(0); } // NOTE: exceptions not supported yet else if (stmtList[0] is ThrowStatementSyntax) { this.Statements.Add(Statement.Create(stmtList[0], this, this.Summary)); stmtList.RemoveAt(0); } else if (stmtList[0] is EmptyStatementSyntax) { stmtList.RemoveAt(0); } else { throw new NotSupportedException($"CFG construction for statement '{stmtList[0]}' " + "is not yet supported. Please report this to the developers."); } } if (stmtList.Count == 0 && successor != null) { this.ISuccessors.Add(successor); successor.IPredecessors.Add(this); } }