// For the first assignment to a local variable in a block before a control statement is hit, // if the local variable is not mentioned previously, we turn this assignment into a local declaration. private void AddDeclarationsWithInitialValues(IEnumerable<ILocalDefinition> localVariables, BasicBlock block) { List<ILocalDefinition> topLevelLocals = new List<ILocalDefinition>(localVariables); List<ILocalDefinition> localsMet = new List<ILocalDefinition>(); for (int i = 0; i < block.Statements.Count; i++) { if (topLevelLocals.Count == 0) break; IExpressionStatement expressionStatement = block.Statements[i] as IExpressionStatement; if (expressionStatement != null) { IAssignment assignment = expressionStatement.Expression as IAssignment; if (assignment != null) { ILocalDefinition localDef = assignment.Target.Definition as ILocalDefinition; if (localDef != null && topLevelLocals.Contains(localDef) && !localsMet.Contains(localDef) && !this.declaredLocals.ContainsKey(localDef)) { LocalDeclarationStatement localDecl = new LocalDeclarationStatement() { LocalVariable = localDef, InitialValue = assignment.Source, Locations = new List<ILocation>(expressionStatement.Locations), }; this.declaredLocals.Add(localDef, true); block.Statements[i] = localDecl; topLevelLocals.Remove(localDef); localsMet.Add(localDef); } } } LocalFinder finder = new LocalFinder(); finder.Traverse(block.Statements[i]); foreach (ILocalDefinition local in finder.FoundLocals) { if (!localsMet.Contains(local)) localsMet.Add(local); } //Once we see a statement that can transfer control somewhere else, we //no longer know that any subsequent assignment dominates all references //and hence cannot postpone adding the declaration until we can unify it with the assignment. IGotoStatement gotoStatement = block.Statements[i] as IGotoStatement; if (gotoStatement != null) break; IConditionalStatement conditionalStatement = block.Statements[i] as IConditionalStatement; if (conditionalStatement != null) break; ISwitchStatement switchStatement = block.Statements[i] as ISwitchStatement; if (switchStatement != null) break; IForEachStatement foreachStatement = block.Statements[i] as IForEachStatement; if (foreachStatement != null) break; IForStatement forStatement = block.Statements[i] as IForStatement; if (forStatement != null) break; ITryCatchFinallyStatement tryStatement = block.Statements[i] as ITryCatchFinallyStatement; if (tryStatement != null) break; } }
public static bool LocalOccursIn(IStatement s, ILocalDefinition local) { Contract.Requires(s != null); Contract.Requires(local != null); var lf = new LocalFinder(local); lf.Traverse(s); return lf.found; }