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