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