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