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, 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, target, expl);
73 public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc)
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.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)
260 return TryReduceConstant (ec, target_type);
261 } catch (OverflowException) {
262 if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
263 ec.Report.Error (221, loc,
264 "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
265 GetValueAsLiteral (), target_type.GetSignatureForError ());
267 Error_ValueCannotBeConverted (ec, target_type, false);
270 return New.Constantify (target_type, loc);
274 Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
276 if (Type == target_type) {
278 // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10
281 return CreateConstantFromValue (target_type, GetValue (), loc);
287 if (target_type.IsEnum) {
288 c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type));
292 return new EnumConstant (c, target_type);
295 return ConvertExplicitly (ec.ConstantCheckState, target_type);
299 /// Need to pass type as the constant can require a boxing
300 /// and in such case no optimization is possible
302 public bool IsDefaultInitializer (TypeSpec type)
305 return IsDefaultValue;
307 return this is NullLiteral;
310 public abstract bool IsDefaultValue {
314 public abstract bool IsNegative {
319 // When constant is declared as literal
321 public virtual bool IsLiteral {
322 get { return false; }
325 public virtual bool IsOneInteger {
326 get { return false; }
329 public override bool IsSideEffectFree {
336 // Returns true iff 1) the stack type of this is one of Object,
337 // int32, int64 and 2) this == 0 or this == null.
339 public virtual bool IsZeroInteger {
340 get { return false; }
343 public override void EmitSideEffect (EmitContext ec)
348 public sealed override Expression Clone (CloneContext clonectx)
350 // No cloning is not needed for constants
354 protected override void CloneTo (CloneContext clonectx, Expression target)
356 throw new NotSupportedException ("should not be reached");
359 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
362 return base.MakeExpression (ctx);
364 return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
368 public new bool Resolve (ResolveContext rc)
370 // It exists only as hint not to call Resolve on constants
375 public abstract class IntegralConstant : Constant
377 protected IntegralConstant (TypeSpec type, Location loc)
381 eclass = ExprClass.Value;
384 public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
387 ConvertExplicitly (true, target);
388 base.Error_ValueCannotBeConverted (ec, target, expl);
392 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
393 GetValue ().ToString (), TypeManager.CSharpName (target));
397 public override string GetValueAsLiteral ()
399 return GetValue ().ToString ();
402 public abstract Constant Increment ();
405 public class BoolConstant : Constant {
406 public readonly bool Value;
408 public BoolConstant (BuiltinTypes types, bool val, Location loc)
409 : this (types.Bool, val, loc)
413 public BoolConstant (TypeSpec type, bool val, Location loc)
416 eclass = ExprClass.Value;
422 public override object GetValue ()
424 return (object) Value;
427 public override string GetValueAsLiteral ()
429 return Value ? "true" : "false";
432 public override long GetValueAsLong ()
434 return Value ? 1 : 0;
437 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
442 public override void Emit (EmitContext ec)
450 public override bool IsDefaultValue {
456 public override bool IsNegative {
462 public override bool IsZeroInteger {
463 get { return Value == false; }
466 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
473 public class ByteConstant : IntegralConstant
475 public readonly byte Value;
477 public ByteConstant (BuiltinTypes types, byte v, Location loc)
478 : this (types.Byte, v, loc)
482 public ByteConstant (TypeSpec type, byte v, Location loc)
488 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
493 public override void Emit (EmitContext ec)
498 public override object GetValue ()
503 public override long GetValueAsLong ()
508 public override Constant Increment ()
510 return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
513 public override bool IsDefaultValue {
519 public override bool IsOneInteger {
525 public override bool IsNegative {
531 public override bool IsZeroInteger {
532 get { return Value == 0; }
535 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
537 switch (target_type.BuiltinType) {
538 case BuiltinTypeSpec.Type.SByte:
539 if (in_checked_context){
540 if (Value > SByte.MaxValue)
541 throw new OverflowException ();
543 return new SByteConstant (target_type, (sbyte) Value, Location);
544 case BuiltinTypeSpec.Type.Short:
545 return new ShortConstant (target_type, (short) Value, Location);
546 case BuiltinTypeSpec.Type.UShort:
547 return new UShortConstant (target_type, (ushort) Value, Location);
548 case BuiltinTypeSpec.Type.Int:
549 return new IntConstant (target_type, (int) Value, Location);
550 case BuiltinTypeSpec.Type.UInt:
551 return new UIntConstant (target_type, (uint) Value, Location);
552 case BuiltinTypeSpec.Type.Long:
553 return new LongConstant (target_type, (long) Value, Location);
554 case BuiltinTypeSpec.Type.ULong:
555 return new ULongConstant (target_type, (ulong) Value, Location);
556 case BuiltinTypeSpec.Type.Float:
557 return new FloatConstant (target_type, (float) Value, Location);
558 case BuiltinTypeSpec.Type.Double:
559 return new DoubleConstant (target_type, (double) Value, Location);
560 case BuiltinTypeSpec.Type.Char:
561 return new CharConstant (target_type, (char) Value, Location);
562 case BuiltinTypeSpec.Type.Decimal:
563 return new DecimalConstant (target_type, (decimal) Value, Location);
571 public class CharConstant : Constant {
572 public readonly char Value;
574 public CharConstant (BuiltinTypes types, char v, Location loc)
575 : this (types.Char, v, loc)
579 public CharConstant (TypeSpec type, char v, Location loc)
583 eclass = ExprClass.Value;
588 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
590 enc.Encode ((ushort) Value);
593 public override void Emit (EmitContext ec)
598 static string descape (char c)
624 return c.ToString ();
627 public override object GetValue ()
632 public override long GetValueAsLong ()
637 public override string GetValueAsLiteral ()
639 return "\"" + descape (Value) + "\"";
642 public override bool IsDefaultValue {
648 public override bool IsNegative {
654 public override bool IsZeroInteger {
655 get { return Value == '\0'; }
658 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
660 switch (target_type.BuiltinType) {
661 case BuiltinTypeSpec.Type.Byte:
662 if (in_checked_context) {
663 if (Value < Byte.MinValue || Value > Byte.MaxValue)
664 throw new OverflowException ();
666 return new ByteConstant (target_type, (byte) Value, Location);
667 case BuiltinTypeSpec.Type.SByte:
668 if (in_checked_context) {
669 if (Value > SByte.MaxValue)
670 throw new OverflowException ();
672 return new SByteConstant (target_type, (sbyte) Value, Location);
674 case BuiltinTypeSpec.Type.Short:
675 if (in_checked_context) {
676 if (Value > Int16.MaxValue)
677 throw new OverflowException ();
679 return new ShortConstant (target_type, (short) Value, Location);
680 case BuiltinTypeSpec.Type.Int:
681 return new IntConstant (target_type, (int) Value, Location);
682 case BuiltinTypeSpec.Type.UInt:
683 return new UIntConstant (target_type, (uint) Value, Location);
684 case BuiltinTypeSpec.Type.Long:
685 return new LongConstant (target_type, (long) Value, Location);
686 case BuiltinTypeSpec.Type.ULong:
687 return new ULongConstant (target_type, (ulong) Value, Location);
688 case BuiltinTypeSpec.Type.Float:
689 return new FloatConstant (target_type, (float) Value, Location);
690 case BuiltinTypeSpec.Type.Double:
691 return new DoubleConstant (target_type, (double) Value, Location);
692 case BuiltinTypeSpec.Type.Decimal:
693 return new DecimalConstant (target_type, (decimal) Value, Location);
701 public class SByteConstant : IntegralConstant
703 public readonly sbyte Value;
705 public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
706 : this (types.SByte, v, loc)
710 public SByteConstant (TypeSpec type, sbyte v, Location loc)
716 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
721 public override void Emit (EmitContext ec)
726 public override object GetValue ()
731 public override long GetValueAsLong ()
736 public override Constant Increment ()
738 return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
741 public override bool IsDefaultValue {
747 public override bool IsNegative {
753 public override bool IsOneInteger {
759 public override bool IsZeroInteger {
760 get { return Value == 0; }
763 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
765 switch (target_type.BuiltinType) {
766 case BuiltinTypeSpec.Type.Byte:
767 if (in_checked_context && Value < 0)
768 throw new OverflowException ();
769 return new ByteConstant (target_type, (byte) Value, Location);
770 case BuiltinTypeSpec.Type.Short:
771 return new ShortConstant (target_type, (short) Value, Location);
772 case BuiltinTypeSpec.Type.UShort:
773 if (in_checked_context && Value < 0)
774 throw new OverflowException ();
775 return new UShortConstant (target_type, (ushort) Value, Location);
776 case BuiltinTypeSpec.Type.Int:
777 return new IntConstant (target_type, (int) Value, Location);
778 case BuiltinTypeSpec.Type.UInt:
779 if (in_checked_context && Value < 0)
780 throw new OverflowException ();
781 return new UIntConstant (target_type, (uint) Value, Location);
782 case BuiltinTypeSpec.Type.Long:
783 return new LongConstant (target_type, (long) Value, Location);
784 case BuiltinTypeSpec.Type.ULong:
785 if (in_checked_context && Value < 0)
786 throw new OverflowException ();
787 return new ULongConstant (target_type, (ulong) Value, Location);
788 case BuiltinTypeSpec.Type.Float:
789 return new FloatConstant (target_type, (float) Value, Location);
790 case BuiltinTypeSpec.Type.Double:
791 return new DoubleConstant (target_type, (double) Value, Location);
792 case BuiltinTypeSpec.Type.Char:
793 if (in_checked_context && Value < 0)
794 throw new OverflowException ();
795 return new CharConstant (target_type, (char) Value, Location);
796 case BuiltinTypeSpec.Type.Decimal:
797 return new DecimalConstant (target_type, (decimal) Value, Location);
805 public class ShortConstant : IntegralConstant {
806 public readonly short Value;
808 public ShortConstant (BuiltinTypes types, short v, Location loc)
809 : this (types.Short, v, loc)
813 public ShortConstant (TypeSpec type, short v, Location loc)
819 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
824 public override void Emit (EmitContext ec)
829 public override object GetValue ()
834 public override long GetValueAsLong ()
839 public override Constant Increment ()
841 return new ShortConstant (type, checked((short)(Value + 1)), loc);
844 public override bool IsDefaultValue {
850 public override bool IsZeroInteger {
851 get { return Value == 0; }
854 public override bool IsNegative {
860 public override bool IsOneInteger {
866 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
868 switch (target_type.BuiltinType) {
869 case BuiltinTypeSpec.Type.Byte:
870 if (in_checked_context) {
871 if (Value < Byte.MinValue || Value > Byte.MaxValue)
872 throw new OverflowException ();
874 return new ByteConstant (target_type, (byte) Value, Location);
875 case BuiltinTypeSpec.Type.SByte:
876 if (in_checked_context) {
877 if (Value < SByte.MinValue || Value > SByte.MaxValue)
878 throw new OverflowException ();
880 return new SByteConstant (target_type, (sbyte) Value, Location);
881 case BuiltinTypeSpec.Type.UShort:
882 if (in_checked_context && Value < 0)
883 throw new OverflowException ();
885 return new UShortConstant (target_type, (ushort) Value, Location);
886 case BuiltinTypeSpec.Type.Int:
887 return new IntConstant (target_type, (int) Value, Location);
888 case BuiltinTypeSpec.Type.UInt:
889 if (in_checked_context && Value < 0)
890 throw new OverflowException ();
891 return new UIntConstant (target_type, (uint) Value, Location);
892 case BuiltinTypeSpec.Type.Long:
893 return new LongConstant (target_type, (long) Value, Location);
894 case BuiltinTypeSpec.Type.ULong:
895 if (in_checked_context && Value < 0)
896 throw new OverflowException ();
897 return new ULongConstant (target_type, (ulong) Value, Location);
898 case BuiltinTypeSpec.Type.Float:
899 return new FloatConstant (target_type, (float) Value, Location);
900 case BuiltinTypeSpec.Type.Double:
901 return new DoubleConstant (target_type, (double) Value, Location);
902 case BuiltinTypeSpec.Type.Char:
903 if (in_checked_context) {
904 if (Value < Char.MinValue)
905 throw new OverflowException ();
907 return new CharConstant (target_type, (char) Value, Location);
908 case BuiltinTypeSpec.Type.Decimal:
909 return new DecimalConstant (target_type, (decimal) Value, Location);
917 public class UShortConstant : IntegralConstant
919 public readonly ushort Value;
921 public UShortConstant (BuiltinTypes types, ushort v, Location loc)
922 : this (types.UShort, v, loc)
926 public UShortConstant (TypeSpec type, ushort v, Location loc)
932 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
937 public override void Emit (EmitContext ec)
942 public override object GetValue ()
947 public override long GetValueAsLong ()
952 public override Constant Increment ()
954 return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
957 public override bool IsDefaultValue {
963 public override bool IsNegative {
969 public override bool IsOneInteger {
975 public override bool IsZeroInteger {
976 get { return Value == 0; }
979 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
981 switch (target_type.BuiltinType) {
982 case BuiltinTypeSpec.Type.Byte:
983 if (in_checked_context) {
984 if (Value > Byte.MaxValue)
985 throw new OverflowException ();
987 return new ByteConstant (target_type, (byte) Value, Location);
988 case BuiltinTypeSpec.Type.SByte:
989 if (in_checked_context) {
990 if (Value > SByte.MaxValue)
991 throw new OverflowException ();
993 return new SByteConstant (target_type, (sbyte) Value, Location);
994 case BuiltinTypeSpec.Type.Short:
995 if (in_checked_context) {
996 if (Value > Int16.MaxValue)
997 throw new OverflowException ();
999 return new ShortConstant (target_type, (short) Value, Location);
1000 case BuiltinTypeSpec.Type.Int:
1001 return new IntConstant (target_type, (int) Value, Location);
1002 case BuiltinTypeSpec.Type.UInt:
1003 return new UIntConstant (target_type, (uint) Value, Location);
1004 case BuiltinTypeSpec.Type.Long:
1005 return new LongConstant (target_type, (long) Value, Location);
1006 case BuiltinTypeSpec.Type.ULong:
1007 return new ULongConstant (target_type, (ulong) Value, Location);
1008 case BuiltinTypeSpec.Type.Float:
1009 return new FloatConstant (target_type, (float) Value, Location);
1010 case BuiltinTypeSpec.Type.Double:
1011 return new DoubleConstant (target_type, (double) Value, Location);
1012 case BuiltinTypeSpec.Type.Char:
1013 if (in_checked_context) {
1014 if (Value > Char.MaxValue)
1015 throw new OverflowException ();
1017 return new CharConstant (target_type, (char) Value, Location);
1018 case BuiltinTypeSpec.Type.Decimal:
1019 return new DecimalConstant (target_type, (decimal) Value, Location);
1026 public class IntConstant : IntegralConstant
1028 public readonly int Value;
1030 public IntConstant (BuiltinTypes types, int v, Location loc)
1031 : this (types.Int, v, loc)
1035 public IntConstant (TypeSpec type, int v, Location loc)
1041 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1046 public override void Emit (EmitContext ec)
1051 public override object GetValue ()
1056 public override long GetValueAsLong ()
1061 public override Constant Increment ()
1063 return new IntConstant (type, checked(Value + 1), loc);
1066 public override bool IsDefaultValue {
1072 public override bool IsNegative {
1078 public override bool IsOneInteger {
1084 public override bool IsZeroInteger {
1085 get { return Value == 0; }
1088 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1090 switch (target_type.BuiltinType) {
1091 case BuiltinTypeSpec.Type.Byte:
1092 if (in_checked_context) {
1093 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1094 throw new OverflowException ();
1096 return new ByteConstant (target_type, (byte) Value, Location);
1097 case BuiltinTypeSpec.Type.SByte:
1098 if (in_checked_context) {
1099 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1100 throw new OverflowException ();
1102 return new SByteConstant (target_type, (sbyte) Value, Location);
1103 case BuiltinTypeSpec.Type.Short:
1104 if (in_checked_context) {
1105 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1106 throw new OverflowException ();
1108 return new ShortConstant (target_type, (short) Value, Location);
1109 case BuiltinTypeSpec.Type.UShort:
1110 if (in_checked_context) {
1111 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1112 throw new OverflowException ();
1114 return new UShortConstant (target_type, (ushort) Value, Location);
1115 case BuiltinTypeSpec.Type.UInt:
1116 if (in_checked_context) {
1117 if (Value < UInt32.MinValue)
1118 throw new OverflowException ();
1120 return new UIntConstant (target_type, (uint) Value, Location);
1121 case BuiltinTypeSpec.Type.Long:
1122 return new LongConstant (target_type, (long) Value, Location);
1123 case BuiltinTypeSpec.Type.ULong:
1124 if (in_checked_context && Value < 0)
1125 throw new OverflowException ();
1126 return new ULongConstant (target_type, (ulong) Value, Location);
1127 case BuiltinTypeSpec.Type.Float:
1128 return new FloatConstant (target_type, (float) Value, Location);
1129 case BuiltinTypeSpec.Type.Double:
1130 return new DoubleConstant (target_type, (double) Value, Location);
1131 case BuiltinTypeSpec.Type.Char:
1132 if (in_checked_context) {
1133 if (Value < Char.MinValue || Value > Char.MaxValue)
1134 throw new OverflowException ();
1136 return new CharConstant (target_type, (char) Value, Location);
1137 case BuiltinTypeSpec.Type.Decimal:
1138 return new DecimalConstant (target_type, (decimal) Value, Location);
1144 public override Constant ConvertImplicitly (TypeSpec type)
1146 if (this.type == type)
1149 Constant c = TryImplicitIntConversion (type);
1151 return c; //.Resolve (rc);
1153 return base.ConvertImplicitly (type);
1157 /// Attempts to perform an implicit constant conversion of the IntConstant
1158 /// into a different data type using casts (See Implicit Constant
1159 /// Expression Conversions)
1161 Constant TryImplicitIntConversion (TypeSpec target_type)
1163 switch (target_type.BuiltinType) {
1164 case BuiltinTypeSpec.Type.SByte:
1165 if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1166 return new SByteConstant (target_type, (sbyte) Value, loc);
1168 case BuiltinTypeSpec.Type.Byte:
1169 if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1170 return new ByteConstant (target_type, (byte) Value, loc);
1172 case BuiltinTypeSpec.Type.Short:
1173 if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1174 return new ShortConstant (target_type, (short) Value, loc);
1176 case BuiltinTypeSpec.Type.UShort:
1177 if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1178 return new UShortConstant (target_type, (ushort) Value, loc);
1180 case BuiltinTypeSpec.Type.UInt:
1182 return new UIntConstant (target_type, (uint) Value, loc);
1184 case BuiltinTypeSpec.Type.ULong:
1186 // we can optimize this case: a positive int32
1187 // always fits on a uint64. But we need an opcode
1191 return new ULongConstant (target_type, (ulong) Value, loc);
1193 case BuiltinTypeSpec.Type.Double:
1194 return new DoubleConstant (target_type, (double) Value, loc);
1195 case BuiltinTypeSpec.Type.Float:
1196 return new FloatConstant (target_type, (float) Value, loc);
1203 public class UIntConstant : IntegralConstant {
1204 public readonly uint Value;
1206 public UIntConstant (BuiltinTypes types, uint v, Location loc)
1207 : this (types.UInt, v, loc)
1211 public UIntConstant (TypeSpec type, uint v, Location loc)
1217 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1222 public override void Emit (EmitContext ec)
1224 ec.EmitInt (unchecked ((int) Value));
1227 public override object GetValue ()
1232 public override long GetValueAsLong ()
1237 public override Constant Increment ()
1239 return new UIntConstant (type, checked(Value + 1), loc);
1242 public override bool IsDefaultValue {
1248 public override bool IsNegative {
1254 public override bool IsOneInteger {
1260 public override bool IsZeroInteger {
1261 get { return Value == 0; }
1264 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1266 switch (target_type.BuiltinType) {
1267 case BuiltinTypeSpec.Type.Byte:
1268 if (in_checked_context) {
1269 if (Value < 0 || Value > byte.MaxValue)
1270 throw new OverflowException ();
1272 return new ByteConstant (target_type, (byte) Value, Location);
1273 case BuiltinTypeSpec.Type.SByte:
1274 if (in_checked_context) {
1275 if (Value > SByte.MaxValue)
1276 throw new OverflowException ();
1278 return new SByteConstant (target_type, (sbyte) Value, Location);
1279 case BuiltinTypeSpec.Type.Short:
1280 if (in_checked_context) {
1281 if (Value > Int16.MaxValue)
1282 throw new OverflowException ();
1284 return new ShortConstant (target_type, (short) Value, Location);
1285 case BuiltinTypeSpec.Type.UShort:
1286 if (in_checked_context) {
1287 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1288 throw new OverflowException ();
1290 return new UShortConstant (target_type, (ushort) Value, Location);
1291 case BuiltinTypeSpec.Type.Int:
1292 if (in_checked_context) {
1293 if (Value > Int32.MaxValue)
1294 throw new OverflowException ();
1296 return new IntConstant (target_type, (int) Value, Location);
1297 case BuiltinTypeSpec.Type.Long:
1298 return new LongConstant (target_type, (long) Value, Location);
1299 case BuiltinTypeSpec.Type.ULong:
1300 return new ULongConstant (target_type, (ulong) Value, Location);
1301 case BuiltinTypeSpec.Type.Float:
1302 return new FloatConstant (target_type, (float) Value, Location);
1303 case BuiltinTypeSpec.Type.Double:
1304 return new DoubleConstant (target_type, (double) Value, Location);
1305 case BuiltinTypeSpec.Type.Char:
1306 if (in_checked_context) {
1307 if (Value < Char.MinValue || Value > Char.MaxValue)
1308 throw new OverflowException ();
1310 return new CharConstant (target_type, (char) Value, Location);
1311 case BuiltinTypeSpec.Type.Decimal:
1312 return new DecimalConstant (target_type, (decimal) Value, Location);
1320 public class LongConstant : IntegralConstant {
1321 public readonly long Value;
1323 public LongConstant (BuiltinTypes types, long v, Location loc)
1324 : this (types.Long, v, loc)
1328 public LongConstant (TypeSpec type, long v, Location loc)
1334 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1339 public override void Emit (EmitContext ec)
1341 ec.EmitLong (Value);
1344 public override object GetValue ()
1349 public override long GetValueAsLong ()
1354 public override Constant Increment ()
1356 return new LongConstant (type, checked(Value + 1), loc);
1359 public override bool IsDefaultValue {
1365 public override bool IsNegative {
1371 public override bool IsOneInteger {
1377 public override bool IsZeroInteger {
1378 get { return Value == 0; }
1381 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1383 switch (target_type.BuiltinType) {
1384 case BuiltinTypeSpec.Type.Byte:
1385 if (in_checked_context) {
1386 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1387 throw new OverflowException ();
1389 return new ByteConstant (target_type, (byte) Value, Location);
1390 case BuiltinTypeSpec.Type.SByte:
1391 if (in_checked_context) {
1392 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1393 throw new OverflowException ();
1395 return new SByteConstant (target_type, (sbyte) Value, Location);
1396 case BuiltinTypeSpec.Type.Short:
1397 if (in_checked_context) {
1398 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1399 throw new OverflowException ();
1401 return new ShortConstant (target_type, (short) Value, Location);
1402 case BuiltinTypeSpec.Type.UShort:
1403 if (in_checked_context) {
1404 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1405 throw new OverflowException ();
1407 return new UShortConstant (target_type, (ushort) Value, Location);
1408 case BuiltinTypeSpec.Type.Int:
1409 if (in_checked_context) {
1410 if (Value < Int32.MinValue || Value > Int32.MaxValue)
1411 throw new OverflowException ();
1413 return new IntConstant (target_type, (int) Value, Location);
1414 case BuiltinTypeSpec.Type.UInt:
1415 if (in_checked_context) {
1416 if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1417 throw new OverflowException ();
1419 return new UIntConstant (target_type, (uint) Value, Location);
1420 case BuiltinTypeSpec.Type.ULong:
1421 if (in_checked_context && Value < 0)
1422 throw new OverflowException ();
1423 return new ULongConstant (target_type, (ulong) Value, Location);
1424 case BuiltinTypeSpec.Type.Float:
1425 return new FloatConstant (target_type, (float) Value, Location);
1426 case BuiltinTypeSpec.Type.Double:
1427 return new DoubleConstant (target_type, (double) Value, Location);
1428 case BuiltinTypeSpec.Type.Char:
1429 if (in_checked_context) {
1430 if (Value < Char.MinValue || Value > Char.MaxValue)
1431 throw new OverflowException ();
1433 return new CharConstant (target_type, (char) Value, Location);
1434 case BuiltinTypeSpec.Type.Decimal:
1435 return new DecimalConstant (target_type, (decimal) Value, Location);
1441 public override Constant ConvertImplicitly (TypeSpec type)
1443 if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
1444 return new ULongConstant (type, (ulong) Value, loc);
1447 return base.ConvertImplicitly (type);
1451 public class ULongConstant : IntegralConstant {
1452 public readonly ulong Value;
1454 public ULongConstant (BuiltinTypes types, ulong v, Location loc)
1455 : this (types.ULong, v, loc)
1459 public ULongConstant (TypeSpec type, ulong v, Location loc)
1465 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1470 public override void Emit (EmitContext ec)
1472 ec.EmitLong (unchecked ((long) Value));
1475 public override object GetValue ()
1480 public override long GetValueAsLong ()
1482 return (long) Value;
1485 public override Constant Increment ()
1487 return new ULongConstant (type, checked(Value + 1), loc);
1490 public override bool IsDefaultValue {
1496 public override bool IsNegative {
1502 public override bool IsOneInteger {
1508 public override bool IsZeroInteger {
1509 get { return Value == 0; }
1512 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1514 switch (target_type.BuiltinType) {
1515 case BuiltinTypeSpec.Type.Byte:
1516 if (in_checked_context && Value > Byte.MaxValue)
1517 throw new OverflowException ();
1518 return new ByteConstant (target_type, (byte) Value, Location);
1519 case BuiltinTypeSpec.Type.SByte:
1520 if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1521 throw new OverflowException ();
1522 return new SByteConstant (target_type, (sbyte) Value, Location);
1523 case BuiltinTypeSpec.Type.Short:
1524 if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1525 throw new OverflowException ();
1526 return new ShortConstant (target_type, (short) Value, Location);
1527 case BuiltinTypeSpec.Type.UShort:
1528 if (in_checked_context && Value > UInt16.MaxValue)
1529 throw new OverflowException ();
1530 return new UShortConstant (target_type, (ushort) Value, Location);
1531 case BuiltinTypeSpec.Type.Int:
1532 if (in_checked_context && Value > UInt32.MaxValue)
1533 throw new OverflowException ();
1534 return new IntConstant (target_type, (int) Value, Location);
1535 case BuiltinTypeSpec.Type.UInt:
1536 if (in_checked_context && Value > UInt32.MaxValue)
1537 throw new OverflowException ();
1538 return new UIntConstant (target_type, (uint) Value, Location);
1539 case BuiltinTypeSpec.Type.Long:
1540 if (in_checked_context && Value > Int64.MaxValue)
1541 throw new OverflowException ();
1542 return new LongConstant (target_type, (long) Value, Location);
1543 case BuiltinTypeSpec.Type.Float:
1544 return new FloatConstant (target_type, (float) Value, Location);
1545 case BuiltinTypeSpec.Type.Double:
1546 return new DoubleConstant (target_type, (double) Value, Location);
1547 case BuiltinTypeSpec.Type.Char:
1548 if (in_checked_context && Value > Char.MaxValue)
1549 throw new OverflowException ();
1550 return new CharConstant (target_type, (char) Value, Location);
1551 case BuiltinTypeSpec.Type.Decimal:
1552 return new DecimalConstant (target_type, (decimal) Value, Location);
1560 public class FloatConstant : Constant {
1561 public readonly float Value;
1563 public FloatConstant (BuiltinTypes types, float v, Location loc)
1564 : this (types.Float, v, loc)
1568 public FloatConstant (TypeSpec type, float v, Location loc)
1572 eclass = ExprClass.Value;
1577 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1582 public override void Emit (EmitContext ec)
1584 ec.Emit (OpCodes.Ldc_R4, Value);
1587 public override object GetValue ()
1592 public override string GetValueAsLiteral ()
1594 return Value.ToString ();
1597 public override long GetValueAsLong ()
1599 throw new NotSupportedException ();
1602 public override bool IsDefaultValue {
1608 public override bool IsNegative {
1614 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1616 switch (target_type.BuiltinType) {
1617 case BuiltinTypeSpec.Type.Byte:
1618 if (in_checked_context) {
1619 if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1620 throw new OverflowException ();
1622 return new ByteConstant (target_type, (byte) Value, Location);
1623 case BuiltinTypeSpec.Type.SByte:
1624 if (in_checked_context) {
1625 if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1626 throw new OverflowException ();
1628 return new SByteConstant (target_type, (sbyte) Value, Location);
1629 case BuiltinTypeSpec.Type.Short:
1630 if (in_checked_context) {
1631 if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1632 throw new OverflowException ();
1634 return new ShortConstant (target_type, (short) Value, Location);
1635 case BuiltinTypeSpec.Type.UShort:
1636 if (in_checked_context) {
1637 if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1638 throw new OverflowException ();
1640 return new UShortConstant (target_type, (ushort) Value, Location);
1641 case BuiltinTypeSpec.Type.Int:
1642 if (in_checked_context) {
1643 if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1644 throw new OverflowException ();
1646 return new IntConstant (target_type, (int) Value, Location);
1647 case BuiltinTypeSpec.Type.UInt:
1648 if (in_checked_context) {
1649 if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1650 throw new OverflowException ();
1652 return new UIntConstant (target_type, (uint) Value, Location);
1653 case BuiltinTypeSpec.Type.Long:
1654 if (in_checked_context) {
1655 if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1656 throw new OverflowException ();
1658 return new LongConstant (target_type, (long) Value, Location);
1659 case BuiltinTypeSpec.Type.ULong:
1660 if (in_checked_context) {
1661 if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1662 throw new OverflowException ();
1664 return new ULongConstant (target_type, (ulong) Value, Location);
1665 case BuiltinTypeSpec.Type.Double:
1666 return new DoubleConstant (target_type, (double) Value, Location);
1667 case BuiltinTypeSpec.Type.Char:
1668 if (in_checked_context) {
1669 if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1670 throw new OverflowException ();
1672 return new CharConstant (target_type, (char) Value, Location);
1673 case BuiltinTypeSpec.Type.Decimal:
1674 return new DecimalConstant (target_type, (decimal) Value, Location);
1682 public class DoubleConstant : Constant
1684 public readonly double Value;
1686 public DoubleConstant (BuiltinTypes types, double v, Location loc)
1687 : this (types.Double, v, loc)
1691 public DoubleConstant (TypeSpec type, double v, Location loc)
1695 eclass = ExprClass.Value;
1700 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1705 public override void Emit (EmitContext ec)
1707 ec.Emit (OpCodes.Ldc_R8, Value);
1710 public override object GetValue ()
1715 public override string GetValueAsLiteral ()
1717 return Value.ToString ();
1720 public override long GetValueAsLong ()
1722 throw new NotSupportedException ();
1725 public override bool IsDefaultValue {
1731 public override bool IsNegative {
1737 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1739 switch (target_type.BuiltinType) {
1740 case BuiltinTypeSpec.Type.Byte:
1741 if (in_checked_context) {
1742 if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1743 throw new OverflowException ();
1745 return new ByteConstant (target_type, (byte) Value, Location);
1746 case BuiltinTypeSpec.Type.SByte:
1747 if (in_checked_context) {
1748 if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1749 throw new OverflowException ();
1751 return new SByteConstant (target_type, (sbyte) Value, Location);
1752 case BuiltinTypeSpec.Type.Short:
1753 if (in_checked_context) {
1754 if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1755 throw new OverflowException ();
1757 return new ShortConstant (target_type, (short) Value, Location);
1758 case BuiltinTypeSpec.Type.UShort:
1759 if (in_checked_context) {
1760 if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1761 throw new OverflowException ();
1763 return new UShortConstant (target_type, (ushort) Value, Location);
1764 case BuiltinTypeSpec.Type.Int:
1765 if (in_checked_context) {
1766 if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1767 throw new OverflowException ();
1769 return new IntConstant (target_type, (int) Value, Location);
1770 case BuiltinTypeSpec.Type.UInt:
1771 if (in_checked_context) {
1772 if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1773 throw new OverflowException ();
1775 return new UIntConstant (target_type, (uint) Value, Location);
1776 case BuiltinTypeSpec.Type.Long:
1777 if (in_checked_context) {
1778 if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1779 throw new OverflowException ();
1781 return new LongConstant (target_type, (long) Value, Location);
1782 case BuiltinTypeSpec.Type.ULong:
1783 if (in_checked_context) {
1784 if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1785 throw new OverflowException ();
1787 return new ULongConstant (target_type, (ulong) Value, Location);
1788 case BuiltinTypeSpec.Type.Float:
1789 return new FloatConstant (target_type, (float) Value, Location);
1790 case BuiltinTypeSpec.Type.Char:
1791 if (in_checked_context) {
1792 if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1793 throw new OverflowException ();
1795 return new CharConstant (target_type, (char) Value, Location);
1796 case BuiltinTypeSpec.Type.Decimal:
1797 return new DecimalConstant (target_type, (decimal) Value, Location);
1805 public class DecimalConstant : Constant {
1806 public readonly decimal Value;
1808 public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1809 : this (types.Decimal, d, loc)
1813 public DecimalConstant (TypeSpec type, decimal d, Location loc)
1817 eclass = ExprClass.Value;
1822 public override void Emit (EmitContext ec)
1826 int [] words = decimal.GetBits (Value);
1827 int power = (words [3] >> 16) & 0xff;
1830 if (Value <= int.MaxValue && Value >= int.MinValue) {
1831 m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1836 ec.EmitInt ((int) Value);
1837 ec.Emit (OpCodes.Newobj, m);
1841 if (Value <= long.MaxValue && Value >= long.MinValue) {
1842 m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1847 ec.EmitLong ((long) Value);
1848 ec.Emit (OpCodes.Newobj, m);
1853 ec.EmitInt (words [0]);
1854 ec.EmitInt (words [1]);
1855 ec.EmitInt (words [2]);
1858 ec.EmitInt (words [3] >> 31);
1863 m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1865 ec.Emit (OpCodes.Newobj, m);
1869 public override bool IsDefaultValue {
1875 public override bool IsNegative {
1881 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1883 switch (target_type.BuiltinType) {
1884 case BuiltinTypeSpec.Type.SByte:
1885 return new SByteConstant (target_type, (sbyte) Value, loc);
1886 case BuiltinTypeSpec.Type.Byte:
1887 return new ByteConstant (target_type, (byte) Value, loc);
1888 case BuiltinTypeSpec.Type.Short:
1889 return new ShortConstant (target_type, (short) Value, loc);
1890 case BuiltinTypeSpec.Type.UShort:
1891 return new UShortConstant (target_type, (ushort) Value, loc);
1892 case BuiltinTypeSpec.Type.Int:
1893 return new IntConstant (target_type, (int) Value, loc);
1894 case BuiltinTypeSpec.Type.UInt:
1895 return new UIntConstant (target_type, (uint) Value, loc);
1896 case BuiltinTypeSpec.Type.Long:
1897 return new LongConstant (target_type, (long) Value, loc);
1898 case BuiltinTypeSpec.Type.ULong:
1899 return new ULongConstant (target_type, (ulong) Value, loc);
1900 case BuiltinTypeSpec.Type.Char:
1901 return new CharConstant (target_type, (char) Value, loc);
1902 case BuiltinTypeSpec.Type.Float:
1903 return new FloatConstant (target_type, (float) Value, loc);
1904 case BuiltinTypeSpec.Type.Double:
1905 return new DoubleConstant (target_type, (double) Value, loc);
1911 public override object GetValue ()
1916 public override string GetValueAsLiteral ()
1918 return Value.ToString () + "M";
1921 public override long GetValueAsLong ()
1923 throw new NotSupportedException ();
1927 public class StringConstant : Constant {
1928 public readonly string Value;
1930 public StringConstant (BuiltinTypes types, string s, Location loc)
1931 : this (types.String, s, loc)
1935 public StringConstant (TypeSpec type, string s, Location loc)
1939 eclass = ExprClass.Value;
1944 public override object GetValue ()
1949 public override string GetValueAsLiteral ()
1951 // FIXME: Escape the string.
1952 return "\"" + Value + "\"";
1955 public override long GetValueAsLong ()
1957 throw new NotSupportedException ();
1960 public override void Emit (EmitContext ec)
1962 if (Value == null) {
1968 // Use string.Empty for both literals and constants even if
1969 // it's not allowed at language level
1971 if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
1972 var string_type = ec.BuiltinTypes.String;
1973 if (ec.CurrentType != string_type) {
1974 var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
1976 ec.Emit (OpCodes.Ldsfld, m);
1982 ec.Emit (OpCodes.Ldstr, Value);
1985 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1988 if (type != targetType)
1994 public override bool IsDefaultValue {
1996 return Value == null;
2000 public override bool IsNegative {
2006 public override bool IsNull {
2008 return IsDefaultValue;
2012 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2019 // Null constant can have its own type, think of `default (Foo)'
2021 public class NullConstant : Constant
2023 public NullConstant (TypeSpec type, Location loc)
2026 eclass = ExprClass.Value;
2030 public override Expression CreateExpressionTree (ResolveContext ec)
2032 if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2033 // Optimized version, also avoids referencing literal internal type
2034 Arguments args = new Arguments (1);
2035 args.Add (new Argument (this));
2036 return CreateExpressionFactoryCall (ec, "Constant", args);
2039 return base.CreateExpressionTree (ec);
2042 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2044 switch (targetType.BuiltinType) {
2045 case BuiltinTypeSpec.Type.Object:
2046 // Type it as string cast
2047 enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2048 goto case BuiltinTypeSpec.Type.String;
2049 case BuiltinTypeSpec.Type.String:
2050 case BuiltinTypeSpec.Type.Type:
2051 enc.Encode (byte.MaxValue);
2054 var ac = targetType as ArrayContainer;
2055 if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
2056 enc.Encode (uint.MaxValue);
2063 base.EncodeAttributeValue (rc, enc, targetType);
2066 public override void Emit (EmitContext ec)
2070 // Only to make verifier happy
2071 if (type.IsGenericParameter)
2072 ec.Emit (OpCodes.Unbox_Any, type);
2075 public override string ExprClassName {
2077 return GetSignatureForError ();
2081 public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2083 if (targetType.IsPointer) {
2084 if (IsLiteral || this is NullPointer)
2085 return new NullPointer (targetType, loc);
2090 // Exlude internal compiler types
2091 if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2094 if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2097 if (TypeSpec.IsReferenceType (targetType))
2098 return new NullConstant (targetType, loc);
2100 if (targetType.IsNullableType)
2101 return Nullable.LiftedNull.Create (targetType, loc);
2106 public override Constant ConvertImplicitly (TypeSpec targetType)
2108 return ConvertExplicitly (false, targetType);
2111 public override string GetSignatureForError ()
2116 public override object GetValue ()
2121 public override string GetValueAsLiteral ()
2123 return GetSignatureForError ();
2126 public override long GetValueAsLong ()
2128 throw new NotSupportedException ();
2131 public override bool IsDefaultValue {
2132 get { return true; }
2135 public override bool IsNegative {
2136 get { return false; }
2139 public override bool IsNull {
2140 get { return true; }
2143 public override bool IsZeroInteger {
2144 get { return true; }
2150 // A null constant in a pointer context
2152 class NullPointer : NullConstant
2154 public NullPointer (TypeSpec type, Location loc)
2159 public override Expression CreateExpressionTree (ResolveContext ec)
2161 Error_PointerInsideExpressionTree (ec);
2162 return base.CreateExpressionTree (ec);
2165 public override void Emit (EmitContext ec)
2168 // Emits null pointer
2171 ec.Emit (OpCodes.Conv_U);
2176 /// The value is constant, but when emitted has a side effect. This is
2177 /// used by BitwiseAnd to ensure that the second expression is invoked
2178 /// regardless of the value of the left side.
2180 public class SideEffectConstant : Constant
2182 public readonly Constant value;
2183 Expression side_effect;
2185 public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2190 eclass = ExprClass.Value;
2192 while (side_effect is SideEffectConstant)
2193 side_effect = ((SideEffectConstant) side_effect).side_effect;
2194 this.side_effect = side_effect;
2197 public override bool IsSideEffectFree {
2203 public override object GetValue ()
2205 return value.GetValue ();
2208 public override string GetValueAsLiteral ()
2210 return value.GetValueAsLiteral ();
2213 public override long GetValueAsLong ()
2215 return value.GetValueAsLong ();
2218 public override void Emit (EmitContext ec)
2220 side_effect.EmitSideEffect (ec);
2224 public override void EmitSideEffect (EmitContext ec)
2226 side_effect.EmitSideEffect (ec);
2227 value.EmitSideEffect (ec);
2230 public override bool IsDefaultValue {
2231 get { return value.IsDefaultValue; }
2234 public override bool IsNegative {
2235 get { return value.IsNegative; }
2238 public override bool IsZeroInteger {
2239 get { return value.IsZeroInteger; }
2242 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2244 Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2245 if (new_value == null)
2248 var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2249 c.type = target_type;