X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fmcs%2Fconstant.cs;h=397d72c9a4ae7653be65733999a337aaf1567695;hb=3f9310e59b924a8ef63dfef6c7f3c72935ac8f21;hp=da0670125a64d6b76f648c1a94c82f7e15b71bda;hpb=a10a9813057cfc4f7d186989f292a529e4112208;p=mono.git diff --git a/mcs/mcs/constant.cs b/mcs/mcs/constant.cs index da0670125a6..397d72c9a4a 100644 --- a/mcs/mcs/constant.cs +++ b/mcs/mcs/constant.cs @@ -3,10 +3,11 @@ // // Author: // Miguel de Icaza (miguel@ximian.com) -// Marek Safar (marek.safar@seznam.cz) +// Marek Safar (marek.safar@gmail.com) // // Copyright 2001-2003 Ximian, Inc. // Copyright 2003-2008 Novell, Inc. +// Copyright 2011-2013 Xamarin Inc // using System; @@ -57,33 +58,38 @@ namespace Mono.CSharp { } #endif - public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl) + public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { if (!expl && IsLiteral && - BuildinTypeSpec.IsPrimitiveNumericOrDecimalType (target) && - BuildinTypeSpec.IsPrimitiveNumericOrDecimalType (type)) { + BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) && + BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", - GetValueAsLiteral (), TypeManager.CSharpName (target)); + GetValueAsLiteral (), target.GetSignatureForError ()); } else { - base.Error_ValueCannotBeConverted (ec, loc, target, expl); + base.Error_ValueCannotBeConverted (ec, target, expl); } } public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc) { - Constant c = ConvertImplicitly (ec, type); + Constant c = ConvertImplicitly (type); if (c == null) - Error_ValueCannotBeConverted (ec, loc, type, false); + Error_ValueCannotBeConverted (ec, type, false); return c; } - public virtual Constant ConvertImplicitly (ResolveContext rc, TypeSpec type) + public override bool ContainsEmitWithAwait () + { + return false; + } + + public virtual Constant ConvertImplicitly (TypeSpec type) { if (this.type == type) return this; - if (Convert.ImplicitNumericConversion (this, type) == null) + if (!Convert.ImplicitNumericConversionExists (this.type, type)) return null; bool fail; @@ -94,77 +100,73 @@ namespace Mono.CSharp { // reached, by calling Convert.ImplicitStandardConversionExists // throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'", - TypeManager.CSharpName (Type), TypeManager.CSharpName (type)); + Type.GetSignatureForError (), type.GetSignatureForError ()); } - return CreateConstant (rc, type, constant_value, loc); + return CreateConstantFromValue (type, constant_value, loc); } // // Returns a constant instance based on Type // - public static Constant CreateConstant (ResolveContext rc, TypeSpec t, object v, Location loc) - { - return CreateConstantFromValue (t, v, loc).Resolve (rc); - } - public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc) { - if (t.BuildinType > 0) { - switch (t.BuildinType) { - case BuildinTypeSpec.Type.Int: - return new IntConstant ((int) v, loc); - case BuildinTypeSpec.Type.String: - return new StringConstant ((string) v, loc); - case BuildinTypeSpec.Type.UInt: - return new UIntConstant ((uint) v, loc); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) v, loc); - case BuildinTypeSpec.Type.ULong: - return new ULongConstant ((ulong) v, loc); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) v, loc); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) v, loc); - case BuildinTypeSpec.Type.Short: - return new ShortConstant ((short) v, loc); - case BuildinTypeSpec.Type.UShort: - return new UShortConstant ((ushort) v, loc); - case BuildinTypeSpec.Type.SByte: - return new SByteConstant ((sbyte) v, loc); - case BuildinTypeSpec.Type.Byte: - return new ByteConstant ((byte) v, loc); - case BuildinTypeSpec.Type.Char: - return new CharConstant ((char) v, loc); - case BuildinTypeSpec.Type.Bool: - return new BoolConstant ((bool) v, loc); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) v, loc); - } + switch (t.BuiltinType) { + case BuiltinTypeSpec.Type.Int: + return new IntConstant (t, (int) v, loc); + case BuiltinTypeSpec.Type.String: + return new StringConstant (t, (string) v, loc); + case BuiltinTypeSpec.Type.UInt: + return new UIntConstant (t, (uint) v, loc); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (t, (long) v, loc); + case BuiltinTypeSpec.Type.ULong: + return new ULongConstant (t, (ulong) v, loc); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (t, (float) v, loc); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (t, (double) v, loc); + case BuiltinTypeSpec.Type.Short: + return new ShortConstant (t, (short) v, loc); + case BuiltinTypeSpec.Type.UShort: + return new UShortConstant (t, (ushort) v, loc); + case BuiltinTypeSpec.Type.SByte: + return new SByteConstant (t, (sbyte) v, loc); + case BuiltinTypeSpec.Type.Byte: + return new ByteConstant (t, (byte) v, loc); + case BuiltinTypeSpec.Type.Char: + return new CharConstant (t, (char) v, loc); + case BuiltinTypeSpec.Type.Bool: + return new BoolConstant (t, (bool) v, loc); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (t, (decimal) v, loc); } if (t.IsEnum) { var real_type = EnumSpec.GetUnderlyingType (t); - return new EnumConstant (CreateConstantFromValue (real_type, v, loc).Resolve (null), t); + return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t); } if (v == null) { - if (TypeManager.IsNullableType (t)) + if (t.IsNullableType) return Nullable.LiftedNull.Create (t, loc); - if (TypeManager.IsReferenceType (t)) + if (TypeSpec.IsReferenceType (t)) return new NullConstant (t, loc); } - throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", - v, TypeManager.CSharpName (t)); +#if STATIC + throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ()); +#else + return null; +#endif } public override Expression CreateExpressionTree (ResolveContext ec) { Arguments args = new Arguments (2); args.Add (new Argument (this)); - args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc))); + args.Add (new Argument (new TypeOf (type, loc))); return CreateExpressionFactoryCall (ec, "Constant", args); } @@ -194,42 +196,42 @@ namespace Mono.CSharp { // error = false; try { - switch (targetType.BuildinType) { - case BuildinTypeSpec.Type.Bool: + switch (targetType.BuiltinType) { + case BuiltinTypeSpec.Type.Bool: return convert_value.ToBoolean (nfi); - case BuildinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.Byte: return convert_value.ToByte (nfi); - case BuildinTypeSpec.Type.Char: + case BuiltinTypeSpec.Type.Char: return convert_value.ToChar (nfi); - case BuildinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.Short: return convert_value.ToInt16 (nfi); - case BuildinTypeSpec.Type.Int: + case BuiltinTypeSpec.Type.Int: return convert_value.ToInt32 (nfi); - case BuildinTypeSpec.Type.Long: + case BuiltinTypeSpec.Type.Long: return convert_value.ToInt64 (nfi); - case BuildinTypeSpec.Type.SByte: + case BuiltinTypeSpec.Type.SByte: return convert_value.ToSByte (nfi); - case BuildinTypeSpec.Type.Decimal: + case BuiltinTypeSpec.Type.Decimal: if (convert_value.GetType () == typeof (char)) return (decimal) convert_value.ToInt32 (nfi); return convert_value.ToDecimal (nfi); - case BuildinTypeSpec.Type.Double: + case BuiltinTypeSpec.Type.Double: if (convert_value.GetType () == typeof (char)) return (double) convert_value.ToInt32 (nfi); return convert_value.ToDouble (nfi); - case BuildinTypeSpec.Type.Float: + case BuiltinTypeSpec.Type.Float: if (convert_value.GetType () == typeof (char)) return (float) convert_value.ToInt32 (nfi); return convert_value.ToSingle (nfi); - case BuildinTypeSpec.Type.String: + case BuiltinTypeSpec.Type.String: return convert_value.ToString (nfi); - case BuildinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.UShort: return convert_value.ToUInt16 (nfi); - case BuildinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.UInt: return convert_value.ToUInt32 (nfi); - case BuildinTypeSpec.Type.ULong: + case BuiltinTypeSpec.Type.ULong: return convert_value.ToUInt64 (nfi); - case BuildinTypeSpec.Type.Object: + case BuiltinTypeSpec.Type.Object: return value; } } catch { @@ -239,46 +241,64 @@ namespace Mono.CSharp { return null; } - /// - /// Attempts to do a compile-time folding of a constant cast. - /// - public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc) + protected override Expression DoResolve (ResolveContext rc) + { + return this; + } + + // + // Attempts to do a compile-time folding of a constant cast and handles + // error reporting for constant overlows only, on normal conversion + // errors returns null + // + public Constant Reduce (ResolveContext ec, TypeSpec target_type) { try { - return TryReduce (ec, target_type); - } - catch (OverflowException) { - if (ec.ConstantCheckState && Type.BuildinType != BuildinTypeSpec.Type.Decimal) { + return TryReduceConstant (ec, target_type); + } catch (OverflowException) { + if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) { ec.Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)", GetValueAsLiteral (), target_type.GetSignatureForError ()); } else { - Error_ValueCannotBeConverted (ec, loc, target_type, false); + Error_ValueCannotBeConverted (ec, target_type, false); } - return New.Constantify (target_type, loc).Resolve (ec); + return New.Constantify (target_type, loc); + } + } + + public Constant TryReduce (ResolveContext rc, TypeSpec targetType) + { + try { + return TryReduceConstant (rc, targetType); + } catch (OverflowException) { + return null; } } - Constant TryReduce (ResolveContext ec, TypeSpec target_type) + Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type) { - if (Type == target_type) + if (Type == target_type) { + // + // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10 + // + if (IsLiteral) + return CreateConstantFromValue (target_type, GetValue (), loc); + return this; + } Constant c; - if (TypeManager.IsEnumType (target_type)) { - c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type)); + if (target_type.IsEnum) { + c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type)); if (c == null) return null; - return new EnumConstant (c, target_type).Resolve (ec); + return new EnumConstant (c, target_type); } - c = ConvertExplicitly (ec.ConstantCheckState, target_type); - if (c != null) - c = c.Resolve (ec); - - return c; + return ConvertExplicitly (ec.ConstantCheckState, target_type); } /// @@ -310,7 +330,13 @@ namespace Mono.CSharp { public virtual bool IsOneInteger { get { return false; } - } + } + + public override bool IsSideEffectFree { + get { + return true; + } + } // // Returns true iff 1) the stack type of this is one of Object, @@ -345,45 +371,32 @@ namespace Mono.CSharp { #endif } - public new Constant Resolve (ResolveContext rc) + public new bool Resolve (ResolveContext rc) { - if (eclass != ExprClass.Unresolved) - return this; - - // Resolved constant has to be still a constant - Constant c = (Constant) DoResolve (rc); - if (c == null) - return null; - - if ((c.eclass & ExprClass.Value) == 0) { - c.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc); - return null; - } - - if (c.type == null) - throw new InternalErrorException ("Expression `{0}' did not set its type after Resolve", c.GetType ()); - - return c; + // It exists only as hint not to call Resolve on constants + return true; } } public abstract class IntegralConstant : Constant { - protected IntegralConstant (Location loc) : - base (loc) + protected IntegralConstant (TypeSpec type, Location loc) + : base (loc) { + this.type = type; + eclass = ExprClass.Value; } - public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl) + public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { try { ConvertExplicitly (true, target); - base.Error_ValueCannotBeConverted (ec, loc, target, expl); + base.Error_ValueCannotBeConverted (ec, target, expl); } catch { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", - GetValue ().ToString (), TypeManager.CSharpName (target)); + GetValue ().ToString (), target.GetSignatureForError ()); } } @@ -397,18 +410,19 @@ namespace Mono.CSharp { public class BoolConstant : Constant { public readonly bool Value; - - public BoolConstant (bool val, Location loc): - base (loc) + + public BoolConstant (BuiltinTypes types, bool val, Location loc) + : this (types.Bool, val, loc) { - Value = val; } - - protected override Expression DoResolve (ResolveContext ec) + + public BoolConstant (TypeSpec type, bool val, Location loc) + : base (loc) { - type = TypeManager.bool_type; eclass = ExprClass.Value; - return this; + this.type = type; + + Value = val; } public override object GetValue () @@ -434,9 +448,9 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { if (Value) - ec.Emit (OpCodes.Ldc_I4_1); + ec.EmitInt (1); else - ec.Emit (OpCodes.Ldc_I4_0); + ec.EmitInt (0); } public override bool IsDefaultValue { @@ -466,8 +480,13 @@ namespace Mono.CSharp { { public readonly byte Value; - public ByteConstant (byte v, Location loc): - base (loc) + public ByteConstant (BuiltinTypes types, byte v, Location loc) + : this (types.Byte, v, loc) + { + } + + public ByteConstant (TypeSpec type, byte v, Location loc) + : base (type, loc) { Value = v; } @@ -482,13 +501,6 @@ namespace Mono.CSharp { ec.EmitInt (Value); } - protected override Expression DoResolve (ResolveContext ec) - { - type = TypeManager.byte_type; - eclass = ExprClass.Value; - return this; - } - public override object GetValue () { return Value; @@ -501,7 +513,7 @@ namespace Mono.CSharp { public override Constant Increment () { - return new ByteConstant (checked ((byte)(Value + 1)), loc); + return new ByteConstant (type, checked ((byte)(Value + 1)), loc); } public override bool IsDefaultValue { @@ -528,33 +540,33 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.SByte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.SByte: if (in_checked_context){ if (Value > SByte.MaxValue) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.UShort: - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.Int: - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.Short: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.UShort: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.Int: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; @@ -565,17 +577,18 @@ namespace Mono.CSharp { public class CharConstant : Constant { public readonly char Value; - public CharConstant (char v, Location loc): - base (loc) + public CharConstant (BuiltinTypes types, char v, Location loc) + : this (types.Char, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public CharConstant (TypeSpec type, char v, Location loc) + : base (loc) { - type = TypeManager.char_type; + this.type = type; eclass = ExprClass.Value; - return this; + + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -650,40 +663,40 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context) { if (Value < Byte.MinValue || Value > Byte.MaxValue) throw new OverflowException (); } - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value > SByte.MaxValue) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); + return new SByteConstant (target_type, (sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.Short: if (in_checked_context) { if (Value > Int16.MaxValue) throw new OverflowException (); } - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.Int: - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.Int: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; @@ -691,20 +704,19 @@ namespace Mono.CSharp { } - public class SByteConstant : IntegralConstant { + public class SByteConstant : IntegralConstant + { public readonly sbyte Value; - public SByteConstant (sbyte v, Location loc): - base (loc) + public SByteConstant (BuiltinTypes types, sbyte v, Location loc) + : this (types.SByte, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public SByteConstant (TypeSpec type, sbyte v, Location loc) + : base (type, loc) { - type = TypeManager.sbyte_type; - eclass = ExprClass.Value; - return this; + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -729,7 +741,7 @@ namespace Mono.CSharp { public override Constant Increment () { - return new SByteConstant (checked((sbyte)(Value + 1)), loc); + return new SByteConstant (type, checked((sbyte)(Value + 1)), loc); } public override bool IsDefaultValue { @@ -756,39 +768,39 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context && Value < 0) throw new OverflowException (); - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.Short: - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.UShort: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.Short: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.UShort: if (in_checked_context && Value < 0) throw new OverflowException (); - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.Int: - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.Int: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: if (in_checked_context && Value < 0) throw new OverflowException (); - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: if (in_checked_context && Value < 0) throw new OverflowException (); - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context && Value < 0) throw new OverflowException (); - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; @@ -799,17 +811,15 @@ namespace Mono.CSharp { public class ShortConstant : IntegralConstant { public readonly short Value; - public ShortConstant (short v, Location loc): - base (loc) + public ShortConstant (BuiltinTypes types, short v, Location loc) + : this (types.Short, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public ShortConstant (TypeSpec type, short v, Location loc) + : base (type, loc) { - type = TypeManager.short_type; - eclass = ExprClass.Value; - return this; + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -834,7 +844,7 @@ namespace Mono.CSharp { public override Constant Increment () { - return new ShortConstant (checked((short)(Value + 1)), loc); + return new ShortConstant (type, checked((short)(Value + 1)), loc); } public override bool IsDefaultValue { @@ -861,48 +871,48 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context) { if (Value < Byte.MinValue || Value > Byte.MaxValue) throw new OverflowException (); } - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value < SByte.MinValue || Value > SByte.MaxValue) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.UShort: + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.UShort: if (in_checked_context && Value < 0) throw new OverflowException (); - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.Int: - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.Int: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: if (in_checked_context && Value < 0) throw new OverflowException (); - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: if (in_checked_context && Value < 0) throw new OverflowException (); - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context) { if (Value < Char.MinValue) throw new OverflowException (); } - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; @@ -914,17 +924,15 @@ namespace Mono.CSharp { { public readonly ushort Value; - public UShortConstant (ushort v, Location loc): - base (loc) + public UShortConstant (BuiltinTypes types, ushort v, Location loc) + : this (types.UShort, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public UShortConstant (TypeSpec type, ushort v, Location loc) + : base (type, loc) { - type = TypeManager.ushort_type; - eclass = ExprClass.Value; - return this; + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -949,7 +957,7 @@ namespace Mono.CSharp { public override Constant Increment () { - return new UShortConstant (checked((ushort)(Value + 1)), loc); + return new UShortConstant (type, checked((ushort)(Value + 1)), loc); } public override bool IsDefaultValue { @@ -976,65 +984,64 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context) { if (Value > Byte.MaxValue) throw new OverflowException (); } - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value > SByte.MaxValue) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.Short: if (in_checked_context) { if (Value > Int16.MaxValue) throw new OverflowException (); } - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.Int: - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.Int: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context) { if (Value > Char.MaxValue) throw new OverflowException (); } - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; } } - public class IntConstant : IntegralConstant { + public class IntConstant : IntegralConstant + { public readonly int Value; - public IntConstant (int v, Location loc): - base (loc) + public IntConstant (BuiltinTypes types, int v, Location loc) + : this (types.Int, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public IntConstant (TypeSpec type, int v, Location loc) + : base (type, loc) { - type = TypeManager.int32_type; - eclass = ExprClass.Value; - return this; + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -1059,7 +1066,7 @@ namespace Mono.CSharp { public override Constant Increment () { - return new IntConstant (checked(Value + 1), loc); + return new IntConstant (type, checked(Value + 1), loc); } public override bool IsDefaultValue { @@ -1086,70 +1093,70 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context) { if (Value < Byte.MinValue || Value > Byte.MaxValue) throw new OverflowException (); } - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value < SByte.MinValue || Value > SByte.MaxValue) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.Short: if (in_checked_context) { if (Value < Int16.MinValue || Value > Int16.MaxValue) throw new OverflowException (); } - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.UShort: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.UShort: if (in_checked_context) { if (Value < UInt16.MinValue || Value > UInt16.MaxValue) throw new OverflowException (); } - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.UInt: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.UInt: if (in_checked_context) { if (Value < UInt32.MinValue) throw new OverflowException (); } - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: if (in_checked_context && Value < 0) throw new OverflowException (); - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context) { if (Value < Char.MinValue || Value > Char.MaxValue) throw new OverflowException (); } - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; } - public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type) + public override Constant ConvertImplicitly (TypeSpec type) { if (this.type == type) return this; Constant c = TryImplicitIntConversion (type); if (c != null) - return c.Resolve (rc); + return c; //.Resolve (rc); - return base.ConvertImplicitly (rc, type); + return base.ConvertImplicitly (type); } /// @@ -1159,40 +1166,40 @@ namespace Mono.CSharp { /// Constant TryImplicitIntConversion (TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.SByte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.SByte: if (Value >= SByte.MinValue && Value <= SByte.MaxValue) - return new SByteConstant ((sbyte) Value, loc); + return new SByteConstant (target_type, (sbyte) Value, loc); break; - case BuildinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.Byte: if (Value >= Byte.MinValue && Value <= Byte.MaxValue) - return new ByteConstant ((byte) Value, loc); + return new ByteConstant (target_type, (byte) Value, loc); break; - case BuildinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.Short: if (Value >= Int16.MinValue && Value <= Int16.MaxValue) - return new ShortConstant ((short) Value, loc); + return new ShortConstant (target_type, (short) Value, loc); break; - case BuildinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.UShort: if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue) - return new UShortConstant ((ushort) Value, loc); + return new UShortConstant (target_type, (ushort) Value, loc); break; - case BuildinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.UInt: if (Value >= 0) - return new UIntConstant ((uint) Value, loc); + return new UIntConstant (target_type, (uint) Value, loc); break; - case BuildinTypeSpec.Type.ULong: + case BuiltinTypeSpec.Type.ULong: // // we can optimize this case: a positive int32 // always fits on a uint64. But we need an opcode // to do it. // if (Value >= 0) - return new ULongConstant ((ulong) Value, loc); + return new ULongConstant (target_type, (ulong) Value, loc); break; - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, loc); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, loc); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, loc); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, loc); } return null; @@ -1202,17 +1209,15 @@ namespace Mono.CSharp { public class UIntConstant : IntegralConstant { public readonly uint Value; - public UIntConstant (uint v, Location loc): - base (loc) + public UIntConstant (BuiltinTypes types, uint v, Location loc) + : this (types.UInt, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public UIntConstant (TypeSpec type, uint v, Location loc) + : base (type, loc) { - type = TypeManager.uint32_type; - eclass = ExprClass.Value; - return this; + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -1237,7 +1242,7 @@ namespace Mono.CSharp { public override Constant Increment () { - return new UIntConstant (checked(Value + 1), loc); + return new UIntConstant (type, checked(Value + 1), loc); } public override bool IsDefaultValue { @@ -1264,53 +1269,53 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context) { if (Value < 0 || Value > byte.MaxValue) throw new OverflowException (); } - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value > SByte.MaxValue) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.Short: if (in_checked_context) { if (Value > Int16.MaxValue) throw new OverflowException (); } - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.UShort: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.UShort: if (in_checked_context) { if (Value < UInt16.MinValue || Value > UInt16.MaxValue) throw new OverflowException (); } - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.Int: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.Int: if (in_checked_context) { if (Value > Int32.MaxValue) throw new OverflowException (); } - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context) { if (Value < Char.MinValue || Value > Char.MaxValue) throw new OverflowException (); } - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; @@ -1321,17 +1326,15 @@ namespace Mono.CSharp { public class LongConstant : IntegralConstant { public readonly long Value; - public LongConstant (long v, Location loc): - base (loc) + public LongConstant (BuiltinTypes types, long v, Location loc) + : this (types.Long, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public LongConstant (TypeSpec type, long v, Location loc) + : base (type, loc) { - type = TypeManager.int64_type; - eclass = ExprClass.Value; - return this; + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -1356,7 +1359,7 @@ namespace Mono.CSharp { public override Constant Increment () { - return new LongConstant (checked(Value + 1), loc); + return new LongConstant (type, checked(Value + 1), loc); } public override bool IsDefaultValue { @@ -1383,88 +1386,86 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context) { if (Value < Byte.MinValue || Value > Byte.MaxValue) throw new OverflowException (); } - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value < SByte.MinValue || Value > SByte.MaxValue) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.Short: if (in_checked_context) { if (Value < Int16.MinValue || Value > Int16.MaxValue) throw new OverflowException (); } - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.UShort: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.UShort: if (in_checked_context) { if (Value < UInt16.MinValue || Value > UInt16.MaxValue) throw new OverflowException (); } - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.Int: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.Int: if (in_checked_context) { if (Value < Int32.MinValue || Value > Int32.MaxValue) throw new OverflowException (); } - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: if (in_checked_context) { if (Value < UInt32.MinValue || Value > UInt32.MaxValue) throw new OverflowException (); } - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.ULong: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.ULong: if (in_checked_context && Value < 0) throw new OverflowException (); - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context) { if (Value < Char.MinValue || Value > Char.MaxValue) throw new OverflowException (); } - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; } - public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type) + public override Constant ConvertImplicitly (TypeSpec type) { - if (Value >= 0 && type == TypeManager.uint64_type) { - return new ULongConstant ((ulong) Value, loc).Resolve (rc); + if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) { + return new ULongConstant (type, (ulong) Value, loc); } - return base.ConvertImplicitly (rc, type); + return base.ConvertImplicitly (type); } } public class ULongConstant : IntegralConstant { public readonly ulong Value; - public ULongConstant (ulong v, Location loc): - base (loc) + public ULongConstant (BuiltinTypes types, ulong v, Location loc) + : this (types.ULong, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public ULongConstant (TypeSpec type, ulong v, Location loc) + : base (type, loc) { - type = TypeManager.uint64_type; - eclass = ExprClass.Value; - return this; + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -1489,7 +1490,7 @@ namespace Mono.CSharp { public override Constant Increment () { - return new ULongConstant (checked(Value + 1), loc); + return new ULongConstant (type, checked(Value + 1), loc); } public override bool IsDefaultValue { @@ -1516,45 +1517,45 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context && Value > Byte.MaxValue) throw new OverflowException (); - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context && Value > ((ulong) SByte.MaxValue)) throw new OverflowException (); - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.Short: if (in_checked_context && Value > ((ulong) Int16.MaxValue)) throw new OverflowException (); - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.UShort: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.UShort: if (in_checked_context && Value > UInt16.MaxValue) throw new OverflowException (); - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.Int: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.Int: if (in_checked_context && Value > UInt32.MaxValue) throw new OverflowException (); - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: if (in_checked_context && Value > UInt32.MaxValue) throw new OverflowException (); - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: if (in_checked_context && Value > Int64.MaxValue) throw new OverflowException (); - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context && Value > Char.MaxValue) throw new OverflowException (); - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; @@ -1563,19 +1564,20 @@ namespace Mono.CSharp { } public class FloatConstant : Constant { - public float Value; + public readonly float Value; - public FloatConstant (float v, Location loc): - base (loc) + public FloatConstant (BuiltinTypes types, float v, Location loc) + : this (types.Float, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public FloatConstant (TypeSpec type, float v, Location loc) + : base (loc) { - type = TypeManager.float_type; + this.type = type; eclass = ExprClass.Value; - return this; + + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -1617,65 +1619,65 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context) { if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.Short: if (in_checked_context) { if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.UShort: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.UShort: if (in_checked_context) { if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.Int: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.Int: if (in_checked_context) { if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: if (in_checked_context) { if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: if (in_checked_context) { if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: if (in_checked_context) { if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, Location); - case BuildinTypeSpec.Type.Char: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context) { if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value)) throw new OverflowException (); } - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; @@ -1683,20 +1685,22 @@ namespace Mono.CSharp { } - public class DoubleConstant : Constant { - public double Value; + public class DoubleConstant : Constant + { + public readonly double Value; - public DoubleConstant (double v, Location loc): - base (loc) + public DoubleConstant (BuiltinTypes types, double v, Location loc) + : this (types.Double, v, loc) { - Value = v; } - protected override Expression DoResolve (ResolveContext rc) + public DoubleConstant (TypeSpec type, double v, Location loc) + : base (loc) { - type = TypeManager.double_type; + this.type = type; eclass = ExprClass.Value; - return this; + + Value = v; } public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) @@ -1738,65 +1742,65 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.Byte: + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.Byte: if (in_checked_context) { if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new ByteConstant ((byte) Value, Location); - case BuildinTypeSpec.Type.SByte: + return new ByteConstant (target_type, (byte) Value, Location); + case BuiltinTypeSpec.Type.SByte: if (in_checked_context) { if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new SByteConstant ((sbyte) Value, Location); - case BuildinTypeSpec.Type.Short: + return new SByteConstant (target_type, (sbyte) Value, Location); + case BuiltinTypeSpec.Type.Short: if (in_checked_context) { if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new ShortConstant ((short) Value, Location); - case BuildinTypeSpec.Type.UShort: + return new ShortConstant (target_type, (short) Value, Location); + case BuiltinTypeSpec.Type.UShort: if (in_checked_context) { if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new UShortConstant ((ushort) Value, Location); - case BuildinTypeSpec.Type.Int: + return new UShortConstant (target_type, (ushort) Value, Location); + case BuiltinTypeSpec.Type.Int: if (in_checked_context) { if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new IntConstant ((int) Value, Location); - case BuildinTypeSpec.Type.UInt: + return new IntConstant (target_type, (int) Value, Location); + case BuiltinTypeSpec.Type.UInt: if (in_checked_context) { if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new UIntConstant ((uint) Value, Location); - case BuildinTypeSpec.Type.Long: + return new UIntConstant (target_type, (uint) Value, Location); + case BuiltinTypeSpec.Type.Long: if (in_checked_context) { if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new LongConstant ((long) Value, Location); - case BuildinTypeSpec.Type.ULong: + return new LongConstant (target_type, (long) Value, Location); + case BuiltinTypeSpec.Type.ULong: if (in_checked_context) { if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new ULongConstant ((ulong) Value, Location); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, Location); - case BuildinTypeSpec.Type.Char: + return new ULongConstant (target_type, (ulong) Value, Location); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, Location); + case BuiltinTypeSpec.Type.Char: if (in_checked_context) { if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value)) throw new OverflowException (); } - return new CharConstant ((char) Value, Location); - case BuildinTypeSpec.Type.Decimal: - return new DecimalConstant ((decimal) Value, Location); + return new CharConstant (target_type, (char) Value, Location); + case BuiltinTypeSpec.Type.Decimal: + return new DecimalConstant (target_type, (decimal) Value, Location); } return null; @@ -1807,50 +1811,47 @@ namespace Mono.CSharp { public class DecimalConstant : Constant { public readonly decimal Value; - public DecimalConstant (decimal d, Location loc): - base (loc) + public DecimalConstant (BuiltinTypes types, decimal d, Location loc) + : this (types.Decimal, d, loc) { - Value = d; } - protected override Expression DoResolve (ResolveContext rc) + public DecimalConstant (TypeSpec type, decimal d, Location loc) + : base (loc) { - type = TypeManager.decimal_type; + this.type = type; eclass = ExprClass.Value; - return this; + + Value = d; } public override void Emit (EmitContext ec) { + MethodSpec m; + int [] words = decimal.GetBits (Value); int power = (words [3] >> 16) & 0xff; if (power == 0) { if (Value <= int.MaxValue && Value >= int.MinValue) { - if (TypeManager.void_decimal_ctor_int_arg == null) { - TypeManager.void_decimal_ctor_int_arg = TypeManager.GetPredefinedConstructor ( - TypeManager.decimal_type, loc, TypeManager.int32_type); - - if (TypeManager.void_decimal_ctor_int_arg == null) - return; + m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc); + if (m == null) { + return; } ec.EmitInt ((int) Value); - ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg); + ec.Emit (OpCodes.Newobj, m); return; } if (Value <= long.MaxValue && Value >= long.MinValue) { - if (TypeManager.void_decimal_ctor_long_arg == null) { - TypeManager.void_decimal_ctor_long_arg = TypeManager.GetPredefinedConstructor ( - TypeManager.decimal_type, loc, TypeManager.int64_type); - - if (TypeManager.void_decimal_ctor_long_arg == null) - return; + m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc); + if (m == null) { + return; } ec.EmitLong ((long) Value); - ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_long_arg); + ec.Emit (OpCodes.Newobj, m); return; } } @@ -1865,16 +1866,10 @@ namespace Mono.CSharp { // power ec.EmitInt (power); - if (TypeManager.void_decimal_ctor_five_args == null) { - TypeManager.void_decimal_ctor_five_args = TypeManager.GetPredefinedConstructor ( - TypeManager.decimal_type, loc, TypeManager.int32_type, TypeManager.int32_type, - TypeManager.int32_type, TypeManager.bool_type, TypeManager.byte_type); - - if (TypeManager.void_decimal_ctor_five_args == null) - return; + m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc); + if (m != null) { + ec.Emit (OpCodes.Newobj, m); } - - ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args); } public override bool IsDefaultValue { @@ -1891,29 +1886,29 @@ namespace Mono.CSharp { public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type) { - switch (target_type.BuildinType) { - case BuildinTypeSpec.Type.SByte: - return new SByteConstant ((sbyte) Value, loc); - case BuildinTypeSpec.Type.Byte: - return new ByteConstant ((byte) Value, loc); - case BuildinTypeSpec.Type.Short: - return new ShortConstant ((short) Value, loc); - case BuildinTypeSpec.Type.UShort: - return new UShortConstant ((ushort) Value, loc); - case BuildinTypeSpec.Type.Int: - return new IntConstant ((int) Value, loc); - case BuildinTypeSpec.Type.UInt: - return new UIntConstant ((uint) Value, loc); - case BuildinTypeSpec.Type.Long: - return new LongConstant ((long) Value, loc); - case BuildinTypeSpec.Type.ULong: - return new ULongConstant ((ulong) Value, loc); - case BuildinTypeSpec.Type.Char: - return new CharConstant ((char) Value, loc); - case BuildinTypeSpec.Type.Float: - return new FloatConstant ((float) Value, loc); - case BuildinTypeSpec.Type.Double: - return new DoubleConstant ((double) Value, loc); + switch (target_type.BuiltinType) { + case BuiltinTypeSpec.Type.SByte: + return new SByteConstant (target_type, (sbyte) Value, loc); + case BuiltinTypeSpec.Type.Byte: + return new ByteConstant (target_type, (byte) Value, loc); + case BuiltinTypeSpec.Type.Short: + return new ShortConstant (target_type, (short) Value, loc); + case BuiltinTypeSpec.Type.UShort: + return new UShortConstant (target_type, (ushort) Value, loc); + case BuiltinTypeSpec.Type.Int: + return new IntConstant (target_type, (int) Value, loc); + case BuiltinTypeSpec.Type.UInt: + return new UIntConstant (target_type, (uint) Value, loc); + case BuiltinTypeSpec.Type.Long: + return new LongConstant (target_type, (long) Value, loc); + case BuiltinTypeSpec.Type.ULong: + return new ULongConstant (target_type, (ulong) Value, loc); + case BuiltinTypeSpec.Type.Char: + return new CharConstant (target_type, (char) Value, loc); + case BuiltinTypeSpec.Type.Float: + return new FloatConstant (target_type, (float) Value, loc); + case BuiltinTypeSpec.Type.Double: + return new DoubleConstant (target_type, (double) Value, loc); } return null; @@ -1938,17 +1933,18 @@ namespace Mono.CSharp { public class StringConstant : Constant { public readonly string Value; - public StringConstant (string s, Location loc): - base (loc) + public StringConstant (BuiltinTypes types, string s, Location loc) + : this (types.String, s, loc) { - Value = s; } - protected override Expression DoResolve (ResolveContext rc) + public StringConstant (TypeSpec type, string s, Location loc) + : base (loc) { - type = TypeManager.string_type; + this.type = type; eclass = ExprClass.Value; - return this; + + Value = s; } public override object GetValue () @@ -1970,7 +1966,7 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { if (Value == null) { - ec.Emit (OpCodes.Ldnull); + ec.EmitNull (); return; } @@ -1978,13 +1974,14 @@ namespace Mono.CSharp { // Use string.Empty for both literals and constants even if // it's not allowed at language level // - if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize && ec.CurrentType != TypeManager.string_type) { - if (TypeManager.string_empty == null) - TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc, TypeManager.string_type); - - if (TypeManager.string_empty != null) { - ec.Emit (OpCodes.Ldsfld, TypeManager.string_empty); - return; + if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) { + var string_type = ec.BuiltinTypes.String; + if (ec.CurrentType != string_type) { + var m = ec.Module.PredefinedMembers.StringEmpty.Get (); + if (m != null) { + ec.Emit (OpCodes.Ldsfld, m); + return; + } } } @@ -2038,7 +2035,7 @@ namespace Mono.CSharp { public override Expression CreateExpressionTree (ResolveContext ec) { - if (type == InternalType.Null || type == TypeManager.object_type) { + if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) { // Optimized version, also avoids referencing literal internal type Arguments args = new Arguments (1); args.Add (new Argument (this)); @@ -2048,34 +2045,36 @@ namespace Mono.CSharp { return base.CreateExpressionTree (ec); } - protected override Expression DoResolve (ResolveContext ec) - { - return this; - } - public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) { - // Type it as string cast - if (targetType == TypeManager.object_type || targetType == InternalType.Null) - enc.Encode (TypeManager.string_type); - - var ac = targetType as ArrayContainer; - if (ac != null) { - if (ac.Rank != 1 || ac.Element.IsArray) - base.EncodeAttributeValue (rc, enc, targetType); - else - enc.Encode (uint.MaxValue); - } else { + switch (targetType.BuiltinType) { + case BuiltinTypeSpec.Type.Object: + // Type it as string cast + enc.Encode (rc.Module.Compiler.BuiltinTypes.String); + goto case BuiltinTypeSpec.Type.String; + case BuiltinTypeSpec.Type.String: + case BuiltinTypeSpec.Type.Type: enc.Encode (byte.MaxValue); + return; + default: + var ac = targetType as ArrayContainer; + if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) { + enc.Encode (uint.MaxValue); + return; + } + + break; } + + base.EncodeAttributeValue (rc, enc, targetType); } public override void Emit (EmitContext ec) { - ec.Emit (OpCodes.Ldnull); + ec.EmitNull (); // Only to make verifier happy - if (TypeManager.IsGenericParameter (type)) + if (type.IsGenericParameter) ec.Emit (OpCodes.Unbox_Any, type); } @@ -2089,28 +2088,28 @@ namespace Mono.CSharp { { if (targetType.IsPointer) { if (IsLiteral || this is NullPointer) - return new EmptyConstantCast (new NullPointer (loc), targetType); + return new NullPointer (targetType, loc); return null; } // Exlude internal compiler types - if (targetType.Kind == MemberKind.InternalCompilerType && targetType != InternalType.Dynamic && targetType != InternalType.Null) + if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic) return null; if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType)) return null; - if (TypeManager.IsReferenceType (targetType)) + if (TypeSpec.IsReferenceType (targetType)) return new NullConstant (targetType, loc); - if (TypeManager.IsNullableType (targetType)) + if (targetType.IsNullableType) return Nullable.LiftedNull.Create (targetType, loc); return null; } - public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec targetType) + public override Constant ConvertImplicitly (TypeSpec targetType) { return ConvertExplicitly (false, targetType); } @@ -2152,30 +2151,59 @@ namespace Mono.CSharp { } } + + // + // A null constant in a pointer context + // + class NullPointer : NullConstant + { + public NullPointer (TypeSpec type, Location loc) + : base (type, loc) + { + } + + public override Expression CreateExpressionTree (ResolveContext ec) + { + Error_PointerInsideExpressionTree (ec); + return base.CreateExpressionTree (ec); + } + + public override void Emit (EmitContext ec) + { + // + // Emits null pointer + // + ec.EmitInt (0); + ec.Emit (OpCodes.Conv_U); + } + } + /// /// The value is constant, but when emitted has a side effect. This is /// used by BitwiseAnd to ensure that the second expression is invoked /// regardless of the value of the left side. /// - public class SideEffectConstant : Constant { - public Constant value; + public class SideEffectConstant : Constant + { + public readonly Constant value; Expression side_effect; - public SideEffectConstant (Constant value, Expression side_effect, Location loc) : base (loc) + public SideEffectConstant (Constant value, Expression side_effect, Location loc) + : base (loc) { this.value = value; + type = value.Type; + eclass = ExprClass.Value; + while (side_effect is SideEffectConstant) side_effect = ((SideEffectConstant) side_effect).side_effect; this.side_effect = side_effect; } - protected override Expression DoResolve (ResolveContext rc) - { - value = value.Resolve (rc); - - type = value.Type; - eclass = ExprClass.Value; - return this; + public override bool IsSideEffectFree { + get { + return false; + } } public override object GetValue ()