public underlyingEnumType ( ) : |
||
return |
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); }