Wiring of BuildinType
[mono.git] / mcs / mcs / constant.cs
1 //
2 // constant.cs: Constants.
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Marek Safar (marek.safar@seznam.cz)
7 //
8 // Copyright 2001-2003 Ximian, Inc.
9 // Copyright 2003-2008 Novell, Inc.
10 //
11
12 using System;
13 using System.Globalization;
14
15 #if STATIC
16 using IKVM.Reflection.Emit;
17 #else
18 using System.Reflection.Emit;
19 #endif
20
21 namespace Mono.CSharp {
22
23         /// <summary>
24         ///   Base class for constants and literals.
25         /// </summary>
26         public abstract class Constant : Expression
27         {
28                 static readonly NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat;
29
30                 protected Constant (Location loc)
31                 {
32                         this.loc = loc;
33                 }
34
35                 override public string ToString ()
36                 {
37                         return this.GetType ().Name + " (" + GetValueAsLiteral () + ")";
38                 }
39
40                 /// <summary>
41                 ///  This is used to obtain the actual value of the literal
42                 ///  cast into an object.
43                 /// </summary>
44                 public abstract object GetValue ();
45
46                 public abstract long GetValueAsLong ();
47
48                 public abstract string GetValueAsLiteral ();
49
50 #if !STATIC
51                 //
52                 // Returns an object value which is typed to contant type
53                 //
54                 public virtual object GetTypedValue ()
55                 {
56                         return GetValue ();
57                 }
58 #endif
59
60                 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
61                 {
62                         if (!expl && IsLiteral && 
63                                 BuildinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
64                                 BuildinTypeSpec.IsPrimitiveTypeOrDecimal (type)) {
65                                 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
66                                         GetValueAsLiteral (), TypeManager.CSharpName (target));
67                         } else {
68                                 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
69                         }
70                 }
71
72                 public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc)
73                 {
74                         Constant c = ConvertImplicitly (ec, type);
75                         if (c == null)
76                                 Error_ValueCannotBeConverted (ec, loc, type, false);
77
78                         return c;
79                 }
80
81                 public virtual Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
82                 {
83                         if (this.type == type)
84                                 return this;
85
86                         if (Convert.ImplicitNumericConversion (this, type) == null) 
87                                 return null;
88
89                         bool fail;                      
90                         object constant_value = ChangeType (GetValue (), type, out fail);
91                         if (fail){
92                                 //
93                                 // We should always catch the error before this is ever
94                                 // reached, by calling Convert.ImplicitStandardConversionExists
95                                 //
96                                 throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
97                                   TypeManager.CSharpName (Type), TypeManager.CSharpName (type));
98                         }
99
100                         return CreateConstant (rc, type, constant_value, loc);
101                 }
102
103                 //
104                 //  Returns a constant instance based on Type
105                 //
106                 public static Constant CreateConstant (ResolveContext rc, TypeSpec t, object v, Location loc)
107                 {
108                         return CreateConstantFromValue (t, v, loc).Resolve (rc);
109                 }
110
111                 public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
112                 {
113                         if (t.BuildinType > 0) {
114                                 switch (t.BuildinType) {
115                                 case BuildinTypeSpec.Type.Int:
116                                         return new IntConstant ((int) v, loc);
117                                 case BuildinTypeSpec.Type.String:
118                                         return new StringConstant ((string) v, loc);
119                                 case BuildinTypeSpec.Type.UInt:
120                                         return new UIntConstant ((uint) v, loc);
121                                 case BuildinTypeSpec.Type.Long:
122                                         return new LongConstant ((long) v, loc);
123                                 case BuildinTypeSpec.Type.ULong:
124                                         return new ULongConstant ((ulong) v, loc);
125                                 case BuildinTypeSpec.Type.Float:
126                                         return new FloatConstant ((float) v, loc);
127                                 case BuildinTypeSpec.Type.Double:
128                                         return new DoubleConstant ((double) v, loc);
129                                 case BuildinTypeSpec.Type.Short:
130                                         return new ShortConstant ((short) v, loc);
131                                 case BuildinTypeSpec.Type.UShort:
132                                         return new UShortConstant ((ushort) v, loc);
133                                 case BuildinTypeSpec.Type.SByte:
134                                         return new SByteConstant ((sbyte) v, loc);
135                                 case BuildinTypeSpec.Type.Byte:
136                                         return new ByteConstant ((byte) v, loc);
137                                 case BuildinTypeSpec.Type.Char:
138                                         return new CharConstant ((char) v, loc);
139                                 case BuildinTypeSpec.Type.Bool:
140                                         return new BoolConstant ((bool) v, loc);
141                                 case BuildinTypeSpec.Type.Decimal:
142                                         return new DecimalConstant ((decimal) v, loc);
143                                 }
144                         }
145
146                         if (t.IsEnum) {
147                                 var real_type = EnumSpec.GetUnderlyingType (t);
148                                 return new EnumConstant (CreateConstantFromValue (real_type, v, loc).Resolve (null), t);
149                         }
150
151                         if (v == null) {
152                                 if (TypeManager.IsNullableType (t))
153                                         return Nullable.LiftedNull.Create (t, loc);
154
155                                 if (TypeManager.IsReferenceType (t))
156                                         return new NullConstant (t, loc);
157                         }
158
159                         throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'",
160                                 v, TypeManager.CSharpName (t));
161                 }
162
163                 public override Expression CreateExpressionTree (ResolveContext ec)
164                 {
165                         Arguments args = new Arguments (2);
166                         args.Add (new Argument (this));
167                         args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
168
169                         return CreateExpressionFactoryCall (ec, "Constant", args);
170                 }
171
172                 /// <summary>
173                 /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
174                 /// It throws OverflowException 
175                 /// </summary>
176                 // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
177                 public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
178
179                 // This is a custom version of Convert.ChangeType() which works
180                 // with the TypeBuilder defined types when compiling corlib.
181                 static object ChangeType (object value, TypeSpec targetType, out bool error)
182                 {
183                         IConvertible convert_value = value as IConvertible;
184
185                         if (convert_value == null) {
186                                 error = true;
187                                 return null;
188                         }
189
190                         //
191                         // We cannot rely on build-in type conversions as they are
192                         // more limited than what C# supports.
193                         // See char -> float/decimal/double conversion
194                         //
195                         error = false;
196                         try {
197                                 switch (targetType.BuildinType) {
198                                 case BuildinTypeSpec.Type.Bool:
199                                         return convert_value.ToBoolean (nfi);
200                                 case BuildinTypeSpec.Type.Byte:
201                                         return convert_value.ToByte (nfi);
202                                 case BuildinTypeSpec.Type.Char:
203                                         return convert_value.ToChar (nfi);
204                                 case BuildinTypeSpec.Type.Short:
205                                         return convert_value.ToInt16 (nfi);
206                                 case BuildinTypeSpec.Type.Int:
207                                         return convert_value.ToInt32 (nfi);
208                                 case BuildinTypeSpec.Type.Long:
209                                         return convert_value.ToInt64 (nfi);
210                                 case BuildinTypeSpec.Type.SByte:
211                                         return convert_value.ToSByte (nfi);
212                                 case BuildinTypeSpec.Type.Decimal:
213                                         if (convert_value.GetType () == typeof (char))
214                                                 return (decimal) convert_value.ToInt32 (nfi);
215                                         return convert_value.ToDecimal (nfi);
216                                 case BuildinTypeSpec.Type.Double:
217                                         if (convert_value.GetType () == typeof (char))
218                                                 return (double) convert_value.ToInt32 (nfi);
219                                         return convert_value.ToDouble (nfi);
220                                 case BuildinTypeSpec.Type.Float:
221                                         if (convert_value.GetType () == typeof (char))
222                                                 return (float) convert_value.ToInt32 (nfi);
223                                         return convert_value.ToSingle (nfi);
224                                 case BuildinTypeSpec.Type.String:
225                                         return convert_value.ToString (nfi);
226                                 case BuildinTypeSpec.Type.UShort:
227                                         return convert_value.ToUInt16 (nfi);
228                                 case BuildinTypeSpec.Type.UInt:
229                                         return convert_value.ToUInt32 (nfi);
230                                 case BuildinTypeSpec.Type.ULong:
231                                         return convert_value.ToUInt64 (nfi);
232                                 case BuildinTypeSpec.Type.Object:
233                                         return value;
234                                 }
235                         } catch {
236                         }
237
238                         error = true;
239                         return null;
240                 }
241
242                 /// <summary>
243                 ///   Attempts to do a compile-time folding of a constant cast.
244                 /// </summary>
245                 public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
246                 {
247                         try {
248                                 return TryReduce (ec, target_type);
249                         }
250                         catch (OverflowException) {
251                                 if (ec.ConstantCheckState && Type.BuildinType != BuildinTypeSpec.Type.Decimal) {
252                                         ec.Report.Error (221, loc,
253                                                 "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
254                                                 GetValueAsLiteral (), target_type.GetSignatureForError ());
255                                 } else {
256                                         Error_ValueCannotBeConverted (ec, loc, target_type, false);
257                                 }
258
259                                 return New.Constantify (target_type, loc).Resolve (ec);
260                         }
261                 }
262
263                 Constant TryReduce (ResolveContext ec, TypeSpec target_type)
264                 {
265                         if (Type == target_type)
266                                 return this;
267
268                         Constant c;
269                         if (TypeManager.IsEnumType (target_type)) {
270                                 c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
271                                 if (c == null)
272                                         return null;
273
274                                 return new EnumConstant (c, target_type).Resolve (ec);
275                         }
276
277                         c = ConvertExplicitly (ec.ConstantCheckState, target_type);
278                         if (c != null)
279                                 c = c.Resolve (ec);
280
281                         return c;
282                 }
283
284                 /// <summary>
285                 /// Need to pass type as the constant can require a boxing
286                 /// and in such case no optimization is possible
287                 /// </summary>
288                 public bool IsDefaultInitializer (TypeSpec type)
289                 {
290                         if (type == Type)
291                                 return IsDefaultValue;
292
293                         return this is NullLiteral;
294                 }
295
296                 public abstract bool IsDefaultValue {
297                         get;
298                 }
299
300                 public abstract bool IsNegative {
301                         get;
302                 }
303
304                 //
305                 // When constant is declared as literal
306                 //
307                 public virtual bool IsLiteral {
308                         get { return false; }
309                 }
310                 
311                 public virtual bool IsOneInteger {
312                         get { return false; }
313                 }               
314
315                 //
316                 // Returns true iff 1) the stack type of this is one of Object, 
317                 // int32, int64 and 2) this == 0 or this == null.
318                 //
319                 public virtual bool IsZeroInteger {
320                         get { return false; }
321                 }
322
323                 public override void EmitSideEffect (EmitContext ec)
324                 {
325                         // do nothing
326                 }
327
328                 public sealed override Expression Clone (CloneContext clonectx)
329                 {
330                         // No cloning is not needed for constants
331                         return this;
332                 }
333
334                 protected override void CloneTo (CloneContext clonectx, Expression target)
335                 {
336                         throw new NotSupportedException ("should not be reached");
337                 }
338
339                 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
340                 {
341 #if STATIC
342                         return base.MakeExpression (ctx);
343 #else
344                         return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
345 #endif
346                 }
347
348                 public new Constant Resolve (ResolveContext rc)
349                 {
350                         if (eclass != ExprClass.Unresolved)
351                                 return this;
352
353                         // Resolved constant has to be still a constant
354                         Constant c = (Constant) DoResolve (rc);
355                         if (c == null)
356                                 return null;
357
358                         if ((c.eclass & ExprClass.Value) == 0) {
359                                 c.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc);
360                                 return null;
361                         }
362
363                         if (c.type == null)
364                                 throw new InternalErrorException ("Expression `{0}' did not set its type after Resolve", c.GetType ());
365
366                         return c;
367                 }
368         }
369
370         public abstract class IntegralConstant : Constant
371         {
372                 protected IntegralConstant (Location loc) :
373                         base (loc)
374                 {
375                 }
376
377                 public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
378                 {
379                         try {
380                                 ConvertExplicitly (true, target);
381                                 base.Error_ValueCannotBeConverted (ec, loc, target, expl);
382                         }
383                         catch
384                         {
385                                 ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
386                                         GetValue ().ToString (), TypeManager.CSharpName (target));
387                         }
388                 }
389
390                 public override string GetValueAsLiteral ()
391                 {
392                         return GetValue ().ToString ();
393                 }
394                 
395                 public abstract Constant Increment ();
396         }
397         
398         public class BoolConstant : Constant {
399                 public readonly bool Value;
400                 
401                 public BoolConstant (bool val, Location loc):
402                         base (loc)
403                 {
404                         Value = val;
405                 }
406
407                 protected override Expression DoResolve (ResolveContext ec)
408                 {
409                         type = TypeManager.bool_type;
410                         eclass = ExprClass.Value;
411                         return this;
412                 }
413
414                 public override object GetValue ()
415                 {
416                         return (object) Value;
417                 }
418
419                 public override string GetValueAsLiteral ()
420                 {
421                         return Value ? "true" : "false";
422                 }
423
424                 public override long GetValueAsLong ()
425                 {
426                         return Value ? 1 : 0;
427                 }
428
429                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
430                 {
431                         enc.Encode (Value);
432                 }
433                 
434                 public override void Emit (EmitContext ec)
435                 {
436                         if (Value)
437                                 ec.Emit (OpCodes.Ldc_I4_1);
438                         else
439                                 ec.Emit (OpCodes.Ldc_I4_0);
440                 }
441
442                 public override bool IsDefaultValue {
443                         get {
444                                 return !Value;
445                         }
446                 }
447
448                 public override bool IsNegative {
449                         get {
450                                 return false;
451                         }
452                 }
453         
454                 public override bool IsZeroInteger {
455                         get { return Value == false; }
456                 }
457
458                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
459                 {
460                         return null;
461                 }
462
463         }
464
465         public class ByteConstant : IntegralConstant
466         {
467                 public readonly byte Value;
468
469                 public ByteConstant (byte v, Location loc):
470                         base (loc)
471                 {
472                         Value = v;
473                 }
474
475                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
476                 {
477                         enc.Encode (Value);
478                 }
479
480                 public override void Emit (EmitContext ec)
481                 {
482                         ec.EmitInt (Value);
483                 }
484
485                 protected override Expression DoResolve (ResolveContext ec)
486                 {
487                         type = TypeManager.byte_type;
488                         eclass = ExprClass.Value;
489                         return this;
490                 }
491
492                 public override object GetValue ()
493                 {
494                         return Value;
495                 }
496
497                 public override long GetValueAsLong ()
498                 {
499                         return Value;
500                 }
501
502                 public override Constant Increment ()
503                 {
504                         return new ByteConstant (checked ((byte)(Value + 1)), loc);
505                 }
506
507                 public override bool IsDefaultValue {
508                         get {
509                                 return Value == 0;
510                         }
511                 }
512
513                 public override bool IsOneInteger {
514                         get {
515                                 return Value == 1;
516                         }
517                 }               
518
519                 public override bool IsNegative {
520                         get {
521                                 return false;
522                         }
523                 }
524
525                 public override bool IsZeroInteger {
526                         get { return Value == 0; }
527                 }
528
529                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
530                 {
531                         switch (target_type.BuildinType) {
532                         case BuildinTypeSpec.Type.SByte:
533                                 if (in_checked_context){
534                                         if (Value > SByte.MaxValue)
535                                                 throw new OverflowException ();
536                                 }
537                                 return new SByteConstant ((sbyte) Value, Location);
538                         case BuildinTypeSpec.Type.Short:
539                                 return new ShortConstant ((short) Value, Location);
540                         case BuildinTypeSpec.Type.UShort:
541                                 return new UShortConstant ((ushort) Value, Location);
542                         case BuildinTypeSpec.Type.Int:
543                                 return new IntConstant ((int) Value, Location);
544                         case BuildinTypeSpec.Type.UInt:
545                                 return new UIntConstant ((uint) Value, Location);
546                         case BuildinTypeSpec.Type.Long:
547                                 return new LongConstant ((long) Value, Location);
548                         case BuildinTypeSpec.Type.ULong:
549                                 return new ULongConstant ((ulong) Value, Location);
550                         case BuildinTypeSpec.Type.Float:
551                                 return new FloatConstant ((float) Value, Location);
552                         case BuildinTypeSpec.Type.Double:
553                                 return new DoubleConstant ((double) Value, Location);
554                         case BuildinTypeSpec.Type.Char:
555                                 return new CharConstant ((char) Value, Location);
556                         case BuildinTypeSpec.Type.Decimal:
557                                 return new DecimalConstant ((decimal) Value, Location);
558                         }
559
560                         return null;
561                 }
562
563         }
564
565         public class CharConstant : Constant {
566                 public readonly char Value;
567
568                 public CharConstant (char v, Location loc):
569                         base (loc)
570                 {
571                         Value = v;
572                 }
573
574                 protected override Expression DoResolve (ResolveContext rc)
575                 {
576                         type = TypeManager.char_type;
577                         eclass = ExprClass.Value;
578                         return this;
579                 }
580
581                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
582                 {
583                         enc.Encode ((ushort) Value);
584                 }
585
586                 public override void Emit (EmitContext ec)
587                 {
588                         ec.EmitInt (Value);
589                 }
590
591                 static string descape (char c)
592                 {
593                         switch (c){
594                         case '\a':
595                                 return "\\a"; 
596                         case '\b':
597                                 return "\\b"; 
598                         case '\n':
599                                 return "\\n"; 
600                         case '\t':
601                                 return "\\t"; 
602                         case '\v':
603                                 return "\\v"; 
604                         case '\r':
605                                 return "\\r"; 
606                         case '\\':
607                                 return "\\\\";
608                         case '\f':
609                                 return "\\f"; 
610                         case '\0':
611                                 return "\\0"; 
612                         case '"':
613                                 return "\\\""; 
614                         case '\'':
615                                 return "\\\'"; 
616                         }
617                         return c.ToString ();
618                 }
619
620                 public override object GetValue ()
621                 {
622                         return Value;
623                 }
624
625                 public override long GetValueAsLong ()
626                 {
627                         return Value;
628                 }
629
630                 public override string GetValueAsLiteral ()
631                 {
632                         return "\"" + descape (Value) + "\"";
633                 }
634
635                 public override bool IsDefaultValue {
636                         get {
637                                 return Value == 0;
638                         }
639                 }
640
641                 public override bool IsNegative {
642                         get {
643                                 return false;
644                         }
645                 }
646
647                 public override bool IsZeroInteger {
648                         get { return Value == '\0'; }
649                 }
650
651                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
652                 {
653                         switch (target_type.BuildinType) {
654                         case BuildinTypeSpec.Type.Byte:
655                                 if (in_checked_context) {
656                                         if (Value < Byte.MinValue || Value > Byte.MaxValue)
657                                                 throw new OverflowException ();
658                                 }
659                                 return new ByteConstant ((byte) Value, Location);
660                         case BuildinTypeSpec.Type.SByte:
661                                 if (in_checked_context) {
662                                         if (Value > SByte.MaxValue)
663                                                 throw new OverflowException ();
664                                 }
665                                 return new SByteConstant ((sbyte) Value, Location);
666
667                         case BuildinTypeSpec.Type.Short:
668                                 if (in_checked_context) {
669                                         if (Value > Int16.MaxValue)
670                                                 throw new OverflowException ();
671                                 }
672                                 return new ShortConstant ((short) Value, Location);
673                         case BuildinTypeSpec.Type.Int:
674                                 return new IntConstant ((int) Value, Location);
675                         case BuildinTypeSpec.Type.UInt:
676                                 return new UIntConstant ((uint) Value, Location);
677                         case BuildinTypeSpec.Type.Long:
678                                 return new LongConstant ((long) Value, Location);
679                         case BuildinTypeSpec.Type.ULong:
680                                 return new ULongConstant ((ulong) Value, Location);
681                         case BuildinTypeSpec.Type.Float:
682                                 return new FloatConstant ((float) Value, Location);
683                         case BuildinTypeSpec.Type.Double:
684                                 return new DoubleConstant ((double) Value, Location);
685                         case BuildinTypeSpec.Type.Decimal:
686                                 return new DecimalConstant ((decimal) Value, Location);
687                         }
688
689                         return null;
690                 }
691
692         }
693
694         public class SByteConstant : IntegralConstant {
695                 public readonly sbyte Value;
696
697                 public SByteConstant (sbyte v, Location loc):
698                         base (loc)
699                 {
700                         Value = v;
701                 }
702
703                 protected override Expression DoResolve (ResolveContext rc)
704                 {
705                         type = TypeManager.sbyte_type;
706                         eclass = ExprClass.Value;
707                         return this;
708                 }
709
710                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
711                 {
712                         enc.Encode (Value);
713                 }
714
715                 public override void Emit (EmitContext ec)
716                 {
717                         ec.EmitInt (Value);
718                 }
719
720                 public override object GetValue ()
721                 {
722                         return Value;
723                 }
724
725                 public override long GetValueAsLong ()
726                 {
727                         return Value;
728                 }
729
730                 public override Constant Increment ()
731                 {
732                     return new SByteConstant (checked((sbyte)(Value + 1)), loc);
733                 }
734
735                 public override bool IsDefaultValue {
736                         get {
737                                 return Value == 0;
738                         }
739                 }
740
741                 public override bool IsNegative {
742                         get {
743                                 return Value < 0;
744                         }
745                 }
746                 
747                 public override bool IsOneInteger {
748                         get {
749                                 return Value == 1;
750                         }
751                 }               
752                 
753                 public override bool IsZeroInteger {
754                         get { return Value == 0; }
755                 }
756
757                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
758                 {
759                         switch (target_type.BuildinType) {
760                         case BuildinTypeSpec.Type.Byte:
761                                 if (in_checked_context && Value < 0)
762                                         throw new OverflowException ();
763                                 return new ByteConstant ((byte) Value, Location);
764                         case BuildinTypeSpec.Type.Short:
765                                 return new ShortConstant ((short) Value, Location);
766                         case BuildinTypeSpec.Type.UShort:
767                                 if (in_checked_context && Value < 0)
768                                         throw new OverflowException ();
769                                 return new UShortConstant ((ushort) Value, Location);
770                         case BuildinTypeSpec.Type.Int:
771                                 return new IntConstant ((int) Value, Location);
772                         case BuildinTypeSpec.Type.UInt:
773                                 if (in_checked_context && Value < 0)
774                                         throw new OverflowException ();
775                                 return new UIntConstant ((uint) Value, Location);
776                         case BuildinTypeSpec.Type.Long:
777                                 return new LongConstant ((long) Value, Location);
778                         case BuildinTypeSpec.Type.ULong:
779                                 if (in_checked_context && Value < 0)
780                                         throw new OverflowException ();
781                                 return new ULongConstant ((ulong) Value, Location);
782                         case BuildinTypeSpec.Type.Float:
783                                 return new FloatConstant ((float) Value, Location);
784                         case BuildinTypeSpec.Type.Double:
785                                 return new DoubleConstant ((double) Value, Location);
786                         case BuildinTypeSpec.Type.Char:
787                                 if (in_checked_context && Value < 0)
788                                         throw new OverflowException ();
789                                 return new CharConstant ((char) Value, Location);
790                         case BuildinTypeSpec.Type.Decimal:
791                                 return new DecimalConstant ((decimal) Value, Location);
792                         }
793
794                         return null;
795                 }
796
797         }
798
799         public class ShortConstant : IntegralConstant {
800                 public readonly short Value;
801
802                 public ShortConstant (short v, Location loc):
803                         base (loc)
804                 {
805                         Value = v;
806                 }
807
808                 protected override Expression DoResolve (ResolveContext rc)
809                 {
810                         type = TypeManager.short_type;
811                         eclass = ExprClass.Value;
812                         return this;
813                 }
814
815                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
816                 {
817                         enc.Encode (Value);
818                 }
819
820                 public override void Emit (EmitContext ec)
821                 {
822                         ec.EmitInt (Value);
823                 }
824
825                 public override object GetValue ()
826                 {
827                         return Value;
828                 }
829
830                 public override long GetValueAsLong ()
831                 {
832                         return Value;
833                 }
834
835                 public override Constant Increment ()
836                 {
837                         return new ShortConstant (checked((short)(Value + 1)), loc);
838                 }
839
840                 public override bool IsDefaultValue {
841                         get {
842                                 return Value == 0;
843                         }
844                 }
845                 
846                 public override bool IsZeroInteger {
847                         get { return Value == 0; }
848                 }
849
850                 public override bool IsNegative {
851                         get {
852                                 return Value < 0;
853                         }
854                 }
855                 
856                 public override bool IsOneInteger {
857                         get {
858                                 return Value == 1;
859                         }
860                 }               
861
862                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
863                 {
864                         switch (target_type.BuildinType) {
865                         case BuildinTypeSpec.Type.Byte:
866                                 if (in_checked_context) {
867                                         if (Value < Byte.MinValue || Value > Byte.MaxValue)
868                                                 throw new OverflowException ();
869                                 }
870                                 return new ByteConstant ((byte) Value, Location);
871                         case BuildinTypeSpec.Type.SByte:
872                                 if (in_checked_context) {
873                                         if (Value < SByte.MinValue || Value > SByte.MaxValue)
874                                                 throw new OverflowException ();
875                                 }
876                                 return new SByteConstant ((sbyte) Value, Location);
877                         case BuildinTypeSpec.Type.UShort:
878                                 if (in_checked_context && Value < 0)
879                                         throw new OverflowException ();
880
881                                 return new UShortConstant ((ushort) Value, Location);
882                         case BuildinTypeSpec.Type.Int:
883                                 return new IntConstant ((int) Value, Location);
884                         case BuildinTypeSpec.Type.UInt:
885                                 if (in_checked_context && Value < 0)
886                                         throw new OverflowException ();
887                                 return new UIntConstant ((uint) Value, Location);
888                         case BuildinTypeSpec.Type.Long:
889                                 return new LongConstant ((long) Value, Location);
890                         case BuildinTypeSpec.Type.ULong:
891                                 if (in_checked_context && Value < 0)
892                                         throw new OverflowException ();
893                                 return new ULongConstant ((ulong) Value, Location);
894                         case BuildinTypeSpec.Type.Float:
895                                 return new FloatConstant ((float) Value, Location);
896                         case BuildinTypeSpec.Type.Double:
897                                 return new DoubleConstant ((double) Value, Location);
898                         case BuildinTypeSpec.Type.Char:
899                                 if (in_checked_context) {
900                                         if (Value < Char.MinValue)
901                                                 throw new OverflowException ();
902                                 }
903                                 return new CharConstant ((char) Value, Location);
904                         case BuildinTypeSpec.Type.Decimal:
905                                 return new DecimalConstant ((decimal) Value, Location);
906                         }
907
908                         return null;
909                 }
910
911         }
912
913         public class UShortConstant : IntegralConstant
914         {
915                 public readonly ushort Value;
916
917                 public UShortConstant (ushort v, Location loc):
918                         base (loc)
919                 {
920                         Value = v;
921                 }
922
923                 protected override Expression DoResolve (ResolveContext rc)
924                 {
925                         type = TypeManager.ushort_type;
926                         eclass = ExprClass.Value;
927                         return this;
928                 }
929
930                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
931                 {
932                         enc.Encode (Value);
933                 }
934
935                 public override void Emit (EmitContext ec)
936                 {
937                         ec.EmitInt (Value);
938                 }
939
940                 public override object GetValue ()
941                 {
942                         return Value;
943                 }
944
945                 public override long GetValueAsLong ()
946                 {
947                         return Value;
948                 }
949         
950                 public override Constant Increment ()
951                 {
952                         return new UShortConstant (checked((ushort)(Value + 1)), loc);
953                 }
954
955                 public override bool IsDefaultValue {
956                         get {
957                                 return Value == 0;
958                         }
959                 }
960
961                 public override bool IsNegative {
962                         get {
963                                 return false;
964                         }
965                 }
966                 
967                 public override bool IsOneInteger {
968                         get {
969                                 return Value == 1;
970                         }
971                 }               
972         
973                 public override bool IsZeroInteger {
974                         get { return Value == 0; }
975                 }
976
977                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
978                 {
979                         switch (target_type.BuildinType) {
980                         case BuildinTypeSpec.Type.Byte:
981                                 if (in_checked_context) {
982                                         if (Value > Byte.MaxValue)
983                                                 throw new OverflowException ();
984                                 }
985                                 return new ByteConstant ((byte) Value, Location);
986                         case BuildinTypeSpec.Type.SByte:
987                                 if (in_checked_context) {
988                                         if (Value > SByte.MaxValue)
989                                                 throw new OverflowException ();
990                                 }
991                                 return new SByteConstant ((sbyte) Value, Location);
992                         case BuildinTypeSpec.Type.Short:
993                                 if (in_checked_context) {
994                                         if (Value > Int16.MaxValue)
995                                                 throw new OverflowException ();
996                                 }
997                                 return new ShortConstant ((short) Value, Location);
998                         case BuildinTypeSpec.Type.Int:
999                                 return new IntConstant ((int) Value, Location);
1000                         case BuildinTypeSpec.Type.UInt:
1001                                 return new UIntConstant ((uint) Value, Location);
1002                         case BuildinTypeSpec.Type.Long:
1003                                 return new LongConstant ((long) Value, Location);
1004                         case BuildinTypeSpec.Type.ULong:
1005                                 return new ULongConstant ((ulong) Value, Location);
1006                         case BuildinTypeSpec.Type.Float:
1007                                 return new FloatConstant ((float) Value, Location);
1008                         case BuildinTypeSpec.Type.Double:
1009                                 return new DoubleConstant ((double) Value, Location);
1010                         case BuildinTypeSpec.Type.Char:
1011                                 if (in_checked_context) {
1012                                         if (Value > Char.MaxValue)
1013                                                 throw new OverflowException ();
1014                                 }
1015                                 return new CharConstant ((char) Value, Location);
1016                         case BuildinTypeSpec.Type.Decimal:
1017                                 return new DecimalConstant ((decimal) Value, Location);
1018                         }
1019
1020                         return null;
1021                 }
1022         }
1023
1024         public class IntConstant : IntegralConstant {
1025                 public readonly int Value;
1026
1027                 public IntConstant (int v, Location loc):
1028                         base (loc)
1029                 {
1030                         Value = v;
1031                 }
1032
1033                 protected override Expression DoResolve (ResolveContext rc)
1034                 {
1035                         type = TypeManager.int32_type;
1036                         eclass = ExprClass.Value;
1037                         return this;
1038                 }
1039
1040                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1041                 {
1042                         enc.Encode (Value);
1043                 }
1044
1045                 public override void Emit (EmitContext ec)
1046                 {
1047                         ec.EmitInt (Value);
1048                 }
1049
1050                 public override object GetValue ()
1051                 {
1052                         return Value;
1053                 }
1054
1055                 public override long GetValueAsLong ()
1056                 {
1057                         return Value;
1058                 }
1059
1060                 public override Constant Increment ()
1061                 {
1062                         return new IntConstant (checked(Value + 1), loc);
1063                 }
1064
1065                 public override bool IsDefaultValue {
1066                         get {
1067                                 return Value == 0;
1068                         }
1069                 }
1070                 
1071                 public override bool IsNegative {
1072                         get {
1073                                 return Value < 0;
1074                         }
1075                 }
1076                 
1077                 public override bool IsOneInteger {
1078                         get {
1079                                 return Value == 1;
1080                         }
1081                 }               
1082
1083                 public override bool IsZeroInteger {
1084                         get { return Value == 0; }
1085                 }
1086
1087                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1088                 {
1089                         switch (target_type.BuildinType) {
1090                         case BuildinTypeSpec.Type.Byte:
1091                                 if (in_checked_context) {
1092                                         if (Value < Byte.MinValue || Value > Byte.MaxValue)
1093                                                 throw new OverflowException ();
1094                                 }
1095                                 return new ByteConstant ((byte) Value, Location);
1096                         case BuildinTypeSpec.Type.SByte:
1097                                 if (in_checked_context) {
1098                                         if (Value < SByte.MinValue || Value > SByte.MaxValue)
1099                                                 throw new OverflowException ();
1100                                 }
1101                                 return new SByteConstant ((sbyte) Value, Location);
1102                         case BuildinTypeSpec.Type.Short:
1103                                 if (in_checked_context) {
1104                                         if (Value < Int16.MinValue || Value > Int16.MaxValue)
1105                                                 throw new OverflowException ();
1106                                 }
1107                                 return new ShortConstant ((short) Value, Location);
1108                         case BuildinTypeSpec.Type.UShort:
1109                                 if (in_checked_context) {
1110                                         if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1111                                                 throw new OverflowException ();
1112                                 }
1113                                 return new UShortConstant ((ushort) Value, Location);
1114                         case BuildinTypeSpec.Type.UInt:
1115                                 if (in_checked_context) {
1116                                         if (Value < UInt32.MinValue)
1117                                                 throw new OverflowException ();
1118                                 }
1119                                 return new UIntConstant ((uint) Value, Location);
1120                         case BuildinTypeSpec.Type.Long:
1121                                 return new LongConstant ((long) Value, Location);
1122                         case BuildinTypeSpec.Type.ULong:
1123                                 if (in_checked_context && Value < 0)
1124                                         throw new OverflowException ();
1125                                 return new ULongConstant ((ulong) Value, Location);
1126                         case BuildinTypeSpec.Type.Float:
1127                                 return new FloatConstant ((float) Value, Location);
1128                         case BuildinTypeSpec.Type.Double:
1129                                 return new DoubleConstant ((double) Value, Location);
1130                         case BuildinTypeSpec.Type.Char:
1131                                 if (in_checked_context) {
1132                                         if (Value < Char.MinValue || Value > Char.MaxValue)
1133                                                 throw new OverflowException ();
1134                                 }
1135                                 return new CharConstant ((char) Value, Location);
1136                         case BuildinTypeSpec.Type.Decimal:
1137                                 return new DecimalConstant ((decimal) Value, Location);
1138                         }
1139
1140                         return null;
1141                 }
1142
1143                 public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
1144                 {
1145                         if (this.type == type)
1146                                 return this;
1147
1148                         Constant c = TryImplicitIntConversion (type);
1149                         if (c != null)
1150                                 return c.Resolve (rc);
1151
1152                         return base.ConvertImplicitly (rc, type);
1153                 }
1154
1155                 /// <summary>
1156                 ///   Attempts to perform an implicit constant conversion of the IntConstant
1157                 ///   into a different data type using casts (See Implicit Constant
1158                 ///   Expression Conversions)
1159                 /// </summary>
1160                 Constant TryImplicitIntConversion (TypeSpec target_type)
1161                 {
1162                         switch (target_type.BuildinType) {
1163                         case BuildinTypeSpec.Type.SByte:
1164                                 if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1165                                         return new SByteConstant ((sbyte) Value, loc);
1166                                 break;
1167                         case BuildinTypeSpec.Type.Byte:
1168                                 if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1169                                         return new ByteConstant ((byte) Value, loc);
1170                                 break;
1171                         case BuildinTypeSpec.Type.Short:
1172                                 if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1173                                         return new ShortConstant ((short) Value, loc);
1174                                 break;
1175                         case BuildinTypeSpec.Type.UShort:
1176                                 if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1177                                         return new UShortConstant ((ushort) Value, loc);
1178                                 break;
1179                         case BuildinTypeSpec.Type.UInt:
1180                                 if (Value >= 0)
1181                                         return new UIntConstant ((uint) Value, loc);
1182                                 break;
1183                         case BuildinTypeSpec.Type.ULong:
1184                                 //
1185                                 // we can optimize this case: a positive int32
1186                                 // always fits on a uint64.  But we need an opcode
1187                                 // to do it.
1188                                 //
1189                                 if (Value >= 0)
1190                                         return new ULongConstant ((ulong) Value, loc);
1191                                 break;
1192                         case BuildinTypeSpec.Type.Double:
1193                                 return new DoubleConstant ((double) Value, loc);
1194                         case BuildinTypeSpec.Type.Float:
1195                                 return new FloatConstant ((float) Value, loc);
1196                         }
1197
1198                         return null;
1199                 }
1200         }
1201
1202         public class UIntConstant : IntegralConstant {
1203                 public readonly uint Value;
1204
1205                 public UIntConstant (uint v, Location loc):
1206                         base (loc)
1207                 {
1208                         Value = v;
1209                 }
1210
1211                 protected override Expression DoResolve (ResolveContext rc)
1212                 {
1213                         type = TypeManager.uint32_type;
1214                         eclass = ExprClass.Value;
1215                         return this;
1216                 }
1217
1218                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1219                 {
1220                         enc.Encode (Value);
1221                 }
1222
1223                 public override void Emit (EmitContext ec)
1224                 {
1225                         ec.EmitInt (unchecked ((int) Value));
1226                 }
1227
1228                 public override object GetValue ()
1229                 {
1230                         return Value;
1231                 }
1232
1233                 public override long GetValueAsLong ()
1234                 {
1235                         return Value;
1236                 }
1237
1238                 public override Constant Increment ()
1239                 {
1240                         return new UIntConstant (checked(Value + 1), loc);
1241                 }
1242         
1243                 public override bool IsDefaultValue {
1244                         get {
1245                                 return Value == 0;
1246                         }
1247                 }
1248
1249                 public override bool IsNegative {
1250                         get {
1251                                 return false;
1252                         }
1253                 }
1254                 
1255                 public override bool IsOneInteger {
1256                         get {
1257                                 return Value == 1;
1258                         }
1259                 }               
1260
1261                 public override bool IsZeroInteger {
1262                         get { return Value == 0; }
1263                 }
1264
1265                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1266                 {
1267                         switch (target_type.BuildinType) {
1268                         case BuildinTypeSpec.Type.Byte:
1269                                 if (in_checked_context) {
1270                                         if (Value < 0 || Value > byte.MaxValue)
1271                                                 throw new OverflowException ();
1272                                 }
1273                                 return new ByteConstant ((byte) Value, Location);
1274                         case BuildinTypeSpec.Type.SByte:
1275                                 if (in_checked_context) {
1276                                         if (Value > SByte.MaxValue)
1277                                                 throw new OverflowException ();
1278                                 }
1279                                 return new SByteConstant ((sbyte) Value, Location);
1280                         case BuildinTypeSpec.Type.Short:
1281                                 if (in_checked_context) {
1282                                         if (Value > Int16.MaxValue)
1283                                                 throw new OverflowException ();
1284                                 }
1285                                 return new ShortConstant ((short) Value, Location);
1286                         case BuildinTypeSpec.Type.UShort:
1287                                 if (in_checked_context) {
1288                                         if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1289                                                 throw new OverflowException ();
1290                                 }
1291                                 return new UShortConstant ((ushort) Value, Location);
1292                         case BuildinTypeSpec.Type.Int:
1293                                 if (in_checked_context) {
1294                                         if (Value > Int32.MaxValue)
1295                                                 throw new OverflowException ();
1296                                 }
1297                                 return new IntConstant ((int) Value, Location);
1298                         case BuildinTypeSpec.Type.Long:
1299                                 return new LongConstant ((long) Value, Location);
1300                         case BuildinTypeSpec.Type.ULong:
1301                                 return new ULongConstant ((ulong) Value, Location);
1302                         case BuildinTypeSpec.Type.Float:
1303                                 return new FloatConstant ((float) Value, Location);
1304                         case BuildinTypeSpec.Type.Double:
1305                                 return new DoubleConstant ((double) Value, Location);
1306                         case BuildinTypeSpec.Type.Char:
1307                                 if (in_checked_context) {
1308                                         if (Value < Char.MinValue || Value > Char.MaxValue)
1309                                                 throw new OverflowException ();
1310                                 }
1311                                 return new CharConstant ((char) Value, Location);
1312                         case BuildinTypeSpec.Type.Decimal:
1313                                 return new DecimalConstant ((decimal) Value, Location);
1314                         }
1315
1316                         return null;
1317                 }
1318
1319         }
1320
1321         public class LongConstant : IntegralConstant {
1322                 public readonly long Value;
1323
1324                 public LongConstant (long v, Location loc):
1325                         base (loc)
1326                 {
1327                         Value = v;
1328                 }
1329
1330                 protected override Expression DoResolve (ResolveContext rc)
1331                 {
1332                         type = TypeManager.int64_type;
1333                         eclass = ExprClass.Value;
1334                         return this;
1335                 }
1336
1337                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1338                 {
1339                         enc.Encode (Value);
1340                 }
1341
1342                 public override void Emit (EmitContext ec)
1343                 {
1344                         ec.EmitLong (Value);
1345                 }
1346
1347                 public override object GetValue ()
1348                 {
1349                         return Value;
1350                 }
1351
1352                 public override long GetValueAsLong ()
1353                 {
1354                         return Value;
1355                 }
1356
1357                 public override Constant Increment ()
1358                 {
1359                         return new LongConstant (checked(Value + 1), loc);
1360                 }
1361                 
1362                 public override bool IsDefaultValue {
1363                         get {
1364                                 return Value == 0;
1365                         }
1366                 }
1367
1368                 public override bool IsNegative {
1369                         get {
1370                                 return Value < 0;
1371                         }
1372                 }
1373                 
1374                 public override bool IsOneInteger {
1375                         get {
1376                                 return Value == 1;
1377                         }
1378                 }               
1379
1380                 public override bool IsZeroInteger {
1381                         get { return Value == 0; }
1382                 }
1383
1384                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1385                 {
1386                         switch (target_type.BuildinType) {
1387                         case BuildinTypeSpec.Type.Byte:
1388                                 if (in_checked_context) {
1389                                         if (Value < Byte.MinValue || Value > Byte.MaxValue)
1390                                                 throw new OverflowException ();
1391                                 }
1392                                 return new ByteConstant ((byte) Value, Location);
1393                         case BuildinTypeSpec.Type.SByte:
1394                                 if (in_checked_context) {
1395                                         if (Value < SByte.MinValue || Value > SByte.MaxValue)
1396                                                 throw new OverflowException ();
1397                                 }
1398                                 return new SByteConstant ((sbyte) Value, Location);
1399                         case BuildinTypeSpec.Type.Short:
1400                                 if (in_checked_context) {
1401                                         if (Value < Int16.MinValue || Value > Int16.MaxValue)
1402                                                 throw new OverflowException ();
1403                                 }
1404                                 return new ShortConstant ((short) Value, Location);
1405                         case BuildinTypeSpec.Type.UShort:
1406                                 if (in_checked_context) {
1407                                         if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1408                                                 throw new OverflowException ();
1409                                 }
1410                                 return new UShortConstant ((ushort) Value, Location);
1411                         case BuildinTypeSpec.Type.Int:
1412                                 if (in_checked_context) {
1413                                         if (Value < Int32.MinValue || Value > Int32.MaxValue)
1414                                                 throw new OverflowException ();
1415                                 }
1416                                 return new IntConstant ((int) Value, Location);
1417                         case BuildinTypeSpec.Type.UInt:
1418                                 if (in_checked_context) {
1419                                         if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1420                                                 throw new OverflowException ();
1421                                 }
1422                                 return new UIntConstant ((uint) Value, Location);
1423                         case BuildinTypeSpec.Type.ULong:
1424                                 if (in_checked_context && Value < 0)
1425                                         throw new OverflowException ();
1426                                 return new ULongConstant ((ulong) Value, Location);
1427                         case BuildinTypeSpec.Type.Float:
1428                                 return new FloatConstant ((float) Value, Location);
1429                         case BuildinTypeSpec.Type.Double:
1430                                 return new DoubleConstant ((double) Value, Location);
1431                         case BuildinTypeSpec.Type.Char:
1432                                 if (in_checked_context) {
1433                                         if (Value < Char.MinValue || Value > Char.MaxValue)
1434                                                 throw new OverflowException ();
1435                                 }
1436                                 return new CharConstant ((char) Value, Location);
1437                         case BuildinTypeSpec.Type.Decimal:
1438                                 return new DecimalConstant ((decimal) Value, Location);
1439                         }
1440
1441                         return null;
1442                 }
1443
1444                 public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
1445                 {
1446                         if (Value >= 0 && type.BuildinType == BuildinTypeSpec.Type.ULong) {
1447                                 return new ULongConstant ((ulong) Value, loc).Resolve (rc);
1448                         }
1449
1450                         return base.ConvertImplicitly (rc, type);
1451                 }
1452         }
1453
1454         public class ULongConstant : IntegralConstant {
1455                 public readonly ulong Value;
1456
1457                 public ULongConstant (ulong v, Location loc):
1458                         base (loc)
1459                 {
1460                         Value = v;
1461                 }
1462
1463                 protected override Expression DoResolve (ResolveContext rc)
1464                 {
1465                         type = TypeManager.uint64_type;
1466                         eclass = ExprClass.Value;
1467                         return this;
1468                 }
1469
1470                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1471                 {
1472                         enc.Encode (Value);
1473                 }
1474
1475                 public override void Emit (EmitContext ec)
1476                 {
1477                         ec.EmitLong (unchecked ((long) Value));
1478                 }
1479
1480                 public override object GetValue ()
1481                 {
1482                         return Value;
1483                 }
1484
1485                 public override long GetValueAsLong ()
1486                 {
1487                         return (long) Value;
1488                 }
1489
1490                 public override Constant Increment ()
1491                 {
1492                         return new ULongConstant (checked(Value + 1), loc);
1493                 }
1494
1495                 public override bool IsDefaultValue {
1496                         get {
1497                                 return Value == 0;
1498                         }
1499                 }
1500
1501                 public override bool IsNegative {
1502                         get {
1503                                 return false;
1504                         }
1505                 }
1506                 
1507                 public override bool IsOneInteger {
1508                         get {
1509                                 return Value == 1;
1510                         }
1511                 }               
1512
1513                 public override bool IsZeroInteger {
1514                         get { return Value == 0; }
1515                 }
1516
1517                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1518                 {
1519                         switch (target_type.BuildinType) {
1520                         case BuildinTypeSpec.Type.Byte:
1521                                 if (in_checked_context && Value > Byte.MaxValue)
1522                                         throw new OverflowException ();
1523                                 return new ByteConstant ((byte) Value, Location);
1524                         case BuildinTypeSpec.Type.SByte:
1525                                 if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1526                                         throw new OverflowException ();
1527                                 return new SByteConstant ((sbyte) Value, Location);
1528                         case BuildinTypeSpec.Type.Short:
1529                                 if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1530                                         throw new OverflowException ();
1531                                 return new ShortConstant ((short) Value, Location);
1532                         case BuildinTypeSpec.Type.UShort:
1533                                 if (in_checked_context && Value > UInt16.MaxValue)
1534                                         throw new OverflowException ();
1535                                 return new UShortConstant ((ushort) Value, Location);
1536                         case BuildinTypeSpec.Type.Int:
1537                                 if (in_checked_context && Value > UInt32.MaxValue)
1538                                         throw new OverflowException ();
1539                                 return new IntConstant ((int) Value, Location);
1540                         case BuildinTypeSpec.Type.UInt:
1541                                 if (in_checked_context && Value > UInt32.MaxValue)
1542                                         throw new OverflowException ();
1543                                 return new UIntConstant ((uint) Value, Location);
1544                         case BuildinTypeSpec.Type.Long:
1545                                 if (in_checked_context && Value > Int64.MaxValue)
1546                                         throw new OverflowException ();
1547                                 return new LongConstant ((long) Value, Location);
1548                         case BuildinTypeSpec.Type.Float:
1549                                 return new FloatConstant ((float) Value, Location);
1550                         case BuildinTypeSpec.Type.Double:
1551                                 return new DoubleConstant ((double) Value, Location);
1552                         case BuildinTypeSpec.Type.Char:
1553                                 if (in_checked_context && Value > Char.MaxValue)
1554                                         throw new OverflowException ();
1555                                 return new CharConstant ((char) Value, Location);
1556                         case BuildinTypeSpec.Type.Decimal:
1557                                 return new DecimalConstant ((decimal) Value, Location);
1558                         }
1559
1560                         return null;
1561                 }
1562
1563         }
1564
1565         public class FloatConstant : Constant {
1566                 public float Value;
1567
1568                 public FloatConstant (float v, Location loc):
1569                         base (loc)
1570                 {
1571                         Value = v;
1572                 }
1573
1574                 protected override Expression DoResolve (ResolveContext rc)
1575                 {
1576                         type = TypeManager.float_type;
1577                         eclass = ExprClass.Value;
1578                         return this;
1579                 }
1580
1581                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1582                 {
1583                         enc.Encode (Value);
1584                 }
1585
1586                 public override void Emit (EmitContext ec)
1587                 {
1588                         ec.Emit (OpCodes.Ldc_R4, Value);
1589                 }
1590
1591                 public override object GetValue ()
1592                 {
1593                         return Value;
1594                 }
1595
1596                 public override string GetValueAsLiteral ()
1597                 {
1598                         return Value.ToString ();
1599                 }
1600
1601                 public override long GetValueAsLong ()
1602                 {
1603                         throw new NotSupportedException ();
1604                 }
1605
1606                 public override bool IsDefaultValue {
1607                         get {
1608                                 return Value == 0;
1609                         }
1610                 }
1611
1612                 public override bool IsNegative {
1613                         get {
1614                                 return Value < 0;
1615                         }
1616                 }
1617
1618                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1619                 {
1620                         switch (target_type.BuildinType) {
1621                         case BuildinTypeSpec.Type.Byte:
1622                                 if (in_checked_context) {
1623                                         if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1624                                                 throw new OverflowException ();
1625                                 }
1626                                 return new ByteConstant ((byte) Value, Location);
1627                         case BuildinTypeSpec.Type.SByte:
1628                                 if (in_checked_context) {
1629                                         if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1630                                                 throw new OverflowException ();
1631                                 }
1632                                 return new SByteConstant ((sbyte) Value, Location);
1633                         case BuildinTypeSpec.Type.Short:
1634                                 if (in_checked_context) {
1635                                         if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1636                                                 throw new OverflowException ();
1637                                 }
1638                                 return new ShortConstant ((short) Value, Location);
1639                         case BuildinTypeSpec.Type.UShort:
1640                                 if (in_checked_context) {
1641                                         if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1642                                                 throw new OverflowException ();
1643                                 }
1644                                 return new UShortConstant ((ushort) Value, Location);
1645                         case BuildinTypeSpec.Type.Int:
1646                                 if (in_checked_context) {
1647                                         if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1648                                                 throw new OverflowException ();
1649                                 }
1650                                 return new IntConstant ((int) Value, Location);
1651                         case BuildinTypeSpec.Type.UInt:
1652                                 if (in_checked_context) {
1653                                         if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1654                                                 throw new OverflowException ();
1655                                 }
1656                                 return new UIntConstant ((uint) Value, Location);
1657                         case BuildinTypeSpec.Type.Long:
1658                                 if (in_checked_context) {
1659                                         if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1660                                                 throw new OverflowException ();
1661                                 }
1662                                 return new LongConstant ((long) Value, Location);
1663                         case BuildinTypeSpec.Type.ULong:
1664                                 if (in_checked_context) {
1665                                         if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1666                                                 throw new OverflowException ();
1667                                 }
1668                                 return new ULongConstant ((ulong) Value, Location);
1669                         case BuildinTypeSpec.Type.Double:
1670                                 return new DoubleConstant ((double) Value, Location);
1671                         case BuildinTypeSpec.Type.Char:
1672                                 if (in_checked_context) {
1673                                         if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1674                                                 throw new OverflowException ();
1675                                 }
1676                                 return new CharConstant ((char) Value, Location);
1677                         case BuildinTypeSpec.Type.Decimal:
1678                                 return new DecimalConstant ((decimal) Value, Location);
1679                         }
1680
1681                         return null;
1682                 }
1683
1684         }
1685
1686         public class DoubleConstant : Constant {
1687                 public double Value;
1688
1689                 public DoubleConstant (double v, Location loc):
1690                         base (loc)
1691                 {
1692                         Value = v;
1693                 }
1694
1695                 protected override Expression DoResolve (ResolveContext rc)
1696                 {
1697                         type = TypeManager.double_type;
1698                         eclass = ExprClass.Value;
1699                         return this;
1700                 }
1701
1702                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1703                 {
1704                         enc.Encode (Value);
1705                 }
1706
1707                 public override void Emit (EmitContext ec)
1708                 {
1709                         ec.Emit (OpCodes.Ldc_R8, Value);
1710                 }
1711
1712                 public override object GetValue ()
1713                 {
1714                         return Value;
1715                 }
1716
1717                 public override string GetValueAsLiteral ()
1718                 {
1719                         return Value.ToString ();
1720                 }
1721
1722                 public override long GetValueAsLong ()
1723                 {
1724                         throw new NotSupportedException ();
1725                 }
1726
1727                 public override bool IsDefaultValue {
1728                         get {
1729                                 return Value == 0;
1730                         }
1731                 }
1732
1733                 public override bool IsNegative {
1734                         get {
1735                                 return Value < 0;
1736                         }
1737                 }
1738
1739                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1740                 {
1741                         switch (target_type.BuildinType) {
1742                         case BuildinTypeSpec.Type.Byte:
1743                                 if (in_checked_context) {
1744                                         if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1745                                                 throw new OverflowException ();
1746                                 }
1747                                 return new ByteConstant ((byte) Value, Location);
1748                         case BuildinTypeSpec.Type.SByte:
1749                                 if (in_checked_context) {
1750                                         if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1751                                                 throw new OverflowException ();
1752                                 }
1753                                 return new SByteConstant ((sbyte) Value, Location);
1754                         case BuildinTypeSpec.Type.Short:
1755                                 if (in_checked_context) {
1756                                         if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1757                                                 throw new OverflowException ();
1758                                 }
1759                                 return new ShortConstant ((short) Value, Location);
1760                         case BuildinTypeSpec.Type.UShort:
1761                                 if (in_checked_context) {
1762                                         if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1763                                                 throw new OverflowException ();
1764                                 }
1765                                 return new UShortConstant ((ushort) Value, Location);
1766                         case BuildinTypeSpec.Type.Int:
1767                                 if (in_checked_context) {
1768                                         if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1769                                                 throw new OverflowException ();
1770                                 }
1771                                 return new IntConstant ((int) Value, Location);
1772                         case BuildinTypeSpec.Type.UInt:
1773                                 if (in_checked_context) {
1774                                         if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1775                                                 throw new OverflowException ();
1776                                 }
1777                                 return new UIntConstant ((uint) Value, Location);
1778                         case BuildinTypeSpec.Type.Long:
1779                                 if (in_checked_context) {
1780                                         if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1781                                                 throw new OverflowException ();
1782                                 }
1783                                 return new LongConstant ((long) Value, Location);
1784                         case BuildinTypeSpec.Type.ULong:
1785                                 if (in_checked_context) {
1786                                         if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1787                                                 throw new OverflowException ();
1788                                 }
1789                                 return new ULongConstant ((ulong) Value, Location);
1790                         case BuildinTypeSpec.Type.Float:
1791                                 return new FloatConstant ((float) Value, Location);
1792                         case BuildinTypeSpec.Type.Char:
1793                                 if (in_checked_context) {
1794                                         if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1795                                                 throw new OverflowException ();
1796                                 }
1797                                 return new CharConstant ((char) Value, Location);
1798                         case BuildinTypeSpec.Type.Decimal:
1799                                 return new DecimalConstant ((decimal) Value, Location);
1800                         }
1801
1802                         return null;
1803                 }
1804
1805         }
1806
1807         public class DecimalConstant : Constant {
1808                 public readonly decimal Value;
1809
1810                 public DecimalConstant (decimal d, Location loc):
1811                         base (loc)
1812                 {
1813                         Value = d;
1814                 }
1815
1816                 protected override Expression DoResolve (ResolveContext rc)
1817                 {
1818                         type = TypeManager.decimal_type;
1819                         eclass = ExprClass.Value;
1820                         return this;
1821                 }
1822
1823                 public override void Emit (EmitContext ec)
1824                 {
1825                         int [] words = decimal.GetBits (Value);
1826                         int power = (words [3] >> 16) & 0xff;
1827
1828                         if (power == 0) {
1829                                 if (Value <= int.MaxValue && Value >= int.MinValue) {
1830                                         if (TypeManager.void_decimal_ctor_int_arg == null) {
1831                                                 TypeManager.void_decimal_ctor_int_arg = TypeManager.GetPredefinedConstructor (
1832                                                         TypeManager.decimal_type, loc, TypeManager.int32_type);
1833
1834                                                 if (TypeManager.void_decimal_ctor_int_arg == null)
1835                                                         return;
1836                                         }
1837
1838                                         ec.EmitInt ((int) Value);
1839                                         ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
1840                                         return;
1841                                 }
1842
1843                                 if (Value <= long.MaxValue && Value >= long.MinValue) {
1844                                         if (TypeManager.void_decimal_ctor_long_arg == null) {
1845                                                 TypeManager.void_decimal_ctor_long_arg = TypeManager.GetPredefinedConstructor (
1846                                                         TypeManager.decimal_type, loc, TypeManager.int64_type);
1847
1848                                                 if (TypeManager.void_decimal_ctor_long_arg == null)
1849                                                         return;
1850                                         }
1851
1852                                         ec.EmitLong ((long) Value);
1853                                         ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_long_arg);
1854                                         return;
1855                                 }
1856                         }
1857
1858                         ec.EmitInt (words [0]);
1859                         ec.EmitInt (words [1]);
1860                         ec.EmitInt (words [2]);
1861
1862                         // sign
1863                         ec.EmitInt (words [3] >> 31);
1864
1865                         // power
1866                         ec.EmitInt (power);
1867
1868                         if (TypeManager.void_decimal_ctor_five_args == null) {
1869                                 TypeManager.void_decimal_ctor_five_args = TypeManager.GetPredefinedConstructor (
1870                                         TypeManager.decimal_type, loc, TypeManager.int32_type, TypeManager.int32_type,
1871                                         TypeManager.int32_type, TypeManager.bool_type, TypeManager.byte_type);
1872
1873                                 if (TypeManager.void_decimal_ctor_five_args == null)
1874                                         return;
1875                         }
1876
1877                         ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
1878                 }
1879
1880                 public override bool IsDefaultValue {
1881                         get {
1882                                 return Value == 0;
1883                         }
1884                 }
1885
1886                 public override bool IsNegative {
1887                         get {
1888                                 return Value < 0;
1889                         }
1890                 }
1891
1892                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1893                 {
1894                         switch (target_type.BuildinType) {
1895                         case BuildinTypeSpec.Type.SByte:
1896                                 return new SByteConstant ((sbyte) Value, loc);
1897                         case BuildinTypeSpec.Type.Byte:
1898                                 return new ByteConstant ((byte) Value, loc);
1899                         case BuildinTypeSpec.Type.Short:
1900                                 return new ShortConstant ((short) Value, loc);
1901                         case BuildinTypeSpec.Type.UShort:
1902                                 return new UShortConstant ((ushort) Value, loc);
1903                         case BuildinTypeSpec.Type.Int:
1904                                 return new IntConstant ((int) Value, loc);
1905                         case BuildinTypeSpec.Type.UInt:
1906                                 return new UIntConstant ((uint) Value, loc);
1907                         case BuildinTypeSpec.Type.Long:
1908                                 return new LongConstant ((long) Value, loc);
1909                         case BuildinTypeSpec.Type.ULong:
1910                                 return new ULongConstant ((ulong) Value, loc);
1911                         case BuildinTypeSpec.Type.Char:
1912                                 return new CharConstant ((char) Value, loc);
1913                         case BuildinTypeSpec.Type.Float:
1914                                 return new FloatConstant ((float) Value, loc);
1915                         case BuildinTypeSpec.Type.Double:
1916                                 return new DoubleConstant ((double) Value, loc);
1917                         }
1918
1919                         return null;
1920                 }
1921
1922                 public override object GetValue ()
1923                 {
1924                         return Value;
1925                 }
1926
1927                 public override string GetValueAsLiteral ()
1928                 {
1929                         return Value.ToString () + "M";
1930                 }
1931
1932                 public override long GetValueAsLong ()
1933                 {
1934                         throw new NotSupportedException ();
1935                 }
1936         }
1937
1938         public class StringConstant : Constant {
1939                 public readonly string Value;
1940
1941                 public StringConstant (string s, Location loc):
1942                         base (loc)
1943                 {
1944                         Value = s;
1945                 }
1946
1947                 protected override Expression DoResolve (ResolveContext rc)
1948                 {
1949                         type = TypeManager.string_type;
1950                         eclass = ExprClass.Value;
1951                         return this;
1952                 }
1953
1954                 public override object GetValue ()
1955                 {
1956                         return Value;
1957                 }
1958
1959                 public override string GetValueAsLiteral ()
1960                 {
1961                         // FIXME: Escape the string.
1962                         return "\"" + Value + "\"";
1963                 }
1964
1965                 public override long GetValueAsLong ()
1966                 {
1967                         throw new NotSupportedException ();
1968                 }
1969                 
1970                 public override void Emit (EmitContext ec)
1971                 {
1972                         if (Value == null) {
1973                                 ec.Emit (OpCodes.Ldnull);
1974                                 return;
1975                         }
1976
1977                         //
1978                         // Use string.Empty for both literals and constants even if
1979                         // it's not allowed at language level
1980                         //
1981                         if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize && ec.CurrentType != TypeManager.string_type) {
1982                                 if (TypeManager.string_empty == null)
1983                                         TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc, TypeManager.string_type);
1984
1985                                 if (TypeManager.string_empty != null) {
1986                                         ec.Emit (OpCodes.Ldsfld, TypeManager.string_empty);
1987                                         return;
1988                                 }
1989                         }
1990
1991                         ec.Emit (OpCodes.Ldstr, Value);
1992                 }
1993
1994                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1995                 {
1996                         // cast to object
1997                         if (type != targetType)
1998                                 enc.Encode (type);
1999
2000                         enc.Encode (Value);
2001                 }
2002
2003                 public override bool IsDefaultValue {
2004                         get {
2005                                 return Value == null;
2006                         }
2007                 }
2008
2009                 public override bool IsNegative {
2010                         get {
2011                                 return false;
2012                         }
2013                 }
2014
2015                 public override bool IsNull {
2016                         get {
2017                                 return IsDefaultValue;
2018                         }
2019                 }
2020
2021                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2022                 {
2023                         return null;
2024                 }
2025         }
2026
2027         //
2028         // Null constant can have its own type, think of `default (Foo)'
2029         //
2030         public class NullConstant : Constant
2031         {
2032                 public NullConstant (TypeSpec type, Location loc)
2033                         : base (loc)
2034                 {
2035                         eclass = ExprClass.Value;
2036                         this.type = type;
2037                 }
2038
2039                 public override Expression CreateExpressionTree (ResolveContext ec)
2040                 {
2041                         if (type == InternalType.Null || type == TypeManager.object_type) {
2042                                 // Optimized version, also avoids referencing literal internal type
2043                                 Arguments args = new Arguments (1);
2044                                 args.Add (new Argument (this));
2045                                 return CreateExpressionFactoryCall (ec, "Constant", args);
2046                         }
2047
2048                         return base.CreateExpressionTree (ec);
2049                 }
2050
2051                 protected override Expression DoResolve (ResolveContext ec)
2052                 {
2053                         return this;
2054                 }
2055
2056                 public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2057                 {
2058                         // Type it as string cast
2059                         if (targetType.BuildinType == BuildinTypeSpec.Type.Object || targetType == InternalType.Null)
2060                                 enc.Encode (TypeManager.string_type);
2061
2062                         var ac = targetType as ArrayContainer;
2063                         if (ac != null) {
2064                                 if (ac.Rank != 1 || ac.Element.IsArray)
2065                                         base.EncodeAttributeValue (rc, enc, targetType);
2066                                 else
2067                                         enc.Encode (uint.MaxValue);
2068                         } else {
2069                                 enc.Encode (byte.MaxValue);
2070                         }
2071                 }
2072
2073                 public override void Emit (EmitContext ec)
2074                 {
2075                         ec.Emit (OpCodes.Ldnull);
2076
2077                         // Only to make verifier happy
2078                         if (TypeManager.IsGenericParameter (type))
2079                                 ec.Emit (OpCodes.Unbox_Any, type);
2080                 }
2081
2082                 public override string ExprClassName {
2083                         get {
2084                                 return GetSignatureForError ();
2085                         }
2086                 }
2087
2088                 public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2089                 {
2090                         if (targetType.IsPointer) {
2091                                 if (IsLiteral || this is NullPointer)
2092                                         return new EmptyConstantCast (new NullPointer (loc), targetType);
2093
2094                                 return null;
2095                         }
2096
2097                         // Exlude internal compiler types
2098                         if (targetType.Kind == MemberKind.InternalCompilerType && targetType != InternalType.Dynamic && targetType != InternalType.Null)
2099                                 return null;
2100
2101                         if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2102                                 return null;
2103
2104                         if (TypeManager.IsReferenceType (targetType))
2105                                 return new NullConstant (targetType, loc);
2106
2107                         if (TypeManager.IsNullableType (targetType))
2108                                 return Nullable.LiftedNull.Create (targetType, loc);
2109
2110                         return null;
2111                 }
2112
2113                 public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec targetType)
2114                 {
2115                         return ConvertExplicitly (false, targetType);
2116                 }
2117
2118                 public override string GetSignatureForError ()
2119                 {
2120                         return "null";
2121                 }
2122
2123                 public override object GetValue ()
2124                 {
2125                         return null;
2126                 }
2127
2128                 public override string GetValueAsLiteral ()
2129                 {
2130                         return GetSignatureForError ();
2131                 }
2132
2133                 public override long GetValueAsLong ()
2134                 {
2135                         throw new NotSupportedException ();
2136                 }
2137
2138                 public override bool IsDefaultValue {
2139                         get { return true; }
2140                 }
2141
2142                 public override bool IsNegative {
2143                         get { return false; }
2144                 }
2145
2146                 public override bool IsNull {
2147                         get { return true; }
2148                 }
2149
2150                 public override bool IsZeroInteger {
2151                         get { return true; }
2152                 }
2153         }
2154
2155         /// <summary>
2156         ///   The value is constant, but when emitted has a side effect.  This is
2157         ///   used by BitwiseAnd to ensure that the second expression is invoked
2158         ///   regardless of the value of the left side.  
2159         /// </summary>
2160         public class SideEffectConstant : Constant {
2161                 public Constant value;
2162                 Expression side_effect;
2163                 
2164                 public SideEffectConstant (Constant value, Expression side_effect, Location loc) : base (loc)
2165                 {
2166                         this.value = value;
2167                         while (side_effect is SideEffectConstant)
2168                                 side_effect = ((SideEffectConstant) side_effect).side_effect;
2169                         this.side_effect = side_effect;
2170                 }
2171
2172                 protected override Expression DoResolve (ResolveContext rc)
2173                 {
2174                         value = value.Resolve (rc);
2175
2176                         type = value.Type;
2177                         eclass = ExprClass.Value;
2178                         return this;
2179                 }
2180
2181                 public override object GetValue ()
2182                 {
2183                         return value.GetValue ();
2184                 }
2185
2186                 public override string GetValueAsLiteral ()
2187                 {
2188                         return value.GetValueAsLiteral ();
2189                 }
2190
2191                 public override long GetValueAsLong ()
2192                 {
2193                         return value.GetValueAsLong ();
2194                 }
2195
2196                 public override void Emit (EmitContext ec)
2197                 {
2198                         side_effect.EmitSideEffect (ec);
2199                         value.Emit (ec);
2200                 }
2201
2202                 public override void EmitSideEffect (EmitContext ec)
2203                 {
2204                         side_effect.EmitSideEffect (ec);
2205                         value.EmitSideEffect (ec);
2206                 }
2207
2208                 public override bool IsDefaultValue {
2209                         get { return value.IsDefaultValue; }
2210                 }
2211
2212                 public override bool IsNegative {
2213                         get { return value.IsNegative; }
2214                 }
2215
2216                 public override bool IsZeroInteger {
2217                         get { return value.IsZeroInteger; }
2218                 }
2219
2220                 public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2221                 {
2222                         Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2223                         if (new_value == null)
2224                                 return null;
2225
2226                         var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2227                         c.type = target_type;
2228                         c.eclass = eclass;
2229                         return c;
2230                 }
2231         }
2232 }