public void RaiseException(Bpl.Expr e)
 {
     Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
     RaiseExceptionHelper(builder);
     Bpl.IfCmd ifCmd = new Bpl.IfCmd(Bpl.Token.NoToken, e, builder.Collect(Bpl.Token.NoToken), null, null);
     StmtBuilder.Add(ifCmd);
 }
Beispiel #2
0
        public void PropagateExceptionIfAny()
        {
            var cond      = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef));
            var traverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);

            traverser.PropagateException();
            Bpl.IfCmd ifCmd = new Bpl.IfCmd(Bpl.Token.NoToken, cond, traverser.StmtBuilder.Collect(Bpl.Token.NoToken), null, null);
            StmtBuilder.Add(ifCmd);
        }
        public override void TraverseChildren(ISwitchStatement switchStatement)
        {
            var eTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);

            eTraverser.Traverse(switchStatement.Expression);
            var conditionExpr = eTraverser.TranslatedExpressions.Pop();

            // Can't depend on default case existing or its index in the collection.
            var         switchCases = new List <ISwitchCase>();
            ISwitchCase defaultCase = null;

            foreach (var switchCase in switchStatement.Cases)
            {
                if (switchCase.IsDefault)
                {
                    defaultCase = switchCase;
                }
                else
                {
                    switchCases.Add(switchCase);
                }
            }
            Bpl.StmtList defaultStmts = null;
            if (defaultCase != null)
            {
                var defaultBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
                defaultBodyTraverser.Traverse(defaultCase.Body);
                defaultStmts = defaultBodyTraverser.StmtBuilder.Collect(defaultCase.Token());
            }

            Bpl.IfCmd ifCmd = null;

            for (int i = switchCases.Count - 1; 0 <= i; i--)
            {
                var switchCase = switchCases[i];

                var scTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
                scTraverser.Traverse(switchCase.Expression);
                var scConditionExpr = scTraverser.TranslatedExpressions.Pop();
                var condition       = Bpl.Expr.Eq(conditionExpr, scConditionExpr);

                var scBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
                scBodyTraverser.Traverse(switchCase.Body);

                ifCmd = new Bpl.IfCmd(switchCase.Token(),
                                      condition,
                                      scBodyTraverser.StmtBuilder.Collect(switchCase.Token()),
                                      ifCmd,
                                      defaultStmts);
                defaultStmts = null; // default body goes only into the innermost if-then-else
            }
            StmtBuilder.Add(ifCmd);
        }
        /// <summary>
        ///
        /// </summary>
        /// <remarks>(mschaef) Works, but still a stub</remarks>
        /// <param name="conditionalStatement"></param>
        public override void TraverseChildren(IConditionalStatement conditionalStatement)
        {
            StatementTraverser  thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
            StatementTraverser  elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
            ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);

            if (this.sink.Options.instrumentBranches)
            {
                var tok = conditionalStatement.Token();
                thenTraverser.StmtBuilder.Add(
                    new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List <object> {
                    Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies)
                }, null))
                    );
                elseTraverser.StmtBuilder.Add(
                    new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List <object> {
                    Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies)
                }, null))
                    );
            }

            condTraverser.Traverse(conditionalStatement.Condition);
            thenTraverser.Traverse(conditionalStatement.TrueBranch);
            elseTraverser.Traverse(conditionalStatement.FalseBranch);

            Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop();
            Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type);
            if (conditionType == this.sink.Heap.RefType)
            {
                conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef));
            }
            else if (conditionType == Bpl.Type.Int)
            {
                conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0));
            }
            else
            {
                System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool);
            }

            Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditionalStatement.Token(),
                                            conditionExpr,
                                            thenTraverser.StmtBuilder.Collect(conditionalStatement.TrueBranch.Token()),
                                            null,
                                            elseTraverser.StmtBuilder.Collect(conditionalStatement.FalseBranch.Token())
                                            );

            StmtBuilder.Add(ifcmd);
        }
Beispiel #5
0
        private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates)
        {
            Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true);
            Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true);
            Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false);

            Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a);
            Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b);
            Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c);

            Bpl.Procedure proc = new Bpl.Procedure(
                Bpl.Token.NoToken,
                sink.DelegateRemove(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { a, b }),
                new List <Bpl.Variable>(new Bpl.Variable[] { c }),
                new List <Bpl.Requires>(),
                new List <Bpl.IdentifierExpr>(),
                new List <Bpl.Ensures>());
            proc.AddAttribute("inline", Bpl.Expr.Literal(1));
            sink.TranslatedProgram.AddTopLevelDeclaration(proc);

            Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder();
            stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { cExpr })));
            foreach (IMethodDefinition defn in delegates)
            {
                Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr))))));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr))));
                stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr))));
            }
            Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef);
            Bpl.IfCmd          ifCmd    = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken));
            ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd);

            Bpl.Implementation impl = new Bpl.Implementation(
                Bpl.Token.NoToken,
                sink.DelegateRemove(type),
                new List <Bpl.TypeVariable>(),
                new List <Bpl.Variable>(new Bpl.Variable[] { a, b }),
                new List <Bpl.Variable>(new Bpl.Variable[] { c }),
                new List <Bpl.Variable>(),
                BuildStmtList(ifCmd)
                );
            impl.AddAttribute("inline", Bpl.Expr.Literal(1));
            impl.Proc = proc;
            sink.TranslatedProgram.AddTopLevelDeclaration(impl);
        }
        public void GenerateDispatchContinuation(ITryCatchFinallyStatement tryCatchFinallyStatement)
        {
            string continuationLabel = this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement);

            Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(true),
                                                TranslationHelper.BuildStmtList(new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { continuationLabel }))), null, null);
            List <string> edges = sink.EscapingEdges(tryCatchFinallyStatement);

            Bpl.IdentifierExpr labelExpr = Bpl.Expr.Ident(this.sink.LabelVariable);
            for (int i = 0; i < edges.Count; i++)
            {
                string      label      = edges[i];
                Bpl.GotoCmd gotoCmd    = new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { label }));
                Bpl.Expr    targetExpr = Bpl.Expr.Literal(i);
                elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, labelExpr, targetExpr),
                                          TranslationHelper.BuildStmtList(gotoCmd), elseIfCmd, null);
            }
            this.StmtBuilder.Add(elseIfCmd);
        }
        public override void TraverseChildren(ITryCatchFinallyStatement tryCatchFinallyStatement)
        {
            if (this.sink.Options.modelExceptions == 0)
            {
                this.Traverse(tryCatchFinallyStatement.TryBody);
                if (tryCatchFinallyStatement.FinallyBody != null)
                {
                    this.Traverse(tryCatchFinallyStatement.FinallyBody);
                }
                return;
            }

            this.sink.nestedTryCatchFinallyStatements.Add(new Tuple <ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InTry));
            this.Traverse(tryCatchFinallyStatement.TryBody);
            StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
            StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement) })));
            this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);

            StmtBuilder.AddLabelCmd(this.sink.FindOrCreateCatchLabel(tryCatchFinallyStatement));
            StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LocalExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)));
            StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef)));
            List <Bpl.StmtList> catchStatements = new List <Bpl.StmtList>();
            List <Bpl.Expr>     typeReferences  = new List <Bpl.Expr>();

            this.sink.nestedTryCatchFinallyStatements.Add(new Tuple <ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InCatch));
            foreach (ICatchClause catchClause in tryCatchFinallyStatement.CatchClauses)
            {
                typeReferences.Insert(0, this.sink.FindOrCreateTypeReference(catchClause.ExceptionType, true));
                StatementTraverser catchTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
                if (catchClause.ExceptionContainer != Dummy.LocalVariable)
                {
                    Bpl.Variable catchClauseVariable = this.sink.FindOrCreateLocalVariable(catchClause.ExceptionContainer);
                    catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(catchClauseVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
                }
                catchTraverser.Traverse(catchClause.Body);
                catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
                catchTraverser.StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement) })));
                catchStatements.Insert(0, catchTraverser.StmtBuilder.Collect(catchClause.Token()));
            }
            Bpl.IfCmd elseIfCmd        = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(false), TranslationHelper.BuildStmtList(new Bpl.ReturnCmd(Bpl.Token.NoToken)), null, null);
            Bpl.Expr  dynTypeOfOperand = this.sink.Heap.DynamicType(Bpl.Expr.Ident(this.sink.LocalExcVariable));
            for (int i = 0; i < catchStatements.Count; i++)
            {
                Bpl.Expr expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Subtype), new List <Bpl.Expr>(new Bpl.Expr[] { dynTypeOfOperand, typeReferences[i] }));
                elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, expr, catchStatements[i], elseIfCmd, null);
            }
            this.StmtBuilder.Add(elseIfCmd);
            this.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
            RaiseException();
            this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);

            this.StmtBuilder.AddLabelCmd(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement));
            if (tryCatchFinallyStatement.FinallyBody != null)
            {
                this.sink.nestedTryCatchFinallyStatements.Add(new Tuple <ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InFinally));
                Bpl.Variable savedExcVariable   = this.sink.CreateFreshLocal(this.sink.Heap.RefType);
                Bpl.Variable savedLabelVariable = this.sink.CreateFreshLocal(Bpl.Type.Int);
                StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)));
                StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedLabelVariable), Bpl.Expr.Ident(this.sink.LabelVariable)));
                this.Traverse(tryCatchFinallyStatement.FinallyBody);
                StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(savedExcVariable)));
                StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Ident(savedLabelVariable)));
                this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);
            }
            GenerateDispatchContinuation(tryCatchFinallyStatement);
            StmtBuilder.AddLabelCmd(this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement));
            Bpl.Expr raiseExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef));
            RaiseException(raiseExpr);
        }
        public Bpl.Procedure addHandlerStubCaller(Sink sink, IMethodDefinition def)
        {
            MethodBody       callerBody = new MethodBody();
            MethodDefinition callerDef  = new MethodDefinition()
            {
                InternFactory            = (def as MethodDefinition).InternFactory,
                ContainingTypeDefinition = def.ContainingTypeDefinition,
                IsStatic = true,
                Name     = sink.host.NameTable.GetNameFor("BOOGIE_STUB_CALLER_" + def.Name.Value),
                Type     = sink.host.PlatformType.SystemVoid,
                Body     = callerBody,
            };

            callerBody.MethodDefinition = callerDef;
            Sink.ProcedureInfo procInfo   = sink.FindOrCreateProcedure(def);
            Sink.ProcedureInfo callerInfo = sink.FindOrCreateProcedure(callerDef);

            Bpl.LocalVariable[]  localVars = new Bpl.LocalVariable[procInfo.Decl.InParams.Count];
            Bpl.IdentifierExpr[] varExpr   = new Bpl.IdentifierExpr[procInfo.Decl.InParams.Count];
            for (int i = 0; i < procInfo.Decl.InParams.Count; i++)
            {
                Bpl.LocalVariable loc = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                              new Bpl.TypedIdent(Bpl.Token.NoToken, TranslationHelper.GenerateTempVarName(),
                                                                                 procInfo.Decl.InParams[i].TypedIdent.Type));
                localVars[i] = loc;
                varExpr[i]   = new Bpl.IdentifierExpr(Bpl.Token.NoToken, loc);
            }

            Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
            builder.Add(getResetNavigationCheck(sink));

            string pageXaml = PhoneCodeHelper.instance().PhonePlugin.getXAMLForPage(def.ContainingTypeDefinition.ToString());

            Bpl.Variable boogieCurrentURI = sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition);
            Bpl.Constant boogieXamlConstant;
            if (pageXaml != null)
            {
                boogieXamlConstant = sink.FindOrCreateConstant(pageXaml);
            }
            else
            {
                boogieXamlConstant = null;
            }
            // NAVIGATION TODO: For now just assume we are in this page to be able to call the handler, this is NOT true for any handler
            // NAVIGATION TODO: ie, a network event handler
            if (boogieXamlConstant != null)
            {
                Bpl.AssumeCmd assumeCurrentPage =
                    new Bpl.AssumeCmd(Bpl.Token.NoToken,
                                      Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                      new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
                builder.Add(assumeCurrentPage);
            }

            // NAVIGATION TODO: have to do the pair generation all in one go instead of having different files that need to be sed'ed
            boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER);
            Bpl.AssumeCmd assumeStartPage = new Bpl.AssumeCmd(Bpl.Token.NoToken,
                                                              Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                                              new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
            builder.Add(assumeStartPage);
            builder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new List <Bpl.Expr>(varExpr), new List <Bpl.IdentifierExpr>()));
            boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER);
            Bpl.AssertCmd assertEndPage = new Bpl.AssertCmd(Bpl.Token.NoToken,
                                                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));

            Bpl.Expr            guard       = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool));
            Bpl.StmtListBuilder thenBuilder = new Bpl.StmtListBuilder();
            thenBuilder.Add(assertEndPage);
            Bpl.IfCmd ifNavigated = new Bpl.IfCmd(Bpl.Token.NoToken, guard, thenBuilder.Collect(Bpl.Token.NoToken), null, new Bpl.StmtListBuilder().Collect(Bpl.Token.NoToken));

            builder.Add(ifNavigated);
            Bpl.Implementation impl =
                new Bpl.Implementation(Bpl.Token.NoToken, callerInfo.Decl.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(),
                                       new List <Bpl.Variable>(), new List <Bpl.Variable>(localVars), builder.Collect(Bpl.Token.NoToken), null, new Bpl.Errors());

            sink.TranslatedProgram.AddTopLevelDeclaration(impl);
            return(impl.Proc);
        }
Beispiel #9
0
 private static Bpl.IfCmd BuildIfCmd(Bpl.Expr b, Bpl.Cmd cmd, Bpl.IfCmd ifCmd)
 {
     Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder();
     ifStmtBuilder.Add(cmd);
     return(new Bpl.IfCmd(b.tok, b, ifStmtBuilder.Collect(b.tok), ifCmd, null));
 }
Beispiel #10
0
 public IfCmd(IToken/*!*/ tok, Expr guard, StmtList/*!*/ thn, IfCmd elseIf, StmtList elseBlock)
     : base(tok)
 {
     Contract.Requires(tok != null);
       Contract.Requires(thn != null);
       Contract.Requires(elseIf == null || elseBlock == null);
       this.Guard = guard;
       this.thn = thn;
       this.elseIf = elseIf;
       this.elseBlock = elseBlock;
 }
    public override void TraverseChildren(ITryCatchFinallyStatement tryCatchFinallyStatement) {

      if (this.sink.Options.modelExceptions == 0) {
        this.Traverse(tryCatchFinallyStatement.TryBody);
        if (tryCatchFinallyStatement.FinallyBody != null)
          this.Traverse(tryCatchFinallyStatement.FinallyBody);
        return;
      }

      this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InTry));
      this.Traverse(tryCatchFinallyStatement.TryBody);
      StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
      StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List<string>(new string[] {this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement)})));
      this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);

      StmtBuilder.AddLabelCmd(this.sink.FindOrCreateCatchLabel(tryCatchFinallyStatement));
      StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LocalExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)));
      StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef)));
      List<Bpl.StmtList> catchStatements = new List<Bpl.StmtList>();
      List<Bpl.Expr> typeReferences = new List<Bpl.Expr>();
      this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InCatch));
      foreach (ICatchClause catchClause in tryCatchFinallyStatement.CatchClauses) {
        typeReferences.Insert(0, this.sink.FindOrCreateTypeReference(catchClause.ExceptionType, true));
        StatementTraverser catchTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
        if (catchClause.ExceptionContainer != Dummy.LocalVariable) {
          Bpl.Variable catchClauseVariable = this.sink.FindOrCreateLocalVariable(catchClause.ExceptionContainer);
          catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(catchClauseVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
        }
        catchTraverser.Traverse(catchClause.Body);
        catchTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Literal(-1)));
        catchTraverser.StmtBuilder.Add(new Bpl.GotoCmd(Bpl.Token.NoToken, new List<string>(new string[] {this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement)})));
        catchStatements.Insert(0, catchTraverser.StmtBuilder.Collect(catchClause.Token()));
      }
      Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(false), TranslationHelper.BuildStmtList(new Bpl.ReturnCmd(Bpl.Token.NoToken)), null, null);
      Bpl.Expr dynTypeOfOperand = this.sink.Heap.DynamicType(Bpl.Expr.Ident(this.sink.LocalExcVariable));
      for (int i = 0; i < catchStatements.Count; i++) {
        Bpl.Expr expr = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(this.sink.Heap.Subtype), new List<Bpl.Expr>(new Bpl.Expr[] {dynTypeOfOperand, typeReferences[i]}));
        elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, expr, catchStatements[i], elseIfCmd, null);
      }
      this.StmtBuilder.Add(elseIfCmd);
      this.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.LocalExcVariable)));
      RaiseException();
      this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);

      this.StmtBuilder.AddLabelCmd(this.sink.FindOrCreateFinallyLabel(tryCatchFinallyStatement));
      if (tryCatchFinallyStatement.FinallyBody != null) {
        this.sink.nestedTryCatchFinallyStatements.Add(new Tuple<ITryCatchFinallyStatement, Sink.TryCatchFinallyContext>(tryCatchFinallyStatement, Sink.TryCatchFinallyContext.InFinally));
        Bpl.Variable savedExcVariable = this.sink.CreateFreshLocal(this.sink.Heap.RefType);
        Bpl.Variable savedLabelVariable = this.sink.CreateFreshLocal(Bpl.Type.Int);
        StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedExcVariable), Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable)));
        StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(savedLabelVariable), Bpl.Expr.Ident(this.sink.LabelVariable)));
        this.Traverse(tryCatchFinallyStatement.FinallyBody);
        StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(savedExcVariable)));
        StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(this.sink.LabelVariable), Bpl.Expr.Ident(savedLabelVariable)));
        this.sink.nestedTryCatchFinallyStatements.RemoveAt(this.sink.nestedTryCatchFinallyStatements.Count - 1);
      }
      GenerateDispatchContinuation(tryCatchFinallyStatement);
      StmtBuilder.AddLabelCmd(this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement));
      Bpl.Expr raiseExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef));
      RaiseException(raiseExpr);
    }
 public void RaiseException(Bpl.Expr e) {
   Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
   RaiseExceptionHelper(builder);
   Bpl.IfCmd ifCmd = new Bpl.IfCmd(Bpl.Token.NoToken, e, builder.Collect(Bpl.Token.NoToken), null, null);
   StmtBuilder.Add(ifCmd);
 }
 public void GenerateDispatchContinuation(ITryCatchFinallyStatement tryCatchFinallyStatement) {
   string continuationLabel = this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement);
   Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(true),
     TranslationHelper.BuildStmtList(new Bpl.GotoCmd(Bpl.Token.NoToken, new List<string>(new string[] {continuationLabel}))), null, null);
   List<string> edges = sink.EscapingEdges(tryCatchFinallyStatement);
   Bpl.IdentifierExpr labelExpr = Bpl.Expr.Ident(this.sink.LabelVariable);
   for (int i = 0; i < edges.Count; i++) {
     string label = edges[i];
     Bpl.GotoCmd gotoCmd = new Bpl.GotoCmd(Bpl.Token.NoToken, new List<string>(new string[] { label }));
     Bpl.Expr targetExpr = Bpl.Expr.Literal(i);
     elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, labelExpr, targetExpr),
       TranslationHelper.BuildStmtList(gotoCmd), elseIfCmd, null);
   }
   this.StmtBuilder.Add(elseIfCmd);
 }
    public override void TraverseChildren(ISwitchStatement switchStatement) {
      var eTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
      eTraverser.Traverse(switchStatement.Expression);
      var conditionExpr = eTraverser.TranslatedExpressions.Pop();

      // Can't depend on default case existing or its index in the collection.
      var switchCases = new List<ISwitchCase>();
      ISwitchCase defaultCase = null;
      foreach (var switchCase in switchStatement.Cases) {
        if (switchCase.IsDefault) {
          defaultCase = switchCase;
        } else {
          switchCases.Add(switchCase);
        }
      }
      Bpl.StmtList defaultStmts = null;
      if (defaultCase != null) {
        var defaultBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
        defaultBodyTraverser.Traverse(defaultCase.Body);
        defaultStmts = defaultBodyTraverser.StmtBuilder.Collect(defaultCase.Token());
      }

      Bpl.IfCmd ifCmd = null;

      for (int i = switchCases.Count-1; 0 <= i; i--) {

        var switchCase = switchCases[i];

        var scTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);
        scTraverser.Traverse(switchCase.Expression);
        var scConditionExpr = scTraverser.TranslatedExpressions.Pop();
        var condition = Bpl.Expr.Eq(conditionExpr, scConditionExpr);

        var scBodyTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
        scBodyTraverser.Traverse(switchCase.Body);

        ifCmd = new Bpl.IfCmd(switchCase.Token(),
          condition,
          scBodyTraverser.StmtBuilder.Collect(switchCase.Token()),
          ifCmd,
          defaultStmts);
        defaultStmts = null; // default body goes only into the innermost if-then-else

      }
      StmtBuilder.Add(ifCmd);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <remarks>(mschaef) Works, but still a stub</remarks>
    /// <param name="conditionalStatement"></param>
    public override void TraverseChildren(IConditionalStatement conditionalStatement) {
      StatementTraverser thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
      StatementTraverser elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext);
      ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext);

      if (this.sink.Options.instrumentBranches) {
        var tok = conditionalStatement.Token();
        thenTraverser.StmtBuilder.Add(
          new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null))
          );
        elseTraverser.StmtBuilder.Add(
          new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null))
          );
      }

      condTraverser.Traverse(conditionalStatement.Condition);
      thenTraverser.Traverse(conditionalStatement.TrueBranch);
      elseTraverser.Traverse(conditionalStatement.FalseBranch);

      Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop();
      Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type);
      if (conditionType == this.sink.Heap.RefType) {
        conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef));
      }
      else if (conditionType == Bpl.Type.Int) {
        conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0));
      }
      else {
        System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool);
      }

      Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditionalStatement.Token(),
          conditionExpr,
          thenTraverser.StmtBuilder.Collect(conditionalStatement.TrueBranch.Token()),
          null,
          elseTraverser.StmtBuilder.Collect(conditionalStatement.FalseBranch.Token())
          );

      StmtBuilder.Add(ifcmd);

    }
    /// <summary>
    /// There aren't any logical-and expressions or logical-or expressions in CCI.
    /// Instead they are encoded as "x ? y : 0" for "x && y" and "x ? 1 : y"
    /// for "x || y".
    /// TODO:
    /// If it isn't either of these short forms then emit the proper expression!
    /// </summary>
    public override void TraverseChildren(IConditional conditional) {
      /*
      #region Try and reconstruct And, Or, Not expressions
      if (conditional.Type.TypeCode == PrimitiveTypeCode.Boolean) {
        CompileTimeConstant ctc = conditional.ResultIfFalse as CompileTimeConstant;
        if (ctc != null) {
          var v = BooleanValueOfCompileTimeConstant(ctc);
          if (!v) { // x ? y : "false or 0" == x && y
            Visit(conditional.Condition);
            Bpl.Expr x = TranslatedExpressions.Pop();
            x = PossiblyCoerceRefToBool(x);
            Visit(conditional.ResultIfTrue);
            Bpl.Expr y = TranslatedExpressions.Pop();
            y = PossiblyCoerceRefToBool(y);
            TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, x, y));
            return;
          } else { // x ? y : "true or 1" == !x || y
            Visit(conditional.Condition);
            Bpl.Expr x = TranslatedExpressions.Pop();
            x = PossiblyCoerceRefToBool(x);
            Visit(conditional.ResultIfTrue);
            Bpl.Expr y = TranslatedExpressions.Pop();
            y = PossiblyCoerceRefToBool(y);
            var notX = Bpl.Expr.Unary(conditional.Token(), Bpl.UnaryOperator.Opcode.Not, x);
            TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or, notX, y));
            return;
          }
        }
        ctc = conditional.ResultIfTrue as CompileTimeConstant;
        if (ctc != null && ctc.Type == BCT.Host.PlatformType.SystemInt32) {
          var v = BooleanValueOfCompileTimeConstant(ctc);
          if (v) { // x ? "true or 1" : y == x || y
            Visit(conditional.Condition);
            Bpl.Expr x = TranslatedExpressions.Pop();
            x = PossiblyCoerceRefToBool(x);
            Visit(conditional.ResultIfFalse);
            Bpl.Expr y = TranslatedExpressions.Pop();
            y = PossiblyCoerceRefToBool(y);
            TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Or, x, y));
            return;
          } else { // x ? "false or 0" : y == !x && y
            Visit(conditional.Condition);
            Bpl.Expr x = TranslatedExpressions.Pop();
            x = PossiblyCoerceRefToBool(x);
            Visit(conditional.ResultIfFalse);
            Bpl.Expr y = TranslatedExpressions.Pop();
            y = PossiblyCoerceRefToBool(y);
            var notX = Bpl.Expr.Unary(conditional.Token(), Bpl.UnaryOperator.Opcode.Not, x);
            TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, notX, y));
            return;
          }
        }
      }
      #endregion

      #region Just translate it as an if-then-else expression
      base.Visit(conditional);
      var ifFalse = TranslatedExpressions.Pop();
      var ifTrue = TranslatedExpressions.Pop();
      var c = TranslatedExpressions.Pop();
      var tok = conditional.Token();
      TranslatedExpressions.Push(
        new Bpl.NAryExpr(tok, new Bpl.IfThenElse(tok), new List<Bpl.Expr>(c, ifTrue, ifFalse))
          );
      return;
      #endregion
      */


      // TODO is this code actually needed at all? It seems that all this is already being done in the Statement traverser for the conditional
      StatementTraverser thenStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext);
      StatementTraverser elseStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext);
      ExpressionTraverser thenExprTraverser = this.StmtTraverser.factory.MakeExpressionTraverser(this.sink, thenStmtTraverser, this.contractContext);
      ExpressionTraverser elseExprTraverser = this.StmtTraverser.factory.MakeExpressionTraverser(this.sink, elseStmtTraverser, this.contractContext);
      thenExprTraverser.Traverse(conditional.ResultIfTrue);
      elseExprTraverser.Traverse(conditional.ResultIfFalse);

      this.Traverse(conditional.Condition);
      Bpl.Expr conditionExpr = this.TranslatedExpressions.Pop();

      Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditional.Token(),
          conditionExpr,
          thenStmtTraverser.StmtBuilder.Collect(conditional.ResultIfTrue.Token()),
          null,
          elseStmtTraverser.StmtBuilder.Collect(conditional.ResultIfFalse.Token())
          );

      this.StmtTraverser.StmtBuilder.Add(ifcmd);

      var ifFalse = elseExprTraverser.TranslatedExpressions.Pop();
      var ifTrue = thenExprTraverser.TranslatedExpressions.Pop();
      TranslatedExpressions.Push(new Bpl.NAryExpr(conditional.Token(), new Bpl.IfThenElse(conditional.Token()), new List<Bpl.Expr>(new Bpl.Expr[] {conditionExpr, ifTrue, ifFalse})));
    }
Beispiel #17
0
	void IfCmd(out IfCmd/*!*/ ifcmd) {
		Contract.Ensures(Contract.ValueAtReturn(out ifcmd) != null); IToken/*!*/ x;
		Expr guard;
		StmtList/*!*/ thn;
		IfCmd/*!*/ elseIf;  IfCmd elseIfOption = null;
		StmtList/*!*/ els;  StmtList elseOption = null;
		
		Expect(41);
		x = t; 
		Guard(out guard);
		Expect(28);
		StmtList(out thn);
		if (la.kind == 42) {
			Get();
			if (la.kind == 41) {
				IfCmd(out elseIf);
				elseIfOption = elseIf; 
			} else if (la.kind == 28) {
				Get();
				StmtList(out els);
				elseOption = els; 
			} else SynErr(109);
		}
		ifcmd = new IfCmd(x, guard, thn, elseIfOption, elseOption); 
	}
    public Bpl.Procedure addHandlerStubCaller(Sink sink, IMethodDefinition def) {
      MethodBody callerBody = new MethodBody();
      MethodDefinition callerDef = new MethodDefinition() {
        InternFactory = (def as MethodDefinition).InternFactory,
        ContainingTypeDefinition = def.ContainingTypeDefinition,
        IsStatic = true,
        Name = sink.host.NameTable.GetNameFor("BOOGIE_STUB_CALLER_" + def.Name.Value),
        Type = sink.host.PlatformType.SystemVoid,
        Body = callerBody,
      };
      callerBody.MethodDefinition = callerDef;
      Sink.ProcedureInfo procInfo = sink.FindOrCreateProcedure(def);
      Sink.ProcedureInfo callerInfo = sink.FindOrCreateProcedure(callerDef);

      Bpl.LocalVariable[] localVars = new Bpl.LocalVariable[procInfo.Decl.InParams.Count];
      Bpl.IdentifierExpr[] varExpr = new Bpl.IdentifierExpr[procInfo.Decl.InParams.Count];
      for (int i = 0; i < procInfo.Decl.InParams.Count; i++) {
        Bpl.LocalVariable loc = new Bpl.LocalVariable(Bpl.Token.NoToken,
                                                     new Bpl.TypedIdent(Bpl.Token.NoToken, TranslationHelper.GenerateTempVarName(),
                                                                        procInfo.Decl.InParams[i].TypedIdent.Type));
        localVars[i] = loc;
        varExpr[i] = new Bpl.IdentifierExpr(Bpl.Token.NoToken, loc);
      }

      Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder();
      builder.Add(getResetNavigationCheck(sink));
      
      string pageXaml= PhoneCodeHelper.instance().PhonePlugin.getXAMLForPage(def.ContainingTypeDefinition.ToString());
      Bpl.Variable boogieCurrentURI = sink.FindOrCreateFieldVariable(PhoneCodeHelper.CurrentURIFieldDefinition);
      Bpl.Constant boogieXamlConstant;
      if (pageXaml != null)
        boogieXamlConstant = sink.FindOrCreateConstant(pageXaml);
      else
        boogieXamlConstant = null;
      // NAVIGATION TODO: For now just assume we are in this page to be able to call the handler, this is NOT true for any handler
      // NAVIGATION TODO: ie, a network event handler
      if (boogieXamlConstant != null) {
        Bpl.AssumeCmd assumeCurrentPage =
          new Bpl.AssumeCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
        builder.Add(assumeCurrentPage);
      }

      // NAVIGATION TODO: have to do the pair generation all in one go instead of having different files that need to be sed'ed
      boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_STARTING_URI_PLACEHOLDER);
      Bpl.AssumeCmd assumeStartPage = new Bpl.AssumeCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));
      builder.Add(assumeStartPage);
      builder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, procInfo.Decl.Name, new List<Bpl.Expr>(varExpr), new List<Bpl.IdentifierExpr>()));
      boogieXamlConstant = sink.FindOrCreateConstant(BOOGIE_ENDING_URI_PLACEHOLDER);
      Bpl.AssertCmd assertEndPage = new Bpl.AssertCmd(Bpl.Token.NoToken,
                            Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieCurrentURI),
                                            new Bpl.IdentifierExpr(Bpl.Token.NoToken, boogieXamlConstant)));

      Bpl.Expr guard= new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateGlobalVariable(PhoneCodeHelper.BOOGIE_NAVIGATION_CHECK_VARIABLE, Bpl.Type.Bool));
      Bpl.StmtListBuilder thenBuilder = new Bpl.StmtListBuilder();
      thenBuilder.Add(assertEndPage);
      Bpl.IfCmd ifNavigated = new Bpl.IfCmd(Bpl.Token.NoToken, guard, thenBuilder.Collect(Bpl.Token.NoToken), null, new Bpl.StmtListBuilder().Collect(Bpl.Token.NoToken));

      builder.Add(ifNavigated);
      Bpl.Implementation impl =
        new Bpl.Implementation(Bpl.Token.NoToken, callerInfo.Decl.Name, new List<Bpl.TypeVariable>(), new List<Bpl.Variable>(),
                               new List<Bpl.Variable>(), new List<Bpl.Variable>(localVars), builder.Collect(Bpl.Token.NoToken), null, new Bpl.Errors());

      sink.TranslatedProgram.AddTopLevelDeclaration(impl);
      return impl.Proc;
    }