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