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