public static BoundStatement Rewrite(BoundStatement node, MethodSymbol containingSymbol, NamedTypeSymbol containingType, SynthesizedSubmissionFields previousSubmissionFields, Compilation compilation) { Debug.Assert(node != null); var rewriter = new CallRewriter(containingSymbol, containingType, previousSubmissionFields, compilation); var result = (BoundStatement)rewriter.Visit(node); return result; }
public static BoundStatement Optimize( BoundStatement src, bool debugFriendly, out HashSet<LocalSymbol> stackLocals) { //TODO: run other optimizing passes here. // stack scheduler must be the last one. var locals = PooledDictionary<LocalSymbol, LocalDefUseInfo>.GetInstance(); var evalStack = ArrayBuilder<ValueTuple<BoundExpression, ExprContext>>.GetInstance(); src = (BoundStatement)StackOptimizerPass1.Analyze(src, locals, evalStack, debugFriendly); evalStack.Free(); FilterValidStackLocals(locals); BoundStatement result; if (locals.Count == 0) { stackLocals = null; result = src; } else { stackLocals = new HashSet<LocalSymbol>(locals.Keys); result = StackOptimizerPass2.Rewrite(src, locals); } foreach (var info in locals.Values) { info.LocalDefs.Free(); } locals.Free(); return result; }
public BoundIfStatement(BoundExpression condition, BoundStatement consequence, BoundStatement alternativeOpt) : base(BoundNodeKind.IfStatement) { Condition = condition; Consequence = consequence; AlternativeOpt = alternativeOpt; }
public CodeGenerator( MethodSymbol method, BoundStatement boundBody, ILBuilder builder, PEModuleBuilder moduleBuilder, DiagnosticBag diagnostics, OptimizationLevel optimizations, bool emittingPdb) { Debug.Assert((object)method != null); Debug.Assert(boundBody != null); Debug.Assert(builder != null); Debug.Assert(moduleBuilder != null); Debug.Assert(diagnostics != null); _method = method; _boundBody = boundBody; _builder = builder; _module = moduleBuilder; _diagnostics = diagnostics; if (!method.GenerateDebugInfo) { // Always optimize synthesized methods that don't contain user code. // // Specifically, always optimize synthesized explicit interface implementation methods // (aka bridge methods) with by-ref returns because peverify produces errors if we // return a ref local (which the return local will be in such cases). _ilEmitStyle = ILEmitStyle.Release; } else { if (optimizations == OptimizationLevel.Debug) { _ilEmitStyle = ILEmitStyle.Debug; } else { _ilEmitStyle = IsDebugPlus() ? ILEmitStyle.DebugFriendlyRelease : ILEmitStyle.Release; } } // Emit sequence points unless // - the PDBs are not being generated // - debug information for the method is not generated since the method does not contain // user code that can be stepped through, or changed during EnC. // // This setting only affects generating PDB sequence points, it shall not affect generated IL in any way. _emitPdbSequencePoints = emittingPdb && method.GenerateDebugInfo; _boundBody = Optimizer.Optimize( boundBody, debugFriendly: _ilEmitStyle != ILEmitStyle.Release, stackLocals: out _stackLocals); _methodBodySyntaxOpt = (method as SourceMethodSymbol)?.BodySyntax; }
public static BoundStatement Rewrite(BoundStatement node, MethodSymbol containingMethod, Compilation compilation, bool generateDebugInfo, out bool sawLambdas) { Debug.Assert(node != null); var rewriter = new ControlFlowRewriter(containingMethod, compilation, generateDebugInfo); var result = (BoundStatement)rewriter.Visit(node); sawLambdas = rewriter.sawLambdas; return result; }
public static BoundStatement Rewrite(BoundStatement node, MethodSymbol containingSymbol, Compilation compilation) { Debug.Assert(node != null); Debug.Assert(compilation != null); var rewriter = new IsAndAsRewriter(containingSymbol, compilation); var result = (BoundStatement)rewriter.Visit(node); return result; }
public BoundForStatement(BoundMultipleVariableDeclarations declaration, BoundExpression initializer, BoundExpression condition, BoundExpression incrementor, BoundStatement body) : base(BoundNodeKind.ForStatement) { Declarations = declaration; Initializer = initializer; Condition = condition; Incrementor = incrementor; Body = body; }
protected RegionPlace regionPlace; // tells whether we are analyzing the region before, during, or after the region protected RegionAnalysisWalker(Compilation compilation, SyntaxTree tree, MethodSymbol method, BoundStatement block, TextSpan region, ThisSymbolCache thisSymbolCache, HashSet<Symbol> unassignedVariables = null, bool trackUnassignmentsInLoops = false) : base(compilation, tree, method, block, thisSymbolCache, unassignedVariables, trackUnassignmentsInLoops) { this.region = region; // assign slots to the parameters foreach (var parameter in method.Parameters) { MakeSlot(parameter); } }
internal StatementBinding( BoundStatement boundStatement, ImmutableMap<SyntaxNode, BlockBaseBinderContext> blockMap, IList<LocalSymbol> locals, Dictionary<SyntaxNode, BoundNode> nodeMap, DiagnosticBag diagnostics) { this.boundStatement = boundStatement; this.blockMap = blockMap; this.locals = locals; this.nodeMap = nodeMap; this.diagnostics = diagnostics; }
private CodeGenerator(MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints) { this.method = method; this.block = block; this.builder = builder; this.module = module; this.diagnostics = diagnostics; this.noOptimizations = !optimize; this.debugInformationKind = module.Compilation.Options.DebugInformationKind; if (!this.debugInformationKind.IsValid()) { this.debugInformationKind = DebugInformationKind.None; } // Special case: always optimize synthesized explicit interface implementation methods // (aka bridge methods) with by-ref returns because peverify produces errors if we // return a ref local (which the return local will be in such cases). if (this.noOptimizations && method.ReturnType is ByRefReturnErrorTypeSymbol) { Debug.Assert(method is SynthesizedExplicitImplementationMethod); this.noOptimizations = false; } this.emitSequencePoints = emitSequencePoints; if (!this.noOptimizations) { this.block = Optimizer.Optimize(block, out stackLocals); } Debug.Assert((object)method != null); Debug.Assert(block != null); Debug.Assert(builder != null); Debug.Assert(module != null); var asSourceMethod = method as SourceMethodSymbol; if ((object)asSourceMethod != null) { methodBlockSyntax = asSourceMethod.BlockSyntax; } }
private static BoundStatement RewriteIfStatement( SyntaxNode syntax, BoundExpression rewrittenCondition, BoundStatement rewrittenConsequence, BoundStatement rewrittenAlternativeOpt, bool hasErrors) { var afterif = new GeneratedLabelSymbol("afterif"); // if (condition) // consequence; // // becomes // // GotoIfFalse condition afterif; // consequence; // afterif: if (rewrittenAlternativeOpt == null) { return BoundStatementList.Synthesized(syntax, new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, afterif), rewrittenConsequence, new BoundLabelStatement(syntax, afterif)); } // if (condition) // consequence; // else // alternative // // becomes // // GotoIfFalse condition alt; // consequence // goto afterif; // alt: // alternative; // afterif: var alt = new GeneratedLabelSymbol("alternative"); return BoundStatementList.Synthesized(syntax, hasErrors, new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, alt), rewrittenConsequence, new BoundGotoStatement(syntax, afterif), new BoundLabelStatement(syntax, alt), rewrittenAlternativeOpt, new BoundLabelStatement(syntax, afterif)); }
private CodeGenerator( MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder moduleBuilder, DiagnosticBag diagnostics, OptimizationLevel optimizations, bool emittingPdbs) { this.method = method; this.block = block; this.builder = builder; this.module = moduleBuilder; this.diagnostics = diagnostics; // Always optimize synthesized methods that don't contain user code. // // Specifically, always optimize synthesized explicit interface implementation methods // (aka bridge methods) with by-ref returns because peverify produces errors if we // return a ref local (which the return local will be in such cases). this.optimizations = method.GenerateDebugInfo ? optimizations : OptimizationLevel.Release; // Emit sequence points unless // - the PDBs are not being generated // - debug information for the method is not generated since the method does not contain // user code that can be stepped thru, or changed during EnC. // // This setting only affects generating PDB sequence points, it shall not affect generated IL in any way. this.emitPdbSequencePoints = emittingPdbs && method.GenerateDebugInfo; if (this.optimizations == OptimizationLevel.Release) { this.block = Optimizer.Optimize(block, out stackLocals); } Debug.Assert((object)method != null); Debug.Assert(block != null); Debug.Assert(builder != null); Debug.Assert(moduleBuilder != null); var asSourceMethod = method as SourceMethodSymbol; if ((object)asSourceMethod != null) { methodBlockSyntax = asSourceMethod.BlockSyntax; } }
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics) { // Method body: // // { // Object..ctor(); // this.backingField_1 = arg1; // ... // this.backingField_N = argN; // } SyntheticBoundNodeFactory F = this.CreateBoundNodeFactory(compilationState, diagnostics); int paramCount = this.ParameterCount; // List of statements BoundStatement[] statements = new BoundStatement[paramCount + 2]; int statementIndex = 0; // explicit base constructor call BoundExpression call = MethodCompiler.GenerateObjectConstructorInitializer(this, diagnostics); if (call == null) { // This may happen if Object..ctor is not found or is unaccessible return; } statements[statementIndex++] = F.ExpressionStatement(call); if (paramCount > 0) { AnonymousTypeTemplateSymbol anonymousType = (AnonymousTypeTemplateSymbol)this.ContainingType; Debug.Assert(anonymousType.Properties.Length == paramCount); // Assign fields for (int index = 0; index < this.ParameterCount; index++) { // Generate 'field' = 'parameter' statement statements[statementIndex++] = F.Assignment(F.Field(F.This(), anonymousType.Properties[index].BackingField), F.Parameter(_parameters[index])); } } // Final return statement statements[statementIndex++] = F.Return(); // Create a bound block F.CloseMethod(F.Block(statements)); }
internal static BoundStatement Rewrite(CSharpCompilation compilation, EENamedTypeSymbol container, HashSet<LocalSymbol> declaredLocals, BoundStatement node, ImmutableArray<LocalSymbol> declaredLocalsArray) { var builder = ArrayBuilder<BoundStatement>.GetInstance(); foreach (var local in declaredLocalsArray) { CreateLocal(compilation, declaredLocals, builder, local, node.Syntax); } // Rewrite top-level declarations only. switch (node.Kind) { case BoundKind.LocalDeclaration: Debug.Assert(declaredLocals.Contains(((BoundLocalDeclaration)node).LocalSymbol)); RewriteLocalDeclaration(builder, (BoundLocalDeclaration)node); break; case BoundKind.MultipleLocalDeclarations: foreach (var declaration in ((BoundMultipleLocalDeclarations)node).LocalDeclarations) { Debug.Assert(declaredLocals.Contains(declaration.LocalSymbol)); RewriteLocalDeclaration(builder, declaration); } break; default: if (builder.Count == 0) { builder.Free(); return node; } builder.Add(node); break; } return BoundBlock.SynthesizedNoLocals(node.Syntax, builder.ToImmutableAndFree()); }
/// <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 once, before looping begins. /// </remarks> private void AddForEachExpressionSequencePoint(ForEachStatementSyntax forEachSyntax, ref BoundStatement collectionVarDecl) { if (this.generateDebugInfo) { // NOTE: This is slightly different from Dev10. In Dev10, when you stop the debugger // on the collection expression, you can see the (uninitialized) iteration variable. // In Roslyn, you cannot because the iteration variable is re-declared in each iteration // of the loop and is, therefore, not yet in scope. collectionVarDecl = new BoundSequencePoint(forEachSyntax.Expression, collectionVarDecl); } }
public BoundForStatement(VariableSymble variable, BoundExpression lowerBound, BoundExpression upperBound, BoundExpression itterator, BoundStatement body, BoundLabel bodyLabel, BoundLabel breakLabel, BoundLabel continueLabel) : base(body, bodyLabel, breakLabel, continueLabel) { Variable = variable; LowerBound = lowerBound; UpperBound = upperBound; Itterator = itterator; }
/// <summary> /// Visit a statement. Note that the language spec requires each statement to be reachable, /// so we report an unreachable statement if it is not reachable. /// </summary> /// <param name="statement"></param> protected void VisitStatement(BoundStatement statement) { Debug.Assert(!this.state.Assigned.IsNull); // We use variable slot 0 to record, in unreachable code, when a warning has // (unassigned) or has not (assigned) been produced. if (!state.Reachable && state.IsAssigned(0)) { // prefer to place the diagnostic on a nonempty statement var unreachable = FirstNonempty(statement); // Dev10 refuses to mark empty statements as unreachable; we follow suit. if (unreachable != null) { Diagnostics.Add(ErrorCode.WRN_UnreachableCode, new SourceLocation(tree, unreachable.Syntax)); state.Unassign(0); // suppress cascaded diagnostics } } Visit(statement); }
public BoundForStatement(VariableSymbol variable, BoundExpression lowerBound, BoundExpression upperBound, BoundStatement body) { Variable = variable; LowerBound = lowerBound; UpperBound = upperBound; Body = body; }
private int EmitStatementAndCountInstructions(BoundStatement statement) { int n = _builder.InstructionsEmitted; this.EmitStatement(statement); return _builder.InstructionsEmitted - n; }
public BoundForStatement(BoundStatement variable, BoundExpression condition, BoundExpression action, BoundStatement body, BoundLabel breakLabel, BoundLabel continueLabel) : base(breakLabel, continueLabel) { Variable = variable; Condition = condition; Action = action; Body = body; }
private BoundStatement GetBoundInsertStatementBasedOnEntity(ManyDataTypesEntity entity) { BoundStatement boundStatement = _preparedStatement.Bind(ConvertEntityToObjectArray(entity)); return(boundStatement); }
/// <summary> /// Creates a new BoundStatement object and bind its variables to the provided /// values. This method is a shortcut for <code>new /// BoundStatement(this).Bind(...)</code>. <p> Note that while no more /// <code>values</code> than bound variables can be provided, it is allowed to /// provide less <code>values</code> that there is variables. In that case, the /// remaining variables will have to be bound to values by another mean because /// the resulting <code>BoundStatement</code> being executable.</p> /// </summary> /// <param name="values"> the values to bind to the variables of the newly /// created BoundStatement. </param> /// /// <returns>the newly created <code>BoundStatement</code> with its variables /// bound to <code>values</code>. </returns> public BoundStatement Bind(params object[] values) { var bs = new BoundStatement(this); return(bs.Bind(values)); }
/// <summary> /// Adds statement to the block. /// </summary> internal void Add(BoundStatement stmt) { Contract.ThrowIfNull(stmt); _statements.Add(stmt); }
public BoundWhileStatement(BoundExpression condition, BoundStatement statement) { Condition = condition; Statement = statement; }
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics) { AnonymousTypeManager manager = ((AnonymousTypeTemplateSymbol)this.ContainingType).Manager; SyntheticBoundNodeFactory F = this.CreateBoundNodeFactory(compilationState, diagnostics); // Method body: // // { // $anonymous$ local = value as $anonymous$; // return local != null // && System.Collections.Generic.EqualityComparer<T_1>.Default.Equals(this.backingFld_1, local.backingFld_1) // ... // && System.Collections.Generic.EqualityComparer<T_N>.Default.Equals(this.backingFld_N, local.backingFld_N); // } // Type and type expression AnonymousTypeTemplateSymbol anonymousType = (AnonymousTypeTemplateSymbol)this.ContainingType; // local BoundAssignmentOperator assignmentToTemp; BoundLocal boundLocal = F.StoreToTemp(F.As(F.Parameter(_parameters[0]), anonymousType), out assignmentToTemp); // Generate: statement <= 'local = value as $anonymous$' BoundStatement assignment = F.ExpressionStatement(assignmentToTemp); // Generate expression for return statement // retExpression <= 'local != null' BoundExpression retExpression = F.Binary(BinaryOperatorKind.ObjectNotEqual, manager.System_Boolean, F.Convert(manager.System_Object, boundLocal), F.Null(manager.System_Object)); // prepare symbols MethodSymbol equalityComparer_Equals = manager.System_Collections_Generic_EqualityComparer_T__Equals; MethodSymbol equalityComparer_get_Default = manager.System_Collections_Generic_EqualityComparer_T__get_Default; NamedTypeSymbol equalityComparerType = equalityComparer_Equals.ContainingType; // Compare fields for (int index = 0; index < anonymousType.Properties.Length; index++) { // Prepare constructed symbols TypeParameterSymbol typeParameter = anonymousType.TypeParameters[index]; FieldSymbol fieldSymbol = anonymousType.Properties[index].BackingField; NamedTypeSymbol constructedEqualityComparer = equalityComparerType.Construct(typeParameter); // Generate 'retExpression' = 'retExpression && System.Collections.Generic.EqualityComparer<T_index>. // Default.Equals(this.backingFld_index, local.backingFld_index)' retExpression = F.LogicalAnd(retExpression, F.Call(F.StaticCall(constructedEqualityComparer, equalityComparer_get_Default.AsMember(constructedEqualityComparer)), equalityComparer_Equals.AsMember(constructedEqualityComparer), F.Field(F.This(), fieldSymbol), F.Field(boundLocal, fieldSymbol))); } // Final return statement BoundStatement retStatement = F.Return(retExpression); // Create a bound block F.CloseMethod(F.Block(ImmutableArray.Create <LocalSymbol>(boundLocal.LocalSymbol), assignment, retStatement)); }
private BoundStatement RewriteForStatement( BoundForStatement node, BoundStatement rewrittenInitializer, BoundExpression rewrittenCondition, BoundStatement rewrittenIncrement, BoundStatement rewrittenBody) { if (node.InnerLocals.IsEmpty) { return(RewriteForStatementWithoutInnerLocals( node, node.OuterLocals, rewrittenInitializer, rewrittenCondition, rewrittenIncrement, rewrittenBody, null, node.BreakLabel, node.ContinueLabel, node.HasErrors)); } // We need to enter inner_scope-block from the top, that is where an instance of a display class will be created // if any local is captured within a lambda. // for (initializer; condition; increment) // body; // // becomes the following (with block added for locals) // // { // initializer; // start: // { // GotoIfFalse condition break; // body; // continue: // increment; // goto start; // } // break: // } Debug.Assert(rewrittenBody != null); SyntaxNode syntax = node.Syntax; var statementBuilder = ArrayBuilder <BoundStatement> .GetInstance(); // initializer; if (rewrittenInitializer != null) { statementBuilder.Add(rewrittenInitializer); } var startLabel = new GeneratedLabelSymbol("start"); // start: BoundStatement startLabelStatement = new BoundLabelStatement(syntax, startLabel); if (Instrument) { startLabelStatement = new BoundSequencePoint(null, startLabelStatement); } statementBuilder.Add(startLabelStatement); var blockBuilder = ArrayBuilder <BoundStatement> .GetInstance(); // GotoIfFalse condition break; if (rewrittenCondition != null) { BoundStatement ifNotConditionGotoBreak = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, node.BreakLabel); blockBuilder.Add(ifNotConditionGotoBreak); } // body; blockBuilder.Add(rewrittenBody); // continue: // increment; blockBuilder.Add(new BoundLabelStatement(syntax, node.ContinueLabel)); if (rewrittenIncrement != null) { blockBuilder.Add(rewrittenIncrement); } // goto start; blockBuilder.Add(new BoundGotoStatement(syntax, startLabel)); statementBuilder.Add(new BoundBlock(syntax, node.InnerLocals, blockBuilder.ToImmutableAndFree())); // break: statementBuilder.Add(new BoundLabelStatement(syntax, node.BreakLabel)); var statements = statementBuilder.ToImmutableAndFree(); return(new BoundBlock(syntax, node.OuterLocals, statements, node.HasErrors)); }
private BoundStatement RewriteForStatementWithoutInnerLocals( BoundLoopStatement original, ImmutableArray <LocalSymbol> outerLocals, BoundStatement rewrittenInitializer, BoundExpression rewrittenCondition, BoundStatement rewrittenIncrement, BoundStatement rewrittenBody, BoundStatement afterBreak, GeneratedLabelSymbol breakLabel, GeneratedLabelSymbol continueLabel, bool hasErrors) { Debug.Assert(original.Kind == BoundKind.ForStatement || original.Kind == BoundKind.ForEachStatement); Debug.Assert(rewrittenBody != null); // The sequence point behavior exhibited here is different from that of the native compiler. In the native // compiler, if you have something like // // for([|int i = 0, j = 0|]; ; [|i++, j++|]) // // then all the initializers are treated as a single sequence point, as are // all the loop incrementors. // // We now make each one individually a sequence point: // // for([|int i = 0|], [|j = 0|]; ; [|i++|], [|j++|]) // // If we decide that we want to preserve the native compiler stepping behavior // then we'll need to be a bit fancy here. The initializer and increment statements // can contain lambdas whose bodies need to have sequence points inserted, so we // need to make sure we visit the children. But we'll also need to make sure that // we do not generate one sequence point for each statement in the initializers // and the incrementors. SyntaxNode syntax = original.Syntax; var statementBuilder = ArrayBuilder <BoundStatement> .GetInstance(); if (rewrittenInitializer != null) { statementBuilder.Add(rewrittenInitializer); } var startLabel = new GeneratedLabelSymbol("start"); // 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: // } var endLabel = new GeneratedLabelSymbol("end"); // initializer; // goto end; BoundStatement gotoEnd = new BoundGotoStatement(syntax, endLabel); if (this.Instrument) { // 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 gotoEnd = new BoundSequencePoint(null, gotoEnd); } statementBuilder.Add(gotoEnd); // start: // body; statementBuilder.Add(new BoundLabelStatement(syntax, startLabel)); 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.Instrument) { switch (original.Kind) { case BoundKind.ForEachStatement: branchBack = _instrumenter.InstrumentForEachStatementConditionalGotoStart((BoundForEachStatement)original, branchBack); break; default: throw ExceptionUtilities.UnexpectedValue(original.Kind); } } statementBuilder.Add(branchBack); // break: statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel)); if (afterBreak != null) { statementBuilder.Add(afterBreak); } var statements = statementBuilder.ToImmutableAndFree(); return(new BoundBlock(syntax, outerLocals, statements, hasErrors)); }
private static TypeSymbol CalculateReturnType(CSharpCompilation compilation, BoundStatement bodyOpt) { if (bodyOpt == null) { // If the method doesn't do anything, then it doesn't return anything. return compilation.GetSpecialType(SpecialType.System_Void); } switch (bodyOpt.Kind) { case BoundKind.ReturnStatement: return ((BoundReturnStatement)bodyOpt).ExpressionOpt.Type; case BoundKind.ExpressionStatement: case BoundKind.LocalDeclaration: case BoundKind.MultipleLocalDeclarations: return compilation.GetSpecialType(SpecialType.System_Void); default: throw ExceptionUtilities.UnexpectedValue(bodyOpt.Kind); } }
public static void Run(MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints) { CodeGenerator generator = new CodeGenerator(method, block, builder, module, diagnostics, optimize, emitSequencePoints); generator.Generate(); Debug.Assert(generator.asyncCatchHandlerOffset < 0); Debug.Assert(generator.asyncYieldPoints == null); Debug.Assert(generator.asyncResumePoints == null); if (!diagnostics.HasAnyErrors()) { builder.Realize(); } }
public Task IncLikesAsync(string itemId) { BoundStatement boundStatement = _incLikesStatement.Value.Bind(itemId); return(_session.Get().ExecuteAsync(boundStatement)); }
public BoundWhileStatement(BoundExpression condition, BoundStatement body, BoundLabel breakLabel, BoundLabel continueLabel) : base(breakLabel, continueLabel) { Condition = condition; Body = body; }
/// <summary> /// Should only be used with scopes that could declare local functions. /// </summary> internal BoundStatement WrapWithVariablesAndLocalFunctionsIfAny(CSharpSyntaxNode scopeDesignator, BoundStatement statement) { var locals = this.GetDeclaredLocalsForScope(scopeDesignator); var localFunctions = this.GetDeclaredLocalFunctionsForScope(scopeDesignator); if (locals.IsEmpty && localFunctions.IsEmpty) { return(statement); } return(new BoundBlock(statement.Syntax, locals, localFunctions, false, ImmutableArray.Create(statement)) { WasCompilerGenerated = true }); }
public CodeGenerator( MethodSymbol method, BoundStatement boundBody, ILBuilder builder, PEModuleBuilder moduleBuilder, DiagnosticBag diagnostics, OptimizationLevel optimizations, bool emittingPdb) { Debug.Assert((object)method != null); Debug.Assert(boundBody != null); Debug.Assert(builder != null); Debug.Assert(moduleBuilder != null); Debug.Assert(diagnostics != null); _method = method; _boundBody = boundBody; _builder = builder; _module = moduleBuilder; _diagnostics = diagnostics; if (!method.GenerateDebugInfo) { // Always optimize synthesized methods that don't contain user code. // // Specifically, always optimize synthesized explicit interface implementation methods // (aka bridge methods) with by-ref returns because peverify produces errors if we // return a ref local (which the return local will be in such cases). _ilEmitStyle = ILEmitStyle.Release; } else { if (optimizations == OptimizationLevel.Debug) { _ilEmitStyle = ILEmitStyle.Debug; } else { _ilEmitStyle = IsDebugPlus() ? ILEmitStyle.DebugFriendlyRelease : ILEmitStyle.Release; } } // Emit sequence points unless // - the PDBs are not being generated // - debug information for the method is not generated since the method does not contain // user code that can be stepped through, or changed during EnC. // // This setting only affects generating PDB sequence points, it shall not affect generated IL in any way. _emitPdbSequencePoints = emittingPdb && method.GenerateDebugInfo; try { _boundBody = Optimizer.Optimize( boundBody, debugFriendly: _ilEmitStyle != ILEmitStyle.Release, stackLocals: out _stackLocals); } catch (BoundTreeVisitor.CancelledByStackGuardException ex) { ex.AddAnError(diagnostics); _boundBody = boundBody; } var sourceMethod = method as SourceMemberMethodSymbol; (BlockSyntax blockBody, ArrowExpressionClauseSyntax expressionBody) = sourceMethod?.Bodies ?? default; _methodBodySyntaxOpt = (SyntaxNode)blockBody ?? expressionBody ?? sourceMethod?.SyntaxNode; }
/// <summary> /// Perform flow analysis, reporting all necessary diagnostics. Returns true if the end of /// the body might be reachable.. /// </summary> /// <param name="compilation"></param> /// <param name="tree"></param> /// <param name="method"></param> /// <param name="block"></param> /// <param name="diagnostics"></param> /// <returns></returns> public static bool Analyze(Compilation compilation, SyntaxTree tree, MethodSymbol method, BoundStatement block, DiagnosticBag diagnostics) { var walker = new FlowAnalysisWalker(compilation, tree, method, block); var result = walker.Analyze(diagnostics); walker.Free(); return result; }
public BoundWhileStatement(BoundExpression condition, BoundStatement body) { Condition = condition; Body = body; }
/// <summary> /// Return the first nonempty statement in the given statement, or null if it is all empty. /// This is used to reproduce the Dev10 behavior for unreachable statements, where the /// diagnostic is only reported when there is a "nonempty" statement. /// </summary> private BoundStatement FirstNonempty(BoundStatement statement) { if (statement == null) { return null; } switch (statement.Kind) { default: return statement; case BoundKind.Block: foreach (var s in ((BoundBlock)statement).Statements) { var result = FirstNonempty(s); if (result != null) return result; } return null; case BoundKind.NoOpStatement: return null; } }
public BoundTryCatchStatement(BoundStatement normalStatement, BoundStatement exceptionStatement) { NormalStatement = normalStatement; ExceptionStatement = exceptionStatement; }
/// <summary> /// Creates a new BoundStatement object and bind its variables to the provided /// values. This method is a shortcut for <code>new /// BoundStatement(this).Bind(...)</code>. <p> Note that while no more /// <code>values</code> than bound variables can be provided, it is allowed to /// provide less <code>values</code> that there is variables. In that case, the /// remaining variables will have to be bound to values by another mean because /// the resulting <code>BoundStatement</code> being executable.</p> /// </summary> /// <param name="values"> the values to bind to the variables of the newly /// created BoundStatement. </param> /// /// <returns>the newly created <code>BoundStatement</code> with its variables /// bound to <code>values</code>. </returns> public BoundStatement Bind(params object[] values) { var bs = new BoundStatement(this); return bs.Bind(values); }
public void copyData(int fedID, string projectNumber, string projectName) { OracleConnection oraConn = DBOperation.Connect(); ISession CSSession = CassandraDB.connect(); CSSession.UserDefinedTypes.Define(UdtMap.For <CSType>(), UdtMap.For <CSPoint>(), UdtMap.For <CSGeometry>(), UdtMap.For <CSMatrix3D>(), UdtMap.For <CSSpatialIndex>(), UdtMap.For <CSTopoFace>(), UdtMap.For <CSProperty>(), UdtMap.For <CSMaterial>(), UdtMap.For <CSClassification>()); PreparedStatement modelIns = CSSession.Prepare("Insert into bimrl_federatedmodel (projectnumber, projectname, federatedid, lastupdatedate, maxoctreelevel, projectid, worldbox) " + "values (?, ?, ?, ?, ?, ?, ?)"); PreparedStatement elemInsPrep = CSSession.Prepare("Insert into bimrl_element (federatedmodelid, projectname, projectnumber, elementid, lineno, elementtype, modelid, type, name, longname, " + "ownerhistoryid, description, objecttype, tag, container, geometrybody, geometrybody_bbox, geometrybody_bbox_centroid, geometryfootprint, geometryaxis, " + "transform, obb_major_axis, obb_major_axis_centroid, obb) " + "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); // Delete existing data first if already exists deleteData(fedID); string sqlStmt = string.Empty; sqlStmt = "Select e.elementid, e.lineno, e.elementtype, e.modelid, e.typeid, e.name, e.longname, e.ownerhistoryid, e.description, e.objecttype, " + "e.tag, e.container, e.geometrybody, e.geometrybody_bbox, e.geometrybody_bbox_centroid, e.geometryfootprint, e.geometryaxis, e.transform_x_axis, e.transform_y_axis, e.transform_z_axis, " + "e.body_major_axis1, e.body_major_axis2, e.body_major_axis3, e.body_major_axis_cnetroid, e.obb, t.elementid, t.ifctype, t.name, t.description, t.ownerhistoryid, " + "t.modelid, t.applicableoccurence, t.tag, t.elementtype, t.predefinedtype, t.assembyplace, t.operationtype, t.constructiontype " + "from bimrl_element_" + fedID.ToString("X4") + " e, bimrl_type_" + fedID.ToString("X4") + " t where t.elementid (+) =e.typeid"; OracleCommand command = new OracleCommand(sqlStmt, oraConn); command.CommandText = sqlStmt; command.FetchSize = 1000; OracleDataReader reader = command.ExecuteReader(); while (reader.Read()) { CSType bType = new CSType(); bType.typeid = reader.GetString(22); bType.ifctype = reader.GetString(23); bType.name = reader.GetString(24); bType.description = reader.GetString(25); bType.ownerhistoryid = reader.GetInt32(26); bType.applicableoccurence = SafeGetString(reader, 27); bType.tag = SafeGetString(reader, 28); bType.elementtype = reader.GetString(29); bType.predefinedtype = reader.GetString(30); bType.assemblyplace = reader.GetString(31); bType.operationtype = reader.GetString(32); bType.constructiontype = reader.GetString(33); List <CSPoint> transf = new List <CSPoint>(); transf.Add(CSpointFromSdoGeom(reader, 17)); transf.Add(CSpointFromSdoGeom(reader, 18)); transf.Add(CSpointFromSdoGeom(reader, 19)); CSMatrix3D transform = new CSMatrix3D(); transform.matrix3d = transf; List <CSPoint> mjAxis = new List <CSPoint>(); mjAxis.Add(CSpointFromSdoGeom(reader, 20)); mjAxis.Add(CSpointFromSdoGeom(reader, 21)); mjAxis.Add(CSpointFromSdoGeom(reader, 22)); CSMatrix3D mjAxisMatrix = new CSMatrix3D(); mjAxisMatrix.matrix3d = mjAxis; NetSdoGeometry.SdoGeometry bodyMjAxisCentroid = reader.GetValue(20) as NetSdoGeometry.SdoGeometry; NetSdoGeometry.SdoGeometry obb = reader.GetValue(21) as NetSdoGeometry.SdoGeometry; BoundStatement boundStmt = elemInsPrep.Bind(fedID, projectName, projectNumber, reader.GetString(0), reader.GetInt32(1), reader.GetString(2), reader.GetInt32(3), bType, SafeGetString(reader, 5), SafeGetString(reader, 6), SafeGetValue(reader, 7), SafeGetString(reader, 8), SafeGetString(reader, 9), SafeGetString(reader, 10), SafeGetString(reader, 11), CSgeomFromSdoGeom(reader, 12), CSgeomFromSdoGeom(reader, 13), CSpointFromSdoGeom(reader, 14), CSgeomFromSdoGeom(reader, 15), CSgeomFromSdoGeom(reader, 16), transform, mjAxisMatrix, CSpointFromSdoGeom(reader, 23), CSgeomFromSdoGeom(reader, 24)); CSSession.Execute(boundStmt); } }
/// <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); } }
internal BoundStatement WrapWithVariablesIfAny(CSharpSyntaxNode scopeDesignator, BoundStatement statement) { Debug.Assert(statement.Kind != BoundKind.StatementList); var locals = this.GetDeclaredLocalsForScope(scopeDesignator); if (locals.IsEmpty) { return(statement); } return(new BoundBlock(statement.Syntax, locals, ImmutableArray.Create(statement)) { WasCompilerGenerated = true }); }
public override void LoadData() { PreparedStatement statement = Session.Prepare( "INSERT INTO simplex.songs " + "(id, title, album, artist, tags) " + "VALUES (?, ?, ?, ?, ?);"); BoundStatement boundStatement = new BoundStatement(statement); HashSet <String> tags = new HashSet <String>(); tags.Add("jazz"); tags.Add("2013"); Session.Execute(boundStatement.Bind( new Guid("756716f7-2e54-4715-9f00-91dcbea6cf50"), "La Petite Tonkinoise'", "Bye Bye Blackbird'", "Joséphine Baker", tags) ); tags = new HashSet <String>(); tags.Add("1996"); tags.Add("nirds"); Session.Execute(boundStatement.Bind( new Guid("f6071e72-48ec-4fcb-bf3e-379c8a696488"), "Die Mösch", "In Gold'", "Willi Ostermann", tags) ); tags = new HashSet <String>(); tags.Add("1970"); tags.Add("soundtrack"); Session.Execute(boundStatement.Bind( new Guid("fbdf82ed-0063-4796-9c7c-a3d4f47b4b25"), "Memo From Turner", "Performance", "Mick Jager", tags) ); // playlists table statement = Session.Prepare( "INSERT INTO simplex.playlists " + "(id, song_id, title, album, artist) " + "VALUES (?, ?, ?, ?, ?);"); boundStatement = new BoundStatement(statement); Session.Execute(boundStatement.Bind( new Guid("2cc9ccb7-6221-4ccb-8387-f22b6a1b354d"), new Guid("756716f7-2e54-4715-9f00-91dcbea6cf50"), "La Petite Tonkinoise", "Bye Bye Blackbird", "Joséphine Baker")); Session.Execute(boundStatement.Bind( new Guid("2cc9ccb7-6221-4ccb-8387-f22b6a1b354d"), new Guid("f6071e72-48ec-4fcb-bf3e-379c8a696488"), "Die Mösch", "In Gold", "Willi Ostermann")); Session.Execute(boundStatement.Bind( new Guid("3fd2bedf-a8c8-455a-a462-0cd3a4353c54"), new Guid("fbdf82ed-0063-4796-9c7c-a3d4f47b4b25"), "Memo From Turner", "Performance", "Mick Jager")); }
internal static BoundStatement AddSequencePoint(UsingStatementSyntax usingSyntax, BoundStatement rewrittenStatement) { int start = usingSyntax.Span.Start; int end = usingSyntax.CloseParenToken.Span.End; TextSpan span = TextSpan.FromBounds(start, end); return(new BoundSequencePointWithSpan(usingSyntax, rewrittenStatement, span)); }
public BoundDoStatement(BoundExpression condition, BoundStatement body) : base(BoundNodeKind.DoStatement) { Condition = condition; Body = body; }
internal static BoundStatement AddSequencePoint(PropertyDeclarationSyntax declarationSyntax, BoundStatement rewrittenStatement) { Debug.Assert(declarationSyntax.Initializer != null); int start = declarationSyntax.Initializer.Value.SpanStart; int end = declarationSyntax.Initializer.Span.End; TextSpan part = TextSpan.FromBounds(start, end); var result = BoundSequencePoint.Create(declarationSyntax, part, rewrittenStatement); result.WasCompilerGenerated = rewrittenStatement.WasCompilerGenerated; return(result); }
public static void Run(MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints, out int asyncCatchHandlerOffset, out ImmutableArray<int> asyncYieldPoints, out ImmutableArray<int> asyncResumePoints) { CodeGenerator generator = new CodeGenerator(method, block, builder, module, diagnostics, optimize, emitSequencePoints); generator.Generate(); if (!diagnostics.HasAnyErrors()) { builder.Realize(); } asyncCatchHandlerOffset = (generator.asyncCatchHandlerOffset < 0) ? -1 : generator.builder.GetILOffsetFromMarker(generator.asyncCatchHandlerOffset); ArrayBuilder<int> yieldPoints = generator.asyncYieldPoints; ArrayBuilder<int> resumePoints = generator.asyncResumePoints; if (yieldPoints == null) { asyncYieldPoints = ImmutableArray<int>.Empty; asyncResumePoints = ImmutableArray<int>.Empty; } else { var yieldPointBuilder = ArrayBuilder<int>.GetInstance(); var resumePointBuilder = ArrayBuilder<int>.GetInstance(); int n = yieldPoints.Count; for (int i = 0; i < n; i++) { int yieldOffset = generator.builder.GetILOffsetFromMarker(yieldPoints[i]); int resumeOffset = generator.builder.GetILOffsetFromMarker(resumePoints[i]); Debug.Assert(resumeOffset >= 0); // resume marker should always be reachable from dispatch // yield point may not be reachable if the whole // await is not reachable; we just ignore such awaits if (yieldOffset > 0) { yieldPointBuilder.Add(yieldOffset); resumePointBuilder.Add(resumeOffset); } } asyncYieldPoints = yieldPointBuilder.ToImmutableAndFree(); asyncResumePoints = resumePointBuilder.ToImmutableAndFree(); yieldPoints.Free(); resumePoints.Free(); } }
internal static BoundStatement AddSequencePoint(VariableDeclarationSyntax declaratorSyntax, BoundStatement rewrittenStatement) { SyntaxNode node; TextSpan? part; GetBreakpointSpan(declaratorSyntax, out node, out part); var result = BoundSequencePoint.Create(declaratorSyntax, part, rewrittenStatement); result.WasCompilerGenerated = rewrittenStatement.WasCompilerGenerated; return(result); }
private BoundStatement AddSequencePoint(BoundStatement node) { return(new BoundSequencePoint(node.Syntax, node)); }
public BoundGlobalScope(BoundGlobalScope previous, ImmutableArray <Diagnostic> diagnostics, ImmutableArray <VariableSymbol> variables, BoundStatement statement) { Previous = previous; Diagnostics = diagnostics; Variables = variables; Statement = statement; }
private void EmitStatement(BoundStatement statement) { switch (statement.Kind) { case BoundKind.Block: EmitBlock((BoundBlock)statement); break; case BoundKind.SequencePoint: this.EmitSequencePointStatement((BoundSequencePoint)statement); break; case BoundKind.SequencePointWithSpan: this.EmitSequencePointStatement((BoundSequencePointWithSpan)statement); break; case BoundKind.ExpressionStatement: EmitExpression(((BoundExpressionStatement)statement).Expression, false); break; case BoundKind.StatementList: EmitStatementList((BoundStatementList)statement); break; case BoundKind.ReturnStatement: EmitReturnStatement((BoundReturnStatement)statement); break; case BoundKind.GotoStatement: EmitGotoStatement((BoundGotoStatement)statement); break; case BoundKind.LabelStatement: EmitLabelStatement((BoundLabelStatement)statement); break; case BoundKind.ConditionalGoto: EmitConditionalGoto((BoundConditionalGoto)statement); break; case BoundKind.ThrowStatement: EmitThrowStatement((BoundThrowStatement)statement); break; case BoundKind.TryStatement: EmitTryStatement((BoundTryStatement)statement); break; case BoundKind.SwitchStatement: EmitSwitchStatement((BoundSwitchStatement)statement); break; case BoundKind.StateMachineScope: EmitStateMachineScope((BoundStateMachineScope)statement); break; case BoundKind.NoOpStatement: EmitNoOpStatement((BoundNoOpStatement)statement); break; default: // Code gen should not be invoked if there are errors. throw ExceptionUtilities.UnexpectedValue(statement.Kind); } #if DEBUG if (_stackLocals == null || _stackLocals.Count == 0) { _builder.AssertStackEmpty(); } #endif }
public static BoundStatement Rewrite(BoundStatement node) { Debug.Assert(node != null); return (BoundStatement)Instance.Visit(node); }
public static BoundStatement Rewrite(BoundStatement src, Dictionary<LocalSymbol, LocalDefUseInfo> info) { var scheduler = new StackOptimizerPass2(info); return (BoundStatement)scheduler.Visit(src); }
protected FlowAnalysisWalker( Compilation compilation, SyntaxTree tree, MethodSymbol method, BoundStatement block, ThisSymbolCache thisSymbolCache = null, HashSet<Symbol> initiallyAssignedVariables = null, bool trackUnassignmentsInLoops = false) { this.compilation = compilation; this.tree = tree; this.method = method; this.block = block; this.thisSymbolCache = thisSymbolCache ?? new ThisSymbolCache(); this.initiallyAssignedVariables = initiallyAssignedVariables; this.loopHeadState = trackUnassignmentsInLoops ? new Dictionary<BoundLoopStatement, FlowAnalysisLocalState>() : null; // TODO: mark "this" as not assigned in a struct constructor (unless it has no fields) // TODO: accommodate instance variables of a local variable of struct type. }
private static bool CanFallThrough(BoundStatement boundStatement) { return(boundStatement.Kind != BoundNodeKind.ReturnStatement && boundStatement.Kind != BoundNodeKind.GotoStatement); }