2 // constant.cs: Constants.
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Copyright 2001-2003 Ximian, Inc.
9 // Copyright 2003-2008 Novell, Inc.
10 // Copyright 2011 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, Location loc, 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 (), TypeManager.CSharpName (target));
69 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
73 public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc)
75 Constant c = ConvertImplicitly (type);
77 Error_ValueCannotBeConverted (ec, loc, type, false);
82 public override bool ContainsEmitWithAwait ()
87 public virtual Constant ConvertImplicitly (TypeSpec type)
89 if (this.type == type)
92 if (Convert.ImplicitNumericConversion (this, type) == null)
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 TypeManager.CSharpName (Type), TypeManager.CSharpName (type));
106 return CreateConstant (type, constant_value, loc);
110 // Returns a constant instance based on Type
112 public static Constant CreateConstant (TypeSpec t, object v, Location loc)
114 return CreateConstantFromValue (t, v, loc);
117 public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
119 switch (t.BuiltinType) {
120 case BuiltinTypeSpec.Type.Int:
121 return new IntConstant (t, (int) v, loc);
122 case BuiltinTypeSpec.Type.String:
123 return new StringConstant (t, (string) v, loc);
124 case BuiltinTypeSpec.Type.UInt:
125 return new UIntConstant (t, (uint) v, loc);
126 case BuiltinTypeSpec.Type.Long:
127 return new LongConstant (t, (long) v, loc);
128 case BuiltinTypeSpec.Type.ULong:
129 return new ULongConstant (t, (ulong) v, loc);
130 case BuiltinTypeSpec.Type.Float:
131 return new FloatConstant (t, (float) v, loc);
132 case BuiltinTypeSpec.Type.Double:
133 return new DoubleConstant (t, (double) v, loc);
134 case BuiltinTypeSpec.Type.Short:
135 return new ShortConstant (t, (short) v, loc);
136 case BuiltinTypeSpec.Type.UShort:
137 return new UShortConstant (t, (ushort) v, loc);
138 case BuiltinTypeSpec.Type.SByte:
139 return new SByteConstant (t, (sbyte) v, loc);
140 case BuiltinTypeSpec.Type.Byte:
141 return new ByteConstant (t, (byte) v, loc);
142 case BuiltinTypeSpec.Type.Char:
143 return new CharConstant (t, (char) v, loc);
144 case BuiltinTypeSpec.Type.Bool:
145 return new BoolConstant (t, (bool) v, loc);
146 case BuiltinTypeSpec.Type.Decimal:
147 return new DecimalConstant (t, (decimal) v, loc);
151 var real_type = EnumSpec.GetUnderlyingType (t);
152 return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
156 if (t.IsNullableType)
157 return Nullable.LiftedNull.Create (t, loc);
159 if (TypeSpec.IsReferenceType (t))
160 return new NullConstant (t, loc);
164 throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ());
170 public override Expression CreateExpressionTree (ResolveContext ec)
172 Arguments args = new Arguments (2);
173 args.Add (new Argument (this));
174 args.Add (new Argument (new TypeOf (type, loc)));
176 return CreateExpressionFactoryCall (ec, "Constant", args);
180 /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
181 /// It throws OverflowException
183 // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
184 public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
186 // This is a custom version of Convert.ChangeType() which works
187 // with the TypeBuilder defined types when compiling corlib.
188 static object ChangeType (object value, TypeSpec targetType, out bool error)
190 IConvertible convert_value = value as IConvertible;
192 if (convert_value == null) {
198 // We cannot rely on build-in type conversions as they are
199 // more limited than what C# supports.
200 // See char -> float/decimal/double conversion
204 switch (targetType.BuiltinType) {
205 case BuiltinTypeSpec.Type.Bool:
206 return convert_value.ToBoolean (nfi);
207 case BuiltinTypeSpec.Type.Byte:
208 return convert_value.ToByte (nfi);
209 case BuiltinTypeSpec.Type.Char:
210 return convert_value.ToChar (nfi);
211 case BuiltinTypeSpec.Type.Short:
212 return convert_value.ToInt16 (nfi);
213 case BuiltinTypeSpec.Type.Int:
214 return convert_value.ToInt32 (nfi);
215 case BuiltinTypeSpec.Type.Long:
216 return convert_value.ToInt64 (nfi);
217 case BuiltinTypeSpec.Type.SByte:
218 return convert_value.ToSByte (nfi);
219 case BuiltinTypeSpec.Type.Decimal:
220 if (convert_value.GetType () == typeof (char))
221 return (decimal) convert_value.ToInt32 (nfi);
222 return convert_value.ToDecimal (nfi);
223 case BuiltinTypeSpec.Type.Double:
224 if (convert_value.GetType () == typeof (char))
225 return (double) convert_value.ToInt32 (nfi);
226 return convert_value.ToDouble (nfi);
227 case BuiltinTypeSpec.Type.Float:
228 if (convert_value.GetType () == typeof (char))
229 return (float) convert_value.ToInt32 (nfi);
230 return convert_value.ToSingle (nfi);
231 case BuiltinTypeSpec.Type.String:
232 return convert_value.ToString (nfi);
233 case BuiltinTypeSpec.Type.UShort:
234 return convert_value.ToUInt16 (nfi);
235 case BuiltinTypeSpec.Type.UInt:
236 return convert_value.ToUInt32 (nfi);
237 case BuiltinTypeSpec.Type.ULong:
238 return convert_value.ToUInt64 (nfi);
239 case BuiltinTypeSpec.Type.Object:
249 protected override Expression DoResolve (ResolveContext rc)
255 /// Attempts to do a compile-time folding of a constant cast.
257 public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
260 return TryReduce (ec, target_type);
262 catch (OverflowException) {
263 if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
264 ec.Report.Error (221, loc,
265 "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
266 GetValueAsLiteral (), target_type.GetSignatureForError ());
268 Error_ValueCannotBeConverted (ec, loc, target_type, false);
271 return New.Constantify (target_type, loc);
275 Constant TryReduce (ResolveContext ec, TypeSpec target_type)
277 if (Type == target_type)
281 if (target_type.IsEnum) {
282 c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
286 return new EnumConstant (c, target_type);
289 return ConvertExplicitly (ec.ConstantCheckState, target_type);
293 /// Need to pass type as the constant can require a boxing
294 /// and in such case no optimization is possible
296 public bool IsDefaultInitializer (TypeSpec type)
299 return IsDefaultValue;
301 return this is NullLiteral;
304 public abstract bool IsDefaultValue {
308 public abstract bool IsNegative {
313 // When constant is declared as literal
315 public virtual bool IsLiteral {
316 get { return false; }
319 public virtual bool IsOneInteger {
320 get { return false; }
323 public override bool IsSideEffectFree {
330 // Returns true iff 1) the stack type of this is one of Object,
331 // int32, int64 and 2) this == 0 or this == null.
333 public virtual bool IsZeroInteger {
334 get { return false; }
337 public override void EmitSideEffect (EmitContext ec)
342 public sealed override Expression Clone (CloneContext clonectx)
344 // No cloning is not needed for constants
348 protected override void CloneTo (CloneContext clonectx, Expression target)
350 throw new NotSupportedException ("should not be reached");
353 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
356 return base.MakeExpression (ctx);
358 return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
362 public new bool Resolve (ResolveContext rc)
364 // It exists only as hint not to call Resolve on constants
369 public abstract class IntegralConstant : Constant
371 protected IntegralConstant (TypeSpec type, Location loc)
375 eclass = ExprClass.Value;
378 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
381 ConvertExplicitly (true, target);
382 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
386 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
387 GetValue ().ToString (), TypeManager.CSharpName (target));
391 public override string GetValueAsLiteral ()
393 return GetValue ().ToString ();
396 public abstract Constant Increment ();
399 public class BoolConstant : Constant {
400 public readonly bool Value;
402 public BoolConstant (BuiltinTypes types, bool val, Location loc)
403 : this (types.Bool, val, loc)
407 public BoolConstant (TypeSpec type, bool val, Location loc)
410 eclass = ExprClass.Value;
416 public override object GetValue ()
418 return (object) Value;
421 public override string GetValueAsLiteral ()
423 return Value ? "true" : "false";
426 public override long GetValueAsLong ()
428 return Value ? 1 : 0;
431 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
436 public override void Emit (EmitContext ec)
444 public override bool IsDefaultValue {
450 public override bool IsNegative {
456 public override bool IsZeroInteger {
457 get { return Value == false; }
460 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
467 public class ByteConstant : IntegralConstant
469 public readonly byte Value;
471 public ByteConstant (BuiltinTypes types, byte v, Location loc)
472 : this (types.Byte, v, loc)
476 public ByteConstant (TypeSpec type, byte v, Location loc)
482 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
487 public override void Emit (EmitContext ec)
492 public override object GetValue ()
497 public override long GetValueAsLong ()
502 public override Constant Increment ()
504 return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
507 public override bool IsDefaultValue {
513 public override bool IsOneInteger {
519 public override bool IsNegative {
525 public override bool IsZeroInteger {
526 get { return Value == 0; }
529 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
531 switch (target_type.BuiltinType) {
532 case BuiltinTypeSpec.Type.SByte:
533 if (in_checked_context){
534 if (Value > SByte.MaxValue)
535 throw new OverflowException ();
537 return new SByteConstant (target_type, (sbyte) Value, Location);
538 case BuiltinTypeSpec.Type.Short:
539 return new ShortConstant (target_type, (short) Value, Location);
540 case BuiltinTypeSpec.Type.UShort:
541 return new UShortConstant (target_type, (ushort) Value, Location);
542 case BuiltinTypeSpec.Type.Int:
543 return new IntConstant (target_type, (int) Value, Location);
544 case BuiltinTypeSpec.Type.UInt:
545 return new UIntConstant (target_type, (uint) Value, Location);
546 case BuiltinTypeSpec.Type.Long:
547 return new LongConstant (target_type, (long) Value, Location);
548 case BuiltinTypeSpec.Type.ULong:
549 return new ULongConstant (target_type, (ulong) Value, Location);
550 case BuiltinTypeSpec.Type.Float:
551 return new FloatConstant (target_type, (float) Value, Location);
552 case BuiltinTypeSpec.Type.Double:
553 return new DoubleConstant (target_type, (double) Value, Location);
554 case BuiltinTypeSpec.Type.Char:
555 return new CharConstant (target_type, (char) Value, Location);
556 case BuiltinTypeSpec.Type.Decimal:
557 return new DecimalConstant (target_type, (decimal) Value, Location);
565 public class CharConstant : Constant {
566 public readonly char Value;
568 public CharConstant (BuiltinTypes types, char v, Location loc)
569 : this (types.Char, v, loc)
573 public CharConstant (TypeSpec type, char v, Location loc)
577 eclass = ExprClass.Value;
582 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
584 enc.Encode ((ushort) Value);
587 public override void Emit (EmitContext ec)
592 static string descape (char c)
618 return c.ToString ();
621 public override object GetValue ()
626 public override long GetValueAsLong ()
631 public override string GetValueAsLiteral ()
633 return "\"" + descape (Value) + "\"";
636 public override bool IsDefaultValue {
642 public override bool IsNegative {
648 public override bool IsZeroInteger {
649 get { return Value == '\0'; }
652 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
654 switch (target_type.BuiltinType) {
655 case BuiltinTypeSpec.Type.Byte:
656 if (in_checked_context) {
657 if (Value < Byte.MinValue || Value > Byte.MaxValue)
658 throw new OverflowException ();
660 return new ByteConstant (target_type, (byte) Value, Location);
661 case BuiltinTypeSpec.Type.SByte:
662 if (in_checked_context) {
663 if (Value > SByte.MaxValue)
664 throw new OverflowException ();
666 return new SByteConstant (target_type, (sbyte) Value, Location);
668 case BuiltinTypeSpec.Type.Short:
669 if (in_checked_context) {
670 if (Value > Int16.MaxValue)
671 throw new OverflowException ();
673 return new ShortConstant (target_type, (short) Value, Location);
674 case BuiltinTypeSpec.Type.Int:
675 return new IntConstant (target_type, (int) Value, Location);
676 case BuiltinTypeSpec.Type.UInt:
677 return new UIntConstant (target_type, (uint) Value, Location);
678 case BuiltinTypeSpec.Type.Long:
679 return new LongConstant (target_type, (long) Value, Location);
680 case BuiltinTypeSpec.Type.ULong:
681 return new ULongConstant (target_type, (ulong) Value, Location);
682 case BuiltinTypeSpec.Type.Float:
683 return new FloatConstant (target_type, (float) Value, Location);
684 case BuiltinTypeSpec.Type.Double:
685 return new DoubleConstant (target_type, (double) Value, Location);
686 case BuiltinTypeSpec.Type.Decimal:
687 return new DecimalConstant (target_type, (decimal) Value, Location);
695 public class SByteConstant : IntegralConstant
697 public readonly sbyte Value;
699 public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
700 : this (types.SByte, v, loc)
704 public SByteConstant (TypeSpec type, sbyte v, Location loc)
710 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
715 public override void Emit (EmitContext ec)
720 public override object GetValue ()
725 public override long GetValueAsLong ()
730 public override Constant Increment ()
732 return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
735 public override bool IsDefaultValue {
741 public override bool IsNegative {
747 public override bool IsOneInteger {
753 public override bool IsZeroInteger {
754 get { return Value == 0; }
757 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
759 switch (target_type.BuiltinType) {
760 case BuiltinTypeSpec.Type.Byte:
761 if (in_checked_context && Value < 0)
762 throw new OverflowException ();
763 return new ByteConstant (target_type, (byte) Value, Location);
764 case BuiltinTypeSpec.Type.Short:
765 return new ShortConstant (target_type, (short) Value, Location);
766 case BuiltinTypeSpec.Type.UShort:
767 if (in_checked_context && Value < 0)
768 throw new OverflowException ();
769 return new UShortConstant (target_type, (ushort) Value, Location);
770 case BuiltinTypeSpec.Type.Int:
771 return new IntConstant (target_type, (int) Value, Location);
772 case BuiltinTypeSpec.Type.UInt:
773 if (in_checked_context && Value < 0)
774 throw new OverflowException ();
775 return new UIntConstant (target_type, (uint) Value, Location);
776 case BuiltinTypeSpec.Type.Long:
777 return new LongConstant (target_type, (long) Value, Location);
778 case BuiltinTypeSpec.Type.ULong:
779 if (in_checked_context && Value < 0)
780 throw new OverflowException ();
781 return new ULongConstant (target_type, (ulong) Value, Location);
782 case BuiltinTypeSpec.Type.Float:
783 return new FloatConstant (target_type, (float) Value, Location);
784 case BuiltinTypeSpec.Type.Double:
785 return new DoubleConstant (target_type, (double) Value, Location);
786 case BuiltinTypeSpec.Type.Char:
787 if (in_checked_context && Value < 0)
788 throw new OverflowException ();
789 return new CharConstant (target_type, (char) Value, Location);
790 case BuiltinTypeSpec.Type.Decimal:
791 return new DecimalConstant (target_type, (decimal) Value, Location);
799 public class ShortConstant : IntegralConstant {
800 public readonly short Value;
802 public ShortConstant (BuiltinTypes types, short v, Location loc)
803 : this (types.Short, v, loc)
807 public ShortConstant (TypeSpec type, short v, Location loc)
813 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
818 public override void Emit (EmitContext ec)
823 public override object GetValue ()
828 public override long GetValueAsLong ()
833 public override Constant Increment ()
835 return new ShortConstant (type, checked((short)(Value + 1)), loc);
838 public override bool IsDefaultValue {
844 public override bool IsZeroInteger {
845 get { return Value == 0; }
848 public override bool IsNegative {
854 public override bool IsOneInteger {
860 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
862 switch (target_type.BuiltinType) {
863 case BuiltinTypeSpec.Type.Byte:
864 if (in_checked_context) {
865 if (Value < Byte.MinValue || Value > Byte.MaxValue)
866 throw new OverflowException ();
868 return new ByteConstant (target_type, (byte) Value, Location);
869 case BuiltinTypeSpec.Type.SByte:
870 if (in_checked_context) {
871 if (Value < SByte.MinValue || Value > SByte.MaxValue)
872 throw new OverflowException ();
874 return new SByteConstant (target_type, (sbyte) Value, Location);
875 case BuiltinTypeSpec.Type.UShort:
876 if (in_checked_context && Value < 0)
877 throw new OverflowException ();
879 return new UShortConstant (target_type, (ushort) Value, Location);
880 case BuiltinTypeSpec.Type.Int:
881 return new IntConstant (target_type, (int) Value, Location);
882 case BuiltinTypeSpec.Type.UInt:
883 if (in_checked_context && Value < 0)
884 throw new OverflowException ();
885 return new UIntConstant (target_type, (uint) Value, Location);
886 case BuiltinTypeSpec.Type.Long:
887 return new LongConstant (target_type, (long) Value, Location);
888 case BuiltinTypeSpec.Type.ULong:
889 if (in_checked_context && Value < 0)
890 throw new OverflowException ();
891 return new ULongConstant (target_type, (ulong) Value, Location);
892 case BuiltinTypeSpec.Type.Float:
893 return new FloatConstant (target_type, (float) Value, Location);
894 case BuiltinTypeSpec.Type.Double:
895 return new DoubleConstant (target_type, (double) Value, Location);
896 case BuiltinTypeSpec.Type.Char:
897 if (in_checked_context) {
898 if (Value < Char.MinValue)
899 throw new OverflowException ();
901 return new CharConstant (target_type, (char) Value, Location);
902 case BuiltinTypeSpec.Type.Decimal:
903 return new DecimalConstant (target_type, (decimal) Value, Location);
911 public class UShortConstant : IntegralConstant
913 public readonly ushort Value;
915 public UShortConstant (BuiltinTypes types, ushort v, Location loc)
916 : this (types.UShort, v, loc)
920 public UShortConstant (TypeSpec type, ushort v, Location loc)
926 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
931 public override void Emit (EmitContext ec)
936 public override object GetValue ()
941 public override long GetValueAsLong ()
946 public override Constant Increment ()
948 return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
951 public override bool IsDefaultValue {
957 public override bool IsNegative {
963 public override bool IsOneInteger {
969 public override bool IsZeroInteger {
970 get { return Value == 0; }
973 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
975 switch (target_type.BuiltinType) {
976 case BuiltinTypeSpec.Type.Byte:
977 if (in_checked_context) {
978 if (Value > Byte.MaxValue)
979 throw new OverflowException ();
981 return new ByteConstant (target_type, (byte) Value, Location);
982 case BuiltinTypeSpec.Type.SByte:
983 if (in_checked_context) {
984 if (Value > SByte.MaxValue)
985 throw new OverflowException ();
987 return new SByteConstant (target_type, (sbyte) Value, Location);
988 case BuiltinTypeSpec.Type.Short:
989 if (in_checked_context) {
990 if (Value > Int16.MaxValue)
991 throw new OverflowException ();
993 return new ShortConstant (target_type, (short) Value, Location);
994 case BuiltinTypeSpec.Type.Int:
995 return new IntConstant (target_type, (int) Value, Location);
996 case BuiltinTypeSpec.Type.UInt:
997 return new UIntConstant (target_type, (uint) Value, Location);
998 case BuiltinTypeSpec.Type.Long:
999 return new LongConstant (target_type, (long) Value, Location);
1000 case BuiltinTypeSpec.Type.ULong:
1001 return new ULongConstant (target_type, (ulong) Value, Location);
1002 case BuiltinTypeSpec.Type.Float:
1003 return new FloatConstant (target_type, (float) Value, Location);
1004 case BuiltinTypeSpec.Type.Double:
1005 return new DoubleConstant (target_type, (double) Value, Location);
1006 case BuiltinTypeSpec.Type.Char:
1007 if (in_checked_context) {
1008 if (Value > Char.MaxValue)
1009 throw new OverflowException ();
1011 return new CharConstant (target_type, (char) Value, Location);
1012 case BuiltinTypeSpec.Type.Decimal:
1013 return new DecimalConstant (target_type, (decimal) Value, Location);
1020 public class IntConstant : IntegralConstant
1022 public readonly int Value;
1024 public IntConstant (BuiltinTypes types, int v, Location loc)
1025 : this (types.Int, v, loc)
1029 public IntConstant (TypeSpec type, int v, Location loc)
1035 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1040 public override void Emit (EmitContext ec)
1045 public override object GetValue ()
1050 public override long GetValueAsLong ()
1055 public override Constant Increment ()
1057 return new IntConstant (type, checked(Value + 1), loc);
1060 public override bool IsDefaultValue {
1066 public override bool IsNegative {
1072 public override bool IsOneInteger {
1078 public override bool IsZeroInteger {
1079 get { return Value == 0; }
1082 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1084 switch (target_type.BuiltinType) {
1085 case BuiltinTypeSpec.Type.Byte:
1086 if (in_checked_context) {
1087 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1088 throw new OverflowException ();
1090 return new ByteConstant (target_type, (byte) Value, Location);
1091 case BuiltinTypeSpec.Type.SByte:
1092 if (in_checked_context) {
1093 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1094 throw new OverflowException ();
1096 return new SByteConstant (target_type, (sbyte) Value, Location);
1097 case BuiltinTypeSpec.Type.Short:
1098 if (in_checked_context) {
1099 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1100 throw new OverflowException ();
1102 return new ShortConstant (target_type, (short) Value, Location);
1103 case BuiltinTypeSpec.Type.UShort:
1104 if (in_checked_context) {
1105 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1106 throw new OverflowException ();
1108 return new UShortConstant (target_type, (ushort) Value, Location);
1109 case BuiltinTypeSpec.Type.UInt:
1110 if (in_checked_context) {
1111 if (Value < UInt32.MinValue)
1112 throw new OverflowException ();
1114 return new UIntConstant (target_type, (uint) Value, Location);
1115 case BuiltinTypeSpec.Type.Long:
1116 return new LongConstant (target_type, (long) Value, Location);
1117 case BuiltinTypeSpec.Type.ULong:
1118 if (in_checked_context && Value < 0)
1119 throw new OverflowException ();
1120 return new ULongConstant (target_type, (ulong) Value, Location);
1121 case BuiltinTypeSpec.Type.Float:
1122 return new FloatConstant (target_type, (float) Value, Location);
1123 case BuiltinTypeSpec.Type.Double:
1124 return new DoubleConstant (target_type, (double) Value, Location);
1125 case BuiltinTypeSpec.Type.Char:
1126 if (in_checked_context) {
1127 if (Value < Char.MinValue || Value > Char.MaxValue)
1128 throw new OverflowException ();
1130 return new CharConstant (target_type, (char) Value, Location);
1131 case BuiltinTypeSpec.Type.Decimal:
1132 return new DecimalConstant (target_type, (decimal) Value, Location);
1138 public override Constant ConvertImplicitly (TypeSpec type)
1140 if (this.type == type)
1143 Constant c = TryImplicitIntConversion (type);
1145 return c; //.Resolve (rc);
1147 return base.ConvertImplicitly (type);
1151 /// Attempts to perform an implicit constant conversion of the IntConstant
1152 /// into a different data type using casts (See Implicit Constant
1153 /// Expression Conversions)
1155 Constant TryImplicitIntConversion (TypeSpec target_type)
1157 switch (target_type.BuiltinType) {
1158 case BuiltinTypeSpec.Type.SByte:
1159 if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1160 return new SByteConstant (target_type, (sbyte) Value, loc);
1162 case BuiltinTypeSpec.Type.Byte:
1163 if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1164 return new ByteConstant (target_type, (byte) Value, loc);
1166 case BuiltinTypeSpec.Type.Short:
1167 if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1168 return new ShortConstant (target_type, (short) Value, loc);
1170 case BuiltinTypeSpec.Type.UShort:
1171 if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1172 return new UShortConstant (target_type, (ushort) Value, loc);
1174 case BuiltinTypeSpec.Type.UInt:
1176 return new UIntConstant (target_type, (uint) Value, loc);
1178 case BuiltinTypeSpec.Type.ULong:
1180 // we can optimize this case: a positive int32
1181 // always fits on a uint64. But we need an opcode
1185 return new ULongConstant (target_type, (ulong) Value, loc);
1187 case BuiltinTypeSpec.Type.Double:
1188 return new DoubleConstant (target_type, (double) Value, loc);
1189 case BuiltinTypeSpec.Type.Float:
1190 return new FloatConstant (target_type, (float) Value, loc);
1197 public class UIntConstant : IntegralConstant {
1198 public readonly uint Value;
1200 public UIntConstant (BuiltinTypes types, uint v, Location loc)
1201 : this (types.UInt, v, loc)
1205 public UIntConstant (TypeSpec type, uint v, Location loc)
1211 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1216 public override void Emit (EmitContext ec)
1218 ec.EmitInt (unchecked ((int) Value));
1221 public override object GetValue ()
1226 public override long GetValueAsLong ()
1231 public override Constant Increment ()
1233 return new UIntConstant (type, checked(Value + 1), loc);
1236 public override bool IsDefaultValue {
1242 public override bool IsNegative {
1248 public override bool IsOneInteger {
1254 public override bool IsZeroInteger {
1255 get { return Value == 0; }
1258 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1260 switch (target_type.BuiltinType) {
1261 case BuiltinTypeSpec.Type.Byte:
1262 if (in_checked_context) {
1263 if (Value < 0 || Value > byte.MaxValue)
1264 throw new OverflowException ();
1266 return new ByteConstant (target_type, (byte) Value, Location);
1267 case BuiltinTypeSpec.Type.SByte:
1268 if (in_checked_context) {
1269 if (Value > SByte.MaxValue)
1270 throw new OverflowException ();
1272 return new SByteConstant (target_type, (sbyte) Value, Location);
1273 case BuiltinTypeSpec.Type.Short:
1274 if (in_checked_context) {
1275 if (Value > Int16.MaxValue)
1276 throw new OverflowException ();
1278 return new ShortConstant (target_type, (short) Value, Location);
1279 case BuiltinTypeSpec.Type.UShort:
1280 if (in_checked_context) {
1281 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1282 throw new OverflowException ();
1284 return new UShortConstant (target_type, (ushort) Value, Location);
1285 case BuiltinTypeSpec.Type.Int:
1286 if (in_checked_context) {
1287 if (Value > Int32.MaxValue)
1288 throw new OverflowException ();
1290 return new IntConstant (target_type, (int) Value, Location);
1291 case BuiltinTypeSpec.Type.Long:
1292 return new LongConstant (target_type, (long) Value, Location);
1293 case BuiltinTypeSpec.Type.ULong:
1294 return new ULongConstant (target_type, (ulong) Value, Location);
1295 case BuiltinTypeSpec.Type.Float:
1296 return new FloatConstant (target_type, (float) Value, Location);
1297 case BuiltinTypeSpec.Type.Double:
1298 return new DoubleConstant (target_type, (double) Value, Location);
1299 case BuiltinTypeSpec.Type.Char:
1300 if (in_checked_context) {
1301 if (Value < Char.MinValue || Value > Char.MaxValue)
1302 throw new OverflowException ();
1304 return new CharConstant (target_type, (char) Value, Location);
1305 case BuiltinTypeSpec.Type.Decimal:
1306 return new DecimalConstant (target_type, (decimal) Value, Location);
1314 public class LongConstant : IntegralConstant {
1315 public readonly long Value;
1317 public LongConstant (BuiltinTypes types, long v, Location loc)
1318 : this (types.Long, v, loc)
1322 public LongConstant (TypeSpec type, long v, Location loc)
1328 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1333 public override void Emit (EmitContext ec)
1335 ec.EmitLong (Value);
1338 public override object GetValue ()
1343 public override long GetValueAsLong ()
1348 public override Constant Increment ()
1350 return new LongConstant (type, checked(Value + 1), loc);
1353 public override bool IsDefaultValue {
1359 public override bool IsNegative {
1365 public override bool IsOneInteger {
1371 public override bool IsZeroInteger {
1372 get { return Value == 0; }
1375 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1377 switch (target_type.BuiltinType) {
1378 case BuiltinTypeSpec.Type.Byte:
1379 if (in_checked_context) {
1380 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1381 throw new OverflowException ();
1383 return new ByteConstant (target_type, (byte) Value, Location);
1384 case BuiltinTypeSpec.Type.SByte:
1385 if (in_checked_context) {
1386 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1387 throw new OverflowException ();
1389 return new SByteConstant (target_type, (sbyte) Value, Location);
1390 case BuiltinTypeSpec.Type.Short:
1391 if (in_checked_context) {
1392 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1393 throw new OverflowException ();
1395 return new ShortConstant (target_type, (short) Value, Location);
1396 case BuiltinTypeSpec.Type.UShort:
1397 if (in_checked_context) {
1398 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1399 throw new OverflowException ();
1401 return new UShortConstant (target_type, (ushort) Value, Location);
1402 case BuiltinTypeSpec.Type.Int:
1403 if (in_checked_context) {
1404 if (Value < Int32.MinValue || Value > Int32.MaxValue)
1405 throw new OverflowException ();
1407 return new IntConstant (target_type, (int) Value, Location);
1408 case BuiltinTypeSpec.Type.UInt:
1409 if (in_checked_context) {
1410 if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1411 throw new OverflowException ();
1413 return new UIntConstant (target_type, (uint) Value, Location);
1414 case BuiltinTypeSpec.Type.ULong:
1415 if (in_checked_context && Value < 0)
1416 throw new OverflowException ();
1417 return new ULongConstant (target_type, (ulong) Value, Location);
1418 case BuiltinTypeSpec.Type.Float:
1419 return new FloatConstant (target_type, (float) Value, Location);
1420 case BuiltinTypeSpec.Type.Double:
1421 return new DoubleConstant (target_type, (double) Value, Location);
1422 case BuiltinTypeSpec.Type.Char:
1423 if (in_checked_context) {
1424 if (Value < Char.MinValue || Value > Char.MaxValue)
1425 throw new OverflowException ();
1427 return new CharConstant (target_type, (char) Value, Location);
1428 case BuiltinTypeSpec.Type.Decimal:
1429 return new DecimalConstant (target_type, (decimal) Value, Location);
1435 public override Constant ConvertImplicitly (TypeSpec type)
1437 if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
1438 return new ULongConstant (type, (ulong) Value, loc);
1441 return base.ConvertImplicitly (type);
1445 public class ULongConstant : IntegralConstant {
1446 public readonly ulong Value;
1448 public ULongConstant (BuiltinTypes types, ulong v, Location loc)
1449 : this (types.ULong, v, loc)
1453 public ULongConstant (TypeSpec type, ulong v, Location loc)
1459 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1464 public override void Emit (EmitContext ec)
1466 ec.EmitLong (unchecked ((long) Value));
1469 public override object GetValue ()
1474 public override long GetValueAsLong ()
1476 return (long) Value;
1479 public override Constant Increment ()
1481 return new ULongConstant (type, checked(Value + 1), loc);
1484 public override bool IsDefaultValue {
1490 public override bool IsNegative {
1496 public override bool IsOneInteger {
1502 public override bool IsZeroInteger {
1503 get { return Value == 0; }
1506 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1508 switch (target_type.BuiltinType) {
1509 case BuiltinTypeSpec.Type.Byte:
1510 if (in_checked_context && Value > Byte.MaxValue)
1511 throw new OverflowException ();
1512 return new ByteConstant (target_type, (byte) Value, Location);
1513 case BuiltinTypeSpec.Type.SByte:
1514 if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1515 throw new OverflowException ();
1516 return new SByteConstant (target_type, (sbyte) Value, Location);
1517 case BuiltinTypeSpec.Type.Short:
1518 if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1519 throw new OverflowException ();
1520 return new ShortConstant (target_type, (short) Value, Location);
1521 case BuiltinTypeSpec.Type.UShort:
1522 if (in_checked_context && Value > UInt16.MaxValue)
1523 throw new OverflowException ();
1524 return new UShortConstant (target_type, (ushort) Value, Location);
1525 case BuiltinTypeSpec.Type.Int:
1526 if (in_checked_context && Value > UInt32.MaxValue)
1527 throw new OverflowException ();
1528 return new IntConstant (target_type, (int) Value, Location);
1529 case BuiltinTypeSpec.Type.UInt:
1530 if (in_checked_context && Value > UInt32.MaxValue)
1531 throw new OverflowException ();
1532 return new UIntConstant (target_type, (uint) Value, Location);
1533 case BuiltinTypeSpec.Type.Long:
1534 if (in_checked_context && Value > Int64.MaxValue)
1535 throw new OverflowException ();
1536 return new LongConstant (target_type, (long) Value, Location);
1537 case BuiltinTypeSpec.Type.Float:
1538 return new FloatConstant (target_type, (float) Value, Location);
1539 case BuiltinTypeSpec.Type.Double:
1540 return new DoubleConstant (target_type, (double) Value, Location);
1541 case BuiltinTypeSpec.Type.Char:
1542 if (in_checked_context && Value > Char.MaxValue)
1543 throw new OverflowException ();
1544 return new CharConstant (target_type, (char) Value, Location);
1545 case BuiltinTypeSpec.Type.Decimal:
1546 return new DecimalConstant (target_type, (decimal) Value, Location);
1554 public class FloatConstant : Constant {
1555 public readonly float Value;
1557 public FloatConstant (BuiltinTypes types, float v, Location loc)
1558 : this (types.Float, v, loc)
1562 public FloatConstant (TypeSpec type, float v, Location loc)
1566 eclass = ExprClass.Value;
1571 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1576 public override void Emit (EmitContext ec)
1578 ec.Emit (OpCodes.Ldc_R4, Value);
1581 public override object GetValue ()
1586 public override string GetValueAsLiteral ()
1588 return Value.ToString ();
1591 public override long GetValueAsLong ()
1593 throw new NotSupportedException ();
1596 public override bool IsDefaultValue {
1602 public override bool IsNegative {
1608 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1610 switch (target_type.BuiltinType) {
1611 case BuiltinTypeSpec.Type.Byte:
1612 if (in_checked_context) {
1613 if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1614 throw new OverflowException ();
1616 return new ByteConstant (target_type, (byte) Value, Location);
1617 case BuiltinTypeSpec.Type.SByte:
1618 if (in_checked_context) {
1619 if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1620 throw new OverflowException ();
1622 return new SByteConstant (target_type, (sbyte) Value, Location);
1623 case BuiltinTypeSpec.Type.Short:
1624 if (in_checked_context) {
1625 if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1626 throw new OverflowException ();
1628 return new ShortConstant (target_type, (short) Value, Location);
1629 case BuiltinTypeSpec.Type.UShort:
1630 if (in_checked_context) {
1631 if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1632 throw new OverflowException ();
1634 return new UShortConstant (target_type, (ushort) Value, Location);
1635 case BuiltinTypeSpec.Type.Int:
1636 if (in_checked_context) {
1637 if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1638 throw new OverflowException ();
1640 return new IntConstant (target_type, (int) Value, Location);
1641 case BuiltinTypeSpec.Type.UInt:
1642 if (in_checked_context) {
1643 if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1644 throw new OverflowException ();
1646 return new UIntConstant (target_type, (uint) Value, Location);
1647 case BuiltinTypeSpec.Type.Long:
1648 if (in_checked_context) {
1649 if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1650 throw new OverflowException ();
1652 return new LongConstant (target_type, (long) Value, Location);
1653 case BuiltinTypeSpec.Type.ULong:
1654 if (in_checked_context) {
1655 if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1656 throw new OverflowException ();
1658 return new ULongConstant (target_type, (ulong) Value, Location);
1659 case BuiltinTypeSpec.Type.Double:
1660 return new DoubleConstant (target_type, (double) Value, Location);
1661 case BuiltinTypeSpec.Type.Char:
1662 if (in_checked_context) {
1663 if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1664 throw new OverflowException ();
1666 return new CharConstant (target_type, (char) Value, Location);
1667 case BuiltinTypeSpec.Type.Decimal:
1668 return new DecimalConstant (target_type, (decimal) Value, Location);
1676 public class DoubleConstant : Constant
1678 public readonly double Value;
1680 public DoubleConstant (BuiltinTypes types, double v, Location loc)
1681 : this (types.Double, v, loc)
1685 public DoubleConstant (TypeSpec type, double v, Location loc)
1689 eclass = ExprClass.Value;
1694 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1699 public override void Emit (EmitContext ec)
1701 ec.Emit (OpCodes.Ldc_R8, Value);
1704 public override object GetValue ()
1709 public override string GetValueAsLiteral ()
1711 return Value.ToString ();
1714 public override long GetValueAsLong ()
1716 throw new NotSupportedException ();
1719 public override bool IsDefaultValue {
1725 public override bool IsNegative {
1731 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1733 switch (target_type.BuiltinType) {
1734 case BuiltinTypeSpec.Type.Byte:
1735 if (in_checked_context) {
1736 if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1737 throw new OverflowException ();
1739 return new ByteConstant (target_type, (byte) Value, Location);
1740 case BuiltinTypeSpec.Type.SByte:
1741 if (in_checked_context) {
1742 if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1743 throw new OverflowException ();
1745 return new SByteConstant (target_type, (sbyte) Value, Location);
1746 case BuiltinTypeSpec.Type.Short:
1747 if (in_checked_context) {
1748 if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1749 throw new OverflowException ();
1751 return new ShortConstant (target_type, (short) Value, Location);
1752 case BuiltinTypeSpec.Type.UShort:
1753 if (in_checked_context) {
1754 if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1755 throw new OverflowException ();
1757 return new UShortConstant (target_type, (ushort) Value, Location);
1758 case BuiltinTypeSpec.Type.Int:
1759 if (in_checked_context) {
1760 if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1761 throw new OverflowException ();
1763 return new IntConstant (target_type, (int) Value, Location);
1764 case BuiltinTypeSpec.Type.UInt:
1765 if (in_checked_context) {
1766 if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1767 throw new OverflowException ();
1769 return new UIntConstant (target_type, (uint) Value, Location);
1770 case BuiltinTypeSpec.Type.Long:
1771 if (in_checked_context) {
1772 if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1773 throw new OverflowException ();
1775 return new LongConstant (target_type, (long) Value, Location);
1776 case BuiltinTypeSpec.Type.ULong:
1777 if (in_checked_context) {
1778 if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1779 throw new OverflowException ();
1781 return new ULongConstant (target_type, (ulong) Value, Location);
1782 case BuiltinTypeSpec.Type.Float:
1783 return new FloatConstant (target_type, (float) Value, Location);
1784 case BuiltinTypeSpec.Type.Char:
1785 if (in_checked_context) {
1786 if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1787 throw new OverflowException ();
1789 return new CharConstant (target_type, (char) Value, Location);
1790 case BuiltinTypeSpec.Type.Decimal:
1791 return new DecimalConstant (target_type, (decimal) Value, Location);
1799 public class DecimalConstant : Constant {
1800 public readonly decimal Value;
1802 public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1803 : this (types.Decimal, d, loc)
1807 public DecimalConstant (TypeSpec type, decimal d, Location loc)
1811 eclass = ExprClass.Value;
1816 public override void Emit (EmitContext ec)
1820 int [] words = decimal.GetBits (Value);
1821 int power = (words [3] >> 16) & 0xff;
1824 if (Value <= int.MaxValue && Value >= int.MinValue) {
1825 m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1830 ec.EmitInt ((int) Value);
1831 ec.Emit (OpCodes.Newobj, m);
1835 if (Value <= long.MaxValue && Value >= long.MinValue) {
1836 m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1841 ec.EmitLong ((long) Value);
1842 ec.Emit (OpCodes.Newobj, m);
1847 ec.EmitInt (words [0]);
1848 ec.EmitInt (words [1]);
1849 ec.EmitInt (words [2]);
1852 ec.EmitInt (words [3] >> 31);
1857 m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1859 ec.Emit (OpCodes.Newobj, m);
1863 public override bool IsDefaultValue {
1869 public override bool IsNegative {
1875 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1877 switch (target_type.BuiltinType) {
1878 case BuiltinTypeSpec.Type.SByte:
1879 return new SByteConstant (target_type, (sbyte) Value, loc);
1880 case BuiltinTypeSpec.Type.Byte:
1881 return new ByteConstant (target_type, (byte) Value, loc);
1882 case BuiltinTypeSpec.Type.Short:
1883 return new ShortConstant (target_type, (short) Value, loc);
1884 case BuiltinTypeSpec.Type.UShort:
1885 return new UShortConstant (target_type, (ushort) Value, loc);
1886 case BuiltinTypeSpec.Type.Int:
1887 return new IntConstant (target_type, (int) Value, loc);
1888 case BuiltinTypeSpec.Type.UInt:
1889 return new UIntConstant (target_type, (uint) Value, loc);
1890 case BuiltinTypeSpec.Type.Long:
1891 return new LongConstant (target_type, (long) Value, loc);
1892 case BuiltinTypeSpec.Type.ULong:
1893 return new ULongConstant (target_type, (ulong) Value, loc);
1894 case BuiltinTypeSpec.Type.Char:
1895 return new CharConstant (target_type, (char) Value, loc);
1896 case BuiltinTypeSpec.Type.Float:
1897 return new FloatConstant (target_type, (float) Value, loc);
1898 case BuiltinTypeSpec.Type.Double:
1899 return new DoubleConstant (target_type, (double) Value, loc);
1905 public override object GetValue ()
1910 public override string GetValueAsLiteral ()
1912 return Value.ToString () + "M";
1915 public override long GetValueAsLong ()
1917 throw new NotSupportedException ();
1921 public class StringConstant : Constant {
1922 public readonly string Value;
1924 public StringConstant (BuiltinTypes types, string s, Location loc)
1925 : this (types.String, s, loc)
1929 public StringConstant (TypeSpec type, string s, Location loc)
1933 eclass = ExprClass.Value;
1938 public override object GetValue ()
1943 public override string GetValueAsLiteral ()
1945 // FIXME: Escape the string.
1946 return "\"" + Value + "\"";
1949 public override long GetValueAsLong ()
1951 throw new NotSupportedException ();
1954 public override void Emit (EmitContext ec)
1956 if (Value == null) {
1962 // Use string.Empty for both literals and constants even if
1963 // it's not allowed at language level
1965 if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
1966 var string_type = ec.BuiltinTypes.String;
1967 if (ec.CurrentType != string_type) {
1968 var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
1970 ec.Emit (OpCodes.Ldsfld, m);
1976 ec.Emit (OpCodes.Ldstr, Value);
1979 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1982 if (type != targetType)
1988 public override bool IsDefaultValue {
1990 return Value == null;
1994 public override bool IsNegative {
2000 public override bool IsNull {
2002 return IsDefaultValue;
2006 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2013 // Null constant can have its own type, think of `default (Foo)'
2015 public class NullConstant : Constant
2017 public NullConstant (TypeSpec type, Location loc)
2020 eclass = ExprClass.Value;
2024 public override Expression CreateExpressionTree (ResolveContext ec)
2026 if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2027 // Optimized version, also avoids referencing literal internal type
2028 Arguments args = new Arguments (1);
2029 args.Add (new Argument (this));
2030 return CreateExpressionFactoryCall (ec, "Constant", args);
2033 return base.CreateExpressionTree (ec);
2036 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2038 switch (targetType.BuiltinType) {
2039 case BuiltinTypeSpec.Type.Object:
2040 // Type it as string cast
2041 enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2042 goto case BuiltinTypeSpec.Type.String;
2043 case BuiltinTypeSpec.Type.String:
2044 case BuiltinTypeSpec.Type.Type:
2045 enc.Encode (byte.MaxValue);
2048 var ac = targetType as ArrayContainer;
2049 if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
2050 enc.Encode (uint.MaxValue);
2057 base.EncodeAttributeValue (rc, enc, targetType);
2060 public override void Emit (EmitContext ec)
2064 // Only to make verifier happy
2065 if (type.IsGenericParameter)
2066 ec.Emit (OpCodes.Unbox_Any, type);
2069 public override string ExprClassName {
2071 return GetSignatureForError ();
2075 public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2077 if (targetType.IsPointer) {
2078 if (IsLiteral || this is NullPointer)
2079 return new NullPointer (targetType, loc);
2084 // Exlude internal compiler types
2085 if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2088 if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2091 if (TypeSpec.IsReferenceType (targetType))
2092 return new NullConstant (targetType, loc);
2094 if (targetType.IsNullableType)
2095 return Nullable.LiftedNull.Create (targetType, loc);
2100 public override Constant ConvertImplicitly (TypeSpec targetType)
2102 return ConvertExplicitly (false, targetType);
2105 public override string GetSignatureForError ()
2110 public override object GetValue ()
2115 public override string GetValueAsLiteral ()
2117 return GetSignatureForError ();
2120 public override long GetValueAsLong ()
2122 throw new NotSupportedException ();
2125 public override bool IsDefaultValue {
2126 get { return true; }
2129 public override bool IsNegative {
2130 get { return false; }
2133 public override bool IsNull {
2134 get { return true; }
2137 public override bool IsZeroInteger {
2138 get { return true; }
2144 // A null constant in a pointer context
2146 class NullPointer : NullConstant
2148 public NullPointer (TypeSpec type, Location loc)
2153 public override Expression CreateExpressionTree (ResolveContext ec)
2155 Error_PointerInsideExpressionTree (ec);
2156 return base.CreateExpressionTree (ec);
2159 public override void Emit (EmitContext ec)
2162 // Emits null pointer
2165 ec.Emit (OpCodes.Conv_U);
2170 /// The value is constant, but when emitted has a side effect. This is
2171 /// used by BitwiseAnd to ensure that the second expression is invoked
2172 /// regardless of the value of the left side.
2174 public class SideEffectConstant : Constant
2176 public readonly Constant value;
2177 Expression side_effect;
2179 public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2184 eclass = ExprClass.Value;
2186 while (side_effect is SideEffectConstant)
2187 side_effect = ((SideEffectConstant) side_effect).side_effect;
2188 this.side_effect = side_effect;
2191 public override bool IsSideEffectFree {
2197 public override object GetValue ()
2199 return value.GetValue ();
2202 public override string GetValueAsLiteral ()
2204 return value.GetValueAsLiteral ();
2207 public override long GetValueAsLong ()
2209 return value.GetValueAsLong ();
2212 public override void Emit (EmitContext ec)
2214 side_effect.EmitSideEffect (ec);
2218 public override void EmitSideEffect (EmitContext ec)
2220 side_effect.EmitSideEffect (ec);
2221 value.EmitSideEffect (ec);
2224 public override bool IsDefaultValue {
2225 get { return value.IsDefaultValue; }
2228 public override bool IsNegative {
2229 get { return value.IsNegative; }
2232 public override bool IsZeroInteger {
2233 get { return value.IsZeroInteger; }
2236 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2238 Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2239 if (new_value == null)
2242 var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2243 c.type = target_type;