2 // constant.cs: Constants.
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@gmail.com)
8 // Copyright 2001-2003 Ximian, Inc.
9 // Copyright 2003-2008 Novell, Inc.
10 // Copyright 2011-2013 Xamarin Inc
14 using System
.Globalization
;
17 using IKVM
.Reflection
.Emit
;
19 using System
.Reflection
.Emit
;
22 namespace Mono
.CSharp
{
25 /// Base class for constants and literals.
27 public abstract class Constant
: Expression
29 static readonly NumberFormatInfo nfi
= CultureInfo
.InvariantCulture
.NumberFormat
;
31 protected Constant (Location loc
)
36 override public string ToString ()
38 return this.GetType ().Name
+ " (" + GetValueAsLiteral () + ")";
42 /// This is used to obtain the actual value of the literal
43 /// cast into an object.
45 public abstract object GetValue ();
47 public abstract long GetValueAsLong ();
49 public abstract string GetValueAsLiteral ();
53 // Returns an object value which is typed to contant type
55 public virtual object GetTypedValue ()
61 public override void Error_ValueCannotBeConverted (ResolveContext ec
, TypeSpec target
, bool expl
)
63 if (!expl
&& IsLiteral
&& type
.BuiltinType
!= BuiltinTypeSpec
.Type
.Double
&&
64 BuiltinTypeSpec
.IsPrimitiveTypeOrDecimal (target
) &&
65 BuiltinTypeSpec
.IsPrimitiveTypeOrDecimal (type
)) {
66 ec
.Report
.Error (31, loc
, "Constant value `{0}' cannot be converted to a `{1}'",
67 GetValueAsLiteral (), target
.GetSignatureForError ());
69 base.Error_ValueCannotBeConverted (ec
, target
, expl
);
73 public Constant
ImplicitConversionRequired (ResolveContext ec
, TypeSpec type
)
75 Constant c
= ConvertImplicitly (type
);
77 Error_ValueCannotBeConverted (ec
, type
, false);
82 public override bool ContainsEmitWithAwait ()
87 public virtual Constant
ConvertImplicitly (TypeSpec type
)
89 if (this.type
== type
)
92 if (!Convert
.ImplicitNumericConversionExists (this.type
, type
))
96 object constant_value
= ChangeType (GetValue (), type
, out fail
);
99 // We should always catch the error before this is ever
100 // reached, by calling Convert.ImplicitStandardConversionExists
102 throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
103 Type
.GetSignatureForError (), type
.GetSignatureForError ());
106 return CreateConstantFromValue (type
, constant_value
, loc
);
110 // Returns a constant instance based on Type
112 public static Constant
CreateConstantFromValue (TypeSpec t
, object v
, Location loc
)
114 switch (t
.BuiltinType
) {
115 case BuiltinTypeSpec
.Type
.Int
:
116 return new IntConstant (t
, (int) v
, loc
);
117 case BuiltinTypeSpec
.Type
.String
:
118 return new StringConstant (t
, (string) v
, loc
);
119 case BuiltinTypeSpec
.Type
.UInt
:
120 return new UIntConstant (t
, (uint) v
, loc
);
121 case BuiltinTypeSpec
.Type
.Long
:
122 return new LongConstant (t
, (long) v
, loc
);
123 case BuiltinTypeSpec
.Type
.ULong
:
124 return new ULongConstant (t
, (ulong) v
, loc
);
125 case BuiltinTypeSpec
.Type
.Float
:
126 return new FloatConstant (t
, (float) v
, loc
);
127 case BuiltinTypeSpec
.Type
.Double
:
128 return new DoubleConstant (t
, (double) v
, loc
);
129 case BuiltinTypeSpec
.Type
.Short
:
130 return new ShortConstant (t
, (short) v
, loc
);
131 case BuiltinTypeSpec
.Type
.UShort
:
132 return new UShortConstant (t
, (ushort) v
, loc
);
133 case BuiltinTypeSpec
.Type
.SByte
:
134 return new SByteConstant (t
, (sbyte) v
, loc
);
135 case BuiltinTypeSpec
.Type
.Byte
:
136 return new ByteConstant (t
, (byte) v
, loc
);
137 case BuiltinTypeSpec
.Type
.Char
:
138 return new CharConstant (t
, (char) v
, loc
);
139 case BuiltinTypeSpec
.Type
.Bool
:
140 return new BoolConstant (t
, (bool) v
, loc
);
141 case BuiltinTypeSpec
.Type
.Decimal
:
142 return new DecimalConstant (t
, (decimal) v
, loc
);
146 var real_type
= EnumSpec
.GetUnderlyingType (t
);
147 return new EnumConstant (CreateConstantFromValue (real_type
, v
, loc
), t
);
151 if (t
.IsNullableType
)
152 return Nullable
.LiftedNull
.Create (t
, loc
);
154 if (TypeSpec
.IsReferenceType (t
))
155 return new NullConstant (t
, loc
);
159 throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v
, t
.GetSignatureForError ());
166 // Returns a constant instance based on value and type. This is probing version of
167 // CreateConstantFromValue
169 public static Constant
ExtractConstantFromValue (TypeSpec t
, object v
, Location loc
)
171 switch (t
.BuiltinType
) {
172 case BuiltinTypeSpec
.Type
.Int
:
174 return new IntConstant (t
, (int) v
, loc
);
176 case BuiltinTypeSpec
.Type
.String
:
178 return new StringConstant (t
, (string) v
, loc
);
180 case BuiltinTypeSpec
.Type
.UInt
:
182 return new UIntConstant (t
, (uint) v
, loc
);
184 case BuiltinTypeSpec
.Type
.Long
:
186 return new LongConstant (t
, (long) v
, loc
);
188 case BuiltinTypeSpec
.Type
.ULong
:
190 return new ULongConstant (t
, (ulong) v
, loc
);
192 case BuiltinTypeSpec
.Type
.Float
:
194 return new FloatConstant (t
, (float) v
, loc
);
196 case BuiltinTypeSpec
.Type
.Double
:
198 return new DoubleConstant (t
, (double) v
, loc
);
200 case BuiltinTypeSpec
.Type
.Short
:
202 return new ShortConstant (t
, (short) v
, loc
);
204 case BuiltinTypeSpec
.Type
.UShort
:
206 return new UShortConstant (t
, (ushort) v
, loc
);
208 case BuiltinTypeSpec
.Type
.SByte
:
210 return new SByteConstant (t
, (sbyte) v
, loc
);
212 case BuiltinTypeSpec
.Type
.Byte
:
214 return new ByteConstant (t
, (byte) v
, loc
);
216 case BuiltinTypeSpec
.Type
.Char
:
218 return new CharConstant (t
, (char) v
, loc
);
220 case BuiltinTypeSpec
.Type
.Bool
:
222 return new BoolConstant (t
, (bool) v
, loc
);
224 case BuiltinTypeSpec
.Type
.Decimal
:
226 return new DecimalConstant (t
, (decimal) v
, loc
);
231 var real_type
= EnumSpec
.GetUnderlyingType (t
);
232 return new EnumConstant (CreateConstantFromValue (real_type
, v
, loc
), t
);
236 if (t
.IsNullableType
)
237 return Nullable
.LiftedNull
.Create (t
, loc
);
239 if (TypeSpec
.IsReferenceType (t
))
240 return new NullConstant (t
, loc
);
247 public override Expression
CreateExpressionTree (ResolveContext ec
)
249 Arguments args
= new Arguments (2);
250 args
.Add (new Argument (this));
251 args
.Add (new Argument (new TypeOf (type
, loc
)));
253 return CreateExpressionFactoryCall (ec
, "Constant", args
);
257 /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
258 /// It throws OverflowException
260 // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
261 public abstract Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
);
263 // This is a custom version of Convert.ChangeType() which works
264 // with the TypeBuilder defined types when compiling corlib.
265 static object ChangeType (object value, TypeSpec targetType
, out bool error
)
267 IConvertible convert_value
= value as IConvertible
;
269 if (convert_value
== null) {
275 // We cannot rely on build-in type conversions as they are
276 // more limited than what C# supports.
277 // See char -> float/decimal/double conversion
281 switch (targetType
.BuiltinType
) {
282 case BuiltinTypeSpec
.Type
.Bool
:
283 return convert_value
.ToBoolean (nfi
);
284 case BuiltinTypeSpec
.Type
.Byte
:
285 return convert_value
.ToByte (nfi
);
286 case BuiltinTypeSpec
.Type
.Char
:
287 return convert_value
.ToChar (nfi
);
288 case BuiltinTypeSpec
.Type
.Short
:
289 return convert_value
.ToInt16 (nfi
);
290 case BuiltinTypeSpec
.Type
.Int
:
291 return convert_value
.ToInt32 (nfi
);
292 case BuiltinTypeSpec
.Type
.Long
:
293 return convert_value
.ToInt64 (nfi
);
294 case BuiltinTypeSpec
.Type
.SByte
:
295 return convert_value
.ToSByte (nfi
);
296 case BuiltinTypeSpec
.Type
.Decimal
:
297 if (convert_value
.GetType () == typeof (char))
298 return (decimal) convert_value
.ToInt32 (nfi
);
299 return convert_value
.ToDecimal (nfi
);
300 case BuiltinTypeSpec
.Type
.Double
:
301 if (convert_value
.GetType () == typeof (char))
302 return (double) convert_value
.ToInt32 (nfi
);
303 return convert_value
.ToDouble (nfi
);
304 case BuiltinTypeSpec
.Type
.Float
:
305 if (convert_value
.GetType () == typeof (char))
306 return (float) convert_value
.ToInt32 (nfi
);
307 return convert_value
.ToSingle (nfi
);
308 case BuiltinTypeSpec
.Type
.String
:
309 return convert_value
.ToString (nfi
);
310 case BuiltinTypeSpec
.Type
.UShort
:
311 return convert_value
.ToUInt16 (nfi
);
312 case BuiltinTypeSpec
.Type
.UInt
:
313 return convert_value
.ToUInt32 (nfi
);
314 case BuiltinTypeSpec
.Type
.ULong
:
315 return convert_value
.ToUInt64 (nfi
);
316 case BuiltinTypeSpec
.Type
.Object
:
326 protected override Expression
DoResolve (ResolveContext rc
)
332 // Attempts to do a compile-time folding of a constant cast and handles
333 // error reporting for constant overlows only, on normal conversion
334 // errors returns null
336 public Constant
Reduce (ResolveContext ec
, TypeSpec target_type
)
339 return TryReduceConstant (ec
, target_type
);
340 } catch (OverflowException
) {
341 if (ec
.ConstantCheckState
&& Type
.BuiltinType
!= BuiltinTypeSpec
.Type
.Decimal
) {
342 ec
.Report
.Error (221, loc
,
343 "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
344 GetValueAsLiteral (), target_type
.GetSignatureForError ());
346 Error_ValueCannotBeConverted (ec
, target_type
, false);
349 return New
.Constantify (target_type
, loc
);
353 public Constant
TryReduce (ResolveContext rc
, TypeSpec targetType
)
356 return TryReduceConstant (rc
, targetType
);
357 } catch (OverflowException
) {
362 Constant
TryReduceConstant (ResolveContext ec
, TypeSpec target_type
)
364 if (Type
== target_type
) {
366 // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10
369 return CreateConstantFromValue (target_type
, GetValue (), loc
);
375 if (target_type
.IsEnum
) {
376 c
= TryReduceConstant (ec
, EnumSpec
.GetUnderlyingType (target_type
));
380 return new EnumConstant (c
, target_type
);
383 return ConvertExplicitly (ec
.ConstantCheckState
, target_type
);
387 /// Need to pass type as the constant can require a boxing
388 /// and in such case no optimization is possible
390 public bool IsDefaultInitializer (TypeSpec type
)
393 return IsDefaultValue
;
395 return this is NullLiteral
;
398 public abstract bool IsDefaultValue
{
402 public abstract bool IsNegative
{
407 // When constant is declared as literal
409 public virtual bool IsLiteral
{
410 get { return false; }
413 public virtual bool IsOneInteger
{
414 get { return false; }
417 public override bool IsSideEffectFree
{
424 // Returns true iff 1) the stack type of this is one of Object,
425 // int32, int64 and 2) this == 0 or this == null.
427 public virtual bool IsZeroInteger
{
428 get { return false; }
431 public override void EmitSideEffect (EmitContext ec
)
436 public sealed override Expression
Clone (CloneContext clonectx
)
438 // No cloning is not needed for constants
442 protected override void CloneTo (CloneContext clonectx
, Expression target
)
444 throw new NotSupportedException ("should not be reached");
447 public override System
.Linq
.Expressions
.Expression
MakeExpression (BuilderContext ctx
)
450 return base.MakeExpression (ctx
);
452 return System
.Linq
.Expressions
.Expression
.Constant (GetTypedValue (), type
.GetMetaInfo ());
456 public new bool Resolve (ResolveContext rc
)
458 // It exists only as hint not to call Resolve on constants
463 public abstract class IntegralConstant
: Constant
465 protected IntegralConstant (TypeSpec type
, Location loc
)
469 eclass
= ExprClass
.Value
;
472 public override void Error_ValueCannotBeConverted (ResolveContext ec
, TypeSpec target
, bool expl
)
475 ConvertExplicitly (true, target
);
476 base.Error_ValueCannotBeConverted (ec
, target
, expl
);
480 ec
.Report
.Error (31, loc
, "Constant value `{0}' cannot be converted to a `{1}'",
481 GetValueAsLiteral (), target
.GetSignatureForError ());
485 public override string GetValueAsLiteral ()
487 return GetValue ().ToString ();
490 public abstract Constant
Increment ();
493 public class BoolConstant
: Constant
{
494 public readonly bool Value
;
496 public BoolConstant (BuiltinTypes types
, bool val
, Location loc
)
497 : this (types
.Bool
, val
, loc
)
501 public BoolConstant (TypeSpec type
, bool val
, Location loc
)
504 eclass
= ExprClass
.Value
;
510 public override object GetValue ()
512 return (object) Value
;
515 public override string GetValueAsLiteral ()
517 return Value
? "true" : "false";
520 public override long GetValueAsLong ()
522 return Value
? 1 : 0;
525 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
530 public override void Emit (EmitContext ec
)
538 public override bool IsDefaultValue
{
544 public override bool IsNegative
{
550 public override bool IsZeroInteger
{
551 get { return Value == false; }
554 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
561 public class ByteConstant
: IntegralConstant
563 public readonly byte Value
;
565 public ByteConstant (BuiltinTypes types
, byte v
, Location loc
)
566 : this (types
.Byte
, v
, loc
)
570 public ByteConstant (TypeSpec type
, byte v
, Location loc
)
576 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
581 public override void Emit (EmitContext ec
)
586 public override object GetValue ()
591 public override long GetValueAsLong ()
596 public override Constant
Increment ()
598 return new ByteConstant (type
, checked ((byte)(Value
+ 1)), loc
);
601 public override bool IsDefaultValue
{
607 public override bool IsOneInteger
{
613 public override bool IsNegative
{
619 public override bool IsZeroInteger
{
620 get { return Value == 0; }
623 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
625 switch (target_type
.BuiltinType
) {
626 case BuiltinTypeSpec
.Type
.SByte
:
627 if (in_checked_context
){
628 if (Value
> SByte
.MaxValue
)
629 throw new OverflowException ();
631 return new SByteConstant (target_type
, (sbyte) Value
, Location
);
632 case BuiltinTypeSpec
.Type
.Short
:
633 return new ShortConstant (target_type
, (short) Value
, Location
);
634 case BuiltinTypeSpec
.Type
.UShort
:
635 return new UShortConstant (target_type
, (ushort) Value
, Location
);
636 case BuiltinTypeSpec
.Type
.Int
:
637 return new IntConstant (target_type
, (int) Value
, Location
);
638 case BuiltinTypeSpec
.Type
.UInt
:
639 return new UIntConstant (target_type
, (uint) Value
, Location
);
640 case BuiltinTypeSpec
.Type
.Long
:
641 return new LongConstant (target_type
, (long) Value
, Location
);
642 case BuiltinTypeSpec
.Type
.ULong
:
643 return new ULongConstant (target_type
, (ulong) Value
, Location
);
644 case BuiltinTypeSpec
.Type
.Float
:
645 return new FloatConstant (target_type
, (float) Value
, Location
);
646 case BuiltinTypeSpec
.Type
.Double
:
647 return new DoubleConstant (target_type
, (double) Value
, Location
);
648 case BuiltinTypeSpec
.Type
.Char
:
649 return new CharConstant (target_type
, (char) Value
, Location
);
650 case BuiltinTypeSpec
.Type
.Decimal
:
651 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
659 public class CharConstant
: Constant
{
660 public readonly char Value
;
662 public CharConstant (BuiltinTypes types
, char v
, Location loc
)
663 : this (types
.Char
, v
, loc
)
667 public CharConstant (TypeSpec type
, char v
, Location loc
)
671 eclass
= ExprClass
.Value
;
676 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
678 enc
.Encode ((ushort) Value
);
681 public override void Emit (EmitContext ec
)
686 static string descape (char c
)
712 return c
.ToString ();
715 public override object GetValue ()
720 public override long GetValueAsLong ()
725 public override string GetValueAsLiteral ()
727 return "\"" + descape (Value
) + "\"";
730 public override bool IsDefaultValue
{
736 public override bool IsNegative
{
742 public override bool IsZeroInteger
{
743 get { return Value == '\0'; }
746 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
748 switch (target_type
.BuiltinType
) {
749 case BuiltinTypeSpec
.Type
.Byte
:
750 if (in_checked_context
) {
751 if (Value
< Byte
.MinValue
|| Value
> Byte
.MaxValue
)
752 throw new OverflowException ();
754 return new ByteConstant (target_type
, (byte) Value
, Location
);
755 case BuiltinTypeSpec
.Type
.SByte
:
756 if (in_checked_context
) {
757 if (Value
> SByte
.MaxValue
)
758 throw new OverflowException ();
760 return new SByteConstant (target_type
, (sbyte) Value
, Location
);
762 case BuiltinTypeSpec
.Type
.Short
:
763 if (in_checked_context
) {
764 if (Value
> Int16
.MaxValue
)
765 throw new OverflowException ();
767 return new ShortConstant (target_type
, (short) Value
, Location
);
768 case BuiltinTypeSpec
.Type
.Int
:
769 return new IntConstant (target_type
, (int) Value
, Location
);
770 case BuiltinTypeSpec
.Type
.UInt
:
771 return new UIntConstant (target_type
, (uint) Value
, Location
);
772 case BuiltinTypeSpec
.Type
.Long
:
773 return new LongConstant (target_type
, (long) Value
, Location
);
774 case BuiltinTypeSpec
.Type
.ULong
:
775 return new ULongConstant (target_type
, (ulong) Value
, Location
);
776 case BuiltinTypeSpec
.Type
.Float
:
777 return new FloatConstant (target_type
, (float) Value
, Location
);
778 case BuiltinTypeSpec
.Type
.Double
:
779 return new DoubleConstant (target_type
, (double) Value
, Location
);
780 case BuiltinTypeSpec
.Type
.Decimal
:
781 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
789 public class SByteConstant
: IntegralConstant
791 public readonly sbyte Value
;
793 public SByteConstant (BuiltinTypes types
, sbyte v
, Location loc
)
794 : this (types
.SByte
, v
, loc
)
798 public SByteConstant (TypeSpec type
, sbyte v
, Location loc
)
804 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
809 public override void Emit (EmitContext ec
)
814 public override object GetValue ()
819 public override long GetValueAsLong ()
824 public override Constant
Increment ()
826 return new SByteConstant (type
, checked((sbyte)(Value
+ 1)), loc
);
829 public override bool IsDefaultValue
{
835 public override bool IsNegative
{
841 public override bool IsOneInteger
{
847 public override bool IsZeroInteger
{
848 get { return Value == 0; }
851 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
853 switch (target_type
.BuiltinType
) {
854 case BuiltinTypeSpec
.Type
.Byte
:
855 if (in_checked_context
&& Value
< 0)
856 throw new OverflowException ();
857 return new ByteConstant (target_type
, (byte) Value
, Location
);
858 case BuiltinTypeSpec
.Type
.Short
:
859 return new ShortConstant (target_type
, (short) Value
, Location
);
860 case BuiltinTypeSpec
.Type
.UShort
:
861 if (in_checked_context
&& Value
< 0)
862 throw new OverflowException ();
863 return new UShortConstant (target_type
, (ushort) Value
, Location
);
864 case BuiltinTypeSpec
.Type
.Int
:
865 return new IntConstant (target_type
, (int) Value
, Location
);
866 case BuiltinTypeSpec
.Type
.UInt
:
867 if (in_checked_context
&& Value
< 0)
868 throw new OverflowException ();
869 return new UIntConstant (target_type
, (uint) Value
, Location
);
870 case BuiltinTypeSpec
.Type
.Long
:
871 return new LongConstant (target_type
, (long) Value
, Location
);
872 case BuiltinTypeSpec
.Type
.ULong
:
873 if (in_checked_context
&& Value
< 0)
874 throw new OverflowException ();
875 return new ULongConstant (target_type
, (ulong) Value
, Location
);
876 case BuiltinTypeSpec
.Type
.Float
:
877 return new FloatConstant (target_type
, (float) Value
, Location
);
878 case BuiltinTypeSpec
.Type
.Double
:
879 return new DoubleConstant (target_type
, (double) Value
, Location
);
880 case BuiltinTypeSpec
.Type
.Char
:
881 if (in_checked_context
&& Value
< 0)
882 throw new OverflowException ();
883 return new CharConstant (target_type
, (char) Value
, Location
);
884 case BuiltinTypeSpec
.Type
.Decimal
:
885 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
893 public class ShortConstant
: IntegralConstant
{
894 public readonly short Value
;
896 public ShortConstant (BuiltinTypes types
, short v
, Location loc
)
897 : this (types
.Short
, v
, loc
)
901 public ShortConstant (TypeSpec type
, short v
, Location loc
)
907 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
912 public override void Emit (EmitContext ec
)
917 public override object GetValue ()
922 public override long GetValueAsLong ()
927 public override Constant
Increment ()
929 return new ShortConstant (type
, checked((short)(Value
+ 1)), loc
);
932 public override bool IsDefaultValue
{
938 public override bool IsZeroInteger
{
939 get { return Value == 0; }
942 public override bool IsNegative
{
948 public override bool IsOneInteger
{
954 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
956 switch (target_type
.BuiltinType
) {
957 case BuiltinTypeSpec
.Type
.Byte
:
958 if (in_checked_context
) {
959 if (Value
< Byte
.MinValue
|| Value
> Byte
.MaxValue
)
960 throw new OverflowException ();
962 return new ByteConstant (target_type
, (byte) Value
, Location
);
963 case BuiltinTypeSpec
.Type
.SByte
:
964 if (in_checked_context
) {
965 if (Value
< SByte
.MinValue
|| Value
> SByte
.MaxValue
)
966 throw new OverflowException ();
968 return new SByteConstant (target_type
, (sbyte) Value
, Location
);
969 case BuiltinTypeSpec
.Type
.UShort
:
970 if (in_checked_context
&& Value
< 0)
971 throw new OverflowException ();
973 return new UShortConstant (target_type
, (ushort) Value
, Location
);
974 case BuiltinTypeSpec
.Type
.Int
:
975 return new IntConstant (target_type
, (int) Value
, Location
);
976 case BuiltinTypeSpec
.Type
.UInt
:
977 if (in_checked_context
&& Value
< 0)
978 throw new OverflowException ();
979 return new UIntConstant (target_type
, (uint) Value
, Location
);
980 case BuiltinTypeSpec
.Type
.Long
:
981 return new LongConstant (target_type
, (long) Value
, Location
);
982 case BuiltinTypeSpec
.Type
.ULong
:
983 if (in_checked_context
&& Value
< 0)
984 throw new OverflowException ();
985 return new ULongConstant (target_type
, (ulong) Value
, Location
);
986 case BuiltinTypeSpec
.Type
.Float
:
987 return new FloatConstant (target_type
, (float) Value
, Location
);
988 case BuiltinTypeSpec
.Type
.Double
:
989 return new DoubleConstant (target_type
, (double) Value
, Location
);
990 case BuiltinTypeSpec
.Type
.Char
:
991 if (in_checked_context
) {
992 if (Value
< Char
.MinValue
)
993 throw new OverflowException ();
995 return new CharConstant (target_type
, (char) Value
, Location
);
996 case BuiltinTypeSpec
.Type
.Decimal
:
997 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
1005 public class UShortConstant
: IntegralConstant
1007 public readonly ushort Value
;
1009 public UShortConstant (BuiltinTypes types
, ushort v
, Location loc
)
1010 : this (types
.UShort
, v
, loc
)
1014 public UShortConstant (TypeSpec type
, ushort v
, Location loc
)
1020 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
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 UShortConstant (type
, checked((ushort)(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
.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
.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
.MaxValue
)
1085 throw new OverflowException ();
1087 return new ShortConstant (target_type
, (short) Value
, Location
);
1088 case BuiltinTypeSpec
.Type
.Int
:
1089 return new IntConstant (target_type
, (int) Value
, Location
);
1090 case BuiltinTypeSpec
.Type
.UInt
:
1091 return new UIntConstant (target_type
, (uint) Value
, Location
);
1092 case BuiltinTypeSpec
.Type
.Long
:
1093 return new LongConstant (target_type
, (long) Value
, Location
);
1094 case BuiltinTypeSpec
.Type
.ULong
:
1095 return new ULongConstant (target_type
, (ulong) Value
, Location
);
1096 case BuiltinTypeSpec
.Type
.Float
:
1097 return new FloatConstant (target_type
, (float) Value
, Location
);
1098 case BuiltinTypeSpec
.Type
.Double
:
1099 return new DoubleConstant (target_type
, (double) Value
, Location
);
1100 case BuiltinTypeSpec
.Type
.Char
:
1101 if (in_checked_context
) {
1102 if (Value
> Char
.MaxValue
)
1103 throw new OverflowException ();
1105 return new CharConstant (target_type
, (char) Value
, Location
);
1106 case BuiltinTypeSpec
.Type
.Decimal
:
1107 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
1114 public class IntConstant
: IntegralConstant
1116 public readonly int Value
;
1118 public IntConstant (BuiltinTypes types
, int v
, Location loc
)
1119 : this (types
.Int
, v
, loc
)
1123 public IntConstant (TypeSpec type
, int v
, Location loc
)
1129 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
1134 public override void Emit (EmitContext ec
)
1139 public override object GetValue ()
1144 public override long GetValueAsLong ()
1149 public override Constant
Increment ()
1151 return new IntConstant (type
, checked(Value
+ 1), loc
);
1154 public override bool IsDefaultValue
{
1160 public override bool IsNegative
{
1166 public override bool IsOneInteger
{
1172 public override bool IsZeroInteger
{
1173 get { return Value == 0; }
1176 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
1178 switch (target_type
.BuiltinType
) {
1179 case BuiltinTypeSpec
.Type
.Byte
:
1180 if (in_checked_context
) {
1181 if (Value
< Byte
.MinValue
|| Value
> Byte
.MaxValue
)
1182 throw new OverflowException ();
1184 return new ByteConstant (target_type
, (byte) Value
, Location
);
1185 case BuiltinTypeSpec
.Type
.SByte
:
1186 if (in_checked_context
) {
1187 if (Value
< SByte
.MinValue
|| Value
> SByte
.MaxValue
)
1188 throw new OverflowException ();
1190 return new SByteConstant (target_type
, (sbyte) Value
, Location
);
1191 case BuiltinTypeSpec
.Type
.Short
:
1192 if (in_checked_context
) {
1193 if (Value
< Int16
.MinValue
|| Value
> Int16
.MaxValue
)
1194 throw new OverflowException ();
1196 return new ShortConstant (target_type
, (short) Value
, Location
);
1197 case BuiltinTypeSpec
.Type
.UShort
:
1198 if (in_checked_context
) {
1199 if (Value
< UInt16
.MinValue
|| Value
> UInt16
.MaxValue
)
1200 throw new OverflowException ();
1202 return new UShortConstant (target_type
, (ushort) Value
, Location
);
1203 case BuiltinTypeSpec
.Type
.UInt
:
1204 if (in_checked_context
) {
1205 if (Value
< UInt32
.MinValue
)
1206 throw new OverflowException ();
1208 return new UIntConstant (target_type
, (uint) Value
, Location
);
1209 case BuiltinTypeSpec
.Type
.Long
:
1210 return new LongConstant (target_type
, (long) Value
, Location
);
1211 case BuiltinTypeSpec
.Type
.ULong
:
1212 if (in_checked_context
&& Value
< 0)
1213 throw new OverflowException ();
1214 return new ULongConstant (target_type
, (ulong) Value
, Location
);
1215 case BuiltinTypeSpec
.Type
.Float
:
1216 return new FloatConstant (target_type
, (float) Value
, Location
);
1217 case BuiltinTypeSpec
.Type
.Double
:
1218 return new DoubleConstant (target_type
, (double) Value
, Location
);
1219 case BuiltinTypeSpec
.Type
.Char
:
1220 if (in_checked_context
) {
1221 if (Value
< Char
.MinValue
|| Value
> Char
.MaxValue
)
1222 throw new OverflowException ();
1224 return new CharConstant (target_type
, (char) Value
, Location
);
1225 case BuiltinTypeSpec
.Type
.Decimal
:
1226 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
1232 public override Constant
ConvertImplicitly (TypeSpec type
)
1234 if (this.type
== type
)
1237 Constant c
= TryImplicitIntConversion (type
);
1239 return c
; //.Resolve (rc);
1241 return base.ConvertImplicitly (type
);
1245 /// Attempts to perform an implicit constant conversion of the IntConstant
1246 /// into a different data type using casts (See Implicit Constant
1247 /// Expression Conversions)
1249 Constant
TryImplicitIntConversion (TypeSpec target_type
)
1251 switch (target_type
.BuiltinType
) {
1252 case BuiltinTypeSpec
.Type
.SByte
:
1253 if (Value
>= SByte
.MinValue
&& Value
<= SByte
.MaxValue
)
1254 return new SByteConstant (target_type
, (sbyte) Value
, loc
);
1256 case BuiltinTypeSpec
.Type
.Byte
:
1257 if (Value
>= Byte
.MinValue
&& Value
<= Byte
.MaxValue
)
1258 return new ByteConstant (target_type
, (byte) Value
, loc
);
1260 case BuiltinTypeSpec
.Type
.Short
:
1261 if (Value
>= Int16
.MinValue
&& Value
<= Int16
.MaxValue
)
1262 return new ShortConstant (target_type
, (short) Value
, loc
);
1264 case BuiltinTypeSpec
.Type
.UShort
:
1265 if (Value
>= UInt16
.MinValue
&& Value
<= UInt16
.MaxValue
)
1266 return new UShortConstant (target_type
, (ushort) Value
, loc
);
1268 case BuiltinTypeSpec
.Type
.UInt
:
1270 return new UIntConstant (target_type
, (uint) Value
, loc
);
1272 case BuiltinTypeSpec
.Type
.ULong
:
1274 // we can optimize this case: a positive int32
1275 // always fits on a uint64. But we need an opcode
1279 return new ULongConstant (target_type
, (ulong) Value
, loc
);
1281 case BuiltinTypeSpec
.Type
.Double
:
1282 return new DoubleConstant (target_type
, (double) Value
, loc
);
1283 case BuiltinTypeSpec
.Type
.Float
:
1284 return new FloatConstant (target_type
, (float) Value
, loc
);
1291 public class UIntConstant
: IntegralConstant
{
1292 public readonly uint Value
;
1294 public UIntConstant (BuiltinTypes types
, uint v
, Location loc
)
1295 : this (types
.UInt
, v
, loc
)
1299 public UIntConstant (TypeSpec type
, uint v
, Location loc
)
1305 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
1310 public override void Emit (EmitContext ec
)
1312 ec
.EmitInt (unchecked ((int) Value
));
1315 public override object GetValue ()
1320 public override long GetValueAsLong ()
1325 public override Constant
Increment ()
1327 return new UIntConstant (type
, checked(Value
+ 1), loc
);
1330 public override bool IsDefaultValue
{
1336 public override bool IsNegative
{
1342 public override bool IsOneInteger
{
1348 public override bool IsZeroInteger
{
1349 get { return Value == 0; }
1352 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
1354 switch (target_type
.BuiltinType
) {
1355 case BuiltinTypeSpec
.Type
.Byte
:
1356 if (in_checked_context
) {
1357 if (Value
< 0 || Value
> byte.MaxValue
)
1358 throw new OverflowException ();
1360 return new ByteConstant (target_type
, (byte) Value
, Location
);
1361 case BuiltinTypeSpec
.Type
.SByte
:
1362 if (in_checked_context
) {
1363 if (Value
> SByte
.MaxValue
)
1364 throw new OverflowException ();
1366 return new SByteConstant (target_type
, (sbyte) Value
, Location
);
1367 case BuiltinTypeSpec
.Type
.Short
:
1368 if (in_checked_context
) {
1369 if (Value
> Int16
.MaxValue
)
1370 throw new OverflowException ();
1372 return new ShortConstant (target_type
, (short) Value
, Location
);
1373 case BuiltinTypeSpec
.Type
.UShort
:
1374 if (in_checked_context
) {
1375 if (Value
< UInt16
.MinValue
|| Value
> UInt16
.MaxValue
)
1376 throw new OverflowException ();
1378 return new UShortConstant (target_type
, (ushort) Value
, Location
);
1379 case BuiltinTypeSpec
.Type
.Int
:
1380 if (in_checked_context
) {
1381 if (Value
> Int32
.MaxValue
)
1382 throw new OverflowException ();
1384 return new IntConstant (target_type
, (int) Value
, Location
);
1385 case BuiltinTypeSpec
.Type
.Long
:
1386 return new LongConstant (target_type
, (long) Value
, Location
);
1387 case BuiltinTypeSpec
.Type
.ULong
:
1388 return new ULongConstant (target_type
, (ulong) Value
, Location
);
1389 case BuiltinTypeSpec
.Type
.Float
:
1390 return new FloatConstant (target_type
, (float) Value
, Location
);
1391 case BuiltinTypeSpec
.Type
.Double
:
1392 return new DoubleConstant (target_type
, (double) Value
, Location
);
1393 case BuiltinTypeSpec
.Type
.Char
:
1394 if (in_checked_context
) {
1395 if (Value
< Char
.MinValue
|| Value
> Char
.MaxValue
)
1396 throw new OverflowException ();
1398 return new CharConstant (target_type
, (char) Value
, Location
);
1399 case BuiltinTypeSpec
.Type
.Decimal
:
1400 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
1408 public class LongConstant
: IntegralConstant
{
1409 public readonly long Value
;
1411 public LongConstant (BuiltinTypes types
, long v
, Location loc
)
1412 : this (types
.Long
, v
, loc
)
1416 public LongConstant (TypeSpec type
, long v
, Location loc
)
1422 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
1427 public override void Emit (EmitContext ec
)
1429 ec
.EmitLong (Value
);
1432 public override object GetValue ()
1437 public override long GetValueAsLong ()
1442 public override Constant
Increment ()
1444 return new LongConstant (type
, checked(Value
+ 1), loc
);
1447 public override bool IsDefaultValue
{
1453 public override bool IsNegative
{
1459 public override bool IsOneInteger
{
1465 public override bool IsZeroInteger
{
1466 get { return Value == 0; }
1469 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
1471 switch (target_type
.BuiltinType
) {
1472 case BuiltinTypeSpec
.Type
.Byte
:
1473 if (in_checked_context
) {
1474 if (Value
< Byte
.MinValue
|| Value
> Byte
.MaxValue
)
1475 throw new OverflowException ();
1477 return new ByteConstant (target_type
, (byte) Value
, Location
);
1478 case BuiltinTypeSpec
.Type
.SByte
:
1479 if (in_checked_context
) {
1480 if (Value
< SByte
.MinValue
|| Value
> SByte
.MaxValue
)
1481 throw new OverflowException ();
1483 return new SByteConstant (target_type
, (sbyte) Value
, Location
);
1484 case BuiltinTypeSpec
.Type
.Short
:
1485 if (in_checked_context
) {
1486 if (Value
< Int16
.MinValue
|| Value
> Int16
.MaxValue
)
1487 throw new OverflowException ();
1489 return new ShortConstant (target_type
, (short) Value
, Location
);
1490 case BuiltinTypeSpec
.Type
.UShort
:
1491 if (in_checked_context
) {
1492 if (Value
< UInt16
.MinValue
|| Value
> UInt16
.MaxValue
)
1493 throw new OverflowException ();
1495 return new UShortConstant (target_type
, (ushort) Value
, Location
);
1496 case BuiltinTypeSpec
.Type
.Int
:
1497 if (in_checked_context
) {
1498 if (Value
< Int32
.MinValue
|| Value
> Int32
.MaxValue
)
1499 throw new OverflowException ();
1501 return new IntConstant (target_type
, (int) Value
, Location
);
1502 case BuiltinTypeSpec
.Type
.UInt
:
1503 if (in_checked_context
) {
1504 if (Value
< UInt32
.MinValue
|| Value
> UInt32
.MaxValue
)
1505 throw new OverflowException ();
1507 return new UIntConstant (target_type
, (uint) Value
, Location
);
1508 case BuiltinTypeSpec
.Type
.ULong
:
1509 if (in_checked_context
&& Value
< 0)
1510 throw new OverflowException ();
1511 return new ULongConstant (target_type
, (ulong) Value
, Location
);
1512 case BuiltinTypeSpec
.Type
.Float
:
1513 return new FloatConstant (target_type
, (float) Value
, Location
);
1514 case BuiltinTypeSpec
.Type
.Double
:
1515 return new DoubleConstant (target_type
, (double) Value
, Location
);
1516 case BuiltinTypeSpec
.Type
.Char
:
1517 if (in_checked_context
) {
1518 if (Value
< Char
.MinValue
|| Value
> Char
.MaxValue
)
1519 throw new OverflowException ();
1521 return new CharConstant (target_type
, (char) Value
, Location
);
1522 case BuiltinTypeSpec
.Type
.Decimal
:
1523 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
1529 public override Constant
ConvertImplicitly (TypeSpec type
)
1531 if (Value
>= 0 && type
.BuiltinType
== BuiltinTypeSpec
.Type
.ULong
) {
1532 return new ULongConstant (type
, (ulong) Value
, loc
);
1535 return base.ConvertImplicitly (type
);
1539 public class ULongConstant
: IntegralConstant
{
1540 public readonly ulong Value
;
1542 public ULongConstant (BuiltinTypes types
, ulong v
, Location loc
)
1543 : this (types
.ULong
, v
, loc
)
1547 public ULongConstant (TypeSpec type
, ulong v
, Location loc
)
1553 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
1558 public override void Emit (EmitContext ec
)
1560 ec
.EmitLong (unchecked ((long) Value
));
1563 public override object GetValue ()
1568 public override long GetValueAsLong ()
1570 return (long) Value
;
1573 public override Constant
Increment ()
1575 return new ULongConstant (type
, checked(Value
+ 1), loc
);
1578 public override bool IsDefaultValue
{
1584 public override bool IsNegative
{
1590 public override bool IsOneInteger
{
1596 public override bool IsZeroInteger
{
1597 get { return Value == 0; }
1600 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
1602 switch (target_type
.BuiltinType
) {
1603 case BuiltinTypeSpec
.Type
.Byte
:
1604 if (in_checked_context
&& Value
> Byte
.MaxValue
)
1605 throw new OverflowException ();
1606 return new ByteConstant (target_type
, (byte) Value
, Location
);
1607 case BuiltinTypeSpec
.Type
.SByte
:
1608 if (in_checked_context
&& Value
> ((ulong) SByte
.MaxValue
))
1609 throw new OverflowException ();
1610 return new SByteConstant (target_type
, (sbyte) Value
, Location
);
1611 case BuiltinTypeSpec
.Type
.Short
:
1612 if (in_checked_context
&& Value
> ((ulong) Int16
.MaxValue
))
1613 throw new OverflowException ();
1614 return new ShortConstant (target_type
, (short) Value
, Location
);
1615 case BuiltinTypeSpec
.Type
.UShort
:
1616 if (in_checked_context
&& Value
> UInt16
.MaxValue
)
1617 throw new OverflowException ();
1618 return new UShortConstant (target_type
, (ushort) Value
, Location
);
1619 case BuiltinTypeSpec
.Type
.Int
:
1620 if (in_checked_context
&& Value
> UInt32
.MaxValue
)
1621 throw new OverflowException ();
1622 return new IntConstant (target_type
, (int) Value
, Location
);
1623 case BuiltinTypeSpec
.Type
.UInt
:
1624 if (in_checked_context
&& Value
> UInt32
.MaxValue
)
1625 throw new OverflowException ();
1626 return new UIntConstant (target_type
, (uint) Value
, Location
);
1627 case BuiltinTypeSpec
.Type
.Long
:
1628 if (in_checked_context
&& Value
> Int64
.MaxValue
)
1629 throw new OverflowException ();
1630 return new LongConstant (target_type
, (long) Value
, Location
);
1631 case BuiltinTypeSpec
.Type
.Float
:
1632 return new FloatConstant (target_type
, (float) Value
, Location
);
1633 case BuiltinTypeSpec
.Type
.Double
:
1634 return new DoubleConstant (target_type
, (double) Value
, Location
);
1635 case BuiltinTypeSpec
.Type
.Char
:
1636 if (in_checked_context
&& Value
> Char
.MaxValue
)
1637 throw new OverflowException ();
1638 return new CharConstant (target_type
, (char) Value
, Location
);
1639 case BuiltinTypeSpec
.Type
.Decimal
:
1640 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
1648 public class FloatConstant
: Constant
{
1650 // Store constant value as double because float constant operations
1651 // need to work on double value to match JIT
1653 public readonly double DoubleValue
;
1655 public FloatConstant (BuiltinTypes types
, double v
, Location loc
)
1656 : this (types
.Float
, v
, loc
)
1660 public FloatConstant (TypeSpec type
, double v
, Location loc
)
1664 eclass
= ExprClass
.Value
;
1669 public override Constant
ConvertImplicitly (TypeSpec type
)
1671 if (type
.BuiltinType
== BuiltinTypeSpec
.Type
.Double
)
1672 return new DoubleConstant (type
, DoubleValue
, loc
);
1674 return base.ConvertImplicitly (type
);
1677 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
1682 public override void Emit (EmitContext ec
)
1684 ec
.Emit (OpCodes
.Ldc_R4
, Value
);
1687 public float Value
{
1689 return (float) DoubleValue
;
1693 public override object GetValue ()
1698 public override string GetValueAsLiteral ()
1700 return Value
.ToString (CultureInfo
.InvariantCulture
);
1703 public override long GetValueAsLong ()
1705 throw new NotSupportedException ();
1708 public override bool IsDefaultValue
{
1714 public override bool IsNegative
{
1720 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
1722 switch (target_type
.BuiltinType
) {
1723 case BuiltinTypeSpec
.Type
.Byte
:
1724 if (in_checked_context
) {
1725 if (Value
< byte.MinValue
|| Value
> byte.MaxValue
|| float.IsNaN (Value
))
1726 throw new OverflowException ();
1728 return new ByteConstant (target_type
, (byte) DoubleValue
, Location
);
1729 case BuiltinTypeSpec
.Type
.SByte
:
1730 if (in_checked_context
) {
1731 if (Value
< sbyte.MinValue
|| Value
> sbyte.MaxValue
|| float.IsNaN (Value
))
1732 throw new OverflowException ();
1734 return new SByteConstant (target_type
, (sbyte) DoubleValue
, Location
);
1735 case BuiltinTypeSpec
.Type
.Short
:
1736 if (in_checked_context
) {
1737 if (Value
< short.MinValue
|| Value
> short.MaxValue
|| float.IsNaN (Value
))
1738 throw new OverflowException ();
1740 return new ShortConstant (target_type
, (short) DoubleValue
, Location
);
1741 case BuiltinTypeSpec
.Type
.UShort
:
1742 if (in_checked_context
) {
1743 if (Value
< ushort.MinValue
|| Value
> ushort.MaxValue
|| float.IsNaN (Value
))
1744 throw new OverflowException ();
1746 return new UShortConstant (target_type
, (ushort) DoubleValue
, Location
);
1747 case BuiltinTypeSpec
.Type
.Int
:
1748 if (in_checked_context
) {
1749 if (Value
< int.MinValue
|| Value
> int.MaxValue
|| float.IsNaN (Value
))
1750 throw new OverflowException ();
1752 return new IntConstant (target_type
, (int) DoubleValue
, Location
);
1753 case BuiltinTypeSpec
.Type
.UInt
:
1754 if (in_checked_context
) {
1755 if (Value
< uint.MinValue
|| Value
> uint.MaxValue
|| float.IsNaN (Value
))
1756 throw new OverflowException ();
1758 return new UIntConstant (target_type
, (uint) DoubleValue
, Location
);
1759 case BuiltinTypeSpec
.Type
.Long
:
1760 if (in_checked_context
) {
1761 if (Value
< long.MinValue
|| Value
> long.MaxValue
|| float.IsNaN (Value
))
1762 throw new OverflowException ();
1764 return new LongConstant (target_type
, (long) DoubleValue
, Location
);
1765 case BuiltinTypeSpec
.Type
.ULong
:
1766 if (in_checked_context
) {
1767 if (Value
< ulong.MinValue
|| Value
> ulong.MaxValue
|| float.IsNaN (Value
))
1768 throw new OverflowException ();
1770 return new ULongConstant (target_type
, (ulong) DoubleValue
, Location
);
1771 case BuiltinTypeSpec
.Type
.Double
:
1772 return new DoubleConstant (target_type
, DoubleValue
, Location
);
1773 case BuiltinTypeSpec
.Type
.Char
:
1774 if (in_checked_context
) {
1775 if (Value
< (float) char.MinValue
|| Value
> (float) char.MaxValue
|| float.IsNaN (Value
))
1776 throw new OverflowException ();
1778 return new CharConstant (target_type
, (char) DoubleValue
, Location
);
1779 case BuiltinTypeSpec
.Type
.Decimal
:
1780 return new DecimalConstant (target_type
, (decimal) DoubleValue
, Location
);
1788 public class DoubleConstant
: Constant
1790 public readonly double Value
;
1792 public DoubleConstant (BuiltinTypes types
, double v
, Location loc
)
1793 : this (types
.Double
, v
, loc
)
1797 public DoubleConstant (TypeSpec type
, double v
, Location loc
)
1801 eclass
= ExprClass
.Value
;
1806 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
1811 public override void Emit (EmitContext ec
)
1813 ec
.Emit (OpCodes
.Ldc_R8
, Value
);
1816 public override object GetValue ()
1821 public override string GetValueAsLiteral ()
1823 return Value
.ToString (CultureInfo
.InvariantCulture
);
1826 public override long GetValueAsLong ()
1828 throw new NotSupportedException ();
1831 public override bool IsDefaultValue
{
1837 public override bool IsNegative
{
1843 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
1845 switch (target_type
.BuiltinType
) {
1846 case BuiltinTypeSpec
.Type
.Byte
:
1847 if (in_checked_context
) {
1848 if (Value
< Byte
.MinValue
|| Value
> Byte
.MaxValue
|| double.IsNaN (Value
))
1849 throw new OverflowException ();
1851 return new ByteConstant (target_type
, (byte) Value
, Location
);
1852 case BuiltinTypeSpec
.Type
.SByte
:
1853 if (in_checked_context
) {
1854 if (Value
< SByte
.MinValue
|| Value
> SByte
.MaxValue
|| double.IsNaN (Value
))
1855 throw new OverflowException ();
1857 return new SByteConstant (target_type
, (sbyte) Value
, Location
);
1858 case BuiltinTypeSpec
.Type
.Short
:
1859 if (in_checked_context
) {
1860 if (Value
< short.MinValue
|| Value
> short.MaxValue
|| double.IsNaN (Value
))
1861 throw new OverflowException ();
1863 return new ShortConstant (target_type
, (short) Value
, Location
);
1864 case BuiltinTypeSpec
.Type
.UShort
:
1865 if (in_checked_context
) {
1866 if (Value
< ushort.MinValue
|| Value
> ushort.MaxValue
|| double.IsNaN (Value
))
1867 throw new OverflowException ();
1869 return new UShortConstant (target_type
, (ushort) Value
, Location
);
1870 case BuiltinTypeSpec
.Type
.Int
:
1871 if (in_checked_context
) {
1872 if (Value
< int.MinValue
|| Value
> int.MaxValue
|| double.IsNaN (Value
))
1873 throw new OverflowException ();
1875 return new IntConstant (target_type
, (int) Value
, Location
);
1876 case BuiltinTypeSpec
.Type
.UInt
:
1877 if (in_checked_context
) {
1878 if (Value
< uint.MinValue
|| Value
> uint.MaxValue
|| double.IsNaN (Value
))
1879 throw new OverflowException ();
1881 return new UIntConstant (target_type
, (uint) Value
, Location
);
1882 case BuiltinTypeSpec
.Type
.Long
:
1883 if (in_checked_context
) {
1884 if (Value
< long.MinValue
|| Value
> long.MaxValue
|| double.IsNaN (Value
))
1885 throw new OverflowException ();
1887 return new LongConstant (target_type
, (long) Value
, Location
);
1888 case BuiltinTypeSpec
.Type
.ULong
:
1889 if (in_checked_context
) {
1890 if (Value
< ulong.MinValue
|| Value
> ulong.MaxValue
|| double.IsNaN (Value
))
1891 throw new OverflowException ();
1893 return new ULongConstant (target_type
, (ulong) Value
, Location
);
1894 case BuiltinTypeSpec
.Type
.Float
:
1895 return new FloatConstant (target_type
, (float) Value
, Location
);
1896 case BuiltinTypeSpec
.Type
.Char
:
1897 if (in_checked_context
) {
1898 if (Value
< (double) char.MinValue
|| Value
> (double) char.MaxValue
|| double.IsNaN (Value
))
1899 throw new OverflowException ();
1901 return new CharConstant (target_type
, (char) Value
, Location
);
1902 case BuiltinTypeSpec
.Type
.Decimal
:
1903 return new DecimalConstant (target_type
, (decimal) Value
, Location
);
1911 public class DecimalConstant
: Constant
{
1912 public readonly decimal Value
;
1914 public DecimalConstant (BuiltinTypes types
, decimal d
, Location loc
)
1915 : this (types
.Decimal
, d
, loc
)
1919 public DecimalConstant (TypeSpec type
, decimal d
, Location loc
)
1923 eclass
= ExprClass
.Value
;
1928 public override void Emit (EmitContext ec
)
1932 int [] words
= decimal.GetBits (Value
);
1933 int power
= (words
[3] >> 16) & 0xff;
1936 if (Value
<= int.MaxValue
&& Value
>= int.MinValue
) {
1937 m
= ec
.Module
.PredefinedMembers
.DecimalCtorInt
.Resolve (loc
);
1942 ec
.EmitInt ((int) Value
);
1943 ec
.Emit (OpCodes
.Newobj
, m
);
1947 if (Value
<= long.MaxValue
&& Value
>= long.MinValue
) {
1948 m
= ec
.Module
.PredefinedMembers
.DecimalCtorLong
.Resolve (loc
);
1953 ec
.EmitLong ((long) Value
);
1954 ec
.Emit (OpCodes
.Newobj
, m
);
1959 ec
.EmitInt (words
[0]);
1960 ec
.EmitInt (words
[1]);
1961 ec
.EmitInt (words
[2]);
1964 ec
.EmitInt (words
[3] >> 31);
1969 m
= ec
.Module
.PredefinedMembers
.DecimalCtor
.Resolve (loc
);
1971 ec
.Emit (OpCodes
.Newobj
, m
);
1975 public override bool IsDefaultValue
{
1981 public override bool IsNegative
{
1987 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
1989 switch (target_type
.BuiltinType
) {
1990 case BuiltinTypeSpec
.Type
.SByte
:
1991 return new SByteConstant (target_type
, (sbyte) Value
, loc
);
1992 case BuiltinTypeSpec
.Type
.Byte
:
1993 return new ByteConstant (target_type
, (byte) Value
, loc
);
1994 case BuiltinTypeSpec
.Type
.Short
:
1995 return new ShortConstant (target_type
, (short) Value
, loc
);
1996 case BuiltinTypeSpec
.Type
.UShort
:
1997 return new UShortConstant (target_type
, (ushort) Value
, loc
);
1998 case BuiltinTypeSpec
.Type
.Int
:
1999 return new IntConstant (target_type
, (int) Value
, loc
);
2000 case BuiltinTypeSpec
.Type
.UInt
:
2001 return new UIntConstant (target_type
, (uint) Value
, loc
);
2002 case BuiltinTypeSpec
.Type
.Long
:
2003 return new LongConstant (target_type
, (long) Value
, loc
);
2004 case BuiltinTypeSpec
.Type
.ULong
:
2005 return new ULongConstant (target_type
, (ulong) Value
, loc
);
2006 case BuiltinTypeSpec
.Type
.Char
:
2007 return new CharConstant (target_type
, (char) Value
, loc
);
2008 case BuiltinTypeSpec
.Type
.Float
:
2009 return new FloatConstant (target_type
, (float) Value
, loc
);
2010 case BuiltinTypeSpec
.Type
.Double
:
2011 return new DoubleConstant (target_type
, (double) Value
, loc
);
2017 public override object GetValue ()
2022 public override string GetValueAsLiteral ()
2024 return Value
.ToString (CultureInfo
.InvariantCulture
) + "M";
2027 public override long GetValueAsLong ()
2029 throw new NotSupportedException ();
2033 public class StringConstant
: Constant
{
2034 public StringConstant (BuiltinTypes types
, string s
, Location loc
)
2035 : this (types
.String
, s
, loc
)
2039 public StringConstant (TypeSpec type
, string s
, Location loc
)
2043 eclass
= ExprClass
.Value
;
2048 protected StringConstant (Location loc
)
2053 public string Value { get; protected set; }
2055 public override object GetValue ()
2060 public override string GetValueAsLiteral ()
2062 // FIXME: Escape the string.
2063 return "\"" + Value
+ "\"";
2066 public override long GetValueAsLong ()
2068 throw new NotSupportedException ();
2071 public override void Emit (EmitContext ec
)
2073 if (Value
== null) {
2079 // Use string.Empty for both literals and constants even if
2080 // it's not allowed at language level
2082 if (Value
.Length
== 0 && ec
.Module
.Compiler
.Settings
.Optimize
) {
2083 var string_type
= ec
.BuiltinTypes
.String
;
2084 if (ec
.CurrentType
!= string_type
) {
2085 var m
= ec
.Module
.PredefinedMembers
.StringEmpty
.Get ();
2087 ec
.Emit (OpCodes
.Ldsfld
, m
);
2094 if (ec
.Module
.GetResourceStrings
!= null && !ec
.Module
.GetResourceStrings
.TryGetValue (str
, out str
)) {
2098 ec
.Emit (OpCodes
.Ldstr
, str
);
2101 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
2104 if (type
!= targetType
)
2110 public override bool IsDefaultValue
{
2112 return Value
== null;
2116 public override bool IsNegative
{
2122 public override bool IsNull
{
2124 return IsDefaultValue
;
2128 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
2133 public override Constant
ConvertImplicitly (TypeSpec type
)
2135 if (IsDefaultValue
&& type
.BuiltinType
== BuiltinTypeSpec
.Type
.Object
)
2136 return new NullConstant (type
, loc
);
2138 return base.ConvertImplicitly (type
);
2142 class NameOf
: StringConstant
2144 readonly SimpleName name
;
2146 public NameOf (SimpleName name
)
2147 : base (name
.Location
)
2152 protected override Expression
DoResolve (ResolveContext rc
)
2154 throw new NotSupportedException ();
2157 bool ResolveArgumentExpression (ResolveContext rc
, Expression expr
)
2159 var sn
= expr
as SimpleName
;
2163 if (rc
.Module
.Compiler
.Settings
.Version
< LanguageVersion
.V_6
)
2164 rc
.Report
.FeatureIsNotAvailable (rc
.Module
.Compiler
, Location
, "nameof operator");
2166 var res
= sn
.LookupNameExpression (rc
, MemberLookupRestrictions
.IgnoreAmbiguity
| MemberLookupRestrictions
.NameOfExcluded
);
2167 var me
= res
as MemberExpr
;
2169 me
.ResolveNameOf (rc
, sn
);
2174 var ma
= expr
as MemberAccess
;
2176 var lexpr
= ma
.LeftExpression
;
2179 using (rc
.Set (ResolveContext
.Options
.NameOfScope
)) {
2180 res
= ma
.LookupNameExpression (rc
, MemberLookupRestrictions
.IgnoreAmbiguity
);
2187 if (rc
.Module
.Compiler
.Settings
.Version
< LanguageVersion
.V_6
)
2188 rc
.Report
.FeatureIsNotAvailable (rc
.Module
.Compiler
, Location
, "nameof operator");
2190 if (ma
is QualifiedAliasMember
) {
2191 rc
.Report
.Error (8083, loc
, "An alias-qualified name is not an expression");
2195 var me
= res
as MemberExpr
;
2197 me
.ResolveNameOf (rc
, ma
);
2201 // LAMESPEC: Why is conditional access not allowed?
2203 if (!IsLeftResolvedExpressionValid (ma
.LeftExpression
) || ma
.HasConditionalAccess ()) {
2204 rc
.Report
.Error (8082, lexpr
.Location
, "An argument to nameof operator cannot include sub-expression");
2212 rc
.Report
.Error (8081, loc
, "Expression does not have a name");
2216 static bool IsLeftResolvedExpressionValid (Expression expr
)
2218 var fe
= expr
as FieldExpr
;
2220 return fe
.InstanceExpression
== null || IsLeftResolvedExpressionValid (fe
.InstanceExpression
);
2223 var pe
= expr
as PropertyExpr
;
2225 return pe
.InstanceExpression
== null || IsLeftResolvedExpressionValid (pe
.InstanceExpression
);
2227 var dmb
= expr
as DynamicMemberBinder
;
2229 return IsLeftResolvedExpressionValid (dmb
.Arguments
[0].Expr
);
2232 if (expr
is ConstantExpr
|| expr
is TypeExpr
|| expr
is NamespaceExpression
|| expr
is VariableReference
)
2238 public Expression
ResolveOverload (ResolveContext rc
, Arguments args
)
2240 if (args
== null || args
.Count
!= 1) {
2241 name
.Error_NameDoesNotExist (rc
);
2246 var res
= ResolveArgumentExpression (rc
, arg
.Expr
);
2251 type
= rc
.BuiltinTypes
.String
;
2252 eclass
= ExprClass
.Value
;
2258 // Null constant can have its own type, think of `default (Foo)'
2260 public class NullConstant
: Constant
2262 public NullConstant (TypeSpec type
, Location loc
)
2265 eclass
= ExprClass
.Value
;
2269 public override Expression
CreateExpressionTree (ResolveContext ec
)
2271 if (type
== InternalType
.NullLiteral
|| type
.BuiltinType
== BuiltinTypeSpec
.Type
.Object
) {
2272 // Optimized version, also avoids referencing literal internal type
2273 Arguments args
= new Arguments (1);
2274 args
.Add (new Argument (this));
2275 return CreateExpressionFactoryCall (ec
, "Constant", args
);
2278 return base.CreateExpressionTree (ec
);
2281 public override void EncodeAttributeValue (IMemberContext rc
, AttributeEncoder enc
, TypeSpec targetType
, TypeSpec parameterType
)
2283 switch (targetType
.BuiltinType
) {
2284 case BuiltinTypeSpec
.Type
.Object
:
2285 // Type it as string cast
2286 enc
.Encode (rc
.Module
.Compiler
.BuiltinTypes
.String
);
2287 goto case BuiltinTypeSpec
.Type
.String
;
2288 case BuiltinTypeSpec
.Type
.String
:
2289 case BuiltinTypeSpec
.Type
.Type
:
2290 enc
.Encode (byte.MaxValue
);
2293 var ac
= targetType
as ArrayContainer
;
2294 if (ac
!= null && ac
.Rank
== 1 && !ac
.Element
.IsArray
) {
2295 enc
.Encode (uint.MaxValue
);
2302 base.EncodeAttributeValue (rc
, enc
, targetType
, parameterType
);
2305 public override void Emit (EmitContext ec
)
2309 // Only to make verifier happy
2310 if (type
.IsGenericParameter
)
2311 ec
.Emit (OpCodes
.Unbox_Any
, type
);
2314 public override string ExprClassName
{
2316 return GetSignatureForError ();
2320 public override Constant
ConvertExplicitly (bool inCheckedContext
, TypeSpec targetType
)
2322 if (targetType
.IsPointer
) {
2323 if (IsLiteral
|| this is NullPointer
)
2324 return new NullPointer (targetType
, loc
);
2329 // Exlude internal compiler types
2330 if (targetType
.Kind
== MemberKind
.InternalCompilerType
&& targetType
.BuiltinType
!= BuiltinTypeSpec
.Type
.Dynamic
)
2333 if (!IsLiteral
&& !Convert
.ImplicitStandardConversionExists (this, targetType
))
2336 if (TypeSpec
.IsReferenceType (targetType
))
2337 return new NullConstant (targetType
, loc
);
2339 if (targetType
.IsNullableType
)
2340 return Nullable
.LiftedNull
.Create (targetType
, loc
);
2345 public override Constant
ConvertImplicitly (TypeSpec targetType
)
2347 return ConvertExplicitly (false, targetType
);
2350 public override string GetSignatureForError ()
2355 public override object GetValue ()
2360 public override string GetValueAsLiteral ()
2362 return GetSignatureForError ();
2365 public override long GetValueAsLong ()
2367 throw new NotSupportedException ();
2370 public override bool IsDefaultValue
{
2371 get { return true; }
2374 public override bool IsNegative
{
2375 get { return false; }
2378 public override bool IsNull
{
2379 get { return true; }
2382 public override bool IsZeroInteger
{
2383 get { return true; }
2389 // A null constant in a pointer context
2391 class NullPointer
: NullConstant
2393 public NullPointer (TypeSpec type
, Location loc
)
2398 public override Expression
CreateExpressionTree (ResolveContext ec
)
2400 Error_PointerInsideExpressionTree (ec
);
2401 return base.CreateExpressionTree (ec
);
2404 public override void Emit (EmitContext ec
)
2407 // Emits null pointer
2410 ec
.Emit (OpCodes
.Conv_U
);
2415 /// The value is constant, but when emitted has a side effect. This is
2416 /// used by BitwiseAnd to ensure that the second expression is invoked
2417 /// regardless of the value of the left side.
2419 public class SideEffectConstant
: Constant
2421 public readonly Constant
value;
2422 Expression side_effect
;
2424 public SideEffectConstant (Constant
value, Expression side_effect
, Location loc
)
2429 eclass
= ExprClass
.Value
;
2431 while (side_effect
is SideEffectConstant
)
2432 side_effect
= ((SideEffectConstant
) side_effect
).side_effect
;
2433 this.side_effect
= side_effect
;
2436 public override bool IsSideEffectFree
{
2442 public override bool ContainsEmitWithAwait ()
2444 return side_effect
.ContainsEmitWithAwait ();
2447 public override object GetValue ()
2449 return value.GetValue ();
2452 public override string GetValueAsLiteral ()
2454 return value.GetValueAsLiteral ();
2457 public override long GetValueAsLong ()
2459 return value.GetValueAsLong ();
2462 public override void Emit (EmitContext ec
)
2464 side_effect
.EmitSideEffect (ec
);
2468 public override void EmitSideEffect (EmitContext ec
)
2470 side_effect
.EmitSideEffect (ec
);
2471 value.EmitSideEffect (ec
);
2474 public override void FlowAnalysis (FlowAnalysisContext fc
)
2476 side_effect
.FlowAnalysis (fc
);
2479 public override bool IsDefaultValue
{
2480 get { return value.IsDefaultValue; }
2483 public override bool IsNegative
{
2484 get { return value.IsNegative; }
2487 public override bool IsZeroInteger
{
2488 get { return value.IsZeroInteger; }
2491 public override Constant
ConvertExplicitly (bool in_checked_context
, TypeSpec target_type
)
2493 Constant new_value
= value.ConvertExplicitly (in_checked_context
, target_type
);
2494 if (new_value
== null)
2497 var c
= new SideEffectConstant (new_value
, side_effect
, new_value
.Location
);
2498 c
.type
= target_type
;