/// <summary> /// Generates the finally block. /// </summary> /// <remarks> /// Since the condition block and the dispose invocation block should have a common successor, a new EmptyBlockLogicalConstruct /// is added to the logical tree. /// </remarks> /// <returns></returns> private BlockLogicalConstruct GenerateFinallyBlock() { CFGBlockLogicalConstruct finallySuccessor = ProcessFinallyNode(finallyEntryBlock, disposeCallBlock); finallySuccessor.RemoveFromPredecessors(conditionBlock); conditionBlock.RemoveFromSuccessors(finallySuccessor); EmptyBlockLogicalConstruct emptyCommonNode = new EmptyBlockLogicalConstruct(++logicalContext.MaxBlockIndex); emptyCommonNode.AddToPredecessors(disposeCallBlock); emptyCommonNode.AddToPredecessors(conditionBlock); disposeCallBlock.AddToSuccessors(emptyCommonNode); conditionBlock.AddToSuccessors(emptyCommonNode); emptyCommonNode.Parent = finallyEntryBlock.Parent; emptyCommonNode.Parent.Children.Add(emptyCommonNode); for (int i = 0; i < conditionBlock.TheBlock.Successors.Length; i++) { if (conditionBlock.TheBlock.Successors[i] == finallySuccessor.TheBlock) { conditionBlock.TheBlock.Successors[i] = null; } } finallyBlocks.Add(emptyCommonNode); return(new BlockLogicalConstruct(finallyEntryBlock, finallyBlocks)); }
/// <summary> /// Maps each CFG instruction blocks to a new CFGBlockLogicalConstruct, creating the relations between the new constructs and updating the logical builder /// context. /// </summary> private void MapBlocks() { //The new CFG logical constructs hold the block that they represent, and all the expressions that are for this block. foreach (InstructionBlock instructionBlock in logicalBuilderContext.CFG.Blocks) { int offset = instructionBlock.First.Offset; logicalBuilderContext.CFGBlockToLogicalConstructMap.Add(instructionBlock, new CFGBlockLogicalConstruct[] { new CFGBlockLogicalConstruct(instructionBlock, methodContext.Expressions.BlockExpressions[offset]) }); } //After creating all the blocks, we can add the relations between them. foreach (InstructionBlock instructionBlock in logicalBuilderContext.CFG.Blocks) { CFGBlockLogicalConstruct logicalConstruct = logicalBuilderContext.CFGBlockToLogicalConstructMap[instructionBlock][0]; foreach (InstructionBlock successorBlock in instructionBlock.Successors) { CFGBlockLogicalConstruct successorConstruct = logicalBuilderContext.CFGBlockToLogicalConstructMap[successorBlock][0]; logicalConstruct.AddToSuccessors(successorConstruct); successorConstruct.AddToPredecessors(logicalConstruct); } } }