/// <summary> /// If the condition has a constant value, then just use the selected branch. /// e.g. "true ? x : y" becomes "x". /// </summary> public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { // just a fact, not a requirement (VisitExpression would have rewritten otherwise) Debug.Assert(node.ConstantValue == null); var rewrittenCondition = VisitExpression(node.Condition); var rewrittenConsequence = VisitExpression(node.Consequence); var rewrittenAlternative = VisitExpression(node.Alternative); if (rewrittenCondition.ConstantValue == null) { return(node.Update( node.IsRef, rewrittenCondition, rewrittenConsequence, rewrittenAlternative, node.ConstantValueOpt, node.NaturalTypeOpt, node.WasTargetTyped, node.Type )); } return(RewriteConditionalOperator( node.Syntax, rewrittenCondition, rewrittenConsequence, rewrittenAlternative, node.ConstantValueOpt, node.Type, node.IsRef )); }
public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { BoundSpillSequenceBuilder conditionBuilder = null; var condition = VisitExpression(ref conditionBuilder, node.Condition); BoundSpillSequenceBuilder consequenceBuilder = null; var consequence = VisitExpression(ref consequenceBuilder, node.Consequence); BoundSpillSequenceBuilder alternativeBuilder = null; var alternative = VisitExpression(ref alternativeBuilder, node.Alternative); if (consequenceBuilder == null && alternativeBuilder == null) { return(UpdateExpression(conditionBuilder, node.Update(condition, consequence, alternative, node.ConstantValueOpt, node.Type))); } if (conditionBuilder == null) { conditionBuilder = new BoundSpillSequenceBuilder(); } if (consequenceBuilder == null) { consequenceBuilder = new BoundSpillSequenceBuilder(); } if (alternativeBuilder == null) { alternativeBuilder = new BoundSpillSequenceBuilder(); } if (node.Type.SpecialType == SpecialType.System_Void) { conditionBuilder.AddStatement( _F.If(condition, UpdateStatement(consequenceBuilder, _F.ExpressionStatement(consequence), substituteTemps: false), UpdateStatement(alternativeBuilder, _F.ExpressionStatement(alternative), substituteTemps: false))); return(conditionBuilder.Update(_F.Default(node.Type))); } else { Debug.Assert(_F.Syntax.IsKind(SyntaxKind.AwaitExpression)); var tmp = _F.SynthesizedLocal(node.Type, kind: SynthesizedLocalKind.AwaitSpill, syntax: _F.Syntax); conditionBuilder.AddLocal(tmp, _F.Diagnostics); conditionBuilder.AddStatement( _F.If(condition, UpdateStatement(consequenceBuilder, _F.Assignment(_F.Local(tmp), consequence), substituteTemps: false), UpdateStatement(alternativeBuilder, _F.Assignment(_F.Local(tmp), alternative), substituteTemps: false))); return(conditionBuilder.Update(_F.Local(tmp))); } }
public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { BoundSpillSequenceBuilder conditionBuilder = null; var condition = VisitExpression(ref conditionBuilder, node.Condition); BoundSpillSequenceBuilder consequenceBuilder = null; var consequence = VisitExpression(ref consequenceBuilder, node.Consequence); BoundSpillSequenceBuilder alternativeBuilder = null; var alternative = VisitExpression(ref alternativeBuilder, node.Alternative); if (consequenceBuilder == null && alternativeBuilder == null) { return(UpdateExpression(conditionBuilder, node.Update(node.IsRef, condition, consequence, alternative, node.ConstantValueOpt, node.Type))); } if (conditionBuilder == null) { conditionBuilder = new BoundSpillSequenceBuilder(); } if (consequenceBuilder == null) { consequenceBuilder = new BoundSpillSequenceBuilder(); } if (alternativeBuilder == null) { alternativeBuilder = new BoundSpillSequenceBuilder(); } if (node.Type.IsVoidType()) { conditionBuilder.AddStatement( _F.If(condition, UpdateStatement(consequenceBuilder, _F.ExpressionStatement(consequence)), UpdateStatement(alternativeBuilder, _F.ExpressionStatement(alternative)))); return(conditionBuilder.Update(_F.Default(node.Type))); } else { var tmp = _F.SynthesizedLocal(node.Type, kind: SynthesizedLocalKind.Spill, syntax: _F.Syntax); conditionBuilder.AddLocal(tmp); conditionBuilder.AddStatement( _F.If(condition, UpdateStatement(consequenceBuilder, _F.Assignment(_F.Local(tmp), consequence)), UpdateStatement(alternativeBuilder, _F.Assignment(_F.Local(tmp), alternative)))); return(conditionBuilder.Update(_F.Local(tmp))); } }
/// <summary> /// If the condition has a constant value, then just use the selected branch. /// e.g. "true ? x : y" becomes "x". /// </summary> public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { // just a fact, not a requirement (VisitExpression would have rewritten otherwise) Debug.Assert(node.ConstantValue == null); var rewrittenCondition = VisitExpression(node.Condition); var rewrittenConsequence = VisitExpression(node.Consequence); var rewrittenAlternative = VisitExpression(node.Alternative); if (rewrittenCondition.ConstantValue == null) { return node.Update(rewrittenCondition, rewrittenConsequence, rewrittenAlternative, node.ConstantValueOpt, node.Type); } return RewriteConditionalOperator( node.Syntax, rewrittenCondition, rewrittenConsequence, rewrittenAlternative, node.ConstantValueOpt, node.Type); }
public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { BoundExpression condition = (BoundExpression)this.Visit(node.Condition); BoundExpression consequence = (BoundExpression)this.Visit(node.Consequence); BoundExpression alternative = (BoundExpression)this.Visit(node.Alternative); TypeSymbol type = this.VisitType(node.Type); if (!RequiresSpill(condition, consequence, alternative)) { return(node.Update(condition, consequence, alternative, node.ConstantValueOpt, type)); } var spillBuilder = new SpillBuilder(); LocalSymbol resultLocal = F.SynthesizedLocal(type, null); spillBuilder.Locals.Add(resultLocal); BoundExpression newCondition; if (condition.Kind == BoundKind.SpillSequence) { var spill = (BoundSpillSequence)condition; spillBuilder.AddSpill(spill); newCondition = spill.Value; } else { newCondition = condition; } spillBuilder.Statements.Add( F.If( condition: newCondition, thenClause: CrushExpression(consequence, resultLocal), elseClause: CrushExpression(alternative, resultLocal))); return(spillBuilder.BuildSequenceAndFree(F, F.Local(resultLocal))); }
public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { BoundSpillSequence2 ss1 = null; var condition = VisitExpression(ref ss1, node.Condition); BoundSpillSequence2 ss2 = null; var consequence = VisitExpression(ref ss2, node.Consequence); BoundSpillSequence2 ss3 = null; var alternative = VisitExpression(ref ss3, node.Alternative); if (ss2 == null && ss3 == null) { return(UpdateExpression(ss1, node.Update(condition, consequence, alternative, node.ConstantValueOpt, node.Type))); } var tmp = F.SynthesizedLocal(node.Type); if (ss1 == null) { ss1 = new BoundSpillSequence2(); } if (ss2 == null) { ss2 = new BoundSpillSequence2(); } if (ss3 == null) { ss3 = new BoundSpillSequence2(); } ss1.Add(tmp); ss1.Add( F.If(condition, UpdateStatement(ss2, F.Assignment(F.Local(tmp), consequence)), UpdateStatement(ss3, F.Assignment(F.Local(tmp), alternative)))); return(ss1.Update(F.Local(tmp))); }
public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { BoundSpillSequence2 ss1 = null; var condition = VisitExpression(ref ss1, node.Condition); BoundSpillSequence2 ss2 = null; var consequence = VisitExpression(ref ss2, node.Consequence); BoundSpillSequence2 ss3 = null; var alternative = VisitExpression(ref ss3, node.Alternative); if (ss2 == null && ss3 == null) { return UpdateExpression(ss1, node.Update(condition, consequence, alternative, node.ConstantValueOpt, node.Type)); } var tmp = F.SynthesizedLocal(node.Type); if (ss1 == null) ss1 = new BoundSpillSequence2(); if (ss2 == null) ss2 = new BoundSpillSequence2(); if (ss3 == null) ss3 = new BoundSpillSequence2(); ss1.Add(tmp); ss1.Add( F.If(condition, UpdateStatement(ss2, F.Assignment(F.Local(tmp), consequence)), UpdateStatement(ss3, F.Assignment(F.Local(tmp), alternative)))); return ss1.Update(F.Local(tmp)); }
public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { BoundExpression condition = (BoundExpression)this.Visit(node.Condition); BoundExpression consequence = (BoundExpression)this.Visit(node.Consequence); BoundExpression alternative = (BoundExpression)this.Visit(node.Alternative); TypeSymbol type = this.VisitType(node.Type); if (!RequiresSpill(condition, consequence, alternative)) { return node.Update(condition, consequence, alternative, node.ConstantValueOpt, type); } var spillBuilder = new SpillBuilder(); LocalSymbol resultLocal = F.SynthesizedLocal(type, null); spillBuilder.Locals.Add(resultLocal); BoundExpression newCondition; if (condition.Kind == BoundKind.SpillSequence) { var spill = (BoundSpillSequence)condition; spillBuilder.AddSpill(spill); newCondition = spill.Value; } else { newCondition = condition; } spillBuilder.Statements.Add( F.If( condition: newCondition, thenClause: CrushExpression(consequence, resultLocal), elseClause: CrushExpression(alternative, resultLocal))); return spillBuilder.BuildSequenceAndFree(F, F.Local(resultLocal)); }