2 // constant.cs: Constants.
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@gmail.com)
8 // Copyright 2001-2003 Ximian, Inc.
9 // Copyright 2003-2008 Novell, Inc.
10 // Copyright 2011-2013 Xamarin Inc
14 using System.Globalization;
17 using IKVM.Reflection.Emit;
19 using System.Reflection.Emit;
22 namespace Mono.CSharp {
25 /// Base class for constants and literals.
27 public abstract class Constant : Expression
29 static readonly NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat;
31 protected Constant (Location loc)
36 override public string ToString ()
38 return this.GetType ().Name + " (" + GetValueAsLiteral () + ")";
42 /// This is used to obtain the actual value of the literal
43 /// cast into an object.
45 public abstract object GetValue ();
47 public abstract long GetValueAsLong ();
49 public abstract string GetValueAsLiteral ();
53 // Returns an object value which is typed to contant type
55 public virtual object GetTypedValue ()
61 public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
63 if (!expl && IsLiteral &&
64 BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
65 BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) {
66 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
67 GetValueAsLiteral (), target.GetSignatureForError ());
69 base.Error_ValueCannotBeConverted (ec, target, expl);
73 public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type)
75 Constant c = ConvertImplicitly (type);
77 Error_ValueCannotBeConverted (ec, type, false);
82 public override bool ContainsEmitWithAwait ()
87 public virtual Constant ConvertImplicitly (TypeSpec type)
89 if (this.type == type)
92 if (!Convert.ImplicitNumericConversionExists (this.type, type))
96 object constant_value = ChangeType (GetValue (), type, out fail);
99 // We should always catch the error before this is ever
100 // reached, by calling Convert.ImplicitStandardConversionExists
102 throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
103 Type.GetSignatureForError (), type.GetSignatureForError ());
106 return CreateConstantFromValue (type, constant_value, loc);
110 // Returns a constant instance based on Type
112 public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
114 switch (t.BuiltinType) {
115 case BuiltinTypeSpec.Type.Int:
116 return new IntConstant (t, (int) v, loc);
117 case BuiltinTypeSpec.Type.String:
118 return new StringConstant (t, (string) v, loc);
119 case BuiltinTypeSpec.Type.UInt:
120 return new UIntConstant (t, (uint) v, loc);
121 case BuiltinTypeSpec.Type.Long:
122 return new LongConstant (t, (long) v, loc);
123 case BuiltinTypeSpec.Type.ULong:
124 return new ULongConstant (t, (ulong) v, loc);
125 case BuiltinTypeSpec.Type.Float:
126 return new FloatConstant (t, (float) v, loc);
127 case BuiltinTypeSpec.Type.Double:
128 return new DoubleConstant (t, (double) v, loc);
129 case BuiltinTypeSpec.Type.Short:
130 return new ShortConstant (t, (short) v, loc);
131 case BuiltinTypeSpec.Type.UShort:
132 return new UShortConstant (t, (ushort) v, loc);
133 case BuiltinTypeSpec.Type.SByte:
134 return new SByteConstant (t, (sbyte) v, loc);
135 case BuiltinTypeSpec.Type.Byte:
136 return new ByteConstant (t, (byte) v, loc);
137 case BuiltinTypeSpec.Type.Char:
138 return new CharConstant (t, (char) v, loc);
139 case BuiltinTypeSpec.Type.Bool:
140 return new BoolConstant (t, (bool) v, loc);
141 case BuiltinTypeSpec.Type.Decimal:
142 return new DecimalConstant (t, (decimal) v, loc);
146 var real_type = EnumSpec.GetUnderlyingType (t);
147 return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
151 if (t.IsNullableType)
152 return Nullable.LiftedNull.Create (t, loc);
154 if (TypeSpec.IsReferenceType (t))
155 return new NullConstant (t, loc);
159 throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ());
166 // Returns a constant instance based on value and type. This is probing version of
167 // CreateConstantFromValue
169 public static Constant ExtractConstantFromValue (TypeSpec t, object v, Location loc)
171 switch (t.BuiltinType) {
172 case BuiltinTypeSpec.Type.Int:
174 return new IntConstant (t, (int) v, loc);
176 case BuiltinTypeSpec.Type.String:
178 return new StringConstant (t, (string) v, loc);
180 case BuiltinTypeSpec.Type.UInt:
182 return new UIntConstant (t, (uint) v, loc);
184 case BuiltinTypeSpec.Type.Long:
186 return new LongConstant (t, (long) v, loc);
188 case BuiltinTypeSpec.Type.ULong:
190 return new ULongConstant (t, (ulong) v, loc);
192 case BuiltinTypeSpec.Type.Float:
194 return new FloatConstant (t, (float) v, loc);
196 case BuiltinTypeSpec.Type.Double:
198 return new DoubleConstant (t, (double) v, loc);
200 case BuiltinTypeSpec.Type.Short:
202 return new ShortConstant (t, (short) v, loc);
204 case BuiltinTypeSpec.Type.UShort:
206 return new UShortConstant (t, (ushort) v, loc);
208 case BuiltinTypeSpec.Type.SByte:
210 return new SByteConstant (t, (sbyte) v, loc);
212 case BuiltinTypeSpec.Type.Byte:
214 return new ByteConstant (t, (byte) v, loc);
216 case BuiltinTypeSpec.Type.Char:
218 return new CharConstant (t, (char) v, loc);
220 case BuiltinTypeSpec.Type.Bool:
222 return new BoolConstant (t, (bool) v, loc);
224 case BuiltinTypeSpec.Type.Decimal:
226 return new DecimalConstant (t, (decimal) v, loc);
231 var real_type = EnumSpec.GetUnderlyingType (t);
232 return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
236 if (t.IsNullableType)
237 return Nullable.LiftedNull.Create (t, loc);
239 if (TypeSpec.IsReferenceType (t))
240 return new NullConstant (t, loc);
247 public override Expression CreateExpressionTree (ResolveContext ec)
249 Arguments args = new Arguments (2);
250 args.Add (new Argument (this));
251 args.Add (new Argument (new TypeOf (type, loc)));
253 return CreateExpressionFactoryCall (ec, "Constant", args);
257 /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
258 /// It throws OverflowException
260 // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
261 public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
263 // This is a custom version of Convert.ChangeType() which works
264 // with the TypeBuilder defined types when compiling corlib.
265 static object ChangeType (object value, TypeSpec targetType, out bool error)
267 IConvertible convert_value = value as IConvertible;
269 if (convert_value == null) {
275 // We cannot rely on build-in type conversions as they are
276 // more limited than what C# supports.
277 // See char -> float/decimal/double conversion
281 switch (targetType.BuiltinType) {
282 case BuiltinTypeSpec.Type.Bool:
283 return convert_value.ToBoolean (nfi);
284 case BuiltinTypeSpec.Type.Byte:
285 return convert_value.ToByte (nfi);
286 case BuiltinTypeSpec.Type.Char:
287 return convert_value.ToChar (nfi);
288 case BuiltinTypeSpec.Type.Short:
289 return convert_value.ToInt16 (nfi);
290 case BuiltinTypeSpec.Type.Int:
291 return convert_value.ToInt32 (nfi);
292 case BuiltinTypeSpec.Type.Long:
293 return convert_value.ToInt64 (nfi);
294 case BuiltinTypeSpec.Type.SByte:
295 return convert_value.ToSByte (nfi);
296 case BuiltinTypeSpec.Type.Decimal:
297 if (convert_value.GetType () == typeof (char))
298 return (decimal) convert_value.ToInt32 (nfi);
299 return convert_value.ToDecimal (nfi);
300 case BuiltinTypeSpec.Type.Double:
301 if (convert_value.GetType () == typeof (char))
302 return (double) convert_value.ToInt32 (nfi);
303 return convert_value.ToDouble (nfi);
304 case BuiltinTypeSpec.Type.Float:
305 if (convert_value.GetType () == typeof (char))
306 return (float) convert_value.ToInt32 (nfi);
307 return convert_value.ToSingle (nfi);
308 case BuiltinTypeSpec.Type.String:
309 return convert_value.ToString (nfi);
310 case BuiltinTypeSpec.Type.UShort:
311 return convert_value.ToUInt16 (nfi);
312 case BuiltinTypeSpec.Type.UInt:
313 return convert_value.ToUInt32 (nfi);
314 case BuiltinTypeSpec.Type.ULong:
315 return convert_value.ToUInt64 (nfi);
316 case BuiltinTypeSpec.Type.Object:
326 protected override Expression DoResolve (ResolveContext rc)
332 // Attempts to do a compile-time folding of a constant cast and handles
333 // error reporting for constant overlows only, on normal conversion
334 // errors returns null
336 public Constant Reduce (ResolveContext ec, TypeSpec target_type)
339 return TryReduceConstant (ec, target_type);
340 } catch (OverflowException) {
341 if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
342 ec.Report.Error (221, loc,
343 "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
344 GetValueAsLiteral (), target_type.GetSignatureForError ());
346 Error_ValueCannotBeConverted (ec, target_type, false);
349 return New.Constantify (target_type, loc);
353 public Constant TryReduce (ResolveContext rc, TypeSpec targetType)
356 return TryReduceConstant (rc, targetType);
357 } catch (OverflowException) {
362 Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
364 if (Type == target_type) {
366 // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10
369 return CreateConstantFromValue (target_type, GetValue (), loc);
375 if (target_type.IsEnum) {
376 c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type));
380 return new EnumConstant (c, target_type);
383 return ConvertExplicitly (ec.ConstantCheckState, target_type);
387 /// Need to pass type as the constant can require a boxing
388 /// and in such case no optimization is possible
390 public bool IsDefaultInitializer (TypeSpec type)
393 return IsDefaultValue;
395 return this is NullLiteral;
398 public abstract bool IsDefaultValue {
402 public abstract bool IsNegative {
407 // When constant is declared as literal
409 public virtual bool IsLiteral {
410 get { return false; }
413 public virtual bool IsOneInteger {
414 get { return false; }
417 public override bool IsSideEffectFree {
424 // Returns true iff 1) the stack type of this is one of Object,
425 // int32, int64 and 2) this == 0 or this == null.
427 public virtual bool IsZeroInteger {
428 get { return false; }
431 public override void EmitSideEffect (EmitContext ec)
436 public sealed override Expression Clone (CloneContext clonectx)
438 // No cloning is not needed for constants
442 protected override void CloneTo (CloneContext clonectx, Expression target)
444 throw new NotSupportedException ("should not be reached");
447 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
450 return base.MakeExpression (ctx);
452 return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
456 public new bool Resolve (ResolveContext rc)
458 // It exists only as hint not to call Resolve on constants
463 public abstract class IntegralConstant : Constant
465 protected IntegralConstant (TypeSpec type, Location loc)
469 eclass = ExprClass.Value;
472 public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
475 ConvertExplicitly (true, target);
476 base.Error_ValueCannotBeConverted (ec, target, expl);
480 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
481 GetValue ().ToString (), target.GetSignatureForError ());
485 public override string GetValueAsLiteral ()
487 return GetValue ().ToString ();
490 public abstract Constant Increment ();
493 public class BoolConstant : Constant {
494 public readonly bool Value;
496 public BoolConstant (BuiltinTypes types, bool val, Location loc)
497 : this (types.Bool, val, loc)
501 public BoolConstant (TypeSpec type, bool val, Location loc)
504 eclass = ExprClass.Value;
510 public override object GetValue ()
512 return (object) Value;
515 public override string GetValueAsLiteral ()
517 return Value ? "true" : "false";
520 public override long GetValueAsLong ()
522 return Value ? 1 : 0;
525 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
530 public override void Emit (EmitContext ec)
538 public override bool IsDefaultValue {
544 public override bool IsNegative {
550 public override bool IsZeroInteger {
551 get { return Value == false; }
554 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
561 public class ByteConstant : IntegralConstant
563 public readonly byte Value;
565 public ByteConstant (BuiltinTypes types, byte v, Location loc)
566 : this (types.Byte, v, loc)
570 public ByteConstant (TypeSpec type, byte v, Location loc)
576 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
581 public override void Emit (EmitContext ec)
586 public override object GetValue ()
591 public override long GetValueAsLong ()
596 public override Constant Increment ()
598 return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
601 public override bool IsDefaultValue {
607 public override bool IsOneInteger {
613 public override bool IsNegative {
619 public override bool IsZeroInteger {
620 get { return Value == 0; }
623 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
625 switch (target_type.BuiltinType) {
626 case BuiltinTypeSpec.Type.SByte:
627 if (in_checked_context){
628 if (Value > SByte.MaxValue)
629 throw new OverflowException ();
631 return new SByteConstant (target_type, (sbyte) Value, Location);
632 case BuiltinTypeSpec.Type.Short:
633 return new ShortConstant (target_type, (short) Value, Location);
634 case BuiltinTypeSpec.Type.UShort:
635 return new UShortConstant (target_type, (ushort) Value, Location);
636 case BuiltinTypeSpec.Type.Int:
637 return new IntConstant (target_type, (int) Value, Location);
638 case BuiltinTypeSpec.Type.UInt:
639 return new UIntConstant (target_type, (uint) Value, Location);
640 case BuiltinTypeSpec.Type.Long:
641 return new LongConstant (target_type, (long) Value, Location);
642 case BuiltinTypeSpec.Type.ULong:
643 return new ULongConstant (target_type, (ulong) Value, Location);
644 case BuiltinTypeSpec.Type.Float:
645 return new FloatConstant (target_type, (float) Value, Location);
646 case BuiltinTypeSpec.Type.Double:
647 return new DoubleConstant (target_type, (double) Value, Location);
648 case BuiltinTypeSpec.Type.Char:
649 return new CharConstant (target_type, (char) Value, Location);
650 case BuiltinTypeSpec.Type.Decimal:
651 return new DecimalConstant (target_type, (decimal) Value, Location);
659 public class CharConstant : Constant {
660 public readonly char Value;
662 public CharConstant (BuiltinTypes types, char v, Location loc)
663 : this (types.Char, v, loc)
667 public CharConstant (TypeSpec type, char v, Location loc)
671 eclass = ExprClass.Value;
676 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
678 enc.Encode ((ushort) Value);
681 public override void Emit (EmitContext ec)
686 static string descape (char c)
712 return c.ToString ();
715 public override object GetValue ()
720 public override long GetValueAsLong ()
725 public override string GetValueAsLiteral ()
727 return "\"" + descape (Value) + "\"";
730 public override bool IsDefaultValue {
736 public override bool IsNegative {
742 public override bool IsZeroInteger {
743 get { return Value == '\0'; }
746 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
748 switch (target_type.BuiltinType) {
749 case BuiltinTypeSpec.Type.Byte:
750 if (in_checked_context) {
751 if (Value < Byte.MinValue || Value > Byte.MaxValue)
752 throw new OverflowException ();
754 return new ByteConstant (target_type, (byte) Value, Location);
755 case BuiltinTypeSpec.Type.SByte:
756 if (in_checked_context) {
757 if (Value > SByte.MaxValue)
758 throw new OverflowException ();
760 return new SByteConstant (target_type, (sbyte) Value, Location);
762 case BuiltinTypeSpec.Type.Short:
763 if (in_checked_context) {
764 if (Value > Int16.MaxValue)
765 throw new OverflowException ();
767 return new ShortConstant (target_type, (short) Value, Location);
768 case BuiltinTypeSpec.Type.Int:
769 return new IntConstant (target_type, (int) Value, Location);
770 case BuiltinTypeSpec.Type.UInt:
771 return new UIntConstant (target_type, (uint) Value, Location);
772 case BuiltinTypeSpec.Type.Long:
773 return new LongConstant (target_type, (long) Value, Location);
774 case BuiltinTypeSpec.Type.ULong:
775 return new ULongConstant (target_type, (ulong) Value, Location);
776 case BuiltinTypeSpec.Type.Float:
777 return new FloatConstant (target_type, (float) Value, Location);
778 case BuiltinTypeSpec.Type.Double:
779 return new DoubleConstant (target_type, (double) Value, Location);
780 case BuiltinTypeSpec.Type.Decimal:
781 return new DecimalConstant (target_type, (decimal) Value, Location);
789 public class SByteConstant : IntegralConstant
791 public readonly sbyte Value;
793 public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
794 : this (types.SByte, v, loc)
798 public SByteConstant (TypeSpec type, sbyte v, Location loc)
804 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
809 public override void Emit (EmitContext ec)
814 public override object GetValue ()
819 public override long GetValueAsLong ()
824 public override Constant Increment ()
826 return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
829 public override bool IsDefaultValue {
835 public override bool IsNegative {
841 public override bool IsOneInteger {
847 public override bool IsZeroInteger {
848 get { return Value == 0; }
851 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
853 switch (target_type.BuiltinType) {
854 case BuiltinTypeSpec.Type.Byte:
855 if (in_checked_context && Value < 0)
856 throw new OverflowException ();
857 return new ByteConstant (target_type, (byte) Value, Location);
858 case BuiltinTypeSpec.Type.Short:
859 return new ShortConstant (target_type, (short) Value, Location);
860 case BuiltinTypeSpec.Type.UShort:
861 if (in_checked_context && Value < 0)
862 throw new OverflowException ();
863 return new UShortConstant (target_type, (ushort) Value, Location);
864 case BuiltinTypeSpec.Type.Int:
865 return new IntConstant (target_type, (int) Value, Location);
866 case BuiltinTypeSpec.Type.UInt:
867 if (in_checked_context && Value < 0)
868 throw new OverflowException ();
869 return new UIntConstant (target_type, (uint) Value, Location);
870 case BuiltinTypeSpec.Type.Long:
871 return new LongConstant (target_type, (long) Value, Location);
872 case BuiltinTypeSpec.Type.ULong:
873 if (in_checked_context && Value < 0)
874 throw new OverflowException ();
875 return new ULongConstant (target_type, (ulong) Value, Location);
876 case BuiltinTypeSpec.Type.Float:
877 return new FloatConstant (target_type, (float) Value, Location);
878 case BuiltinTypeSpec.Type.Double:
879 return new DoubleConstant (target_type, (double) Value, Location);
880 case BuiltinTypeSpec.Type.Char:
881 if (in_checked_context && Value < 0)
882 throw new OverflowException ();
883 return new CharConstant (target_type, (char) Value, Location);
884 case BuiltinTypeSpec.Type.Decimal:
885 return new DecimalConstant (target_type, (decimal) Value, Location);
893 public class ShortConstant : IntegralConstant {
894 public readonly short Value;
896 public ShortConstant (BuiltinTypes types, short v, Location loc)
897 : this (types.Short, v, loc)
901 public ShortConstant (TypeSpec type, short v, Location loc)
907 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
912 public override void Emit (EmitContext ec)
917 public override object GetValue ()
922 public override long GetValueAsLong ()
927 public override Constant Increment ()
929 return new ShortConstant (type, checked((short)(Value + 1)), loc);
932 public override bool IsDefaultValue {
938 public override bool IsZeroInteger {
939 get { return Value == 0; }
942 public override bool IsNegative {
948 public override bool IsOneInteger {
954 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
956 switch (target_type.BuiltinType) {
957 case BuiltinTypeSpec.Type.Byte:
958 if (in_checked_context) {
959 if (Value < Byte.MinValue || Value > Byte.MaxValue)
960 throw new OverflowException ();
962 return new ByteConstant (target_type, (byte) Value, Location);
963 case BuiltinTypeSpec.Type.SByte:
964 if (in_checked_context) {
965 if (Value < SByte.MinValue || Value > SByte.MaxValue)
966 throw new OverflowException ();
968 return new SByteConstant (target_type, (sbyte) Value, Location);
969 case BuiltinTypeSpec.Type.UShort:
970 if (in_checked_context && Value < 0)
971 throw new OverflowException ();
973 return new UShortConstant (target_type, (ushort) Value, Location);
974 case BuiltinTypeSpec.Type.Int:
975 return new IntConstant (target_type, (int) Value, Location);
976 case BuiltinTypeSpec.Type.UInt:
977 if (in_checked_context && Value < 0)
978 throw new OverflowException ();
979 return new UIntConstant (target_type, (uint) Value, Location);
980 case BuiltinTypeSpec.Type.Long:
981 return new LongConstant (target_type, (long) Value, Location);
982 case BuiltinTypeSpec.Type.ULong:
983 if (in_checked_context && Value < 0)
984 throw new OverflowException ();
985 return new ULongConstant (target_type, (ulong) Value, Location);
986 case BuiltinTypeSpec.Type.Float:
987 return new FloatConstant (target_type, (float) Value, Location);
988 case BuiltinTypeSpec.Type.Double:
989 return new DoubleConstant (target_type, (double) Value, Location);
990 case BuiltinTypeSpec.Type.Char:
991 if (in_checked_context) {
992 if (Value < Char.MinValue)
993 throw new OverflowException ();
995 return new CharConstant (target_type, (char) Value, Location);
996 case BuiltinTypeSpec.Type.Decimal:
997 return new DecimalConstant (target_type, (decimal) Value, Location);
1005 public class UShortConstant : IntegralConstant
1007 public readonly ushort Value;
1009 public UShortConstant (BuiltinTypes types, ushort v, Location loc)
1010 : this (types.UShort, v, loc)
1014 public UShortConstant (TypeSpec type, ushort v, Location loc)
1020 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1025 public override void Emit (EmitContext ec)
1030 public override object GetValue ()
1035 public override long GetValueAsLong ()
1040 public override Constant Increment ()
1042 return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
1045 public override bool IsDefaultValue {
1051 public override bool IsNegative {
1057 public override bool IsOneInteger {
1063 public override bool IsZeroInteger {
1064 get { return Value == 0; }
1067 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1069 switch (target_type.BuiltinType) {
1070 case BuiltinTypeSpec.Type.Byte:
1071 if (in_checked_context) {
1072 if (Value > Byte.MaxValue)
1073 throw new OverflowException ();
1075 return new ByteConstant (target_type, (byte) Value, Location);
1076 case BuiltinTypeSpec.Type.SByte:
1077 if (in_checked_context) {
1078 if (Value > SByte.MaxValue)
1079 throw new OverflowException ();
1081 return new SByteConstant (target_type, (sbyte) Value, Location);
1082 case BuiltinTypeSpec.Type.Short:
1083 if (in_checked_context) {
1084 if (Value > Int16.MaxValue)
1085 throw new OverflowException ();
1087 return new ShortConstant (target_type, (short) Value, Location);
1088 case BuiltinTypeSpec.Type.Int:
1089 return new IntConstant (target_type, (int) Value, Location);
1090 case BuiltinTypeSpec.Type.UInt:
1091 return new UIntConstant (target_type, (uint) Value, Location);
1092 case BuiltinTypeSpec.Type.Long:
1093 return new LongConstant (target_type, (long) Value, Location);
1094 case BuiltinTypeSpec.Type.ULong:
1095 return new ULongConstant (target_type, (ulong) Value, Location);
1096 case BuiltinTypeSpec.Type.Float:
1097 return new FloatConstant (target_type, (float) Value, Location);
1098 case BuiltinTypeSpec.Type.Double:
1099 return new DoubleConstant (target_type, (double) Value, Location);
1100 case BuiltinTypeSpec.Type.Char:
1101 if (in_checked_context) {
1102 if (Value > Char.MaxValue)
1103 throw new OverflowException ();
1105 return new CharConstant (target_type, (char) Value, Location);
1106 case BuiltinTypeSpec.Type.Decimal:
1107 return new DecimalConstant (target_type, (decimal) Value, Location);
1114 public class IntConstant : IntegralConstant
1116 public readonly int Value;
1118 public IntConstant (BuiltinTypes types, int v, Location loc)
1119 : this (types.Int, v, loc)
1123 public IntConstant (TypeSpec type, int v, Location loc)
1129 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1134 public override void Emit (EmitContext ec)
1139 public override object GetValue ()
1144 public override long GetValueAsLong ()
1149 public override Constant Increment ()
1151 return new IntConstant (type, checked(Value + 1), loc);
1154 public override bool IsDefaultValue {
1160 public override bool IsNegative {
1166 public override bool IsOneInteger {
1172 public override bool IsZeroInteger {
1173 get { return Value == 0; }
1176 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1178 switch (target_type.BuiltinType) {
1179 case BuiltinTypeSpec.Type.Byte:
1180 if (in_checked_context) {
1181 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1182 throw new OverflowException ();
1184 return new ByteConstant (target_type, (byte) Value, Location);
1185 case BuiltinTypeSpec.Type.SByte:
1186 if (in_checked_context) {
1187 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1188 throw new OverflowException ();
1190 return new SByteConstant (target_type, (sbyte) Value, Location);
1191 case BuiltinTypeSpec.Type.Short:
1192 if (in_checked_context) {
1193 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1194 throw new OverflowException ();
1196 return new ShortConstant (target_type, (short) Value, Location);
1197 case BuiltinTypeSpec.Type.UShort:
1198 if (in_checked_context) {
1199 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1200 throw new OverflowException ();
1202 return new UShortConstant (target_type, (ushort) Value, Location);
1203 case BuiltinTypeSpec.Type.UInt:
1204 if (in_checked_context) {
1205 if (Value < UInt32.MinValue)
1206 throw new OverflowException ();
1208 return new UIntConstant (target_type, (uint) Value, Location);
1209 case BuiltinTypeSpec.Type.Long:
1210 return new LongConstant (target_type, (long) Value, Location);
1211 case BuiltinTypeSpec.Type.ULong:
1212 if (in_checked_context && Value < 0)
1213 throw new OverflowException ();
1214 return new ULongConstant (target_type, (ulong) Value, Location);
1215 case BuiltinTypeSpec.Type.Float:
1216 return new FloatConstant (target_type, (float) Value, Location);
1217 case BuiltinTypeSpec.Type.Double:
1218 return new DoubleConstant (target_type, (double) Value, Location);
1219 case BuiltinTypeSpec.Type.Char:
1220 if (in_checked_context) {
1221 if (Value < Char.MinValue || Value > Char.MaxValue)
1222 throw new OverflowException ();
1224 return new CharConstant (target_type, (char) Value, Location);
1225 case BuiltinTypeSpec.Type.Decimal:
1226 return new DecimalConstant (target_type, (decimal) Value, Location);
1232 public override Constant ConvertImplicitly (TypeSpec type)
1234 if (this.type == type)
1237 Constant c = TryImplicitIntConversion (type);
1239 return c; //.Resolve (rc);
1241 return base.ConvertImplicitly (type);
1245 /// Attempts to perform an implicit constant conversion of the IntConstant
1246 /// into a different data type using casts (See Implicit Constant
1247 /// Expression Conversions)
1249 Constant TryImplicitIntConversion (TypeSpec target_type)
1251 switch (target_type.BuiltinType) {
1252 case BuiltinTypeSpec.Type.SByte:
1253 if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1254 return new SByteConstant (target_type, (sbyte) Value, loc);
1256 case BuiltinTypeSpec.Type.Byte:
1257 if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1258 return new ByteConstant (target_type, (byte) Value, loc);
1260 case BuiltinTypeSpec.Type.Short:
1261 if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1262 return new ShortConstant (target_type, (short) Value, loc);
1264 case BuiltinTypeSpec.Type.UShort:
1265 if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1266 return new UShortConstant (target_type, (ushort) Value, loc);
1268 case BuiltinTypeSpec.Type.UInt:
1270 return new UIntConstant (target_type, (uint) Value, loc);
1272 case BuiltinTypeSpec.Type.ULong:
1274 // we can optimize this case: a positive int32
1275 // always fits on a uint64. But we need an opcode
1279 return new ULongConstant (target_type, (ulong) Value, loc);
1281 case BuiltinTypeSpec.Type.Double:
1282 return new DoubleConstant (target_type, (double) Value, loc);
1283 case BuiltinTypeSpec.Type.Float:
1284 return new FloatConstant (target_type, (float) Value, loc);
1291 public class UIntConstant : IntegralConstant {
1292 public readonly uint Value;
1294 public UIntConstant (BuiltinTypes types, uint v, Location loc)
1295 : this (types.UInt, v, loc)
1299 public UIntConstant (TypeSpec type, uint v, Location loc)
1305 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1310 public override void Emit (EmitContext ec)
1312 ec.EmitInt (unchecked ((int) Value));
1315 public override object GetValue ()
1320 public override long GetValueAsLong ()
1325 public override Constant Increment ()
1327 return new UIntConstant (type, checked(Value + 1), loc);
1330 public override bool IsDefaultValue {
1336 public override bool IsNegative {
1342 public override bool IsOneInteger {
1348 public override bool IsZeroInteger {
1349 get { return Value == 0; }
1352 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1354 switch (target_type.BuiltinType) {
1355 case BuiltinTypeSpec.Type.Byte:
1356 if (in_checked_context) {
1357 if (Value < 0 || Value > byte.MaxValue)
1358 throw new OverflowException ();
1360 return new ByteConstant (target_type, (byte) Value, Location);
1361 case BuiltinTypeSpec.Type.SByte:
1362 if (in_checked_context) {
1363 if (Value > SByte.MaxValue)
1364 throw new OverflowException ();
1366 return new SByteConstant (target_type, (sbyte) Value, Location);
1367 case BuiltinTypeSpec.Type.Short:
1368 if (in_checked_context) {
1369 if (Value > Int16.MaxValue)
1370 throw new OverflowException ();
1372 return new ShortConstant (target_type, (short) Value, Location);
1373 case BuiltinTypeSpec.Type.UShort:
1374 if (in_checked_context) {
1375 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1376 throw new OverflowException ();
1378 return new UShortConstant (target_type, (ushort) Value, Location);
1379 case BuiltinTypeSpec.Type.Int:
1380 if (in_checked_context) {
1381 if (Value > Int32.MaxValue)
1382 throw new OverflowException ();
1384 return new IntConstant (target_type, (int) Value, Location);
1385 case BuiltinTypeSpec.Type.Long:
1386 return new LongConstant (target_type, (long) Value, Location);
1387 case BuiltinTypeSpec.Type.ULong:
1388 return new ULongConstant (target_type, (ulong) Value, Location);
1389 case BuiltinTypeSpec.Type.Float:
1390 return new FloatConstant (target_type, (float) Value, Location);
1391 case BuiltinTypeSpec.Type.Double:
1392 return new DoubleConstant (target_type, (double) Value, Location);
1393 case BuiltinTypeSpec.Type.Char:
1394 if (in_checked_context) {
1395 if (Value < Char.MinValue || Value > Char.MaxValue)
1396 throw new OverflowException ();
1398 return new CharConstant (target_type, (char) Value, Location);
1399 case BuiltinTypeSpec.Type.Decimal:
1400 return new DecimalConstant (target_type, (decimal) Value, Location);
1408 public class LongConstant : IntegralConstant {
1409 public readonly long Value;
1411 public LongConstant (BuiltinTypes types, long v, Location loc)
1412 : this (types.Long, v, loc)
1416 public LongConstant (TypeSpec type, long v, Location loc)
1422 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1427 public override void Emit (EmitContext ec)
1429 ec.EmitLong (Value);
1432 public override object GetValue ()
1437 public override long GetValueAsLong ()
1442 public override Constant Increment ()
1444 return new LongConstant (type, checked(Value + 1), loc);
1447 public override bool IsDefaultValue {
1453 public override bool IsNegative {
1459 public override bool IsOneInteger {
1465 public override bool IsZeroInteger {
1466 get { return Value == 0; }
1469 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1471 switch (target_type.BuiltinType) {
1472 case BuiltinTypeSpec.Type.Byte:
1473 if (in_checked_context) {
1474 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1475 throw new OverflowException ();
1477 return new ByteConstant (target_type, (byte) Value, Location);
1478 case BuiltinTypeSpec.Type.SByte:
1479 if (in_checked_context) {
1480 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1481 throw new OverflowException ();
1483 return new SByteConstant (target_type, (sbyte) Value, Location);
1484 case BuiltinTypeSpec.Type.Short:
1485 if (in_checked_context) {
1486 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1487 throw new OverflowException ();
1489 return new ShortConstant (target_type, (short) Value, Location);
1490 case BuiltinTypeSpec.Type.UShort:
1491 if (in_checked_context) {
1492 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1493 throw new OverflowException ();
1495 return new UShortConstant (target_type, (ushort) Value, Location);
1496 case BuiltinTypeSpec.Type.Int:
1497 if (in_checked_context) {
1498 if (Value < Int32.MinValue || Value > Int32.MaxValue)
1499 throw new OverflowException ();
1501 return new IntConstant (target_type, (int) Value, Location);
1502 case BuiltinTypeSpec.Type.UInt:
1503 if (in_checked_context) {
1504 if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1505 throw new OverflowException ();
1507 return new UIntConstant (target_type, (uint) Value, Location);
1508 case BuiltinTypeSpec.Type.ULong:
1509 if (in_checked_context && Value < 0)
1510 throw new OverflowException ();
1511 return new ULongConstant (target_type, (ulong) Value, Location);
1512 case BuiltinTypeSpec.Type.Float:
1513 return new FloatConstant (target_type, (float) Value, Location);
1514 case BuiltinTypeSpec.Type.Double:
1515 return new DoubleConstant (target_type, (double) Value, Location);
1516 case BuiltinTypeSpec.Type.Char:
1517 if (in_checked_context) {
1518 if (Value < Char.MinValue || Value > Char.MaxValue)
1519 throw new OverflowException ();
1521 return new CharConstant (target_type, (char) Value, Location);
1522 case BuiltinTypeSpec.Type.Decimal:
1523 return new DecimalConstant (target_type, (decimal) Value, Location);
1529 public override Constant ConvertImplicitly (TypeSpec type)
1531 if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
1532 return new ULongConstant (type, (ulong) Value, loc);
1535 return base.ConvertImplicitly (type);
1539 public class ULongConstant : IntegralConstant {
1540 public readonly ulong Value;
1542 public ULongConstant (BuiltinTypes types, ulong v, Location loc)
1543 : this (types.ULong, v, loc)
1547 public ULongConstant (TypeSpec type, ulong v, Location loc)
1553 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1558 public override void Emit (EmitContext ec)
1560 ec.EmitLong (unchecked ((long) Value));
1563 public override object GetValue ()
1568 public override long GetValueAsLong ()
1570 return (long) Value;
1573 public override Constant Increment ()
1575 return new ULongConstant (type, checked(Value + 1), loc);
1578 public override bool IsDefaultValue {
1584 public override bool IsNegative {
1590 public override bool IsOneInteger {
1596 public override bool IsZeroInteger {
1597 get { return Value == 0; }
1600 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1602 switch (target_type.BuiltinType) {
1603 case BuiltinTypeSpec.Type.Byte:
1604 if (in_checked_context && Value > Byte.MaxValue)
1605 throw new OverflowException ();
1606 return new ByteConstant (target_type, (byte) Value, Location);
1607 case BuiltinTypeSpec.Type.SByte:
1608 if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1609 throw new OverflowException ();
1610 return new SByteConstant (target_type, (sbyte) Value, Location);
1611 case BuiltinTypeSpec.Type.Short:
1612 if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1613 throw new OverflowException ();
1614 return new ShortConstant (target_type, (short) Value, Location);
1615 case BuiltinTypeSpec.Type.UShort:
1616 if (in_checked_context && Value > UInt16.MaxValue)
1617 throw new OverflowException ();
1618 return new UShortConstant (target_type, (ushort) Value, Location);
1619 case BuiltinTypeSpec.Type.Int:
1620 if (in_checked_context && Value > UInt32.MaxValue)
1621 throw new OverflowException ();
1622 return new IntConstant (target_type, (int) Value, Location);
1623 case BuiltinTypeSpec.Type.UInt:
1624 if (in_checked_context && Value > UInt32.MaxValue)
1625 throw new OverflowException ();
1626 return new UIntConstant (target_type, (uint) Value, Location);
1627 case BuiltinTypeSpec.Type.Long:
1628 if (in_checked_context && Value > Int64.MaxValue)
1629 throw new OverflowException ();
1630 return new LongConstant (target_type, (long) Value, Location);
1631 case BuiltinTypeSpec.Type.Float:
1632 return new FloatConstant (target_type, (float) Value, Location);
1633 case BuiltinTypeSpec.Type.Double:
1634 return new DoubleConstant (target_type, (double) Value, Location);
1635 case BuiltinTypeSpec.Type.Char:
1636 if (in_checked_context && Value > Char.MaxValue)
1637 throw new OverflowException ();
1638 return new CharConstant (target_type, (char) Value, Location);
1639 case BuiltinTypeSpec.Type.Decimal:
1640 return new DecimalConstant (target_type, (decimal) Value, Location);
1648 public class FloatConstant : Constant {
1650 // Store constant value as double because float constant operations
1651 // need to work on double value to match JIT
1653 public readonly double DoubleValue;
1655 public FloatConstant (BuiltinTypes types, double v, Location loc)
1656 : this (types.Float, v, loc)
1660 public FloatConstant (TypeSpec type, double v, Location loc)
1664 eclass = ExprClass.Value;
1669 public override Constant ConvertImplicitly (TypeSpec type)
1671 if (type.BuiltinType == BuiltinTypeSpec.Type.Double)
1672 return new DoubleConstant (type, DoubleValue, loc);
1674 return base.ConvertImplicitly (type);
1677 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1682 public override void Emit (EmitContext ec)
1684 ec.Emit (OpCodes.Ldc_R4, Value);
1687 public float Value {
1689 return (float) DoubleValue;
1693 public override object GetValue ()
1698 public override string GetValueAsLiteral ()
1700 return Value.ToString ();
1703 public override long GetValueAsLong ()
1705 throw new NotSupportedException ();
1708 public override bool IsDefaultValue {
1714 public override bool IsNegative {
1720 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1722 switch (target_type.BuiltinType) {
1723 case BuiltinTypeSpec.Type.Byte:
1724 if (in_checked_context) {
1725 if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1726 throw new OverflowException ();
1728 return new ByteConstant (target_type, (byte) DoubleValue, Location);
1729 case BuiltinTypeSpec.Type.SByte:
1730 if (in_checked_context) {
1731 if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1732 throw new OverflowException ();
1734 return new SByteConstant (target_type, (sbyte) DoubleValue, Location);
1735 case BuiltinTypeSpec.Type.Short:
1736 if (in_checked_context) {
1737 if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1738 throw new OverflowException ();
1740 return new ShortConstant (target_type, (short) DoubleValue, Location);
1741 case BuiltinTypeSpec.Type.UShort:
1742 if (in_checked_context) {
1743 if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1744 throw new OverflowException ();
1746 return new UShortConstant (target_type, (ushort) DoubleValue, Location);
1747 case BuiltinTypeSpec.Type.Int:
1748 if (in_checked_context) {
1749 if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1750 throw new OverflowException ();
1752 return new IntConstant (target_type, (int) DoubleValue, Location);
1753 case BuiltinTypeSpec.Type.UInt:
1754 if (in_checked_context) {
1755 if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1756 throw new OverflowException ();
1758 return new UIntConstant (target_type, (uint) DoubleValue, Location);
1759 case BuiltinTypeSpec.Type.Long:
1760 if (in_checked_context) {
1761 if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1762 throw new OverflowException ();
1764 return new LongConstant (target_type, (long) DoubleValue, Location);
1765 case BuiltinTypeSpec.Type.ULong:
1766 if (in_checked_context) {
1767 if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1768 throw new OverflowException ();
1770 return new ULongConstant (target_type, (ulong) DoubleValue, Location);
1771 case BuiltinTypeSpec.Type.Double:
1772 return new DoubleConstant (target_type, DoubleValue, Location);
1773 case BuiltinTypeSpec.Type.Char:
1774 if (in_checked_context) {
1775 if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1776 throw new OverflowException ();
1778 return new CharConstant (target_type, (char) DoubleValue, Location);
1779 case BuiltinTypeSpec.Type.Decimal:
1780 return new DecimalConstant (target_type, (decimal) DoubleValue, Location);
1788 public class DoubleConstant : Constant
1790 public readonly double Value;
1792 public DoubleConstant (BuiltinTypes types, double v, Location loc)
1793 : this (types.Double, v, loc)
1797 public DoubleConstant (TypeSpec type, double v, Location loc)
1801 eclass = ExprClass.Value;
1806 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1811 public override void Emit (EmitContext ec)
1813 ec.Emit (OpCodes.Ldc_R8, Value);
1816 public override object GetValue ()
1821 public override string GetValueAsLiteral ()
1823 return Value.ToString ();
1826 public override long GetValueAsLong ()
1828 throw new NotSupportedException ();
1831 public override bool IsDefaultValue {
1837 public override bool IsNegative {
1843 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1845 switch (target_type.BuiltinType) {
1846 case BuiltinTypeSpec.Type.Byte:
1847 if (in_checked_context) {
1848 if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1849 throw new OverflowException ();
1851 return new ByteConstant (target_type, (byte) Value, Location);
1852 case BuiltinTypeSpec.Type.SByte:
1853 if (in_checked_context) {
1854 if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1855 throw new OverflowException ();
1857 return new SByteConstant (target_type, (sbyte) Value, Location);
1858 case BuiltinTypeSpec.Type.Short:
1859 if (in_checked_context) {
1860 if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1861 throw new OverflowException ();
1863 return new ShortConstant (target_type, (short) Value, Location);
1864 case BuiltinTypeSpec.Type.UShort:
1865 if (in_checked_context) {
1866 if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1867 throw new OverflowException ();
1869 return new UShortConstant (target_type, (ushort) Value, Location);
1870 case BuiltinTypeSpec.Type.Int:
1871 if (in_checked_context) {
1872 if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1873 throw new OverflowException ();
1875 return new IntConstant (target_type, (int) Value, Location);
1876 case BuiltinTypeSpec.Type.UInt:
1877 if (in_checked_context) {
1878 if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1879 throw new OverflowException ();
1881 return new UIntConstant (target_type, (uint) Value, Location);
1882 case BuiltinTypeSpec.Type.Long:
1883 if (in_checked_context) {
1884 if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1885 throw new OverflowException ();
1887 return new LongConstant (target_type, (long) Value, Location);
1888 case BuiltinTypeSpec.Type.ULong:
1889 if (in_checked_context) {
1890 if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1891 throw new OverflowException ();
1893 return new ULongConstant (target_type, (ulong) Value, Location);
1894 case BuiltinTypeSpec.Type.Float:
1895 return new FloatConstant (target_type, (float) Value, Location);
1896 case BuiltinTypeSpec.Type.Char:
1897 if (in_checked_context) {
1898 if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1899 throw new OverflowException ();
1901 return new CharConstant (target_type, (char) Value, Location);
1902 case BuiltinTypeSpec.Type.Decimal:
1903 return new DecimalConstant (target_type, (decimal) Value, Location);
1911 public class DecimalConstant : Constant {
1912 public readonly decimal Value;
1914 public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1915 : this (types.Decimal, d, loc)
1919 public DecimalConstant (TypeSpec type, decimal d, Location loc)
1923 eclass = ExprClass.Value;
1928 public override void Emit (EmitContext ec)
1932 int [] words = decimal.GetBits (Value);
1933 int power = (words [3] >> 16) & 0xff;
1936 if (Value <= int.MaxValue && Value >= int.MinValue) {
1937 m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1942 ec.EmitInt ((int) Value);
1943 ec.Emit (OpCodes.Newobj, m);
1947 if (Value <= long.MaxValue && Value >= long.MinValue) {
1948 m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1953 ec.EmitLong ((long) Value);
1954 ec.Emit (OpCodes.Newobj, m);
1959 ec.EmitInt (words [0]);
1960 ec.EmitInt (words [1]);
1961 ec.EmitInt (words [2]);
1964 ec.EmitInt (words [3] >> 31);
1969 m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1971 ec.Emit (OpCodes.Newobj, m);
1975 public override bool IsDefaultValue {
1981 public override bool IsNegative {
1987 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1989 switch (target_type.BuiltinType) {
1990 case BuiltinTypeSpec.Type.SByte:
1991 return new SByteConstant (target_type, (sbyte) Value, loc);
1992 case BuiltinTypeSpec.Type.Byte:
1993 return new ByteConstant (target_type, (byte) Value, loc);
1994 case BuiltinTypeSpec.Type.Short:
1995 return new ShortConstant (target_type, (short) Value, loc);
1996 case BuiltinTypeSpec.Type.UShort:
1997 return new UShortConstant (target_type, (ushort) Value, loc);
1998 case BuiltinTypeSpec.Type.Int:
1999 return new IntConstant (target_type, (int) Value, loc);
2000 case BuiltinTypeSpec.Type.UInt:
2001 return new UIntConstant (target_type, (uint) Value, loc);
2002 case BuiltinTypeSpec.Type.Long:
2003 return new LongConstant (target_type, (long) Value, loc);
2004 case BuiltinTypeSpec.Type.ULong:
2005 return new ULongConstant (target_type, (ulong) Value, loc);
2006 case BuiltinTypeSpec.Type.Char:
2007 return new CharConstant (target_type, (char) Value, loc);
2008 case BuiltinTypeSpec.Type.Float:
2009 return new FloatConstant (target_type, (float) Value, loc);
2010 case BuiltinTypeSpec.Type.Double:
2011 return new DoubleConstant (target_type, (double) Value, loc);
2017 public override object GetValue ()
2022 public override string GetValueAsLiteral ()
2024 return Value.ToString () + "M";
2027 public override long GetValueAsLong ()
2029 throw new NotSupportedException ();
2033 public class StringConstant : Constant {
2034 public readonly string Value;
2036 public StringConstant (BuiltinTypes types, string s, Location loc)
2037 : this (types.String, s, loc)
2041 public StringConstant (TypeSpec type, string s, Location loc)
2045 eclass = ExprClass.Value;
2050 public override object GetValue ()
2055 public override string GetValueAsLiteral ()
2057 // FIXME: Escape the string.
2058 return "\"" + Value + "\"";
2061 public override long GetValueAsLong ()
2063 throw new NotSupportedException ();
2066 public override void Emit (EmitContext ec)
2068 if (Value == null) {
2074 // Use string.Empty for both literals and constants even if
2075 // it's not allowed at language level
2077 if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
2078 var string_type = ec.BuiltinTypes.String;
2079 if (ec.CurrentType != string_type) {
2080 var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
2082 ec.Emit (OpCodes.Ldsfld, m);
2088 ec.Emit (OpCodes.Ldstr, Value);
2091 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2094 if (type != targetType)
2100 public override bool IsDefaultValue {
2102 return Value == null;
2106 public override bool IsNegative {
2112 public override bool IsNull {
2114 return IsDefaultValue;
2118 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2123 public override Constant ConvertImplicitly (TypeSpec type)
2125 if (IsDefaultValue && type.BuiltinType == BuiltinTypeSpec.Type.Object)
2126 return new NullConstant (type, loc);
2128 return base.ConvertImplicitly (type);
2133 // Null constant can have its own type, think of `default (Foo)'
2135 public class NullConstant : Constant
2137 public NullConstant (TypeSpec type, Location loc)
2140 eclass = ExprClass.Value;
2144 public override Expression CreateExpressionTree (ResolveContext ec)
2146 if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2147 // Optimized version, also avoids referencing literal internal type
2148 Arguments args = new Arguments (1);
2149 args.Add (new Argument (this));
2150 return CreateExpressionFactoryCall (ec, "Constant", args);
2153 return base.CreateExpressionTree (ec);
2156 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2158 switch (targetType.BuiltinType) {
2159 case BuiltinTypeSpec.Type.Object:
2160 // Type it as string cast
2161 enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2162 goto case BuiltinTypeSpec.Type.String;
2163 case BuiltinTypeSpec.Type.String:
2164 case BuiltinTypeSpec.Type.Type:
2165 enc.Encode (byte.MaxValue);
2168 var ac = targetType as ArrayContainer;
2169 if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
2170 enc.Encode (uint.MaxValue);
2177 base.EncodeAttributeValue (rc, enc, targetType);
2180 public override void Emit (EmitContext ec)
2184 // Only to make verifier happy
2185 if (type.IsGenericParameter)
2186 ec.Emit (OpCodes.Unbox_Any, type);
2189 public override string ExprClassName {
2191 return GetSignatureForError ();
2195 public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2197 if (targetType.IsPointer) {
2198 if (IsLiteral || this is NullPointer)
2199 return new NullPointer (targetType, loc);
2204 // Exlude internal compiler types
2205 if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2208 if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2211 if (TypeSpec.IsReferenceType (targetType))
2212 return new NullConstant (targetType, loc);
2214 if (targetType.IsNullableType)
2215 return Nullable.LiftedNull.Create (targetType, loc);
2220 public override Constant ConvertImplicitly (TypeSpec targetType)
2222 return ConvertExplicitly (false, targetType);
2225 public override string GetSignatureForError ()
2230 public override object GetValue ()
2235 public override string GetValueAsLiteral ()
2237 return GetSignatureForError ();
2240 public override long GetValueAsLong ()
2242 throw new NotSupportedException ();
2245 public override bool IsDefaultValue {
2246 get { return true; }
2249 public override bool IsNegative {
2250 get { return false; }
2253 public override bool IsNull {
2254 get { return true; }
2257 public override bool IsZeroInteger {
2258 get { return true; }
2264 // A null constant in a pointer context
2266 class NullPointer : NullConstant
2268 public NullPointer (TypeSpec type, Location loc)
2273 public override Expression CreateExpressionTree (ResolveContext ec)
2275 Error_PointerInsideExpressionTree (ec);
2276 return base.CreateExpressionTree (ec);
2279 public override void Emit (EmitContext ec)
2282 // Emits null pointer
2285 ec.Emit (OpCodes.Conv_U);
2290 /// The value is constant, but when emitted has a side effect. This is
2291 /// used by BitwiseAnd to ensure that the second expression is invoked
2292 /// regardless of the value of the left side.
2294 public class SideEffectConstant : Constant
2296 public readonly Constant value;
2297 Expression side_effect;
2299 public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2304 eclass = ExprClass.Value;
2306 while (side_effect is SideEffectConstant)
2307 side_effect = ((SideEffectConstant) side_effect).side_effect;
2308 this.side_effect = side_effect;
2311 public override bool IsSideEffectFree {
2317 public override object GetValue ()
2319 return value.GetValue ();
2322 public override string GetValueAsLiteral ()
2324 return value.GetValueAsLiteral ();
2327 public override long GetValueAsLong ()
2329 return value.GetValueAsLong ();
2332 public override void Emit (EmitContext ec)
2334 side_effect.EmitSideEffect (ec);
2338 public override void EmitSideEffect (EmitContext ec)
2340 side_effect.EmitSideEffect (ec);
2341 value.EmitSideEffect (ec);
2344 public override bool IsDefaultValue {
2345 get { return value.IsDefaultValue; }
2348 public override bool IsNegative {
2349 get { return value.IsNegative; }
2352 public override bool IsZeroInteger {
2353 get { return value.IsZeroInteger; }
2356 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2358 Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2359 if (new_value == null)
2362 var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2363 c.type = target_type;