X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fmcs%2Fenum.cs;h=3e1c3fc653091cd47f86df6b839d92c96a296127;hb=f8c90493e69dc7afb6137813dea3ab6ddcf46475;hp=a7ed0e2107a3b4b619ad462f0c9ce60b95a3ab80;hpb=54c0b5c4224d5463f9c50d3c6725fc239631df52;p=mono.git diff --git a/mcs/mcs/enum.cs b/mcs/mcs/enum.cs index a7ed0e2107a..3e1c3fc6530 100644 --- a/mcs/mcs/enum.cs +++ b/mcs/mcs/enum.cs @@ -9,6 +9,7 @@ // // Copyright 2001 Ximian, Inc (http://www.ximian.com) // Copyright 2003-2003 Novell, Inc (http://www.novell.com) +// Copyright 2011 Xamarin Inc // using System; @@ -27,15 +28,11 @@ namespace Mono.CSharp { { class EnumTypeExpr : TypeExpr { - protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec) + public override TypeSpec ResolveAsType (IMemberContext ec, bool allowUnboundTypeArguments) { type = ec.CurrentType; - return this; - } - - public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent) - { - return DoResolveAsTypeStep (ec); + eclass = ExprClass.Type; + return type; } } @@ -46,10 +43,20 @@ namespace Mono.CSharp { static bool IsValidEnumType (TypeSpec 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 || - TypeManager.IsEnumType (t)); + switch (t.BuiltinType) { + case BuiltinTypeSpec.Type.Int: + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.Long: + case BuiltinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.SByte: + case BuiltinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.ULong: + case BuiltinTypeSpec.Type.Char: + return true; + default: + return t.IsEnum; + } } public override Constant ConvertInitializer (ResolveContext rc, Constant expr) @@ -57,11 +64,12 @@ namespace Mono.CSharp { 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; } } @@ -69,7 +77,7 @@ namespace Mono.CSharp { if (expr == null) expr = New.Constantify (underlying, Location); - return new EnumConstant (expr, MemberType).Resolve (rc); + return new EnumConstant (expr, MemberType); } public override bool Define () @@ -84,17 +92,23 @@ namespace Mono.CSharp { Parent.MemberCache.AddMember (spec); return true; } + + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + } /// /// Enumeration container /// - public class Enum : TypeContainer + public class Enum : TypeDefinition { // // Implicit enum member initializer, used when no constant value is provided // - class ImplicitInitializer : Expression + sealed class ImplicitInitializer : Expression { readonly EnumMember prev; readonly EnumMember current; @@ -105,6 +119,11 @@ namespace Mono.CSharp { this.prev = prev; } + public override bool ContainsEmitWithAwait () + { + return false; + } + public override Expression CreateExpressionTree (ResolveContext ec) { throw new NotSupportedException ("Missing Resolve call"); @@ -114,18 +133,18 @@ namespace Mono.CSharp { { // We are the first member if (prev == null) { - return New.Constantify (current.Parent.Definition, Location).Resolve (rc); + return New.Constantify (current.Parent.Definition, Location); } var c = ((ConstSpec) prev.Spec).GetConstant (rc) as EnumConstant; try { - return c.Increment ().Resolve (rc); + return c.Increment (); } catch (OverflowException) { rc.Report.Error (543, current.Location, "The enumerator value `{0}' is outside the range of enumerator underlying type `{1}'", current.GetSignatureForError (), ((Enum) current.Parent).UnderlyingType.GetSignatureForError ()); - return New.Constantify (current.Parent.Definition, current.Location).Resolve (rc); + return New.Constantify (current.Parent.Definition, current.Location); } } @@ -144,11 +163,12 @@ namespace Mono.CSharp { Modifiers.INTERNAL | Modifiers.PRIVATE; - public Enum (NamespaceEntry ns, DeclSpace parent, TypeExpression type, - Modifiers mod_flags, MemberName name, Attributes attrs) - : base (ns, parent, name, attrs, MemberKind.Enum) + readonly FullNamedExpression underlying_type_expr; + + public Enum (TypeContainer parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs) + : base (parent, name, attrs, MemberKind.Enum) { - base_type_expr = type; + underlying_type_expr = type; var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE; ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod_flags, accmods, Location, Report); spec = new EnumSpec (null, this, null, null, ModFlags); @@ -162,16 +182,15 @@ namespace Mono.CSharp { } } - public TypeExpr BaseTypeExpression { + public FullNamedExpression BaseTypeExpression { get { - return base_type_expr; + return underlying_type_expr; } } protected override TypeAttributes TypeAttr { get { - return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel) | - TypeAttributes.Class | TypeAttributes.Sealed | base.TypeAttr; + return base.TypeAttr | TypeAttributes.Class | TypeAttributes.Sealed; } } @@ -183,6 +202,11 @@ namespace Mono.CSharp { #endregion + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + public void AddEnumMember (EnumMember em) { if (em.Name == UnderlyingValueField) { @@ -191,36 +215,48 @@ namespace Mono.CSharp { return; } - AddConstant (em); + 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 bool DefineNestedTypes () + protected override void DoDefineContainer () { - ((EnumSpec) spec).UnderlyingType = base_type_expr == null ? TypeManager.int32_type : base_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); - return true; + DefineBaseTypes (); } protected override bool DoDefineMembers () { - if (constants != null) { - for (int i = 0; i < constants.Count; ++i) { - EnumMember em = (EnumMember) constants [i]; - if (em.Initializer == null) { - em.Initializer = new ImplicitInitializer (em, i == 0 ? null : (EnumMember) constants[i - 1]); - } - - em.Define (); + for (int i = 0; i < Members.Count; ++i) { + EnumMember em = (EnumMember) Members[i]; + if (em.Initializer == null) { + em.Initializer = new ImplicitInitializer (em, i == 0 ? null : (EnumMember) Members[i - 1]); } + + em.Define (); } return true; @@ -231,10 +267,10 @@ namespace Mono.CSharp { return true; } - protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class) + protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class) { - base_type = TypeManager.enum_type; - base_class = base_type_expr; + base_type = Compiler.BuiltinTypes.Enum; + base_class = null; return null; } @@ -243,10 +279,13 @@ namespace Mono.CSharp { if (!base.VerifyClsCompliance ()) return false; - if (UnderlyingType == TypeManager.uint32_type || - UnderlyingType == TypeManager.uint64_type || - UnderlyingType == TypeManager.ushort_type) { - Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (UnderlyingType)); + switch (UnderlyingType.BuiltinType) { + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.ULong: + case BuiltinTypeSpec.Type.UShort: + Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant", + GetSignatureForError (), UnderlyingType.GetSignatureForError ()); + break; } return true; @@ -279,5 +318,22 @@ namespace Mono.CSharp { { return ((EnumSpec) t.GetDefinition ()).UnderlyingType; } + + public static bool IsValidUnderlyingType (TypeSpec type) + { + switch (type.BuiltinType) { + case BuiltinTypeSpec.Type.Int: + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.Long: + case BuiltinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.SByte: + case BuiltinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.ULong: + return true; + } + + return false; + } } }