PageRenderTime 121ms CodeModel.GetById 17ms app.highlight 92ms RepoModel.GetById 1ms app.codeStats 1ms

/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs

http://github.com/icsharpcode/ILSpy
C# | 2496 lines | 2030 code | 358 blank | 108 comment | 389 complexity | 8d98d5b9f24e6fb154dec2af4eab76ca MD5 | raw file

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file