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);
163 throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'",
164 v, TypeManager.CSharpName (t));
167 public override Expression CreateExpressionTree (ResolveContext ec)
169 Arguments args = new Arguments (2);
170 args.Add (new Argument (this));
171 args.Add (new Argument (new TypeOf (type, loc)));
173 return CreateExpressionFactoryCall (ec, "Constant", args);
177 /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
178 /// It throws OverflowException
180 // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
181 public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
183 // This is a custom version of Convert.ChangeType() which works
184 // with the TypeBuilder defined types when compiling corlib.
185 static object ChangeType (object value, TypeSpec targetType, out bool error)
187 IConvertible convert_value = value as IConvertible;
189 if (convert_value == null) {
195 // We cannot rely on build-in type conversions as they are
196 // more limited than what C# supports.
197 // See char -> float/decimal/double conversion
201 switch (targetType.BuiltinType) {
202 case BuiltinTypeSpec.Type.Bool:
203 return convert_value.ToBoolean (nfi);
204 case BuiltinTypeSpec.Type.Byte:
205 return convert_value.ToByte (nfi);
206 case BuiltinTypeSpec.Type.Char:
207 return convert_value.ToChar (nfi);
208 case BuiltinTypeSpec.Type.Short:
209 return convert_value.ToInt16 (nfi);
210 case BuiltinTypeSpec.Type.Int:
211 return convert_value.ToInt32 (nfi);
212 case BuiltinTypeSpec.Type.Long:
213 return convert_value.ToInt64 (nfi);
214 case BuiltinTypeSpec.Type.SByte:
215 return convert_value.ToSByte (nfi);
216 case BuiltinTypeSpec.Type.Decimal:
217 if (convert_value.GetType () == typeof (char))
218 return (decimal) convert_value.ToInt32 (nfi);
219 return convert_value.ToDecimal (nfi);
220 case BuiltinTypeSpec.Type.Double:
221 if (convert_value.GetType () == typeof (char))
222 return (double) convert_value.ToInt32 (nfi);
223 return convert_value.ToDouble (nfi);
224 case BuiltinTypeSpec.Type.Float:
225 if (convert_value.GetType () == typeof (char))
226 return (float) convert_value.ToInt32 (nfi);
227 return convert_value.ToSingle (nfi);
228 case BuiltinTypeSpec.Type.String:
229 return convert_value.ToString (nfi);
230 case BuiltinTypeSpec.Type.UShort:
231 return convert_value.ToUInt16 (nfi);
232 case BuiltinTypeSpec.Type.UInt:
233 return convert_value.ToUInt32 (nfi);
234 case BuiltinTypeSpec.Type.ULong:
235 return convert_value.ToUInt64 (nfi);
236 case BuiltinTypeSpec.Type.Object:
246 protected override Expression DoResolve (ResolveContext rc)
252 /// Attempts to do a compile-time folding of a constant cast.
254 public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
257 return TryReduce (ec, target_type);
259 catch (OverflowException) {
260 if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
261 ec.Report.Error (221, loc,
262 "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
263 GetValueAsLiteral (), target_type.GetSignatureForError ());
265 Error_ValueCannotBeConverted (ec, loc, target_type, false);
268 return New.Constantify (target_type, loc);
272 Constant TryReduce (ResolveContext ec, TypeSpec target_type)
274 if (Type == target_type)
278 if (target_type.IsEnum) {
279 c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
283 return new EnumConstant (c, target_type);
286 return ConvertExplicitly (ec.ConstantCheckState, target_type);
290 /// Need to pass type as the constant can require a boxing
291 /// and in such case no optimization is possible
293 public bool IsDefaultInitializer (TypeSpec type)
296 return IsDefaultValue;
298 return this is NullLiteral;
301 public abstract bool IsDefaultValue {
305 public abstract bool IsNegative {
310 // When constant is declared as literal
312 public virtual bool IsLiteral {
313 get { return false; }
316 public virtual bool IsOneInteger {
317 get { return false; }
320 public override bool IsSideEffectFree {
327 // Returns true iff 1) the stack type of this is one of Object,
328 // int32, int64 and 2) this == 0 or this == null.
330 public virtual bool IsZeroInteger {
331 get { return false; }
334 public override void EmitSideEffect (EmitContext ec)
339 public sealed override Expression Clone (CloneContext clonectx)
341 // No cloning is not needed for constants
345 protected override void CloneTo (CloneContext clonectx, Expression target)
347 throw new NotSupportedException ("should not be reached");
350 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
353 return base.MakeExpression (ctx);
355 return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
359 public new bool Resolve (ResolveContext rc)
361 // It exists only as hint not to call Resolve on constants
366 public abstract class IntegralConstant : Constant
368 protected IntegralConstant (TypeSpec type, Location loc)
372 eclass = ExprClass.Value;
375 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
378 ConvertExplicitly (true, target);
379 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
383 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
384 GetValue ().ToString (), TypeManager.CSharpName (target));
388 public override string GetValueAsLiteral ()
390 return GetValue ().ToString ();
393 public abstract Constant Increment ();
396 public class BoolConstant : Constant {
397 public readonly bool Value;
399 public BoolConstant (BuiltinTypes types, bool val, Location loc)
400 : this (types.Bool, val, loc)
404 public BoolConstant (TypeSpec type, bool val, Location loc)
407 eclass = ExprClass.Value;
413 public override object GetValue ()
415 return (object) Value;
418 public override string GetValueAsLiteral ()
420 return Value ? "true" : "false";
423 public override long GetValueAsLong ()
425 return Value ? 1 : 0;
428 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
433 public override void Emit (EmitContext ec)
441 public override bool IsDefaultValue {
447 public override bool IsNegative {
453 public override bool IsZeroInteger {
454 get { return Value == false; }
457 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
464 public class ByteConstant : IntegralConstant
466 public readonly byte Value;
468 public ByteConstant (BuiltinTypes types, byte v, Location loc)
469 : this (types.Byte, v, loc)
473 public ByteConstant (TypeSpec type, byte v, Location loc)
479 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
484 public override void Emit (EmitContext ec)
489 public override object GetValue ()
494 public override long GetValueAsLong ()
499 public override Constant Increment ()
501 return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
504 public override bool IsDefaultValue {
510 public override bool IsOneInteger {
516 public override bool IsNegative {
522 public override bool IsZeroInteger {
523 get { return Value == 0; }
526 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
528 switch (target_type.BuiltinType) {
529 case BuiltinTypeSpec.Type.SByte:
530 if (in_checked_context){
531 if (Value > SByte.MaxValue)
532 throw new OverflowException ();
534 return new SByteConstant (target_type, (sbyte) Value, Location);
535 case BuiltinTypeSpec.Type.Short:
536 return new ShortConstant (target_type, (short) Value, Location);
537 case BuiltinTypeSpec.Type.UShort:
538 return new UShortConstant (target_type, (ushort) Value, Location);
539 case BuiltinTypeSpec.Type.Int:
540 return new IntConstant (target_type, (int) Value, Location);
541 case BuiltinTypeSpec.Type.UInt:
542 return new UIntConstant (target_type, (uint) Value, Location);
543 case BuiltinTypeSpec.Type.Long:
544 return new LongConstant (target_type, (long) Value, Location);
545 case BuiltinTypeSpec.Type.ULong:
546 return new ULongConstant (target_type, (ulong) Value, Location);
547 case BuiltinTypeSpec.Type.Float:
548 return new FloatConstant (target_type, (float) Value, Location);
549 case BuiltinTypeSpec.Type.Double:
550 return new DoubleConstant (target_type, (double) Value, Location);
551 case BuiltinTypeSpec.Type.Char:
552 return new CharConstant (target_type, (char) Value, Location);
553 case BuiltinTypeSpec.Type.Decimal:
554 return new DecimalConstant (target_type, (decimal) Value, Location);
562 public class CharConstant : Constant {
563 public readonly char Value;
565 public CharConstant (BuiltinTypes types, char v, Location loc)
566 : this (types.Char, v, loc)
570 public CharConstant (TypeSpec type, char v, Location loc)
574 eclass = ExprClass.Value;
579 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
581 enc.Encode ((ushort) Value);
584 public override void Emit (EmitContext ec)
589 static string descape (char c)
615 return c.ToString ();
618 public override object GetValue ()
623 public override long GetValueAsLong ()
628 public override string GetValueAsLiteral ()
630 return "\"" + descape (Value) + "\"";
633 public override bool IsDefaultValue {
639 public override bool IsNegative {
645 public override bool IsZeroInteger {
646 get { return Value == '\0'; }
649 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
651 switch (target_type.BuiltinType) {
652 case BuiltinTypeSpec.Type.Byte:
653 if (in_checked_context) {
654 if (Value < Byte.MinValue || Value > Byte.MaxValue)
655 throw new OverflowException ();
657 return new ByteConstant (target_type, (byte) Value, Location);
658 case BuiltinTypeSpec.Type.SByte:
659 if (in_checked_context) {
660 if (Value > SByte.MaxValue)
661 throw new OverflowException ();
663 return new SByteConstant (target_type, (sbyte) Value, Location);
665 case BuiltinTypeSpec.Type.Short:
666 if (in_checked_context) {
667 if (Value > Int16.MaxValue)
668 throw new OverflowException ();
670 return new ShortConstant (target_type, (short) Value, Location);
671 case BuiltinTypeSpec.Type.Int:
672 return new IntConstant (target_type, (int) Value, Location);
673 case BuiltinTypeSpec.Type.UInt:
674 return new UIntConstant (target_type, (uint) Value, Location);
675 case BuiltinTypeSpec.Type.Long:
676 return new LongConstant (target_type, (long) Value, Location);
677 case BuiltinTypeSpec.Type.ULong:
678 return new ULongConstant (target_type, (ulong) Value, Location);
679 case BuiltinTypeSpec.Type.Float:
680 return new FloatConstant (target_type, (float) Value, Location);
681 case BuiltinTypeSpec.Type.Double:
682 return new DoubleConstant (target_type, (double) Value, Location);
683 case BuiltinTypeSpec.Type.Decimal:
684 return new DecimalConstant (target_type, (decimal) Value, Location);
692 public class SByteConstant : IntegralConstant
694 public readonly sbyte Value;
696 public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
697 : this (types.SByte, v, loc)
701 public SByteConstant (TypeSpec type, sbyte v, Location loc)
707 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
712 public override void Emit (EmitContext ec)
717 public override object GetValue ()
722 public override long GetValueAsLong ()
727 public override Constant Increment ()
729 return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
732 public override bool IsDefaultValue {
738 public override bool IsNegative {
744 public override bool IsOneInteger {
750 public override bool IsZeroInteger {
751 get { return Value == 0; }
754 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
756 switch (target_type.BuiltinType) {
757 case BuiltinTypeSpec.Type.Byte:
758 if (in_checked_context && Value < 0)
759 throw new OverflowException ();
760 return new ByteConstant (target_type, (byte) Value, Location);
761 case BuiltinTypeSpec.Type.Short:
762 return new ShortConstant (target_type, (short) Value, Location);
763 case BuiltinTypeSpec.Type.UShort:
764 if (in_checked_context && Value < 0)
765 throw new OverflowException ();
766 return new UShortConstant (target_type, (ushort) Value, Location);
767 case BuiltinTypeSpec.Type.Int:
768 return new IntConstant (target_type, (int) Value, Location);
769 case BuiltinTypeSpec.Type.UInt:
770 if (in_checked_context && Value < 0)
771 throw new OverflowException ();
772 return new UIntConstant (target_type, (uint) Value, Location);
773 case BuiltinTypeSpec.Type.Long:
774 return new LongConstant (target_type, (long) Value, Location);
775 case BuiltinTypeSpec.Type.ULong:
776 if (in_checked_context && Value < 0)
777 throw new OverflowException ();
778 return new ULongConstant (target_type, (ulong) Value, Location);
779 case BuiltinTypeSpec.Type.Float:
780 return new FloatConstant (target_type, (float) Value, Location);
781 case BuiltinTypeSpec.Type.Double:
782 return new DoubleConstant (target_type, (double) Value, Location);
783 case BuiltinTypeSpec.Type.Char:
784 if (in_checked_context && Value < 0)
785 throw new OverflowException ();
786 return new CharConstant (target_type, (char) Value, Location);
787 case BuiltinTypeSpec.Type.Decimal:
788 return new DecimalConstant (target_type, (decimal) Value, Location);
796 public class ShortConstant : IntegralConstant {
797 public readonly short Value;
799 public ShortConstant (BuiltinTypes types, short v, Location loc)
800 : this (types.Short, v, loc)
804 public ShortConstant (TypeSpec type, short v, Location loc)
810 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
815 public override void Emit (EmitContext ec)
820 public override object GetValue ()
825 public override long GetValueAsLong ()
830 public override Constant Increment ()
832 return new ShortConstant (type, checked((short)(Value + 1)), loc);
835 public override bool IsDefaultValue {
841 public override bool IsZeroInteger {
842 get { return Value == 0; }
845 public override bool IsNegative {
851 public override bool IsOneInteger {
857 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
859 switch (target_type.BuiltinType) {
860 case BuiltinTypeSpec.Type.Byte:
861 if (in_checked_context) {
862 if (Value < Byte.MinValue || Value > Byte.MaxValue)
863 throw new OverflowException ();
865 return new ByteConstant (target_type, (byte) Value, Location);
866 case BuiltinTypeSpec.Type.SByte:
867 if (in_checked_context) {
868 if (Value < SByte.MinValue || Value > SByte.MaxValue)
869 throw new OverflowException ();
871 return new SByteConstant (target_type, (sbyte) Value, Location);
872 case BuiltinTypeSpec.Type.UShort:
873 if (in_checked_context && Value < 0)
874 throw new OverflowException ();
876 return new UShortConstant (target_type, (ushort) Value, Location);
877 case BuiltinTypeSpec.Type.Int:
878 return new IntConstant (target_type, (int) Value, Location);
879 case BuiltinTypeSpec.Type.UInt:
880 if (in_checked_context && Value < 0)
881 throw new OverflowException ();
882 return new UIntConstant (target_type, (uint) Value, Location);
883 case BuiltinTypeSpec.Type.Long:
884 return new LongConstant (target_type, (long) Value, Location);
885 case BuiltinTypeSpec.Type.ULong:
886 if (in_checked_context && Value < 0)
887 throw new OverflowException ();
888 return new ULongConstant (target_type, (ulong) Value, Location);
889 case BuiltinTypeSpec.Type.Float:
890 return new FloatConstant (target_type, (float) Value, Location);
891 case BuiltinTypeSpec.Type.Double:
892 return new DoubleConstant (target_type, (double) Value, Location);
893 case BuiltinTypeSpec.Type.Char:
894 if (in_checked_context) {
895 if (Value < Char.MinValue)
896 throw new OverflowException ();
898 return new CharConstant (target_type, (char) Value, Location);
899 case BuiltinTypeSpec.Type.Decimal:
900 return new DecimalConstant (target_type, (decimal) Value, Location);
908 public class UShortConstant : IntegralConstant
910 public readonly ushort Value;
912 public UShortConstant (BuiltinTypes types, ushort v, Location loc)
913 : this (types.UShort, v, loc)
917 public UShortConstant (TypeSpec type, ushort v, Location loc)
923 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
928 public override void Emit (EmitContext ec)
933 public override object GetValue ()
938 public override long GetValueAsLong ()
943 public override Constant Increment ()
945 return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
948 public override bool IsDefaultValue {
954 public override bool IsNegative {
960 public override bool IsOneInteger {
966 public override bool IsZeroInteger {
967 get { return Value == 0; }
970 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
972 switch (target_type.BuiltinType) {
973 case BuiltinTypeSpec.Type.Byte:
974 if (in_checked_context) {
975 if (Value > Byte.MaxValue)
976 throw new OverflowException ();
978 return new ByteConstant (target_type, (byte) Value, Location);
979 case BuiltinTypeSpec.Type.SByte:
980 if (in_checked_context) {
981 if (Value > SByte.MaxValue)
982 throw new OverflowException ();
984 return new SByteConstant (target_type, (sbyte) Value, Location);
985 case BuiltinTypeSpec.Type.Short:
986 if (in_checked_context) {
987 if (Value > Int16.MaxValue)
988 throw new OverflowException ();
990 return new ShortConstant (target_type, (short) Value, Location);
991 case BuiltinTypeSpec.Type.Int:
992 return new IntConstant (target_type, (int) Value, Location);
993 case BuiltinTypeSpec.Type.UInt:
994 return new UIntConstant (target_type, (uint) Value, Location);
995 case BuiltinTypeSpec.Type.Long:
996 return new LongConstant (target_type, (long) Value, Location);
997 case BuiltinTypeSpec.Type.ULong:
998 return new ULongConstant (target_type, (ulong) Value, Location);
999 case BuiltinTypeSpec.Type.Float:
1000 return new FloatConstant (target_type, (float) Value, Location);
1001 case BuiltinTypeSpec.Type.Double:
1002 return new DoubleConstant (target_type, (double) Value, Location);
1003 case BuiltinTypeSpec.Type.Char:
1004 if (in_checked_context) {
1005 if (Value > Char.MaxValue)
1006 throw new OverflowException ();
1008 return new CharConstant (target_type, (char) Value, Location);
1009 case BuiltinTypeSpec.Type.Decimal:
1010 return new DecimalConstant (target_type, (decimal) Value, Location);
1017 public class IntConstant : IntegralConstant
1019 public readonly int Value;
1021 public IntConstant (BuiltinTypes types, int v, Location loc)
1022 : this (types.Int, v, loc)
1026 public IntConstant (TypeSpec type, int v, Location loc)
1032 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1037 public override void Emit (EmitContext ec)
1042 public override object GetValue ()
1047 public override long GetValueAsLong ()
1052 public override Constant Increment ()
1054 return new IntConstant (type, checked(Value + 1), loc);
1057 public override bool IsDefaultValue {
1063 public override bool IsNegative {
1069 public override bool IsOneInteger {
1075 public override bool IsZeroInteger {
1076 get { return Value == 0; }
1079 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1081 switch (target_type.BuiltinType) {
1082 case BuiltinTypeSpec.Type.Byte:
1083 if (in_checked_context) {
1084 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1085 throw new OverflowException ();
1087 return new ByteConstant (target_type, (byte) Value, Location);
1088 case BuiltinTypeSpec.Type.SByte:
1089 if (in_checked_context) {
1090 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1091 throw new OverflowException ();
1093 return new SByteConstant (target_type, (sbyte) Value, Location);
1094 case BuiltinTypeSpec.Type.Short:
1095 if (in_checked_context) {
1096 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1097 throw new OverflowException ();
1099 return new ShortConstant (target_type, (short) Value, Location);
1100 case BuiltinTypeSpec.Type.UShort:
1101 if (in_checked_context) {
1102 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1103 throw new OverflowException ();
1105 return new UShortConstant (target_type, (ushort) Value, Location);
1106 case BuiltinTypeSpec.Type.UInt:
1107 if (in_checked_context) {
1108 if (Value < UInt32.MinValue)
1109 throw new OverflowException ();
1111 return new UIntConstant (target_type, (uint) Value, Location);
1112 case BuiltinTypeSpec.Type.Long:
1113 return new LongConstant (target_type, (long) Value, Location);
1114 case BuiltinTypeSpec.Type.ULong:
1115 if (in_checked_context && Value < 0)
1116 throw new OverflowException ();
1117 return new ULongConstant (target_type, (ulong) Value, Location);
1118 case BuiltinTypeSpec.Type.Float:
1119 return new FloatConstant (target_type, (float) Value, Location);
1120 case BuiltinTypeSpec.Type.Double:
1121 return new DoubleConstant (target_type, (double) Value, Location);
1122 case BuiltinTypeSpec.Type.Char:
1123 if (in_checked_context) {
1124 if (Value < Char.MinValue || Value > Char.MaxValue)
1125 throw new OverflowException ();
1127 return new CharConstant (target_type, (char) Value, Location);
1128 case BuiltinTypeSpec.Type.Decimal:
1129 return new DecimalConstant (target_type, (decimal) Value, Location);
1135 public override Constant ConvertImplicitly (TypeSpec type)
1137 if (this.type == type)
1140 Constant c = TryImplicitIntConversion (type);
1142 return c; //.Resolve (rc);
1144 return base.ConvertImplicitly (type);
1148 /// Attempts to perform an implicit constant conversion of the IntConstant
1149 /// into a different data type using casts (See Implicit Constant
1150 /// Expression Conversions)
1152 Constant TryImplicitIntConversion (TypeSpec target_type)
1154 switch (target_type.BuiltinType) {
1155 case BuiltinTypeSpec.Type.SByte:
1156 if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1157 return new SByteConstant (target_type, (sbyte) Value, loc);
1159 case BuiltinTypeSpec.Type.Byte:
1160 if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1161 return new ByteConstant (target_type, (byte) Value, loc);
1163 case BuiltinTypeSpec.Type.Short:
1164 if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1165 return new ShortConstant (target_type, (short) Value, loc);
1167 case BuiltinTypeSpec.Type.UShort:
1168 if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1169 return new UShortConstant (target_type, (ushort) Value, loc);
1171 case BuiltinTypeSpec.Type.UInt:
1173 return new UIntConstant (target_type, (uint) Value, loc);
1175 case BuiltinTypeSpec.Type.ULong:
1177 // we can optimize this case: a positive int32
1178 // always fits on a uint64. But we need an opcode
1182 return new ULongConstant (target_type, (ulong) Value, loc);
1184 case BuiltinTypeSpec.Type.Double:
1185 return new DoubleConstant (target_type, (double) Value, loc);
1186 case BuiltinTypeSpec.Type.Float:
1187 return new FloatConstant (target_type, (float) Value, loc);
1194 public class UIntConstant : IntegralConstant {
1195 public readonly uint Value;
1197 public UIntConstant (BuiltinTypes types, uint v, Location loc)
1198 : this (types.UInt, v, loc)
1202 public UIntConstant (TypeSpec type, uint v, Location loc)
1208 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1213 public override void Emit (EmitContext ec)
1215 ec.EmitInt (unchecked ((int) Value));
1218 public override object GetValue ()
1223 public override long GetValueAsLong ()
1228 public override Constant Increment ()
1230 return new UIntConstant (type, checked(Value + 1), loc);
1233 public override bool IsDefaultValue {
1239 public override bool IsNegative {
1245 public override bool IsOneInteger {
1251 public override bool IsZeroInteger {
1252 get { return Value == 0; }
1255 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1257 switch (target_type.BuiltinType) {
1258 case BuiltinTypeSpec.Type.Byte:
1259 if (in_checked_context) {
1260 if (Value < 0 || Value > byte.MaxValue)
1261 throw new OverflowException ();
1263 return new ByteConstant (target_type, (byte) Value, Location);
1264 case BuiltinTypeSpec.Type.SByte:
1265 if (in_checked_context) {
1266 if (Value > SByte.MaxValue)
1267 throw new OverflowException ();
1269 return new SByteConstant (target_type, (sbyte) Value, Location);
1270 case BuiltinTypeSpec.Type.Short:
1271 if (in_checked_context) {
1272 if (Value > Int16.MaxValue)
1273 throw new OverflowException ();
1275 return new ShortConstant (target_type, (short) Value, Location);
1276 case BuiltinTypeSpec.Type.UShort:
1277 if (in_checked_context) {
1278 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1279 throw new OverflowException ();
1281 return new UShortConstant (target_type, (ushort) Value, Location);
1282 case BuiltinTypeSpec.Type.Int:
1283 if (in_checked_context) {
1284 if (Value > Int32.MaxValue)
1285 throw new OverflowException ();
1287 return new IntConstant (target_type, (int) Value, Location);
1288 case BuiltinTypeSpec.Type.Long:
1289 return new LongConstant (target_type, (long) Value, Location);
1290 case BuiltinTypeSpec.Type.ULong:
1291 return new ULongConstant (target_type, (ulong) Value, Location);
1292 case BuiltinTypeSpec.Type.Float:
1293 return new FloatConstant (target_type, (float) Value, Location);
1294 case BuiltinTypeSpec.Type.Double:
1295 return new DoubleConstant (target_type, (double) Value, Location);
1296 case BuiltinTypeSpec.Type.Char:
1297 if (in_checked_context) {
1298 if (Value < Char.MinValue || Value > Char.MaxValue)
1299 throw new OverflowException ();
1301 return new CharConstant (target_type, (char) Value, Location);
1302 case BuiltinTypeSpec.Type.Decimal:
1303 return new DecimalConstant (target_type, (decimal) Value, Location);
1311 public class LongConstant : IntegralConstant {
1312 public readonly long Value;
1314 public LongConstant (BuiltinTypes types, long v, Location loc)
1315 : this (types.Long, v, loc)
1319 public LongConstant (TypeSpec type, long v, Location loc)
1325 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1330 public override void Emit (EmitContext ec)
1332 ec.EmitLong (Value);
1335 public override object GetValue ()
1340 public override long GetValueAsLong ()
1345 public override Constant Increment ()
1347 return new LongConstant (type, checked(Value + 1), loc);
1350 public override bool IsDefaultValue {
1356 public override bool IsNegative {
1362 public override bool IsOneInteger {
1368 public override bool IsZeroInteger {
1369 get { return Value == 0; }
1372 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1374 switch (target_type.BuiltinType) {
1375 case BuiltinTypeSpec.Type.Byte:
1376 if (in_checked_context) {
1377 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1378 throw new OverflowException ();
1380 return new ByteConstant (target_type, (byte) Value, Location);
1381 case BuiltinTypeSpec.Type.SByte:
1382 if (in_checked_context) {
1383 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1384 throw new OverflowException ();
1386 return new SByteConstant (target_type, (sbyte) Value, Location);
1387 case BuiltinTypeSpec.Type.Short:
1388 if (in_checked_context) {
1389 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1390 throw new OverflowException ();
1392 return new ShortConstant (target_type, (short) Value, Location);
1393 case BuiltinTypeSpec.Type.UShort:
1394 if (in_checked_context) {
1395 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1396 throw new OverflowException ();
1398 return new UShortConstant (target_type, (ushort) Value, Location);
1399 case BuiltinTypeSpec.Type.Int:
1400 if (in_checked_context) {
1401 if (Value < Int32.MinValue || Value > Int32.MaxValue)
1402 throw new OverflowException ();
1404 return new IntConstant (target_type, (int) Value, Location);
1405 case BuiltinTypeSpec.Type.UInt:
1406 if (in_checked_context) {
1407 if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1408 throw new OverflowException ();
1410 return new UIntConstant (target_type, (uint) Value, Location);
1411 case BuiltinTypeSpec.Type.ULong:
1412 if (in_checked_context && Value < 0)
1413 throw new OverflowException ();
1414 return new ULongConstant (target_type, (ulong) Value, Location);
1415 case BuiltinTypeSpec.Type.Float:
1416 return new FloatConstant (target_type, (float) Value, Location);
1417 case BuiltinTypeSpec.Type.Double:
1418 return new DoubleConstant (target_type, (double) Value, Location);
1419 case BuiltinTypeSpec.Type.Char:
1420 if (in_checked_context) {
1421 if (Value < Char.MinValue || Value > Char.MaxValue)
1422 throw new OverflowException ();
1424 return new CharConstant (target_type, (char) Value, Location);
1425 case BuiltinTypeSpec.Type.Decimal:
1426 return new DecimalConstant (target_type, (decimal) Value, Location);
1432 public override Constant ConvertImplicitly (TypeSpec type)
1434 if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
1435 return new ULongConstant (type, (ulong) Value, loc);
1438 return base.ConvertImplicitly (type);
1442 public class ULongConstant : IntegralConstant {
1443 public readonly ulong Value;
1445 public ULongConstant (BuiltinTypes types, ulong v, Location loc)
1446 : this (types.ULong, v, loc)
1450 public ULongConstant (TypeSpec type, ulong v, Location loc)
1456 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1461 public override void Emit (EmitContext ec)
1463 ec.EmitLong (unchecked ((long) Value));
1466 public override object GetValue ()
1471 public override long GetValueAsLong ()
1473 return (long) Value;
1476 public override Constant Increment ()
1478 return new ULongConstant (type, checked(Value + 1), loc);
1481 public override bool IsDefaultValue {
1487 public override bool IsNegative {
1493 public override bool IsOneInteger {
1499 public override bool IsZeroInteger {
1500 get { return Value == 0; }
1503 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1505 switch (target_type.BuiltinType) {
1506 case BuiltinTypeSpec.Type.Byte:
1507 if (in_checked_context && Value > Byte.MaxValue)
1508 throw new OverflowException ();
1509 return new ByteConstant (target_type, (byte) Value, Location);
1510 case BuiltinTypeSpec.Type.SByte:
1511 if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1512 throw new OverflowException ();
1513 return new SByteConstant (target_type, (sbyte) Value, Location);
1514 case BuiltinTypeSpec.Type.Short:
1515 if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1516 throw new OverflowException ();
1517 return new ShortConstant (target_type, (short) Value, Location);
1518 case BuiltinTypeSpec.Type.UShort:
1519 if (in_checked_context && Value > UInt16.MaxValue)
1520 throw new OverflowException ();
1521 return new UShortConstant (target_type, (ushort) Value, Location);
1522 case BuiltinTypeSpec.Type.Int:
1523 if (in_checked_context && Value > UInt32.MaxValue)
1524 throw new OverflowException ();
1525 return new IntConstant (target_type, (int) Value, Location);
1526 case BuiltinTypeSpec.Type.UInt:
1527 if (in_checked_context && Value > UInt32.MaxValue)
1528 throw new OverflowException ();
1529 return new UIntConstant (target_type, (uint) Value, Location);
1530 case BuiltinTypeSpec.Type.Long:
1531 if (in_checked_context && Value > Int64.MaxValue)
1532 throw new OverflowException ();
1533 return new LongConstant (target_type, (long) Value, Location);
1534 case BuiltinTypeSpec.Type.Float:
1535 return new FloatConstant (target_type, (float) Value, Location);
1536 case BuiltinTypeSpec.Type.Double:
1537 return new DoubleConstant (target_type, (double) Value, Location);
1538 case BuiltinTypeSpec.Type.Char:
1539 if (in_checked_context && Value > Char.MaxValue)
1540 throw new OverflowException ();
1541 return new CharConstant (target_type, (char) Value, Location);
1542 case BuiltinTypeSpec.Type.Decimal:
1543 return new DecimalConstant (target_type, (decimal) Value, Location);
1551 public class FloatConstant : Constant {
1552 public readonly float Value;
1554 public FloatConstant (BuiltinTypes types, float v, Location loc)
1555 : this (types.Float, v, loc)
1559 public FloatConstant (TypeSpec type, float v, Location loc)
1563 eclass = ExprClass.Value;
1568 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1573 public override void Emit (EmitContext ec)
1575 ec.Emit (OpCodes.Ldc_R4, Value);
1578 public override object GetValue ()
1583 public override string GetValueAsLiteral ()
1585 return Value.ToString ();
1588 public override long GetValueAsLong ()
1590 throw new NotSupportedException ();
1593 public override bool IsDefaultValue {
1599 public override bool IsNegative {
1605 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1607 switch (target_type.BuiltinType) {
1608 case BuiltinTypeSpec.Type.Byte:
1609 if (in_checked_context) {
1610 if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1611 throw new OverflowException ();
1613 return new ByteConstant (target_type, (byte) Value, Location);
1614 case BuiltinTypeSpec.Type.SByte:
1615 if (in_checked_context) {
1616 if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1617 throw new OverflowException ();
1619 return new SByteConstant (target_type, (sbyte) Value, Location);
1620 case BuiltinTypeSpec.Type.Short:
1621 if (in_checked_context) {
1622 if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1623 throw new OverflowException ();
1625 return new ShortConstant (target_type, (short) Value, Location);
1626 case BuiltinTypeSpec.Type.UShort:
1627 if (in_checked_context) {
1628 if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1629 throw new OverflowException ();
1631 return new UShortConstant (target_type, (ushort) Value, Location);
1632 case BuiltinTypeSpec.Type.Int:
1633 if (in_checked_context) {
1634 if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1635 throw new OverflowException ();
1637 return new IntConstant (target_type, (int) Value, Location);
1638 case BuiltinTypeSpec.Type.UInt:
1639 if (in_checked_context) {
1640 if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1641 throw new OverflowException ();
1643 return new UIntConstant (target_type, (uint) Value, Location);
1644 case BuiltinTypeSpec.Type.Long:
1645 if (in_checked_context) {
1646 if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1647 throw new OverflowException ();
1649 return new LongConstant (target_type, (long) Value, Location);
1650 case BuiltinTypeSpec.Type.ULong:
1651 if (in_checked_context) {
1652 if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1653 throw new OverflowException ();
1655 return new ULongConstant (target_type, (ulong) Value, Location);
1656 case BuiltinTypeSpec.Type.Double:
1657 return new DoubleConstant (target_type, (double) Value, Location);
1658 case BuiltinTypeSpec.Type.Char:
1659 if (in_checked_context) {
1660 if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1661 throw new OverflowException ();
1663 return new CharConstant (target_type, (char) Value, Location);
1664 case BuiltinTypeSpec.Type.Decimal:
1665 return new DecimalConstant (target_type, (decimal) Value, Location);
1673 public class DoubleConstant : Constant
1675 public readonly double Value;
1677 public DoubleConstant (BuiltinTypes types, double v, Location loc)
1678 : this (types.Double, v, loc)
1682 public DoubleConstant (TypeSpec type, double v, Location loc)
1686 eclass = ExprClass.Value;
1691 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1696 public override void Emit (EmitContext ec)
1698 ec.Emit (OpCodes.Ldc_R8, Value);
1701 public override object GetValue ()
1706 public override string GetValueAsLiteral ()
1708 return Value.ToString ();
1711 public override long GetValueAsLong ()
1713 throw new NotSupportedException ();
1716 public override bool IsDefaultValue {
1722 public override bool IsNegative {
1728 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1730 switch (target_type.BuiltinType) {
1731 case BuiltinTypeSpec.Type.Byte:
1732 if (in_checked_context) {
1733 if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1734 throw new OverflowException ();
1736 return new ByteConstant (target_type, (byte) Value, Location);
1737 case BuiltinTypeSpec.Type.SByte:
1738 if (in_checked_context) {
1739 if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1740 throw new OverflowException ();
1742 return new SByteConstant (target_type, (sbyte) Value, Location);
1743 case BuiltinTypeSpec.Type.Short:
1744 if (in_checked_context) {
1745 if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1746 throw new OverflowException ();
1748 return new ShortConstant (target_type, (short) Value, Location);
1749 case BuiltinTypeSpec.Type.UShort:
1750 if (in_checked_context) {
1751 if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1752 throw new OverflowException ();
1754 return new UShortConstant (target_type, (ushort) Value, Location);
1755 case BuiltinTypeSpec.Type.Int:
1756 if (in_checked_context) {
1757 if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1758 throw new OverflowException ();
1760 return new IntConstant (target_type, (int) Value, Location);
1761 case BuiltinTypeSpec.Type.UInt:
1762 if (in_checked_context) {
1763 if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1764 throw new OverflowException ();
1766 return new UIntConstant (target_type, (uint) Value, Location);
1767 case BuiltinTypeSpec.Type.Long:
1768 if (in_checked_context) {
1769 if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1770 throw new OverflowException ();
1772 return new LongConstant (target_type, (long) Value, Location);
1773 case BuiltinTypeSpec.Type.ULong:
1774 if (in_checked_context) {
1775 if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1776 throw new OverflowException ();
1778 return new ULongConstant (target_type, (ulong) Value, Location);
1779 case BuiltinTypeSpec.Type.Float:
1780 return new FloatConstant (target_type, (float) Value, Location);
1781 case BuiltinTypeSpec.Type.Char:
1782 if (in_checked_context) {
1783 if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1784 throw new OverflowException ();
1786 return new CharConstant (target_type, (char) Value, Location);
1787 case BuiltinTypeSpec.Type.Decimal:
1788 return new DecimalConstant (target_type, (decimal) Value, Location);
1796 public class DecimalConstant : Constant {
1797 public readonly decimal Value;
1799 public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1800 : this (types.Decimal, d, loc)
1804 public DecimalConstant (TypeSpec type, decimal d, Location loc)
1808 eclass = ExprClass.Value;
1813 public override void Emit (EmitContext ec)
1817 int [] words = decimal.GetBits (Value);
1818 int power = (words [3] >> 16) & 0xff;
1821 if (Value <= int.MaxValue && Value >= int.MinValue) {
1822 m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1827 ec.EmitInt ((int) Value);
1828 ec.Emit (OpCodes.Newobj, m);
1832 if (Value <= long.MaxValue && Value >= long.MinValue) {
1833 m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1838 ec.EmitLong ((long) Value);
1839 ec.Emit (OpCodes.Newobj, m);
1844 ec.EmitInt (words [0]);
1845 ec.EmitInt (words [1]);
1846 ec.EmitInt (words [2]);
1849 ec.EmitInt (words [3] >> 31);
1854 m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1856 ec.Emit (OpCodes.Newobj, m);
1860 public override bool IsDefaultValue {
1866 public override bool IsNegative {
1872 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1874 switch (target_type.BuiltinType) {
1875 case BuiltinTypeSpec.Type.SByte:
1876 return new SByteConstant (target_type, (sbyte) Value, loc);
1877 case BuiltinTypeSpec.Type.Byte:
1878 return new ByteConstant (target_type, (byte) Value, loc);
1879 case BuiltinTypeSpec.Type.Short:
1880 return new ShortConstant (target_type, (short) Value, loc);
1881 case BuiltinTypeSpec.Type.UShort:
1882 return new UShortConstant (target_type, (ushort) Value, loc);
1883 case BuiltinTypeSpec.Type.Int:
1884 return new IntConstant (target_type, (int) Value, loc);
1885 case BuiltinTypeSpec.Type.UInt:
1886 return new UIntConstant (target_type, (uint) Value, loc);
1887 case BuiltinTypeSpec.Type.Long:
1888 return new LongConstant (target_type, (long) Value, loc);
1889 case BuiltinTypeSpec.Type.ULong:
1890 return new ULongConstant (target_type, (ulong) Value, loc);
1891 case BuiltinTypeSpec.Type.Char:
1892 return new CharConstant (target_type, (char) Value, loc);
1893 case BuiltinTypeSpec.Type.Float:
1894 return new FloatConstant (target_type, (float) Value, loc);
1895 case BuiltinTypeSpec.Type.Double:
1896 return new DoubleConstant (target_type, (double) Value, loc);
1902 public override object GetValue ()
1907 public override string GetValueAsLiteral ()
1909 return Value.ToString () + "M";
1912 public override long GetValueAsLong ()
1914 throw new NotSupportedException ();
1918 public class StringConstant : Constant {
1919 public readonly string Value;
1921 public StringConstant (BuiltinTypes types, string s, Location loc)
1922 : this (types.String, s, loc)
1926 public StringConstant (TypeSpec type, string s, Location loc)
1930 eclass = ExprClass.Value;
1935 public override object GetValue ()
1940 public override string GetValueAsLiteral ()
1942 // FIXME: Escape the string.
1943 return "\"" + Value + "\"";
1946 public override long GetValueAsLong ()
1948 throw new NotSupportedException ();
1951 public override void Emit (EmitContext ec)
1953 if (Value == null) {
1959 // Use string.Empty for both literals and constants even if
1960 // it's not allowed at language level
1962 if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
1963 var string_type = ec.BuiltinTypes.String;
1964 if (ec.CurrentType != string_type) {
1965 var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
1967 ec.Emit (OpCodes.Ldsfld, m);
1973 ec.Emit (OpCodes.Ldstr, Value);
1976 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1979 if (type != targetType)
1985 public override bool IsDefaultValue {
1987 return Value == null;
1991 public override bool IsNegative {
1997 public override bool IsNull {
1999 return IsDefaultValue;
2003 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2010 // Null constant can have its own type, think of `default (Foo)'
2012 public class NullConstant : Constant
2014 public NullConstant (TypeSpec type, Location loc)
2017 eclass = ExprClass.Value;
2021 public override Expression CreateExpressionTree (ResolveContext ec)
2023 if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2024 // Optimized version, also avoids referencing literal internal type
2025 Arguments args = new Arguments (1);
2026 args.Add (new Argument (this));
2027 return CreateExpressionFactoryCall (ec, "Constant", args);
2030 return base.CreateExpressionTree (ec);
2033 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2035 switch (targetType.BuiltinType) {
2036 case BuiltinTypeSpec.Type.Object:
2037 // Type it as string cast
2038 enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2039 goto case BuiltinTypeSpec.Type.String;
2040 case BuiltinTypeSpec.Type.String:
2041 case BuiltinTypeSpec.Type.Type:
2042 enc.Encode (byte.MaxValue);
2045 var ac = targetType as ArrayContainer;
2046 if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
2047 enc.Encode (uint.MaxValue);
2054 base.EncodeAttributeValue (rc, enc, targetType);
2057 public override void Emit (EmitContext ec)
2061 // Only to make verifier happy
2062 if (type.IsGenericParameter)
2063 ec.Emit (OpCodes.Unbox_Any, type);
2066 public override string ExprClassName {
2068 return GetSignatureForError ();
2072 public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2074 if (targetType.IsPointer) {
2075 if (IsLiteral || this is NullPointer)
2076 return new NullPointer (targetType, loc);
2081 // Exlude internal compiler types
2082 if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2085 if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2088 if (TypeSpec.IsReferenceType (targetType))
2089 return new NullConstant (targetType, loc);
2091 if (targetType.IsNullableType)
2092 return Nullable.LiftedNull.Create (targetType, loc);
2097 public override Constant ConvertImplicitly (TypeSpec targetType)
2099 return ConvertExplicitly (false, targetType);
2102 public override string GetSignatureForError ()
2107 public override object GetValue ()
2112 public override string GetValueAsLiteral ()
2114 return GetSignatureForError ();
2117 public override long GetValueAsLong ()
2119 throw new NotSupportedException ();
2122 public override bool IsDefaultValue {
2123 get { return true; }
2126 public override bool IsNegative {
2127 get { return false; }
2130 public override bool IsNull {
2131 get { return true; }
2134 public override bool IsZeroInteger {
2135 get { return true; }
2141 // A null constant in a pointer context
2143 class NullPointer : NullConstant
2145 public NullPointer (TypeSpec type, Location loc)
2150 public override Expression CreateExpressionTree (ResolveContext ec)
2152 Error_PointerInsideExpressionTree (ec);
2153 return base.CreateExpressionTree (ec);
2156 public override void Emit (EmitContext ec)
2159 // Emits null pointer
2162 ec.Emit (OpCodes.Conv_U);
2167 /// The value is constant, but when emitted has a side effect. This is
2168 /// used by BitwiseAnd to ensure that the second expression is invoked
2169 /// regardless of the value of the left side.
2171 public class SideEffectConstant : Constant
2173 public readonly Constant value;
2174 Expression side_effect;
2176 public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2181 eclass = ExprClass.Value;
2183 while (side_effect is SideEffectConstant)
2184 side_effect = ((SideEffectConstant) side_effect).side_effect;
2185 this.side_effect = side_effect;
2188 public override bool IsSideEffectFree {
2194 public override object GetValue ()
2196 return value.GetValue ();
2199 public override string GetValueAsLiteral ()
2201 return value.GetValueAsLiteral ();
2204 public override long GetValueAsLong ()
2206 return value.GetValueAsLong ();
2209 public override void Emit (EmitContext ec)
2211 side_effect.EmitSideEffect (ec);
2215 public override void EmitSideEffect (EmitContext ec)
2217 side_effect.EmitSideEffect (ec);
2218 value.EmitSideEffect (ec);
2221 public override bool IsDefaultValue {
2222 get { return value.IsDefaultValue; }
2225 public override bool IsNegative {
2226 get { return value.IsNegative; }
2229 public override bool IsZeroInteger {
2230 get { return value.IsZeroInteger; }
2233 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2235 Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2236 if (new_value == null)
2239 var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2240 c.type = target_type;