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.SpecialType == SpecialType.System_Void) { 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(node.IsRef, rewrittenCondition, rewrittenConsequence, rewrittenAlternative, node.ConstantValueOpt, node.Type)); } return(RewriteConditionalOperator( node.Syntax, rewrittenCondition, rewrittenConsequence, rewrittenAlternative, node.ConstantValueOpt, node.Type, node.IsRef)); }