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