未验证 提交 85edae87 编写于 作者: C Charles Stoner 提交者: GitHub

Increment and decrement operators (#41380)

上级 a1bcd597
......@@ -1150,7 +1150,6 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
// The int is converted to float and stored internally as the double 214783648, even though the
// fully precise int would fit into a double.
// PROTOTYPE: Test all cases.
unchecked
{
switch (value.Discriminator)
......@@ -1168,6 +1167,8 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)byteValue;
case SpecialType.System_Int32: return (int)byteValue;
case SpecialType.System_Int64: return (long)byteValue;
case SpecialType.System_IntPtr: return (int)byteValue;
case SpecialType.System_UIntPtr: return (uint)byteValue;
case SpecialType.System_Single:
case SpecialType.System_Double: return (double)byteValue;
case SpecialType.System_Decimal: return (decimal)byteValue;
......@@ -1186,6 +1187,8 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)charValue;
case SpecialType.System_Int32: return (int)charValue;
case SpecialType.System_Int64: return (long)charValue;
case SpecialType.System_IntPtr: return (int)charValue;
case SpecialType.System_UIntPtr: return (uint)charValue;
case SpecialType.System_Single:
case SpecialType.System_Double: return (double)charValue;
case SpecialType.System_Decimal: return (decimal)charValue;
......@@ -1204,6 +1207,8 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)uint16Value;
case SpecialType.System_Int32: return (int)uint16Value;
case SpecialType.System_Int64: return (long)uint16Value;
case SpecialType.System_IntPtr: return (int)uint16Value;
case SpecialType.System_UIntPtr: return (uint)uint16Value;
case SpecialType.System_Single:
case SpecialType.System_Double: return (double)uint16Value;
case SpecialType.System_Decimal: return (decimal)uint16Value;
......@@ -1222,6 +1227,8 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)uint32Value;
case SpecialType.System_Int32: return (int)uint32Value;
case SpecialType.System_Int64: return (long)uint32Value;
case SpecialType.System_IntPtr: return (int)uint32Value;
case SpecialType.System_UIntPtr: return (uint)uint32Value;
case SpecialType.System_Single: return (double)(float)uint32Value;
case SpecialType.System_Double: return (double)uint32Value;
case SpecialType.System_Decimal: return (decimal)uint32Value;
......@@ -1240,11 +1247,32 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)uint64Value;
case SpecialType.System_Int32: return (int)uint64Value;
case SpecialType.System_Int64: return (long)uint64Value;
case SpecialType.System_IntPtr: return (int)uint64Value;
case SpecialType.System_UIntPtr: return (uint)uint64Value;
case SpecialType.System_Single: return (double)(float)uint64Value;
case SpecialType.System_Double: return (double)uint64Value;
case SpecialType.System_Decimal: return (decimal)uint64Value;
default: throw ExceptionUtilities.UnexpectedValue(destinationType);
}
case ConstantValueTypeDiscriminator.NUInt:
uint nuintValue = value.UInt32Value;
switch (destinationType)
{
case SpecialType.System_Byte: return (byte)nuintValue;
case SpecialType.System_Char: return (char)nuintValue;
case SpecialType.System_UInt16: return (ushort)nuintValue;
case SpecialType.System_UInt32: return (uint)nuintValue;
case SpecialType.System_UInt64: return (ulong)nuintValue;
case SpecialType.System_SByte: return (sbyte)nuintValue;
case SpecialType.System_Int16: return (short)nuintValue;
case SpecialType.System_Int32: return (int)nuintValue;
case SpecialType.System_Int64: return (long)nuintValue;
case SpecialType.System_IntPtr: return (int)nuintValue;
case SpecialType.System_Single: return (double)(float)nuintValue;
case SpecialType.System_Double: return (double)nuintValue;
case SpecialType.System_Decimal: return (decimal)nuintValue;
default: throw ExceptionUtilities.UnexpectedValue(destinationType);
}
case ConstantValueTypeDiscriminator.SByte:
sbyte sbyteValue = value.SByteValue;
switch (destinationType)
......@@ -1258,6 +1286,8 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)sbyteValue;
case SpecialType.System_Int32: return (int)sbyteValue;
case SpecialType.System_Int64: return (long)sbyteValue;
case SpecialType.System_IntPtr: return (int)sbyteValue;
case SpecialType.System_UIntPtr: return (uint)sbyteValue;
case SpecialType.System_Single:
case SpecialType.System_Double: return (double)sbyteValue;
case SpecialType.System_Decimal: return (decimal)sbyteValue;
......@@ -1276,6 +1306,8 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)int16Value;
case SpecialType.System_Int32: return (int)int16Value;
case SpecialType.System_Int64: return (long)int16Value;
case SpecialType.System_IntPtr: return (int)int16Value;
case SpecialType.System_UIntPtr: return (uint)int16Value;
case SpecialType.System_Single:
case SpecialType.System_Double: return (double)int16Value;
case SpecialType.System_Decimal: return (decimal)int16Value;
......@@ -1314,11 +1346,33 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)int64Value;
case SpecialType.System_Int32: return (int)int64Value;
case SpecialType.System_Int64: return (long)int64Value;
case SpecialType.System_IntPtr: return (int)int64Value;
case SpecialType.System_UIntPtr: return (uint)int64Value;
case SpecialType.System_Single: return (double)(float)int64Value;
case SpecialType.System_Double: return (double)int64Value;
case SpecialType.System_Decimal: return (decimal)int64Value;
default: throw ExceptionUtilities.UnexpectedValue(destinationType);
}
case ConstantValueTypeDiscriminator.NInt:
int nintValue = value.Int32Value;
switch (destinationType)
{
case SpecialType.System_Byte: return (byte)nintValue;
case SpecialType.System_Char: return (char)nintValue;
case SpecialType.System_UInt16: return (ushort)nintValue;
case SpecialType.System_UInt32: return (uint)nintValue;
case SpecialType.System_UInt64: return (ulong)nintValue;
case SpecialType.System_SByte: return (sbyte)nintValue;
case SpecialType.System_Int16: return (short)nintValue;
case SpecialType.System_Int32: return (int)nintValue;
case SpecialType.System_Int64: return (long)nintValue;
case SpecialType.System_IntPtr: return (int)nintValue;
case SpecialType.System_UIntPtr: return (uint)nintValue;
case SpecialType.System_Single: return (double)(float)nintValue;
case SpecialType.System_Double: return (double)nintValue;
case SpecialType.System_Decimal: return (decimal)nintValue;
default: throw ExceptionUtilities.UnexpectedValue(destinationType);
}
case ConstantValueTypeDiscriminator.Single:
case ConstantValueTypeDiscriminator.Double:
// When converting from a floating-point type to an integral type, if the checked conversion would
......@@ -1336,6 +1390,8 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)doubleValue;
case SpecialType.System_Int32: return (int)doubleValue;
case SpecialType.System_Int64: return (long)doubleValue;
case SpecialType.System_IntPtr: return (int)doubleValue;
case SpecialType.System_UIntPtr: return (uint)doubleValue;
case SpecialType.System_Single: return (double)(float)doubleValue;
case SpecialType.System_Double: return (double)doubleValue;
case SpecialType.System_Decimal: return (value.Discriminator == ConstantValueTypeDiscriminator.Single) ? (decimal)(float)doubleValue : (decimal)doubleValue;
......@@ -1354,6 +1410,8 @@ private static object DoUncheckedConversion(SpecialType destinationType, Constan
case SpecialType.System_Int16: return (short)decimalValue;
case SpecialType.System_Int32: return (int)decimalValue;
case SpecialType.System_Int64: return (long)decimalValue;
case SpecialType.System_IntPtr: return (int)decimalValue;
case SpecialType.System_UIntPtr: return (uint)decimalValue;
case SpecialType.System_Single: return (double)(float)decimalValue;
case SpecialType.System_Double: return (double)decimalValue;
case SpecialType.System_Decimal: return (decimal)decimalValue;
......@@ -1436,11 +1494,13 @@ private static object CanonicalizeConstant(ConstantValue value)
case ConstantValueTypeDiscriminator.Int16: return (decimal)value.Int16Value;
case ConstantValueTypeDiscriminator.Int32: return (decimal)value.Int32Value;
case ConstantValueTypeDiscriminator.Int64: return (decimal)value.Int64Value;
case ConstantValueTypeDiscriminator.NInt: return (decimal)value.Int32Value;
case ConstantValueTypeDiscriminator.Byte: return (decimal)value.ByteValue;
case ConstantValueTypeDiscriminator.Char: return (decimal)value.CharValue;
case ConstantValueTypeDiscriminator.UInt16: return (decimal)value.UInt16Value;
case ConstantValueTypeDiscriminator.UInt32: return (decimal)value.UInt32Value;
case ConstantValueTypeDiscriminator.UInt64: return (decimal)value.UInt64Value;
case ConstantValueTypeDiscriminator.NUInt: return (decimal)value.UInt32Value;
case ConstantValueTypeDiscriminator.Single:
case ConstantValueTypeDiscriminator.Double: return value.DoubleValue;
case ConstantValueTypeDiscriminator.Decimal: return value.DecimalValue;
......
......@@ -76,6 +76,8 @@ internal enum UnaryOperatorKind
UIntPostfixIncrement = UInt | PostfixIncrement,
LongPostfixIncrement = Long | PostfixIncrement,
ULongPostfixIncrement = ULong | PostfixIncrement,
NIntPostfixIncrement = NInt | PostfixIncrement,
NUIntPostfixIncrement = NUInt | PostfixIncrement,
CharPostfixIncrement = Char | PostfixIncrement,
FloatPostfixIncrement = Float | PostfixIncrement,
DoublePostfixIncrement = Double | PostfixIncrement,
......@@ -90,6 +92,8 @@ internal enum UnaryOperatorKind
LiftedUIntPostfixIncrement = Lifted | UInt | PostfixIncrement,
LiftedLongPostfixIncrement = Lifted | Long | PostfixIncrement,
LiftedULongPostfixIncrement = Lifted | ULong | PostfixIncrement,
LiftedNIntPostfixIncrement = Lifted | NInt | PostfixIncrement,
LiftedNUIntPostfixIncrement = Lifted | NUInt | PostfixIncrement,
LiftedCharPostfixIncrement = Lifted | Char | PostfixIncrement,
LiftedFloatPostfixIncrement = Lifted | Float | PostfixIncrement,
LiftedDoublePostfixIncrement = Lifted | Double | PostfixIncrement,
......@@ -107,6 +111,8 @@ internal enum UnaryOperatorKind
UIntPrefixIncrement = UInt | PrefixIncrement,
LongPrefixIncrement = Long | PrefixIncrement,
ULongPrefixIncrement = ULong | PrefixIncrement,
NIntPrefixIncrement = NInt | PrefixIncrement,
NUIntPrefixIncrement = NUInt | PrefixIncrement,
CharPrefixIncrement = Char | PrefixIncrement,
FloatPrefixIncrement = Float | PrefixIncrement,
DoublePrefixIncrement = Double | PrefixIncrement,
......@@ -121,6 +127,8 @@ internal enum UnaryOperatorKind
LiftedUIntPrefixIncrement = Lifted | UInt | PrefixIncrement,
LiftedLongPrefixIncrement = Lifted | Long | PrefixIncrement,
LiftedULongPrefixIncrement = Lifted | ULong | PrefixIncrement,
LiftedNIntPrefixIncrement = Lifted | NInt | PrefixIncrement,
LiftedNUIntPrefixIncrement = Lifted | NUInt | PrefixIncrement,
LiftedCharPrefixIncrement = Lifted | Char | PrefixIncrement,
LiftedFloatPrefixIncrement = Lifted | Float | PrefixIncrement,
LiftedDoublePrefixIncrement = Lifted | Double | PrefixIncrement,
......@@ -138,6 +146,8 @@ internal enum UnaryOperatorKind
UIntPostfixDecrement = UInt | PostfixDecrement,
LongPostfixDecrement = Long | PostfixDecrement,
ULongPostfixDecrement = ULong | PostfixDecrement,
NIntPostfixDecrement = NInt | PostfixDecrement,
NUIntPostfixDecrement = NUInt | PostfixDecrement,
CharPostfixDecrement = Char | PostfixDecrement,
FloatPostfixDecrement = Float | PostfixDecrement,
DoublePostfixDecrement = Double | PostfixDecrement,
......@@ -152,6 +162,8 @@ internal enum UnaryOperatorKind
LiftedUIntPostfixDecrement = Lifted | UInt | PostfixDecrement,
LiftedLongPostfixDecrement = Lifted | Long | PostfixDecrement,
LiftedULongPostfixDecrement = Lifted | ULong | PostfixDecrement,
LiftedNIntPostfixDecrement = Lifted | NInt | PostfixDecrement,
LiftedNUIntPostfixDecrement = Lifted | NUInt | PostfixDecrement,
LiftedCharPostfixDecrement = Lifted | Char | PostfixDecrement,
LiftedFloatPostfixDecrement = Lifted | Float | PostfixDecrement,
LiftedDoublePostfixDecrement = Lifted | Double | PostfixDecrement,
......@@ -169,6 +181,8 @@ internal enum UnaryOperatorKind
UIntPrefixDecrement = UInt | PrefixDecrement,
LongPrefixDecrement = Long | PrefixDecrement,
ULongPrefixDecrement = ULong | PrefixDecrement,
NIntPrefixDecrement = NInt | PrefixDecrement,
NUIntPrefixDecrement = NUInt | PrefixDecrement,
CharPrefixDecrement = Char | PrefixDecrement,
FloatPrefixDecrement = Float | PrefixDecrement,
DoublePrefixDecrement = Double | PrefixDecrement,
......@@ -183,6 +197,8 @@ internal enum UnaryOperatorKind
LiftedUIntPrefixDecrement = Lifted | UInt | PrefixDecrement,
LiftedLongPrefixDecrement = Lifted | Long | PrefixDecrement,
LiftedULongPrefixDecrement = Lifted | ULong | PrefixDecrement,
LiftedNIntPrefixDecrement = Lifted | NInt | PrefixDecrement,
LiftedNUIntPrefixDecrement = Lifted | NUInt | PrefixDecrement,
LiftedCharPrefixDecrement = Lifted | Char | PrefixDecrement,
LiftedFloatPrefixDecrement = Lifted | Float | PrefixDecrement,
LiftedDoublePrefixDecrement = Lifted | Double | PrefixDecrement,
......@@ -196,6 +212,8 @@ internal enum UnaryOperatorKind
UIntUnaryPlus = UInt | UnaryPlus,
LongUnaryPlus = Long | UnaryPlus,
ULongUnaryPlus = ULong | UnaryPlus,
NIntUnaryPlus = NInt | UnaryPlus,
NUIntUnaryPlus = NUInt | UnaryPlus,
FloatUnaryPlus = Float | UnaryPlus,
DoubleUnaryPlus = Double | UnaryPlus,
DecimalUnaryPlus = Decimal | UnaryPlus,
......@@ -204,6 +222,8 @@ internal enum UnaryOperatorKind
LiftedUIntUnaryPlus = Lifted | UInt | UnaryPlus,
LiftedLongUnaryPlus = Lifted | Long | UnaryPlus,
LiftedULongUnaryPlus = Lifted | ULong | UnaryPlus,
LiftedNIntUnaryPlus = Lifted | NInt | UnaryPlus,
LiftedNUIntUnaryPlus = Lifted | NUInt | UnaryPlus,
LiftedFloatUnaryPlus = Lifted | Float | UnaryPlus,
LiftedDoubleUnaryPlus = Lifted | Double | UnaryPlus,
LiftedDecimalUnaryPlus = Lifted | Decimal | UnaryPlus,
......@@ -212,12 +232,14 @@ internal enum UnaryOperatorKind
IntUnaryMinus = Int | UnaryMinus,
LongUnaryMinus = Long | UnaryMinus,
NIntUnaryMinus = NInt | UnaryMinus,
FloatUnaryMinus = Float | UnaryMinus,
DoubleUnaryMinus = Double | UnaryMinus,
DecimalUnaryMinus = Decimal | UnaryMinus,
UserDefinedUnaryMinus = UserDefined | UnaryMinus,
LiftedIntUnaryMinus = Lifted | Int | UnaryMinus,
LiftedLongUnaryMinus = Lifted | Long | UnaryMinus,
LiftedNIntUnaryMinus = Lifted | NInt | UnaryMinus,
LiftedFloatUnaryMinus = Lifted | Float | UnaryMinus,
LiftedDoubleUnaryMinus = Lifted | Double | UnaryMinus,
LiftedDecimalUnaryMinus = Lifted | Decimal | UnaryMinus,
......@@ -234,12 +256,16 @@ internal enum UnaryOperatorKind
UIntBitwiseComplement = UInt | BitwiseComplement,
LongBitwiseComplement = Long | BitwiseComplement,
ULongBitwiseComplement = ULong | BitwiseComplement,
NIntBitwiseComplement = NInt | BitwiseComplement,
NUIntBitwiseComplement = NUInt | BitwiseComplement,
EnumBitwiseComplement = Enum | BitwiseComplement,
UserDefinedBitwiseComplement = UserDefined | BitwiseComplement,
LiftedIntBitwiseComplement = Lifted | Int | BitwiseComplement,
LiftedUIntBitwiseComplement = Lifted | UInt | BitwiseComplement,
LiftedLongBitwiseComplement = Lifted | Long | BitwiseComplement,
LiftedULongBitwiseComplement = Lifted | ULong | BitwiseComplement,
LiftedNIntBitwiseComplement = Lifted | NInt | BitwiseComplement,
LiftedNUIntBitwiseComplement = Lifted | NUInt | BitwiseComplement,
LiftedEnumBitwiseComplement = Lifted | Enum | BitwiseComplement,
LiftedUserDefinedBitwiseComplement = Lifted | UserDefined | BitwiseComplement,
DynamicBitwiseComplement = Dynamic | BitwiseComplement,
......
......@@ -104,6 +104,8 @@ public static bool IsIntegral(this UnaryOperatorKind kind)
case UnaryOperatorKind.UInt:
case UnaryOperatorKind.Long:
case UnaryOperatorKind.ULong:
case UnaryOperatorKind.NInt:
case UnaryOperatorKind.NUInt:
case UnaryOperatorKind.Char:
case UnaryOperatorKind.Enum:
case UnaryOperatorKind.Pointer:
......
......@@ -46,8 +46,8 @@ internal static class UnopEasyOut
private static readonly UnaryOperatorKind[] s_increment =
//obj str bool chr i08 i16 i32 i64 u08 u16 u32 u64 nint nuint r32 r64 dec
{ ERR, ERR, ERR, CHR, I08, I16, I32, I64, U08, U16, U32, U64, ERR, ERR, R32, R64, DEC,
/* lifted */ ERR, LCHR, LI08, LI16, LI32, LI64, LU08, LU16, LU32, LU64, ERR, ERR, LR32, LR64, LDEC };
{ ERR, ERR, ERR, CHR, I08, I16, I32, I64, U08, U16, U32, U64, NIN, NUI, R32, R64, DEC,
/* lifted */ ERR, LCHR, LI08, LI16, LI32, LI64, LU08, LU16, LU32, LU64, LNI, LNU, LR32, LR64, LDEC };
private static readonly UnaryOperatorKind[] s_plus =
//obj str bool chr i08 i16 i32 i64 u08 u16 u32 u64 nint nuint r32 r64 dec
......
......@@ -58,6 +58,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.UIntPostfixIncrement,
(int)UnaryOperatorKind.LongPostfixIncrement,
(int)UnaryOperatorKind.ULongPostfixIncrement,
(int)UnaryOperatorKind.NIntPostfixIncrement,
(int)UnaryOperatorKind.NUIntPostfixIncrement,
(int)UnaryOperatorKind.CharPostfixIncrement,
(int)UnaryOperatorKind.FloatPostfixIncrement,
(int)UnaryOperatorKind.DoublePostfixIncrement,
......@@ -70,6 +72,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.LiftedUIntPostfixIncrement,
(int)UnaryOperatorKind.LiftedLongPostfixIncrement,
(int)UnaryOperatorKind.LiftedULongPostfixIncrement,
(int)UnaryOperatorKind.LiftedNIntPostfixIncrement,
(int)UnaryOperatorKind.LiftedNUIntPostfixIncrement,
(int)UnaryOperatorKind.LiftedCharPostfixIncrement,
(int)UnaryOperatorKind.LiftedFloatPostfixIncrement,
(int)UnaryOperatorKind.LiftedDoublePostfixIncrement,
......@@ -85,6 +89,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.UIntPostfixDecrement,
(int)UnaryOperatorKind.LongPostfixDecrement,
(int)UnaryOperatorKind.ULongPostfixDecrement,
(int)UnaryOperatorKind.NIntPostfixDecrement,
(int)UnaryOperatorKind.NUIntPostfixDecrement,
(int)UnaryOperatorKind.CharPostfixDecrement,
(int)UnaryOperatorKind.FloatPostfixDecrement,
(int)UnaryOperatorKind.DoublePostfixDecrement,
......@@ -97,6 +103,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.LiftedUIntPostfixDecrement,
(int)UnaryOperatorKind.LiftedLongPostfixDecrement,
(int)UnaryOperatorKind.LiftedULongPostfixDecrement,
(int)UnaryOperatorKind.LiftedNIntPostfixDecrement,
(int)UnaryOperatorKind.LiftedNUIntPostfixDecrement,
(int)UnaryOperatorKind.LiftedCharPostfixDecrement,
(int)UnaryOperatorKind.LiftedFloatPostfixDecrement,
(int)UnaryOperatorKind.LiftedDoublePostfixDecrement,
......@@ -112,6 +120,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.UIntPrefixIncrement,
(int)UnaryOperatorKind.LongPrefixIncrement,
(int)UnaryOperatorKind.ULongPrefixIncrement,
(int)UnaryOperatorKind.NIntPrefixIncrement,
(int)UnaryOperatorKind.NUIntPrefixIncrement,
(int)UnaryOperatorKind.CharPrefixIncrement,
(int)UnaryOperatorKind.FloatPrefixIncrement,
(int)UnaryOperatorKind.DoublePrefixIncrement,
......@@ -124,6 +134,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.LiftedUIntPrefixIncrement,
(int)UnaryOperatorKind.LiftedLongPrefixIncrement,
(int)UnaryOperatorKind.LiftedULongPrefixIncrement,
(int)UnaryOperatorKind.LiftedNIntPrefixIncrement,
(int)UnaryOperatorKind.LiftedNUIntPrefixIncrement,
(int)UnaryOperatorKind.LiftedCharPrefixIncrement,
(int)UnaryOperatorKind.LiftedFloatPrefixIncrement,
(int)UnaryOperatorKind.LiftedDoublePrefixIncrement,
......@@ -137,6 +149,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.UShortPrefixDecrement,
(int)UnaryOperatorKind.IntPrefixDecrement,
(int)UnaryOperatorKind.UIntPrefixDecrement,
(int)UnaryOperatorKind.NIntPrefixDecrement,
(int)UnaryOperatorKind.NUIntPrefixDecrement,
(int)UnaryOperatorKind.LongPrefixDecrement,
(int)UnaryOperatorKind.ULongPrefixDecrement,
(int)UnaryOperatorKind.CharPrefixDecrement,
......@@ -151,6 +165,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.LiftedUIntPrefixDecrement,
(int)UnaryOperatorKind.LiftedLongPrefixDecrement,
(int)UnaryOperatorKind.LiftedULongPrefixDecrement,
(int)UnaryOperatorKind.LiftedNIntPrefixDecrement,
(int)UnaryOperatorKind.LiftedNUIntPrefixDecrement,
(int)UnaryOperatorKind.LiftedCharPrefixDecrement,
(int)UnaryOperatorKind.LiftedFloatPrefixDecrement,
(int)UnaryOperatorKind.LiftedDoublePrefixDecrement,
......@@ -162,6 +178,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.UIntUnaryPlus,
(int)UnaryOperatorKind.LongUnaryPlus,
(int)UnaryOperatorKind.ULongUnaryPlus,
(int)UnaryOperatorKind.NIntUnaryPlus,
(int)UnaryOperatorKind.NUIntUnaryPlus,
(int)UnaryOperatorKind.FloatUnaryPlus,
(int)UnaryOperatorKind.DoubleUnaryPlus,
(int)UnaryOperatorKind.DecimalUnaryPlus,
......@@ -169,6 +187,8 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.LiftedUIntUnaryPlus,
(int)UnaryOperatorKind.LiftedLongUnaryPlus,
(int)UnaryOperatorKind.LiftedULongUnaryPlus,
(int)UnaryOperatorKind.LiftedNIntUnaryPlus,
(int)UnaryOperatorKind.LiftedNUIntUnaryPlus,
(int)UnaryOperatorKind.LiftedFloatUnaryPlus,
(int)UnaryOperatorKind.LiftedDoubleUnaryPlus,
(int)UnaryOperatorKind.LiftedDecimalUnaryPlus,
......@@ -177,11 +197,13 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
{
(int)UnaryOperatorKind.IntUnaryMinus,
(int)UnaryOperatorKind.LongUnaryMinus,
(int)UnaryOperatorKind.NIntUnaryMinus,
(int)UnaryOperatorKind.FloatUnaryMinus,
(int)UnaryOperatorKind.DoubleUnaryMinus,
(int)UnaryOperatorKind.DecimalUnaryMinus,
(int)UnaryOperatorKind.LiftedIntUnaryMinus,
(int)UnaryOperatorKind.LiftedLongUnaryMinus,
(int)UnaryOperatorKind.LiftedNIntUnaryMinus,
(int)UnaryOperatorKind.LiftedFloatUnaryMinus,
(int)UnaryOperatorKind.LiftedDoubleUnaryMinus,
(int)UnaryOperatorKind.LiftedDecimalUnaryMinus,
......@@ -197,10 +219,14 @@ internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<Una
(int)UnaryOperatorKind.UIntBitwiseComplement,
(int)UnaryOperatorKind.LongBitwiseComplement,
(int)UnaryOperatorKind.ULongBitwiseComplement,
(int)UnaryOperatorKind.NIntBitwiseComplement,
(int)UnaryOperatorKind.NUIntBitwiseComplement,
(int)UnaryOperatorKind.LiftedIntBitwiseComplement,
(int)UnaryOperatorKind.LiftedUIntBitwiseComplement,
(int)UnaryOperatorKind.LiftedLongBitwiseComplement,
(int)UnaryOperatorKind.LiftedULongBitwiseComplement,
(int)UnaryOperatorKind.LiftedNIntBitwiseComplement,
(int)UnaryOperatorKind.LiftedNUIntBitwiseComplement,
}),
// No built-in operator true or operator false
ImmutableArray<UnaryOperatorSignature>.Empty,
......
......@@ -687,16 +687,15 @@ private BoundExpression MakeBuiltInIncrementOperator(BoundIncrementOperator node
BinaryOperatorKind binaryOperatorKind = GetCorrespondingBinaryOperator(node);
binaryOperatorKind |= IsIncrement(node) ? BinaryOperatorKind.Addition : BinaryOperatorKind.Subtraction;
// The input/output type of the binary operand. "int" in the example.
// The "1" in the example above.
ConstantValue constantOne = GetConstantOneForBinOp(binaryOperatorKind);
(TypeSymbol binaryOperandType, ConstantValue constantOne) = GetConstantOneForIncrement(_compilation, binaryOperatorKind);
Debug.Assert(constantOne != null);
Debug.Assert(constantOne.SpecialType != SpecialType.None);
Debug.Assert(binaryOperandType.SpecialType != SpecialType.None);
Debug.Assert(binaryOperatorKind.OperandTypes() != 0);
// The input/output type of the binary operand. "int" in the example.
TypeSymbol binaryOperandType = _compilation.GetSpecialType(constantOne.SpecialType);
// 1
BoundExpression boundOne = MakeLiteral(
syntax: node.Syntax,
......@@ -900,6 +899,12 @@ private TypeSymbol GetUnaryOperatorType(BoundIncrementOperator node)
case UnaryOperatorKind.ULong:
specialType = SpecialType.System_UInt64;
break;
case UnaryOperatorKind.NInt:
specialType = SpecialType.System_IntPtr;
break;
case UnaryOperatorKind.NUInt:
specialType = SpecialType.System_UIntPtr;
break;
case UnaryOperatorKind.Float:
specialType = SpecialType.System_Single;
break;
......@@ -955,6 +960,12 @@ private static BinaryOperatorKind GetCorrespondingBinaryOperator(BoundIncrementO
case UnaryOperatorKind.ULong:
result = BinaryOperatorKind.ULong;
break;
case UnaryOperatorKind.NInt:
result = BinaryOperatorKind.NInt;
break;
case UnaryOperatorKind.NUInt:
result = BinaryOperatorKind.NUInt;
break;
case UnaryOperatorKind.Float:
result = BinaryOperatorKind.Float;
break;
......@@ -1015,6 +1026,8 @@ private static BinaryOperatorKind GetCorrespondingBinaryOperator(BoundIncrementO
case BinaryOperatorKind.Int:
case BinaryOperatorKind.ULong:
case BinaryOperatorKind.Long:
case BinaryOperatorKind.NUInt:
case BinaryOperatorKind.NInt:
case BinaryOperatorKind.PointerAndInt:
result |= (BinaryOperatorKind)unaryOperatorKind.OverflowChecks();
break;
......@@ -1028,29 +1041,45 @@ private static BinaryOperatorKind GetCorrespondingBinaryOperator(BoundIncrementO
return result;
}
private static ConstantValue GetConstantOneForBinOp(
private static (TypeSymbol, ConstantValue) GetConstantOneForIncrement(
CSharpCompilation compilation,
BinaryOperatorKind binaryOperatorKind)
{
ConstantValue constantOne;
switch (binaryOperatorKind.OperandTypes())
{
case BinaryOperatorKind.PointerAndInt:
case BinaryOperatorKind.Int:
return ConstantValue.Create(1);
constantOne = ConstantValue.Create(1);
break;
case BinaryOperatorKind.UInt:
return ConstantValue.Create(1U);
constantOne = ConstantValue.Create(1U);
break;
case BinaryOperatorKind.Long:
return ConstantValue.Create(1L);
constantOne = ConstantValue.Create(1L);
break;
case BinaryOperatorKind.ULong:
return ConstantValue.Create(1LU);
constantOne = ConstantValue.Create(1LU);
break;
case BinaryOperatorKind.NInt:
constantOne = ConstantValue.Create(1);
return (compilation.GetSpecialType(SpecialType.System_IntPtr).AsNativeInt(true), constantOne);
case BinaryOperatorKind.NUInt:
constantOne = ConstantValue.Create(1U);
return (compilation.GetSpecialType(SpecialType.System_UIntPtr).AsNativeInt(true), constantOne);
case BinaryOperatorKind.Float:
return ConstantValue.Create(1f);
constantOne = ConstantValue.Create(1f);
break;
case BinaryOperatorKind.Double:
return ConstantValue.Create(1.0);
constantOne = ConstantValue.Create(1.0);
break;
case BinaryOperatorKind.Decimal:
return ConstantValue.Create(1m);
constantOne = ConstantValue.Create(1m);
break;
default:
throw ExceptionUtilities.UnexpectedValue(binaryOperatorKind.OperandTypes());
}
return (compilation.GetSpecialType(constantOne.SpecialType), constantOne);
}
}
}
......@@ -41,7 +41,7 @@ public static bool CanBeConst(this TypeSymbol typeSymbol)
{
RoslynDebug.Assert((object)typeSymbol != null);
return typeSymbol.IsReferenceType || typeSymbol.IsEnumType() || typeSymbol.SpecialType.CanBeConst();
return typeSymbol.IsReferenceType || typeSymbol.IsEnumType() || typeSymbol.SpecialType.CanBeConst() || (typeSymbol as NamedTypeSymbol)?.IsNativeInt == true;
}
/// <summary>
......@@ -476,6 +476,8 @@ public static MethodSymbol DelegateInvokeMethod(this TypeSymbol type)
case SpecialType.System_UInt32:
case SpecialType.System_Int64:
case SpecialType.System_UInt64:
case SpecialType.System_IntPtr when ((NamedTypeSymbol)type).IsNativeInt:
case SpecialType.System_UIntPtr when ((NamedTypeSymbol)type).IsNativeInt:
case SpecialType.System_Char:
case SpecialType.System_Boolean:
case SpecialType.System_Single:
......
......@@ -597,6 +597,12 @@ internal void EmitConstantValue(ConstantValue value)
case ConstantValueTypeDiscriminator.UInt64:
EmitLongConstant(value.Int64Value);
break;
case ConstantValueTypeDiscriminator.NInt:
EmitNativeIntConstant(value.Int32Value);
break;
case ConstantValueTypeDiscriminator.NUInt:
EmitNativeIntConstant(value.UInt32Value);
break;
case ConstantValueTypeDiscriminator.Single:
EmitSingleConstant(value.SingleValue);
break;
......@@ -695,6 +701,24 @@ internal void EmitLongConstant(long value)
}
}
internal void EmitNativeIntConstant(long value)
{
if (value >= int.MinValue && value <= int.MaxValue)
{
EmitIntConstant((int)value);
EmitOpCode(ILOpCode.Conv_i);
}
else if (value >= uint.MinValue && value <= uint.MaxValue)
{
EmitIntConstant(unchecked((int)value));
EmitOpCode(ILOpCode.Conv_u);
}
else
{
throw ExceptionUtilities.UnexpectedValue(value);
}
}
internal void EmitSingleConstant(float value)
{
EmitOpCode(ILOpCode.Ldc_r4);
......
......@@ -233,6 +233,34 @@ public static ConstantValue Create(UInt64 value)
return new ConstantValueI64(value);
}
public static ConstantValue CreateNativeInt(Int32 value)
{
if (value == 0)
{
return ConstantValueDefault.NInt;
}
else if (value == 1)
{
return ConstantValueOne.NInt;
}
return new ConstantValueNativeInt(value);
}
public static ConstantValue CreateNativeUInt(UInt32 value)
{
if (value == 0)
{
return ConstantValueDefault.NUInt;
}
else if (value == 1)
{
return ConstantValueOne.NUInt;
}
return new ConstantValueNativeInt(value);
}
public static ConstantValue Create(bool value)
{
if (value)
......@@ -345,8 +373,8 @@ public static ConstantValue Create(object value, ConstantValueTypeDiscriminator
case ConstantValueTypeDiscriminator.UInt32: return Create((uint)value);
case ConstantValueTypeDiscriminator.Int64: return Create((long)value);
case ConstantValueTypeDiscriminator.UInt64: return Create((ulong)value);
case ConstantValueTypeDiscriminator.NInt: return Create((int)value);
case ConstantValueTypeDiscriminator.NUInt: return Create((uint)value);
case ConstantValueTypeDiscriminator.NInt: return CreateNativeInt((int)value);
case ConstantValueTypeDiscriminator.NUInt: return CreateNativeUInt((uint)value);
case ConstantValueTypeDiscriminator.Char: return Create((char)value);
case ConstantValueTypeDiscriminator.Boolean: return Create((bool)value);
case ConstantValueTypeDiscriminator.Single:
......@@ -384,6 +412,8 @@ public static ConstantValue Default(ConstantValueTypeDiscriminator discriminator
case ConstantValueTypeDiscriminator.UInt32: return ConstantValueDefault.UInt32;
case ConstantValueTypeDiscriminator.Int64: return ConstantValueDefault.Int64;
case ConstantValueTypeDiscriminator.UInt64: return ConstantValueDefault.UInt64;
case ConstantValueTypeDiscriminator.NInt: return ConstantValueDefault.NInt;
case ConstantValueTypeDiscriminator.NUInt: return ConstantValueDefault.NUInt;
case ConstantValueTypeDiscriminator.Char: return ConstantValueDefault.Char;
case ConstantValueTypeDiscriminator.Boolean: return ConstantValueDefault.Boolean;
case ConstantValueTypeDiscriminator.Single: return ConstantValueDefault.Single;
......@@ -464,6 +494,8 @@ private static SpecialType GetSpecialType(ConstantValueTypeDiscriminator discrim
case ConstantValueTypeDiscriminator.UInt32: return Boxes.Box(UInt32Value);
case ConstantValueTypeDiscriminator.Int64: return Boxes.Box(Int64Value);
case ConstantValueTypeDiscriminator.UInt64: return Boxes.Box(UInt64Value);
case ConstantValueTypeDiscriminator.NInt: return Boxes.Box(Int32Value);
case ConstantValueTypeDiscriminator.NUInt: return Boxes.Box(UInt32Value);
case ConstantValueTypeDiscriminator.Char: return Boxes.Box(CharValue);
case ConstantValueTypeDiscriminator.Boolean: return Boxes.Box(BooleanValue);
case ConstantValueTypeDiscriminator.Single: return Boxes.Box(SingleValue);
......
......@@ -303,6 +303,8 @@ private class ConstantValueDefault : ConstantValueDiscriminated
public static readonly ConstantValueDefault UInt32 = new ConstantValueDefault(ConstantValueTypeDiscriminator.UInt32);
public static readonly ConstantValueDefault Int64 = new ConstantValueDefault(ConstantValueTypeDiscriminator.Int64);
public static readonly ConstantValueDefault UInt64 = new ConstantValueDefault(ConstantValueTypeDiscriminator.UInt64);
public static readonly ConstantValueDefault NInt = new ConstantValueDefault(ConstantValueTypeDiscriminator.NInt);
public static readonly ConstantValueDefault NUInt = new ConstantValueDefault(ConstantValueTypeDiscriminator.NUInt);
public static readonly ConstantValueDefault Char = new ConstantValueDefault(ConstantValueTypeDiscriminator.Char);
public static readonly ConstantValueDefault Single = new ConstantValueSingleZero();
public static readonly ConstantValueDefault Double = new ConstantValueDoubleZero();
......@@ -475,6 +477,8 @@ private class ConstantValueOne : ConstantValueDiscriminated
public static readonly ConstantValueOne UInt32 = new ConstantValueOne(ConstantValueTypeDiscriminator.UInt32);
public static readonly ConstantValueOne Int64 = new ConstantValueOne(ConstantValueTypeDiscriminator.Int64);
public static readonly ConstantValueOne UInt64 = new ConstantValueOne(ConstantValueTypeDiscriminator.UInt64);
public static readonly ConstantValueOne NInt = new ConstantValueOne(ConstantValueTypeDiscriminator.NInt);
public static readonly ConstantValueOne NUInt = new ConstantValueOne(ConstantValueTypeDiscriminator.NUInt);
public static readonly ConstantValueOne Single = new ConstantValueOne(ConstantValueTypeDiscriminator.Single);
public static readonly ConstantValueOne Double = new ConstantValueOne(ConstantValueTypeDiscriminator.Double);
public static readonly ConstantValueOne Decimal = new ConstantValueDecimalOne();
......@@ -754,6 +758,50 @@ public override bool Equals(ConstantValue? other)
}
}
private sealed class ConstantValueNativeInt : ConstantValueDiscriminated
{
// Constants are limited to 32-bit for portability.
private readonly int _value;
public ConstantValueNativeInt(int value)
: base(ConstantValueTypeDiscriminator.NInt)
{
_value = value;
}
public ConstantValueNativeInt(uint value)
: base(ConstantValueTypeDiscriminator.NUInt)
{
_value = unchecked((int)value);
}
public override int Int32Value
{
get
{
return _value;
}
}
public override uint UInt32Value
{
get
{
return unchecked((uint)_value);
}
}
public override int GetHashCode()
{
return Hash.Combine(base.GetHashCode(), _value.GetHashCode());
}
public override bool Equals(ConstantValue? other)
{
return base.Equals(other) && _value == other.Int32Value;
}
}
private sealed class ConstantValueDouble : ConstantValueDiscriminated
{
private readonly double _value;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册