Ejemplo n.º 1
0
        private void EmitSequencePointStatement(BoundSequencePointWithSpan node)
        {
            TextSpan span = node.Span;

            if (span != default(TextSpan) && _emitPdbSequencePoints)
            {
                this.EmitSequencePoint(node.SyntaxTree, span);
            }

            BoundStatement statement           = node.StatementOpt;
            int            instructionsEmitted = 0;

            if (statement != null)
            {
                instructionsEmitted = this.EmitStatementAndCountInstructions(statement);
            }

            if (
                instructionsEmitted == 0 &&
                span != default(TextSpan) &&
                _ilEmitStyle == ILEmitStyle.Debug
                )
            {
                // if there was no code emitted, then emit nop
                // otherwise this point could get associated with some random statement, possibly in a wrong scope
                _builder.EmitOpCode(ILOpCode.Nop);
            }
        }
Ejemplo n.º 2
0
        private void EmitSequencePointStatement(BoundSequencePointWithSpan node)
        {
            AssertExplicitSequencePointAllowed();

            TextSpan span = node.Span;

            if (span != default(TextSpan) && this.emitSequencePoints)
            {
                this.EmitSequencePoint(node.SyntaxTree, span);
            }

            BoundStatement statement           = node.StatementOpt;
            int            instructionsEmitted = 0;

            if (statement != null)
            {
                instructionsEmitted = -builder.InstructionsEmitted;
                this.EmitStatement(statement);
                instructionsEmitted += builder.InstructionsEmitted;
            }

            if (instructionsEmitted == 0 && span != default(TextSpan) && noOptimizations)
            {
                // if there was no code emitted, then emit nop
                // otherwise this point could get associated with some random statement, possibly in a wrong scope
                builder.EmitOpCode(ILOpCode.Nop);
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Add sequence point |here|:
 ///
 /// |foreach| (Type var in expr) { }
 /// </summary>
 /// <remarks>
 /// Hit once, before looping begins.
 /// </remarks>
 private void AddForEachKeywordSequencePoint(ForEachStatementSyntax forEachSyntax, ref BoundStatement result)
 {
     if (this.generateDebugInfo)
     {
         BoundSequencePointWithSpan foreachKeywordSequencePoint = new BoundSequencePointWithSpan(forEachSyntax, null, forEachSyntax.ForEachKeyword.Span);
         result = new BoundStatementList(forEachSyntax, ReadOnlyArray <BoundStatement> .CreateFrom(foreachKeywordSequencePoint, result));
     }
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Add sequence point |here|:
 ///
 /// foreach (|Type var| in expr) { }
 /// </summary>
 /// <remarks>
 /// Hit every iteration.
 /// </remarks>
 private void AddForEachIterationVariableSequencePoint(ForEachStatementSyntax forEachSyntax, ref BoundStatement iterationVarDecl)
 {
     if (this.generateDebugInfo)
     {
         TextSpan iterationVarDeclSpan = TextSpan.FromBounds(forEachSyntax.Type.Span.Start, forEachSyntax.Identifier.Span.End);
         iterationVarDecl = new BoundSequencePointWithSpan(forEachSyntax, iterationVarDecl, iterationVarDeclSpan);
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Add sequence point |here|:
        ///
        /// |foreach| (Type var in expr) { }
        /// </summary>
        /// <remarks>
        /// Hit once, before looping begins.
        /// </remarks>
        public override BoundStatement InstrumentForEachStatement(BoundForEachStatement original, BoundStatement rewritten)
        {
            var forEachSyntax = (ForStatementSyntax)original.Syntax;
            BoundSequencePointWithSpan foreachKeywordSequencePoint = new BoundSequencePointWithSpan(forEachSyntax, null, forEachSyntax.ForEachKeyword.Span);

            return(new BoundStatementList(forEachSyntax,
                                          ImmutableArray.Create <BoundStatement>(foreachKeywordSequencePoint,
                                                                                 base.InstrumentForEachStatement(original, rewritten))));
        }
Ejemplo n.º 6
0
        private BoundStatement RewriteWhileStatement(
            SyntaxNode syntax,
            BoundExpression rewrittenCondition,
            TextSpan conditionSequencePointSpan,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            var            startLabel           = new GeneratedLabelSymbol("start");
            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);

            if (this.generateDebugInfo)
            {
                ifConditionGotoStart = new BoundSequencePointWithSpan(syntax, ifConditionGotoStart, conditionSequencePointSpan);
            }

            // while (condition)
            //   body;
            //
            // becomes
            //
            // goto continue;
            // start:
            // body
            // continue:
            // GotoIfTrue condition start;
            // break:

            BoundStatement gotoContinue = new BoundGotoStatement(syntax, continueLabel);

            if (this.generateDebugInfo)
            {
                //mark the initial jump as hidden.
                //We do it to tell that this is not a part of previou statement.
                //This jump may be a target of another jump (for example if loops are nested) and that will make
                //impression of the previous statement being re-executed
                gotoContinue = new BoundSequencePoint(null, gotoContinue);
            }

            return(BoundStatementList.Synthesized(syntax, hasErrors,
                                                  gotoContinue,
                                                  new BoundLabelStatement(syntax, startLabel),
                                                  rewrittenBody,
                                                  new BoundLabelStatement(syntax, continueLabel),
                                                  ifConditionGotoStart,
                                                  new BoundLabelStatement(syntax, breakLabel)));
        }
Ejemplo n.º 7
0
        public override BoundNode VisitDoStatement(BoundDoStatement node)
        {
            Debug.Assert(node != null);

            var rewrittenCondition = (BoundExpression)Visit(node.Condition);
            var rewrittenBody      = (BoundStatement)Visit(node.Body);
            var startLabel         = new GeneratedLabelSymbol("start");

            var syntax = node.Syntax;

            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(syntax, rewrittenCondition, true, startLabel);

            if (this.generateDebugInfo)
            {
                var doSyntax = (DoStatementSyntax)syntax;
                var span     = TextSpan.FromBounds(
                    doSyntax.WhileKeyword.Span.Start,
                    doSyntax.SemicolonToken.Span.End);

                ifConditionGotoStart = new BoundSequencePointWithSpan(doSyntax, ifConditionGotoStart, span);
            }

            // do
            //   body
            // while (condition);
            //
            // becomes
            //
            // start:
            // body
            // continue:
            // sequence point
            // GotoIfTrue condition start;
            // break:

            return(BoundStatementList.Synthesized(syntax, node.HasErrors,
                                                  new BoundLabelStatement(syntax, startLabel),
                                                  rewrittenBody,
                                                  new BoundLabelStatement(syntax, node.ContinueLabel),
                                                  ifConditionGotoStart,
                                                  new BoundLabelStatement(syntax, node.BreakLabel)));
        }
Ejemplo n.º 8
0
        internal static BoundBlock ConstructDestructorBody(MethodSymbol method, BoundBlock block)
        {
            var syntax = block.Syntax;

            Debug.Assert(method.MethodKind == MethodKind.Destructor);
            Debug.Assert(syntax.Kind() == SyntaxKind.Block || syntax.Kind() == SyntaxKind.ArrowExpressionClause);

            // If this is a destructor and a base type has a Finalize method (see GetBaseTypeFinalizeMethod for exact
            // requirements), then we need to call that method in a finally block.  Otherwise, just return block as-is.
            // NOTE: the Finalize method need not be a destructor or be overridden by the current method.
            MethodSymbol baseTypeFinalize = GetBaseTypeFinalizeMethod(method);

            if ((object)baseTypeFinalize != null)
            {
                BoundStatement baseFinalizeCall = new BoundExpressionStatement(
                    syntax,
                    BoundCall.Synthesized(
                        syntax,
                        new BoundBaseReference(
                            syntax,
                            method.ContainingType)
                {
                    WasCompilerGenerated = true
                },
                        baseTypeFinalize))
                {
                    WasCompilerGenerated = true
                };

                if (syntax.Kind() == SyntaxKind.Block)
                {
                    //sequence point to mimic Dev10
                    baseFinalizeCall = new BoundSequencePointWithSpan(
                        syntax,
                        baseFinalizeCall,
                        ((BlockSyntax)syntax).CloseBraceToken.Span);
                }

                return(new BoundBlock(
                           syntax,
                           ImmutableArray <LocalSymbol> .Empty,
                           ImmutableArray.Create <BoundStatement>(
                               new BoundTryStatement(
                                   syntax,
                                   block,
                                   ImmutableArray <BoundCatchBlock> .Empty,
                                   new BoundBlock(
                                       syntax,
                                       ImmutableArray <LocalSymbol> .Empty,
                                       ImmutableArray.Create <BoundStatement>(
                                           baseFinalizeCall)
                                       )
                {
                    WasCompilerGenerated = true
                }
                                   )
                {
                    WasCompilerGenerated = true
                })));
            }

            return(block);
        }
Ejemplo n.º 9
0
        private void EmitSequencePointStatement(BoundSequencePointWithSpan node)
        {
            AssertExplicitSequencePointAllowed();

            TextSpan span = node.Span;
            if (span != default(TextSpan) && this.emitSequencePoints)
            {
                this.EmitSequencePoint(node.SyntaxTree, span);
            }

            BoundStatement statement = node.StatementOpt;
            int instructionsEmitted = 0;

            if (statement != null)
            {
                instructionsEmitted = -builder.InstructionsEmitted;
                this.EmitStatement(statement);
                instructionsEmitted += builder.InstructionsEmitted;
            }

            if (instructionsEmitted == 0 && span != default(TextSpan) && noOptimizations)
            {
                // if there was no code emitted, then emit nop 
                // otherwise this point could get associated with some random statement, possibly in a wrong scope
                builder.EmitOpCode(ILOpCode.Nop);
            }
        }
 /// <summary>
 /// Add sequence point |here|:
 /// 
 /// |foreach| (Type var in expr) { }
 /// </summary>
 /// <remarks>
 /// Hit once, before looping begins.
 /// </remarks>
 private void AddForEachKeywordSequencePoint(ForEachStatementSyntax forEachSyntax, ref BoundStatement result)
 {
     if (this.generateDebugInfo)
     {
         BoundSequencePointWithSpan foreachKeywordSequencePoint = new BoundSequencePointWithSpan(forEachSyntax, null, forEachSyntax.ForEachKeyword.Span);
         result = new BoundStatementList(forEachSyntax, ReadOnlyArray<BoundStatement>.CreateFrom(foreachKeywordSequencePoint, result));
     }
 }
 /// <summary>
 /// Add sequence point |here|:
 /// 
 /// foreach (|Type var| in expr) { }
 /// </summary>
 /// <remarks>
 /// Hit every iteration.
 /// </remarks>
 private void AddForEachIterationVariableSequencePoint(ForEachStatementSyntax forEachSyntax, ref BoundStatement iterationVarDecl)
 {
     if (this.generateDebugInfo)
     {
         TextSpan iterationVarDeclSpan = TextSpan.FromBounds(forEachSyntax.Type.Span.Start, forEachSyntax.Identifier.Span.End);
         iterationVarDecl = new BoundSequencePointWithSpan(forEachSyntax, iterationVarDecl, iterationVarDeclSpan);
     }
 }
Ejemplo n.º 12
0
        private BoundStatement RewriteWhileStatement(
            SyntaxNode syntax,
            BoundExpression rewrittenCondition,
            TextSpan conditionSequencePointSpan,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            var startLabel = new GeneratedLabelSymbol("start");
            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);

            if (this.generateDebugInfo)
            {
                ifConditionGotoStart = new BoundSequencePointWithSpan(syntax, ifConditionGotoStart, conditionSequencePointSpan);
            }

            // while (condition) 
            //   body;
            //
            // becomes
            //
            // goto continue;
            // start: 
            // body
            // continue:
            // GotoIfTrue condition start;
            // break:

            BoundStatement gotoContinue = new BoundGotoStatement(syntax, continueLabel);
            if (this.generateDebugInfo)
            {
                //mark the initial jump as hidden.
                //We do it to tell that this is not a part of previou statement.
                //This jump may be a target of another jump (for example if loops are nested) and that will make 
                //impression of the previous statement being re-executed
                gotoContinue = new BoundSequencePoint(null, gotoContinue);
            }

            return BoundStatementList.Synthesized(syntax, hasErrors,
                gotoContinue,
                new BoundLabelStatement(syntax, startLabel),
                rewrittenBody,
                new BoundLabelStatement(syntax, continueLabel),
                ifConditionGotoStart,
                new BoundLabelStatement(syntax, breakLabel));
        }
Ejemplo n.º 13
0
        private BoundStatement RewriteForStatement(
            SyntaxNode syntax,
            ReadOnlyArray <LocalSymbol> locals,
            BoundStatement rewrittenInitializer,
            BoundExpression rewrittenCondition,
            SyntaxNodeOrToken conditionSyntax,
            BoundStatement rewrittenIncrement,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            var startLabel = new GeneratedLabelSymbol("start");
            var endLabel   = new GeneratedLabelSymbol("end");

            // for (initializer; condition; increment)
            //   body;
            //
            // becomes the following (with
            // block added for locals)
            //
            // {
            //   initializer;
            //   goto end;
            // start:
            //   body;
            // continue:
            //   increment;
            // end:
            //   GotoIfTrue condition start;
            // break:
            // }

            //  initializer;
            //  goto end;
            var statementBuilder = ArrayBuilder <BoundStatement> .GetInstance();

            if (rewrittenInitializer != null)
            {
                statementBuilder.Add(rewrittenInitializer);
            }

            //mark the initial jump as hidden.
            //We do it to tell that this is not a part of previous statement.
            //This jump may be a target of another jump (for example if loops are nested) and that will make
            //impression of the previous statement being re-executed
            var gotoEnd = new BoundSequencePoint(null, new BoundGotoStatement(syntax, endLabel));

            statementBuilder.Add(gotoEnd);

            // start:
            //   body;
            statementBuilder.Add(new BoundLabelStatement(syntax, startLabel));
            Debug.Assert(rewrittenBody != null);
            statementBuilder.Add(rewrittenBody);

            // continue:
            //   increment;
            statementBuilder.Add(new BoundLabelStatement(syntax, continueLabel));
            if (rewrittenIncrement != null)
            {
                statementBuilder.Add(rewrittenIncrement);
            }

            // end:
            //   GotoIfTrue condition start;
            statementBuilder.Add(new BoundLabelStatement(syntax, endLabel));
            BoundStatement branchBack = null;

            if (rewrittenCondition != null)
            {
                branchBack = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);
            }
            else
            {
                branchBack = new BoundGotoStatement(syntax, startLabel);
            }

            if (this.generateDebugInfo)
            {
                if (conditionSyntax.IsToken)
                {
                    branchBack = new BoundSequencePointWithSpan(syntax, branchBack, conditionSyntax.Span);
                }
                else
                {
                    //if there is no condition, make this a hidden point so that
                    //it does not count as a part of previous statement
                    branchBack = new BoundSequencePoint(conditionSyntax.AsNode(), branchBack);
                }
            }

            statementBuilder.Add(branchBack);


            // break:
            statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel));

            var statements = statementBuilder.ToReadOnlyAndFree();

            return(new BoundBlock(syntax, locals, statements, hasErrors));
        }
Ejemplo n.º 14
0
        private BoundStatement RewriteForStatement(
            SyntaxNode syntax,
            ReadOnlyArray<LocalSymbol> locals,
            BoundStatement rewrittenInitializer,
            BoundExpression rewrittenCondition,
            SyntaxNodeOrToken conditionSyntax,
            BoundStatement rewrittenIncrement,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            var startLabel = new GeneratedLabelSymbol("start");
            var endLabel = new GeneratedLabelSymbol("end");

            // for (initializer; condition; increment)
            //   body;
            //
            // becomes the following (with
            // block added for locals)
            //
            // {
            //   initializer;
            //   goto end;
            // start:
            //   body;
            // continue:
            //   increment;
            // end:
            //   GotoIfTrue condition start;
            // break:
            // }

            //  initializer;
            //  goto end;
            var statementBuilder = ArrayBuilder<BoundStatement>.GetInstance();
            if (rewrittenInitializer != null)
            {
                statementBuilder.Add(rewrittenInitializer);
            }

            //mark the initial jump as hidden.
            //We do it to tell that this is not a part of previous statement.
            //This jump may be a target of another jump (for example if loops are nested) and that will make 
            //impression of the previous statement being re-executed
            var gotoEnd = new BoundSequencePoint(null, new BoundGotoStatement(syntax, endLabel));
            statementBuilder.Add(gotoEnd);

            // start:
            //   body;
            statementBuilder.Add(new BoundLabelStatement(syntax, startLabel));
            Debug.Assert(rewrittenBody != null);
            statementBuilder.Add(rewrittenBody);

            // continue:
            //   increment;
            statementBuilder.Add(new BoundLabelStatement(syntax, continueLabel));
            if (rewrittenIncrement != null)
            {
                statementBuilder.Add(rewrittenIncrement);
            }

            // end:
            //   GotoIfTrue condition start;
            statementBuilder.Add(new BoundLabelStatement(syntax, endLabel));
            BoundStatement branchBack = null;
            if (rewrittenCondition != null)
            {
                branchBack = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);
            }
            else
            {
                branchBack = new BoundGotoStatement(syntax, startLabel);
            }

            if (this.generateDebugInfo)
            {
                if (conditionSyntax.IsToken)
                {
                    branchBack = new BoundSequencePointWithSpan(syntax, branchBack, conditionSyntax.Span);
                }
                else
                {
                    //if there is no condition, make this a hidden point so that 
                    //it does not count as a part of previous statement
                    branchBack = new BoundSequencePoint(conditionSyntax.AsNode(), branchBack);
                }
            }

            statementBuilder.Add(branchBack);


            // break:
            statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel));

            var statements = statementBuilder.ToReadOnlyAndFree();
            return new BoundBlock(syntax, locals, statements, hasErrors);
        }
Ejemplo n.º 15
0
        public override BoundNode VisitDoStatement(BoundDoStatement node)
        {
            Debug.Assert(node != null);

            var rewrittenCondition = (BoundExpression)Visit(node.Condition);
            var rewrittenBody = (BoundStatement)Visit(node.Body);
            var startLabel = new GeneratedLabelSymbol("start");
            
            var syntax = node.Syntax;

            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(syntax, rewrittenCondition, true, startLabel);

            if (this.generateDebugInfo)
            {
                var doSyntax = (DoStatementSyntax)syntax;
                var span = TextSpan.FromBounds(
                    doSyntax.WhileKeyword.Span.Start,
                    doSyntax.SemicolonToken.Span.End);

                ifConditionGotoStart = new BoundSequencePointWithSpan(doSyntax, ifConditionGotoStart, span);
            }

            // do
            //   body
            // while (condition);
            //
            // becomes
            //
            // start: 
            // body
            // continue:
            // sequence point
            // GotoIfTrue condition start;
            // break:

            return BoundStatementList.Synthesized(syntax, node.HasErrors,
                new BoundLabelStatement(syntax, startLabel),
                rewrittenBody,
                new BoundLabelStatement(syntax, node.ContinueLabel),
                ifConditionGotoStart,
                new BoundLabelStatement(syntax, node.BreakLabel));
        }
Ejemplo n.º 16
0
        private void EmitSequencePointStatement(BoundSequencePointWithSpan node)
        {
            TextSpan span = node.Span;
            if (span != default(TextSpan) && _emitPdbSequencePoints)
            {
                this.EmitSequencePoint(node.SyntaxTree, span);
            }

            BoundStatement statement = node.StatementOpt;
            int instructionsEmitted = 0;
            if (statement != null)
            {
                instructionsEmitted = this.EmitStatementAndCountInstructions(statement);
            }

            if (instructionsEmitted == 0 && span != default(TextSpan) && _ilEmitStyle == ILEmitStyle.Debug)
            {
                // if there was no code emitted, then emit nop 
                // otherwise this point could get associated with some random statement, possibly in a wrong scope
                _builder.EmitOpCode(ILOpCode.Nop);
            }
        }
Ejemplo n.º 17
0
 public override object VisitSequencePointWithSpan(BoundSequencePointWithSpan node, object arg)
 {
     return(null);
 }