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