using System.Reflection;
#endif
-namespace Mono.CSharp {
+namespace Mono.CSharp
+{
public class EnumMember : Const
{
+#if !STATIC
+ class MemberTypeDelegator : TypeDelegator
+ {
+ Type underlyingType;
+
+ public MemberTypeDelegator (Type delegatingType, Type underlyingType)
+ : base (delegatingType)
+ {
+ this.underlyingType = underlyingType;
+ }
+
+ public override Type GetEnumUnderlyingType ()
+ {
+ return underlyingType;
+ }
+
+ public override Type UnderlyingSystemType {
+ get {
+ return underlyingType;
+ }
+ }
+ }
+#endif
+
class EnumTypeExpr : TypeExpr
{
- public override TypeSpec ResolveAsType (IMemberContext ec)
+ public override TypeSpec ResolveAsType (IMemberContext ec, bool allowUnboundTypeArguments)
{
type = ec.CurrentType;
eclass = ExprClass.Type;
if (expr is EnumConstant)
expr = ((EnumConstant) expr).Child;
- var underlying = ((Enum) Parent).UnderlyingType;
+ var en = (Enum)Parent;
+ var underlying = en.UnderlyingType;
if (expr != null) {
- expr = expr.ImplicitConversionRequired (rc, underlying, Location);
+ expr = expr.ImplicitConversionRequired (rc, underlying);
if (expr != null && !IsValidEnumType (expr.Type)) {
- Enum.Error_1008 (Location, Report);
+ en.Error_UnderlyingType (Location);
expr = null;
}
}
if (!ResolveMemberType ())
return false;
+ MetaType ftype = MemberType.GetMetaInfo ();
+#if !STATIC
+ //
+ // Workaround for .net SRE limitation which cannot define field of unbaked enum type
+ // which is how all enums are declared
+ //
+ ftype = new MemberTypeDelegator (ftype, ((Enum)Parent).UnderlyingType.GetMetaInfo ());
+#endif
+
const FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
- FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType.GetMetaInfo (), attr);
+ FieldBuilder = Parent.TypeBuilder.DefineField (Name, ftype, attr);
spec = new ConstSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags, initializer);
Parent.MemberCache.AddMember (spec);
AddMember (em);
}
- public static void Error_1008 (Location loc, Report Report)
+ public void Error_UnderlyingType (Location loc)
{
Report.Error (1008, loc,
"Type byte, sbyte, short, ushort, int, uint, long or ulong expected");
protected override void DoDefineContainer ()
{
- ((EnumSpec) spec).UnderlyingType = underlying_type_expr == null ? Compiler.BuiltinTypes.Int : underlying_type_expr.Type;
+ TypeSpec ut;
+ if (underlying_type_expr != null) {
+ ut = underlying_type_expr.ResolveAsType (this);
+ if (!EnumSpec.IsValidUnderlyingType (ut)) {
+ Error_UnderlyingType (underlying_type_expr.Location);
+ ut = null;
+ }
+ } else {
+ ut = null;
+ }
+
+ if (ut == null)
+ ut = Compiler.BuiltinTypes.Int;
+
+ ((EnumSpec) spec).UnderlyingType = ut;
TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType.GetMetaInfo (),
FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);