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.
13 using System.Globalization;
16 using IKVM.Reflection.Emit;
18 using System.Reflection.Emit;
21 namespace Mono.CSharp {
24 /// Base class for constants and literals.
26 public abstract class Constant : Expression
28 static readonly NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat;
30 protected Constant (Location loc)
35 override public string ToString ()
37 return this.GetType ().Name + " (" + GetValueAsLiteral () + ")";
41 /// This is used to obtain the actual value of the literal
42 /// cast into an object.
44 public abstract object GetValue ();
46 public abstract long GetValueAsLong ();
48 public abstract string GetValueAsLiteral ();
52 // Returns an object value which is typed to contant type
54 public virtual object GetTypedValue ()
60 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
62 if (!expl && IsLiteral &&
63 BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
64 BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) {
65 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
66 GetValueAsLiteral (), TypeManager.CSharpName (target));
68 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
72 public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc)
74 Constant c = ConvertImplicitly (type);
76 Error_ValueCannotBeConverted (ec, loc, type, false);
81 public override bool ContainsEmitWithAwait ()
86 public virtual Constant ConvertImplicitly (TypeSpec type)
88 if (this.type == type)
91 if (Convert.ImplicitNumericConversion (this, type) == null)
95 object constant_value = ChangeType (GetValue (), type, out fail);
98 // We should always catch the error before this is ever
99 // reached, by calling Convert.ImplicitStandardConversionExists
101 throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
102 TypeManager.CSharpName (Type), TypeManager.CSharpName (type));
105 return CreateConstant (type, constant_value, loc);
109 // Returns a constant instance based on Type
111 public static Constant CreateConstant (TypeSpec t, object v, Location loc)
113 return CreateConstantFromValue (t, v, loc);
116 public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
118 switch (t.BuiltinType) {
119 case BuiltinTypeSpec.Type.Int:
120 return new IntConstant (t, (int) v, loc);
121 case BuiltinTypeSpec.Type.String:
122 return new StringConstant (t, (string) v, loc);
123 case BuiltinTypeSpec.Type.UInt:
124 return new UIntConstant (t, (uint) v, loc);
125 case BuiltinTypeSpec.Type.Long:
126 return new LongConstant (t, (long) v, loc);
127 case BuiltinTypeSpec.Type.ULong:
128 return new ULongConstant (t, (ulong) v, loc);
129 case BuiltinTypeSpec.Type.Float:
130 return new FloatConstant (t, (float) v, loc);
131 case BuiltinTypeSpec.Type.Double:
132 return new DoubleConstant (t, (double) v, loc);
133 case BuiltinTypeSpec.Type.Short:
134 return new ShortConstant (t, (short) v, loc);
135 case BuiltinTypeSpec.Type.UShort:
136 return new UShortConstant (t, (ushort) v, loc);
137 case BuiltinTypeSpec.Type.SByte:
138 return new SByteConstant (t, (sbyte) v, loc);
139 case BuiltinTypeSpec.Type.Byte:
140 return new ByteConstant (t, (byte) v, loc);
141 case BuiltinTypeSpec.Type.Char:
142 return new CharConstant (t, (char) v, loc);
143 case BuiltinTypeSpec.Type.Bool:
144 return new BoolConstant (t, (bool) v, loc);
145 case BuiltinTypeSpec.Type.Decimal:
146 return new DecimalConstant (t, (decimal) v, loc);
150 var real_type = EnumSpec.GetUnderlyingType (t);
151 return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
155 if (t.IsNullableType)
156 return Nullable.LiftedNull.Create (t, loc);
158 if (TypeSpec.IsReferenceType (t))
159 return new NullConstant (t, loc);
162 throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'",
163 v, TypeManager.CSharpName (t));
166 public override Expression CreateExpressionTree (ResolveContext ec)
168 Arguments args = new Arguments (2);
169 args.Add (new Argument (this));
170 args.Add (new Argument (new TypeOf (type, loc)));
172 return CreateExpressionFactoryCall (ec, "Constant", args);
176 /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
177 /// It throws OverflowException
179 // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
180 public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
182 // This is a custom version of Convert.ChangeType() which works
183 // with the TypeBuilder defined types when compiling corlib.
184 static object ChangeType (object value, TypeSpec targetType, out bool error)
186 IConvertible convert_value = value as IConvertible;
188 if (convert_value == null) {
194 // We cannot rely on build-in type conversions as they are
195 // more limited than what C# supports.
196 // See char -> float/decimal/double conversion
200 switch (targetType.BuiltinType) {
201 case BuiltinTypeSpec.Type.Bool:
202 return convert_value.ToBoolean (nfi);
203 case BuiltinTypeSpec.Type.Byte:
204 return convert_value.ToByte (nfi);
205 case BuiltinTypeSpec.Type.Char:
206 return convert_value.ToChar (nfi);
207 case BuiltinTypeSpec.Type.Short:
208 return convert_value.ToInt16 (nfi);
209 case BuiltinTypeSpec.Type.Int:
210 return convert_value.ToInt32 (nfi);
211 case BuiltinTypeSpec.Type.Long:
212 return convert_value.ToInt64 (nfi);
213 case BuiltinTypeSpec.Type.SByte:
214 return convert_value.ToSByte (nfi);
215 case BuiltinTypeSpec.Type.Decimal:
216 if (convert_value.GetType () == typeof (char))
217 return (decimal) convert_value.ToInt32 (nfi);
218 return convert_value.ToDecimal (nfi);
219 case BuiltinTypeSpec.Type.Double:
220 if (convert_value.GetType () == typeof (char))
221 return (double) convert_value.ToInt32 (nfi);
222 return convert_value.ToDouble (nfi);
223 case BuiltinTypeSpec.Type.Float:
224 if (convert_value.GetType () == typeof (char))
225 return (float) convert_value.ToInt32 (nfi);
226 return convert_value.ToSingle (nfi);
227 case BuiltinTypeSpec.Type.String:
228 return convert_value.ToString (nfi);
229 case BuiltinTypeSpec.Type.UShort:
230 return convert_value.ToUInt16 (nfi);
231 case BuiltinTypeSpec.Type.UInt:
232 return convert_value.ToUInt32 (nfi);
233 case BuiltinTypeSpec.Type.ULong:
234 return convert_value.ToUInt64 (nfi);
235 case BuiltinTypeSpec.Type.Object:
245 protected override Expression DoResolve (ResolveContext rc)
251 /// Attempts to do a compile-time folding of a constant cast.
253 public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
256 return TryReduce (ec, target_type);
258 catch (OverflowException) {
259 if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
260 ec.Report.Error (221, loc,
261 "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
262 GetValueAsLiteral (), target_type.GetSignatureForError ());
264 Error_ValueCannotBeConverted (ec, loc, target_type, false);
267 return New.Constantify (target_type, loc);
271 Constant TryReduce (ResolveContext ec, TypeSpec target_type)
273 if (Type == target_type)
277 if (TypeManager.IsEnumType (target_type)) {
278 c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
282 return new EnumConstant (c, target_type);
285 return ConvertExplicitly (ec.ConstantCheckState, target_type);
289 /// Need to pass type as the constant can require a boxing
290 /// and in such case no optimization is possible
292 public bool IsDefaultInitializer (TypeSpec type)
295 return IsDefaultValue;
297 return this is NullLiteral;
300 public abstract bool IsDefaultValue {
304 public abstract bool IsNegative {
309 // When constant is declared as literal
311 public virtual bool IsLiteral {
312 get { return false; }
315 public virtual bool IsOneInteger {
316 get { return false; }
319 public override bool IsSideEffectFree {
326 // Returns true iff 1) the stack type of this is one of Object,
327 // int32, int64 and 2) this == 0 or this == null.
329 public virtual bool IsZeroInteger {
330 get { return false; }
333 public override void EmitSideEffect (EmitContext ec)
338 public sealed override Expression Clone (CloneContext clonectx)
340 // No cloning is not needed for constants
344 protected override void CloneTo (CloneContext clonectx, Expression target)
346 throw new NotSupportedException ("should not be reached");
349 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
352 return base.MakeExpression (ctx);
354 return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
358 public new bool Resolve (ResolveContext rc)
360 // It exists only as hint not to call Resolve on constants
365 public abstract class IntegralConstant : Constant
367 protected IntegralConstant (TypeSpec type, Location loc)
371 eclass = ExprClass.Value;
374 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
377 ConvertExplicitly (true, target);
378 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
382 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
383 GetValue ().ToString (), TypeManager.CSharpName (target));
387 public override string GetValueAsLiteral ()
389 return GetValue ().ToString ();
392 public abstract Constant Increment ();
395 public class BoolConstant : Constant {
396 public readonly bool Value;
398 public BoolConstant (BuiltinTypes types, bool val, Location loc)
399 : this (types.Bool, val, loc)
403 public BoolConstant (TypeSpec type, bool val, Location loc)
406 eclass = ExprClass.Value;
412 public override object GetValue ()
414 return (object) Value;
417 public override string GetValueAsLiteral ()
419 return Value ? "true" : "false";
422 public override long GetValueAsLong ()
424 return Value ? 1 : 0;
427 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
432 public override void Emit (EmitContext ec)
440 public override bool IsDefaultValue {
446 public override bool IsNegative {
452 public override bool IsZeroInteger {
453 get { return Value == false; }
456 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
463 public class ByteConstant : IntegralConstant
465 public readonly byte Value;
467 public ByteConstant (BuiltinTypes types, byte v, Location loc)
468 : this (types.Byte, v, loc)
472 public ByteConstant (TypeSpec type, byte v, Location loc)
478 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
483 public override void Emit (EmitContext ec)
488 public override object GetValue ()
493 public override long GetValueAsLong ()
498 public override Constant Increment ()
500 return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
503 public override bool IsDefaultValue {
509 public override bool IsOneInteger {
515 public override bool IsNegative {
521 public override bool IsZeroInteger {
522 get { return Value == 0; }
525 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
527 switch (target_type.BuiltinType) {
528 case BuiltinTypeSpec.Type.SByte:
529 if (in_checked_context){
530 if (Value > SByte.MaxValue)
531 throw new OverflowException ();
533 return new SByteConstant (target_type, (sbyte) Value, Location);
534 case BuiltinTypeSpec.Type.Short:
535 return new ShortConstant (target_type, (short) Value, Location);
536 case BuiltinTypeSpec.Type.UShort:
537 return new UShortConstant (target_type, (ushort) Value, Location);
538 case BuiltinTypeSpec.Type.Int:
539 return new IntConstant (target_type, (int) Value, Location);
540 case BuiltinTypeSpec.Type.UInt:
541 return new UIntConstant (target_type, (uint) Value, Location);
542 case BuiltinTypeSpec.Type.Long:
543 return new LongConstant (target_type, (long) Value, Location);
544 case BuiltinTypeSpec.Type.ULong:
545 return new ULongConstant (target_type, (ulong) Value, Location);
546 case BuiltinTypeSpec.Type.Float:
547 return new FloatConstant (target_type, (float) Value, Location);
548 case BuiltinTypeSpec.Type.Double:
549 return new DoubleConstant (target_type, (double) Value, Location);
550 case BuiltinTypeSpec.Type.Char:
551 return new CharConstant (target_type, (char) Value, Location);
552 case BuiltinTypeSpec.Type.Decimal:
553 return new DecimalConstant (target_type, (decimal) Value, Location);
561 public class CharConstant : Constant {
562 public readonly char Value;
564 public CharConstant (BuiltinTypes types, char v, Location loc)
565 : this (types.Char, v, loc)
569 public CharConstant (TypeSpec type, char v, Location loc)
573 eclass = ExprClass.Value;
578 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
580 enc.Encode ((ushort) Value);
583 public override void Emit (EmitContext ec)
588 static string descape (char c)
614 return c.ToString ();
617 public override object GetValue ()
622 public override long GetValueAsLong ()
627 public override string GetValueAsLiteral ()
629 return "\"" + descape (Value) + "\"";
632 public override bool IsDefaultValue {
638 public override bool IsNegative {
644 public override bool IsZeroInteger {
645 get { return Value == '\0'; }
648 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
650 switch (target_type.BuiltinType) {
651 case BuiltinTypeSpec.Type.Byte:
652 if (in_checked_context) {
653 if (Value < Byte.MinValue || Value > Byte.MaxValue)
654 throw new OverflowException ();
656 return new ByteConstant (target_type, (byte) Value, Location);
657 case BuiltinTypeSpec.Type.SByte:
658 if (in_checked_context) {
659 if (Value > SByte.MaxValue)
660 throw new OverflowException ();
662 return new SByteConstant (target_type, (sbyte) Value, Location);
664 case BuiltinTypeSpec.Type.Short:
665 if (in_checked_context) {
666 if (Value > Int16.MaxValue)
667 throw new OverflowException ();
669 return new ShortConstant (target_type, (short) Value, Location);
670 case BuiltinTypeSpec.Type.Int:
671 return new IntConstant (target_type, (int) Value, Location);
672 case BuiltinTypeSpec.Type.UInt:
673 return new UIntConstant (target_type, (uint) Value, Location);
674 case BuiltinTypeSpec.Type.Long:
675 return new LongConstant (target_type, (long) Value, Location);
676 case BuiltinTypeSpec.Type.ULong:
677 return new ULongConstant (target_type, (ulong) Value, Location);
678 case BuiltinTypeSpec.Type.Float:
679 return new FloatConstant (target_type, (float) Value, Location);
680 case BuiltinTypeSpec.Type.Double:
681 return new DoubleConstant (target_type, (double) Value, Location);
682 case BuiltinTypeSpec.Type.Decimal:
683 return new DecimalConstant (target_type, (decimal) Value, Location);
691 public class SByteConstant : IntegralConstant
693 public readonly sbyte Value;
695 public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
696 : this (types.SByte, v, loc)
700 public SByteConstant (TypeSpec type, sbyte v, Location loc)
706 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
711 public override void Emit (EmitContext ec)
716 public override object GetValue ()
721 public override long GetValueAsLong ()
726 public override Constant Increment ()
728 return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
731 public override bool IsDefaultValue {
737 public override bool IsNegative {
743 public override bool IsOneInteger {
749 public override bool IsZeroInteger {
750 get { return Value == 0; }
753 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
755 switch (target_type.BuiltinType) {
756 case BuiltinTypeSpec.Type.Byte:
757 if (in_checked_context && Value < 0)
758 throw new OverflowException ();
759 return new ByteConstant (target_type, (byte) Value, Location);
760 case BuiltinTypeSpec.Type.Short:
761 return new ShortConstant (target_type, (short) Value, Location);
762 case BuiltinTypeSpec.Type.UShort:
763 if (in_checked_context && Value < 0)
764 throw new OverflowException ();
765 return new UShortConstant (target_type, (ushort) Value, Location);
766 case BuiltinTypeSpec.Type.Int:
767 return new IntConstant (target_type, (int) Value, Location);
768 case BuiltinTypeSpec.Type.UInt:
769 if (in_checked_context && Value < 0)
770 throw new OverflowException ();
771 return new UIntConstant (target_type, (uint) Value, Location);
772 case BuiltinTypeSpec.Type.Long:
773 return new LongConstant (target_type, (long) Value, Location);
774 case BuiltinTypeSpec.Type.ULong:
775 if (in_checked_context && Value < 0)
776 throw new OverflowException ();
777 return new ULongConstant (target_type, (ulong) Value, Location);
778 case BuiltinTypeSpec.Type.Float:
779 return new FloatConstant (target_type, (float) Value, Location);
780 case BuiltinTypeSpec.Type.Double:
781 return new DoubleConstant (target_type, (double) Value, Location);
782 case BuiltinTypeSpec.Type.Char:
783 if (in_checked_context && Value < 0)
784 throw new OverflowException ();
785 return new CharConstant (target_type, (char) Value, Location);
786 case BuiltinTypeSpec.Type.Decimal:
787 return new DecimalConstant (target_type, (decimal) Value, Location);
795 public class ShortConstant : IntegralConstant {
796 public readonly short Value;
798 public ShortConstant (BuiltinTypes types, short v, Location loc)
799 : this (types.Short, v, loc)
803 public ShortConstant (TypeSpec type, short v, Location loc)
809 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
814 public override void Emit (EmitContext ec)
819 public override object GetValue ()
824 public override long GetValueAsLong ()
829 public override Constant Increment ()
831 return new ShortConstant (type, checked((short)(Value + 1)), loc);
834 public override bool IsDefaultValue {
840 public override bool IsZeroInteger {
841 get { return Value == 0; }
844 public override bool IsNegative {
850 public override bool IsOneInteger {
856 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
858 switch (target_type.BuiltinType) {
859 case BuiltinTypeSpec.Type.Byte:
860 if (in_checked_context) {
861 if (Value < Byte.MinValue || Value > Byte.MaxValue)
862 throw new OverflowException ();
864 return new ByteConstant (target_type, (byte) Value, Location);
865 case BuiltinTypeSpec.Type.SByte:
866 if (in_checked_context) {
867 if (Value < SByte.MinValue || Value > SByte.MaxValue)
868 throw new OverflowException ();
870 return new SByteConstant (target_type, (sbyte) Value, Location);
871 case BuiltinTypeSpec.Type.UShort:
872 if (in_checked_context && Value < 0)
873 throw new OverflowException ();
875 return new UShortConstant (target_type, (ushort) Value, Location);
876 case BuiltinTypeSpec.Type.Int:
877 return new IntConstant (target_type, (int) Value, Location);
878 case BuiltinTypeSpec.Type.UInt:
879 if (in_checked_context && Value < 0)
880 throw new OverflowException ();
881 return new UIntConstant (target_type, (uint) Value, Location);
882 case BuiltinTypeSpec.Type.Long:
883 return new LongConstant (target_type, (long) Value, Location);
884 case BuiltinTypeSpec.Type.ULong:
885 if (in_checked_context && Value < 0)
886 throw new OverflowException ();
887 return new ULongConstant (target_type, (ulong) Value, Location);
888 case BuiltinTypeSpec.Type.Float:
889 return new FloatConstant (target_type, (float) Value, Location);
890 case BuiltinTypeSpec.Type.Double:
891 return new DoubleConstant (target_type, (double) Value, Location);
892 case BuiltinTypeSpec.Type.Char:
893 if (in_checked_context) {
894 if (Value < Char.MinValue)
895 throw new OverflowException ();
897 return new CharConstant (target_type, (char) Value, Location);
898 case BuiltinTypeSpec.Type.Decimal:
899 return new DecimalConstant (target_type, (decimal) Value, Location);
907 public class UShortConstant : IntegralConstant
909 public readonly ushort Value;
911 public UShortConstant (BuiltinTypes types, ushort v, Location loc)
912 : this (types.UShort, v, loc)
916 public UShortConstant (TypeSpec type, ushort v, Location loc)
922 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
927 public override void Emit (EmitContext ec)
932 public override object GetValue ()
937 public override long GetValueAsLong ()
942 public override Constant Increment ()
944 return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
947 public override bool IsDefaultValue {
953 public override bool IsNegative {
959 public override bool IsOneInteger {
965 public override bool IsZeroInteger {
966 get { return Value == 0; }
969 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
971 switch (target_type.BuiltinType) {
972 case BuiltinTypeSpec.Type.Byte:
973 if (in_checked_context) {
974 if (Value > Byte.MaxValue)
975 throw new OverflowException ();
977 return new ByteConstant (target_type, (byte) Value, Location);
978 case BuiltinTypeSpec.Type.SByte:
979 if (in_checked_context) {
980 if (Value > SByte.MaxValue)
981 throw new OverflowException ();
983 return new SByteConstant (target_type, (sbyte) Value, Location);
984 case BuiltinTypeSpec.Type.Short:
985 if (in_checked_context) {
986 if (Value > Int16.MaxValue)
987 throw new OverflowException ();
989 return new ShortConstant (target_type, (short) Value, Location);
990 case BuiltinTypeSpec.Type.Int:
991 return new IntConstant (target_type, (int) Value, Location);
992 case BuiltinTypeSpec.Type.UInt:
993 return new UIntConstant (target_type, (uint) Value, Location);
994 case BuiltinTypeSpec.Type.Long:
995 return new LongConstant (target_type, (long) Value, Location);
996 case BuiltinTypeSpec.Type.ULong:
997 return new ULongConstant (target_type, (ulong) Value, Location);
998 case BuiltinTypeSpec.Type.Float:
999 return new FloatConstant (target_type, (float) Value, Location);
1000 case BuiltinTypeSpec.Type.Double:
1001 return new DoubleConstant (target_type, (double) Value, Location);
1002 case BuiltinTypeSpec.Type.Char:
1003 if (in_checked_context) {
1004 if (Value > Char.MaxValue)
1005 throw new OverflowException ();
1007 return new CharConstant (target_type, (char) Value, Location);
1008 case BuiltinTypeSpec.Type.Decimal:
1009 return new DecimalConstant (target_type, (decimal) Value, Location);
1016 public class IntConstant : IntegralConstant
1018 public readonly int Value;
1020 public IntConstant (BuiltinTypes types, int v, Location loc)
1021 : this (types.Int, v, loc)
1025 public IntConstant (TypeSpec type, int v, Location loc)
1031 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1036 public override void Emit (EmitContext ec)
1041 public override object GetValue ()
1046 public override long GetValueAsLong ()
1051 public override Constant Increment ()
1053 return new IntConstant (type, checked(Value + 1), loc);
1056 public override bool IsDefaultValue {
1062 public override bool IsNegative {
1068 public override bool IsOneInteger {
1074 public override bool IsZeroInteger {
1075 get { return Value == 0; }
1078 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1080 switch (target_type.BuiltinType) {
1081 case BuiltinTypeSpec.Type.Byte:
1082 if (in_checked_context) {
1083 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1084 throw new OverflowException ();
1086 return new ByteConstant (target_type, (byte) Value, Location);
1087 case BuiltinTypeSpec.Type.SByte:
1088 if (in_checked_context) {
1089 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1090 throw new OverflowException ();
1092 return new SByteConstant (target_type, (sbyte) Value, Location);
1093 case BuiltinTypeSpec.Type.Short:
1094 if (in_checked_context) {
1095 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1096 throw new OverflowException ();
1098 return new ShortConstant (target_type, (short) Value, Location);
1099 case BuiltinTypeSpec.Type.UShort:
1100 if (in_checked_context) {
1101 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1102 throw new OverflowException ();
1104 return new UShortConstant (target_type, (ushort) Value, Location);
1105 case BuiltinTypeSpec.Type.UInt:
1106 if (in_checked_context) {
1107 if (Value < UInt32.MinValue)
1108 throw new OverflowException ();
1110 return new UIntConstant (target_type, (uint) Value, Location);
1111 case BuiltinTypeSpec.Type.Long:
1112 return new LongConstant (target_type, (long) Value, Location);
1113 case BuiltinTypeSpec.Type.ULong:
1114 if (in_checked_context && Value < 0)
1115 throw new OverflowException ();
1116 return new ULongConstant (target_type, (ulong) Value, Location);
1117 case BuiltinTypeSpec.Type.Float:
1118 return new FloatConstant (target_type, (float) Value, Location);
1119 case BuiltinTypeSpec.Type.Double:
1120 return new DoubleConstant (target_type, (double) Value, Location);
1121 case BuiltinTypeSpec.Type.Char:
1122 if (in_checked_context) {
1123 if (Value < Char.MinValue || Value > Char.MaxValue)
1124 throw new OverflowException ();
1126 return new CharConstant (target_type, (char) Value, Location);
1127 case BuiltinTypeSpec.Type.Decimal:
1128 return new DecimalConstant (target_type, (decimal) Value, Location);
1134 public override Constant ConvertImplicitly (TypeSpec type)
1136 if (this.type == type)
1139 Constant c = TryImplicitIntConversion (type);
1141 return c; //.Resolve (rc);
1143 return base.ConvertImplicitly (type);
1147 /// Attempts to perform an implicit constant conversion of the IntConstant
1148 /// into a different data type using casts (See Implicit Constant
1149 /// Expression Conversions)
1151 Constant TryImplicitIntConversion (TypeSpec target_type)
1153 switch (target_type.BuiltinType) {
1154 case BuiltinTypeSpec.Type.SByte:
1155 if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1156 return new SByteConstant (target_type, (sbyte) Value, loc);
1158 case BuiltinTypeSpec.Type.Byte:
1159 if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1160 return new ByteConstant (target_type, (byte) Value, loc);
1162 case BuiltinTypeSpec.Type.Short:
1163 if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1164 return new ShortConstant (target_type, (short) Value, loc);
1166 case BuiltinTypeSpec.Type.UShort:
1167 if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1168 return new UShortConstant (target_type, (ushort) Value, loc);
1170 case BuiltinTypeSpec.Type.UInt:
1172 return new UIntConstant (target_type, (uint) Value, loc);
1174 case BuiltinTypeSpec.Type.ULong:
1176 // we can optimize this case: a positive int32
1177 // always fits on a uint64. But we need an opcode
1181 return new ULongConstant (target_type, (ulong) Value, loc);
1183 case BuiltinTypeSpec.Type.Double:
1184 return new DoubleConstant (target_type, (double) Value, loc);
1185 case BuiltinTypeSpec.Type.Float:
1186 return new FloatConstant (target_type, (float) Value, loc);
1193 public class UIntConstant : IntegralConstant {
1194 public readonly uint Value;
1196 public UIntConstant (BuiltinTypes types, uint v, Location loc)
1197 : this (types.UInt, v, loc)
1201 public UIntConstant (TypeSpec type, uint v, Location loc)
1207 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1212 public override void Emit (EmitContext ec)
1214 ec.EmitInt (unchecked ((int) Value));
1217 public override object GetValue ()
1222 public override long GetValueAsLong ()
1227 public override Constant Increment ()
1229 return new UIntConstant (type, checked(Value + 1), loc);
1232 public override bool IsDefaultValue {
1238 public override bool IsNegative {
1244 public override bool IsOneInteger {
1250 public override bool IsZeroInteger {
1251 get { return Value == 0; }
1254 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1256 switch (target_type.BuiltinType) {
1257 case BuiltinTypeSpec.Type.Byte:
1258 if (in_checked_context) {
1259 if (Value < 0 || Value > byte.MaxValue)
1260 throw new OverflowException ();
1262 return new ByteConstant (target_type, (byte) Value, Location);
1263 case BuiltinTypeSpec.Type.SByte:
1264 if (in_checked_context) {
1265 if (Value > SByte.MaxValue)
1266 throw new OverflowException ();
1268 return new SByteConstant (target_type, (sbyte) Value, Location);
1269 case BuiltinTypeSpec.Type.Short:
1270 if (in_checked_context) {
1271 if (Value > Int16.MaxValue)
1272 throw new OverflowException ();
1274 return new ShortConstant (target_type, (short) Value, Location);
1275 case BuiltinTypeSpec.Type.UShort:
1276 if (in_checked_context) {
1277 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1278 throw new OverflowException ();
1280 return new UShortConstant (target_type, (ushort) Value, Location);
1281 case BuiltinTypeSpec.Type.Int:
1282 if (in_checked_context) {
1283 if (Value > Int32.MaxValue)
1284 throw new OverflowException ();
1286 return new IntConstant (target_type, (int) Value, Location);
1287 case BuiltinTypeSpec.Type.Long:
1288 return new LongConstant (target_type, (long) Value, Location);
1289 case BuiltinTypeSpec.Type.ULong:
1290 return new ULongConstant (target_type, (ulong) Value, Location);
1291 case BuiltinTypeSpec.Type.Float:
1292 return new FloatConstant (target_type, (float) Value, Location);
1293 case BuiltinTypeSpec.Type.Double:
1294 return new DoubleConstant (target_type, (double) Value, Location);
1295 case BuiltinTypeSpec.Type.Char:
1296 if (in_checked_context) {
1297 if (Value < Char.MinValue || Value > Char.MaxValue)
1298 throw new OverflowException ();
1300 return new CharConstant (target_type, (char) Value, Location);
1301 case BuiltinTypeSpec.Type.Decimal:
1302 return new DecimalConstant (target_type, (decimal) Value, Location);
1310 public class LongConstant : IntegralConstant {
1311 public readonly long Value;
1313 public LongConstant (BuiltinTypes types, long v, Location loc)
1314 : this (types.Long, v, loc)
1318 public LongConstant (TypeSpec type, long v, Location loc)
1324 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1329 public override void Emit (EmitContext ec)
1331 ec.EmitLong (Value);
1334 public override object GetValue ()
1339 public override long GetValueAsLong ()
1344 public override Constant Increment ()
1346 return new LongConstant (type, checked(Value + 1), loc);
1349 public override bool IsDefaultValue {
1355 public override bool IsNegative {
1361 public override bool IsOneInteger {
1367 public override bool IsZeroInteger {
1368 get { return Value == 0; }
1371 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1373 switch (target_type.BuiltinType) {
1374 case BuiltinTypeSpec.Type.Byte:
1375 if (in_checked_context) {
1376 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1377 throw new OverflowException ();
1379 return new ByteConstant (target_type, (byte) Value, Location);
1380 case BuiltinTypeSpec.Type.SByte:
1381 if (in_checked_context) {
1382 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1383 throw new OverflowException ();
1385 return new SByteConstant (target_type, (sbyte) Value, Location);
1386 case BuiltinTypeSpec.Type.Short:
1387 if (in_checked_context) {
1388 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1389 throw new OverflowException ();
1391 return new ShortConstant (target_type, (short) Value, Location);
1392 case BuiltinTypeSpec.Type.UShort:
1393 if (in_checked_context) {
1394 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1395 throw new OverflowException ();
1397 return new UShortConstant (target_type, (ushort) Value, Location);
1398 case BuiltinTypeSpec.Type.Int:
1399 if (in_checked_context) {
1400 if (Value < Int32.MinValue || Value > Int32.MaxValue)
1401 throw new OverflowException ();
1403 return new IntConstant (target_type, (int) Value, Location);
1404 case BuiltinTypeSpec.Type.UInt:
1405 if (in_checked_context) {
1406 if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1407 throw new OverflowException ();
1409 return new UIntConstant (target_type, (uint) Value, Location);
1410 case BuiltinTypeSpec.Type.ULong:
1411 if (in_checked_context && Value < 0)
1412 throw new OverflowException ();
1413 return new ULongConstant (target_type, (ulong) Value, Location);
1414 case BuiltinTypeSpec.Type.Float:
1415 return new FloatConstant (target_type, (float) Value, Location);
1416 case BuiltinTypeSpec.Type.Double:
1417 return new DoubleConstant (target_type, (double) Value, Location);
1418 case BuiltinTypeSpec.Type.Char:
1419 if (in_checked_context) {
1420 if (Value < Char.MinValue || Value > Char.MaxValue)
1421 throw new OverflowException ();
1423 return new CharConstant (target_type, (char) Value, Location);
1424 case BuiltinTypeSpec.Type.Decimal:
1425 return new DecimalConstant (target_type, (decimal) Value, Location);
1431 public override Constant ConvertImplicitly (TypeSpec type)
1433 if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
1434 return new ULongConstant (type, (ulong) Value, loc);
1437 return base.ConvertImplicitly (type);
1441 public class ULongConstant : IntegralConstant {
1442 public readonly ulong Value;
1444 public ULongConstant (BuiltinTypes types, ulong v, Location loc)
1445 : this (types.ULong, v, loc)
1449 public ULongConstant (TypeSpec type, ulong v, Location loc)
1455 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1460 public override void Emit (EmitContext ec)
1462 ec.EmitLong (unchecked ((long) Value));
1465 public override object GetValue ()
1470 public override long GetValueAsLong ()
1472 return (long) Value;
1475 public override Constant Increment ()
1477 return new ULongConstant (type, checked(Value + 1), loc);
1480 public override bool IsDefaultValue {
1486 public override bool IsNegative {
1492 public override bool IsOneInteger {
1498 public override bool IsZeroInteger {
1499 get { return Value == 0; }
1502 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1504 switch (target_type.BuiltinType) {
1505 case BuiltinTypeSpec.Type.Byte:
1506 if (in_checked_context && Value > Byte.MaxValue)
1507 throw new OverflowException ();
1508 return new ByteConstant (target_type, (byte) Value, Location);
1509 case BuiltinTypeSpec.Type.SByte:
1510 if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1511 throw new OverflowException ();
1512 return new SByteConstant (target_type, (sbyte) Value, Location);
1513 case BuiltinTypeSpec.Type.Short:
1514 if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1515 throw new OverflowException ();
1516 return new ShortConstant (target_type, (short) Value, Location);
1517 case BuiltinTypeSpec.Type.UShort:
1518 if (in_checked_context && Value > UInt16.MaxValue)
1519 throw new OverflowException ();
1520 return new UShortConstant (target_type, (ushort) Value, Location);
1521 case BuiltinTypeSpec.Type.Int:
1522 if (in_checked_context && Value > UInt32.MaxValue)
1523 throw new OverflowException ();
1524 return new IntConstant (target_type, (int) Value, Location);
1525 case BuiltinTypeSpec.Type.UInt:
1526 if (in_checked_context && Value > UInt32.MaxValue)
1527 throw new OverflowException ();
1528 return new UIntConstant (target_type, (uint) Value, Location);
1529 case BuiltinTypeSpec.Type.Long:
1530 if (in_checked_context && Value > Int64.MaxValue)
1531 throw new OverflowException ();
1532 return new LongConstant (target_type, (long) Value, Location);
1533 case BuiltinTypeSpec.Type.Float:
1534 return new FloatConstant (target_type, (float) Value, Location);
1535 case BuiltinTypeSpec.Type.Double:
1536 return new DoubleConstant (target_type, (double) Value, Location);
1537 case BuiltinTypeSpec.Type.Char:
1538 if (in_checked_context && Value > Char.MaxValue)
1539 throw new OverflowException ();
1540 return new CharConstant (target_type, (char) Value, Location);
1541 case BuiltinTypeSpec.Type.Decimal:
1542 return new DecimalConstant (target_type, (decimal) Value, Location);
1550 public class FloatConstant : Constant {
1551 public readonly float Value;
1553 public FloatConstant (BuiltinTypes types, float v, Location loc)
1554 : this (types.Float, v, loc)
1558 public FloatConstant (TypeSpec type, float v, Location loc)
1562 eclass = ExprClass.Value;
1567 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1572 public override void Emit (EmitContext ec)
1574 ec.Emit (OpCodes.Ldc_R4, Value);
1577 public override object GetValue ()
1582 public override string GetValueAsLiteral ()
1584 return Value.ToString ();
1587 public override long GetValueAsLong ()
1589 throw new NotSupportedException ();
1592 public override bool IsDefaultValue {
1598 public override bool IsNegative {
1604 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1606 switch (target_type.BuiltinType) {
1607 case BuiltinTypeSpec.Type.Byte:
1608 if (in_checked_context) {
1609 if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1610 throw new OverflowException ();
1612 return new ByteConstant (target_type, (byte) Value, Location);
1613 case BuiltinTypeSpec.Type.SByte:
1614 if (in_checked_context) {
1615 if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1616 throw new OverflowException ();
1618 return new SByteConstant (target_type, (sbyte) Value, Location);
1619 case BuiltinTypeSpec.Type.Short:
1620 if (in_checked_context) {
1621 if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1622 throw new OverflowException ();
1624 return new ShortConstant (target_type, (short) Value, Location);
1625 case BuiltinTypeSpec.Type.UShort:
1626 if (in_checked_context) {
1627 if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1628 throw new OverflowException ();
1630 return new UShortConstant (target_type, (ushort) Value, Location);
1631 case BuiltinTypeSpec.Type.Int:
1632 if (in_checked_context) {
1633 if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1634 throw new OverflowException ();
1636 return new IntConstant (target_type, (int) Value, Location);
1637 case BuiltinTypeSpec.Type.UInt:
1638 if (in_checked_context) {
1639 if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1640 throw new OverflowException ();
1642 return new UIntConstant (target_type, (uint) Value, Location);
1643 case BuiltinTypeSpec.Type.Long:
1644 if (in_checked_context) {
1645 if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1646 throw new OverflowException ();
1648 return new LongConstant (target_type, (long) Value, Location);
1649 case BuiltinTypeSpec.Type.ULong:
1650 if (in_checked_context) {
1651 if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1652 throw new OverflowException ();
1654 return new ULongConstant (target_type, (ulong) Value, Location);
1655 case BuiltinTypeSpec.Type.Double:
1656 return new DoubleConstant (target_type, (double) Value, Location);
1657 case BuiltinTypeSpec.Type.Char:
1658 if (in_checked_context) {
1659 if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1660 throw new OverflowException ();
1662 return new CharConstant (target_type, (char) Value, Location);
1663 case BuiltinTypeSpec.Type.Decimal:
1664 return new DecimalConstant (target_type, (decimal) Value, Location);
1672 public class DoubleConstant : Constant
1674 public readonly double Value;
1676 public DoubleConstant (BuiltinTypes types, double v, Location loc)
1677 : this (types.Double, v, loc)
1681 public DoubleConstant (TypeSpec type, double v, Location loc)
1685 eclass = ExprClass.Value;
1690 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1695 public override void Emit (EmitContext ec)
1697 ec.Emit (OpCodes.Ldc_R8, Value);
1700 public override object GetValue ()
1705 public override string GetValueAsLiteral ()
1707 return Value.ToString ();
1710 public override long GetValueAsLong ()
1712 throw new NotSupportedException ();
1715 public override bool IsDefaultValue {
1721 public override bool IsNegative {
1727 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1729 switch (target_type.BuiltinType) {
1730 case BuiltinTypeSpec.Type.Byte:
1731 if (in_checked_context) {
1732 if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1733 throw new OverflowException ();
1735 return new ByteConstant (target_type, (byte) Value, Location);
1736 case BuiltinTypeSpec.Type.SByte:
1737 if (in_checked_context) {
1738 if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1739 throw new OverflowException ();
1741 return new SByteConstant (target_type, (sbyte) Value, Location);
1742 case BuiltinTypeSpec.Type.Short:
1743 if (in_checked_context) {
1744 if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1745 throw new OverflowException ();
1747 return new ShortConstant (target_type, (short) Value, Location);
1748 case BuiltinTypeSpec.Type.UShort:
1749 if (in_checked_context) {
1750 if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1751 throw new OverflowException ();
1753 return new UShortConstant (target_type, (ushort) Value, Location);
1754 case BuiltinTypeSpec.Type.Int:
1755 if (in_checked_context) {
1756 if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1757 throw new OverflowException ();
1759 return new IntConstant (target_type, (int) Value, Location);
1760 case BuiltinTypeSpec.Type.UInt:
1761 if (in_checked_context) {
1762 if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1763 throw new OverflowException ();
1765 return new UIntConstant (target_type, (uint) Value, Location);
1766 case BuiltinTypeSpec.Type.Long:
1767 if (in_checked_context) {
1768 if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1769 throw new OverflowException ();
1771 return new LongConstant (target_type, (long) Value, Location);
1772 case BuiltinTypeSpec.Type.ULong:
1773 if (in_checked_context) {
1774 if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1775 throw new OverflowException ();
1777 return new ULongConstant (target_type, (ulong) Value, Location);
1778 case BuiltinTypeSpec.Type.Float:
1779 return new FloatConstant (target_type, (float) Value, Location);
1780 case BuiltinTypeSpec.Type.Char:
1781 if (in_checked_context) {
1782 if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1783 throw new OverflowException ();
1785 return new CharConstant (target_type, (char) Value, Location);
1786 case BuiltinTypeSpec.Type.Decimal:
1787 return new DecimalConstant (target_type, (decimal) Value, Location);
1795 public class DecimalConstant : Constant {
1796 public readonly decimal Value;
1798 public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1799 : this (types.Decimal, d, loc)
1803 public DecimalConstant (TypeSpec type, decimal d, Location loc)
1807 eclass = ExprClass.Value;
1812 public override void Emit (EmitContext ec)
1816 int [] words = decimal.GetBits (Value);
1817 int power = (words [3] >> 16) & 0xff;
1820 if (Value <= int.MaxValue && Value >= int.MinValue) {
1821 m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1826 ec.EmitInt ((int) Value);
1827 ec.Emit (OpCodes.Newobj, m);
1831 if (Value <= long.MaxValue && Value >= long.MinValue) {
1832 m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1837 ec.EmitLong ((long) Value);
1838 ec.Emit (OpCodes.Newobj, m);
1843 ec.EmitInt (words [0]);
1844 ec.EmitInt (words [1]);
1845 ec.EmitInt (words [2]);
1848 ec.EmitInt (words [3] >> 31);
1853 m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1855 ec.Emit (OpCodes.Newobj, m);
1859 public override bool IsDefaultValue {
1865 public override bool IsNegative {
1871 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1873 switch (target_type.BuiltinType) {
1874 case BuiltinTypeSpec.Type.SByte:
1875 return new SByteConstant (target_type, (sbyte) Value, loc);
1876 case BuiltinTypeSpec.Type.Byte:
1877 return new ByteConstant (target_type, (byte) Value, loc);
1878 case BuiltinTypeSpec.Type.Short:
1879 return new ShortConstant (target_type, (short) Value, loc);
1880 case BuiltinTypeSpec.Type.UShort:
1881 return new UShortConstant (target_type, (ushort) Value, loc);
1882 case BuiltinTypeSpec.Type.Int:
1883 return new IntConstant (target_type, (int) Value, loc);
1884 case BuiltinTypeSpec.Type.UInt:
1885 return new UIntConstant (target_type, (uint) Value, loc);
1886 case BuiltinTypeSpec.Type.Long:
1887 return new LongConstant (target_type, (long) Value, loc);
1888 case BuiltinTypeSpec.Type.ULong:
1889 return new ULongConstant (target_type, (ulong) Value, loc);
1890 case BuiltinTypeSpec.Type.Char:
1891 return new CharConstant (target_type, (char) Value, loc);
1892 case BuiltinTypeSpec.Type.Float:
1893 return new FloatConstant (target_type, (float) Value, loc);
1894 case BuiltinTypeSpec.Type.Double:
1895 return new DoubleConstant (target_type, (double) Value, loc);
1901 public override object GetValue ()
1906 public override string GetValueAsLiteral ()
1908 return Value.ToString () + "M";
1911 public override long GetValueAsLong ()
1913 throw new NotSupportedException ();
1917 public class StringConstant : Constant {
1918 public readonly string Value;
1920 public StringConstant (BuiltinTypes types, string s, Location loc)
1921 : this (types.String, s, loc)
1925 public StringConstant (TypeSpec type, string s, Location loc)
1929 eclass = ExprClass.Value;
1934 public override object GetValue ()
1939 public override string GetValueAsLiteral ()
1941 // FIXME: Escape the string.
1942 return "\"" + Value + "\"";
1945 public override long GetValueAsLong ()
1947 throw new NotSupportedException ();
1950 public override void Emit (EmitContext ec)
1952 if (Value == null) {
1958 // Use string.Empty for both literals and constants even if
1959 // it's not allowed at language level
1961 if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
1962 var string_type = ec.BuiltinTypes.String;
1963 if (ec.CurrentType != string_type) {
1964 var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
1966 ec.Emit (OpCodes.Ldsfld, m);
1972 ec.Emit (OpCodes.Ldstr, Value);
1975 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1978 if (type != targetType)
1984 public override bool IsDefaultValue {
1986 return Value == null;
1990 public override bool IsNegative {
1996 public override bool IsNull {
1998 return IsDefaultValue;
2002 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2009 // Null constant can have its own type, think of `default (Foo)'
2011 public class NullConstant : Constant
2013 public NullConstant (TypeSpec type, Location loc)
2016 eclass = ExprClass.Value;
2020 public override Expression CreateExpressionTree (ResolveContext ec)
2022 if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2023 // Optimized version, also avoids referencing literal internal type
2024 Arguments args = new Arguments (1);
2025 args.Add (new Argument (this));
2026 return CreateExpressionFactoryCall (ec, "Constant", args);
2029 return base.CreateExpressionTree (ec);
2032 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2034 switch (targetType.BuiltinType) {
2035 case BuiltinTypeSpec.Type.Object:
2036 // Type it as string cast
2037 enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2038 goto case BuiltinTypeSpec.Type.String;
2039 case BuiltinTypeSpec.Type.String:
2040 case BuiltinTypeSpec.Type.Type:
2041 enc.Encode (byte.MaxValue);
2044 var ac = targetType as ArrayContainer;
2045 if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
2046 enc.Encode (uint.MaxValue);
2053 base.EncodeAttributeValue (rc, enc, targetType);
2056 public override void Emit (EmitContext ec)
2060 // Only to make verifier happy
2061 if (type.IsGenericParameter)
2062 ec.Emit (OpCodes.Unbox_Any, type);
2065 public override string ExprClassName {
2067 return GetSignatureForError ();
2071 public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2073 if (targetType.IsPointer) {
2074 if (IsLiteral || this is NullPointer)
2075 return new NullPointer (targetType, loc);
2080 // Exlude internal compiler types
2081 if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2084 if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2087 if (TypeSpec.IsReferenceType (targetType))
2088 return new NullConstant (targetType, loc);
2090 if (targetType.IsNullableType)
2091 return Nullable.LiftedNull.Create (targetType, loc);
2096 public override Constant ConvertImplicitly (TypeSpec targetType)
2098 return ConvertExplicitly (false, targetType);
2101 public override string GetSignatureForError ()
2106 public override object GetValue ()
2111 public override string GetValueAsLiteral ()
2113 return GetSignatureForError ();
2116 public override long GetValueAsLong ()
2118 throw new NotSupportedException ();
2121 public override bool IsDefaultValue {
2122 get { return true; }
2125 public override bool IsNegative {
2126 get { return false; }
2129 public override bool IsNull {
2130 get { return true; }
2133 public override bool IsZeroInteger {
2134 get { return true; }
2140 // A null constant in a pointer context
2142 class NullPointer : NullConstant
2144 public NullPointer (TypeSpec type, Location loc)
2149 public override Expression CreateExpressionTree (ResolveContext ec)
2151 Error_PointerInsideExpressionTree (ec);
2152 return base.CreateExpressionTree (ec);
2155 public override void Emit (EmitContext ec)
2158 // Emits null pointer
2161 ec.Emit (OpCodes.Conv_U);
2166 /// The value is constant, but when emitted has a side effect. This is
2167 /// used by BitwiseAnd to ensure that the second expression is invoked
2168 /// regardless of the value of the left side.
2170 public class SideEffectConstant : Constant
2172 public readonly Constant value;
2173 Expression side_effect;
2175 public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2180 eclass = ExprClass.Value;
2182 while (side_effect is SideEffectConstant)
2183 side_effect = ((SideEffectConstant) side_effect).side_effect;
2184 this.side_effect = side_effect;
2187 public override bool IsSideEffectFree {
2193 public override object GetValue ()
2195 return value.GetValue ();
2198 public override string GetValueAsLiteral ()
2200 return value.GetValueAsLiteral ();
2203 public override long GetValueAsLong ()
2205 return value.GetValueAsLong ();
2208 public override void Emit (EmitContext ec)
2210 side_effect.EmitSideEffect (ec);
2214 public override void EmitSideEffect (EmitContext ec)
2216 side_effect.EmitSideEffect (ec);
2217 value.EmitSideEffect (ec);
2220 public override bool IsDefaultValue {
2221 get { return value.IsDefaultValue; }
2224 public override bool IsNegative {
2225 get { return value.IsNegative; }
2228 public override bool IsZeroInteger {
2229 get { return value.IsZeroInteger; }
2232 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2234 Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2235 if (new_value == null)
2238 var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2239 c.type = target_type;