2005-08-16 Marek Safar <marek.safar@seznam.cz>
authorMarek Safar <marek.safar@gmail.com>
Tue, 16 Aug 2005 09:21:41 +0000 (09:21 -0000)
committerMarek Safar <marek.safar@gmail.com>
Tue, 16 Aug 2005 09:21:41 +0000 (09:21 -0000)
The big constants rewrite
Fix #75746, #75685 and more
As a side effect saved 1MB for MWF ;-)

* attribute.cs (GetAttributeArgumentExpression): Use ToType, GetTypedValue.
(GetMarshal, GetMethodImplOptions, GetLayoutKindValue): Values are not
enum based for corlib compilation.

* cfold.cs (BinaryFold): Convert operand for enum additions. Fixed enum
subtractions.

* class.cs (FixedField.Define): Use ResolveAsConstant.

* const.cs (IConstant): Interface constants and enums.
(Const.ResolveValue): New method for constant resolvning.
(ExternalConstant): Constants from imported assemblies.

* constant.cs (Constant.GetTypedValue): Used to get constant with forced
conversion; like enums.
(Constant.ToType): Converts this constant to different type.
(Constant.Increment): Adds 1.

* convert.cs (ImplicitConversionRequired): Simplified.

* cs-parser.jay: Create EnumMember directly.

* decl.cs (MemberCore.CheckObsoleteness): Checks for ObsoleteAttribute presence.

* doc.cs (GenerateEnumDocComment): Removed.

* ecore.cs (Expression.ResolveAsConstant): New constant specific method.
(ConvertIntLiteral): Removed.
(FieldExpr.ResolveMemberAccess): Refactored to remove constant specific if(s).

* enum.cs (EnumMember): Implement IConstant.
(Enum.IsValidEnumConstant): Removed.
(Enum.GetNextDefaultValue): Removed.
(Enum.FindMembers): Updated.
(Enum.GenerateDocComment): Iterate enum members.

* expression.cs (Cast.TryReduce): Handle enums correctly.
(New.Constantify): Made public.
(MemberAccess.DoResolve): Removed contant specific if(s).

* literal.cs (NullLiteral): Implement new abstract methods.

* statement.cs (GotoCase.Resolve): Use new constant methods.
(SwitchLabel.ResolveAndReduce): Use new constant methods.

* typemanager.cs (LookupEnum): Removed.
(IsEnumType): Fixed to work with corlib.
(RegisterConstant): Removed.
(LookupConstant): Removed.
(GetConstant): Changed to work with IConstant.

svn path=/trunk/mcs/; revision=48416

34 files changed:
1  2 
mcs/errors/cs0019-10.cs
mcs/errors/cs0029-3.cs
mcs/errors/cs0037-3.cs
mcs/errors/cs0037-4.cs
mcs/errors/cs0110-2.cs
mcs/errors/cs0133-5.cs
mcs/errors/cs0159-3.cs
mcs/errors/cs0619-19.cs
mcs/errors/cs0619-39.cs
mcs/errors/cs0619-40.cs
mcs/errors/cs1008.cs
mcs/errors/known-issues-gmcs
mcs/errors/known-issues-mcs
mcs/mcs/ChangeLog
mcs/mcs/attribute.cs
mcs/mcs/cfold.cs
mcs/mcs/class.cs
mcs/mcs/const.cs
mcs/mcs/constant.cs
mcs/mcs/convert.cs
mcs/mcs/cs-parser.jay
mcs/mcs/decl.cs
mcs/mcs/doc.cs
mcs/mcs/ecore.cs
mcs/mcs/enum.cs
mcs/mcs/expression.cs
mcs/mcs/literal.cs
mcs/mcs/statement.cs
mcs/mcs/typemanager.cs
mcs/tests/Makefile
mcs/tests/known-issues-gmcs
mcs/tests/known-issues-mcs
mcs/tests/test-437.cs
mcs/tests/test-49.cs

index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..97b00d8f2ef1848f01a83f5e629cb13155831bc8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++// cs0019-10.cs: Operator `+' cannot be applied to operands of type `A' and `B'
++// Line : 20
++
++enum A
++{
++        A1,
++        A2
++}
++
++enum B
++{
++        B1,
++        B2
++}
++
++class C
++{
++        static void Main ()
++        {
++                System.Console.WriteLine (A.A1 - B.B1);
++        }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..63e490e8fe2638679c5f8bde692adba7953e9725
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,14 @@@
++// cs0029-3.cs: Cannot implicitly convert type `string' to `int'
++// Line : 7
++
++public class Blah {
++
++      public enum MyEnum {
++              Foo = "foo",
++              Bar
++      }
++
++      public static void Main ()
++      {
++      }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a19c609d9ce00395ac8f4ff7312e6109a310718b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,14 @@@
++// cs0031.cs: Constant value `256' cannot be converted to a `byte'
++// Line : 7
++
++public class Blah {
++
++      public enum MyEnum : byte {
++              Foo = null,
++              Bar
++      }
++
++      public static void Main ()
++      {
++      }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..84556c8fd2d186cef9e0a0e8d55bc5b6cf6a112a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++// cs0037-4.cs: Cannot convert null to `int' because it is a value type
++// Line: 9
++
++class X {
++      static void Main ()
++      {
++              int s = 44;
++              switch (s) {
++                      case null: break;
++              }
++      }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cb069f15e7d78798f9c58245fe282ffb8dba012a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++// cs0110.cs: The evaluation of the constant value for `E.a' involves a circular definition
++// Line: 6
++
++enum E
++{
++      a = b,
++      b = c,
++      c = a
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..da55726770636b70a80c7da9a71cf0d8b2939f32
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++// cs0133-5.cs: The expression being assigned to `i' must be constant
++// Line: 12
++
++class T
++{
++      const decimal[] i = new decimal [] { 2m };
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5cdf61320b1c9e09391234cb34815f82c62cdc17
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,14 @@@
++// cs0159-3.cs: No such label `case null:' within the scope of the goto statement
++// Line: 10
++
++class y {
++      static void Main ()
++      {
++              string x = null;
++
++              switch (x){
++                      case "": goto case null;
++              }
++      }
++}
++              
index 4d4a3b5e658c666b0c1c52c453795577b9b27e80,4d4a3b5e658c666b0c1c52c453795577b9b27e80..6c02d358e1d10dd89f6bbf7053838ccd5565fc62
@@@ -1,11 -1,11 +1,15 @@@
--// cs0619-19.cs: `MainClass' is obsolete: `'
--// Line: 8
++// cs0619-19.cs: `O' is obsolete: `'
++// Line: 12
  
  [System.Obsolete("", true)]
++class O
++{
++}
++
  class MainClass {
          public void Method ()
          {
--                lock (new MainClass ()) {
++                lock (new O ()) {
                  }
          }
  }
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..02d0d41c5a8d7a44a839b8b982789ee1665a617c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,16 @@@
++// cs0619-39.cs: `c.ob' is obsolete: `ooo'
++// Line: 13
++
++using System;
++
++class C
++{
++      [Obsolete("ooo", true)]
++      const int ob = 4;
++      
++    public int Prop {
++              get {
++                      return ob;
++              }
++      }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..edbb62177453b11711a2edaa9edf876366963e79
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,17 @@@
++// cs0619-39.cs: `c.ob' is obsolete: `ooo'
++// Line: 13
++
++using System;
++
++class C
++{
++      [Obsolete("ooo", true)]
++      const int ob = 4;
++
++      public void Test (int arg)
++      {
++              switch (arg) {
++                      case ob: return;
++              }
++      }
++}
diff --cc mcs/errors/cs1008.cs
index 8b0a10d5ccb54ac11f16cfd6f53152150491a760,8b0a10d5ccb54ac11f16cfd6f53152150491a760..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,14 -1,14 +1,0 @@@
--// cs1008.cs: Type byte, sbyte, short, ushort, int, uint, long or ulong expected
--// Line : 7
--
--public class Blah {
--
--      public enum MyEnum {
--              Foo = "foo",
--              Bar
--      }
--
--      public static void Main ()
--      {
--      }
--}
index 5a705b1d7c118bceabeaae2b2e239c578ea3e4af,4e52c20c85203580bdaef74dfd5595be619d6cb6..8e2b0af41c9066883ea6d347b525800c3329e986
  # csXXXX.cs NO ERROR  : error test case doesn't report any error. An exception is considered
  #                       as NO ERROR and CS5001 is automatically ignored.
  
++cs0029-3.cs
  cs0037-2.cs
++cs0037-3.cs
++cs0037-4.cs
  cs0118.cs
  cs0118-3.cs
  cs0118-4.cs
@@@ -20,6 -20,6 +23,7 @@@ cs0121-3.cs NO ERRO
  cs0122-17.cs NO ERROR
  cs0133-4.cs
  cs0136-6.cs NO ERROR
++cs0159-3.cs
  cs0201.cs
  cs0202.cs # new in GMCS
  cs0229-2.cs
@@@ -48,6 -48,6 +52,8 @@@ cs0548-4.c
  cs0548.cs
  cs0560.cs
  cs0567.cs
++cs0619-39.cs NO ERROR
++cs0619-40.cs NO ERROR
  cs0642-2.cs NO ERROR
  cs0642-3.cs
  cs0642-4.cs
index 6dd975ef1441a6198b3233aec74527ec2699b87a,6dd975ef1441a6198b3233aec74527ec2699b87a..99a9a0cd027727bbee44e414d32b2e13cfcc24b7
@@@ -27,6 -27,6 +27,7 @@@ cs0548-4.c
  cs0548.cs
  cs0560.cs
  cs0567.cs
++cs0619-31.cs NO ERROR
  cs0642.cs NO ERROR
  cs0642-2.cs NO ERROR
  cs0642-3.cs
index 5c915d3a8dbfb3207ee0dd3a1b8c669a87530778,5c915d3a8dbfb3207ee0dd3a1b8c669a87530778..ca6bf933140e9a9d2a06c0f256372f97ee60dad9
@@@ -1,3 -1,3 +1,60 @@@
++2005-08-16  Marek Safar  <marek.safar@seznam.cz>
++
++      The big constants rewrite
++      Fix #75746, #75685 and more
++      As a side effect saved 1MB for MWF ;-)
++      
++      * attribute.cs (GetAttributeArgumentExpression): Use ToType, GetTypedValue.
++      (GetMarshal, GetMethodImplOptions, GetLayoutKindValue): Values are not
++      enum based for corlib compilation.
++      
++      * cfold.cs (BinaryFold): Convert operand for enum additions. Fixed enum
++      subtractions.
++      
++      * class.cs (FixedField.Define): Use ResolveAsConstant.
++      
++      * const.cs (IConstant): Interface constants and enums.
++      (Const.ResolveValue): New method for constant resolvning.
++      (ExternalConstant): Constants from imported assemblies.
++      
++      * constant.cs (Constant.GetTypedValue): Used to get constant with forced
++      conversion; like enums.
++      (Constant.ToType): Converts this constant to different type.
++      (Constant.Increment): Adds 1.
++      
++      * convert.cs (ImplicitConversionRequired): Simplified.
++      
++      * cs-parser.jay: Create EnumMember directly.
++      
++      * decl.cs (MemberCore.CheckObsoleteness): Checks for ObsoleteAttribute presence.
++      
++      * doc.cs (GenerateEnumDocComment): Removed.
++      
++      * ecore.cs (Expression.ResolveAsConstant): New constant specific method.
++      (ConvertIntLiteral): Removed.
++      (FieldExpr.ResolveMemberAccess): Refactored to remove constant specific if(s).
++      
++      * enum.cs (EnumMember): Implement IConstant.
++      (Enum.IsValidEnumConstant): Removed.
++      (Enum.GetNextDefaultValue): Removed.
++      (Enum.FindMembers): Updated.
++      (Enum.GenerateDocComment): Iterate enum members.
++      
++      * expression.cs (Cast.TryReduce): Handle enums correctly.
++      (New.Constantify): Made public.
++      (MemberAccess.DoResolve): Removed contant specific if(s).
++      
++      * literal.cs (NullLiteral): Implement new abstract methods.
++      
++      * statement.cs (GotoCase.Resolve): Use new constant methods.
++      (SwitchLabel.ResolveAndReduce): Use new constant methods.
++      
++      * typemanager.cs (LookupEnum): Removed.
++      (IsEnumType): Fixed to work with corlib.
++      (RegisterConstant): Removed.
++      (LookupConstant): Removed.
++      (GetConstant): Changed to work with IConstant.
++
  2005-08-04  Atsushi Enomoto  <atsushi@ximian.com>
  
        * location.cs : Fixed overflown (>255) column number.
index 3ac4d54fd318feca28ce8f30635b2ac70b4808a5,3ac4d54fd318feca28ce8f30635b2ac70b4808a5..9e17bcad24be7edbfd6affc1b95fd464b6af5243
@@@ -240,26 -240,26 +240,14 @@@ namespace Mono.CSharp 
                //
                public static bool GetAttributeArgumentExpression (Expression e, Location loc, Type arg_type, out object result)
                {
--                      if (e is EnumConstant) {
--                              if (RootContext.StdLib)
--                                      result = ((EnumConstant)e).GetValueAsEnumType ();
--                              else
--                                      result = ((EnumConstant)e).GetValue ();
--
--                              return true;
--                      }
--
                        Constant constant = e as Constant;
                        if (constant != null) {
--                              if (e.Type != arg_type) {
--                                      constant = Const.ChangeType (loc, constant, arg_type);
--                                      if (constant == null) {
--                                              result = null;
--                                              Error_AttributeArgumentNotValid (loc);
--                                              return false;
--                                      }
++                              constant = constant.ToType (arg_type, loc);
++                              if (constant == null) {
++                                      result = null;
++                                      return false;
                                }
--                              result = constant.GetValue ();
++                              result = constant.GetTypedValue ();
                                return true;
                        } else if (e is TypeOf) {
                                result = ((TypeOf) e).TypeArg;
  
                public UnmanagedMarshal GetMarshal (Attributable attr)
                {
--                      UnmanagedType UnmanagedType = (UnmanagedType)System.Enum.Parse (typeof (UnmanagedType), pos_values [0].ToString ());
++                      UnmanagedType UnmanagedType;
++                      if (!RootContext.StdLib || pos_values [0].GetType () != typeof (UnmanagedType))
++                              UnmanagedType = (UnmanagedType)System.Enum.ToObject (typeof (UnmanagedType), pos_values [0]);
++                      else
++                              UnmanagedType = (UnmanagedType) pos_values [0];
  
                        object value = GetFieldValue ("SizeParamIndex");
                        if (value != null && UnmanagedType != UnmanagedType.LPArray) {
  
                public MethodImplOptions GetMethodImplOptions ()
                {
--                      return (MethodImplOptions)System.Enum.Parse (typeof (MethodImplOptions), pos_values [0].ToString ());
++                      if (pos_values [0].GetType () != typeof (MethodImplOptions))
++                              return (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values [0]);
++                      return (MethodImplOptions)pos_values [0];
                }
  
                public LayoutKind GetLayoutKindValue ()
                {
--                      return (LayoutKind)System.Enum.Parse (typeof (LayoutKind), pos_values [0].ToString ());
++                      if (!RootContext.StdLib || pos_values [0].GetType () != typeof (LayoutKind))
++                              return (LayoutKind)System.Enum.ToObject (typeof (LayoutKind), pos_values [0]);
++
++                      return (LayoutKind)pos_values [0];
                }
  
                /// <summary>
index c14eab475516664c1ec43215c8dfa5244a1d521e,c14eab475516664c1ec43215c8dfa5244a1d521e..0c69e1c5d3dfc80be89753efb9f04014b287e1c0
@@@ -450,13 -450,13 +450,17 @@@ namespace Mono.CSharp 
                                        if (right is EnumConstant){
                                                return null;
                                        }
--                                      if (((EnumConstant) left).Child.Type != right.Type)
++
++                                      right = right.ToType (((EnumConstant) left).Child.Type, loc);
++                                      if (right == null)
                                                return null;
  
                                        wrap_as = left.Type;
                                } else if (right is EnumConstant){
--                                      if (((EnumConstant) right).Child.Type != left.Type)
++                                      left = left.ToType (((EnumConstant) right).Child.Type, loc);
++                                      if (left == null)
                                                return null;
++
                                        wrap_as = right.Type;
                                }
  
                                wrap_as = null;
                                if (left is EnumConstant){
                                        if (right is EnumConstant){
--                                              if (left.Type == right.Type)
--                                                      wrap_as = TypeManager.EnumToUnderlying (left.Type);
--                                              else
++                                              if (left.Type != right.Type) {
++                                                      Binary.Error_OperatorCannotBeApplied (loc, "-", left.Type, right.Type);
++                                                      return null;
++                                              }
++
++                                              wrap_as = TypeManager.EnumToUnderlying (left.Type);
++                                              right = ((EnumConstant) right).Child.ToType (wrap_as, loc);
++                                              if (right == null)
++                                                      return null;
++
++                                              left = ((EnumConstant) left).Child.ToType (wrap_as, loc);
++                                              if (left == null)
                                                        return null;
                                        }
--                                      if (((EnumConstant) left).Child.Type != right.Type)
--                                              return null;
++                                      else {
++                                              right = right.ToType (((EnumConstant) left).Child.Type, loc);
++                                              if (right == null)
++                                                      return null;
  
--                                      wrap_as = left.Type;
++                                              wrap_as = left.Type;
++                                      }
                                } else if (right is EnumConstant){
--                                      if (((EnumConstant) right).Child.Type != left.Type)
++                                      left = left.ToType (((EnumConstant) right).Child.Type, loc);
++                                      if (left == null)
                                                return null;
++
                                        wrap_as = right.Type;
                                }
  
index a24c0619a2303b0efd08baf83f4139ed66961d71,a24c0619a2303b0efd08baf83f4139ed66961d71..2902b8ac5a52159bd8c4e463b1078a9c9d3beda9
@@@ -5462,16 -5462,16 +5462,10 @@@ namespace Mono.CSharp 
                                return false;
                        }
  
--                      Expression e = size_expr.Resolve (Parent.EmitContext);
--                      if (e == null)
++                      Constant c = size_expr.ResolveAsConstant (Parent.EmitContext, this);
++                      if (c == null)
                                return false;
  
--                      Constant c = e as Constant;
--                      if (c == null) {
--                              Const.Error_ExpressionMustBeConstant (e.Location, GetSignatureForError ());
--                              return false;
--                      }
--
                        IntConstant buffer_size_const = c.ToInt (Location);
                        if (buffer_size_const == null)
                                return false;
index d8c461560704ab7e911b3d8e06235d75bb7f8ddc,d8c461560704ab7e911b3d8e06235d75bb7f8ddc..39fe478eb9224584d4f4133c40446b99cf49df78
@@@ -9,15 -9,15 +9,6 @@@
  //
  //
  
--//
--// This is needed because the following situation arises:
--//
--//     The FieldBuilder is declared with the real type for an enumeration
--//
--//     When we attempt to set the value for the constant, the FieldBuilder.SetConstant
--//     function aborts because it requires its argument to be of the same type
--//
--
  namespace Mono.CSharp {
  
        using System;
        using System.Reflection.Emit;
        using System.Collections;
  
--      public class Const : FieldMember {
--              public Expression Expr;
--              EmitContext const_ec;
--
--              bool resolved = false;
--              object ConstantValue = null;
++      public interface IConstant
++      {
++              void CheckObsoleteness (Location loc);
++              bool ResolveValue ();
++              Constant Value { get; }
++      }
  
--              bool in_transit = false;
++      public class Const : FieldMember, IConstant {
++              Expression Expr;
++              Constant value;
++              bool in_transit;
  
                public const int AllowedModifiers =
                        Modifiers.NEW |
                        ModFlags |= Modifiers.STATIC;
                }
  
--#if DEBUG
--              void dump_tree (Type t)
--              {
--                      Console.WriteLine ("Dumping hierarchy");
--                      while (t != null){
--                              Console.WriteLine ("   " + t.FullName + " " +
--                                      (t.GetType ().IsEnum ? "yes" : "no"));
--                              t = t.BaseType;
--                      }
--              }
--#endif
--
                protected override bool CheckBase ()
                {
                        // Constant.Define can be called when the parent type hasn't yet been populated
                        if (!base.Define ())
                                return false;
  
--                      const_ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
--
                        Type ttype = MemberType;
                        while (ttype.IsArray)
                            ttype = TypeManager.GetElementType (ttype);
--                      
--                      if (!TypeManager.IsBuiltinType(ttype) && (!ttype.IsSubclassOf(TypeManager.enum_type)) && !(Expr is NullLiteral)){
--                              Report.Error (
--                                      -3, Location,
--                                      "Constant type is not valid (only system types are allowed)");
--                              return false;
--                      }
  
                        FieldAttributes field_attr = FieldAttributes.Static | Modifiers.FieldAttr (ModFlags);
                        // Decimals cannot be emitted into the constant blob.  So, convert to 'readonly'.
  
                        return true;
                }
--
--              //
--              // Changes the type of the constant expression `expr' to the Type `type'
--              // Returns null on failure.
--              //
--              public static Constant ChangeType (Location loc, Constant expr, Type type)
++              
++              /// <summary>
++              ///  Emits the field value by evaluating the expression
++              /// </summary>
++              public override void Emit ()
                {
--                      if (type == TypeManager.object_type)
--                              return expr;
--
--                      bool fail;
--
--                      // from the null type to any reference-type.
--                      if (expr.Type == TypeManager.null_type && !type.IsValueType && !TypeManager.IsEnumType (type))
--                              return NullLiteral.Null;
++                      if (!ResolveValue ())
++                              return;
  
--                      if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, expr, type)){
--                              Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
--                              return null;
--                      }
--
--                      // Special-case: The 0 literal can be converted to an enum value,
--                      // and ImplicitStandardConversionExists will return true in that case.
--                      if (expr.Type == TypeManager.int32_type && TypeManager.IsEnumType (type)){
--                              if (expr is IntLiteral && ((IntLiteral) expr).Value == 0)
--                                      return new EnumConstant (expr, type);
++                      if (value.Type == TypeManager.decimal_type) {
++                              Decimal d = ((DecimalConstant)value).Value;
++                              int[] bits = Decimal.GetBits (d);
++                              object[] args = new object[] { (byte)(bits [3] >> 16), (byte)(bits [3] >> 31), (uint)bits [2], (uint)bits [1], (uint)bits [0] };
++                              CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.decimal_constant_attribute_ctor, args);
++                              FieldBuilder.SetCustomAttribute (cab);
                        }
--                      
--                      object constant_value = TypeManager.ChangeType (expr.GetValue (), type, out fail);
--                      if (fail){
--                              Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
--                              
--                              //
--                              // We should always catch the error before this is ever
--                              // reached, by calling Convert.ImplicitStandardConversionExists
--                              //
--                              throw new Exception (
--                                                   String.Format ("LookupConstantValue: This should never be reached {0} {1}", expr.Type, type));
++                      else{
++                              FieldBuilder.SetConstant (value.GetTypedValue ());
                        }
  
--                      Constant retval;
--                      if (type == TypeManager.int32_type)
--                              retval = new IntConstant ((int) constant_value);
--                      else if (type == TypeManager.uint32_type)
--                              retval = new UIntConstant ((uint) constant_value);
--                      else if (type == TypeManager.int64_type)
--                              retval = new LongConstant ((long) constant_value);
--                      else if (type == TypeManager.uint64_type)
--                              retval = new ULongConstant ((ulong) constant_value);
--                      else if (type == TypeManager.float_type)
--                              retval = new FloatConstant ((float) constant_value);
--                      else if (type == TypeManager.double_type)
--                              retval = new DoubleConstant ((double) constant_value);
--                      else if (type == TypeManager.string_type)
--                              retval = new StringConstant ((string) constant_value);
--                      else if (type == TypeManager.short_type)
--                              retval = new ShortConstant ((short) constant_value);
--                      else if (type == TypeManager.ushort_type)
--                              retval = new UShortConstant ((ushort) constant_value);
--                      else if (type == TypeManager.sbyte_type)
--                              retval = new SByteConstant ((sbyte) constant_value);
--                      else if (type == TypeManager.byte_type)
--                              retval = new ByteConstant ((byte) constant_value);
--                      else if (type == TypeManager.char_type)
--                              retval = new CharConstant ((char) constant_value);
--                      else if (type == TypeManager.bool_type)
--                              retval = new BoolConstant ((bool) constant_value);
--                      else if (type == TypeManager.decimal_type)
--                              retval = new DecimalConstant ((decimal) constant_value);
--                      else
--                              throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);
--                      
--                      return retval;
++                      base.Emit ();
                }
--              
--              /// <summary>
--              ///  Looks up the value of a constant field. Defines it if it hasn't
--              ///  already been. Similar to LookupEnumValue in spirit.
--              /// </summary>
--              public bool LookupConstantValue (out object value)
++
++              public static void Error_ExpressionMustBeConstant (Location loc, string e_name)
++              {
++                      Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
++              }
++
++              public static void Error_CyclicDeclaration (MemberCore mc)
                {
--                      if (resolved) {
--                              value = ConstantValue;
++                      Report.Error (110, mc.Location, "The evaluation of the constant value for `{0}' involves a circular definition",
++                              mc.GetSignatureForError ());
++              }
++
++              #region IConstant Members
++
++              public bool ResolveValue ()
++              {
++                      if (value != null)
                                return true;
--                      }
  
++                      SetMemberIsUsed ();
                        if (in_transit) {
--                              Report.Error (110, Location,
--                                            "The evaluation of the constant value for `" +
--                                            Name + "' involves a circular definition.");
--                              value = null;
++                              Error_CyclicDeclaration (this);
++                              // Suppress cyclic errors
++                              value = New.Constantify (MemberType);
                                return false;
                        }
  
                        in_transit = true;
--                      int errors = Report.Errors;
--
--                      //
--                      // We might have cleared Expr ourselves in a recursive definition
--                      //
--                      if (Expr == null){
--                              value = null;
++                      EmitContext ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
++                      value = Expr.ResolveAsConstant (ec, this);
++                      if (value == null)
                                return false;
--                      }
  
--                      Expr = Expr.Resolve (const_ec);
++                      value = value.ToType (MemberType, Location);
++                      if (value == null)
++                              return false;
  
                        in_transit = false;
++                      return true;
++              }
  
--                      if (Expr == null) {
--                              Error_ExpressionMustBeConstant (Location, GetSignatureForError ());
--                              value = null;
--                              return false;
++              public Constant Value {
++                      get {
++                              return value;
                        }
++              }
  
--                      Expression real_expr = Expr;
--
--                      Constant ce = Expr as Constant;
--                      if (ce == null){
--                              UnCheckedExpr un_expr = Expr as UnCheckedExpr;
--                              CheckedExpr ch_expr = Expr as CheckedExpr;
--                              EmptyCast ec_expr = Expr as EmptyCast;
--
--                              if ((un_expr != null) && (un_expr.Expr is Constant))
--                                      Expr = un_expr.Expr;
--                              else if ((ch_expr != null) && (ch_expr.Expr is Constant))
--                                      Expr = ch_expr.Expr;
--                              else if ((ec_expr != null) && (ec_expr.Child is Constant))
--                                      Expr = ec_expr.Child;
--                              else if (Expr is ArrayCreation){
--                                      Report.Error (133, Location, "Arrays can not be constant");
--                              } else {
--                                      if (errors == Report.Errors)
--                                              Report.Error (150, Location, "A constant value is expected");
--                                      value = null;
--                                      return false;
--                              }
--
--                              ce = Expr as Constant;
--                      }
++              #endregion
++      }
  
--                      if (MemberType != real_expr.Type) {
--                              ce = ChangeType (Location, ce, MemberType);
--                              if (ce == null){
--                                      value = null;
--                                      return false;
--                              }
--                              Expr = ce;
--                      }
++      public class ExternalConstant: IConstant
++      {
++              FieldInfo fi;
++              Constant value;
  
--                      if (ce != null)
--                              ConstantValue = ce.GetValue ();
--
--                      if (MemberType.IsEnum){
--                              //
--                              // This sadly does not work for our user-defined enumerations types ;-(
--                              //
--                              try {
--                                      ConstantValue = System.Enum.ToObject (
--                                              MemberType, ConstantValue);
--                              } catch (ArgumentException){
--                                      Report.Error (
--                                              -16, Location,
--                                              ".NET SDK 1.0 does not permit to create the constant "+
--                                              " field from a user-defined enumeration");
--                              }
--                      }
++              public ExternalConstant (FieldInfo fi)
++              {
++                      this.fi = fi;
++              }
  
--                      if (ce is DecimalConstant) {
--                              Decimal d = ((DecimalConstant)ce).Value;
--                              int[] bits = Decimal.GetBits (d);
--                              object[] args = new object[] { (byte)(bits [3] >> 16), (byte)(bits [3] >> 31), (uint)bits [2], (uint)bits [1], (uint)bits [0] };
--                              CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.decimal_constant_attribute_ctor, args);
--                              FieldBuilder.SetCustomAttribute (cab);
--                      }
--                      else{
--                              FieldBuilder.SetConstant (ConstantValue);
--                      }
++              #region IConstant Members
  
--                      if (!TypeManager.RegisterFieldValue (FieldBuilder, ConstantValue))
--                              throw new Exception ("Cannot register const value");
++              public void CheckObsoleteness (Location loc)
++              {
++                      ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (fi);
++                      if (oa == null) {
++                              return;
++                      }
  
--                      value = ConstantValue;
--                      resolved = true;
--                      return true;
++                      AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (fi), loc);
                }
--              
--              
--              /// <summary>
--              ///  Emits the field value by evaluating the expression
--              /// </summary>
--              public override void Emit ()
++
++              public bool ResolveValue ()
                {
--                      object value;
--                      LookupConstantValue (out value);
--                      base.Emit ();
++                      if (value != null)
++                              return true;
++
++                      if (fi.DeclaringType.IsEnum) {
++                              value = Expression.Constantify (fi.GetValue (fi), TypeManager.EnumToUnderlying (fi.FieldType));
++                              value = new EnumConstant (value, fi.DeclaringType);
++                              return true;
++                      }
++
++                      value = Expression.Constantify (fi.GetValue (fi), fi.FieldType);
++                      return true;
                }
  
--              public static void Error_ExpressionMustBeConstant (Location loc, string e_name)
--              {
--                      Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
++              public Constant Value {
++                      get {
++                              return value;
++                      }
                }
  
++              #endregion
        }
--}
--
  
++}
index c7b07ef1986ad22fb7a5742dde00d743ab0c862c,c7b07ef1986ad22fb7a5742dde00d743ab0c862c..bee3c077a038d7628a34d1f508082a2558471dfd
@@@ -38,6 -38,6 +38,11 @@@ namespace Mono.CSharp 
                /// </summary>
                public abstract object GetValue ();
  
++              public virtual object GetTypedValue ()
++              {
++                      return GetValue ();
++              }
++
                /// <summary>
                ///   Constants are always born in a fully resolved state
                /// </summary>
                        return this;
                }
  
--              public virtual void Error_ConstantValueCannotBeConverted (Location loc, Type t)
++              public override void Error_ValueCannotBeConverted (Location loc, Type t)
                {
--                      Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
--                              AsString (), TypeManager.CSharpName (t));
++                      // string is not real constant
++                      if (type == TypeManager.string_type)
++                              base.Error_ValueCannotBeConverted (loc, t);
++                      else
++                              Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
++                                      AsString (), TypeManager.CSharpName (t));
                }
  
  
                        return c;
                }
  
++              public virtual Constant ToType (Type type, Location loc)
++              {
++                      if (Type == type)
++                              return this;
++
++                      if (type == TypeManager.object_type)
++                              return this;
++
++                      if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, this, type)){
++                              Error_ValueCannotBeConverted (loc, type);
++                              return null;
++                      }
++
++                      // Special-case: The 0 literal can be converted to an enum value,
++                      // and ImplicitStandardConversionExists will return true in that case.
++                      if (IsZeroInteger && Type == TypeManager.int32_type && TypeManager.IsEnumType (type)) {
++                              return new EnumConstant (this, type);
++                      }
++
++                      bool fail;                      
++                      object constant_value = TypeManager.ChangeType (GetValue (), type, out fail);
++                      if (fail){
++                              Convert.Error_CannotImplicitConversion (loc, Type, type);
++                              
++                              //
++                              // We should always catch the error before this is ever
++                              // reached, by calling Convert.ImplicitStandardConversionExists
++                              //
++                              throw new Exception (
++                                      String.Format ("LookupConstantValue: This should never be reached {0} {1}", Type, type));
++                      }
++
++                      Constant retval;
++                      if (type == TypeManager.int32_type)
++                              retval = new IntConstant ((int) constant_value);
++                      else if (type == TypeManager.uint32_type)
++                              retval = new UIntConstant ((uint) constant_value);
++                      else if (type == TypeManager.int64_type)
++                              retval = new LongConstant ((long) constant_value);
++                      else if (type == TypeManager.uint64_type)
++                              retval = new ULongConstant ((ulong) constant_value);
++                      else if (type == TypeManager.float_type)
++                              retval = new FloatConstant ((float) constant_value);
++                      else if (type == TypeManager.double_type)
++                              retval = new DoubleConstant ((double) constant_value);
++                      else if (type == TypeManager.string_type)
++                              retval = new StringConstant ((string) constant_value);
++                      else if (type == TypeManager.short_type)
++                              retval = new ShortConstant ((short) constant_value);
++                      else if (type == TypeManager.ushort_type)
++                              retval = new UShortConstant ((ushort) constant_value);
++                      else if (type == TypeManager.sbyte_type)
++                              retval = new SByteConstant ((sbyte) constant_value);
++                      else if (type == TypeManager.byte_type)
++                              retval = new ByteConstant ((byte) constant_value);
++                      else if (type == TypeManager.char_type)
++                              retval = new CharConstant ((char) constant_value);
++                      else if (type == TypeManager.bool_type)
++                              retval = new BoolConstant ((bool) constant_value);
++                      else if (type == TypeManager.decimal_type)
++                              retval = new DecimalConstant ((decimal) constant_value);
++                      else
++                              throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);
++                      
++                      return retval;
++              }
++
                public virtual DecimalConstant ConvertToDecimal ()
                {
                        return null;
                {
                        return null;
                }
++
++              public abstract Constant Increment ();
                
                public abstract bool IsDefaultValue {
                        get;
                        else
                                ec.ig.Emit (OpCodes.Ldc_I4_0);
                }
++
++              public override Constant Increment ()
++              {
++                      throw new NotSupportedException ();
++              }
        
                public override bool IsDefaultValue {
                        get {
                        return new IntConstant (Value);
                }
  
++              public override Constant Increment ()
++              {
++                      return new ByteConstant (checked ((byte)(Value + 1)));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                {
                        return new IntConstant (Value);
                }
++
++              public override Constant Increment ()
++              {
++                      return new CharConstant (checked ((char)(Value + 1)));
++              }
                
                public override bool IsDefaultValue {
                        get {
                        return new IntConstant (Value);
                }
  
++              public override Constant Increment ()
++              {
++                  return new SByteConstant (checked((sbyte)(Value + 1)));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                        return new IntConstant (Value);
                }
  
++              public override Constant Increment ()
++              {
++                      return new ShortConstant (checked((short)(Value + 1)));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                        return new IntConstant (Value);
                }
        
++              public override Constant Increment ()
++              {
++                      return new UShortConstant (checked((ushort)(Value + 1)));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                        return this;
                }
  
++              public override Constant Increment ()
++              {
++                      return new IntConstant (checked(Value + 1));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                {
                        return null;
                }
--              
++      
++              public override Constant Increment ()
++              {
++                      return new UIntConstant (checked(Value + 1));
++              }
++      
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                {
                        return null;
                }
++
++              public override Constant Increment ()
++              {
++                      return new LongConstant (checked(Value + 1));
++              }
                
                public override bool IsDefaultValue {
                        get {
                        return null;
                }
  
++              public override Constant Increment ()
++              {
++                      return new ULongConstant (checked(Value + 1));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                        return null;
                }
  
++              public override Constant Increment ()
++              {
++                      return new FloatConstant (checked(Value + 1));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                        return null;
                }
  
++              public override Constant Increment ()
++              {
++                      return new DoubleConstant (checked(Value + 1));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                        ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
                }
  
++              public override Constant Increment ()
++              {
++                      return new DecimalConstant (checked (Value + 1));
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == 0;
                                ec.ig.Emit (OpCodes.Ldstr, Value);
                }
  
++              public override Constant Increment ()
++              {
++                      throw new NotSupportedException ();
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Value == null;
index 081681f099e87f880be82fb468ff7bbb360fe6d9,081681f099e87f880be82fb468ff7bbb360fe6d9..3efc3246b7f033032414e1679c0b51161b4899ac
@@@ -1304,15 -1304,15 +1304,7 @@@ namespace Mono.CSharp 
                                }
                        }
  
--                      if (source is Constant){
--                              Constant c = (Constant) source;
--
--                              c.Error_ConstantValueCannotBeConverted (loc, target_type);
--                              return null;
--                      }
--                      
--                      Error_CannotImplicitConversion (loc, source.Type, target_type);
--
++                      source.Error_ValueCannotBeConverted (loc, target_type);
                        return null;
                }
  
                        if (ne != null)
                                return ne;
  
--                      if (expr is NullLiteral){
--                              ((NullLiteral)expr).Error_ConstantValueCannotBeConverted (loc, target_type);
--                              return null;
--                      }
--
--                      Error_CannotConvertType (loc, original_expr_type, target_type);
++                      if (expr is Constant)
++                              expr.Error_ValueCannotBeConverted (loc, target_type);
++                      else
++                              Error_CannotConvertType (loc, original_expr_type, target_type);
                        return null;
                }
  
index 944b8dc2cbeda719e4b34c9d4cfae9a7b2f9ab17,944b8dc2cbeda719e4b34c9d4cfae9a7b2f9ab17..3db9eac6c7da66c2fb95dafdf6a830137e6c840a
@@@ -2349,11 -2349,11 +2349,16 @@@ enum_declaratio
                if (RootContext.Documentation != null)
                        e.DocComment = enumTypeComment;
  
++
++              EnumMember em = null;
                foreach (VariableDeclaration ev in (ArrayList) $8) {
--                      e.AddEnumMember (ev.identifier, 
--                                       (Expression) ev.expression_or_array_initializer,
--                                       ev.Location, ev.OptAttributes,
--                                       ev.DocComment);
++                      em = new EnumMember (e, em, (Expression) ev.expression_or_array_initializer,
++                              new MemberName (ev.identifier, ev.Location), ev.OptAttributes);
++
++//                    if (RootContext.Documentation != null)
++                              em.DocComment = ev.DocComment;
++
++                      e.AddEnumMember (em);
                }
  
                current_container.AddEnum (e);
diff --cc mcs/mcs/decl.cs
index 953bfb6ed4a069cd7f0b7331a53d522029d73b89,953bfb6ed4a069cd7f0b7331a53d522029d73b89..ede1f1b6894a457edc6caf5601f6ae9bd23cbd13
@@@ -400,6 -400,6 +400,19 @@@ namespace Mono.CSharp 
                        return obsolete;
                }
  
++              /// <summary>
++              /// Checks for ObsoleteAttribute presence. It's used for testing of all non-types elements
++              /// </summary>
++              public void CheckObsoleteness (Location loc)
++              {
++                      ObsoleteAttribute oa = GetObsoleteAttribute (Parent);
++                      if (oa == null) {
++                              return;
++                      }
++
++                      AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
++              }
++
                /// <summary>
                /// Analyze whether CLS-Compliant verification must be execute for this MemberCore.
                /// </summary>
diff --cc mcs/mcs/doc.cs
index 6fd6ddb8df3e042aaf4a1fff5e388c6d3fbc1057,6fd6ddb8df3e042aaf4a1fff5e388c6d3fbc1057..5affd4790d395c764d7fe63fcdc088b51c74222e
@@@ -742,16 -742,16 +742,6 @@@ namespace Mono.CSharp 
                        }
                }
  
--              // Enum
--              public static void GenerateEnumDocComment (Enum e, DeclSpace ds)
--              {
--                      GenerateDocComment (e, ds);
--                      foreach (string name in e.ordered_enums) {
--                              MemberCore mc = e.GetDefinition (name);
--                              GenerateDocComment (mc, e);
--                      }
--              }
--
                private static void Normalize (MemberCore mc, ref string name)
                {
                        if (name.Length > 0 && name [0] == '@')
  
                        if (root.Enums != null)
                                foreach (Enum e in root.Enums)
--                                      DocUtil.GenerateEnumDocComment (e, null);
++                                      e.GenerateDocComment (null);
  
                        IDictionary table = new ListDictionary ();
                        foreach (ClassPart cp in PartialComments.Keys) {
index fb6b4c67c125d22a6036f914ff6db283890dfc11,fb6b4c67c125d22a6036f914ff6db283890dfc11..51cc0569b5fb891c10a5c224d69661806e17686b
@@@ -273,6 -273,6 +273,11 @@@ namespace Mono.CSharp 
                        Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", name);
                }
  
++              public virtual void Error_ValueCannotBeConverted (Location loc, Type t)
++              {
++                      Convert.Error_CannotImplicitConversion (loc, Type, t);
++              }
++
                ResolveFlags ExprClassToResolveFlags ()
                {
                        switch (eclass) {
                        return e;
                }
  
++              public Constant ResolveAsConstant (EmitContext ec, MemberCore mc)
++              {
++                      Expression e = Resolve (ec);
++                      if (e != null) {
++                              Constant c = e as Constant;
++                              if (c != null)
++                                      return c;
++
++                              EmptyCast empty = e as EmptyCast;
++                              if (empty != null) {
++                                      c = empty.Child as Constant;
++                                      if (c != null) {
++                                              // TODO: not sure about this maybe there is easier way how to use EmptyCast
++                                              if (e.Type.IsEnum)
++                                                      c.Type = e.Type;
++
++                                              return c;
++                                      }
++                              }
++                      }
++
++                      Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
++                      return null;
++              }
++
                /// <summary>
                ///   Resolves an expression for LValue assignment
                /// </summary>
                {
                        Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
                }
--              
--              /// <summary>
--              ///   Converts the IntConstant, UIntConstant, LongConstant or
--              ///   ULongConstant into the integral target_type.   Notice
--              ///   that we do not return an `Expression' we do return
--              ///   a boxed integral type.
--              ///
--              ///   FIXME: Since I added the new constants, we need to
--              ///   also support conversions from CharConstant, ByteConstant,
--              ///   SByteConstant, UShortConstant, ShortConstant
--              ///
--              ///   This is used by the switch statement, so the domain
--              ///   of work is restricted to the literals above, and the
--              ///   targets are int32, uint32, char, byte, sbyte, ushort,
--              ///   short, uint64 and int64
--              /// </summary>
--              public static object ConvertIntLiteral (Constant c, Type target_type, Location loc)
--              {
--                      if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, c, target_type)){
--                              Convert.Error_CannotImplicitConversion (loc, c.Type, target_type);
--                              return null;
--                      }
--                      
--                      if (c.Type == target_type)
--                              return ((Constant) c).GetValue ();
--
--                      //
--                      // Make into one of the literals we handle, we dont really care
--                      // about this value as we will just return a few limited types
--                      // 
--                      if (c is EnumConstant)
--                              c = ((EnumConstant)c).WidenToCompilerConstant ();
--
--                      if (c is IntConstant){
--                              int v = ((IntConstant) c).Value;
--                              
--                              if (target_type == TypeManager.uint32_type){
--                                      if (v >= 0)
--                                              return (uint) v;
--                              } else if (target_type == TypeManager.char_type){
--                                      if (v >= Char.MinValue && v <= Char.MaxValue)
--                                              return (char) v;
--                              } else if (target_type == TypeManager.byte_type){
--                                      if (v >= Byte.MinValue && v <= Byte.MaxValue)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.sbyte_type){
--                                      if (v >= SByte.MinValue && v <= SByte.MaxValue)
--                                              return (sbyte) v;
--                              } else if (target_type == TypeManager.short_type){
--                                      if (v >= Int16.MinValue && v <= UInt16.MaxValue)
--                                              return (short) v;
--                              } else if (target_type == TypeManager.ushort_type){
--                                      if (v >= UInt16.MinValue && v <= UInt16.MaxValue)
--                                              return (ushort) v;
--                              } else if (target_type == TypeManager.int64_type)
--                                      return (long) v;
--                              else if (target_type == TypeManager.uint64_type){
--                                      if (v > 0)
--                                              return (ulong) v;
--                              }
--
--                      } else if (c is UIntConstant){
--                              uint v = ((UIntConstant) c).Value;
--
--                              if (target_type == TypeManager.int32_type){
--                                      if (v <= Int32.MaxValue)
--                                              return (int) v;
--                              } else if (target_type == TypeManager.char_type){
--                                      if (v >= Char.MinValue && v <= Char.MaxValue)
--                                              return (char) v;
--                              } else if (target_type == TypeManager.byte_type){
--                                      if (v <= Byte.MaxValue)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.sbyte_type){
--                                      if (v <= SByte.MaxValue)
--                                              return (sbyte) v;
--                              } else if (target_type == TypeManager.short_type){
--                                      if (v <= UInt16.MaxValue)
--                                              return (short) v;
--                              } else if (target_type == TypeManager.ushort_type){
--                                      if (v <= UInt16.MaxValue)
--                                              return (ushort) v;
--                              } else if (target_type == TypeManager.int64_type)
--                                      return (long) v;
--                              else if (target_type == TypeManager.uint64_type)
--                                      return (ulong) v;
--                      } else if (c is LongConstant){ 
--                              long v = ((LongConstant) c).Value;
--
--                              if (target_type == TypeManager.int32_type){
--                                      if (v >= UInt32.MinValue && v <= UInt32.MaxValue)
--                                              return (int) v;
--                              } else if (target_type == TypeManager.uint32_type){
--                                      if (v >= 0 && v <= UInt32.MaxValue)
--                                              return (uint) v;
--                              } else if (target_type == TypeManager.char_type){
--                                      if (v >= Char.MinValue && v <= Char.MaxValue)
--                                              return (char) v;
--                              } else if (target_type == TypeManager.byte_type){
--                                      if (v >= Byte.MinValue && v <= Byte.MaxValue)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.sbyte_type){
--                                      if (v >= SByte.MinValue && v <= SByte.MaxValue)
--                                              return (sbyte) v;
--                              } else if (target_type == TypeManager.short_type){
--                                      if (v >= Int16.MinValue && v <= UInt16.MaxValue)
--                                              return (short) v;
--                              } else if (target_type == TypeManager.ushort_type){
--                                      if (v >= UInt16.MinValue && v <= UInt16.MaxValue)
--                                              return (ushort) v;
--                              } else if (target_type == TypeManager.uint64_type){
--                                      if (v > 0)
--                                              return (ulong) v;
--                              }
--                      } else if (c is ULongConstant){
--                              ulong v = ((ULongConstant) c).Value;
--
--                              if (target_type == TypeManager.int32_type){
--                                      if (v <= Int32.MaxValue)
--                                              return (int) v;
--                              } else if (target_type == TypeManager.uint32_type){
--                                      if (v <= UInt32.MaxValue)
--                                              return (uint) v;
--                              } else if (target_type == TypeManager.char_type){
--                                      if (v >= Char.MinValue && v <= Char.MaxValue)
--                                              return (char) v;
--                              } else if (target_type == TypeManager.byte_type){
--                                      if (v >= Byte.MinValue && v <= Byte.MaxValue)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.sbyte_type){
--                                      if (v <= (int) SByte.MaxValue)
--                                              return (sbyte) v;
--                              } else if (target_type == TypeManager.short_type){
--                                      if (v <= UInt16.MaxValue)
--                                              return (short) v;
--                              } else if (target_type == TypeManager.ushort_type){
--                                      if (v <= UInt16.MaxValue)
--                                              return (ushort) v;
--                              } else if (target_type == TypeManager.int64_type){
--                                      if (v <= Int64.MaxValue)
--                                              return (long) v;
--                              }
--                      } else if (c is ByteConstant){
--                              byte v = ((ByteConstant) c).Value;
--                              
--                              if (target_type == TypeManager.int32_type)
--                                      return (int) v;
--                              else if (target_type == TypeManager.uint32_type)
--                                      return (uint) v;
--                              else if (target_type == TypeManager.char_type)
--                                      return (char) v;
--                              else if (target_type == TypeManager.sbyte_type){
--                                      if (v <= SByte.MaxValue)
--                                              return (sbyte) v;
--                              } else if (target_type == TypeManager.short_type)
--                                      return (short) v;
--                              else if (target_type == TypeManager.ushort_type)
--                                      return (ushort) v;
--                              else if (target_type == TypeManager.int64_type)
--                                      return (long) v;
--                              else if (target_type == TypeManager.uint64_type)
--                                      return (ulong) v;
--                      } else if (c is SByteConstant){
--                              sbyte v = ((SByteConstant) c).Value;
--                              
--                              if (target_type == TypeManager.int32_type)
--                                      return (int) v;
--                              else if (target_type == TypeManager.uint32_type){
--                                      if (v >= 0)
--                                              return (uint) v;
--                              } else if (target_type == TypeManager.char_type){
--                                      if (v >= 0)
--                                              return (char) v;
--                              } else if (target_type == TypeManager.byte_type){
--                                      if (v >= 0)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.short_type)
--                                      return (short) v;
--                              else if (target_type == TypeManager.ushort_type){
--                                      if (v >= 0)
--                                              return (ushort) v;
--                              } else if (target_type == TypeManager.int64_type)
--                                      return (long) v;
--                              else if (target_type == TypeManager.uint64_type){
--                                      if (v >= 0)
--                                              return (ulong) v;
--                              }
--                      } else if (c is ShortConstant){
--                              short v = ((ShortConstant) c).Value;
--                              
--                              if (target_type == TypeManager.int32_type){
--                                      return (int) v;
--                              } else if (target_type == TypeManager.uint32_type){
--                                      if (v >= 0)
--                                              return (uint) v;
--                              } else if (target_type == TypeManager.char_type){
--                                      if (v >= 0)
--                                              return (char) v;
--                              } else if (target_type == TypeManager.byte_type){
--                                      if (v >= Byte.MinValue && v <= Byte.MaxValue)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.sbyte_type){
--                                      if (v >= SByte.MinValue && v <= SByte.MaxValue)
--                                              return (sbyte) v;
--                              } else if (target_type == TypeManager.ushort_type){
--                                      if (v >= 0)
--                                              return (ushort) v;
--                              } else if (target_type == TypeManager.int64_type)
--                                      return (long) v;
--                              else if (target_type == TypeManager.uint64_type)
--                                      return (ulong) v;
--                      } else if (c is UShortConstant){
--                              ushort v = ((UShortConstant) c).Value;
--                              
--                              if (target_type == TypeManager.int32_type)
--                                      return (int) v;
--                              else if (target_type == TypeManager.uint32_type)
--                                      return (uint) v;
--                              else if (target_type == TypeManager.char_type){
--                                      if (v >= Char.MinValue && v <= Char.MaxValue)
--                                              return (char) v;
--                              } else if (target_type == TypeManager.byte_type){
--                                      if (v >= Byte.MinValue && v <= Byte.MaxValue)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.sbyte_type){
--                                      if (v <= SByte.MaxValue)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.short_type){
--                                      if (v <= Int16.MaxValue)
--                                              return (short) v;
--                              } else if (target_type == TypeManager.int64_type)
--                                      return (long) v;
--                              else if (target_type == TypeManager.uint64_type)
--                                      return (ulong) v;
--
--                      } else if (c is CharConstant){
--                              char v = ((CharConstant) c).Value;
--                              
--                              if (target_type == TypeManager.int32_type)
--                                      return (int) v;
--                              else if (target_type == TypeManager.uint32_type)
--                                      return (uint) v;
--                              else if (target_type == TypeManager.byte_type){
--                                      if (v >= Byte.MinValue && v <= Byte.MaxValue)
--                                              return (byte) v;
--                              } else if (target_type == TypeManager.sbyte_type){
--                                      if (v <= SByte.MaxValue)
--                                              return (sbyte) v;
--                              } else if (target_type == TypeManager.short_type){
--                                      if (v <= Int16.MaxValue)
--                                              return (short) v;
--                              } else if (target_type == TypeManager.ushort_type)
--                                      return (short) v;
--                              else if (target_type == TypeManager.int64_type)
--                                      return (long) v;
--                              else if (target_type == TypeManager.uint64_type)
--                                      return (ulong) v;
--
--                      }
--                      c.Error_ConstantValueCannotBeConverted (loc, target_type);
--                      return null;
--              }
  
                //
                // Load the object from the pointer.  
                        child.Emit (ec);
                }
  
++              public override Constant Increment ()
++              {
++                      throw new NotSupportedException ();
++              }
++
                public override bool IsDefaultValue {
                        get {
                                throw new NotImplementedException ();
                        return Child.GetValue ();
                }
  
--              public object GetValueAsEnumType ()
++              public override object GetTypedValue ()
                {
++                      // FIXME: runtime is not ready to work with just emited enums
++                      if (!RootContext.StdLib) {
++                              return Child.GetValue ();
++                      }
++
                        return System.Enum.ToObject (type, Child.GetValue ());
                }
--
--              //
--              // Converts from one of the valid underlying types for an enumeration
--              // (int32, uint32, int64, uint64, short, ushort, byte, sbyte) to
--              // one of the internal compiler literals: Int/UInt/Long/ULong Literals.
--              //
--              public Constant WidenToCompilerConstant ()
++              
++              public override void Error_ValueCannotBeConverted (Location loc, Type t)
                {
--                      Type t = TypeManager.EnumToUnderlying (Child.Type);
--                      object v = ((Constant) Child).GetValue ();;
--                      
--                      if (t == TypeManager.int32_type)
--                              return new IntConstant ((int) v);
--                      if (t == TypeManager.uint32_type)
--                              return new UIntConstant ((uint) v);
--                      if (t == TypeManager.int64_type)
--                              return new LongConstant ((long) v);
--                      if (t == TypeManager.uint64_type)
--                              return new ULongConstant ((ulong) v);
--                      if (t == TypeManager.short_type)
--                              return new ShortConstant ((short) v);
--                      if (t == TypeManager.ushort_type)
--                              return new UShortConstant ((ushort) v);
--                      if (t == TypeManager.byte_type)
--                              return new ByteConstant ((byte) v);
--                      if (t == TypeManager.sbyte_type)
--                              return new SByteConstant ((sbyte) v);
--
--                      throw new Exception ("Invalid enumeration underlying type: " + t);
++                      Convert.Error_CannotImplicitConversion (loc, Type, t);
                }
  
--              //
--              // Extracts the value in the enumeration on its native representation
--              //
--              public object GetPlainValue ()
--              {
--                      Type t = TypeManager.EnumToUnderlying (Child.Type);
--                      object v = ((Constant) Child).GetValue ();;
--                      
--                      if (t == TypeManager.int32_type)
--                              return (int) v;
--                      if (t == TypeManager.uint32_type)
--                              return (uint) v;
--                      if (t == TypeManager.int64_type)
--                              return (long) v;
--                      if (t == TypeManager.uint64_type)
--                              return (ulong) v;
--                      if (t == TypeManager.short_type)
--                              return (short) v;
--                      if (t == TypeManager.ushort_type)
--                              return (ushort) v;
--                      if (t == TypeManager.byte_type)
--                              return (byte) v;
--                      if (t == TypeManager.sbyte_type)
--                              return (sbyte) v;
--
--                      return null;
--              }
--              
                public override string AsString ()
                {
                        return Child.AsString ();
                        return Child.ConvertToInt ();
                }
  
++              public override Constant Increment()
++              {
++                      return new EnumConstant (Child.Increment (), type);
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return Child.IsDefaultValue;
                                return Child.IsNegative;
                        }
                }
++
++              public override Constant ToType (Type type, Location loc)
++              {
++                      if (Type == type) {
++                              // This is workaround of mono bug. It can be removed when the latest corlib spreads enough
++                              if (TypeManager.IsEnumType (type.UnderlyingSystemType))
++                                      return this;
++
++                              if (type.UnderlyingSystemType != Child.Type)
++                                      Child = Child.ToType (type.UnderlyingSystemType, loc);
++                              return this;
++                      }
++
++                      if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, this, type)){
++                              Error_ValueCannotBeConverted (loc, type);
++                              return null;
++                      }
++
++                      return Child.ToType (type, loc);
++              }
++
        }
  
        /// <summary>
                public override Expression ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
                                                                SimpleName original)
                {
--                      bool left_is_type = left is TypeExpr;
++                      if (FieldInfo.IsLiteral) {
++                              IConstant ic = TypeManager.GetConstant (FieldInfo);
++                              if (ic == null) {
++                                      ic = new ExternalConstant (FieldInfo);
++                                      TypeManager.RegisterConstant (FieldInfo, ic);
++                              }
  
--                      Type decl_type = FieldInfo.DeclaringType;
--                      
--                      bool is_emitted = FieldInfo is FieldBuilder;
--                      Type t = FieldInfo.FieldType;
--                      
--                      if (is_emitted) {
--                              Const c = TypeManager.LookupConstant ((FieldBuilder) FieldInfo);
--                              
--                              if (c != null) {
--                                      object o;
--                                      if (!c.LookupConstantValue (out o))
--                                              return null;
++                              bool left_is_type = left is TypeExpr;
++                              if (!left_is_type && (original == null || !original.IdenticalNameAndTypeName (ec, left, loc))) {
++                                      Report.SymbolRelatedToPreviousError (FieldInfo);
++                                      error176 (loc, TypeManager.GetFullNameSignature (FieldInfo));
++                                      return null;
++                              }
  
--                                      c.SetMemberIsUsed ();
--                                      object real_value = ((Constant) c.Expr).GetValue ();
++                              if (ic.ResolveValue ())
++                                      ic.CheckObsoleteness (loc);
  
--                                      Expression exp = Constantify (real_value, t);
--                                      
--                                      if (!left_is_type && 
--                                          (original == null || !original.IdenticalNameAndTypeName (ec, left, loc))) {
--                                              Report.SymbolRelatedToPreviousError (c);
--                                              error176 (loc, c.GetSignatureForError ());
--                                              return null;
--                                      }
--                                      
--                                      return exp;
--                              }
++                              return ic.Value;
                        }
  
++                      bool is_emitted = FieldInfo is FieldBuilder;
++                      Type t = FieldInfo.FieldType;
++                      
                        //
                        // Decimal constants cannot be encoded in the constant blob, and thus are marked
                        // as IsInitOnly ('readonly' in C# parlance).  We get its value from the 
                        // DecimalConstantAttribute metadata.
                        //
++                      //TODO: incorporare in GetContant otherwise we miss all error checks + obsoleteness check
                        if (FieldInfo.IsInitOnly && !is_emitted && t == TypeManager.decimal_type) {
                                object[] attrs = FieldInfo.GetCustomAttributes (TypeManager.decimal_constant_attribute_type, false);
                                if (attrs.Length == 1)
                                        return new DecimalConstant (((System.Runtime.CompilerServices.DecimalConstantAttribute) attrs [0]).Value);
                        }
                        
--                      if (FieldInfo.IsLiteral) {
--                              object o;
--                              
--                              if (is_emitted)
--                                      o = TypeManager.GetValue ((FieldBuilder) FieldInfo);
--                              else
--                                      o = FieldInfo.GetValue (FieldInfo);
--                              
--                              if (decl_type.IsSubclassOf (TypeManager.enum_type)) {
--                                      if (!left_is_type &&
--                                          (original == null || !original.IdenticalNameAndTypeName (ec, left, loc))) {
--                                              error176 (loc, TypeManager.GetFullNameSignature (FieldInfo));
--                                              return null;
--                                      }                                       
--                                      
--                                      Expression enum_member = MemberLookup (
--                                             ec, decl_type, "value__", MemberTypes.Field,
--                                             AllBindingFlags | BindingFlags.NonPublic, loc); 
--                                      
--                                      Enum en = TypeManager.LookupEnum (decl_type);
--                                      
--                                      Constant c;
--                                      if (en != null)
--                                              c = Constantify (o, en.UnderlyingType);
--                                      else 
--                                              c = Constantify (o, enum_member.Type);
--                                      
--                                      return new EnumConstant (c, decl_type);
--                              }
--
--                              Expression exp = Constantify (o, t);
--                              
--                              if (!left_is_type) {
--                                      error176 (loc, TypeManager.GetFullNameSignature (FieldInfo));
--                                      return null;
--                              }
--                              
--                              return exp;
--                      }
--                      
                        if (t.IsPointer && !ec.InUnsafe) {
                                UnsafeError (loc);
                                return null;
                                ObsoleteAttribute oa;
                                FieldBase f = TypeManager.GetField (FieldInfo);
                                if (f != null) {
--                                      oa = f.GetObsoleteAttribute (f.Parent);
--                                      if (oa != null)
--                                              AttributeTester.Report_ObsoleteMessage (oa, f.GetSignatureForError (), loc);
++                                      f.CheckObsoleteness (loc);
                                  
                                        // To be sure that type is external because we do not register generated fields
                                } else if (!(FieldInfo.DeclaringType is TypeBuilder)) {                                
diff --cc mcs/mcs/enum.cs
index eaaa390e05a38d3df42f7e1215e948d53b46d29b,eaaa390e05a38d3df42f7e1215e948d53b46d29b..e4d4167c46e522b69b220607e38e104e8162dc55
@@@ -19,20 -19,20 +19,26 @@@ using System.Globalization
  
  namespace Mono.CSharp {
  
--      class EnumMember: MemberCore {
++      public class EnumMember: MemberCore, IConstant {
                static string[] attribute_targets = new string [] { "field" };
  
--              Enum parent_enum;
                public FieldBuilder builder;
--              internal readonly Expression Type;
  
--              public EnumMember (Enum parent_enum, Expression expr, string name, Location loc,
--                                 Attributes attrs):
--                      base (null, new MemberName (name, loc), attrs)
++              readonly Enum parent_enum;
++              readonly Expression ValueExpr;
++              readonly EnumMember prev_member;
++
++              Constant value;
++              bool in_transit;
++
++              public EnumMember (Enum parent_enum, EnumMember prev_member, Expression expr,
++                              MemberName name, Attributes attrs):
++                      base (parent_enum.Parent, name, attrs)
                {
                        this.parent_enum = parent_enum;
                        this.ModFlags = parent_enum.ModFlags;
--                      this.Type = expr;
++                      this.ValueExpr = expr;
++                      this.prev_member = prev_member;
                }
  
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
                        }
                }
  
--              public void DefineMember (TypeBuilder tb)
++              bool IsValidEnumType (Type t)
++              {
++                      return (t == TypeManager.int32_type || t == TypeManager.uint32_type || t == TypeManager.int64_type ||
++                              t == TypeManager.byte_type || t == TypeManager.sbyte_type || t == TypeManager.short_type ||
++                              t == TypeManager.ushort_type || t == TypeManager.uint64_type || t == TypeManager.char_type ||
++                              t.IsEnum);
++              }
++      
++              public override bool Define ()
                {
--                      FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static
--                              | FieldAttributes.Literal;
--                      
++                      const FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
++                      TypeBuilder tb = parent_enum.TypeBuilder;
                        builder = tb.DefineField (Name, tb, attr);
++
++                      TypeManager.RegisterConstant (builder, this);
++                      return true;
                }
  
--              public override bool Define ()
++              public bool ResolveValue ()
                {
--                      throw new NotImplementedException ();
++                      if (value != null)
++                              return true;
++
++                      if (in_transit) {
++                              // suppress cyclic errors
++                              value = new EnumConstant (New.Constantify (parent_enum.UnderlyingType), parent_enum.TypeBuilder);
++                              Const.Error_CyclicDeclaration (this);
++                              return false;
++                      }
++
++                      if (ValueExpr != null) {
++                              in_transit = true;
++
++                              Constant c = ValueExpr.ResolveAsConstant (parent_enum.EmitContext, this);
++                              if (c == null)
++                                      return false;
++
++                              if (c is EnumConstant)
++                                      c = ((EnumConstant)c).Child;
++                                      
++                              c = c.ToType (parent_enum.UnderlyingType, Location);
++                              if (c == null)
++                                      return false;
++
++                              if (!IsValidEnumType (c.Type)) {
++                                      Report.Error (1008, Location, "Type byte, sbyte, short, ushort, int, uint, long or ulong expected");
++                                      return false;
++                              }
++
++                              in_transit = false;
++                              value = new EnumConstant (c, parent_enum.TypeBuilder);
++                              return true;
++                      }
++
++                      if (prev_member == null) {
++                              value = new EnumConstant (New.Constantify (parent_enum.UnderlyingType), parent_enum.TypeBuilder);
++                              return true;
++                      }
++
++                      if (!prev_member.ResolveValue ())
++                              return false;
++
++                      in_transit = true;
++
++                      try {
++                              value = prev_member.value.Increment ();
++                      }
++                      catch (OverflowException) {
++                              Report.Error (543, Location, "The enumerator value `{0}' is too large to fit in its type `{1}'",
++                                      GetSignatureForError (), TypeManager.CSharpName (parent_enum.UnderlyingType));
++                              return false;
++                      }
++                      in_transit = false;
++
++                      return true;
                }
  
                public void Emit (EmitContext ec)
                        if (OptAttributes != null)
                                OptAttributes.Emit (ec, this); 
  
++                      if (ResolveValue ())
++                              builder.SetConstant (value.GetValue ());
++
                        Emit ();
                }
  
                public override string DocCommentHeader {
                        get { return "F:"; }
                }
++
++              #region IConstant Members
++
++              public Constant Value {
++                      get {
++                              return value;
++                      }
++              }
++
++              #endregion
        }
  
        /// <summary>
        ///   Enumeration container
        /// </summary>
        public class Enum : DeclSpace {
--              public ArrayList ordered_enums;
--              
--              public Expression BaseType;
--              
++              Expression BaseType;
                public Type UnderlyingType;
  
--              Hashtable member_to_location;
--
--              //
--              // This is for members that have been defined
--              //
--              Hashtable member_to_value;
--
--              //
--              // This is used to mark members we're currently defining
--              //
--              Hashtable in_transit;
--              
--              ArrayList field_builders;
++              static MemberList no_list = new MemberList (new object[0]);
                
                public const int AllowedModifiers =
                        Modifiers.NEW |
                        this.BaseType = type;
                        ModFlags = Modifiers.Check (AllowedModifiers, mod_flags,
                                                    IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, name.Location);
--
--                      ordered_enums = new ArrayList ();
--                      member_to_location = new Hashtable ();
--                      member_to_value = new Hashtable ();
--                      in_transit = new Hashtable ();
--                      field_builders = new ArrayList ();
                }
  
--              /// <summary>
--              ///   Adds @name to the enumeration space, with @expr
--              ///   being its definition.  
--              /// </summary>
--              public void AddEnumMember (string name, Expression expr, Location loc, Attributes opt_attrs, string documentation)
++              public void AddEnumMember (EnumMember em)
                {
--                      if (name == "value__") {
--                              Report.Error (76, loc, "An item in an enumeration cannot have an identifier `value__'");
++                      if (em.Name == "value__") {
++                              Report.Error (76, em.Location, "An item in an enumeration cannot have an identifier `value__'");
                                return;
                        }
  
--                      EnumMember em = new EnumMember (this, expr, name, loc, opt_attrs);
--                      em.DocComment = documentation;
--                      if (!AddToContainer (em, name))
++                      if (!AddToContainer (em, em.Name))
                                return;
--
--
--                      // TODO: can be almost deleted
--                      ordered_enums.Add (name);
--                      member_to_location.Add (name, loc);
                }
                
                public override TypeBuilder DefineType ()
  
                        TypeManager.AddUserType (Name, this);
  
--                      return TypeBuilder;
--              }
--
--              bool IsValidEnumConstant (Expression e)
--              {
--                      if (!(e is Constant))
--                              return false;
--
--                      if (e is IntConstant || e is UIntConstant || e is LongConstant ||
--                          e is ByteConstant || e is SByteConstant || e is ShortConstant ||
--                          e is UShortConstant || e is ULongConstant || e is EnumConstant ||
--                          e is CharConstant)
--                              return true;
--                      else
--                              return false;
--              }
--
--              object GetNextDefaultValue (object default_value)
--              {
--                      if (UnderlyingType == TypeManager.int32_type) {
--                              int i = (int) default_value;
--                              
--                              if (i < System.Int32.MaxValue)
--                                      return ++i;
--                              else
--                                      return null;
--                      } else if (UnderlyingType == TypeManager.uint32_type) {
--                              uint i = (uint) default_value;
--
--                              if (i < System.UInt32.MaxValue)
--                                      return ++i;
--                              else
--                                      return null;
--                      } else if (UnderlyingType == TypeManager.int64_type) {
--                              long i = (long) default_value;
--
--                              if (i < System.Int64.MaxValue)
--                                      return ++i;
--                              else
--                                      return null;
--                      } else if (UnderlyingType == TypeManager.uint64_type) {
--                              ulong i = (ulong) default_value;
--
--                              if (i < System.UInt64.MaxValue)
--                                      return ++i;
--                              else
--                                      return null;
--                      } else if (UnderlyingType == TypeManager.short_type) {
--                              short i = (short) default_value;
--
--                              if (i < System.Int16.MaxValue)
--                                      return ++i;
--                              else
--                                      return null;
--                      } else if (UnderlyingType == TypeManager.ushort_type) {
--                              ushort i = (ushort) default_value;
--
--                              if (i < System.UInt16.MaxValue)
--                                      return ++i;
--                              else
--                                      return null;
--                      } else if (UnderlyingType == TypeManager.byte_type) {
--                              byte i = (byte) default_value;
--
--                              if (i < System.Byte.MaxValue)
--                                      return ++i;
--                              else
--                                      return null;
--                      } else if (UnderlyingType == TypeManager.sbyte_type) {
--                              sbyte i = (sbyte) default_value;
--
--                              if (i < System.SByte.MaxValue)
--                                      return ++i;
--                              else
--                                      return null;
--                      }
--
--                      return null;
--              }
--
--              /// <summary>
--              ///  Determines if a standard implicit conversion exists from
--              ///  expr_type to target_type
--              /// </summary>
--              public static bool ImplicitConversionExists (Type expr_type, Type target_type)
--              {
--                      expr_type = TypeManager.TypeToCoreType (expr_type);
--
--                      if (expr_type == TypeManager.void_type)
--                              return false;
--                      
--                      if (expr_type == target_type)
--                              return true;
--
--                      // First numeric conversions 
--
--                      if (expr_type == TypeManager.sbyte_type){
--                              //
--                              // From sbyte to short, int, long, float, double.
--                              //
--                              if ((target_type == TypeManager.int32_type) || 
--                                  (target_type == TypeManager.int64_type) ||
--                                  (target_type == TypeManager.double_type) ||
--                                  (target_type == TypeManager.float_type)  ||
--                                  (target_type == TypeManager.short_type) ||
--                                  (target_type == TypeManager.decimal_type))
--                                      return true;
--                              
--                      } else if (expr_type == TypeManager.byte_type){
--                              //
--                              // From byte to short, ushort, int, uint, long, ulong, float, double
--                              // 
--                              if ((target_type == TypeManager.short_type) ||
--                                  (target_type == TypeManager.ushort_type) ||
--                                  (target_type == TypeManager.int32_type) ||
--                                  (target_type == TypeManager.uint32_type) ||
--                                  (target_type == TypeManager.uint64_type) ||
--                                  (target_type == TypeManager.int64_type) ||
--                                  (target_type == TypeManager.float_type) ||
--                                  (target_type == TypeManager.double_type) ||
--                                  (target_type == TypeManager.decimal_type))
--                                      return true;
--      
--                      } else if (expr_type == TypeManager.short_type){
--                              //
--                              // From short to int, long, float, double
--                              // 
--                              if ((target_type == TypeManager.int32_type) ||
--                                  (target_type == TypeManager.int64_type) ||
--                                  (target_type == TypeManager.double_type) ||
--                                  (target_type == TypeManager.float_type) ||
--                                  (target_type == TypeManager.decimal_type))
--                                      return true;
--                                      
--                      } else if (expr_type == TypeManager.ushort_type){
--                              //
--                              // From ushort to int, uint, long, ulong, float, double
--                              //
--                              if ((target_type == TypeManager.uint32_type) ||
--                                  (target_type == TypeManager.uint64_type) ||
--                                  (target_type == TypeManager.int32_type) ||
--                                  (target_type == TypeManager.int64_type) ||
--                                  (target_type == TypeManager.double_type) ||
--                                  (target_type == TypeManager.float_type) ||
--                                  (target_type == TypeManager.decimal_type))
--                                      return true;
--                                  
--                      } else if (expr_type == TypeManager.int32_type){
--                              //
--                              // From int to long, float, double
--                              //
--                              if ((target_type == TypeManager.int64_type) ||
--                                  (target_type == TypeManager.double_type) ||
--                                  (target_type == TypeManager.float_type) ||
--                                  (target_type == TypeManager.decimal_type))
--                                      return true;
--                                      
--                      } else if (expr_type == TypeManager.uint32_type){
--                              //
--                              // From uint to long, ulong, float, double
--                              //
--                              if ((target_type == TypeManager.int64_type) ||
--                                  (target_type == TypeManager.uint64_type) ||
--                                  (target_type == TypeManager.double_type) ||
--                                  (target_type == TypeManager.float_type) ||
--                                  (target_type == TypeManager.decimal_type))
--                                      return true;
--                                      
--                      } else if ((expr_type == TypeManager.uint64_type) ||
--                                 (expr_type == TypeManager.int64_type)) {
--                              //
--                              // From long/ulong to float, double
--                              //
--                              if ((target_type == TypeManager.double_type) ||
--                                  (target_type == TypeManager.float_type) ||
--                                  (target_type == TypeManager.decimal_type))
--                                      return true;
--                                  
--                      } else if (expr_type == TypeManager.char_type){
--                              //
--                              // From char to ushort, int, uint, long, ulong, float, double
--                              // 
--                              if ((target_type == TypeManager.ushort_type) ||
--                                  (target_type == TypeManager.int32_type) ||
--                                  (target_type == TypeManager.uint32_type) ||
--                                  (target_type == TypeManager.uint64_type) ||
--                                  (target_type == TypeManager.int64_type) ||
--                                  (target_type == TypeManager.float_type) ||
--                                  (target_type == TypeManager.double_type) ||
--                                  (target_type == TypeManager.decimal_type))
--                                      return true;
--
--                      } else if (expr_type == TypeManager.float_type){
--                              //
--                              // float to double
--                              //
--                              if (target_type == TypeManager.double_type)
--                                      return true;
--                      }       
--                      
--                      return false;
--              }
--
--              /// <summary>
--              ///  This is used to lookup the value of an enum member. If the member is undefined,
--              ///  it attempts to define it and return its value
--              /// </summary>
--              public object LookupEnumValue (string name, Location loc)
--              {
--                      if (ec == null)
--                              Report.Error (-1, loc, "Enum.LookupEnumValue () called too soon");
--                      
--                      object default_value = null;
--                      Constant c = null;
--
--                      default_value = member_to_value [name];
--
--                      if (default_value != null)
--                              return default_value;
--
--                      //
--                      // This may happen if we're calling a method in System.Enum, for instance
--                      // Enum.IsDefined().
--                      //
--                      if (!defined_names.Contains (name))
--                              return null;
--
--                      if (in_transit.Contains (name)) {
--                              Report.Error (110, loc, "The evaluation of the constant value for `" +
--                                            Name + "." + name + "' involves a circular definition.");
--                              return null;
--                      }
--
--                      //
--                      // So if the above doesn't happen, we have a member that is undefined
--                      // We now proceed to define it 
--                      //
--                      Expression val = this [name];
--
--                      if (val == null) {
--                              
--                              int idx = ordered_enums.IndexOf (name);
--
--                              if (idx == 0)
--                                      default_value = 0;
--                              else {
--                                      for (int i = 0; i < idx; ++i) {
--                                              string n = (string) ordered_enums [i];
--                                              Location m_loc = (Mono.CSharp.Location)
--                                                      member_to_location [n];
--                                              in_transit.Add (name, true);
--                                              default_value = LookupEnumValue (n, m_loc);
--                                              in_transit.Remove (name);
--                                              if (default_value == null)
--                                                      return null;
--                                      }
--                                      
--                                      default_value = GetNextDefaultValue (default_value);
--                              }
--                              
--                      } else {
--                              in_transit.Add (name, true);
--                              val = val.Resolve (EmitContext);
--                              in_transit.Remove (name);
--
--                              if (val == null)
--                                      return null;
--
--                              if (!IsValidEnumConstant (val)) {
--                                      Report.Error (1008, loc,
--                                              "Type byte, sbyte, short, ushort, int, uint, long or ulong expected");
--                                      return null;
--                              }
--
--                              c = (Constant) val;
--                              default_value = c.GetValue ();
--
--                              if (default_value == null) {
--                                      c.Error_ConstantValueCannotBeConverted (loc, UnderlyingType);
++                      foreach (EnumMember em in defined_names.Values) {
++                              if (!em.Define ())
                                        return null;
--                              }
--
--                              if (val is EnumConstant){
--                                      Type etype = TypeManager.EnumToUnderlying (c.Type);
--                                      
--                                      if (!ImplicitConversionExists (etype, UnderlyingType)){
--                                              Convert.Error_CannotImplicitConversion (
--                                                      loc, c.Type, UnderlyingType);
--                                              return null;
--                                      }
--                              }
                        }
  
--                      EnumMember em = (EnumMember) defined_names [name];
--                      em.DefineMember (TypeBuilder);
--
--                      bool fail;
--                      default_value = TypeManager.ChangeType (default_value, UnderlyingType, out fail);
--                      if (fail){
--                              c.Error_ConstantValueCannotBeConverted (loc, UnderlyingType);
--                              return null;
--                      }
--
--                      em.builder.SetConstant (default_value);
--                      field_builders.Add (em.builder);
--                      member_to_value [name] = default_value;
--
--                      if (!TypeManager.RegisterFieldValue (em.builder, default_value))
--                              return null;
--
--                      return default_value;
++                      return TypeBuilder;
                }
                
                public override bool Define ()
                {
--                      //
--                      // If there was an error during DefineEnum, return
--                      //
--                      if (TypeBuilder == null)
--                              return false;
--
--                      if (ec == null)
--                              throw new InternalErrorException ("Enum.Define () called too soon");
--                      
--                      object default_value = 0;
--                      
--              
--                      foreach (string name in ordered_enums) {
--                              //
--                              // Have we already been defined, thanks to some cross-referencing ?
--                              // 
--                              if (member_to_value.Contains (name))
--                                      continue;
--                              
--                              Location loc = (Mono.CSharp.Location) member_to_location [name];
--
--                              if (this [name] != null) {
--                                      default_value = LookupEnumValue (name, loc);
--
--                                      if (default_value == null)
--                                              return true;
--                              } else {
--                                      EnumMember em = (EnumMember) defined_names [name];
--
--                                      em.DefineMember (TypeBuilder);
--                                      FieldBuilder fb = em.builder;
--                                      
--                                      if (default_value == null) {
--                                         Report.Error (543, loc, "The enumerator value `{0}.{1}' is too large to fit in its type `{2}'",
--                                                 GetSignatureForError (), name, TypeManager.CSharpName (this.UnderlyingType));
--                                              return false;
--                                      }
--
--                                      bool fail;
--                                      default_value = TypeManager.ChangeType (default_value, UnderlyingType, out fail);
--                                      if (fail){
--                                              //TODO: really interested if can be reached
--                                              throw new NotImplementedException ();
--                                      }
--
--                                      fb.SetConstant (default_value);
--                                      field_builders.Add (fb);
--                                      member_to_value [name] = default_value;
--                                      
--                                      if (!TypeManager.RegisterFieldValue (fb, default_value))
--                                              return false;
--                              }
--
--                              default_value = GetNextDefaultValue (default_value);
--                      }
--
                        return true;
                }
  
  
                        base.Emit ();
                }
--              
++
++              //
++              // IMemberFinder
++              //
++              public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
++                      MemberFilter filter, object criteria)
++              {
++                      if ((mt & MemberTypes.Field) == 0)
++                              return no_list;
++
++                      EnumMember em = defined_names [criteria] as EnumMember;
++                      if (em == null)
++                              return no_list;
++
++                      FieldBuilder[] fb = new FieldBuilder[] { em.builder };
++                      return new MemberList (fb);
++              }
++
                void VerifyClsName ()
                {
                        HybridDictionary dict = new HybridDictionary (defined_names.Count, true);
  
                        return true;
                }
--              
--              //
--              // IMemberFinder
--              //
--              public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
--                                                      MemberFilter filter, object criteria)
--              {
--                      ArrayList members = new ArrayList ();
--
--                      if ((mt & MemberTypes.Field) != 0) {
--                              if (criteria is string && member_to_value [criteria] == null) {
--                                      LookupEnumValue ((string) criteria, Location.Null);
--                              }
--                              
--                              foreach (FieldBuilder fb in field_builders)
--                                      if (filter (fb, criteria) == true)
--                                              members.Add (fb);
--                      }
--
--                      return new MemberList (members);
--              }
++      
  
                public override MemberCache MemberCache {
                        get {
                        }
                }
  
--              public ArrayList ValueNames {
--                      get {
--                              return ordered_enums;
--                      }
--              }
--
--              // indexer
--              public Expression this [string name] {
--                      get {
--                              return ((EnumMember) defined_names [name]).Type;
--                      }
--              }
--
                public override AttributeTargets AttributeTargets {
                        get {
                                return AttributeTargets.Enum;
                        }
                }
  
--
                protected override void VerifyObsoleteAttribute()
                {
                        // UnderlyingType is never obsolete
                //
                internal override void GenerateDocComment (DeclSpace ds)
                {
--                      DocUtil.GenerateEnumDocComment (this, ds);
++                      base.GenerateDocComment (ds);
++
++                      foreach (EnumMember em in defined_names.Values) {
++                              em.GenerateDocComment (this);
++                      }
                }
  
                //
index e815e8340d86cad58d3912b705a70722cd3c152d,e815e8340d86cad58d3912b705a70722cd3c152d..6361593a76daa5cc4b38cf43e38800e7d08022bb
@@@ -1332,11 -1332,11 +1332,18 @@@ namespace Mono.CSharp 
                        return true;
                }
  
++              // TODO: move to constant
                /// <summary>
                ///   Attempts to do a compile-time folding of a constant cast.
                /// </summary>
                Expression TryReduce (EmitContext ec, Type target_type)
                {
++                      if (expr.Type == target_type)
++                              return expr;
++
++                      if (TypeManager.IsEnumType (target_type))
++                              return new EnumConstant ((Constant)expr, target_type);
++
                        Expression real_expr = expr;
                        if (real_expr is EnumConstant)
                                real_expr = ((EnumConstant) real_expr).Child;
                        }
  
                        if (rc != null && lc != null){
++                              int prev_e = Report.Errors;
                                Expression e = ConstantFold.BinaryFold (
                                        ec, oper, lc, rc, loc);
--                              if (e != null)
++                              if (e != null || Report.Errors != prev_e)
                                        return e;
                        }
  
                }
  
                /// <summary>
--              ///   Determines "better conversion" as specified in 7.4.2.3
++              ///   Determines "better conversion" as specified in 14.4.2.3
                ///
                  ///    Returns : p    if a->p is better,
                ///              q    if a->q is better,
                /// <summary>
                /// Converts complex core type syntax like 'new int ()' to simple constant
                /// </summary>
--              Expression Constantify (Type t)
++              public static Constant Constantify (Type t)
                {
                        if (t == TypeManager.int32_type)
                                return new IntConstant (0);
        ///   Implements the member access expression
        /// </summary>
        public class MemberAccess : Expression {
--              public readonly string Identifier;
++              public readonly string Identifier;  // TODO: LocatedToken
                Expression expr;
                
                public MemberAccess (Expression expr, string id, Location l)
                        get { return expr; }
                }
  
++              // TODO: this method has very poor performace for Enum fields and
++              // probably for other constants as well
                Expression DoResolve (EmitContext ec, Expression right_side)
                {
                        if (type != null)
                                return retval;
                        }
  
--                      //
--                      // TODO: I mailed Ravi about this, and apparently we can get rid
--                      // of this and put it in the right place.
--                      // 
--                      // Handle enums here when they are in transit.
--                      // Note that we cannot afford to hit MemberLookup in this case because
--                      // it will fail to find any members at all
--                      //
--
                        Type expr_type = new_expr.Type;
--                      if (new_expr is TypeExpr){
--                              if (!ec.DeclSpace.CheckAccessLevel (expr_type)){
--                                      ErrorIsInaccesible (loc, TypeManager.CSharpName (expr_type));
--                                      return null;
--                              }
--
--                              if (expr_type == TypeManager.enum_type || expr_type.IsSubclassOf (TypeManager.enum_type)){
--                                      Enum en = TypeManager.LookupEnum (expr_type);
--
--                                      if (en != null) {
--                                              object value = en.LookupEnumValue (Identifier, loc);
--                                              if (value != null){
--                                                      MemberCore mc = en.GetDefinition (Identifier);
--                                                      ObsoleteAttribute oa = mc.GetObsoleteAttribute (en);
--                                                      if (oa != null) {
--                                                              AttributeTester.Report_ObsoleteMessage (oa, mc.GetSignatureForError (), Location);
--                                                      }
--                                                      oa = en.GetObsoleteAttribute (en);
--                                                      if (oa != null) {
--                                                              AttributeTester.Report_ObsoleteMessage (oa, en.GetSignatureForError (), Location);
--                                                      }
--
--                                                      Constant c = Constantify (value, en.UnderlyingType);
--                                                      return new EnumConstant (c, expr_type);
--                                              }
--                                      } else {
--                                              CheckObsoleteAttribute (expr_type);
--
--                                              FieldInfo fi = expr_type.GetField (Identifier);
--                                              if (fi != null) {
--                                                      ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (fi);
--                                                      if (oa != null)
--                                                              AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (fi), Location);
--                                              }
--                                      }
--                              }
--                      }
--
                        if (expr_type.IsPointer){
                                Error (23, "The `.' operator can not be applied to pointer operands (" +
                                       TypeManager.CSharpName (expr_type) + ")");
index fcdb869a6b0ca51709a52bb8a8018d8b7edfc50a,fcdb869a6b0ca51709a52bb8a8018d8b7edfc50a..8582a4f8dfcd4facf87622c8242f002da9add880
@@@ -80,6 -80,6 +80,11 @@@ namespace Mono.CSharp 
                        ec.ig.Emit (OpCodes.Ldnull);
                }
  
++              public override Constant Increment ()
++              {
++                      throw new NotSupportedException ();
++              }
++
                public override bool IsDefaultValue {
                        get {
                                return true;
                        return "null";
                }
  
--              public override void Error_ConstantValueCannotBeConverted (Location loc, Type t)
++              public override void Error_ValueCannotBeConverted (Location loc, Type t)
                {
                        Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
                                TypeManager.CSharpName (t));
                }
++
++              public override Constant ToType (Type type, Location loc)
++              {
++                      if (!type.IsValueType && !TypeManager.IsEnumType (type))
++                              return NullLiteral.Null;
++
++                      return base.ToType (type, loc);
++              }
++
        }
  
        //
index b1aa97561c3a96c551e9788b77e6c659ff4f8996,b1aa97561c3a96c551e9788b77e6c659ff4f8996..a5ebed1ce98510f6084def2593b459651b8b96da
@@@ -800,21 -800,21 +800,24 @@@ namespace Mono.CSharp 
                        if (expr == null)
                                return false;
  
--                      if (!(expr is Constant)){
++                      Constant c = expr as Constant;
++                      if (c == null) {
                                Error (150, "A constant value is expected");
                                return false;
                        }
  
--                      object val = Expression.ConvertIntLiteral (
--                              (Constant) expr, ec.Switch.SwitchType, loc);
++                      c = c.ToType (ec.Switch.SwitchType, loc);
++                      if (c == null)
++                              return false;
  
++                      object val = c.GetValue ();
                        if (val == null)
--                              return false;
++                              val = c;
                                        
                        sl = (SwitchLabel) ec.Switch.Elements [val];
  
                        if (sl == null){
--                              Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", val);
++                              Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", c.GetValue () == null ? "null" : val);
                                return false;
                        }
  
                                                continue;
                                        }
  
--                                      if (e.Type != variable_type){
--                                              e = Const.ChangeType (vi.Location, ce, variable_type);
--                                              if (e == null)
--                                                      continue;
--                                      }
++                                      e = ce.ToType (variable_type, vi.Location);
++                                      if (e == null)
++                                              continue;
  
                                        constants.Remove (name);
                                        constants.Add (name, e);
                                return false;
                        }
  
--                      if (required_type == TypeManager.string_type) {
--                              if (c.Type == TypeManager.string_type) {
--                                      converted = c.GetValue ();
--                                      return true;
--                              }
--
--                              if (e is NullLiteral) {
--                                      converted = e;
--                                      return true;
--                              }
++                      if (required_type == TypeManager.string_type && e is NullLiteral) {
++                              converted = e;
++                              return true;
                        }
  
--                      converted = Expression.ConvertIntLiteral (c, required_type, loc);
--                      return converted != null;
++                      c = c.ToType (required_type, loc);
++                      if (c == null)
++                              return false;
++
++                      converted = c.GetValue ();
++                      return true;
                }
  
                public void Erorr_AlreadyOccurs ()
index 196a05479e70e44987d43c732a35cb83391fb5ca,196a05479e70e44987d43c732a35cb83391fb5ca..02bcb95cf52188add447e534338bbc72a7abf7fd
@@@ -287,7 -287,7 +287,6 @@@ public class TypeManager 
                builder_to_method = null;
                
                fields = null;
--              builder_to_constant = null;
                fieldbuilders_to_fields = null;
                events = null;
                priv_fields_events = null;
                return builder_to_declspace [t] as Delegate;
        }
  
--      public static Enum LookupEnum (Type t)
--      {
--              return builder_to_declspace [t] as Enum;
--      }
--
        public static Class LookupClass (Type t)
        {
                return (Class) builder_to_declspace [t];
        
        public static bool IsEnumType (Type t)
        {
--              if (t.IsSubclassOf (TypeManager.enum_type))
++              if (builder_to_declspace [t] is Enum)
                        return true;
--              else
--                      return false;
++
++              return t.IsEnum;
        }
++
        public static bool IsBuiltinOrEnum (Type t)
        {
                if (IsBuiltinType (t))
        {
                return t.IsArray || t.IsPointer || t.IsByRef;
        }
--
--      static Hashtable builder_to_constant;
--
--      public static void RegisterConstant (FieldBuilder fb, Const c)
--      {
--              if (builder_to_constant == null)
--                      builder_to_constant = new PtrHashtable ();
--
--              if (builder_to_constant.Contains (fb))
--                      return;
--
--              builder_to_constant.Add (fb, c);
--      }
--
--      public static Const LookupConstant (FieldBuilder fb)
--      {
--              if (builder_to_constant == null)
--                      return null;
--              
--              return (Const) builder_to_constant [fb];
--      }
        
        /// <summary>
        ///   Gigantic work around for missing features in System.Reflection.Emit follows.
                }
        }
        
--      // <remarks>
--      //  This is a workaround the fact that GetValue is not
--      //  supported for dynamic types
--      // </remarks>
--      static public bool RegisterFieldValue (FieldBuilder fb, object value)
++      public static void RegisterConstant (FieldInfo fb, IConstant ic)
        {
--              if (fields.Contains (fb))
--                      return false;
--
--              fields.Add (fb, value);
--
--              return true;
++              fields.Add (fb, ic);
        }
  
--      static public object GetValue (FieldBuilder fb)
++      public static IConstant GetConstant (FieldInfo fb)
        {
--              return fields [fb];
++              if (fb == null)
++                      return null;
++
++              return (IConstant)fields [fb];
        }
  
        static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f)
index 988003ea000b6f0d8914eee8682037bf4145abc8,988003ea000b6f0d8914eee8682037bf4145abc8..3339f69de0f5cf04df6aea6faaac70e2e2637f54
@@@ -63,7 -63,7 +63,7 @@@ TEST_PATTERN = 'test-*.cs
  endif
  
  run-test-local: ilasm
--      MONO_RUNTIME='$(RUNTIME)' $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(PROFILE)/compiler-tester.exe positive $(TEST_PATTERN) $(COMPILER) known-issues-$(COMPILER_NAME) $(COMPILER_NAME).log
++      MONO_RUNTIME='mono' $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(PROFILE)/compiler-tester.exe positive $(TEST_PATTERN) $(COMPILER) known-issues-$(COMPILER_NAME) $(COMPILER_NAME).log
  
  # do nothing for this target
  run-test-ondotnet-local:
index 0d77b8e73ccd749a37499b83634cfdd3c4eb8a13,0d77b8e73ccd749a37499b83634cfdd3c4eb8a13..ae38c7fa5c584873a184291cabbe95fe38e17d06
@@@ -20,6 -20,6 +20,8 @@@ test-433.c
  test-434.cs
  test-435.cs
  test-436.cs
++test-437.cs
++
  test-50.cs IGNORE     # Windows-only test
  test-67.cs IGNORE     # Windows-only test
  test-anon-27.cs
index 404a0cc57e53433a758387592859b0560617f4e8,404a0cc57e53433a758387592859b0560617f4e8..72578323cfdb53dee0fd8ae064db8b1de4ce3c0b
@@@ -7,7 -7,7 +7,8 @@@
  test-50.cs IGNORE     # Windows-only tests
  test-67.cs IGNORE     # Windows-only test
  
--test-308.cs
++test-49.cs IGNORE
++
  test-377.cs
  test-anon-27.cs
  test-xml-027.cs
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..88ed74501ded8ec9980f0266f5ec7a213e816f62
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,40 @@@
++using System;
++using System.Runtime.InteropServices;
++
++class T2
++{
++      public enum E2: sbyte
++      {
++              A = Test.E.d,
++              B = Test.E.a,
++              C = Test.Constant
++      }
++      
++}
++
++class Test
++{
++      public const UnmanagedType UnmanagedType_80 = (UnmanagedType) 80;       
++      public const sbyte Constant = (sbyte)T2.E2.A;
++      
++      public enum E: sbyte
++      {
++              a = -3,
++              b = d,
++              c = T2.E2.B,
++              d,
++              e,
++              f = -Constant,
++              g = checked (3 * 4),
++              h = unchecked ((sbyte)(250 + 10))
++      }
++              
++      public static void Main ()
++      {
++              Console.WriteLine (E.d.ToString ());
++              Console.WriteLine (Constant.ToString ());
++              object o = E.a;
++              Console.WriteLine (E.a);
++              Console.WriteLine (System.Reflection.BindingFlags.NonPublic);
++      }
++}
index 04a76d1a98b8ad3324d8b1217d73b4685630eabf,04a76d1a98b8ad3324d8b1217d73b4685630eabf..298edf269aad1431209072c6f92125847675db70
@@@ -318,6 -318,6 +318,8 @@@ class X 
                        return 5;
                case null:
                        return 9;
++              case "new":
++                      goto case null;
                default:
                        return 6;
                }
                        return 20;
  
                case TestEnum.c:
--                      return 30;
++                      goto case TestEnum.b;
  
                default:
                        return 40;
                        return 1;
                if (testSwitchEnumLong (TestEnum.b) != 20)
                        return 2;
--              if (testSwitchEnumLong (TestEnum.c) != 30)
++              if (testSwitchEnumLong (TestEnum.c) != 20)
                        return 3;
                if (testSwitchEnumLong ((TestEnum)5) != 40)
                        return 4;
                        return 10;
                if (tests ("blah") != 6)
                        return 11;
++              if (tests ("new") != 9)
++                      return 110;
++
  
                if (testn ("one") != 1)
                        return 12;