internal override BoundStatement BindSwitchStatementCore(SwitchStatementSyntax node, Binder originalBinder, BindingDiagnosticBag diagnostics)
        {
            Debug.Assert(SwitchSyntax.Equals(node));

            if (node.Sections.Count == 0)
            {
                diagnostics.Add(ErrorCode.WRN_EmptySwitch, node.OpenBraceToken.GetLocation());
            }

            // Bind switch expression and set the switch governing type.
            BoundExpression boundSwitchGoverningExpression = SwitchGoverningExpression;

            diagnostics.AddRange(SwitchGoverningDiagnostics, allowMismatchInDependencyAccumulation: true);

            ImmutableArray <BoundSwitchSection>  switchSections = BindSwitchSections(originalBinder, diagnostics, out BoundSwitchLabel defaultLabel);
            ImmutableArray <LocalSymbol>         locals         = GetDeclaredLocalsForScope(node);
            ImmutableArray <LocalFunctionSymbol> functions      = GetDeclaredLocalFunctionsForScope(node);
            BoundDecisionDag decisionDag = DecisionDagBuilder.CreateDecisionDagForSwitchStatement(
                compilation: this.Compilation,
                syntax: node,
                switchGoverningExpression: boundSwitchGoverningExpression,
                switchSections: switchSections,
                // If there is no explicit default label, the default action is to break out of the switch
                defaultLabel: defaultLabel?.Label ?? BreakLabel,
                diagnostics);

            // Report subsumption errors, but ignore the input's constant value for that.
            CheckSwitchErrors(node, boundSwitchGoverningExpression, ref switchSections, decisionDag, diagnostics);

            // When the input is constant, we use that to reshape the decision dag that is returned
            // so that flow analysis will see that some of the cases may be unreachable.
            decisionDag = decisionDag.SimplifyDecisionDagIfConstantInput(boundSwitchGoverningExpression);

            return(new BoundSwitchStatement(
                       syntax: node,
                       expression: boundSwitchGoverningExpression,
                       innerLocals: locals,
                       innerLocalFunctions: functions,
                       switchSections: switchSections,
                       defaultLabel: defaultLabel,
                       breakLabel: this.BreakLabel,
                       reachabilityDecisionDag: decisionDag));
        }
Beispiel #2
0
        public BoundDecisionDag GetDecisionDagForLowering(CSharpCompilation compilation)
        {
            BoundDecisionDag decisionDag = this.ReachabilityDecisionDag;

            if (decisionDag.ContainsAnySynthesizedNodes())
            {
                decisionDag = DecisionDagBuilder.CreateDecisionDagForSwitchStatement(
                    compilation,
                    this.Syntax,
                    this.Expression,
                    this.SwitchSections,
                    this.DefaultLabel?.Label ?? this.BreakLabel,
                    BindingDiagnosticBag.Discarded,
                    forLowering: true);
                Debug.Assert(!decisionDag.ContainsAnySynthesizedNodes());
            }

            return(decisionDag);
        }