private void PatchValidEndStateProperty(Class methodClass, List<BasicBlock> basicBlocks)
{
Property validEndStateProperty = (Property)Templates.GetMemberByName(methodClass.Members, "ValidEndState");
Method validEndStateMethod = validEndStateProperty.Getter;
Debug.Assert(validEndStateMethod.Body.Statements[0] is System.Compiler.Switch);
System.Compiler.Switch switchStmt = (System.Compiler.Switch)validEndStateMethod.Body.Statements[0];
foreach (BasicBlock block in basicBlocks)
{
if (block.selectStmt != null && block.selectStmt.validEndState)
{
SwitchCase newCase;
newCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("ValidEndStateSwitch")).Cases[0];
Replacer.Replace(newCase, "_BlockName", new Identifier(block.Name));
switchStmt.Cases.Add(newCase);
//
// Now check for blocks that flow atomically into this one and add cases for them
// as well. This can happen when the target of a "goto" is a label preceding a
// select statement.
//
foreach (BasicBlock previousBlock in basicBlocks)
{
if (previousBlock.UnconditionalTarget == block && previousBlock.ConditionalTarget == null &&
previousBlock.Statement == null && previousBlock.MiddleOfTransition)
{
newCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("RelatedSwitchSelect")).Cases[0];
Replacer.Replace(newCase, "_BlockName", new Identifier(previousBlock.Name));
Replacer.Replace(newCase, "_TargetName", new Identifier(block.Name));
switchStmt.Cases.Add(newCase);
}
}
}
}
}