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 {
1649 public readonly float Value;
1651 public FloatConstant (BuiltinTypes types, float v, Location loc)
1652 : this (types.Float, v, loc)
1656 public FloatConstant (TypeSpec type, float v, Location loc)
1660 eclass = ExprClass.Value;
1665 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1670 public override void Emit (EmitContext ec)
1672 ec.Emit (OpCodes.Ldc_R4, Value);
1675 public override object GetValue ()
1680 public override string GetValueAsLiteral ()
1682 return Value.ToString ();
1685 public override long GetValueAsLong ()
1687 throw new NotSupportedException ();
1690 public override bool IsDefaultValue {
1696 public override bool IsNegative {
1702 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1704 switch (target_type.BuiltinType) {
1705 case BuiltinTypeSpec.Type.Byte:
1706 if (in_checked_context) {
1707 if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1708 throw new OverflowException ();
1710 return new ByteConstant (target_type, (byte) Value, Location);
1711 case BuiltinTypeSpec.Type.SByte:
1712 if (in_checked_context) {
1713 if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1714 throw new OverflowException ();
1716 return new SByteConstant (target_type, (sbyte) Value, Location);
1717 case BuiltinTypeSpec.Type.Short:
1718 if (in_checked_context) {
1719 if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1720 throw new OverflowException ();
1722 return new ShortConstant (target_type, (short) Value, Location);
1723 case BuiltinTypeSpec.Type.UShort:
1724 if (in_checked_context) {
1725 if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1726 throw new OverflowException ();
1728 return new UShortConstant (target_type, (ushort) Value, Location);
1729 case BuiltinTypeSpec.Type.Int:
1730 if (in_checked_context) {
1731 if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1732 throw new OverflowException ();
1734 return new IntConstant (target_type, (int) Value, Location);
1735 case BuiltinTypeSpec.Type.UInt:
1736 if (in_checked_context) {
1737 if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1738 throw new OverflowException ();
1740 return new UIntConstant (target_type, (uint) Value, Location);
1741 case BuiltinTypeSpec.Type.Long:
1742 if (in_checked_context) {
1743 if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1744 throw new OverflowException ();
1746 return new LongConstant (target_type, (long) Value, Location);
1747 case BuiltinTypeSpec.Type.ULong:
1748 if (in_checked_context) {
1749 if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1750 throw new OverflowException ();
1752 return new ULongConstant (target_type, (ulong) Value, Location);
1753 case BuiltinTypeSpec.Type.Double:
1754 return new DoubleConstant (target_type, (double) Value, Location);
1755 case BuiltinTypeSpec.Type.Char:
1756 if (in_checked_context) {
1757 if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1758 throw new OverflowException ();
1760 return new CharConstant (target_type, (char) Value, Location);
1761 case BuiltinTypeSpec.Type.Decimal:
1762 return new DecimalConstant (target_type, (decimal) Value, Location);
1770 public class DoubleConstant : Constant
1772 public readonly double Value;
1774 public DoubleConstant (BuiltinTypes types, double v, Location loc)
1775 : this (types.Double, v, loc)
1779 public DoubleConstant (TypeSpec type, double v, Location loc)
1783 eclass = ExprClass.Value;
1788 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1793 public override void Emit (EmitContext ec)
1795 ec.Emit (OpCodes.Ldc_R8, Value);
1798 public override object GetValue ()
1803 public override string GetValueAsLiteral ()
1805 return Value.ToString ();
1808 public override long GetValueAsLong ()
1810 throw new NotSupportedException ();
1813 public override bool IsDefaultValue {
1819 public override bool IsNegative {
1825 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1827 switch (target_type.BuiltinType) {
1828 case BuiltinTypeSpec.Type.Byte:
1829 if (in_checked_context) {
1830 if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1831 throw new OverflowException ();
1833 return new ByteConstant (target_type, (byte) Value, Location);
1834 case BuiltinTypeSpec.Type.SByte:
1835 if (in_checked_context) {
1836 if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1837 throw new OverflowException ();
1839 return new SByteConstant (target_type, (sbyte) Value, Location);
1840 case BuiltinTypeSpec.Type.Short:
1841 if (in_checked_context) {
1842 if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1843 throw new OverflowException ();
1845 return new ShortConstant (target_type, (short) Value, Location);
1846 case BuiltinTypeSpec.Type.UShort:
1847 if (in_checked_context) {
1848 if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1849 throw new OverflowException ();
1851 return new UShortConstant (target_type, (ushort) Value, Location);
1852 case BuiltinTypeSpec.Type.Int:
1853 if (in_checked_context) {
1854 if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1855 throw new OverflowException ();
1857 return new IntConstant (target_type, (int) Value, Location);
1858 case BuiltinTypeSpec.Type.UInt:
1859 if (in_checked_context) {
1860 if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1861 throw new OverflowException ();
1863 return new UIntConstant (target_type, (uint) Value, Location);
1864 case BuiltinTypeSpec.Type.Long:
1865 if (in_checked_context) {
1866 if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1867 throw new OverflowException ();
1869 return new LongConstant (target_type, (long) Value, Location);
1870 case BuiltinTypeSpec.Type.ULong:
1871 if (in_checked_context) {
1872 if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1873 throw new OverflowException ();
1875 return new ULongConstant (target_type, (ulong) Value, Location);
1876 case BuiltinTypeSpec.Type.Float:
1877 return new FloatConstant (target_type, (float) Value, Location);
1878 case BuiltinTypeSpec.Type.Char:
1879 if (in_checked_context) {
1880 if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1881 throw new OverflowException ();
1883 return new CharConstant (target_type, (char) Value, Location);
1884 case BuiltinTypeSpec.Type.Decimal:
1885 return new DecimalConstant (target_type, (decimal) Value, Location);
1893 public class DecimalConstant : Constant {
1894 public readonly decimal Value;
1896 public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1897 : this (types.Decimal, d, loc)
1901 public DecimalConstant (TypeSpec type, decimal d, Location loc)
1905 eclass = ExprClass.Value;
1910 public override void Emit (EmitContext ec)
1914 int [] words = decimal.GetBits (Value);
1915 int power = (words [3] >> 16) & 0xff;
1918 if (Value <= int.MaxValue && Value >= int.MinValue) {
1919 m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1924 ec.EmitInt ((int) Value);
1925 ec.Emit (OpCodes.Newobj, m);
1929 if (Value <= long.MaxValue && Value >= long.MinValue) {
1930 m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1935 ec.EmitLong ((long) Value);
1936 ec.Emit (OpCodes.Newobj, m);
1941 ec.EmitInt (words [0]);
1942 ec.EmitInt (words [1]);
1943 ec.EmitInt (words [2]);
1946 ec.EmitInt (words [3] >> 31);
1951 m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1953 ec.Emit (OpCodes.Newobj, m);
1957 public override bool IsDefaultValue {
1963 public override bool IsNegative {
1969 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1971 switch (target_type.BuiltinType) {
1972 case BuiltinTypeSpec.Type.SByte:
1973 return new SByteConstant (target_type, (sbyte) Value, loc);
1974 case BuiltinTypeSpec.Type.Byte:
1975 return new ByteConstant (target_type, (byte) Value, loc);
1976 case BuiltinTypeSpec.Type.Short:
1977 return new ShortConstant (target_type, (short) Value, loc);
1978 case BuiltinTypeSpec.Type.UShort:
1979 return new UShortConstant (target_type, (ushort) Value, loc);
1980 case BuiltinTypeSpec.Type.Int:
1981 return new IntConstant (target_type, (int) Value, loc);
1982 case BuiltinTypeSpec.Type.UInt:
1983 return new UIntConstant (target_type, (uint) Value, loc);
1984 case BuiltinTypeSpec.Type.Long:
1985 return new LongConstant (target_type, (long) Value, loc);
1986 case BuiltinTypeSpec.Type.ULong:
1987 return new ULongConstant (target_type, (ulong) Value, loc);
1988 case BuiltinTypeSpec.Type.Char:
1989 return new CharConstant (target_type, (char) Value, loc);
1990 case BuiltinTypeSpec.Type.Float:
1991 return new FloatConstant (target_type, (float) Value, loc);
1992 case BuiltinTypeSpec.Type.Double:
1993 return new DoubleConstant (target_type, (double) Value, loc);
1999 public override object GetValue ()
2004 public override string GetValueAsLiteral ()
2006 return Value.ToString () + "M";
2009 public override long GetValueAsLong ()
2011 throw new NotSupportedException ();
2015 public class StringConstant : Constant {
2016 public readonly string Value;
2018 public StringConstant (BuiltinTypes types, string s, Location loc)
2019 : this (types.String, s, loc)
2023 public StringConstant (TypeSpec type, string s, Location loc)
2027 eclass = ExprClass.Value;
2032 public override object GetValue ()
2037 public override string GetValueAsLiteral ()
2039 // FIXME: Escape the string.
2040 return "\"" + Value + "\"";
2043 public override long GetValueAsLong ()
2045 throw new NotSupportedException ();
2048 public override void Emit (EmitContext ec)
2050 if (Value == null) {
2056 // Use string.Empty for both literals and constants even if
2057 // it's not allowed at language level
2059 if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
2060 var string_type = ec.BuiltinTypes.String;
2061 if (ec.CurrentType != string_type) {
2062 var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
2064 ec.Emit (OpCodes.Ldsfld, m);
2070 ec.Emit (OpCodes.Ldstr, Value);
2073 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2076 if (type != targetType)
2082 public override bool IsDefaultValue {
2084 return Value == null;
2088 public override bool IsNegative {
2094 public override bool IsNull {
2096 return IsDefaultValue;
2100 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2105 public override Constant ConvertImplicitly (TypeSpec type)
2107 if (IsDefaultValue && type.BuiltinType == BuiltinTypeSpec.Type.Object)
2108 return new NullConstant (type, loc);
2110 return base.ConvertImplicitly (type);
2115 // Null constant can have its own type, think of `default (Foo)'
2117 public class NullConstant : Constant
2119 public NullConstant (TypeSpec type, Location loc)
2122 eclass = ExprClass.Value;
2126 public override Expression CreateExpressionTree (ResolveContext ec)
2128 if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2129 // Optimized version, also avoids referencing literal internal type
2130 Arguments args = new Arguments (1);
2131 args.Add (new Argument (this));
2132 return CreateExpressionFactoryCall (ec, "Constant", args);
2135 return base.CreateExpressionTree (ec);
2138 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2140 switch (targetType.BuiltinType) {
2141 case BuiltinTypeSpec.Type.Object:
2142 // Type it as string cast
2143 enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2144 goto case BuiltinTypeSpec.Type.String;
2145 case BuiltinTypeSpec.Type.String:
2146 case BuiltinTypeSpec.Type.Type:
2147 enc.Encode (byte.MaxValue);
2150 var ac = targetType as ArrayContainer;
2151 if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
2152 enc.Encode (uint.MaxValue);
2159 base.EncodeAttributeValue (rc, enc, targetType);
2162 public override void Emit (EmitContext ec)
2166 // Only to make verifier happy
2167 if (type.IsGenericParameter)
2168 ec.Emit (OpCodes.Unbox_Any, type);
2171 public override string ExprClassName {
2173 return GetSignatureForError ();
2177 public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2179 if (targetType.IsPointer) {
2180 if (IsLiteral || this is NullPointer)
2181 return new NullPointer (targetType, loc);
2186 // Exlude internal compiler types
2187 if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2190 if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2193 if (TypeSpec.IsReferenceType (targetType))
2194 return new NullConstant (targetType, loc);
2196 if (targetType.IsNullableType)
2197 return Nullable.LiftedNull.Create (targetType, loc);
2202 public override Constant ConvertImplicitly (TypeSpec targetType)
2204 return ConvertExplicitly (false, targetType);
2207 public override string GetSignatureForError ()
2212 public override object GetValue ()
2217 public override string GetValueAsLiteral ()
2219 return GetSignatureForError ();
2222 public override long GetValueAsLong ()
2224 throw new NotSupportedException ();
2227 public override bool IsDefaultValue {
2228 get { return true; }
2231 public override bool IsNegative {
2232 get { return false; }
2235 public override bool IsNull {
2236 get { return true; }
2239 public override bool IsZeroInteger {
2240 get { return true; }
2246 // A null constant in a pointer context
2248 class NullPointer : NullConstant
2250 public NullPointer (TypeSpec type, Location loc)
2255 public override Expression CreateExpressionTree (ResolveContext ec)
2257 Error_PointerInsideExpressionTree (ec);
2258 return base.CreateExpressionTree (ec);
2261 public override void Emit (EmitContext ec)
2264 // Emits null pointer
2267 ec.Emit (OpCodes.Conv_U);
2272 /// The value is constant, but when emitted has a side effect. This is
2273 /// used by BitwiseAnd to ensure that the second expression is invoked
2274 /// regardless of the value of the left side.
2276 public class SideEffectConstant : Constant
2278 public readonly Constant value;
2279 Expression side_effect;
2281 public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2286 eclass = ExprClass.Value;
2288 while (side_effect is SideEffectConstant)
2289 side_effect = ((SideEffectConstant) side_effect).side_effect;
2290 this.side_effect = side_effect;
2293 public override bool IsSideEffectFree {
2299 public override object GetValue ()
2301 return value.GetValue ();
2304 public override string GetValueAsLiteral ()
2306 return value.GetValueAsLiteral ();
2309 public override long GetValueAsLong ()
2311 return value.GetValueAsLong ();
2314 public override void Emit (EmitContext ec)
2316 side_effect.EmitSideEffect (ec);
2320 public override void EmitSideEffect (EmitContext ec)
2322 side_effect.EmitSideEffect (ec);
2323 value.EmitSideEffect (ec);
2326 public override bool IsDefaultValue {
2327 get { return value.IsDefaultValue; }
2330 public override bool IsNegative {
2331 get { return value.IsNegative; }
2334 public override bool IsZeroInteger {
2335 get { return value.IsZeroInteger; }
2338 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2340 Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2341 if (new_value == null)
2344 var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2345 c.type = target_type;