Wiring of BuildinType
[mono.git] / mcs / mcs / constant.cs
index c0b0ca72526f4df346ee416d9b9fcd77bef48b57..cab0daa3b7fc33278242e5baae6c074d9abed3bf 100644 (file)
 //
 
 using System;
+
+#if STATIC
+using IKVM.Reflection.Emit;
+#else
 using System.Reflection.Emit;
+#endif
 
 namespace Mono.CSharp {
 
@@ -24,19 +29,9 @@ namespace Mono.CSharp {
                        this.loc = loc;
                }
 
-               /// <remarks>
-               ///   This is different from ToString in that ToString
-               ///   is supposed to be there for debugging purposes,
-               ///   and is not guaranteed to be useful for anything else,
-               ///   AsString() will provide something that can be used
-               ///   for round-tripping C# code.  Maybe it can be used
-               ///   for IL assembly as well.
-               /// </remarks>
-               public abstract string AsString ();
-
                override public string ToString ()
                {
-                       return this.GetType ().Name + " (" + AsString () + ")";
+                       return this.GetType ().Name + " (" + GetValueAsLiteral () + ")";
                }
 
                /// <summary>
@@ -45,10 +40,19 @@ namespace Mono.CSharp {
                /// </summary>
                public abstract object GetValue ();
 
+               public abstract long GetValueAsLong ();
+
+               public abstract string GetValueAsLiteral ();
+
+#if !STATIC
+               //
+               // Returns an object value which is typed to contant type
+               //
                public virtual object GetTypedValue ()
                {
                        return GetValue ();
                }
+#endif
 
                public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
                {
@@ -56,7 +60,7 @@ namespace Mono.CSharp {
                                (TypeManager.IsPrimitiveType (target) || type == TypeManager.decimal_type) &&
                                (TypeManager.IsPrimitiveType (type) || type == TypeManager.decimal_type)) {
                                ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
-                                       AsString (), TypeManager.CSharpName (target));
+                                       GetValueAsLiteral (), TypeManager.CSharpName (target));
                        } else {
                                base.Error_ValueCannotBeConverted (ec, loc, target, expl);
                        }
@@ -103,38 +107,44 @@ namespace Mono.CSharp {
 
                public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
                {
-                       if (t == TypeManager.int32_type)
-                               return new IntConstant ((int) v, loc);
-                       if (t == TypeManager.string_type)
-                               return new StringConstant ((string) v, loc);
-                       if (t == TypeManager.uint32_type)
-                               return new UIntConstant ((uint) v, loc);
-                       if (t == TypeManager.int64_type)
-                               return new LongConstant ((long) v, loc);
-                       if (t == TypeManager.uint64_type)
-                               return new ULongConstant ((ulong) v, loc);
-                       if (t == TypeManager.float_type)
-                               return new FloatConstant ((float) v, loc);
-                       if (t == TypeManager.double_type)
-                               return new DoubleConstant ((double) v, loc);
-                       if (t == TypeManager.short_type)
-                               return new ShortConstant ((short)v, loc);
-                       if (t == TypeManager.ushort_type)
-                               return new UShortConstant ((ushort)v, loc);
-                       if (t == TypeManager.sbyte_type)
-                               return new SByteConstant ((sbyte)v, loc);
-                       if (t == TypeManager.byte_type)
-                               return new ByteConstant ((byte)v, loc);
-                       if (t == TypeManager.char_type)
-                               return new CharConstant ((char)v, loc);
-                       if (t == TypeManager.bool_type)
-                               return new BoolConstant ((bool) v, loc);
-                       if (t == TypeManager.decimal_type)
-                               return new DecimalConstant ((decimal) v, loc);
-                       if (TypeManager.IsEnumType (t)) {
+                       if (t.BuildinType > 0) {
+                               switch (t.BuildinType) {
+                               case BuildinTypeSpec.Type.Int:
+                                       return new IntConstant ((int) v, loc);
+                               case BuildinTypeSpec.Type.String:
+                                       return new StringConstant ((string) v, loc);
+                               case BuildinTypeSpec.Type.UInt:
+                                       return new UIntConstant ((uint) v, loc);
+                               case BuildinTypeSpec.Type.Long:
+                                       return new LongConstant ((long) v, loc);
+                               case BuildinTypeSpec.Type.ULong:
+                                       return new ULongConstant ((ulong) v, loc);
+                               case BuildinTypeSpec.Type.Float:
+                                       return new FloatConstant ((float) v, loc);
+                               case BuildinTypeSpec.Type.Double:
+                                       return new DoubleConstant ((double) v, loc);
+                               case BuildinTypeSpec.Type.Short:
+                                       return new ShortConstant ((short) v, loc);
+                               case BuildinTypeSpec.Type.UShort:
+                                       return new UShortConstant ((ushort) v, loc);
+                               case BuildinTypeSpec.Type.SByte:
+                                       return new SByteConstant ((sbyte) v, loc);
+                               case BuildinTypeSpec.Type.Byte:
+                                       return new ByteConstant ((byte) v, loc);
+                               case BuildinTypeSpec.Type.Char:
+                                       return new CharConstant ((char) v, loc);
+                               case BuildinTypeSpec.Type.Bool:
+                                       return new BoolConstant ((bool) v, loc);
+                               case BuildinTypeSpec.Type.Decimal:
+                                       return new DecimalConstant ((decimal) v, loc);
+                               }
+                       }
+
+                       if (t.IsEnum) {
                                var real_type = EnumSpec.GetUnderlyingType (t);
                                return new EnumConstant (CreateConstantFromValue (real_type, v, loc).Resolve (null), t);
                        }
+
                        if (v == null) {
                                if (TypeManager.IsNullableType (t))
                                        return Nullable.LiftedNull.Create (t, loc);
@@ -173,9 +183,10 @@ namespace Mono.CSharp {
                                return TryReduce (ec, target_type);
                        }
                        catch (OverflowException) {
-                               if (ec.ConstantCheckState) {                            
-                                       ec.Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
-                                               GetValue ().ToString (), TypeManager.CSharpName (target_type));
+                               if (ec.ConstantCheckState && Type.BuildinType != BuildinTypeSpec.Type.Decimal) {
+                                       ec.Report.Error (221, loc,
+                                               "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
+                                               GetValueAsLiteral (), target_type.GetSignatureForError ());
                                } else {
                                        Error_ValueCannotBeConverted (ec, loc, target_type, false);
                                }
@@ -262,7 +273,11 @@ namespace Mono.CSharp {
 
                public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
                {
+#if STATIC
+                       return base.MakeExpression (ctx);
+#else
                        return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
+#endif
                }
 
                public new Constant Resolve (ResolveContext rc)
@@ -306,6 +321,11 @@ namespace Mono.CSharp {
                                        GetValue ().ToString (), TypeManager.CSharpName (target));
                        }
                }
+
+               public override string GetValueAsLiteral ()
+               {
+                       return GetValue ().ToString ();
+               }
                
                public abstract Constant Increment ();
        }
@@ -319,11 +339,6 @@ namespace Mono.CSharp {
                        Value = val;
                }
 
-               override public string AsString ()
-               {
-                       return Value ? "true" : "false";
-               }
-
                protected override Expression DoResolve (ResolveContext ec)
                {
                        type = TypeManager.bool_type;
@@ -336,9 +351,19 @@ namespace Mono.CSharp {
                        return (object) Value;
                }
 
+               public override string GetValueAsLiteral ()
+               {
+                       return Value ? "true" : "false";
+               }
+
+               public override long GetValueAsLong ()
+               {
+                       return Value ? 1 : 0;
+               }
+
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
                
                public override void Emit (EmitContext ec)
@@ -372,7 +397,8 @@ namespace Mono.CSharp {
 
        }
 
-       public class ByteConstant : IntegralConstant {
+       public class ByteConstant : IntegralConstant
+       {
                public readonly byte Value;
 
                public ByteConstant (byte v, Location loc):
@@ -383,7 +409,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -391,11 +417,6 @@ namespace Mono.CSharp {
                        ec.EmitInt (Value);
                }
 
-               public override string AsString ()
-               {
-                       return Value.ToString ();
-               }
-
                protected override Expression DoResolve (ResolveContext ec)
                {
                        type = TypeManager.byte_type;
@@ -408,6 +429,11 @@ namespace Mono.CSharp {
                        return Value;
                }
 
+               public override long GetValueAsLong ()
+               {
+                       return Value;
+               }
+
                public override Constant Increment ()
                {
                        return new ByteConstant (checked ((byte)(Value + 1)), loc);
@@ -437,33 +463,34 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.sbyte_type) {
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.SByte:
                                if (in_checked_context){
                                        if (Value > SByte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type)
+                       case BuildinTypeSpec.Type.Short:
                                return new ShortConstant ((short) Value, Location);
-                       if (target_type == TypeManager.ushort_type)
+                       case BuildinTypeSpec.Type.UShort:
                                return new UShortConstant ((ushort) Value, Location);
-                       if (target_type == TypeManager.int32_type)
+                       case BuildinTypeSpec.Type.Int:
                                return new IntConstant ((int) Value, Location);
-                       if (target_type == TypeManager.uint32_type)
+                       case BuildinTypeSpec.Type.UInt:
                                return new UIntConstant ((uint) Value, Location);
-                       if (target_type == TypeManager.int64_type)
+                       case BuildinTypeSpec.Type.Long:
                                return new LongConstant ((long) Value, Location);
-                       if (target_type == TypeManager.uint64_type)
+                       case BuildinTypeSpec.Type.ULong:
                                return new ULongConstant ((ulong) Value, Location);
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type)
+                       case BuildinTypeSpec.Type.Char:
                                return new CharConstant ((char) Value, Location);
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -488,7 +515,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write ((ushort) Value);
+                       enc.Encode ((ushort) Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -525,16 +552,21 @@ namespace Mono.CSharp {
                        return c.ToString ();
                }
 
-               public override string AsString ()
+               public override object GetValue ()
                {
-                       return "\"" + descape (Value) + "\"";
+                       return Value;
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
                        return Value;
                }
 
+               public override string GetValueAsLiteral ()
+               {
+                       return "\"" + descape (Value) + "\"";
+               }
+
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
@@ -553,41 +585,41 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
-                               if (in_checked_context){
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
+                               if (in_checked_context) {
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.SByte:
+                               if (in_checked_context) {
                                        if (Value > SByte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type) {
-                               if (in_checked_context){
+
+                       case BuildinTypeSpec.Type.Short:
+                               if (in_checked_context) {
                                        if (Value > Int16.MaxValue)
                                                throw new OverflowException ();
-                               }                                       
+                               }
                                return new ShortConstant ((short) Value, Location);
-                       }
-                       if (target_type == TypeManager.int32_type)
+                       case BuildinTypeSpec.Type.Int:
                                return new IntConstant ((int) Value, Location);
-                       if (target_type == TypeManager.uint32_type)
+                       case BuildinTypeSpec.Type.UInt:
                                return new UIntConstant ((uint) Value, Location);
-                       if (target_type == TypeManager.int64_type)
+                       case BuildinTypeSpec.Type.Long:
                                return new LongConstant ((long) Value, Location);
-                       if (target_type == TypeManager.uint64_type)
+                       case BuildinTypeSpec.Type.ULong:
                                return new ULongConstant ((ulong) Value, Location);
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -612,7 +644,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -620,12 +652,12 @@ namespace Mono.CSharp {
                        ec.EmitInt (Value);
                }
 
-               public override string AsString ()
+               public override object GetValue ()
                {
-                       return Value.ToString ();
+                       return Value;
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
                        return Value;
                }
@@ -659,41 +691,40 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type)
+                       case BuildinTypeSpec.Type.Short:
                                return new ShortConstant ((short) Value, Location);
-                       if (target_type == TypeManager.ushort_type) {
+                       case BuildinTypeSpec.Type.UShort:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new UShortConstant ((ushort) Value, Location);
-                       } if (target_type == TypeManager.int32_type)
-                                 return new IntConstant ((int) Value, Location);
-                       if (target_type == TypeManager.uint32_type) {
+                       case BuildinTypeSpec.Type.Int:
+                               return new IntConstant ((int) Value, Location);
+                       case BuildinTypeSpec.Type.UInt:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new UIntConstant ((uint) Value, Location);
-                       } if (target_type == TypeManager.int64_type)
-                                 return new LongConstant ((long) Value, Location);
-                       if (target_type == TypeManager.uint64_type) {
+                       case BuildinTypeSpec.Type.Long:
+                               return new LongConstant ((long) Value, Location);
+                       case BuildinTypeSpec.Type.ULong:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new ULongConstant ((ulong) Value, Location);
-                       }
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type) {
+                       case BuildinTypeSpec.Type.Char:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -718,7 +749,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -726,12 +757,12 @@ namespace Mono.CSharp {
                        ec.EmitInt (Value);
                }
 
-               public override string AsString ()
+               public override object GetValue ()
                {
-                       return Value.ToString ();
+                       return Value;
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
                        return Value;
                }
@@ -765,60 +796,57 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
-                               if (in_checked_context){
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
+                               if (in_checked_context) {
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.SByte:
+                               if (in_checked_context) {
                                        if (Value < SByte.MinValue || Value > SByte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.ushort_type) {
+                       case BuildinTypeSpec.Type.UShort:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
-                               
+
                                return new UShortConstant ((ushort) Value, Location);
-                       }
-                       if (target_type == TypeManager.int32_type)
+                       case BuildinTypeSpec.Type.Int:
                                return new IntConstant ((int) Value, Location);
-                       if (target_type == TypeManager.uint32_type) {
+                       case BuildinTypeSpec.Type.UInt:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new UIntConstant ((uint) Value, Location);
-                       }
-                       if (target_type == TypeManager.int64_type)
+                       case BuildinTypeSpec.Type.Long:
                                return new LongConstant ((long) Value, Location);
-                       if (target_type == TypeManager.uint64_type) {
+                       case BuildinTypeSpec.Type.ULong:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new ULongConstant ((ulong) Value, Location);
-                       }
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Char:
+                               if (in_checked_context) {
                                        if (Value < Char.MinValue)
                                                throw new OverflowException ();
                                }
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
 
        }
 
-       public class UShortConstant : IntegralConstant {
+       public class UShortConstant : IntegralConstant
+       {
                public readonly ushort Value;
 
                public UShortConstant (ushort v, Location loc):
@@ -836,7 +864,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -844,12 +872,12 @@ namespace Mono.CSharp {
                        ec.EmitInt (Value);
                }
 
-               public override string AsString ()
+               public override object GetValue ()
                {
-                       return Value.ToString ();
+                       return Value;
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
                        return Value;
                }
@@ -883,48 +911,46 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
-                               if (in_checked_context){
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
+                               if (in_checked_context) {
                                        if (Value > Byte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.SByte:
+                               if (in_checked_context) {
                                        if (Value > SByte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Short:
+                               if (in_checked_context) {
                                        if (Value > Int16.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ShortConstant ((short) Value, Location);
-                       }
-                       if (target_type == TypeManager.int32_type)
+                       case BuildinTypeSpec.Type.Int:
                                return new IntConstant ((int) Value, Location);
-                       if (target_type == TypeManager.uint32_type)
+                       case BuildinTypeSpec.Type.UInt:
                                return new UIntConstant ((uint) Value, Location);
-                       if (target_type == TypeManager.int64_type)
+                       case BuildinTypeSpec.Type.Long:
                                return new LongConstant ((long) Value, Location);
-                       if (target_type == TypeManager.uint64_type)
+                       case BuildinTypeSpec.Type.ULong:
                                return new ULongConstant ((ulong) Value, Location);
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Char:
+                               if (in_checked_context) {
                                        if (Value > Char.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -948,7 +974,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -956,12 +982,12 @@ namespace Mono.CSharp {
                        ec.EmitInt (Value);
                }
 
-               public override string AsString ()
+               public override object GetValue ()
                {
-                       return Value.ToString ();
+                       return Value;
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
                        return Value;
                }
@@ -995,61 +1021,56 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
-                               if (in_checked_context){
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
+                               if (in_checked_context) {
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.SByte:
+                               if (in_checked_context) {
                                        if (Value < SByte.MinValue || Value > SByte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Short:
+                               if (in_checked_context) {
                                        if (Value < Int16.MinValue || Value > Int16.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ShortConstant ((short) Value, Location);
-                       }
-                       if (target_type == TypeManager.ushort_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UShort:
+                               if (in_checked_context) {
                                        if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new UShortConstant ((ushort) Value, Location);
-                       }
-                       if (target_type == TypeManager.uint32_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UInt:
+                               if (in_checked_context) {
                                        if (Value < UInt32.MinValue)
                                                throw new OverflowException ();
                                }
                                return new UIntConstant ((uint) Value, Location);
-                       }
-                       if (target_type == TypeManager.int64_type)
+                       case BuildinTypeSpec.Type.Long:
                                return new LongConstant ((long) Value, Location);
-                       if (target_type == TypeManager.uint64_type) {
+                       case BuildinTypeSpec.Type.ULong:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new ULongConstant ((ulong) Value, Location);
-                       }
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Char:
+                               if (in_checked_context) {
                                        if (Value < Char.MinValue || Value > Char.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -1073,27 +1094,28 @@ namespace Mono.CSharp {
                /// </summary>
                Constant TryImplicitIntConversion (TypeSpec target_type)
                {
-                       if (target_type == TypeManager.sbyte_type) {
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.SByte:
                                if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
                                        return new SByteConstant ((sbyte) Value, loc);
-                       } 
-                       else if (target_type == TypeManager.byte_type) {
+                               break;
+                       case BuildinTypeSpec.Type.Byte:
                                if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
                                        return new ByteConstant ((byte) Value, loc);
-                       } 
-                       else if (target_type == TypeManager.short_type) {
+                               break;
+                       case BuildinTypeSpec.Type.Short:
                                if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
                                        return new ShortConstant ((short) Value, loc);
-                       } 
-                       else if (target_type == TypeManager.ushort_type) {
+                               break;
+                       case BuildinTypeSpec.Type.UShort:
                                if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
                                        return new UShortConstant ((ushort) Value, loc);
-                       } 
-                       else if (target_type == TypeManager.uint32_type) {
+                               break;
+                       case BuildinTypeSpec.Type.UInt:
                                if (Value >= 0)
                                        return new UIntConstant ((uint) Value, loc);
-                       } 
-                       else if (target_type == TypeManager.uint64_type) {
+                               break;
+                       case BuildinTypeSpec.Type.ULong:
                                //
                                // we can optimize this case: a positive int32
                                // always fits on a uint64.  But we need an opcode
@@ -1101,11 +1123,12 @@ namespace Mono.CSharp {
                                //
                                if (Value >= 0)
                                        return new ULongConstant ((ulong) Value, loc);
-                       } 
-                       else if (target_type == TypeManager.double_type)
+                               break;
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, loc);
-                       else if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, loc);
+                       }
 
                        return null;
                }
@@ -1129,7 +1152,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -1137,12 +1160,12 @@ namespace Mono.CSharp {
                        ec.EmitInt (unchecked ((int) Value));
                }
 
-               public override string AsString ()
+               public override object GetValue ()
                {
-                       return Value.ToString ();
+                       return Value;
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
                        return Value;
                }
@@ -1176,58 +1199,54 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
-                               if (in_checked_context){
-                                       if (Value < Char.MinValue || Value > Char.MaxValue)
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
+                               if (in_checked_context) {
+                                       if (Value < 0 || Value > byte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.SByte:
+                               if (in_checked_context) {
                                        if (Value > SByte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Short:
+                               if (in_checked_context) {
                                        if (Value > Int16.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ShortConstant ((short) Value, Location);
-                       }
-                       if (target_type == TypeManager.ushort_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UShort:
+                               if (in_checked_context) {
                                        if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new UShortConstant ((ushort) Value, Location);
-                       }
-                       if (target_type == TypeManager.int32_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Int:
+                               if (in_checked_context) {
                                        if (Value > Int32.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new IntConstant ((int) Value, Location);
-                       }
-                       if (target_type == TypeManager.int64_type)
+                       case BuildinTypeSpec.Type.Long:
                                return new LongConstant ((long) Value, Location);
-                       if (target_type == TypeManager.uint64_type)
+                       case BuildinTypeSpec.Type.ULong:
                                return new ULongConstant ((ulong) Value, Location);
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Char:
+                               if (in_checked_context) {
                                        if (Value < Char.MinValue || Value > Char.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -1252,7 +1271,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -1260,12 +1279,12 @@ namespace Mono.CSharp {
                        ec.EmitLong (Value);
                }
 
-               public override string AsString ()
+               public override object GetValue ()
                {
-                       return Value.ToString ();
+                       return Value;
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
                        return Value;
                }
@@ -1299,66 +1318,60 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
-                               if (in_checked_context){
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
+                               if (in_checked_context) {
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.SByte:
+                               if (in_checked_context) {
                                        if (Value < SByte.MinValue || Value > SByte.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Short:
+                               if (in_checked_context) {
                                        if (Value < Int16.MinValue || Value > Int16.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new ShortConstant ((short) Value, Location);
-                       }
-                       if (target_type == TypeManager.ushort_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UShort:
+                               if (in_checked_context) {
                                        if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new UShortConstant ((ushort) Value, Location);
-                       }
-                       if (target_type == TypeManager.int32_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Int:
+                               if (in_checked_context) {
                                        if (Value < Int32.MinValue || Value > Int32.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new IntConstant ((int) Value, Location);
-                       }
-                       if (target_type == TypeManager.uint32_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UInt:
+                               if (in_checked_context) {
                                        if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new UIntConstant ((uint) Value, Location);
-                       }
-                       if (target_type == TypeManager.uint64_type) {
+                       case BuildinTypeSpec.Type.ULong:
                                if (in_checked_context && Value < 0)
                                        throw new OverflowException ();
                                return new ULongConstant ((ulong) Value, Location);
-                       }
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Char:
+                               if (in_checked_context) {
                                        if (Value < Char.MinValue || Value > Char.MaxValue)
                                                throw new OverflowException ();
                                }
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -1391,7 +1404,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -1399,14 +1412,14 @@ namespace Mono.CSharp {
                        ec.EmitLong (unchecked ((long) Value));
                }
 
-               public override string AsString ()
+               public override object GetValue ()
                {
-                       return Value.ToString ();
+                       return Value;
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
-                       return Value;
+                       return (long) Value;
                }
 
                public override Constant Increment ()
@@ -1438,52 +1451,46 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
                                if (in_checked_context && Value > Byte.MaxValue)
                                        throw new OverflowException ();
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
+                       case BuildinTypeSpec.Type.SByte:
                                if (in_checked_context && Value > ((ulong) SByte.MaxValue))
                                        throw new OverflowException ();
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type) {
+                       case BuildinTypeSpec.Type.Short:
                                if (in_checked_context && Value > ((ulong) Int16.MaxValue))
                                        throw new OverflowException ();
                                return new ShortConstant ((short) Value, Location);
-                       }
-                       if (target_type == TypeManager.ushort_type) {
+                       case BuildinTypeSpec.Type.UShort:
                                if (in_checked_context && Value > UInt16.MaxValue)
                                        throw new OverflowException ();
                                return new UShortConstant ((ushort) Value, Location);
-                       }
-                       if (target_type == TypeManager.int32_type) {
+                       case BuildinTypeSpec.Type.Int:
                                if (in_checked_context && Value > UInt32.MaxValue)
                                        throw new OverflowException ();
                                return new IntConstant ((int) Value, Location);
-                       }
-                       if (target_type == TypeManager.uint32_type) {
-                               if  (in_checked_context && Value > UInt32.MaxValue)
+                       case BuildinTypeSpec.Type.UInt:
+                               if (in_checked_context && Value > UInt32.MaxValue)
                                        throw new OverflowException ();
                                return new UIntConstant ((uint) Value, Location);
-                       }
-                       if (target_type == TypeManager.int64_type) {
+                       case BuildinTypeSpec.Type.Long:
                                if (in_checked_context && Value > Int64.MaxValue)
                                        throw new OverflowException ();
                                return new LongConstant ((long) Value, Location);
-                       }
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type) {
+                       case BuildinTypeSpec.Type.Char:
                                if (in_checked_context && Value > Char.MaxValue)
                                        throw new OverflowException ();
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -1508,7 +1515,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -1516,14 +1523,19 @@ namespace Mono.CSharp {
                        ec.Emit (OpCodes.Ldc_R4, Value);
                }
 
-               public override string AsString ()
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override string GetValueAsLiteral ()
                {
                        return Value.ToString ();
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
-                       return Value;
+                       throw new NotSupportedException ();
                }
 
                public override bool IsDefaultValue {
@@ -1540,73 +1552,66 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
-                               if (in_checked_context){
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
+                               if (in_checked_context) {
                                        if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.SByte:
+                               if (in_checked_context) {
                                        if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Short:
+                               if (in_checked_context) {
                                        if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new ShortConstant ((short) Value, Location);
-                       }
-                       if (target_type == TypeManager.ushort_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UShort:
+                               if (in_checked_context) {
                                        if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new UShortConstant ((ushort) Value, Location);
-                       }
-                       if (target_type == TypeManager.int32_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Int:
+                               if (in_checked_context) {
                                        if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new IntConstant ((int) Value, Location);
-                       }
-                       if (target_type == TypeManager.uint32_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UInt:
+                               if (in_checked_context) {
                                        if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new UIntConstant ((uint) Value, Location);
-                       }
-                       if (target_type == TypeManager.int64_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Long:
+                               if (in_checked_context) {
                                        if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new LongConstant ((long) Value, Location);
-                       }
-                       if (target_type == TypeManager.uint64_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.ULong:
+                               if (in_checked_context) {
                                        if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new ULongConstant ((ulong) Value, Location);
-                       }
-                       if (target_type == TypeManager.double_type)
+                       case BuildinTypeSpec.Type.Double:
                                return new DoubleConstant ((double) Value, Location);
-                       if (target_type == TypeManager.char_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Char:
+                               if (in_checked_context) {
                                        if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -1631,7 +1636,7 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       enc.Stream.Write (Value);
+                       enc.Encode (Value);
                }
 
                public override void Emit (EmitContext ec)
@@ -1639,14 +1644,19 @@ namespace Mono.CSharp {
                        ec.Emit (OpCodes.Ldc_R8, Value);
                }
 
-               public override string AsString ()
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override string GetValueAsLiteral ()
                {
                        return Value.ToString ();
                }
 
-               public override object GetValue ()
+               public override long GetValueAsLong ()
                {
-                       return Value;
+                       throw new NotSupportedException ();
                }
 
                public override bool IsDefaultValue {
@@ -1663,73 +1673,66 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.byte_type) {
-                               if (in_checked_context){
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.Byte:
+                               if (in_checked_context) {
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new ByteConstant ((byte) Value, Location);
-                       }
-                       if (target_type == TypeManager.sbyte_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.SByte:
+                               if (in_checked_context) {
                                        if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new SByteConstant ((sbyte) Value, Location);
-                       }
-                       if (target_type == TypeManager.short_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Short:
+                               if (in_checked_context) {
                                        if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new ShortConstant ((short) Value, Location);
-                       }
-                       if (target_type == TypeManager.ushort_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UShort:
+                               if (in_checked_context) {
                                        if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new UShortConstant ((ushort) Value, Location);
-                       }
-                       if (target_type == TypeManager.int32_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Int:
+                               if (in_checked_context) {
                                        if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new IntConstant ((int) Value, Location);
-                       }
-                       if (target_type == TypeManager.uint32_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.UInt:
+                               if (in_checked_context) {
                                        if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new UIntConstant ((uint) Value, Location);
-                       }
-                       if (target_type == TypeManager.int64_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Long:
+                               if (in_checked_context) {
                                        if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new LongConstant ((long) Value, Location);
-                       }
-                       if (target_type == TypeManager.uint64_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.ULong:
+                               if (in_checked_context) {
                                        if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new ULongConstant ((ulong) Value, Location);
-                       }
-                       if (target_type == TypeManager.float_type)
+                       case BuildinTypeSpec.Type.Float:
                                return new FloatConstant ((float) Value, Location);
-                       if (target_type == TypeManager.char_type) {
-                               if (in_checked_context){
+                       case BuildinTypeSpec.Type.Char:
+                               if (in_checked_context) {
                                        if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
                                                throw new OverflowException ();
                                }
                                return new CharConstant ((char) Value, Location);
-                       }
-                       if (target_type == TypeManager.decimal_type)
+                       case BuildinTypeSpec.Type.Decimal:
                                return new DecimalConstant ((decimal) Value, Location);
+                       }
 
                        return null;
                }
@@ -1745,11 +1748,6 @@ namespace Mono.CSharp {
                        Value = d;
                }
 
-               override public string AsString ()
-               {
-                       return Value.ToString () + "M";
-               }
-
                protected override Expression DoResolve (ResolveContext rc)
                {
                        type = TypeManager.decimal_type;
@@ -1757,11 +1755,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override object GetValue ()
-               {
-                       return (object) Value;
-               }
-
                public override void Emit (EmitContext ec)
                {
                        int [] words = decimal.GetBits (Value);
@@ -1833,32 +1826,48 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
-                       if (target_type == TypeManager.sbyte_type)
-                               return new SByteConstant ((sbyte)Value, loc);
-                       if (target_type == TypeManager.byte_type)
-                               return new ByteConstant ((byte)Value, loc);
-                       if (target_type == TypeManager.short_type)
-                               return new ShortConstant ((short)Value, loc);
-                       if (target_type == TypeManager.ushort_type)
-                               return new UShortConstant ((ushort)Value, loc);
-                       if (target_type == TypeManager.int32_type)
-                               return new IntConstant ((int)Value, loc);
-                       if (target_type == TypeManager.uint32_type)
-                               return new UIntConstant ((uint)Value, loc);
-                       if (target_type == TypeManager.int64_type)
-                               return new LongConstant ((long)Value, loc);
-                       if (target_type == TypeManager.uint64_type)
-                               return new ULongConstant ((ulong)Value, loc);
-                       if (target_type == TypeManager.char_type)
-                               return new CharConstant ((char)Value, loc);
-                       if (target_type == TypeManager.float_type)
-                               return new FloatConstant ((float)Value, loc);
-                       if (target_type == TypeManager.double_type)
-                               return new DoubleConstant ((double)Value, loc);
+                       switch (target_type.BuildinType) {
+                       case BuildinTypeSpec.Type.SByte:
+                               return new SByteConstant ((sbyte) Value, loc);
+                       case BuildinTypeSpec.Type.Byte:
+                               return new ByteConstant ((byte) Value, loc);
+                       case BuildinTypeSpec.Type.Short:
+                               return new ShortConstant ((short) Value, loc);
+                       case BuildinTypeSpec.Type.UShort:
+                               return new UShortConstant ((ushort) Value, loc);
+                       case BuildinTypeSpec.Type.Int:
+                               return new IntConstant ((int) Value, loc);
+                       case BuildinTypeSpec.Type.UInt:
+                               return new UIntConstant ((uint) Value, loc);
+                       case BuildinTypeSpec.Type.Long:
+                               return new LongConstant ((long) Value, loc);
+                       case BuildinTypeSpec.Type.ULong:
+                               return new ULongConstant ((ulong) Value, loc);
+                       case BuildinTypeSpec.Type.Char:
+                               return new CharConstant ((char) Value, loc);
+                       case BuildinTypeSpec.Type.Float:
+                               return new FloatConstant ((float) Value, loc);
+                       case BuildinTypeSpec.Type.Double:
+                               return new DoubleConstant ((double) Value, loc);
+                       }
 
                        return null;
                }
 
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override string GetValueAsLiteral ()
+               {
+                       return Value.ToString () + "M";
+               }
+
+               public override long GetValueAsLong ()
+               {
+                       throw new NotSupportedException ();
+               }
        }
 
        public class StringConstant : Constant {
@@ -1870,12 +1879,6 @@ namespace Mono.CSharp {
                        Value = s;
                }
 
-               // FIXME: Escape the string.
-               override public string AsString ()
-               {
-                       return "\"" + Value + "\"";
-               }
-
                protected override Expression DoResolve (ResolveContext rc)
                {
                        type = TypeManager.string_type;
@@ -1887,6 +1890,17 @@ namespace Mono.CSharp {
                {
                        return Value;
                }
+
+               public override string GetValueAsLiteral ()
+               {
+                       // FIXME: Escape the string.
+                       return "\"" + Value + "\"";
+               }
+
+               public override long GetValueAsLong ()
+               {
+                       throw new NotSupportedException ();
+               }
                
                public override void Emit (EmitContext ec)
                {
@@ -1899,7 +1913,7 @@ namespace Mono.CSharp {
                        // Use string.Empty for both literals and constants even if
                        // it's not allowed at language level
                        //
-                       if (Value.Length == 0 && RootContext.Optimize && ec.CurrentType != TypeManager.string_type) {
+                       if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize && ec.CurrentType != TypeManager.string_type) {
                                if (TypeManager.string_empty == null)
                                        TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc, TypeManager.string_type);
 
@@ -1957,11 +1971,6 @@ namespace Mono.CSharp {
                        this.type = type;
                }
 
-               public override string AsString ()
-               {
-                       return GetSignatureForError ();
-               }
-
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        if (type == InternalType.Null || type == TypeManager.object_type) {
@@ -1990,9 +1999,9 @@ namespace Mono.CSharp {
                                if (ac.Rank != 1 || ac.Element.IsArray)
                                        base.EncodeAttributeValue (rc, enc, targetType);
                                else
-                                       enc.Stream.Write (uint.MaxValue);
+                                       enc.Encode (uint.MaxValue);
                        } else {
-                               enc.Stream.Write (byte.MaxValue);
+                               enc.Encode (byte.MaxValue);
                        }
                }
 
@@ -2011,11 +2020,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override string GetSignatureForError ()
-               {
-                       return "null";
-               }
-
                public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
                {
                        if (targetType.IsPointer) {
@@ -2046,11 +2050,26 @@ namespace Mono.CSharp {
                        return ConvertExplicitly (false, targetType);
                }
 
+               public override string GetSignatureForError ()
+               {
+                       return "null";
+               }
+
                public override object GetValue ()
                {
                        return null;
                }
 
+               public override string GetValueAsLiteral ()
+               {
+                       return GetSignatureForError ();
+               }
+
+               public override long GetValueAsLong ()
+               {
+                       throw new NotSupportedException ();
+               }
+
                public override bool IsDefaultValue {
                        get { return true; }
                }
@@ -2085,11 +2104,6 @@ namespace Mono.CSharp {
                        this.side_effect = side_effect;
                }
 
-               public override string AsString ()
-               {
-                       return value.AsString ();
-               }
-
                protected override Expression DoResolve (ResolveContext rc)
                {
                        value = value.Resolve (rc);
@@ -2104,6 +2118,16 @@ namespace Mono.CSharp {
                        return value.GetValue ();
                }
 
+               public override string GetValueAsLiteral ()
+               {
+                       return value.GetValueAsLiteral ();
+               }
+
+               public override long GetValueAsLong ()
+               {
+                       return value.GetValueAsLong ();
+               }
+
                public override void Emit (EmitContext ec)
                {
                        side_effect.EmitSideEffect (ec);
@@ -2131,7 +2155,13 @@ namespace Mono.CSharp {
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
-                       return new_value == null ? null : new SideEffectConstant (new_value, side_effect, new_value.Location);
+                       if (new_value == null)
+                               return null;
+
+                       var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
+                       c.type = target_type;
+                       c.eclass = eclass;
+                       return c;
                }
        }
 }