Esempio n. 1
0
        private BoundForStatement BindForParts(ForStatementSyntax node, Binder originalBinder, DiagnosticBag diagnostics)
        {
            BoundStatement initializer;

            // Deconstruction, Declaration, and Initializers are mutually exclusive.
            if (_syntax.Deconstruction != null)
            {
                var assignment = originalBinder.BindDeconstructionDeclaration(node.Deconstruction, node.Deconstruction.VariableComponent, node.Deconstruction.Value, diagnostics);
                initializer = new BoundLocalDeconstructionDeclaration(node, assignment);
            }
            else if (_syntax.Declaration != null)
            {
                ImmutableArray <BoundLocalDeclaration> unused;
                initializer = originalBinder.BindForOrUsingOrFixedDeclarations(node.Declaration, LocalDeclarationKind.ForInitializerVariable, diagnostics, out unused);
            }
            else
            {
                initializer = originalBinder.BindStatementExpressionList(node.Initializers, diagnostics);
            }

            var condition = (node.Condition != null) ? originalBinder.BindBooleanExpression(node.Condition, diagnostics) : null;
            var increment = originalBinder.BindStatementExpressionList(node.Incrementors, diagnostics);
            var body      = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);

            Debug.Assert(this.Locals == this.GetDeclaredLocalsForScope(node));
            return(new BoundForStatement(node,
                                         this.Locals,
                                         initializer,
                                         condition,
                                         increment,
                                         body,
                                         this.BreakLabel,
                                         this.ContinueLabel));
        }
Esempio n. 2
0
        private BoundForStatement BindForParts(ForStatementSyntax node, Binder originalBinder, DiagnosticBag diagnostics)
        {
            BoundStatement initializer;
            // Deconstruction, Declaration, and Initializers are mutually exclusive.
            if (_syntax.Deconstruction != null)
            {
                var assignment = originalBinder.BindDeconstructionDeclaration(node.Deconstruction, node.Deconstruction.VariableComponent, node.Deconstruction.Value, diagnostics);
                initializer = new BoundLocalDeconstructionDeclaration(node, assignment);
            }
            else if (_syntax.Declaration != null)
            {
                ImmutableArray<BoundLocalDeclaration> unused;
                initializer = originalBinder.BindForOrUsingOrFixedDeclarations(node.Declaration, LocalDeclarationKind.ForInitializerVariable, diagnostics, out unused);
            }
            else
            {
                initializer = originalBinder.BindStatementExpressionList(node.Initializers, diagnostics);
            }

            var condition = (node.Condition != null) ? originalBinder.BindBooleanExpression(node.Condition, diagnostics) : null;
            var increment = originalBinder.BindStatementExpressionList(node.Incrementors, diagnostics);
            var body = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);

            Debug.Assert(this.Locals == this.GetDeclaredLocalsForScope(node));
            return new BoundForStatement(node,
                                         this.Locals,
                                         initializer,
                                         condition,
                                         increment,
                                         body,
                                         this.BreakLabel,
                                         this.ContinueLabel);
        }
Esempio n. 3
0
        internal override BoundDoStatement BindDoParts(DiagnosticBag diagnostics, Binder originalBinder)
        {
            var node = (DoStatementSyntax)_syntax;

            var condition = originalBinder.BindBooleanExpression(node.Condition, diagnostics);
            var body = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);
            Debug.Assert(this.Locals.IsDefaultOrEmpty);
            return new BoundDoStatement(node, condition, body, this.BreakLabel, this.ContinueLabel);
        }
Esempio n. 4
0
        internal override BoundWhileStatement BindWhileParts(DiagnosticBag diagnostics, Binder originalBinder)
        {
            var node = (WhileStatementSyntax)_syntax;

            var condition = originalBinder.BindBooleanExpression(node.Condition, diagnostics);
            var body = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);
            Debug.Assert(this.Locals == this.GetDeclaredLocalsForScope(node));
            return new BoundWhileStatement(node, this.Locals, condition, body, this.BreakLabel, this.ContinueLabel);
        }
Esempio n. 5
0
        internal override BoundDoStatement BindDoParts(DiagnosticBag diagnostics, Binder originalBinder)
        {
            var node = (DoStatementSyntax)_syntax;

            var condition = originalBinder.BindBooleanExpression(node.Condition, diagnostics);
            var body      = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);

            Debug.Assert(this.Locals == this.GetDeclaredLocalsForScope(node));
            return(new BoundDoStatement(node, this.Locals, condition, body, this.BreakLabel, this.ContinueLabel));
        }
Esempio n. 6
0
        internal override BoundWhileStatement BindWhileParts(DiagnosticBag diagnostics, Binder originalBinder)
        {
            var node = (WhileStatementSyntax)_syntax;

            var condition = originalBinder.BindBooleanExpression(node.Condition, diagnostics);
            var body      = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);

            Debug.Assert(this.Locals.IsDefaultOrEmpty);
            return(new BoundWhileStatement(node, condition, body, this.BreakLabel, this.ContinueLabel));
        }
Esempio n. 7
0
        private BoundForStatement BindForParts(ForStatementSyntax node, Binder originalBinder, DiagnosticBag diagnostics)
        {
            BoundStatement initializer;

            // Declaration and Initializers are mutually exclusive.
            if (_syntax.Declaration != null)
            {
                ImmutableArray <BoundLocalDeclaration> unused;
                initializer = originalBinder.BindForOrUsingOrFixedDeclarations(node.Declaration, LocalDeclarationKind.RegularVariable, diagnostics, out unused);
            }
            else
            {
                initializer = originalBinder.BindStatementExpressionList(node.Initializers, diagnostics);
            }

            BoundExpression  condition       = null;
            var              innerLocals     = ImmutableArray <LocalSymbol> .Empty;
            ExpressionSyntax conditionSyntax = node.Condition;

            if (conditionSyntax != null)
            {
                originalBinder = originalBinder.GetBinder(conditionSyntax);
                condition      = originalBinder.BindBooleanExpression(conditionSyntax, diagnostics);
                innerLocals    = originalBinder.GetDeclaredLocalsForScope(conditionSyntax);
            }

            BoundStatement increment = null;
            SeparatedSyntaxList <ExpressionSyntax> incrementors = node.Incrementors;

            if (incrementors.Count > 0)
            {
                var scopeDesignator = incrementors.First();
                var incrementBinder = originalBinder.GetBinder(scopeDesignator);
                increment = incrementBinder.WrapWithVariablesIfAny(scopeDesignator, incrementBinder.BindStatementExpressionList(incrementors, diagnostics));
            }

            var body = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);

            Debug.Assert(this.Locals == this.GetDeclaredLocalsForScope(node));
            return(new BoundForStatement(node,
                                         this.Locals,
                                         initializer,
                                         innerLocals,
                                         condition,
                                         increment,
                                         body,
                                         this.BreakLabel,
                                         this.ContinueLabel));
        }
Esempio n. 8
0
        internal override BoundSwitchExpressionArm BindSwitchExpressionArm(SwitchExpressionArmSyntax node, BindingDiagnosticBag diagnostics)
        {
            Debug.Assert(node == _arm);
            Binder armBinder = this.GetBinder(node);
            bool   hasErrors = _switchExpressionBinder.SwitchGoverningType.IsErrorType();
            ImmutableArray <LocalSymbol> locals = _armScopeBinder.Locals;
            BoundPattern    pattern             = armBinder.BindPattern(node.Pattern, _switchExpressionBinder.SwitchGoverningType, _switchExpressionBinder.SwitchGoverningValEscape, permitDesignations: true, hasErrors, diagnostics);
            BoundExpression whenClause          = node.WhenClause != null
                ? armBinder.BindBooleanExpression(node.WhenClause.Condition, diagnostics)
                : null;

            BoundExpression armResult = armBinder.BindValue(node.Expression, diagnostics, BindValueKind.RValue);
            var             label     = new GeneratedLabelSymbol("arm");

            return(new BoundSwitchExpressionArm(node, locals, pattern, whenClause, armResult, label, hasErrors | pattern.HasErrors));
        }
Esempio n. 9
0
        private BoundForStatement BindForParts(ForStatementSyntax node, Binder originalBinder, DiagnosticBag diagnostics)
        {
            BoundStatement initializer;
            // Declaration and Initializers are mutually exclusive.
            if (_syntax.Declaration != null)
            {
                ImmutableArray<BoundLocalDeclaration> unused;
                initializer = originalBinder.BindForOrUsingOrFixedDeclarations(node.Declaration, LocalDeclarationKind.RegularVariable, diagnostics, out unused);
            }
            else
            {
                initializer = originalBinder.BindStatementExpressionList(node.Initializers, diagnostics);
            }

            BoundExpression condition = null;
            var innerLocals = ImmutableArray<LocalSymbol>.Empty;
            ExpressionSyntax conditionSyntax = node.Condition;
            if (conditionSyntax != null)
            {
                originalBinder = originalBinder.GetBinder(conditionSyntax);
                condition = originalBinder.BindBooleanExpression(conditionSyntax, diagnostics);
                innerLocals = originalBinder.GetDeclaredLocalsForScope(conditionSyntax);
            }

            BoundStatement increment = null;
            SeparatedSyntaxList<ExpressionSyntax> incrementors = node.Incrementors;
            if (incrementors.Count > 0)
            {
                var scopeDesignator = incrementors.First();
                var incrementBinder = originalBinder.GetBinder(scopeDesignator);
                increment = incrementBinder.WrapWithVariablesIfAny(scopeDesignator, incrementBinder.BindStatementExpressionList(incrementors, diagnostics));
            }

            var body = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);

            Debug.Assert(this.Locals == this.GetDeclaredLocalsForScope(node));
            return new BoundForStatement(node,
                                         this.Locals,
                                         initializer,
                                         innerLocals,
                                         condition,
                                         increment,
                                         body,
                                         this.BreakLabel,
                                         this.ContinueLabel);
        }
Esempio n. 10
0
        private static BoundPatternSwitchLabel BindPatternSwitchSectionLabel(Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, ref DefaultSwitchLabelSyntax defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors);
                    }

                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
                        }

                        defaultLabel = defaultLabelSyntax;
                        return new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors); // note that this is semantically last!
                    }

                default:
                    throw ExceptionUtilities.Unreachable;
            }
        }
Esempio n. 11
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        bool hasErrors = pattern.HasErrors;
                        var constantValue = pattern.ConstantValue;
                        if (!hasErrors &&
                            (object)constantValue != null &&
                            pattern.Value.Type == SwitchGoverningType &&
                            this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                            hasErrors = true;
                        }

                        // Until we've determined whether or not the switch label is reachable, we assume it
                        // is. The caller updates isReachable after determining if the label is subsumed.
                        const bool isReachable = true;
                        return new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        bool hasErrors = pattern.HasErrors;
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                            hasErrors = true;
                        }

                        // We always treat the default label as reachable, even if the switch is complete.
                        const bool isReachable = true;

                        // Note that this is semantically last! The caller will place it in the decision tree
                        // in the final position.
                        defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                        return defaultLabel;
                    }

                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, label, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null,
                            true, node.HasErrors);
                    }

                default:
                    throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
Esempio n. 12
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CaseSwitchLabel:
            {
                var  caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                bool wasExpression;
                var  pattern = sectionBinder.BindConstantPattern(
                    node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                bool hasErrors     = pattern.HasErrors;
                var  constantValue = pattern.ConstantValue;
                if (!hasErrors &&
                    (object)constantValue != null &&
                    pattern.Value.Type == SwitchGoverningType &&
                    this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                    hasErrors = true;
                }

                if (caseLabelSyntax.Value.Kind() == SyntaxKind.DefaultLiteralExpression)
                {
                    diagnostics.Add(ErrorCode.WRN_DefaultInSwitch, caseLabelSyntax.Value.Location);
                }

                // Until we've determined whether or not the switch label is reachable, we assume it
                // is. The caller updates isReachable after determining if the label is subsumed.
                const bool isReachable = true;
                return(new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors));
            }

            case SyntaxKind.DefaultSwitchLabel:
            {
                var  defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                var  pattern            = new BoundWildcardPattern(node);
                bool hasErrors          = pattern.HasErrors;
                if (defaultLabel != null)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                    hasErrors = true;
                }

                // We always treat the default label as reachable, even if the switch is complete.
                const bool isReachable = true;

                // Note that this is semantically last! The caller will place it in the decision tree
                // in the final position.
                defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                return(defaultLabel);
            }

            case SyntaxKind.CasePatternSwitchLabel:
            {
                var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                var pattern          = sectionBinder.BindPattern(
                    matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, label, pattern,
                                                   matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null,
                                                   true, node.HasErrors));
            }

            default:
                throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        bool hasErrors = pattern.HasErrors;
                        var constantValue = pattern.ConstantValue;
                        if (!hasErrors && (object)constantValue != null && this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                            hasErrors = true;
                        }
                        return new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        bool hasErrors = pattern.HasErrors;
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
                            hasErrors = true;
                        }

                        // Note that this is semantically last! The caller will place it in the decision tree
                        // in the final position.
                        defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                        return defaultLabel;
                    }

                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, label, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors);
                    }

                default:
                    throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
Esempio n. 14
0
        private BoundForStatement BindForParts(ForStatementSyntax node, Binder originalBinder, BindingDiagnosticBag diagnostics)
        {
            BoundStatement initializer;

            // Declaration and Initializers are mutually exclusive.
            if (_syntax.Declaration != null)
            {
                ImmutableArray <BoundLocalDeclaration> unused;
                initializer = originalBinder.BindForOrUsingOrFixedDeclarations(node.Declaration, LocalDeclarationKind.RegularVariable, diagnostics, out unused);
            }
            else
            {
                initializer = originalBinder.BindStatementExpressionList(node.Initializers, diagnostics);
            }

            BoundExpression  condition       = null;
            var              innerLocals     = ImmutableArray <LocalSymbol> .Empty;
            ExpressionSyntax conditionSyntax = node.Condition;

            if (conditionSyntax != null)
            {
                originalBinder = originalBinder.GetBinder(conditionSyntax);
                condition      = originalBinder.BindBooleanExpression(conditionSyntax, diagnostics);
                innerLocals    = originalBinder.GetDeclaredLocalsForScope(conditionSyntax);
            }

            BoundStatement increment = null;
            SeparatedSyntaxList <ExpressionSyntax> incrementors = node.Incrementors;

            if (incrementors.Count > 0)
            {
                var scopeDesignator = incrementors.First();
                var incrementBinder = originalBinder.GetBinder(scopeDesignator);
                increment = incrementBinder.BindStatementExpressionList(incrementors, diagnostics);
                Debug.Assert(increment.Kind != BoundKind.StatementList || ((BoundStatementList)increment).Statements.Length > 1);

                var locals = incrementBinder.GetDeclaredLocalsForScope(scopeDesignator);
                if (!locals.IsEmpty)
                {
                    if (increment.Kind == BoundKind.StatementList)
                    {
                        increment = new BoundBlock(scopeDesignator, locals, ((BoundStatementList)increment).Statements)
                        {
                            WasCompilerGenerated = true
                        };
                    }
                    else
                    {
                        increment = new BoundBlock(increment.Syntax, locals, ImmutableArray.Create(increment))
                        {
                            WasCompilerGenerated = true
                        };
                    }
                }
            }

            var body = originalBinder.BindPossibleEmbeddedStatement(node.Statement, diagnostics);

            Debug.Assert(this.Locals == this.GetDeclaredLocalsForScope(node));
            return(new BoundForStatement(node,
                                         this.Locals,
                                         initializer,
                                         innerLocals,
                                         condition,
                                         increment,
                                         body,
                                         this.BreakLabel,
                                         this.ContinueLabel));
        }
Esempio n. 15
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CaseSwitchLabel:
            {
                var  caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                bool wasExpression;
                var  pattern = sectionBinder.BindConstantPattern(
                    node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                bool hasErrors     = pattern.HasErrors;
                var  constantValue = pattern.ConstantValue;
                if (!hasErrors &&
                    (object)constantValue != null &&
                    pattern.Value.Type == SwitchGoverningType &&
                    this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                    hasErrors = true;
                }
                return(new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors));
            }

            case SyntaxKind.DefaultSwitchLabel:
            {
                var  defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                var  pattern            = new BoundWildcardPattern(node);
                bool hasErrors          = pattern.HasErrors;
                if (defaultLabel != null)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                    hasErrors = true;
                }

                // Note that this is semantically last! The caller will place it in the decision tree
                // in the final position.
                defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                return(defaultLabel);
            }

            case SyntaxKind.CasePatternSwitchLabel:
            {
                var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                var pattern          = sectionBinder.BindPattern(
                    matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, label, pattern,
                                                   matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors));
            }

            default:
                throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
        private static BoundPatternSwitchLabel BindPatternSwitchSectionLabel(Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, ref DefaultSwitchLabelSyntax defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CasePatternSwitchLabel:
            {
                var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                var pattern          = sectionBinder.BindPattern(
                    matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, pattern,
                                                   matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors));
            }

            case SyntaxKind.CaseSwitchLabel:
            {
                var  caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                bool wasExpression;
                var  pattern = sectionBinder.BindConstantPattern(
                    node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors));
            }

            case SyntaxKind.DefaultSwitchLabel:
            {
                var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                var pattern            = new BoundWildcardPattern(node);
                if (defaultLabel != null)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
                }

                defaultLabel = defaultLabelSyntax;
                return(new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors));        // note that this is semantically last!
            }

            default:
                throw ExceptionUtilities.Unreachable;
            }
        }