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 virtual Constant ConvertImplicitly (TypeSpec type)
83 if (this.type == type)
86 if (Convert.ImplicitNumericConversion (this, type) == null)
90 object constant_value = ChangeType (GetValue (), type, out fail);
93 // We should always catch the error before this is ever
94 // reached, by calling Convert.ImplicitStandardConversionExists
96 throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
97 TypeManager.CSharpName (Type), TypeManager.CSharpName (type));
100 return CreateConstant (type, constant_value, loc);
104 // Returns a constant instance based on Type
106 public static Constant CreateConstant (TypeSpec t, object v, Location loc)
108 return CreateConstantFromValue (t, v, loc);
111 public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
113 switch (t.BuiltinType) {
114 case BuiltinTypeSpec.Type.Int:
115 return new IntConstant (t, (int) v, loc);
116 case BuiltinTypeSpec.Type.String:
117 return new StringConstant (t, (string) v, loc);
118 case BuiltinTypeSpec.Type.UInt:
119 return new UIntConstant (t, (uint) v, loc);
120 case BuiltinTypeSpec.Type.Long:
121 return new LongConstant (t, (long) v, loc);
122 case BuiltinTypeSpec.Type.ULong:
123 return new ULongConstant (t, (ulong) v, loc);
124 case BuiltinTypeSpec.Type.Float:
125 return new FloatConstant (t, (float) v, loc);
126 case BuiltinTypeSpec.Type.Double:
127 return new DoubleConstant (t, (double) v, loc);
128 case BuiltinTypeSpec.Type.Short:
129 return new ShortConstant (t, (short) v, loc);
130 case BuiltinTypeSpec.Type.UShort:
131 return new UShortConstant (t, (ushort) v, loc);
132 case BuiltinTypeSpec.Type.SByte:
133 return new SByteConstant (t, (sbyte) v, loc);
134 case BuiltinTypeSpec.Type.Byte:
135 return new ByteConstant (t, (byte) v, loc);
136 case BuiltinTypeSpec.Type.Char:
137 return new CharConstant (t, (char) v, loc);
138 case BuiltinTypeSpec.Type.Bool:
139 return new BoolConstant (t, (bool) v, loc);
140 case BuiltinTypeSpec.Type.Decimal:
141 return new DecimalConstant (t, (decimal) v, loc);
145 var real_type = EnumSpec.GetUnderlyingType (t);
146 return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
150 if (t.IsNullableType)
151 return Nullable.LiftedNull.Create (t, loc);
153 if (TypeManager.IsReferenceType (t))
154 return new NullConstant (t, loc);
157 throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'",
158 v, TypeManager.CSharpName (t));
161 public override Expression CreateExpressionTree (ResolveContext ec)
163 Arguments args = new Arguments (2);
164 args.Add (new Argument (this));
165 args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
167 return CreateExpressionFactoryCall (ec, "Constant", args);
171 /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
172 /// It throws OverflowException
174 // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
175 public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
177 // This is a custom version of Convert.ChangeType() which works
178 // with the TypeBuilder defined types when compiling corlib.
179 static object ChangeType (object value, TypeSpec targetType, out bool error)
181 IConvertible convert_value = value as IConvertible;
183 if (convert_value == null) {
189 // We cannot rely on build-in type conversions as they are
190 // more limited than what C# supports.
191 // See char -> float/decimal/double conversion
195 switch (targetType.BuiltinType) {
196 case BuiltinTypeSpec.Type.Bool:
197 return convert_value.ToBoolean (nfi);
198 case BuiltinTypeSpec.Type.Byte:
199 return convert_value.ToByte (nfi);
200 case BuiltinTypeSpec.Type.Char:
201 return convert_value.ToChar (nfi);
202 case BuiltinTypeSpec.Type.Short:
203 return convert_value.ToInt16 (nfi);
204 case BuiltinTypeSpec.Type.Int:
205 return convert_value.ToInt32 (nfi);
206 case BuiltinTypeSpec.Type.Long:
207 return convert_value.ToInt64 (nfi);
208 case BuiltinTypeSpec.Type.SByte:
209 return convert_value.ToSByte (nfi);
210 case BuiltinTypeSpec.Type.Decimal:
211 if (convert_value.GetType () == typeof (char))
212 return (decimal) convert_value.ToInt32 (nfi);
213 return convert_value.ToDecimal (nfi);
214 case BuiltinTypeSpec.Type.Double:
215 if (convert_value.GetType () == typeof (char))
216 return (double) convert_value.ToInt32 (nfi);
217 return convert_value.ToDouble (nfi);
218 case BuiltinTypeSpec.Type.Float:
219 if (convert_value.GetType () == typeof (char))
220 return (float) convert_value.ToInt32 (nfi);
221 return convert_value.ToSingle (nfi);
222 case BuiltinTypeSpec.Type.String:
223 return convert_value.ToString (nfi);
224 case BuiltinTypeSpec.Type.UShort:
225 return convert_value.ToUInt16 (nfi);
226 case BuiltinTypeSpec.Type.UInt:
227 return convert_value.ToUInt32 (nfi);
228 case BuiltinTypeSpec.Type.ULong:
229 return convert_value.ToUInt64 (nfi);
230 case BuiltinTypeSpec.Type.Object:
240 protected override Expression DoResolve (ResolveContext rc)
246 /// Attempts to do a compile-time folding of a constant cast.
248 public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
251 return TryReduce (ec, target_type);
253 catch (OverflowException) {
254 if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
255 ec.Report.Error (221, loc,
256 "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
257 GetValueAsLiteral (), target_type.GetSignatureForError ());
259 Error_ValueCannotBeConverted (ec, loc, target_type, false);
262 return New.Constantify (target_type, loc);
266 Constant TryReduce (ResolveContext ec, TypeSpec target_type)
268 if (Type == target_type)
272 if (TypeManager.IsEnumType (target_type)) {
273 c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
277 return new EnumConstant (c, target_type);
280 return ConvertExplicitly (ec.ConstantCheckState, target_type);
284 /// Need to pass type as the constant can require a boxing
285 /// and in such case no optimization is possible
287 public bool IsDefaultInitializer (TypeSpec type)
290 return IsDefaultValue;
292 return this is NullLiteral;
295 public abstract bool IsDefaultValue {
299 public abstract bool IsNegative {
304 // When constant is declared as literal
306 public virtual bool IsLiteral {
307 get { return false; }
310 public virtual bool IsOneInteger {
311 get { return false; }
315 // Returns true iff 1) the stack type of this is one of Object,
316 // int32, int64 and 2) this == 0 or this == null.
318 public virtual bool IsZeroInteger {
319 get { return false; }
322 public override void EmitSideEffect (EmitContext ec)
327 public sealed override Expression Clone (CloneContext clonectx)
329 // No cloning is not needed for constants
333 protected override void CloneTo (CloneContext clonectx, Expression target)
335 throw new NotSupportedException ("should not be reached");
338 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
341 return base.MakeExpression (ctx);
343 return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
347 public new bool Resolve (ResolveContext rc)
349 // It exists only as hint not to call Resolve on constants
354 public abstract class IntegralConstant : Constant
356 protected IntegralConstant (TypeSpec type, Location loc)
360 eclass = ExprClass.Value;
363 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
366 ConvertExplicitly (true, target);
367 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
371 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
372 GetValue ().ToString (), TypeManager.CSharpName (target));
376 public override string GetValueAsLiteral ()
378 return GetValue ().ToString ();
381 public abstract Constant Increment ();
384 public class BoolConstant : Constant {
385 public readonly bool Value;
387 public BoolConstant (BuiltinTypes types, bool val, Location loc)
388 : this (types.Bool, val, loc)
392 public BoolConstant (TypeSpec type, bool val, Location loc)
395 eclass = ExprClass.Value;
401 public override object GetValue ()
403 return (object) Value;
406 public override string GetValueAsLiteral ()
408 return Value ? "true" : "false";
411 public override long GetValueAsLong ()
413 return Value ? 1 : 0;
416 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
421 public override void Emit (EmitContext ec)
424 ec.Emit (OpCodes.Ldc_I4_1);
426 ec.Emit (OpCodes.Ldc_I4_0);
429 public override bool IsDefaultValue {
435 public override bool IsNegative {
441 public override bool IsZeroInteger {
442 get { return Value == false; }
445 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
452 public class ByteConstant : IntegralConstant
454 public readonly byte Value;
456 public ByteConstant (BuiltinTypes types, byte v, Location loc)
457 : this (types.Byte, v, loc)
461 public ByteConstant (TypeSpec type, byte v, Location loc)
467 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
472 public override void Emit (EmitContext ec)
477 public override object GetValue ()
482 public override long GetValueAsLong ()
487 public override Constant Increment ()
489 return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
492 public override bool IsDefaultValue {
498 public override bool IsOneInteger {
504 public override bool IsNegative {
510 public override bool IsZeroInteger {
511 get { return Value == 0; }
514 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
516 switch (target_type.BuiltinType) {
517 case BuiltinTypeSpec.Type.SByte:
518 if (in_checked_context){
519 if (Value > SByte.MaxValue)
520 throw new OverflowException ();
522 return new SByteConstant (target_type, (sbyte) Value, Location);
523 case BuiltinTypeSpec.Type.Short:
524 return new ShortConstant (target_type, (short) Value, Location);
525 case BuiltinTypeSpec.Type.UShort:
526 return new UShortConstant (target_type, (ushort) Value, Location);
527 case BuiltinTypeSpec.Type.Int:
528 return new IntConstant (target_type, (int) Value, Location);
529 case BuiltinTypeSpec.Type.UInt:
530 return new UIntConstant (target_type, (uint) Value, Location);
531 case BuiltinTypeSpec.Type.Long:
532 return new LongConstant (target_type, (long) Value, Location);
533 case BuiltinTypeSpec.Type.ULong:
534 return new ULongConstant (target_type, (ulong) Value, Location);
535 case BuiltinTypeSpec.Type.Float:
536 return new FloatConstant (target_type, (float) Value, Location);
537 case BuiltinTypeSpec.Type.Double:
538 return new DoubleConstant (target_type, (double) Value, Location);
539 case BuiltinTypeSpec.Type.Char:
540 return new CharConstant (target_type, (char) Value, Location);
541 case BuiltinTypeSpec.Type.Decimal:
542 return new DecimalConstant (target_type, (decimal) Value, Location);
550 public class CharConstant : Constant {
551 public readonly char Value;
553 public CharConstant (BuiltinTypes types, char v, Location loc)
554 : this (types.Char, v, loc)
558 public CharConstant (TypeSpec type, char v, Location loc)
562 eclass = ExprClass.Value;
567 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
569 enc.Encode ((ushort) Value);
572 public override void Emit (EmitContext ec)
577 static string descape (char c)
603 return c.ToString ();
606 public override object GetValue ()
611 public override long GetValueAsLong ()
616 public override string GetValueAsLiteral ()
618 return "\"" + descape (Value) + "\"";
621 public override bool IsDefaultValue {
627 public override bool IsNegative {
633 public override bool IsZeroInteger {
634 get { return Value == '\0'; }
637 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
639 switch (target_type.BuiltinType) {
640 case BuiltinTypeSpec.Type.Byte:
641 if (in_checked_context) {
642 if (Value < Byte.MinValue || Value > Byte.MaxValue)
643 throw new OverflowException ();
645 return new ByteConstant (target_type, (byte) Value, Location);
646 case BuiltinTypeSpec.Type.SByte:
647 if (in_checked_context) {
648 if (Value > SByte.MaxValue)
649 throw new OverflowException ();
651 return new SByteConstant (target_type, (sbyte) Value, Location);
653 case BuiltinTypeSpec.Type.Short:
654 if (in_checked_context) {
655 if (Value > Int16.MaxValue)
656 throw new OverflowException ();
658 return new ShortConstant (target_type, (short) Value, Location);
659 case BuiltinTypeSpec.Type.Int:
660 return new IntConstant (target_type, (int) Value, Location);
661 case BuiltinTypeSpec.Type.UInt:
662 return new UIntConstant (target_type, (uint) Value, Location);
663 case BuiltinTypeSpec.Type.Long:
664 return new LongConstant (target_type, (long) Value, Location);
665 case BuiltinTypeSpec.Type.ULong:
666 return new ULongConstant (target_type, (ulong) Value, Location);
667 case BuiltinTypeSpec.Type.Float:
668 return new FloatConstant (target_type, (float) Value, Location);
669 case BuiltinTypeSpec.Type.Double:
670 return new DoubleConstant (target_type, (double) Value, Location);
671 case BuiltinTypeSpec.Type.Decimal:
672 return new DecimalConstant (target_type, (decimal) Value, Location);
680 public class SByteConstant : IntegralConstant
682 public readonly sbyte Value;
684 public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
685 : this (types.SByte, v, loc)
689 public SByteConstant (TypeSpec type, sbyte v, Location loc)
695 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
700 public override void Emit (EmitContext ec)
705 public override object GetValue ()
710 public override long GetValueAsLong ()
715 public override Constant Increment ()
717 return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
720 public override bool IsDefaultValue {
726 public override bool IsNegative {
732 public override bool IsOneInteger {
738 public override bool IsZeroInteger {
739 get { return Value == 0; }
742 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
744 switch (target_type.BuiltinType) {
745 case BuiltinTypeSpec.Type.Byte:
746 if (in_checked_context && Value < 0)
747 throw new OverflowException ();
748 return new ByteConstant (target_type, (byte) Value, Location);
749 case BuiltinTypeSpec.Type.Short:
750 return new ShortConstant (target_type, (short) Value, Location);
751 case BuiltinTypeSpec.Type.UShort:
752 if (in_checked_context && Value < 0)
753 throw new OverflowException ();
754 return new UShortConstant (target_type, (ushort) Value, Location);
755 case BuiltinTypeSpec.Type.Int:
756 return new IntConstant (target_type, (int) Value, Location);
757 case BuiltinTypeSpec.Type.UInt:
758 if (in_checked_context && Value < 0)
759 throw new OverflowException ();
760 return new UIntConstant (target_type, (uint) Value, Location);
761 case BuiltinTypeSpec.Type.Long:
762 return new LongConstant (target_type, (long) Value, Location);
763 case BuiltinTypeSpec.Type.ULong:
764 if (in_checked_context && Value < 0)
765 throw new OverflowException ();
766 return new ULongConstant (target_type, (ulong) Value, Location);
767 case BuiltinTypeSpec.Type.Float:
768 return new FloatConstant (target_type, (float) Value, Location);
769 case BuiltinTypeSpec.Type.Double:
770 return new DoubleConstant (target_type, (double) Value, Location);
771 case BuiltinTypeSpec.Type.Char:
772 if (in_checked_context && Value < 0)
773 throw new OverflowException ();
774 return new CharConstant (target_type, (char) Value, Location);
775 case BuiltinTypeSpec.Type.Decimal:
776 return new DecimalConstant (target_type, (decimal) Value, Location);
784 public class ShortConstant : IntegralConstant {
785 public readonly short Value;
787 public ShortConstant (BuiltinTypes types, short v, Location loc)
788 : this (types.Short, v, loc)
792 public ShortConstant (TypeSpec type, short v, Location loc)
798 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
803 public override void Emit (EmitContext ec)
808 public override object GetValue ()
813 public override long GetValueAsLong ()
818 public override Constant Increment ()
820 return new ShortConstant (type, checked((short)(Value + 1)), loc);
823 public override bool IsDefaultValue {
829 public override bool IsZeroInteger {
830 get { return Value == 0; }
833 public override bool IsNegative {
839 public override bool IsOneInteger {
845 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
847 switch (target_type.BuiltinType) {
848 case BuiltinTypeSpec.Type.Byte:
849 if (in_checked_context) {
850 if (Value < Byte.MinValue || Value > Byte.MaxValue)
851 throw new OverflowException ();
853 return new ByteConstant (target_type, (byte) Value, Location);
854 case BuiltinTypeSpec.Type.SByte:
855 if (in_checked_context) {
856 if (Value < SByte.MinValue || Value > SByte.MaxValue)
857 throw new OverflowException ();
859 return new SByteConstant (target_type, (sbyte) Value, Location);
860 case BuiltinTypeSpec.Type.UShort:
861 if (in_checked_context && Value < 0)
862 throw new OverflowException ();
864 return new UShortConstant (target_type, (ushort) Value, Location);
865 case BuiltinTypeSpec.Type.Int:
866 return new IntConstant (target_type, (int) Value, Location);
867 case BuiltinTypeSpec.Type.UInt:
868 if (in_checked_context && Value < 0)
869 throw new OverflowException ();
870 return new UIntConstant (target_type, (uint) Value, Location);
871 case BuiltinTypeSpec.Type.Long:
872 return new LongConstant (target_type, (long) Value, Location);
873 case BuiltinTypeSpec.Type.ULong:
874 if (in_checked_context && Value < 0)
875 throw new OverflowException ();
876 return new ULongConstant (target_type, (ulong) Value, Location);
877 case BuiltinTypeSpec.Type.Float:
878 return new FloatConstant (target_type, (float) Value, Location);
879 case BuiltinTypeSpec.Type.Double:
880 return new DoubleConstant (target_type, (double) Value, Location);
881 case BuiltinTypeSpec.Type.Char:
882 if (in_checked_context) {
883 if (Value < Char.MinValue)
884 throw new OverflowException ();
886 return new CharConstant (target_type, (char) Value, Location);
887 case BuiltinTypeSpec.Type.Decimal:
888 return new DecimalConstant (target_type, (decimal) Value, Location);
896 public class UShortConstant : IntegralConstant
898 public readonly ushort Value;
900 public UShortConstant (BuiltinTypes types, ushort v, Location loc)
901 : this (types.UShort, v, loc)
905 public UShortConstant (TypeSpec type, ushort v, Location loc)
911 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
916 public override void Emit (EmitContext ec)
921 public override object GetValue ()
926 public override long GetValueAsLong ()
931 public override Constant Increment ()
933 return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
936 public override bool IsDefaultValue {
942 public override bool IsNegative {
948 public override bool IsOneInteger {
954 public override bool IsZeroInteger {
955 get { return Value == 0; }
958 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
960 switch (target_type.BuiltinType) {
961 case BuiltinTypeSpec.Type.Byte:
962 if (in_checked_context) {
963 if (Value > Byte.MaxValue)
964 throw new OverflowException ();
966 return new ByteConstant (target_type, (byte) Value, Location);
967 case BuiltinTypeSpec.Type.SByte:
968 if (in_checked_context) {
969 if (Value > SByte.MaxValue)
970 throw new OverflowException ();
972 return new SByteConstant (target_type, (sbyte) Value, Location);
973 case BuiltinTypeSpec.Type.Short:
974 if (in_checked_context) {
975 if (Value > Int16.MaxValue)
976 throw new OverflowException ();
978 return new ShortConstant (target_type, (short) Value, Location);
979 case BuiltinTypeSpec.Type.Int:
980 return new IntConstant (target_type, (int) Value, Location);
981 case BuiltinTypeSpec.Type.UInt:
982 return new UIntConstant (target_type, (uint) Value, Location);
983 case BuiltinTypeSpec.Type.Long:
984 return new LongConstant (target_type, (long) Value, Location);
985 case BuiltinTypeSpec.Type.ULong:
986 return new ULongConstant (target_type, (ulong) Value, Location);
987 case BuiltinTypeSpec.Type.Float:
988 return new FloatConstant (target_type, (float) Value, Location);
989 case BuiltinTypeSpec.Type.Double:
990 return new DoubleConstant (target_type, (double) Value, Location);
991 case BuiltinTypeSpec.Type.Char:
992 if (in_checked_context) {
993 if (Value > Char.MaxValue)
994 throw new OverflowException ();
996 return new CharConstant (target_type, (char) Value, Location);
997 case BuiltinTypeSpec.Type.Decimal:
998 return new DecimalConstant (target_type, (decimal) Value, Location);
1005 public class IntConstant : IntegralConstant
1007 public readonly int Value;
1009 public IntConstant (BuiltinTypes types, int v, Location loc)
1010 : this (types.Int, v, loc)
1014 public IntConstant (TypeSpec type, int v, Location loc)
1020 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1025 public override void Emit (EmitContext ec)
1030 public override object GetValue ()
1035 public override long GetValueAsLong ()
1040 public override Constant Increment ()
1042 return new IntConstant (type, checked(Value + 1), loc);
1045 public override bool IsDefaultValue {
1051 public override bool IsNegative {
1057 public override bool IsOneInteger {
1063 public override bool IsZeroInteger {
1064 get { return Value == 0; }
1067 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1069 switch (target_type.BuiltinType) {
1070 case BuiltinTypeSpec.Type.Byte:
1071 if (in_checked_context) {
1072 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1073 throw new OverflowException ();
1075 return new ByteConstant (target_type, (byte) Value, Location);
1076 case BuiltinTypeSpec.Type.SByte:
1077 if (in_checked_context) {
1078 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1079 throw new OverflowException ();
1081 return new SByteConstant (target_type, (sbyte) Value, Location);
1082 case BuiltinTypeSpec.Type.Short:
1083 if (in_checked_context) {
1084 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1085 throw new OverflowException ();
1087 return new ShortConstant (target_type, (short) Value, Location);
1088 case BuiltinTypeSpec.Type.UShort:
1089 if (in_checked_context) {
1090 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1091 throw new OverflowException ();
1093 return new UShortConstant (target_type, (ushort) Value, Location);
1094 case BuiltinTypeSpec.Type.UInt:
1095 if (in_checked_context) {
1096 if (Value < UInt32.MinValue)
1097 throw new OverflowException ();
1099 return new UIntConstant (target_type, (uint) Value, Location);
1100 case BuiltinTypeSpec.Type.Long:
1101 return new LongConstant (target_type, (long) Value, Location);
1102 case BuiltinTypeSpec.Type.ULong:
1103 if (in_checked_context && Value < 0)
1104 throw new OverflowException ();
1105 return new ULongConstant (target_type, (ulong) Value, Location);
1106 case BuiltinTypeSpec.Type.Float:
1107 return new FloatConstant (target_type, (float) Value, Location);
1108 case BuiltinTypeSpec.Type.Double:
1109 return new DoubleConstant (target_type, (double) Value, Location);
1110 case BuiltinTypeSpec.Type.Char:
1111 if (in_checked_context) {
1112 if (Value < Char.MinValue || Value > Char.MaxValue)
1113 throw new OverflowException ();
1115 return new CharConstant (target_type, (char) Value, Location);
1116 case BuiltinTypeSpec.Type.Decimal:
1117 return new DecimalConstant (target_type, (decimal) Value, Location);
1123 public override Constant ConvertImplicitly (TypeSpec type)
1125 if (this.type == type)
1128 Constant c = TryImplicitIntConversion (type);
1130 return c; //.Resolve (rc);
1132 return base.ConvertImplicitly (type);
1136 /// Attempts to perform an implicit constant conversion of the IntConstant
1137 /// into a different data type using casts (See Implicit Constant
1138 /// Expression Conversions)
1140 Constant TryImplicitIntConversion (TypeSpec target_type)
1142 switch (target_type.BuiltinType) {
1143 case BuiltinTypeSpec.Type.SByte:
1144 if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1145 return new SByteConstant (target_type, (sbyte) Value, loc);
1147 case BuiltinTypeSpec.Type.Byte:
1148 if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1149 return new ByteConstant (target_type, (byte) Value, loc);
1151 case BuiltinTypeSpec.Type.Short:
1152 if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1153 return new ShortConstant (target_type, (short) Value, loc);
1155 case BuiltinTypeSpec.Type.UShort:
1156 if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1157 return new UShortConstant (target_type, (ushort) Value, loc);
1159 case BuiltinTypeSpec.Type.UInt:
1161 return new UIntConstant (target_type, (uint) Value, loc);
1163 case BuiltinTypeSpec.Type.ULong:
1165 // we can optimize this case: a positive int32
1166 // always fits on a uint64. But we need an opcode
1170 return new ULongConstant (target_type, (ulong) Value, loc);
1172 case BuiltinTypeSpec.Type.Double:
1173 return new DoubleConstant (target_type, (double) Value, loc);
1174 case BuiltinTypeSpec.Type.Float:
1175 return new FloatConstant (target_type, (float) Value, loc);
1182 public class UIntConstant : IntegralConstant {
1183 public readonly uint Value;
1185 public UIntConstant (BuiltinTypes types, uint v, Location loc)
1186 : this (types.UInt, v, loc)
1190 public UIntConstant (TypeSpec type, uint v, Location loc)
1196 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1201 public override void Emit (EmitContext ec)
1203 ec.EmitInt (unchecked ((int) Value));
1206 public override object GetValue ()
1211 public override long GetValueAsLong ()
1216 public override Constant Increment ()
1218 return new UIntConstant (type, checked(Value + 1), loc);
1221 public override bool IsDefaultValue {
1227 public override bool IsNegative {
1233 public override bool IsOneInteger {
1239 public override bool IsZeroInteger {
1240 get { return Value == 0; }
1243 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1245 switch (target_type.BuiltinType) {
1246 case BuiltinTypeSpec.Type.Byte:
1247 if (in_checked_context) {
1248 if (Value < 0 || Value > byte.MaxValue)
1249 throw new OverflowException ();
1251 return new ByteConstant (target_type, (byte) Value, Location);
1252 case BuiltinTypeSpec.Type.SByte:
1253 if (in_checked_context) {
1254 if (Value > SByte.MaxValue)
1255 throw new OverflowException ();
1257 return new SByteConstant (target_type, (sbyte) Value, Location);
1258 case BuiltinTypeSpec.Type.Short:
1259 if (in_checked_context) {
1260 if (Value > Int16.MaxValue)
1261 throw new OverflowException ();
1263 return new ShortConstant (target_type, (short) Value, Location);
1264 case BuiltinTypeSpec.Type.UShort:
1265 if (in_checked_context) {
1266 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1267 throw new OverflowException ();
1269 return new UShortConstant (target_type, (ushort) Value, Location);
1270 case BuiltinTypeSpec.Type.Int:
1271 if (in_checked_context) {
1272 if (Value > Int32.MaxValue)
1273 throw new OverflowException ();
1275 return new IntConstant (target_type, (int) Value, Location);
1276 case BuiltinTypeSpec.Type.Long:
1277 return new LongConstant (target_type, (long) Value, Location);
1278 case BuiltinTypeSpec.Type.ULong:
1279 return new ULongConstant (target_type, (ulong) Value, Location);
1280 case BuiltinTypeSpec.Type.Float:
1281 return new FloatConstant (target_type, (float) Value, Location);
1282 case BuiltinTypeSpec.Type.Double:
1283 return new DoubleConstant (target_type, (double) Value, Location);
1284 case BuiltinTypeSpec.Type.Char:
1285 if (in_checked_context) {
1286 if (Value < Char.MinValue || Value > Char.MaxValue)
1287 throw new OverflowException ();
1289 return new CharConstant (target_type, (char) Value, Location);
1290 case BuiltinTypeSpec.Type.Decimal:
1291 return new DecimalConstant (target_type, (decimal) Value, Location);
1299 public class LongConstant : IntegralConstant {
1300 public readonly long Value;
1302 public LongConstant (BuiltinTypes types, long v, Location loc)
1303 : this (types.Long, v, loc)
1307 public LongConstant (TypeSpec type, long v, Location loc)
1313 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1318 public override void Emit (EmitContext ec)
1320 ec.EmitLong (Value);
1323 public override object GetValue ()
1328 public override long GetValueAsLong ()
1333 public override Constant Increment ()
1335 return new LongConstant (type, checked(Value + 1), loc);
1338 public override bool IsDefaultValue {
1344 public override bool IsNegative {
1350 public override bool IsOneInteger {
1356 public override bool IsZeroInteger {
1357 get { return Value == 0; }
1360 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1362 switch (target_type.BuiltinType) {
1363 case BuiltinTypeSpec.Type.Byte:
1364 if (in_checked_context) {
1365 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1366 throw new OverflowException ();
1368 return new ByteConstant (target_type, (byte) Value, Location);
1369 case BuiltinTypeSpec.Type.SByte:
1370 if (in_checked_context) {
1371 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1372 throw new OverflowException ();
1374 return new SByteConstant (target_type, (sbyte) Value, Location);
1375 case BuiltinTypeSpec.Type.Short:
1376 if (in_checked_context) {
1377 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1378 throw new OverflowException ();
1380 return new ShortConstant (target_type, (short) Value, Location);
1381 case BuiltinTypeSpec.Type.UShort:
1382 if (in_checked_context) {
1383 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1384 throw new OverflowException ();
1386 return new UShortConstant (target_type, (ushort) Value, Location);
1387 case BuiltinTypeSpec.Type.Int:
1388 if (in_checked_context) {
1389 if (Value < Int32.MinValue || Value > Int32.MaxValue)
1390 throw new OverflowException ();
1392 return new IntConstant (target_type, (int) Value, Location);
1393 case BuiltinTypeSpec.Type.UInt:
1394 if (in_checked_context) {
1395 if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1396 throw new OverflowException ();
1398 return new UIntConstant (target_type, (uint) Value, Location);
1399 case BuiltinTypeSpec.Type.ULong:
1400 if (in_checked_context && Value < 0)
1401 throw new OverflowException ();
1402 return new ULongConstant (target_type, (ulong) Value, Location);
1403 case BuiltinTypeSpec.Type.Float:
1404 return new FloatConstant (target_type, (float) Value, Location);
1405 case BuiltinTypeSpec.Type.Double:
1406 return new DoubleConstant (target_type, (double) Value, Location);
1407 case BuiltinTypeSpec.Type.Char:
1408 if (in_checked_context) {
1409 if (Value < Char.MinValue || Value > Char.MaxValue)
1410 throw new OverflowException ();
1412 return new CharConstant (target_type, (char) Value, Location);
1413 case BuiltinTypeSpec.Type.Decimal:
1414 return new DecimalConstant (target_type, (decimal) Value, Location);
1420 public override Constant ConvertImplicitly (TypeSpec type)
1422 if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
1423 return new ULongConstant (type, (ulong) Value, loc);
1426 return base.ConvertImplicitly (type);
1430 public class ULongConstant : IntegralConstant {
1431 public readonly ulong Value;
1433 public ULongConstant (BuiltinTypes types, ulong v, Location loc)
1434 : this (types.ULong, v, loc)
1438 public ULongConstant (TypeSpec type, ulong v, Location loc)
1444 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1449 public override void Emit (EmitContext ec)
1451 ec.EmitLong (unchecked ((long) Value));
1454 public override object GetValue ()
1459 public override long GetValueAsLong ()
1461 return (long) Value;
1464 public override Constant Increment ()
1466 return new ULongConstant (type, checked(Value + 1), loc);
1469 public override bool IsDefaultValue {
1475 public override bool IsNegative {
1481 public override bool IsOneInteger {
1487 public override bool IsZeroInteger {
1488 get { return Value == 0; }
1491 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1493 switch (target_type.BuiltinType) {
1494 case BuiltinTypeSpec.Type.Byte:
1495 if (in_checked_context && Value > Byte.MaxValue)
1496 throw new OverflowException ();
1497 return new ByteConstant (target_type, (byte) Value, Location);
1498 case BuiltinTypeSpec.Type.SByte:
1499 if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1500 throw new OverflowException ();
1501 return new SByteConstant (target_type, (sbyte) Value, Location);
1502 case BuiltinTypeSpec.Type.Short:
1503 if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1504 throw new OverflowException ();
1505 return new ShortConstant (target_type, (short) Value, Location);
1506 case BuiltinTypeSpec.Type.UShort:
1507 if (in_checked_context && Value > UInt16.MaxValue)
1508 throw new OverflowException ();
1509 return new UShortConstant (target_type, (ushort) Value, Location);
1510 case BuiltinTypeSpec.Type.Int:
1511 if (in_checked_context && Value > UInt32.MaxValue)
1512 throw new OverflowException ();
1513 return new IntConstant (target_type, (int) Value, Location);
1514 case BuiltinTypeSpec.Type.UInt:
1515 if (in_checked_context && Value > UInt32.MaxValue)
1516 throw new OverflowException ();
1517 return new UIntConstant (target_type, (uint) Value, Location);
1518 case BuiltinTypeSpec.Type.Long:
1519 if (in_checked_context && Value > Int64.MaxValue)
1520 throw new OverflowException ();
1521 return new LongConstant (target_type, (long) Value, Location);
1522 case BuiltinTypeSpec.Type.Float:
1523 return new FloatConstant (target_type, (float) Value, Location);
1524 case BuiltinTypeSpec.Type.Double:
1525 return new DoubleConstant (target_type, (double) Value, Location);
1526 case BuiltinTypeSpec.Type.Char:
1527 if (in_checked_context && Value > Char.MaxValue)
1528 throw new OverflowException ();
1529 return new CharConstant (target_type, (char) Value, Location);
1530 case BuiltinTypeSpec.Type.Decimal:
1531 return new DecimalConstant (target_type, (decimal) Value, Location);
1539 public class FloatConstant : Constant {
1540 public readonly float Value;
1542 public FloatConstant (BuiltinTypes types, float v, Location loc)
1543 : this (types.Float, v, loc)
1547 public FloatConstant (TypeSpec type, float v, Location loc)
1551 eclass = ExprClass.Value;
1556 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1561 public override void Emit (EmitContext ec)
1563 ec.Emit (OpCodes.Ldc_R4, Value);
1566 public override object GetValue ()
1571 public override string GetValueAsLiteral ()
1573 return Value.ToString ();
1576 public override long GetValueAsLong ()
1578 throw new NotSupportedException ();
1581 public override bool IsDefaultValue {
1587 public override bool IsNegative {
1593 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1595 switch (target_type.BuiltinType) {
1596 case BuiltinTypeSpec.Type.Byte:
1597 if (in_checked_context) {
1598 if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1599 throw new OverflowException ();
1601 return new ByteConstant (target_type, (byte) Value, Location);
1602 case BuiltinTypeSpec.Type.SByte:
1603 if (in_checked_context) {
1604 if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1605 throw new OverflowException ();
1607 return new SByteConstant (target_type, (sbyte) Value, Location);
1608 case BuiltinTypeSpec.Type.Short:
1609 if (in_checked_context) {
1610 if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1611 throw new OverflowException ();
1613 return new ShortConstant (target_type, (short) Value, Location);
1614 case BuiltinTypeSpec.Type.UShort:
1615 if (in_checked_context) {
1616 if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1617 throw new OverflowException ();
1619 return new UShortConstant (target_type, (ushort) Value, Location);
1620 case BuiltinTypeSpec.Type.Int:
1621 if (in_checked_context) {
1622 if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1623 throw new OverflowException ();
1625 return new IntConstant (target_type, (int) Value, Location);
1626 case BuiltinTypeSpec.Type.UInt:
1627 if (in_checked_context) {
1628 if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1629 throw new OverflowException ();
1631 return new UIntConstant (target_type, (uint) Value, Location);
1632 case BuiltinTypeSpec.Type.Long:
1633 if (in_checked_context) {
1634 if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1635 throw new OverflowException ();
1637 return new LongConstant (target_type, (long) Value, Location);
1638 case BuiltinTypeSpec.Type.ULong:
1639 if (in_checked_context) {
1640 if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1641 throw new OverflowException ();
1643 return new ULongConstant (target_type, (ulong) Value, Location);
1644 case BuiltinTypeSpec.Type.Double:
1645 return new DoubleConstant (target_type, (double) Value, Location);
1646 case BuiltinTypeSpec.Type.Char:
1647 if (in_checked_context) {
1648 if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1649 throw new OverflowException ();
1651 return new CharConstant (target_type, (char) Value, Location);
1652 case BuiltinTypeSpec.Type.Decimal:
1653 return new DecimalConstant (target_type, (decimal) Value, Location);
1661 public class DoubleConstant : Constant
1663 public readonly double Value;
1665 public DoubleConstant (BuiltinTypes types, double v, Location loc)
1666 : this (types.Double, v, loc)
1670 public DoubleConstant (TypeSpec type, double v, Location loc)
1674 eclass = ExprClass.Value;
1679 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1684 public override void Emit (EmitContext ec)
1686 ec.Emit (OpCodes.Ldc_R8, Value);
1689 public override object GetValue ()
1694 public override string GetValueAsLiteral ()
1696 return Value.ToString ();
1699 public override long GetValueAsLong ()
1701 throw new NotSupportedException ();
1704 public override bool IsDefaultValue {
1710 public override bool IsNegative {
1716 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1718 switch (target_type.BuiltinType) {
1719 case BuiltinTypeSpec.Type.Byte:
1720 if (in_checked_context) {
1721 if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1722 throw new OverflowException ();
1724 return new ByteConstant (target_type, (byte) Value, Location);
1725 case BuiltinTypeSpec.Type.SByte:
1726 if (in_checked_context) {
1727 if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1728 throw new OverflowException ();
1730 return new SByteConstant (target_type, (sbyte) Value, Location);
1731 case BuiltinTypeSpec.Type.Short:
1732 if (in_checked_context) {
1733 if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1734 throw new OverflowException ();
1736 return new ShortConstant (target_type, (short) Value, Location);
1737 case BuiltinTypeSpec.Type.UShort:
1738 if (in_checked_context) {
1739 if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1740 throw new OverflowException ();
1742 return new UShortConstant (target_type, (ushort) Value, Location);
1743 case BuiltinTypeSpec.Type.Int:
1744 if (in_checked_context) {
1745 if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1746 throw new OverflowException ();
1748 return new IntConstant (target_type, (int) Value, Location);
1749 case BuiltinTypeSpec.Type.UInt:
1750 if (in_checked_context) {
1751 if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1752 throw new OverflowException ();
1754 return new UIntConstant (target_type, (uint) Value, Location);
1755 case BuiltinTypeSpec.Type.Long:
1756 if (in_checked_context) {
1757 if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1758 throw new OverflowException ();
1760 return new LongConstant (target_type, (long) Value, Location);
1761 case BuiltinTypeSpec.Type.ULong:
1762 if (in_checked_context) {
1763 if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1764 throw new OverflowException ();
1766 return new ULongConstant (target_type, (ulong) Value, Location);
1767 case BuiltinTypeSpec.Type.Float:
1768 return new FloatConstant (target_type, (float) Value, Location);
1769 case BuiltinTypeSpec.Type.Char:
1770 if (in_checked_context) {
1771 if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1772 throw new OverflowException ();
1774 return new CharConstant (target_type, (char) Value, Location);
1775 case BuiltinTypeSpec.Type.Decimal:
1776 return new DecimalConstant (target_type, (decimal) Value, Location);
1784 public class DecimalConstant : Constant {
1785 public readonly decimal Value;
1787 public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1788 : this (types.Decimal, d, loc)
1792 public DecimalConstant (TypeSpec type, decimal d, Location loc)
1796 eclass = ExprClass.Value;
1801 public override void Emit (EmitContext ec)
1805 int [] words = decimal.GetBits (Value);
1806 int power = (words [3] >> 16) & 0xff;
1809 if (Value <= int.MaxValue && Value >= int.MinValue) {
1810 m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1815 ec.EmitInt ((int) Value);
1816 ec.Emit (OpCodes.Newobj, m);
1820 if (Value <= long.MaxValue && Value >= long.MinValue) {
1821 m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1826 ec.EmitLong ((long) Value);
1827 ec.Emit (OpCodes.Newobj, m);
1832 ec.EmitInt (words [0]);
1833 ec.EmitInt (words [1]);
1834 ec.EmitInt (words [2]);
1837 ec.EmitInt (words [3] >> 31);
1842 m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1844 ec.Emit (OpCodes.Newobj, m);
1848 public override bool IsDefaultValue {
1854 public override bool IsNegative {
1860 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1862 switch (target_type.BuiltinType) {
1863 case BuiltinTypeSpec.Type.SByte:
1864 return new SByteConstant (target_type, (sbyte) Value, loc);
1865 case BuiltinTypeSpec.Type.Byte:
1866 return new ByteConstant (target_type, (byte) Value, loc);
1867 case BuiltinTypeSpec.Type.Short:
1868 return new ShortConstant (target_type, (short) Value, loc);
1869 case BuiltinTypeSpec.Type.UShort:
1870 return new UShortConstant (target_type, (ushort) Value, loc);
1871 case BuiltinTypeSpec.Type.Int:
1872 return new IntConstant (target_type, (int) Value, loc);
1873 case BuiltinTypeSpec.Type.UInt:
1874 return new UIntConstant (target_type, (uint) Value, loc);
1875 case BuiltinTypeSpec.Type.Long:
1876 return new LongConstant (target_type, (long) Value, loc);
1877 case BuiltinTypeSpec.Type.ULong:
1878 return new ULongConstant (target_type, (ulong) Value, loc);
1879 case BuiltinTypeSpec.Type.Char:
1880 return new CharConstant (target_type, (char) Value, loc);
1881 case BuiltinTypeSpec.Type.Float:
1882 return new FloatConstant (target_type, (float) Value, loc);
1883 case BuiltinTypeSpec.Type.Double:
1884 return new DoubleConstant (target_type, (double) Value, loc);
1890 public override object GetValue ()
1895 public override string GetValueAsLiteral ()
1897 return Value.ToString () + "M";
1900 public override long GetValueAsLong ()
1902 throw new NotSupportedException ();
1906 public class StringConstant : Constant {
1907 public readonly string Value;
1909 public StringConstant (BuiltinTypes types, string s, Location loc)
1910 : this (types.String, s, loc)
1914 public StringConstant (TypeSpec type, string s, Location loc)
1918 eclass = ExprClass.Value;
1923 public override object GetValue ()
1928 public override string GetValueAsLiteral ()
1930 // FIXME: Escape the string.
1931 return "\"" + Value + "\"";
1934 public override long GetValueAsLong ()
1936 throw new NotSupportedException ();
1939 public override void Emit (EmitContext ec)
1941 if (Value == null) {
1942 ec.Emit (OpCodes.Ldnull);
1947 // Use string.Empty for both literals and constants even if
1948 // it's not allowed at language level
1950 if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
1951 var string_type = ec.BuiltinTypes.String;
1952 if (ec.CurrentType != string_type) {
1953 var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
1955 ec.Emit (OpCodes.Ldsfld, m);
1961 ec.Emit (OpCodes.Ldstr, Value);
1964 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1967 if (type != targetType)
1973 public override bool IsDefaultValue {
1975 return Value == null;
1979 public override bool IsNegative {
1985 public override bool IsNull {
1987 return IsDefaultValue;
1991 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1998 // Null constant can have its own type, think of `default (Foo)'
2000 public class NullConstant : Constant
2002 public NullConstant (TypeSpec type, Location loc)
2005 eclass = ExprClass.Value;
2009 public override Expression CreateExpressionTree (ResolveContext ec)
2011 if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2012 // Optimized version, also avoids referencing literal internal type
2013 Arguments args = new Arguments (1);
2014 args.Add (new Argument (this));
2015 return CreateExpressionFactoryCall (ec, "Constant", args);
2018 return base.CreateExpressionTree (ec);
2021 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2023 // Type it as string cast
2024 if (targetType.BuiltinType == BuiltinTypeSpec.Type.Object)
2025 enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2027 var ac = targetType as ArrayContainer;
2029 if (ac.Rank != 1 || ac.Element.IsArray)
2030 base.EncodeAttributeValue (rc, enc, targetType);
2032 enc.Encode (uint.MaxValue);
2034 enc.Encode (byte.MaxValue);
2038 public override void Emit (EmitContext ec)
2040 ec.Emit (OpCodes.Ldnull);
2042 // Only to make verifier happy
2043 if (type.IsGenericParameter)
2044 ec.Emit (OpCodes.Unbox_Any, type);
2047 public override string ExprClassName {
2049 return GetSignatureForError ();
2053 public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2055 if (targetType.IsPointer) {
2056 if (IsLiteral || this is NullPointer)
2057 return new NullPointer (targetType, loc);
2062 // Exlude internal compiler types
2063 if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2066 if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2069 if (TypeManager.IsReferenceType (targetType))
2070 return new NullConstant (targetType, loc);
2072 if (targetType.IsNullableType)
2073 return Nullable.LiftedNull.Create (targetType, loc);
2078 public override Constant ConvertImplicitly (TypeSpec targetType)
2080 return ConvertExplicitly (false, targetType);
2083 public override string GetSignatureForError ()
2088 public override object GetValue ()
2093 public override string GetValueAsLiteral ()
2095 return GetSignatureForError ();
2098 public override long GetValueAsLong ()
2100 throw new NotSupportedException ();
2103 public override bool IsDefaultValue {
2104 get { return true; }
2107 public override bool IsNegative {
2108 get { return false; }
2111 public override bool IsNull {
2112 get { return true; }
2115 public override bool IsZeroInteger {
2116 get { return true; }
2122 // A null constant in a pointer context
2124 class NullPointer : NullConstant
2126 public NullPointer (TypeSpec type, Location loc)
2131 public override Expression CreateExpressionTree (ResolveContext ec)
2133 Error_PointerInsideExpressionTree (ec);
2134 return base.CreateExpressionTree (ec);
2137 public override void Emit (EmitContext ec)
2140 // Emits null pointer
2142 ec.Emit (OpCodes.Ldc_I4_0);
2143 ec.Emit (OpCodes.Conv_U);
2148 /// The value is constant, but when emitted has a side effect. This is
2149 /// used by BitwiseAnd to ensure that the second expression is invoked
2150 /// regardless of the value of the left side.
2152 public class SideEffectConstant : Constant {
2153 public readonly Constant value;
2154 Expression side_effect;
2156 public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2161 eclass = ExprClass.Value;
2163 while (side_effect is SideEffectConstant)
2164 side_effect = ((SideEffectConstant) side_effect).side_effect;
2165 this.side_effect = side_effect;
2168 public override object GetValue ()
2170 return value.GetValue ();
2173 public override string GetValueAsLiteral ()
2175 return value.GetValueAsLiteral ();
2178 public override long GetValueAsLong ()
2180 return value.GetValueAsLong ();
2183 public override void Emit (EmitContext ec)
2185 side_effect.EmitSideEffect (ec);
2189 public override void EmitSideEffect (EmitContext ec)
2191 side_effect.EmitSideEffect (ec);
2192 value.EmitSideEffect (ec);
2195 public override bool IsDefaultValue {
2196 get { return value.IsDefaultValue; }
2199 public override bool IsNegative {
2200 get { return value.IsNegative; }
2203 public override bool IsZeroInteger {
2204 get { return value.IsZeroInteger; }
2207 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2209 Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2210 if (new_value == null)
2213 var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2214 c.type = target_type;