2
// constant.cs: Constants.
5
// Miguel de Icaza (miguel@ximian.com)
6
// Marek Safar (marek.safar@seznam.cz)
8
// Copyright 2001-2003 Ximian, Inc.
9
// Copyright 2003-2008 Novell, Inc.
10
// Copyright 2011 Xamarin Inc
14
using System.Globalization;
17
using IKVM.Reflection.Emit;
19
using System.Reflection.Emit;
22
namespace Mono.CSharp {
25
/// Base class for constants and literals.
27
public abstract class Constant : Expression
29
static readonly NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat;
31
protected Constant (Location loc)
36
override public string ToString ()
38
return this.GetType ().Name + " (" + GetValueAsLiteral () + ")";
42
/// This is used to obtain the actual value of the literal
43
/// cast into an object.
45
public abstract object GetValue ();
47
public abstract long GetValueAsLong ();
49
public abstract string GetValueAsLiteral ();
53
// Returns an object value which is typed to contant type
55
public virtual object GetTypedValue ()
61
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
63
if (!expl && IsLiteral &&
64
BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
65
BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) {
66
ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
67
GetValueAsLiteral (), TypeManager.CSharpName (target));
69
base.Error_ValueCannotBeConverted (ec, target, expl);
73
public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc)
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.ImplicitNumericConversion (this, type) == null)
96
object constant_value = ChangeType (GetValue (), type, out fail);
99
// We should always catch the error before this is ever
100
// reached, by calling Convert.ImplicitStandardConversionExists
102
throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
103
TypeManager.CSharpName (Type), TypeManager.CSharpName (type));
106
return CreateConstant (type, constant_value, loc);
110
// Returns a constant instance based on Type
112
public static Constant CreateConstant (TypeSpec t, object v, Location loc)
114
return CreateConstantFromValue (t, v, loc);
117
public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
119
switch (t.BuiltinType) {
120
case BuiltinTypeSpec.Type.Int:
121
return new IntConstant (t, (int) v, loc);
122
case BuiltinTypeSpec.Type.String:
123
return new StringConstant (t, (string) v, loc);
124
case BuiltinTypeSpec.Type.UInt:
125
return new UIntConstant (t, (uint) v, loc);
126
case BuiltinTypeSpec.Type.Long:
127
return new LongConstant (t, (long) v, loc);
128
case BuiltinTypeSpec.Type.ULong:
129
return new ULongConstant (t, (ulong) v, loc);
130
case BuiltinTypeSpec.Type.Float:
131
return new FloatConstant (t, (float) v, loc);
132
case BuiltinTypeSpec.Type.Double:
133
return new DoubleConstant (t, (double) v, loc);
134
case BuiltinTypeSpec.Type.Short:
135
return new ShortConstant (t, (short) v, loc);
136
case BuiltinTypeSpec.Type.UShort:
137
return new UShortConstant (t, (ushort) v, loc);
138
case BuiltinTypeSpec.Type.SByte:
139
return new SByteConstant (t, (sbyte) v, loc);
140
case BuiltinTypeSpec.Type.Byte:
141
return new ByteConstant (t, (byte) v, loc);
142
case BuiltinTypeSpec.Type.Char:
143
return new CharConstant (t, (char) v, loc);
144
case BuiltinTypeSpec.Type.Bool:
145
return new BoolConstant (t, (bool) v, loc);
146
case BuiltinTypeSpec.Type.Decimal:
147
return new DecimalConstant (t, (decimal) v, loc);
151
var real_type = EnumSpec.GetUnderlyingType (t);
152
return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
156
if (t.IsNullableType)
157
return Nullable.LiftedNull.Create (t, loc);
159
if (TypeSpec.IsReferenceType (t))
160
return new NullConstant (t, loc);
164
throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ());
170
public override Expression CreateExpressionTree (ResolveContext ec)
172
Arguments args = new Arguments (2);
173
args.Add (new Argument (this));
174
args.Add (new Argument (new TypeOf (type, loc)));
176
return CreateExpressionFactoryCall (ec, "Constant", args);
180
/// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
181
/// It throws OverflowException
183
// DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
184
public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
186
// This is a custom version of Convert.ChangeType() which works
187
// with the TypeBuilder defined types when compiling corlib.
188
static object ChangeType (object value, TypeSpec targetType, out bool error)
190
IConvertible convert_value = value as IConvertible;
192
if (convert_value == null) {
198
// We cannot rely on build-in type conversions as they are
199
// more limited than what C# supports.
200
// See char -> float/decimal/double conversion
204
switch (targetType.BuiltinType) {
205
case BuiltinTypeSpec.Type.Bool:
206
return convert_value.ToBoolean (nfi);
207
case BuiltinTypeSpec.Type.Byte:
208
return convert_value.ToByte (nfi);
209
case BuiltinTypeSpec.Type.Char:
210
return convert_value.ToChar (nfi);
211
case BuiltinTypeSpec.Type.Short:
212
return convert_value.ToInt16 (nfi);
213
case BuiltinTypeSpec.Type.Int:
214
return convert_value.ToInt32 (nfi);
215
case BuiltinTypeSpec.Type.Long:
216
return convert_value.ToInt64 (nfi);
217
case BuiltinTypeSpec.Type.SByte:
218
return convert_value.ToSByte (nfi);
219
case BuiltinTypeSpec.Type.Decimal:
220
if (convert_value.GetType () == typeof (char))
221
return (decimal) convert_value.ToInt32 (nfi);
222
return convert_value.ToDecimal (nfi);
223
case BuiltinTypeSpec.Type.Double:
224
if (convert_value.GetType () == typeof (char))
225
return (double) convert_value.ToInt32 (nfi);
226
return convert_value.ToDouble (nfi);
227
case BuiltinTypeSpec.Type.Float:
228
if (convert_value.GetType () == typeof (char))
229
return (float) convert_value.ToInt32 (nfi);
230
return convert_value.ToSingle (nfi);
231
case BuiltinTypeSpec.Type.String:
232
return convert_value.ToString (nfi);
233
case BuiltinTypeSpec.Type.UShort:
234
return convert_value.ToUInt16 (nfi);
235
case BuiltinTypeSpec.Type.UInt:
236
return convert_value.ToUInt32 (nfi);
237
case BuiltinTypeSpec.Type.ULong:
238
return convert_value.ToUInt64 (nfi);
239
case BuiltinTypeSpec.Type.Object:
249
protected override Expression DoResolve (ResolveContext rc)
255
/// Attempts to do a compile-time folding of a constant cast.
257
public Constant TryReduce (ResolveContext ec, TypeSpec target_type)
260
return TryReduceConstant (ec, target_type);
261
} catch (OverflowException) {
262
if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
263
ec.Report.Error (221, loc,
264
"Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
265
GetValueAsLiteral (), target_type.GetSignatureForError ());
267
Error_ValueCannotBeConverted (ec, target_type, false);
270
return New.Constantify (target_type, loc);
274
Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
276
if (Type == target_type) {
278
// Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10
281
return CreateConstantFromValue (target_type, GetValue (), loc);
287
if (target_type.IsEnum) {
288
c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type));
292
return new EnumConstant (c, target_type);
295
return ConvertExplicitly (ec.ConstantCheckState, target_type);
299
/// Need to pass type as the constant can require a boxing
300
/// and in such case no optimization is possible
302
public bool IsDefaultInitializer (TypeSpec type)
305
return IsDefaultValue;
307
return this is NullLiteral;
310
public abstract bool IsDefaultValue {
314
public abstract bool IsNegative {
319
// When constant is declared as literal
321
public virtual bool IsLiteral {
322
get { return false; }
325
public virtual bool IsOneInteger {
326
get { return false; }
329
public override bool IsSideEffectFree {
336
// Returns true iff 1) the stack type of this is one of Object,
337
// int32, int64 and 2) this == 0 or this == null.
339
public virtual bool IsZeroInteger {
340
get { return false; }
343
public override void EmitSideEffect (EmitContext ec)
348
public sealed override Expression Clone (CloneContext clonectx)
350
// No cloning is not needed for constants
354
protected override void CloneTo (CloneContext clonectx, Expression target)
356
throw new NotSupportedException ("should not be reached");
359
public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
362
return base.MakeExpression (ctx);
364
return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
368
public new bool Resolve (ResolveContext rc)
370
// It exists only as hint not to call Resolve on constants
374
public override object Accept (StructuralVisitor visitor)
376
return visitor.Visit (this);
381
public abstract class IntegralConstant : Constant
383
protected IntegralConstant (TypeSpec type, Location loc)
387
eclass = ExprClass.Value;
390
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
393
ConvertExplicitly (true, target);
394
base.Error_ValueCannotBeConverted (ec, target, expl);
398
ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
399
GetValue ().ToString (), TypeManager.CSharpName (target));
403
public override string GetValueAsLiteral ()
405
return GetValue ().ToString ();
408
public abstract Constant Increment ();
411
public class BoolConstant : Constant {
412
public readonly bool Value;
414
public BoolConstant (BuiltinTypes types, bool val, Location loc)
415
: this (types.Bool, val, loc)
419
public BoolConstant (TypeSpec type, bool val, Location loc)
422
eclass = ExprClass.Value;
428
public override object GetValue ()
430
return (object) Value;
433
public override string GetValueAsLiteral ()
435
return Value ? "true" : "false";
438
public override long GetValueAsLong ()
440
return Value ? 1 : 0;
443
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
448
public override void Emit (EmitContext ec)
456
public override bool IsDefaultValue {
462
public override bool IsNegative {
468
public override bool IsZeroInteger {
469
get { return Value == false; }
472
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
479
public class ByteConstant : IntegralConstant
481
public readonly byte Value;
483
public ByteConstant (BuiltinTypes types, byte v, Location loc)
484
: this (types.Byte, v, loc)
488
public ByteConstant (TypeSpec type, byte v, Location loc)
494
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
499
public override void Emit (EmitContext ec)
504
public override object GetValue ()
509
public override long GetValueAsLong ()
514
public override Constant Increment ()
516
return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
519
public override bool IsDefaultValue {
525
public override bool IsOneInteger {
531
public override bool IsNegative {
537
public override bool IsZeroInteger {
538
get { return Value == 0; }
541
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
543
switch (target_type.BuiltinType) {
544
case BuiltinTypeSpec.Type.SByte:
545
if (in_checked_context){
546
if (Value > SByte.MaxValue)
547
throw new OverflowException ();
549
return new SByteConstant (target_type, (sbyte) Value, Location);
550
case BuiltinTypeSpec.Type.Short:
551
return new ShortConstant (target_type, (short) Value, Location);
552
case BuiltinTypeSpec.Type.UShort:
553
return new UShortConstant (target_type, (ushort) Value, Location);
554
case BuiltinTypeSpec.Type.Int:
555
return new IntConstant (target_type, (int) Value, Location);
556
case BuiltinTypeSpec.Type.UInt:
557
return new UIntConstant (target_type, (uint) Value, Location);
558
case BuiltinTypeSpec.Type.Long:
559
return new LongConstant (target_type, (long) Value, Location);
560
case BuiltinTypeSpec.Type.ULong:
561
return new ULongConstant (target_type, (ulong) Value, Location);
562
case BuiltinTypeSpec.Type.Float:
563
return new FloatConstant (target_type, (float) Value, Location);
564
case BuiltinTypeSpec.Type.Double:
565
return new DoubleConstant (target_type, (double) Value, Location);
566
case BuiltinTypeSpec.Type.Char:
567
return new CharConstant (target_type, (char) Value, Location);
568
case BuiltinTypeSpec.Type.Decimal:
569
return new DecimalConstant (target_type, (decimal) Value, Location);
577
public class CharConstant : Constant {
578
public readonly char Value;
580
public CharConstant (BuiltinTypes types, char v, Location loc)
581
: this (types.Char, v, loc)
585
public CharConstant (TypeSpec type, char v, Location loc)
589
eclass = ExprClass.Value;
594
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
596
enc.Encode ((ushort) Value);
599
public override void Emit (EmitContext ec)
604
static string descape (char c)
630
return c.ToString ();
633
public override object GetValue ()
638
public override long GetValueAsLong ()
643
public override string GetValueAsLiteral ()
645
return "\"" + descape (Value) + "\"";
648
public override bool IsDefaultValue {
654
public override bool IsNegative {
660
public override bool IsZeroInteger {
661
get { return Value == '\0'; }
664
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
666
switch (target_type.BuiltinType) {
667
case BuiltinTypeSpec.Type.Byte:
668
if (in_checked_context) {
669
if (Value < Byte.MinValue || Value > Byte.MaxValue)
670
throw new OverflowException ();
672
return new ByteConstant (target_type, (byte) Value, Location);
673
case BuiltinTypeSpec.Type.SByte:
674
if (in_checked_context) {
675
if (Value > SByte.MaxValue)
676
throw new OverflowException ();
678
return new SByteConstant (target_type, (sbyte) Value, Location);
680
case BuiltinTypeSpec.Type.Short:
681
if (in_checked_context) {
682
if (Value > Int16.MaxValue)
683
throw new OverflowException ();
685
return new ShortConstant (target_type, (short) Value, Location);
686
case BuiltinTypeSpec.Type.Int:
687
return new IntConstant (target_type, (int) Value, Location);
688
case BuiltinTypeSpec.Type.UInt:
689
return new UIntConstant (target_type, (uint) Value, Location);
690
case BuiltinTypeSpec.Type.Long:
691
return new LongConstant (target_type, (long) Value, Location);
692
case BuiltinTypeSpec.Type.ULong:
693
return new ULongConstant (target_type, (ulong) Value, Location);
694
case BuiltinTypeSpec.Type.Float:
695
return new FloatConstant (target_type, (float) Value, Location);
696
case BuiltinTypeSpec.Type.Double:
697
return new DoubleConstant (target_type, (double) Value, Location);
698
case BuiltinTypeSpec.Type.Decimal:
699
return new DecimalConstant (target_type, (decimal) Value, Location);
707
public class SByteConstant : IntegralConstant
709
public readonly sbyte Value;
711
public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
712
: this (types.SByte, v, loc)
716
public SByteConstant (TypeSpec type, sbyte v, Location loc)
722
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
727
public override void Emit (EmitContext ec)
732
public override object GetValue ()
737
public override long GetValueAsLong ()
742
public override Constant Increment ()
744
return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
747
public override bool IsDefaultValue {
753
public override bool IsNegative {
759
public override bool IsOneInteger {
765
public override bool IsZeroInteger {
766
get { return Value == 0; }
769
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
771
switch (target_type.BuiltinType) {
772
case BuiltinTypeSpec.Type.Byte:
773
if (in_checked_context && Value < 0)
774
throw new OverflowException ();
775
return new ByteConstant (target_type, (byte) Value, Location);
776
case BuiltinTypeSpec.Type.Short:
777
return new ShortConstant (target_type, (short) Value, Location);
778
case BuiltinTypeSpec.Type.UShort:
779
if (in_checked_context && Value < 0)
780
throw new OverflowException ();
781
return new UShortConstant (target_type, (ushort) Value, Location);
782
case BuiltinTypeSpec.Type.Int:
783
return new IntConstant (target_type, (int) Value, Location);
784
case BuiltinTypeSpec.Type.UInt:
785
if (in_checked_context && Value < 0)
786
throw new OverflowException ();
787
return new UIntConstant (target_type, (uint) Value, Location);
788
case BuiltinTypeSpec.Type.Long:
789
return new LongConstant (target_type, (long) Value, Location);
790
case BuiltinTypeSpec.Type.ULong:
791
if (in_checked_context && Value < 0)
792
throw new OverflowException ();
793
return new ULongConstant (target_type, (ulong) Value, Location);
794
case BuiltinTypeSpec.Type.Float:
795
return new FloatConstant (target_type, (float) Value, Location);
796
case BuiltinTypeSpec.Type.Double:
797
return new DoubleConstant (target_type, (double) Value, Location);
798
case BuiltinTypeSpec.Type.Char:
799
if (in_checked_context && Value < 0)
800
throw new OverflowException ();
801
return new CharConstant (target_type, (char) Value, Location);
802
case BuiltinTypeSpec.Type.Decimal:
803
return new DecimalConstant (target_type, (decimal) Value, Location);
811
public class ShortConstant : IntegralConstant {
812
public readonly short Value;
814
public ShortConstant (BuiltinTypes types, short v, Location loc)
815
: this (types.Short, v, loc)
819
public ShortConstant (TypeSpec type, short v, Location loc)
825
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
830
public override void Emit (EmitContext ec)
835
public override object GetValue ()
840
public override long GetValueAsLong ()
845
public override Constant Increment ()
847
return new ShortConstant (type, checked((short)(Value + 1)), loc);
850
public override bool IsDefaultValue {
856
public override bool IsZeroInteger {
857
get { return Value == 0; }
860
public override bool IsNegative {
866
public override bool IsOneInteger {
872
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
874
switch (target_type.BuiltinType) {
875
case BuiltinTypeSpec.Type.Byte:
876
if (in_checked_context) {
877
if (Value < Byte.MinValue || Value > Byte.MaxValue)
878
throw new OverflowException ();
880
return new ByteConstant (target_type, (byte) Value, Location);
881
case BuiltinTypeSpec.Type.SByte:
882
if (in_checked_context) {
883
if (Value < SByte.MinValue || Value > SByte.MaxValue)
884
throw new OverflowException ();
886
return new SByteConstant (target_type, (sbyte) Value, Location);
887
case BuiltinTypeSpec.Type.UShort:
888
if (in_checked_context && Value < 0)
889
throw new OverflowException ();
891
return new UShortConstant (target_type, (ushort) Value, Location);
892
case BuiltinTypeSpec.Type.Int:
893
return new IntConstant (target_type, (int) Value, Location);
894
case BuiltinTypeSpec.Type.UInt:
895
if (in_checked_context && Value < 0)
896
throw new OverflowException ();
897
return new UIntConstant (target_type, (uint) Value, Location);
898
case BuiltinTypeSpec.Type.Long:
899
return new LongConstant (target_type, (long) Value, Location);
900
case BuiltinTypeSpec.Type.ULong:
901
if (in_checked_context && Value < 0)
902
throw new OverflowException ();
903
return new ULongConstant (target_type, (ulong) Value, Location);
904
case BuiltinTypeSpec.Type.Float:
905
return new FloatConstant (target_type, (float) Value, Location);
906
case BuiltinTypeSpec.Type.Double:
907
return new DoubleConstant (target_type, (double) Value, Location);
908
case BuiltinTypeSpec.Type.Char:
909
if (in_checked_context) {
910
if (Value < Char.MinValue)
911
throw new OverflowException ();
913
return new CharConstant (target_type, (char) Value, Location);
914
case BuiltinTypeSpec.Type.Decimal:
915
return new DecimalConstant (target_type, (decimal) Value, Location);
923
public class UShortConstant : IntegralConstant
925
public readonly ushort Value;
927
public UShortConstant (BuiltinTypes types, ushort v, Location loc)
928
: this (types.UShort, v, loc)
932
public UShortConstant (TypeSpec type, ushort v, Location loc)
938
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
943
public override void Emit (EmitContext ec)
948
public override object GetValue ()
953
public override long GetValueAsLong ()
958
public override Constant Increment ()
960
return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
963
public override bool IsDefaultValue {
969
public override bool IsNegative {
975
public override bool IsOneInteger {
981
public override bool IsZeroInteger {
982
get { return Value == 0; }
985
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
987
switch (target_type.BuiltinType) {
988
case BuiltinTypeSpec.Type.Byte:
989
if (in_checked_context) {
990
if (Value > Byte.MaxValue)
991
throw new OverflowException ();
993
return new ByteConstant (target_type, (byte) Value, Location);
994
case BuiltinTypeSpec.Type.SByte:
995
if (in_checked_context) {
996
if (Value > SByte.MaxValue)
997
throw new OverflowException ();
999
return new SByteConstant (target_type, (sbyte) Value, Location);
1000
case BuiltinTypeSpec.Type.Short:
1001
if (in_checked_context) {
1002
if (Value > Int16.MaxValue)
1003
throw new OverflowException ();
1005
return new ShortConstant (target_type, (short) Value, Location);
1006
case BuiltinTypeSpec.Type.Int:
1007
return new IntConstant (target_type, (int) Value, Location);
1008
case BuiltinTypeSpec.Type.UInt:
1009
return new UIntConstant (target_type, (uint) Value, Location);
1010
case BuiltinTypeSpec.Type.Long:
1011
return new LongConstant (target_type, (long) Value, Location);
1012
case BuiltinTypeSpec.Type.ULong:
1013
return new ULongConstant (target_type, (ulong) Value, Location);
1014
case BuiltinTypeSpec.Type.Float:
1015
return new FloatConstant (target_type, (float) Value, Location);
1016
case BuiltinTypeSpec.Type.Double:
1017
return new DoubleConstant (target_type, (double) Value, Location);
1018
case BuiltinTypeSpec.Type.Char:
1019
if (in_checked_context) {
1020
if (Value > Char.MaxValue)
1021
throw new OverflowException ();
1023
return new CharConstant (target_type, (char) Value, Location);
1024
case BuiltinTypeSpec.Type.Decimal:
1025
return new DecimalConstant (target_type, (decimal) Value, Location);
1032
public class IntConstant : IntegralConstant
1034
public readonly int Value;
1036
public IntConstant (BuiltinTypes types, int v, Location loc)
1037
: this (types.Int, v, loc)
1041
public IntConstant (TypeSpec type, int v, Location loc)
1047
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1052
public override void Emit (EmitContext ec)
1057
public override object GetValue ()
1062
public override long GetValueAsLong ()
1067
public override Constant Increment ()
1069
return new IntConstant (type, checked(Value + 1), loc);
1072
public override bool IsDefaultValue {
1078
public override bool IsNegative {
1084
public override bool IsOneInteger {
1090
public override bool IsZeroInteger {
1091
get { return Value == 0; }
1094
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1096
switch (target_type.BuiltinType) {
1097
case BuiltinTypeSpec.Type.Byte:
1098
if (in_checked_context) {
1099
if (Value < Byte.MinValue || Value > Byte.MaxValue)
1100
throw new OverflowException ();
1102
return new ByteConstant (target_type, (byte) Value, Location);
1103
case BuiltinTypeSpec.Type.SByte:
1104
if (in_checked_context) {
1105
if (Value < SByte.MinValue || Value > SByte.MaxValue)
1106
throw new OverflowException ();
1108
return new SByteConstant (target_type, (sbyte) Value, Location);
1109
case BuiltinTypeSpec.Type.Short:
1110
if (in_checked_context) {
1111
if (Value < Int16.MinValue || Value > Int16.MaxValue)
1112
throw new OverflowException ();
1114
return new ShortConstant (target_type, (short) Value, Location);
1115
case BuiltinTypeSpec.Type.UShort:
1116
if (in_checked_context) {
1117
if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1118
throw new OverflowException ();
1120
return new UShortConstant (target_type, (ushort) Value, Location);
1121
case BuiltinTypeSpec.Type.UInt:
1122
if (in_checked_context) {
1123
if (Value < UInt32.MinValue)
1124
throw new OverflowException ();
1126
return new UIntConstant (target_type, (uint) Value, Location);
1127
case BuiltinTypeSpec.Type.Long:
1128
return new LongConstant (target_type, (long) Value, Location);
1129
case BuiltinTypeSpec.Type.ULong:
1130
if (in_checked_context && Value < 0)
1131
throw new OverflowException ();
1132
return new ULongConstant (target_type, (ulong) Value, Location);
1133
case BuiltinTypeSpec.Type.Float:
1134
return new FloatConstant (target_type, (float) Value, Location);
1135
case BuiltinTypeSpec.Type.Double:
1136
return new DoubleConstant (target_type, (double) Value, Location);
1137
case BuiltinTypeSpec.Type.Char:
1138
if (in_checked_context) {
1139
if (Value < Char.MinValue || Value > Char.MaxValue)
1140
throw new OverflowException ();
1142
return new CharConstant (target_type, (char) Value, Location);
1143
case BuiltinTypeSpec.Type.Decimal:
1144
return new DecimalConstant (target_type, (decimal) Value, Location);
1150
public override Constant ConvertImplicitly (TypeSpec type)
1152
if (this.type == type)
1155
Constant c = TryImplicitIntConversion (type);
1157
return c; //.Resolve (rc);
1159
return base.ConvertImplicitly (type);
1163
/// Attempts to perform an implicit constant conversion of the IntConstant
1164
/// into a different data type using casts (See Implicit Constant
1165
/// Expression Conversions)
1167
Constant TryImplicitIntConversion (TypeSpec target_type)
1169
switch (target_type.BuiltinType) {
1170
case BuiltinTypeSpec.Type.SByte:
1171
if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1172
return new SByteConstant (target_type, (sbyte) Value, loc);
1174
case BuiltinTypeSpec.Type.Byte:
1175
if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1176
return new ByteConstant (target_type, (byte) Value, loc);
1178
case BuiltinTypeSpec.Type.Short:
1179
if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1180
return new ShortConstant (target_type, (short) Value, loc);
1182
case BuiltinTypeSpec.Type.UShort:
1183
if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1184
return new UShortConstant (target_type, (ushort) Value, loc);
1186
case BuiltinTypeSpec.Type.UInt:
1188
return new UIntConstant (target_type, (uint) Value, loc);
1190
case BuiltinTypeSpec.Type.ULong:
1192
// we can optimize this case: a positive int32
1193
// always fits on a uint64. But we need an opcode
1197
return new ULongConstant (target_type, (ulong) Value, loc);
1199
case BuiltinTypeSpec.Type.Double:
1200
return new DoubleConstant (target_type, (double) Value, loc);
1201
case BuiltinTypeSpec.Type.Float:
1202
return new FloatConstant (target_type, (float) Value, loc);
1209
public class UIntConstant : IntegralConstant {
1210
public readonly uint Value;
1212
public UIntConstant (BuiltinTypes types, uint v, Location loc)
1213
: this (types.UInt, v, loc)
1217
public UIntConstant (TypeSpec type, uint v, Location loc)
1223
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1228
public override void Emit (EmitContext ec)
1230
ec.EmitInt (unchecked ((int) Value));
1233
public override object GetValue ()
1238
public override long GetValueAsLong ()
1243
public override Constant Increment ()
1245
return new UIntConstant (type, checked(Value + 1), loc);
1248
public override bool IsDefaultValue {
1254
public override bool IsNegative {
1260
public override bool IsOneInteger {
1266
public override bool IsZeroInteger {
1267
get { return Value == 0; }
1270
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1272
switch (target_type.BuiltinType) {
1273
case BuiltinTypeSpec.Type.Byte:
1274
if (in_checked_context) {
1275
if (Value < 0 || Value > byte.MaxValue)
1276
throw new OverflowException ();
1278
return new ByteConstant (target_type, (byte) Value, Location);
1279
case BuiltinTypeSpec.Type.SByte:
1280
if (in_checked_context) {
1281
if (Value > SByte.MaxValue)
1282
throw new OverflowException ();
1284
return new SByteConstant (target_type, (sbyte) Value, Location);
1285
case BuiltinTypeSpec.Type.Short:
1286
if (in_checked_context) {
1287
if (Value > Int16.MaxValue)
1288
throw new OverflowException ();
1290
return new ShortConstant (target_type, (short) Value, Location);
1291
case BuiltinTypeSpec.Type.UShort:
1292
if (in_checked_context) {
1293
if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1294
throw new OverflowException ();
1296
return new UShortConstant (target_type, (ushort) Value, Location);
1297
case BuiltinTypeSpec.Type.Int:
1298
if (in_checked_context) {
1299
if (Value > Int32.MaxValue)
1300
throw new OverflowException ();
1302
return new IntConstant (target_type, (int) Value, Location);
1303
case BuiltinTypeSpec.Type.Long:
1304
return new LongConstant (target_type, (long) Value, Location);
1305
case BuiltinTypeSpec.Type.ULong:
1306
return new ULongConstant (target_type, (ulong) Value, Location);
1307
case BuiltinTypeSpec.Type.Float:
1308
return new FloatConstant (target_type, (float) Value, Location);
1309
case BuiltinTypeSpec.Type.Double:
1310
return new DoubleConstant (target_type, (double) Value, Location);
1311
case BuiltinTypeSpec.Type.Char:
1312
if (in_checked_context) {
1313
if (Value < Char.MinValue || Value > Char.MaxValue)
1314
throw new OverflowException ();
1316
return new CharConstant (target_type, (char) Value, Location);
1317
case BuiltinTypeSpec.Type.Decimal:
1318
return new DecimalConstant (target_type, (decimal) Value, Location);
1326
public class LongConstant : IntegralConstant {
1327
public readonly long Value;
1329
public LongConstant (BuiltinTypes types, long v, Location loc)
1330
: this (types.Long, v, loc)
1334
public LongConstant (TypeSpec type, long v, Location loc)
1340
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1345
public override void Emit (EmitContext ec)
1347
ec.EmitLong (Value);
1350
public override object GetValue ()
1355
public override long GetValueAsLong ()
1360
public override Constant Increment ()
1362
return new LongConstant (type, checked(Value + 1), loc);
1365
public override bool IsDefaultValue {
1371
public override bool IsNegative {
1377
public override bool IsOneInteger {
1383
public override bool IsZeroInteger {
1384
get { return Value == 0; }
1387
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1389
switch (target_type.BuiltinType) {
1390
case BuiltinTypeSpec.Type.Byte:
1391
if (in_checked_context) {
1392
if (Value < Byte.MinValue || Value > Byte.MaxValue)
1393
throw new OverflowException ();
1395
return new ByteConstant (target_type, (byte) Value, Location);
1396
case BuiltinTypeSpec.Type.SByte:
1397
if (in_checked_context) {
1398
if (Value < SByte.MinValue || Value > SByte.MaxValue)
1399
throw new OverflowException ();
1401
return new SByteConstant (target_type, (sbyte) Value, Location);
1402
case BuiltinTypeSpec.Type.Short:
1403
if (in_checked_context) {
1404
if (Value < Int16.MinValue || Value > Int16.MaxValue)
1405
throw new OverflowException ();
1407
return new ShortConstant (target_type, (short) Value, Location);
1408
case BuiltinTypeSpec.Type.UShort:
1409
if (in_checked_context) {
1410
if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1411
throw new OverflowException ();
1413
return new UShortConstant (target_type, (ushort) Value, Location);
1414
case BuiltinTypeSpec.Type.Int:
1415
if (in_checked_context) {
1416
if (Value < Int32.MinValue || Value > Int32.MaxValue)
1417
throw new OverflowException ();
1419
return new IntConstant (target_type, (int) Value, Location);
1420
case BuiltinTypeSpec.Type.UInt:
1421
if (in_checked_context) {
1422
if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1423
throw new OverflowException ();
1425
return new UIntConstant (target_type, (uint) Value, Location);
1426
case BuiltinTypeSpec.Type.ULong:
1427
if (in_checked_context && Value < 0)
1428
throw new OverflowException ();
1429
return new ULongConstant (target_type, (ulong) Value, Location);
1430
case BuiltinTypeSpec.Type.Float:
1431
return new FloatConstant (target_type, (float) Value, Location);
1432
case BuiltinTypeSpec.Type.Double:
1433
return new DoubleConstant (target_type, (double) Value, Location);
1434
case BuiltinTypeSpec.Type.Char:
1435
if (in_checked_context) {
1436
if (Value < Char.MinValue || Value > Char.MaxValue)
1437
throw new OverflowException ();
1439
return new CharConstant (target_type, (char) Value, Location);
1440
case BuiltinTypeSpec.Type.Decimal:
1441
return new DecimalConstant (target_type, (decimal) Value, Location);
1447
public override Constant ConvertImplicitly (TypeSpec type)
1449
if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
1450
return new ULongConstant (type, (ulong) Value, loc);
1453
return base.ConvertImplicitly (type);
1457
public class ULongConstant : IntegralConstant {
1458
public readonly ulong Value;
1460
public ULongConstant (BuiltinTypes types, ulong v, Location loc)
1461
: this (types.ULong, v, loc)
1465
public ULongConstant (TypeSpec type, ulong v, Location loc)
1471
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1476
public override void Emit (EmitContext ec)
1478
ec.EmitLong (unchecked ((long) Value));
1481
public override object GetValue ()
1486
public override long GetValueAsLong ()
1488
return (long) Value;
1491
public override Constant Increment ()
1493
return new ULongConstant (type, checked(Value + 1), loc);
1496
public override bool IsDefaultValue {
1502
public override bool IsNegative {
1508
public override bool IsOneInteger {
1514
public override bool IsZeroInteger {
1515
get { return Value == 0; }
1518
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1520
switch (target_type.BuiltinType) {
1521
case BuiltinTypeSpec.Type.Byte:
1522
if (in_checked_context && Value > Byte.MaxValue)
1523
throw new OverflowException ();
1524
return new ByteConstant (target_type, (byte) Value, Location);
1525
case BuiltinTypeSpec.Type.SByte:
1526
if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1527
throw new OverflowException ();
1528
return new SByteConstant (target_type, (sbyte) Value, Location);
1529
case BuiltinTypeSpec.Type.Short:
1530
if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1531
throw new OverflowException ();
1532
return new ShortConstant (target_type, (short) Value, Location);
1533
case BuiltinTypeSpec.Type.UShort:
1534
if (in_checked_context && Value > UInt16.MaxValue)
1535
throw new OverflowException ();
1536
return new UShortConstant (target_type, (ushort) Value, Location);
1537
case BuiltinTypeSpec.Type.Int:
1538
if (in_checked_context && Value > UInt32.MaxValue)
1539
throw new OverflowException ();
1540
return new IntConstant (target_type, (int) Value, Location);
1541
case BuiltinTypeSpec.Type.UInt:
1542
if (in_checked_context && Value > UInt32.MaxValue)
1543
throw new OverflowException ();
1544
return new UIntConstant (target_type, (uint) Value, Location);
1545
case BuiltinTypeSpec.Type.Long:
1546
if (in_checked_context && Value > Int64.MaxValue)
1547
throw new OverflowException ();
1548
return new LongConstant (target_type, (long) Value, Location);
1549
case BuiltinTypeSpec.Type.Float:
1550
return new FloatConstant (target_type, (float) Value, Location);
1551
case BuiltinTypeSpec.Type.Double:
1552
return new DoubleConstant (target_type, (double) Value, Location);
1553
case BuiltinTypeSpec.Type.Char:
1554
if (in_checked_context && Value > Char.MaxValue)
1555
throw new OverflowException ();
1556
return new CharConstant (target_type, (char) Value, Location);
1557
case BuiltinTypeSpec.Type.Decimal:
1558
return new DecimalConstant (target_type, (decimal) Value, Location);
1566
public class FloatConstant : Constant {
1567
public readonly float Value;
1569
public FloatConstant (BuiltinTypes types, float v, Location loc)
1570
: this (types.Float, v, loc)
1574
public FloatConstant (TypeSpec type, float v, Location loc)
1578
eclass = ExprClass.Value;
1583
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1588
public override void Emit (EmitContext ec)
1590
ec.Emit (OpCodes.Ldc_R4, Value);
1593
public override object GetValue ()
1598
public override string GetValueAsLiteral ()
1600
return Value.ToString ();
1603
public override long GetValueAsLong ()
1605
throw new NotSupportedException ();
1608
public override bool IsDefaultValue {
1614
public override bool IsNegative {
1620
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1622
switch (target_type.BuiltinType) {
1623
case BuiltinTypeSpec.Type.Byte:
1624
if (in_checked_context) {
1625
if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1626
throw new OverflowException ();
1628
return new ByteConstant (target_type, (byte) Value, Location);
1629
case BuiltinTypeSpec.Type.SByte:
1630
if (in_checked_context) {
1631
if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1632
throw new OverflowException ();
1634
return new SByteConstant (target_type, (sbyte) Value, Location);
1635
case BuiltinTypeSpec.Type.Short:
1636
if (in_checked_context) {
1637
if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1638
throw new OverflowException ();
1640
return new ShortConstant (target_type, (short) Value, Location);
1641
case BuiltinTypeSpec.Type.UShort:
1642
if (in_checked_context) {
1643
if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1644
throw new OverflowException ();
1646
return new UShortConstant (target_type, (ushort) Value, Location);
1647
case BuiltinTypeSpec.Type.Int:
1648
if (in_checked_context) {
1649
if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1650
throw new OverflowException ();
1652
return new IntConstant (target_type, (int) Value, Location);
1653
case BuiltinTypeSpec.Type.UInt:
1654
if (in_checked_context) {
1655
if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1656
throw new OverflowException ();
1658
return new UIntConstant (target_type, (uint) Value, Location);
1659
case BuiltinTypeSpec.Type.Long:
1660
if (in_checked_context) {
1661
if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1662
throw new OverflowException ();
1664
return new LongConstant (target_type, (long) Value, Location);
1665
case BuiltinTypeSpec.Type.ULong:
1666
if (in_checked_context) {
1667
if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1668
throw new OverflowException ();
1670
return new ULongConstant (target_type, (ulong) Value, Location);
1671
case BuiltinTypeSpec.Type.Double:
1672
return new DoubleConstant (target_type, (double) Value, Location);
1673
case BuiltinTypeSpec.Type.Char:
1674
if (in_checked_context) {
1675
if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1676
throw new OverflowException ();
1678
return new CharConstant (target_type, (char) Value, Location);
1679
case BuiltinTypeSpec.Type.Decimal:
1680
return new DecimalConstant (target_type, (decimal) Value, Location);
1688
public class DoubleConstant : Constant
1690
public readonly double Value;
1692
public DoubleConstant (BuiltinTypes types, double v, Location loc)
1693
: this (types.Double, v, loc)
1697
public DoubleConstant (TypeSpec type, double v, Location loc)
1701
eclass = ExprClass.Value;
1706
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1711
public override void Emit (EmitContext ec)
1713
ec.Emit (OpCodes.Ldc_R8, Value);
1716
public override object GetValue ()
1721
public override string GetValueAsLiteral ()
1723
return Value.ToString ();
1726
public override long GetValueAsLong ()
1728
throw new NotSupportedException ();
1731
public override bool IsDefaultValue {
1737
public override bool IsNegative {
1743
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1745
switch (target_type.BuiltinType) {
1746
case BuiltinTypeSpec.Type.Byte:
1747
if (in_checked_context) {
1748
if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1749
throw new OverflowException ();
1751
return new ByteConstant (target_type, (byte) Value, Location);
1752
case BuiltinTypeSpec.Type.SByte:
1753
if (in_checked_context) {
1754
if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1755
throw new OverflowException ();
1757
return new SByteConstant (target_type, (sbyte) Value, Location);
1758
case BuiltinTypeSpec.Type.Short:
1759
if (in_checked_context) {
1760
if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1761
throw new OverflowException ();
1763
return new ShortConstant (target_type, (short) Value, Location);
1764
case BuiltinTypeSpec.Type.UShort:
1765
if (in_checked_context) {
1766
if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1767
throw new OverflowException ();
1769
return new UShortConstant (target_type, (ushort) Value, Location);
1770
case BuiltinTypeSpec.Type.Int:
1771
if (in_checked_context) {
1772
if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1773
throw new OverflowException ();
1775
return new IntConstant (target_type, (int) Value, Location);
1776
case BuiltinTypeSpec.Type.UInt:
1777
if (in_checked_context) {
1778
if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1779
throw new OverflowException ();
1781
return new UIntConstant (target_type, (uint) Value, Location);
1782
case BuiltinTypeSpec.Type.Long:
1783
if (in_checked_context) {
1784
if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1785
throw new OverflowException ();
1787
return new LongConstant (target_type, (long) Value, Location);
1788
case BuiltinTypeSpec.Type.ULong:
1789
if (in_checked_context) {
1790
if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1791
throw new OverflowException ();
1793
return new ULongConstant (target_type, (ulong) Value, Location);
1794
case BuiltinTypeSpec.Type.Float:
1795
return new FloatConstant (target_type, (float) Value, Location);
1796
case BuiltinTypeSpec.Type.Char:
1797
if (in_checked_context) {
1798
if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1799
throw new OverflowException ();
1801
return new CharConstant (target_type, (char) Value, Location);
1802
case BuiltinTypeSpec.Type.Decimal:
1803
return new DecimalConstant (target_type, (decimal) Value, Location);
1811
public class DecimalConstant : Constant {
1812
public readonly decimal Value;
1814
public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1815
: this (types.Decimal, d, loc)
1819
public DecimalConstant (TypeSpec type, decimal d, Location loc)
1823
eclass = ExprClass.Value;
1828
public override void Emit (EmitContext ec)
1832
int [] words = decimal.GetBits (Value);
1833
int power = (words [3] >> 16) & 0xff;
1836
if (Value <= int.MaxValue && Value >= int.MinValue) {
1837
m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1842
ec.EmitInt ((int) Value);
1843
ec.Emit (OpCodes.Newobj, m);
1847
if (Value <= long.MaxValue && Value >= long.MinValue) {
1848
m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1853
ec.EmitLong ((long) Value);
1854
ec.Emit (OpCodes.Newobj, m);
1859
ec.EmitInt (words [0]);
1860
ec.EmitInt (words [1]);
1861
ec.EmitInt (words [2]);
1864
ec.EmitInt (words [3] >> 31);
1869
m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1871
ec.Emit (OpCodes.Newobj, m);
1875
public override bool IsDefaultValue {
1881
public override bool IsNegative {
1887
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1889
switch (target_type.BuiltinType) {
1890
case BuiltinTypeSpec.Type.SByte:
1891
return new SByteConstant (target_type, (sbyte) Value, loc);
1892
case BuiltinTypeSpec.Type.Byte:
1893
return new ByteConstant (target_type, (byte) Value, loc);
1894
case BuiltinTypeSpec.Type.Short:
1895
return new ShortConstant (target_type, (short) Value, loc);
1896
case BuiltinTypeSpec.Type.UShort:
1897
return new UShortConstant (target_type, (ushort) Value, loc);
1898
case BuiltinTypeSpec.Type.Int:
1899
return new IntConstant (target_type, (int) Value, loc);
1900
case BuiltinTypeSpec.Type.UInt:
1901
return new UIntConstant (target_type, (uint) Value, loc);
1902
case BuiltinTypeSpec.Type.Long:
1903
return new LongConstant (target_type, (long) Value, loc);
1904
case BuiltinTypeSpec.Type.ULong:
1905
return new ULongConstant (target_type, (ulong) Value, loc);
1906
case BuiltinTypeSpec.Type.Char:
1907
return new CharConstant (target_type, (char) Value, loc);
1908
case BuiltinTypeSpec.Type.Float:
1909
return new FloatConstant (target_type, (float) Value, loc);
1910
case BuiltinTypeSpec.Type.Double:
1911
return new DoubleConstant (target_type, (double) Value, loc);
1917
public override object GetValue ()
1922
public override string GetValueAsLiteral ()
1924
return Value.ToString () + "M";
1927
public override long GetValueAsLong ()
1929
throw new NotSupportedException ();
1933
public class StringConstant : Constant {
1934
public readonly string Value;
1936
public StringConstant (BuiltinTypes types, string s, Location loc)
1937
: this (types.String, s, loc)
1941
public StringConstant (TypeSpec type, string s, Location loc)
1945
eclass = ExprClass.Value;
1950
public override object GetValue ()
1955
public override string GetValueAsLiteral ()
1957
// FIXME: Escape the string.
1958
return "\"" + Value + "\"";
1961
public override long GetValueAsLong ()
1963
throw new NotSupportedException ();
1966
public override void Emit (EmitContext ec)
1968
if (Value == null) {
1974
// Use string.Empty for both literals and constants even if
1975
// it's not allowed at language level
1977
if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
1978
var string_type = ec.BuiltinTypes.String;
1979
if (ec.CurrentType != string_type) {
1980
var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
1982
ec.Emit (OpCodes.Ldsfld, m);
1988
ec.Emit (OpCodes.Ldstr, Value);
1991
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1994
if (type != targetType)
2000
public override bool IsDefaultValue {
2002
return Value == null;
2006
public override bool IsNegative {
2012
public override bool IsNull {
2014
return IsDefaultValue;
2018
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2025
// Null constant can have its own type, think of `default (Foo)'
2027
public class NullConstant : Constant
2029
public NullConstant (TypeSpec type, Location loc)
2032
eclass = ExprClass.Value;
2036
public override Expression CreateExpressionTree (ResolveContext ec)
2038
if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2039
// Optimized version, also avoids referencing literal internal type
2040
Arguments args = new Arguments (1);
2041
args.Add (new Argument (this));
2042
return CreateExpressionFactoryCall (ec, "Constant", args);
2045
return base.CreateExpressionTree (ec);
2048
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2050
switch (targetType.BuiltinType) {
2051
case BuiltinTypeSpec.Type.Object:
2052
// Type it as string cast
2053
enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2054
goto case BuiltinTypeSpec.Type.String;
2055
case BuiltinTypeSpec.Type.String:
2056
case BuiltinTypeSpec.Type.Type:
2057
enc.Encode (byte.MaxValue);
2060
var ac = targetType as ArrayContainer;
2061
if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
2062
enc.Encode (uint.MaxValue);
2069
base.EncodeAttributeValue (rc, enc, targetType);
2072
public override void Emit (EmitContext ec)
2076
// Only to make verifier happy
2077
if (type.IsGenericParameter)
2078
ec.Emit (OpCodes.Unbox_Any, type);
2081
public override string ExprClassName {
2083
return GetSignatureForError ();
2087
public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2089
if (targetType.IsPointer) {
2090
if (IsLiteral || this is NullPointer)
2091
return new NullPointer (targetType, loc);
2096
// Exlude internal compiler types
2097
if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2100
if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2103
if (TypeSpec.IsReferenceType (targetType))
2104
return new NullConstant (targetType, loc);
2106
if (targetType.IsNullableType)
2107
return Nullable.LiftedNull.Create (targetType, loc);
2112
public override Constant ConvertImplicitly (TypeSpec targetType)
2114
return ConvertExplicitly (false, targetType);
2117
public override string GetSignatureForError ()
2122
public override object GetValue ()
2127
public override string GetValueAsLiteral ()
2129
return GetSignatureForError ();
2132
public override long GetValueAsLong ()
2134
throw new NotSupportedException ();
2137
public override bool IsDefaultValue {
2138
get { return true; }
2141
public override bool IsNegative {
2142
get { return false; }
2145
public override bool IsNull {
2146
get { return true; }
2149
public override bool IsZeroInteger {
2150
get { return true; }
2156
// A null constant in a pointer context
2158
class NullPointer : NullConstant
2160
public NullPointer (TypeSpec type, Location loc)
2165
public override Expression CreateExpressionTree (ResolveContext ec)
2167
Error_PointerInsideExpressionTree (ec);
2168
return base.CreateExpressionTree (ec);
2171
public override void Emit (EmitContext ec)
2174
// Emits null pointer
2177
ec.Emit (OpCodes.Conv_U);
2182
/// The value is constant, but when emitted has a side effect. This is
2183
/// used by BitwiseAnd to ensure that the second expression is invoked
2184
/// regardless of the value of the left side.
2186
public class SideEffectConstant : Constant
2188
public readonly Constant value;
2189
Expression side_effect;
2191
public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2196
eclass = ExprClass.Value;
2198
while (side_effect is SideEffectConstant)
2199
side_effect = ((SideEffectConstant) side_effect).side_effect;
2200
this.side_effect = side_effect;
2203
public override bool IsSideEffectFree {
2209
public override object GetValue ()
2211
return value.GetValue ();
2214
public override string GetValueAsLiteral ()
2216
return value.GetValueAsLiteral ();
2219
public override long GetValueAsLong ()
2221
return value.GetValueAsLong ();
2224
public override void Emit (EmitContext ec)
2226
side_effect.EmitSideEffect (ec);
2230
public override void EmitSideEffect (EmitContext ec)
2232
side_effect.EmitSideEffect (ec);
2233
value.EmitSideEffect (ec);
2236
public override bool IsDefaultValue {
2237
get { return value.IsDefaultValue; }
2240
public override bool IsNegative {
2241
get { return value.IsNegative; }
2244
public override bool IsZeroInteger {
2245
get { return value.IsZeroInteger; }
2248
public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2250
Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2251
if (new_value == null)
2254
var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2255
c.type = target_type;