underlyingEnumType() public method

public underlyingEnumType ( ) : AggregateType
return AggregateType
Ejemplo n.º 1
0
        private Expr GenerateBuiltInBinaryOperator(ExprBinOp expr)
        {
            Debug.Assert(expr != null);
            PREDEFMETH pdm;

            switch (expr.Kind)
            {
            case ExpressionKind.LeftShirt: pdm = PREDEFMETH.PM_EXPRESSION_LEFTSHIFT; break;

            case ExpressionKind.RightShift: pdm = PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT; break;

            case ExpressionKind.BitwiseExclusiveOr: pdm = PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR; break;

            case ExpressionKind.BitwiseOr: pdm = PREDEFMETH.PM_EXPRESSION_OR; break;

            case ExpressionKind.BitwiseAnd: pdm = PREDEFMETH.PM_EXPRESSION_AND; break;

            case ExpressionKind.LogicalAnd: pdm = PREDEFMETH.PM_EXPRESSION_ANDALSO; break;

            case ExpressionKind.LogicalOr: pdm = PREDEFMETH.PM_EXPRESSION_ORELSE; break;

            case ExpressionKind.StringEq: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL; break;

            case ExpressionKind.Eq: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL; break;

            case ExpressionKind.StringNotEq: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL; break;

            case ExpressionKind.NotEq: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL; break;

            case ExpressionKind.GreaterThanOrEqual: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL; break;

            case ExpressionKind.LessThanOrEqual: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL; break;

            case ExpressionKind.LessThan: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHAN; break;

            case ExpressionKind.GreaterThan: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHAN; break;

            case ExpressionKind.Modulo: pdm = PREDEFMETH.PM_EXPRESSION_MODULO; break;

            case ExpressionKind.Divide: pdm = PREDEFMETH.PM_EXPRESSION_DIVIDE; break;

            case ExpressionKind.Multiply:
                pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED : PREDEFMETH.PM_EXPRESSION_MULTIPLY;
                break;

            case ExpressionKind.Subtract:
                pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED : PREDEFMETH.PM_EXPRESSION_SUBTRACT;
                break;

            case ExpressionKind.Add:
                pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_ADDCHECKED : PREDEFMETH.PM_EXPRESSION_ADD;
                break;

            default:
                throw Error.InternalCompilerError();
            }
            Expr origL = expr.OptionalLeftChild;
            Expr origR = expr.OptionalRightChild;

            Debug.Assert(origL != null);
            Debug.Assert(origR != null);
            CType typeL = origL.Type;
            CType typeR = origR.Type;

            Expr newL = Visit(origL);
            Expr newR = Visit(origR);

            bool  didEnumConversion = false;
            CType convertL          = null;
            CType convertR          = null;

            if (typeL.isEnumType())
            {
                // We have already inserted casts if not lifted, so we should never see an enum.
                Debug.Assert(expr.IsLifted);
                convertL          = GetSymbolLoader().GetTypeManager().GetNullable(typeL.underlyingEnumType());
                typeL             = convertL;
                didEnumConversion = true;
            }
            else if (typeL is NullableType nubL && nubL.UnderlyingType.isEnumType())
            {
                Debug.Assert(expr.IsLifted);
                convertL          = GetSymbolLoader().GetTypeManager().GetNullable(nubL.UnderlyingType.underlyingEnumType());
                typeL             = convertL;
                didEnumConversion = true;
            }
            if (typeR.isEnumType())
            {
                Debug.Assert(expr.IsLifted);
                convertR          = GetSymbolLoader().GetTypeManager().GetNullable(typeR.underlyingEnumType());
                typeR             = convertR;
                didEnumConversion = true;
            }
            else if (typeR is NullableType nubR && nubR.UnderlyingType.isEnumType())
            {
                Debug.Assert(expr.IsLifted);
                convertR          = GetSymbolLoader().GetTypeManager().GetNullable(nubR.UnderlyingType.underlyingEnumType());
                typeR             = convertR;
                didEnumConversion = true;
            }
            if (typeL is NullableType nubL2 && nubL2.UnderlyingType == typeR)
            {
                convertR = typeL;
            }
            if (typeR is NullableType nubR2 && nubR2.UnderlyingType == typeL)
            {
                convertL = typeR;
            }

            if (convertL != null)
            {
                newL = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, newL, CreateTypeOf(convertL));
            }
            if (convertR != null)
            {
                newR = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, newR, CreateTypeOf(convertR));
            }

            Expr call = GenerateCall(pdm, newL, newR);

            if (didEnumConversion && expr.Type.StripNubs().isEnumType())
            {
                call = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, CreateTypeOf(expr.Type));
            }

            return(call);
        }