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.Reflection.Emit;
15 namespace Mono.CSharp {
18 /// Base class for constants and literals.
20 public abstract class Constant : Expression {
22 protected Constant (Location loc)
28 /// This is different from ToString in that ToString
29 /// is supposed to be there for debugging purposes,
30 /// and is not guaranteed to be useful for anything else,
31 /// AsString() will provide something that can be used
32 /// for round-tripping C# code. Maybe it can be used
33 /// for IL assembly as well.
35 public abstract string AsString ();
37 override public string ToString ()
39 return this.GetType ().Name + " (" + AsString () + ")";
42 public override bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
44 if (value_type == TypeManager.object_type) {
45 value = GetTypedValue ();
49 Constant c = ImplicitConversionRequired (ec, value_type, loc);
55 value = c.GetTypedValue ();
60 /// This is used to obtain the actual value of the literal
61 /// cast into an object.
63 public abstract object GetValue ();
65 public virtual object GetTypedValue ()
70 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
72 if (!expl && IsLiteral &&
73 (TypeManager.IsPrimitiveType (target) || type == TypeManager.decimal_type) &&
74 (TypeManager.IsPrimitiveType (type) || type == TypeManager.decimal_type)) {
75 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
76 AsString (), TypeManager.CSharpName (target));
78 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
82 public Constant ImplicitConversionRequired (ResolveContext ec, Type type, Location loc)
84 Constant c = ConvertImplicitly (ec, type);
86 Error_ValueCannotBeConverted (ec, loc, type, false);
91 public virtual Constant ConvertImplicitly (ResolveContext rc, Type type)
93 if (this.type == type)
96 if (Convert.ImplicitNumericConversion (this, type) == null)
100 object constant_value = TypeManager.ChangeType (GetValue (), type, out fail);
103 // We should always catch the error before this is ever
104 // reached, by calling Convert.ImplicitStandardConversionExists
106 throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
107 TypeManager.CSharpName (Type), TypeManager.CSharpName (type));
110 return CreateConstant (rc, type, constant_value, loc);
114 // Returns a constant instance based on Type
116 public static Constant CreateConstant (ResolveContext rc, Type t, object v, Location loc)
118 return CreateConstantFromValue (t, v, loc).Resolve (rc);
121 public static Constant CreateConstantFromValue (Type t, object v, Location loc)
123 if (t == TypeManager.int32_type)
124 return new IntConstant ((int) v, loc);
125 if (t == TypeManager.string_type)
126 return new StringConstant ((string) v, loc);
127 if (t == TypeManager.uint32_type)
128 return new UIntConstant ((uint) v, loc);
129 if (t == TypeManager.int64_type)
130 return new LongConstant ((long) v, loc);
131 if (t == TypeManager.uint64_type)
132 return new ULongConstant ((ulong) v, loc);
133 if (t == TypeManager.float_type)
134 return new FloatConstant ((float) v, loc);
135 if (t == TypeManager.double_type)
136 return new DoubleConstant ((double) v, loc);
137 if (t == TypeManager.short_type)
138 return new ShortConstant ((short)v, loc);
139 if (t == TypeManager.ushort_type)
140 return new UShortConstant ((ushort)v, loc);
141 if (t == TypeManager.sbyte_type)
142 return new SByteConstant ((sbyte)v, loc);
143 if (t == TypeManager.byte_type)
144 return new ByteConstant ((byte)v, loc);
145 if (t == TypeManager.char_type)
146 return new CharConstant ((char)v, loc);
147 if (t == TypeManager.bool_type)
148 return new BoolConstant ((bool) v, loc);
149 if (t == TypeManager.decimal_type)
150 return new DecimalConstant ((decimal) v, loc);
151 if (TypeManager.IsEnumType (t)) {
152 Type real_type = TypeManager.GetEnumUnderlyingType (t);
153 return new EnumConstant (CreateConstantFromValue (real_type, v, loc).Resolve (null), t);
156 if (TypeManager.IsNullableType (t))
157 return Nullable.LiftedNull.Create (t, loc);
159 if (TypeManager.IsReferenceType (t))
160 return new NullConstant (t, loc);
163 throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'",
164 v, TypeManager.CSharpName (t));
167 public override Expression CreateExpressionTree (ResolveContext ec)
169 Arguments args = new Arguments (2);
170 args.Add (new Argument (this));
171 args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
173 return CreateExpressionFactoryCall (ec, "Constant", args);
178 /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
179 /// It throws OverflowException
181 // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
182 public abstract Constant ConvertExplicitly (bool in_checked_context, Type target_type);
185 /// Attempts to do a compile-time folding of a constant cast.
187 public Constant TryReduce (ResolveContext ec, Type target_type, Location loc)
190 return TryReduce (ec, target_type);
192 catch (OverflowException) {
193 if (ec.ConstantCheckState) {
194 ec.Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
195 GetValue ().ToString (), TypeManager.CSharpName (target_type));
197 Error_ValueCannotBeConverted (ec, loc, target_type, false);
200 return New.Constantify (target_type).Resolve (ec);
204 Constant TryReduce (ResolveContext ec, Type target_type)
206 if (Type == target_type)
210 if (TypeManager.IsEnumType (target_type)) {
211 c = TryReduce (ec, TypeManager.GetEnumUnderlyingType (target_type));
215 return new EnumConstant (c, target_type).Resolve (ec);
218 c = ConvertExplicitly (ec.ConstantCheckState, target_type);
226 /// Need to pass type as the constant can require a boxing
227 /// and in such case no optimization is possible
229 public bool IsDefaultInitializer (Type type)
232 return IsDefaultValue;
234 return this is NullLiteral;
237 public abstract bool IsDefaultValue {
241 public abstract bool IsNegative {
246 // When constant is declared as literal
248 public virtual bool IsLiteral {
249 get { return false; }
253 // Returns true iff 1) the stack type of this is one of Object,
254 // int32, int64 and 2) this == 0 or this == null.
256 public virtual bool IsZeroInteger {
257 get { return false; }
260 public override void EmitSideEffect (EmitContext ec)
265 protected override void CloneTo (CloneContext clonectx, Expression target)
267 // CloneTo: Nothing, we do not keep any state on this expression
271 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
273 return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type);
277 public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
279 // A constant cannot be of generic type
282 public new Constant Resolve (ResolveContext rc)
284 if (eclass != ExprClass.Unresolved)
287 // Resolved constant has to be still a constant
288 Constant c = (Constant) DoResolve (rc);
292 if ((c.eclass & ExprClass.Value) == 0) {
293 c.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc);
298 throw new InternalErrorException ("Expression `{0}' did not set its type after Resolve", c.GetType ());
304 public abstract class IntegralConstant : Constant {
305 protected IntegralConstant (Location loc) :
310 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
313 ConvertExplicitly (true, target);
314 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
318 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
319 GetValue ().ToString (), TypeManager.CSharpName (target));
323 public abstract Constant Increment ();
326 public class BoolConstant : Constant {
327 public readonly bool Value;
329 public BoolConstant (bool val, Location loc):
335 override public string AsString ()
337 return Value ? "true" : "false";
340 protected override Expression DoResolve (ResolveContext ec)
342 type = TypeManager.bool_type;
343 eclass = ExprClass.Value;
347 public override object GetValue ()
349 return (object) Value;
352 public override void Emit (EmitContext ec)
355 ec.ig.Emit (OpCodes.Ldc_I4_1);
357 ec.ig.Emit (OpCodes.Ldc_I4_0);
360 public override bool IsDefaultValue {
366 public override bool IsNegative {
372 public override bool IsZeroInteger {
373 get { return Value == false; }
376 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
383 public class ByteConstant : IntegralConstant {
384 public readonly byte Value;
386 public ByteConstant (byte v, Location loc):
392 public override void Emit (EmitContext ec)
394 IntLiteral.EmitInt (ec.ig, Value);
397 public override string AsString ()
399 return Value.ToString ();
402 protected override Expression DoResolve (ResolveContext ec)
404 type = TypeManager.byte_type;
405 eclass = ExprClass.Value;
409 public override object GetValue ()
414 public override Constant Increment ()
416 return new ByteConstant (checked ((byte)(Value + 1)), loc);
419 public override bool IsDefaultValue {
425 public override bool IsNegative {
431 public override bool IsZeroInteger {
432 get { return Value == 0; }
435 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
437 if (target_type == TypeManager.sbyte_type) {
438 if (in_checked_context){
439 if (Value > SByte.MaxValue)
440 throw new OverflowException ();
442 return new SByteConstant ((sbyte) Value, Location);
444 if (target_type == TypeManager.short_type)
445 return new ShortConstant ((short) Value, Location);
446 if (target_type == TypeManager.ushort_type)
447 return new UShortConstant ((ushort) Value, Location);
448 if (target_type == TypeManager.int32_type)
449 return new IntConstant ((int) Value, Location);
450 if (target_type == TypeManager.uint32_type)
451 return new UIntConstant ((uint) Value, Location);
452 if (target_type == TypeManager.int64_type)
453 return new LongConstant ((long) Value, Location);
454 if (target_type == TypeManager.uint64_type)
455 return new ULongConstant ((ulong) Value, Location);
456 if (target_type == TypeManager.float_type)
457 return new FloatConstant ((float) Value, Location);
458 if (target_type == TypeManager.double_type)
459 return new DoubleConstant ((double) Value, Location);
460 if (target_type == TypeManager.char_type)
461 return new CharConstant ((char) Value, Location);
462 if (target_type == TypeManager.decimal_type)
463 return new DecimalConstant ((decimal) Value, Location);
470 public class CharConstant : Constant {
471 public readonly char Value;
473 public CharConstant (char v, Location loc):
479 protected override Expression DoResolve (ResolveContext rc)
481 type = TypeManager.char_type;
482 eclass = ExprClass.Value;
486 public override void Emit (EmitContext ec)
488 IntLiteral.EmitInt (ec.ig, Value);
491 static string descape (char c)
517 return c.ToString ();
520 public override string AsString ()
522 return "\"" + descape (Value) + "\"";
525 public override object GetValue ()
530 public override bool IsDefaultValue {
536 public override bool IsNegative {
542 public override bool IsZeroInteger {
543 get { return Value == '\0'; }
546 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
548 if (target_type == TypeManager.byte_type) {
549 if (in_checked_context){
550 if (Value < Byte.MinValue || Value > Byte.MaxValue)
551 throw new OverflowException ();
553 return new ByteConstant ((byte) Value, Location);
555 if (target_type == TypeManager.sbyte_type) {
556 if (in_checked_context){
557 if (Value > SByte.MaxValue)
558 throw new OverflowException ();
560 return new SByteConstant ((sbyte) Value, Location);
562 if (target_type == TypeManager.short_type) {
563 if (in_checked_context){
564 if (Value > Int16.MaxValue)
565 throw new OverflowException ();
567 return new ShortConstant ((short) Value, Location);
569 if (target_type == TypeManager.int32_type)
570 return new IntConstant ((int) Value, Location);
571 if (target_type == TypeManager.uint32_type)
572 return new UIntConstant ((uint) Value, Location);
573 if (target_type == TypeManager.int64_type)
574 return new LongConstant ((long) Value, Location);
575 if (target_type == TypeManager.uint64_type)
576 return new ULongConstant ((ulong) Value, Location);
577 if (target_type == TypeManager.float_type)
578 return new FloatConstant ((float) Value, Location);
579 if (target_type == TypeManager.double_type)
580 return new DoubleConstant ((double) Value, Location);
581 if (target_type == TypeManager.decimal_type)
582 return new DecimalConstant ((decimal) Value, Location);
589 public class SByteConstant : IntegralConstant {
590 public readonly sbyte Value;
592 public SByteConstant (sbyte v, Location loc):
598 protected override Expression DoResolve (ResolveContext rc)
600 type = TypeManager.sbyte_type;
601 eclass = ExprClass.Value;
605 public override void Emit (EmitContext ec)
607 IntLiteral.EmitInt (ec.ig, Value);
610 public override string AsString ()
612 return Value.ToString ();
615 public override object GetValue ()
620 public override Constant Increment ()
622 return new SByteConstant (checked((sbyte)(Value + 1)), loc);
625 public override bool IsDefaultValue {
631 public override bool IsNegative {
637 public override bool IsZeroInteger {
638 get { return Value == 0; }
641 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
643 if (target_type == TypeManager.byte_type) {
644 if (in_checked_context && Value < 0)
645 throw new OverflowException ();
646 return new ByteConstant ((byte) Value, Location);
648 if (target_type == TypeManager.short_type)
649 return new ShortConstant ((short) Value, Location);
650 if (target_type == TypeManager.ushort_type) {
651 if (in_checked_context && Value < 0)
652 throw new OverflowException ();
653 return new UShortConstant ((ushort) Value, Location);
654 } if (target_type == TypeManager.int32_type)
655 return new IntConstant ((int) Value, Location);
656 if (target_type == TypeManager.uint32_type) {
657 if (in_checked_context && Value < 0)
658 throw new OverflowException ();
659 return new UIntConstant ((uint) Value, Location);
660 } if (target_type == TypeManager.int64_type)
661 return new LongConstant ((long) Value, Location);
662 if (target_type == TypeManager.uint64_type) {
663 if (in_checked_context && Value < 0)
664 throw new OverflowException ();
665 return new ULongConstant ((ulong) Value, Location);
667 if (target_type == TypeManager.float_type)
668 return new FloatConstant ((float) Value, Location);
669 if (target_type == TypeManager.double_type)
670 return new DoubleConstant ((double) Value, Location);
671 if (target_type == TypeManager.char_type) {
672 if (in_checked_context && Value < 0)
673 throw new OverflowException ();
674 return new CharConstant ((char) Value, Location);
676 if (target_type == TypeManager.decimal_type)
677 return new DecimalConstant ((decimal) Value, Location);
684 public class ShortConstant : IntegralConstant {
685 public readonly short Value;
687 public ShortConstant (short v, Location loc):
693 protected override Expression DoResolve (ResolveContext rc)
695 type = TypeManager.short_type;
696 eclass = ExprClass.Value;
700 public override void Emit (EmitContext ec)
702 IntLiteral.EmitInt (ec.ig, Value);
705 public override string AsString ()
707 return Value.ToString ();
710 public override object GetValue ()
715 public override Constant Increment ()
717 return new ShortConstant (checked((short)(Value + 1)), loc);
720 public override bool IsDefaultValue {
726 public override bool IsZeroInteger {
727 get { return Value == 0; }
730 public override bool IsNegative {
736 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
738 if (target_type == TypeManager.byte_type) {
739 if (in_checked_context){
740 if (Value < Byte.MinValue || Value > Byte.MaxValue)
741 throw new OverflowException ();
743 return new ByteConstant ((byte) Value, Location);
745 if (target_type == TypeManager.sbyte_type) {
746 if (in_checked_context){
747 if (Value < SByte.MinValue || Value > SByte.MaxValue)
748 throw new OverflowException ();
750 return new SByteConstant ((sbyte) Value, Location);
752 if (target_type == TypeManager.ushort_type) {
753 if (in_checked_context && Value < 0)
754 throw new OverflowException ();
756 return new UShortConstant ((ushort) Value, Location);
758 if (target_type == TypeManager.int32_type)
759 return new IntConstant ((int) Value, Location);
760 if (target_type == TypeManager.uint32_type) {
761 if (in_checked_context && Value < 0)
762 throw new OverflowException ();
763 return new UIntConstant ((uint) Value, Location);
765 if (target_type == TypeManager.int64_type)
766 return new LongConstant ((long) Value, Location);
767 if (target_type == TypeManager.uint64_type) {
768 if (in_checked_context && Value < 0)
769 throw new OverflowException ();
770 return new ULongConstant ((ulong) Value, Location);
772 if (target_type == TypeManager.float_type)
773 return new FloatConstant ((float) Value, Location);
774 if (target_type == TypeManager.double_type)
775 return new DoubleConstant ((double) Value, Location);
776 if (target_type == TypeManager.char_type) {
777 if (in_checked_context){
778 if (Value < Char.MinValue)
779 throw new OverflowException ();
781 return new CharConstant ((char) Value, Location);
783 if (target_type == TypeManager.decimal_type)
784 return new DecimalConstant ((decimal) Value, Location);
791 public class UShortConstant : IntegralConstant {
792 public readonly ushort Value;
794 public UShortConstant (ushort v, Location loc):
800 protected override Expression DoResolve (ResolveContext rc)
802 type = TypeManager.ushort_type;
803 eclass = ExprClass.Value;
807 public override void Emit (EmitContext ec)
809 IntLiteral.EmitInt (ec.ig, Value);
812 public override string AsString ()
814 return Value.ToString ();
817 public override object GetValue ()
822 public override Constant Increment ()
824 return new UShortConstant (checked((ushort)(Value + 1)), loc);
827 public override bool IsDefaultValue {
833 public override bool IsNegative {
839 public override bool IsZeroInteger {
840 get { return Value == 0; }
843 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
845 if (target_type == TypeManager.byte_type) {
846 if (in_checked_context){
847 if (Value > Byte.MaxValue)
848 throw new OverflowException ();
850 return new ByteConstant ((byte) Value, Location);
852 if (target_type == TypeManager.sbyte_type) {
853 if (in_checked_context){
854 if (Value > SByte.MaxValue)
855 throw new OverflowException ();
857 return new SByteConstant ((sbyte) Value, Location);
859 if (target_type == TypeManager.short_type) {
860 if (in_checked_context){
861 if (Value > Int16.MaxValue)
862 throw new OverflowException ();
864 return new ShortConstant ((short) Value, Location);
866 if (target_type == TypeManager.int32_type)
867 return new IntConstant ((int) Value, Location);
868 if (target_type == TypeManager.uint32_type)
869 return new UIntConstant ((uint) Value, Location);
870 if (target_type == TypeManager.int64_type)
871 return new LongConstant ((long) Value, Location);
872 if (target_type == TypeManager.uint64_type)
873 return new ULongConstant ((ulong) Value, Location);
874 if (target_type == TypeManager.float_type)
875 return new FloatConstant ((float) Value, Location);
876 if (target_type == TypeManager.double_type)
877 return new DoubleConstant ((double) Value, Location);
878 if (target_type == TypeManager.char_type) {
879 if (in_checked_context){
880 if (Value > Char.MaxValue)
881 throw new OverflowException ();
883 return new CharConstant ((char) Value, Location);
885 if (target_type == TypeManager.decimal_type)
886 return new DecimalConstant ((decimal) Value, Location);
892 public class IntConstant : IntegralConstant {
893 public readonly int Value;
895 public IntConstant (int v, Location loc):
901 protected override Expression DoResolve (ResolveContext rc)
903 type = TypeManager.int32_type;
904 eclass = ExprClass.Value;
908 static public void EmitInt (ILGenerator ig, int i)
912 ig.Emit (OpCodes.Ldc_I4_M1);
916 ig.Emit (OpCodes.Ldc_I4_0);
920 ig.Emit (OpCodes.Ldc_I4_1);
924 ig.Emit (OpCodes.Ldc_I4_2);
928 ig.Emit (OpCodes.Ldc_I4_3);
932 ig.Emit (OpCodes.Ldc_I4_4);
936 ig.Emit (OpCodes.Ldc_I4_5);
940 ig.Emit (OpCodes.Ldc_I4_6);
944 ig.Emit (OpCodes.Ldc_I4_7);
948 ig.Emit (OpCodes.Ldc_I4_8);
952 if (i >= -128 && i <= 127){
953 ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
955 ig.Emit (OpCodes.Ldc_I4, i);
960 public override void Emit (EmitContext ec)
962 EmitInt (ec.ig, Value);
965 public override string AsString ()
967 return Value.ToString ();
970 public override object GetValue ()
975 public override Constant Increment ()
977 return new IntConstant (checked(Value + 1), loc);
980 public override bool IsDefaultValue {
986 public override bool IsNegative {
992 public override bool IsZeroInteger {
993 get { return Value == 0; }
996 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
998 if (target_type == TypeManager.byte_type) {
999 if (in_checked_context){
1000 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1001 throw new OverflowException ();
1003 return new ByteConstant ((byte) Value, Location);
1005 if (target_type == TypeManager.sbyte_type) {
1006 if (in_checked_context){
1007 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1008 throw new OverflowException ();
1010 return new SByteConstant ((sbyte) Value, Location);
1012 if (target_type == TypeManager.short_type) {
1013 if (in_checked_context){
1014 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1015 throw new OverflowException ();
1017 return new ShortConstant ((short) Value, Location);
1019 if (target_type == TypeManager.ushort_type) {
1020 if (in_checked_context){
1021 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1022 throw new OverflowException ();
1024 return new UShortConstant ((ushort) Value, Location);
1026 if (target_type == TypeManager.uint32_type) {
1027 if (in_checked_context){
1028 if (Value < UInt32.MinValue)
1029 throw new OverflowException ();
1031 return new UIntConstant ((uint) Value, Location);
1033 if (target_type == TypeManager.int64_type)
1034 return new LongConstant ((long) Value, Location);
1035 if (target_type == TypeManager.uint64_type) {
1036 if (in_checked_context && Value < 0)
1037 throw new OverflowException ();
1038 return new ULongConstant ((ulong) Value, Location);
1040 if (target_type == TypeManager.float_type)
1041 return new FloatConstant ((float) Value, Location);
1042 if (target_type == TypeManager.double_type)
1043 return new DoubleConstant ((double) Value, Location);
1044 if (target_type == TypeManager.char_type) {
1045 if (in_checked_context){
1046 if (Value < Char.MinValue || Value > Char.MaxValue)
1047 throw new OverflowException ();
1049 return new CharConstant ((char) Value, Location);
1051 if (target_type == TypeManager.decimal_type)
1052 return new DecimalConstant ((decimal) Value, Location);
1057 public override Constant ConvertImplicitly (ResolveContext rc, Type type)
1059 if (this.type == type)
1062 Constant c = TryImplicitIntConversion (type);
1064 return c.Resolve (rc);
1066 return base.ConvertImplicitly (rc, type);
1070 /// Attempts to perform an implicit constant conversion of the IntConstant
1071 /// into a different data type using casts (See Implicit Constant
1072 /// Expression Conversions)
1074 Constant TryImplicitIntConversion (Type target_type)
1076 if (target_type == TypeManager.sbyte_type) {
1077 if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1078 return new SByteConstant ((sbyte) Value, loc);
1080 else if (target_type == TypeManager.byte_type) {
1081 if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1082 return new ByteConstant ((byte) Value, loc);
1084 else if (target_type == TypeManager.short_type) {
1085 if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1086 return new ShortConstant ((short) Value, loc);
1088 else if (target_type == TypeManager.ushort_type) {
1089 if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1090 return new UShortConstant ((ushort) Value, loc);
1092 else if (target_type == TypeManager.uint32_type) {
1094 return new UIntConstant ((uint) Value, loc);
1096 else if (target_type == TypeManager.uint64_type) {
1098 // we can optimize this case: a positive int32
1099 // always fits on a uint64. But we need an opcode
1103 return new ULongConstant ((ulong) Value, loc);
1105 else if (target_type == TypeManager.double_type)
1106 return new DoubleConstant ((double) Value, loc);
1107 else if (target_type == TypeManager.float_type)
1108 return new FloatConstant ((float) Value, loc);
1114 public class UIntConstant : IntegralConstant {
1115 public readonly uint Value;
1117 public UIntConstant (uint v, Location loc):
1123 protected override Expression DoResolve (ResolveContext rc)
1125 type = TypeManager.uint32_type;
1126 eclass = ExprClass.Value;
1130 public override void Emit (EmitContext ec)
1132 IntLiteral.EmitInt (ec.ig, unchecked ((int) Value));
1135 public override string AsString ()
1137 return Value.ToString ();
1140 public override object GetValue ()
1145 public override Constant Increment ()
1147 return new UIntConstant (checked(Value + 1), loc);
1150 public override bool IsDefaultValue {
1156 public override bool IsNegative {
1162 public override bool IsZeroInteger {
1163 get { return Value == 0; }
1166 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
1168 if (target_type == TypeManager.byte_type) {
1169 if (in_checked_context){
1170 if (Value < Char.MinValue || Value > Char.MaxValue)
1171 throw new OverflowException ();
1173 return new ByteConstant ((byte) Value, Location);
1175 if (target_type == TypeManager.sbyte_type) {
1176 if (in_checked_context){
1177 if (Value > SByte.MaxValue)
1178 throw new OverflowException ();
1180 return new SByteConstant ((sbyte) Value, Location);
1182 if (target_type == TypeManager.short_type) {
1183 if (in_checked_context){
1184 if (Value > Int16.MaxValue)
1185 throw new OverflowException ();
1187 return new ShortConstant ((short) Value, Location);
1189 if (target_type == TypeManager.ushort_type) {
1190 if (in_checked_context){
1191 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1192 throw new OverflowException ();
1194 return new UShortConstant ((ushort) Value, Location);
1196 if (target_type == TypeManager.int32_type) {
1197 if (in_checked_context){
1198 if (Value > Int32.MaxValue)
1199 throw new OverflowException ();
1201 return new IntConstant ((int) Value, Location);
1203 if (target_type == TypeManager.int64_type)
1204 return new LongConstant ((long) Value, Location);
1205 if (target_type == TypeManager.uint64_type)
1206 return new ULongConstant ((ulong) Value, Location);
1207 if (target_type == TypeManager.float_type)
1208 return new FloatConstant ((float) Value, Location);
1209 if (target_type == TypeManager.double_type)
1210 return new DoubleConstant ((double) Value, Location);
1211 if (target_type == TypeManager.char_type) {
1212 if (in_checked_context){
1213 if (Value < Char.MinValue || Value > Char.MaxValue)
1214 throw new OverflowException ();
1216 return new CharConstant ((char) Value, Location);
1218 if (target_type == TypeManager.decimal_type)
1219 return new DecimalConstant ((decimal) Value, Location);
1226 public class LongConstant : IntegralConstant {
1227 public readonly long Value;
1229 public LongConstant (long v, Location loc):
1235 protected override Expression DoResolve (ResolveContext rc)
1237 type = TypeManager.int64_type;
1238 eclass = ExprClass.Value;
1242 public override void Emit (EmitContext ec)
1244 EmitLong (ec.ig, Value);
1247 static public void EmitLong (ILGenerator ig, long l)
1249 if (l >= int.MinValue && l <= int.MaxValue) {
1250 IntLiteral.EmitInt (ig, unchecked ((int) l));
1251 ig.Emit (OpCodes.Conv_I8);
1255 if (l >= 0 && l <= uint.MaxValue) {
1256 IntLiteral.EmitInt (ig, unchecked ((int) l));
1257 ig.Emit (OpCodes.Conv_U8);
1261 ig.Emit (OpCodes.Ldc_I8, l);
1264 public override string AsString ()
1266 return Value.ToString ();
1269 public override object GetValue ()
1274 public override Constant Increment ()
1276 return new LongConstant (checked(Value + 1), loc);
1279 public override bool IsDefaultValue {
1285 public override bool IsNegative {
1291 public override bool IsZeroInteger {
1292 get { return Value == 0; }
1295 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
1297 if (target_type == TypeManager.byte_type) {
1298 if (in_checked_context){
1299 if (Value < Byte.MinValue || Value > Byte.MaxValue)
1300 throw new OverflowException ();
1302 return new ByteConstant ((byte) Value, Location);
1304 if (target_type == TypeManager.sbyte_type) {
1305 if (in_checked_context){
1306 if (Value < SByte.MinValue || Value > SByte.MaxValue)
1307 throw new OverflowException ();
1309 return new SByteConstant ((sbyte) Value, Location);
1311 if (target_type == TypeManager.short_type) {
1312 if (in_checked_context){
1313 if (Value < Int16.MinValue || Value > Int16.MaxValue)
1314 throw new OverflowException ();
1316 return new ShortConstant ((short) Value, Location);
1318 if (target_type == TypeManager.ushort_type) {
1319 if (in_checked_context){
1320 if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1321 throw new OverflowException ();
1323 return new UShortConstant ((ushort) Value, Location);
1325 if (target_type == TypeManager.int32_type) {
1326 if (in_checked_context){
1327 if (Value < Int32.MinValue || Value > Int32.MaxValue)
1328 throw new OverflowException ();
1330 return new IntConstant ((int) Value, Location);
1332 if (target_type == TypeManager.uint32_type) {
1333 if (in_checked_context){
1334 if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1335 throw new OverflowException ();
1337 return new UIntConstant ((uint) Value, Location);
1339 if (target_type == TypeManager.uint64_type) {
1340 if (in_checked_context && Value < 0)
1341 throw new OverflowException ();
1342 return new ULongConstant ((ulong) Value, Location);
1344 if (target_type == TypeManager.float_type)
1345 return new FloatConstant ((float) Value, Location);
1346 if (target_type == TypeManager.double_type)
1347 return new DoubleConstant ((double) Value, Location);
1348 if (target_type == TypeManager.char_type) {
1349 if (in_checked_context){
1350 if (Value < Char.MinValue || Value > Char.MaxValue)
1351 throw new OverflowException ();
1353 return new CharConstant ((char) Value, Location);
1355 if (target_type == TypeManager.decimal_type)
1356 return new DecimalConstant ((decimal) Value, Location);
1361 public override Constant ConvertImplicitly (ResolveContext rc, Type type)
1363 if (Value >= 0 && type == TypeManager.uint64_type) {
1364 return new ULongConstant ((ulong) Value, loc).Resolve (rc);
1367 return base.ConvertImplicitly (rc, type);
1371 public class ULongConstant : IntegralConstant {
1372 public readonly ulong Value;
1374 public ULongConstant (ulong v, Location loc):
1380 protected override Expression DoResolve (ResolveContext rc)
1382 type = TypeManager.uint64_type;
1383 eclass = ExprClass.Value;
1387 public override void Emit (EmitContext ec)
1389 ILGenerator ig = ec.ig;
1391 LongLiteral.EmitLong (ig, unchecked ((long) Value));
1394 public override string AsString ()
1396 return Value.ToString ();
1399 public override object GetValue ()
1404 public override Constant Increment ()
1406 return new ULongConstant (checked(Value + 1), loc);
1409 public override bool IsDefaultValue {
1415 public override bool IsNegative {
1421 public override bool IsZeroInteger {
1422 get { return Value == 0; }
1425 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
1427 if (target_type == TypeManager.byte_type) {
1428 if (in_checked_context && Value > Byte.MaxValue)
1429 throw new OverflowException ();
1430 return new ByteConstant ((byte) Value, Location);
1432 if (target_type == TypeManager.sbyte_type) {
1433 if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1434 throw new OverflowException ();
1435 return new SByteConstant ((sbyte) Value, Location);
1437 if (target_type == TypeManager.short_type) {
1438 if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1439 throw new OverflowException ();
1440 return new ShortConstant ((short) Value, Location);
1442 if (target_type == TypeManager.ushort_type) {
1443 if (in_checked_context && Value > UInt16.MaxValue)
1444 throw new OverflowException ();
1445 return new UShortConstant ((ushort) Value, Location);
1447 if (target_type == TypeManager.int32_type) {
1448 if (in_checked_context && Value > UInt32.MaxValue)
1449 throw new OverflowException ();
1450 return new IntConstant ((int) Value, Location);
1452 if (target_type == TypeManager.uint32_type) {
1453 if (in_checked_context && Value > UInt32.MaxValue)
1454 throw new OverflowException ();
1455 return new UIntConstant ((uint) Value, Location);
1457 if (target_type == TypeManager.int64_type) {
1458 if (in_checked_context && Value > Int64.MaxValue)
1459 throw new OverflowException ();
1460 return new LongConstant ((long) Value, Location);
1462 if (target_type == TypeManager.float_type)
1463 return new FloatConstant ((float) Value, Location);
1464 if (target_type == TypeManager.double_type)
1465 return new DoubleConstant ((double) Value, Location);
1466 if (target_type == TypeManager.char_type) {
1467 if (in_checked_context && Value > Char.MaxValue)
1468 throw new OverflowException ();
1469 return new CharConstant ((char) Value, Location);
1471 if (target_type == TypeManager.decimal_type)
1472 return new DecimalConstant ((decimal) Value, Location);
1479 public class FloatConstant : Constant {
1482 public FloatConstant (float v, Location loc):
1488 protected override Expression DoResolve (ResolveContext rc)
1490 type = TypeManager.float_type;
1491 eclass = ExprClass.Value;
1495 public override void Emit (EmitContext ec)
1497 ec.ig.Emit (OpCodes.Ldc_R4, Value);
1500 public override string AsString ()
1502 return Value.ToString ();
1505 public override object GetValue ()
1510 public override bool IsDefaultValue {
1516 public override bool IsNegative {
1522 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
1524 if (target_type == TypeManager.byte_type) {
1525 if (in_checked_context){
1526 if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1527 throw new OverflowException ();
1529 return new ByteConstant ((byte) Value, Location);
1531 if (target_type == TypeManager.sbyte_type) {
1532 if (in_checked_context){
1533 if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1534 throw new OverflowException ();
1536 return new SByteConstant ((sbyte) Value, Location);
1538 if (target_type == TypeManager.short_type) {
1539 if (in_checked_context){
1540 if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1541 throw new OverflowException ();
1543 return new ShortConstant ((short) Value, Location);
1545 if (target_type == TypeManager.ushort_type) {
1546 if (in_checked_context){
1547 if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1548 throw new OverflowException ();
1550 return new UShortConstant ((ushort) Value, Location);
1552 if (target_type == TypeManager.int32_type) {
1553 if (in_checked_context){
1554 if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1555 throw new OverflowException ();
1557 return new IntConstant ((int) Value, Location);
1559 if (target_type == TypeManager.uint32_type) {
1560 if (in_checked_context){
1561 if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1562 throw new OverflowException ();
1564 return new UIntConstant ((uint) Value, Location);
1566 if (target_type == TypeManager.int64_type) {
1567 if (in_checked_context){
1568 if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1569 throw new OverflowException ();
1571 return new LongConstant ((long) Value, Location);
1573 if (target_type == TypeManager.uint64_type) {
1574 if (in_checked_context){
1575 if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1576 throw new OverflowException ();
1578 return new ULongConstant ((ulong) Value, Location);
1580 if (target_type == TypeManager.double_type)
1581 return new DoubleConstant ((double) Value, Location);
1582 if (target_type == TypeManager.char_type) {
1583 if (in_checked_context){
1584 if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1585 throw new OverflowException ();
1587 return new CharConstant ((char) Value, Location);
1589 if (target_type == TypeManager.decimal_type)
1590 return new DecimalConstant ((decimal) Value, Location);
1597 public class DoubleConstant : Constant {
1598 public double Value;
1600 public DoubleConstant (double v, Location loc):
1606 protected override Expression DoResolve (ResolveContext rc)
1608 type = TypeManager.double_type;
1609 eclass = ExprClass.Value;
1613 public override void Emit (EmitContext ec)
1615 ec.ig.Emit (OpCodes.Ldc_R8, Value);
1618 public override string AsString ()
1620 return Value.ToString ();
1623 public override object GetValue ()
1628 public override bool IsDefaultValue {
1634 public override bool IsNegative {
1640 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
1642 if (target_type == TypeManager.byte_type) {
1643 if (in_checked_context){
1644 if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1645 throw new OverflowException ();
1647 return new ByteConstant ((byte) Value, Location);
1649 if (target_type == TypeManager.sbyte_type) {
1650 if (in_checked_context){
1651 if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1652 throw new OverflowException ();
1654 return new SByteConstant ((sbyte) Value, Location);
1656 if (target_type == TypeManager.short_type) {
1657 if (in_checked_context){
1658 if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1659 throw new OverflowException ();
1661 return new ShortConstant ((short) Value, Location);
1663 if (target_type == TypeManager.ushort_type) {
1664 if (in_checked_context){
1665 if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1666 throw new OverflowException ();
1668 return new UShortConstant ((ushort) Value, Location);
1670 if (target_type == TypeManager.int32_type) {
1671 if (in_checked_context){
1672 if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1673 throw new OverflowException ();
1675 return new IntConstant ((int) Value, Location);
1677 if (target_type == TypeManager.uint32_type) {
1678 if (in_checked_context){
1679 if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1680 throw new OverflowException ();
1682 return new UIntConstant ((uint) Value, Location);
1684 if (target_type == TypeManager.int64_type) {
1685 if (in_checked_context){
1686 if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1687 throw new OverflowException ();
1689 return new LongConstant ((long) Value, Location);
1691 if (target_type == TypeManager.uint64_type) {
1692 if (in_checked_context){
1693 if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1694 throw new OverflowException ();
1696 return new ULongConstant ((ulong) Value, Location);
1698 if (target_type == TypeManager.float_type)
1699 return new FloatConstant ((float) Value, Location);
1700 if (target_type == TypeManager.char_type) {
1701 if (in_checked_context){
1702 if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1703 throw new OverflowException ();
1705 return new CharConstant ((char) Value, Location);
1707 if (target_type == TypeManager.decimal_type)
1708 return new DecimalConstant ((decimal) Value, Location);
1715 public class DecimalConstant : Constant {
1716 public readonly decimal Value;
1718 public DecimalConstant (decimal d, Location loc):
1724 override public string AsString ()
1726 return Value.ToString () + "M";
1729 protected override Expression DoResolve (ResolveContext rc)
1731 type = TypeManager.decimal_type;
1732 eclass = ExprClass.Value;
1736 public override object GetValue ()
1738 return (object) Value;
1741 public override void Emit (EmitContext ec)
1743 ILGenerator ig = ec.ig;
1745 int [] words = decimal.GetBits (Value);
1746 int power = (words [3] >> 16) & 0xff;
1749 if (Value <= int.MaxValue && Value >= int.MinValue) {
1750 if (TypeManager.void_decimal_ctor_int_arg == null) {
1751 TypeManager.void_decimal_ctor_int_arg = TypeManager.GetPredefinedConstructor (
1752 TypeManager.decimal_type, loc, TypeManager.int32_type);
1754 if (TypeManager.void_decimal_ctor_int_arg == null)
1758 IntConstant.EmitInt (ig, (int) Value);
1759 ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
1763 if (Value <= long.MaxValue && Value >= long.MinValue) {
1764 if (TypeManager.void_decimal_ctor_long_arg == null) {
1765 TypeManager.void_decimal_ctor_long_arg = TypeManager.GetPredefinedConstructor (
1766 TypeManager.decimal_type, loc, TypeManager.int64_type);
1768 if (TypeManager.void_decimal_ctor_long_arg == null)
1772 LongConstant.EmitLong (ig, (long) Value);
1773 ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_long_arg);
1778 IntConstant.EmitInt (ig, words [0]);
1779 IntConstant.EmitInt (ig, words [1]);
1780 IntConstant.EmitInt (ig, words [2]);
1783 IntConstant.EmitInt (ig, words [3] >> 31);
1786 IntConstant.EmitInt (ig, power);
1788 if (TypeManager.void_decimal_ctor_five_args == null) {
1789 TypeManager.void_decimal_ctor_five_args = TypeManager.GetPredefinedConstructor (
1790 TypeManager.decimal_type, loc, TypeManager.int32_type, TypeManager.int32_type,
1791 TypeManager.int32_type, TypeManager.bool_type, TypeManager.byte_type);
1793 if (TypeManager.void_decimal_ctor_five_args == null)
1797 ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
1800 public override bool IsDefaultValue {
1806 public override bool IsNegative {
1812 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
1814 if (target_type == TypeManager.sbyte_type)
1815 return new SByteConstant ((sbyte)Value, loc);
1816 if (target_type == TypeManager.byte_type)
1817 return new ByteConstant ((byte)Value, loc);
1818 if (target_type == TypeManager.short_type)
1819 return new ShortConstant ((short)Value, loc);
1820 if (target_type == TypeManager.ushort_type)
1821 return new UShortConstant ((ushort)Value, loc);
1822 if (target_type == TypeManager.int32_type)
1823 return new IntConstant ((int)Value, loc);
1824 if (target_type == TypeManager.uint32_type)
1825 return new UIntConstant ((uint)Value, loc);
1826 if (target_type == TypeManager.int64_type)
1827 return new LongConstant ((long)Value, loc);
1828 if (target_type == TypeManager.uint64_type)
1829 return new ULongConstant ((ulong)Value, loc);
1830 if (target_type == TypeManager.char_type)
1831 return new CharConstant ((char)Value, loc);
1832 if (target_type == TypeManager.float_type)
1833 return new FloatConstant ((float)Value, loc);
1834 if (target_type == TypeManager.double_type)
1835 return new DoubleConstant ((double)Value, loc);
1842 public class StringConstant : Constant {
1843 public readonly string Value;
1845 public StringConstant (string s, Location loc):
1851 // FIXME: Escape the string.
1852 override public string AsString ()
1854 return "\"" + Value + "\"";
1857 protected override Expression DoResolve (ResolveContext rc)
1859 type = TypeManager.string_type;
1860 eclass = ExprClass.Value;
1864 public override object GetValue ()
1869 public override void Emit (EmitContext ec)
1871 if (Value == null) {
1872 ec.ig.Emit (OpCodes.Ldnull);
1877 // Use string.Empty for both literals and constants even if
1878 // it's not allowed at language level
1880 if (Value.Length == 0 && RootContext.Optimize && !TypeManager.IsEqual (ec.CurrentType, TypeManager.string_type)) {
1881 if (TypeManager.string_empty == null)
1882 TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc);
1884 if (TypeManager.string_empty != null) {
1885 ec.ig.Emit (OpCodes.Ldsfld, TypeManager.string_empty);
1890 ec.ig.Emit (OpCodes.Ldstr, Value);
1893 public override bool IsDefaultValue {
1895 return Value == null;
1899 public override bool IsNegative {
1905 public override bool IsNull {
1907 return IsDefaultValue;
1911 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
1918 // Null constant can have its own type, think of `default (Foo)'
1920 public class NullConstant : Constant
1922 public NullConstant (Type type, Location loc)
1925 eclass = ExprClass.Value;
1929 public override string AsString ()
1931 return GetSignatureForError ();
1934 protected override Expression DoResolve (ResolveContext ec)
1939 public override void Emit (EmitContext ec)
1941 ec.ig.Emit (OpCodes.Ldnull);
1943 // Only to make verifier happy
1944 if (TypeManager.IsGenericParameter (type))
1945 ec.ig.Emit (OpCodes.Unbox_Any, type);
1948 public override string ExprClassName {
1950 return GetSignatureForError ();
1954 public override string GetSignatureForError ()
1959 public override Constant ConvertExplicitly (bool inCheckedContext, Type targetType)
1961 if (targetType.IsPointer) {
1962 if (IsLiteral || this is NullPointer)
1963 return new EmptyConstantCast (new NullPointer (loc), targetType);
1968 // Exlude internal compiler types
1969 if (targetType == InternalType.AnonymousMethod)
1972 if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
1975 if (TypeManager.IsReferenceType (targetType))
1976 return new NullConstant (targetType, loc);
1978 if (TypeManager.IsNullableType (targetType))
1979 return Nullable.LiftedNull.Create (targetType, loc);
1984 public override Constant ConvertImplicitly (ResolveContext rc, Type targetType)
1986 return ConvertExplicitly (false, targetType);
1989 public override object GetValue ()
1994 public override bool IsDefaultValue {
1995 get { return true; }
1998 public override bool IsNegative {
1999 get { return false; }
2002 public override bool IsNull {
2003 get { return true; }
2006 public override bool IsZeroInteger {
2007 get { return true; }
2010 public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
2012 type = storey.MutateType (type);
2017 /// The value is constant, but when emitted has a side effect. This is
2018 /// used by BitwiseAnd to ensure that the second expression is invoked
2019 /// regardless of the value of the left side.
2021 public class SideEffectConstant : Constant {
2022 public Constant value;
2023 Expression side_effect;
2025 public SideEffectConstant (Constant value, Expression side_effect, Location loc) : base (loc)
2028 while (side_effect is SideEffectConstant)
2029 side_effect = ((SideEffectConstant) side_effect).side_effect;
2030 this.side_effect = side_effect;
2033 public override string AsString ()
2035 return value.AsString ();
2038 protected override Expression DoResolve (ResolveContext rc)
2040 value = value.Resolve (rc);
2043 eclass = ExprClass.Value;
2047 public override object GetValue ()
2049 return value.GetValue ();
2052 public override void Emit (EmitContext ec)
2054 side_effect.EmitSideEffect (ec);
2058 public override void EmitSideEffect (EmitContext ec)
2060 side_effect.EmitSideEffect (ec);
2061 value.EmitSideEffect (ec);
2064 public override bool IsDefaultValue {
2065 get { return value.IsDefaultValue; }
2068 public override bool IsNegative {
2069 get { return value.IsNegative; }
2072 public override bool IsZeroInteger {
2073 get { return value.IsZeroInteger; }
2076 public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
2078 Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2079 return new_value == null ? null : new SideEffectConstant (new_value, side_effect, new_value.Location);