X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fenum.cs;h=d8f5415fe500a691b9c52b3f49c3be36e86fbb49;hb=e482c4db5e7393fb76731cfff7a507d1f2cb290c;hp=f2ed451959df2f06fe27c88745496de91ad36d2a;hpb=ff228e1c801bda9666b6edab3ee962e05edcf480;p=mono.git diff --git a/mcs/mcs/enum.cs b/mcs/mcs/enum.cs index f2ed451959d..d8f5415fe50 100644 --- a/mcs/mcs/enum.cs +++ b/mcs/mcs/enum.cs @@ -3,752 +3,280 @@ // // Author: Miguel de Icaza (miguel@gnu.org) // Ravi Pratap (ravi@ximian.com) +// Marek Safar (marek.safar@seznam.cz) // -// Licensed under the terms of the GNU GPL +// Dual licensed under the terms of the MIT X11 or GNU GPL // -// (C) 2001 Ximian, Inc (http://www.ximian.com) +// Copyright 2001 Ximian, Inc (http://www.ximian.com) +// Copyright 2003-2003 Novell, Inc (http://www.novell.com) // using System; -using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using System.Globalization; namespace Mono.CSharp { - class EnumMember: MemberCore { - 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), attrs, loc) - { - this.parent_enum = parent_enum; - this.ModFlags = parent_enum.ModFlags; - this.Type = expr; - } - - public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) + public class EnumMember : Const + { + class EnumTypeExpr : TypeExpr { - if (a.Type == TypeManager.marshal_as_attr_type) { - UnmanagedMarshal marshal = a.GetMarshal (this); - if (marshal != null) { - builder.SetMarshal (marshal); - } - return; - } - - if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) { - a.Error_InvalidSecurityParent (); - return; + protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec) + { + type = ec.CurrentType; + return this; } - builder.SetCustomAttribute (cb); - } - - public override AttributeTargets AttributeTargets { - get { - return AttributeTargets.Field; + public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent) + { + return DoResolveAsTypeStep (ec); } } - public void DefineMember (TypeBuilder tb) + public EnumMember (Enum parent, MemberName name, Attributes attrs) + : base (parent, new EnumTypeExpr (), Modifiers.PUBLIC, name, attrs) { - FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static - | FieldAttributes.Literal; - - builder = tb.DefineField (Name, tb, attr); } - public override bool Define () + static bool IsValidEnumType (TypeSpec t) { - throw new NotImplementedException (); + 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)); } - public void Emit (EmitContext ec) + public override Constant ConvertInitializer (ResolveContext rc, Constant expr) { - if (OptAttributes != null) - OptAttributes.Emit (ec, this); + if (expr is EnumConstant) + expr = ((EnumConstant) expr).Child; + + var underlying = ((Enum) Parent).UnderlyingType; + if (expr != null) { + expr = expr.ImplicitConversionRequired (rc, underlying, Location); + if (expr != null && !IsValidEnumType (expr.Type)) { + Enum.Error_1008 (Location, Report); + expr = null; + } + } - Emit (); - } + if (expr == null) + expr = New.Constantify (underlying); - public override string GetSignatureForError() - { - return String.Concat (parent_enum.GetSignatureForError (), '.', base.GetSignatureForError ()); + return new EnumConstant (expr, MemberType).Resolve (rc); } - public override string[] ValidAttributeTargets { - get { - return attribute_targets; - } - } - - protected override bool VerifyClsCompliance(DeclSpace ds) + public override bool Define () { - // Because parent is TypeContainer and we have only DeclSpace parent. - // Parameter replacing is required - return base.VerifyClsCompliance (parent_enum); - } + if (!ResolveMemberType ()) + return false; - // There is no base type - protected override void VerifyObsoleteAttribute() - { - } + const FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal; + FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType.GetMetaInfo (), attr); + spec = new ConstSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags, initializer); - public override string DocCommentHeader { - get { return "F:"; } + Parent.MemberCache.AddMember (spec); + return true; } } /// /// Enumeration container /// - public class Enum : DeclSpace { - public ArrayList ordered_enums; - - public Expression BaseType; - - public Type UnderlyingType; - - Hashtable member_to_location; - - // - // This is for members that have been defined + public class Enum : TypeContainer + { // - Hashtable member_to_value; - + // Implicit enum member initializer, used when no constant value is provided // - // This is used to mark members we're currently defining - // - Hashtable in_transit; - - ArrayList field_builders; - - public const int AllowedModifiers = - Modifiers.NEW | - Modifiers.PUBLIC | - Modifiers.PROTECTED | - Modifiers.INTERNAL | - Modifiers.PRIVATE; - - public Enum (NamespaceEntry ns, TypeContainer parent, Expression type, - int mod_flags, MemberName name, Attributes attrs, Location l) - : base (ns, parent, name, attrs, l) + class ImplicitInitializer : Expression { - this.BaseType = type; - ModFlags = Modifiers.Check (AllowedModifiers, mod_flags, - IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, l); - - ordered_enums = new ArrayList (); - member_to_location = new Hashtable (); - member_to_value = new Hashtable (); - in_transit = new Hashtable (); - field_builders = new ArrayList (); - } + readonly EnumMember prev; + readonly EnumMember current; - /// - /// Adds @name to the enumeration space, with @expr - /// being its definition. - /// - public void AddEnumMember (string name, Expression expr, Location loc, Attributes opt_attrs, string documentation) - { - if (name == "value__") { - Report.Error (76, loc, "An item in an enumeration can't have an identifier `value__'"); - return; + public ImplicitInitializer (EnumMember current, EnumMember prev) + { + this.current = current; + this.prev = prev; } - EnumMember em = new EnumMember (this, expr, name, loc, opt_attrs); - em.DocComment = documentation; - if (!AddToContainer (em, name)) - return; - - - // TODO: can be almost deleted - ordered_enums.Add (name); - member_to_location.Add (name, loc); - } - - public override TypeBuilder DefineType () - { - if (TypeBuilder != null) - return TypeBuilder; - - ec = new EmitContext (this, this, Location, null, null, ModFlags, false); - ec.InEnumContext = true; - - if (!(BaseType is TypeLookupExpression)) { - Report.Error (1008, Location, - "Type byte, sbyte, short, ushort, int, uint, " + - "long, or ulong expected (got: `{0}')", BaseType); - return null; - } - - TypeExpr ute = ResolveBaseTypeExpr (BaseType, false, Location); - UnderlyingType = ute.Type; - - if (UnderlyingType != TypeManager.int32_type && - UnderlyingType != TypeManager.uint32_type && - UnderlyingType != TypeManager.int64_type && - UnderlyingType != TypeManager.uint64_type && - UnderlyingType != TypeManager.short_type && - UnderlyingType != TypeManager.ushort_type && - UnderlyingType != TypeManager.byte_type && - UnderlyingType != TypeManager.sbyte_type) { - Report.Error (1008, Location, - "Type byte, sbyte, short, ushort, int, uint, " + - "long, or ulong expected (got: " + - TypeManager.CSharpName (UnderlyingType) + ")"); - return null; + public override Expression CreateExpressionTree (ResolveContext ec) + { + throw new NotSupportedException ("Missing Resolve call"); } - if (IsTopLevel) { - if (TypeManager.NamespaceClash (Name, Location)) - return null; - - ModuleBuilder builder = CodeGen.Module.Builder; + protected override Expression DoResolve (ResolveContext rc) + { + // We are the first member + if (prev == null) { + return New.Constantify (current.Parent.Definition).Resolve (rc); + } - TypeBuilder = builder.DefineType (Name, TypeAttr, TypeManager.enum_type); - } else { - TypeBuilder builder = Parent.TypeBuilder; + var c = ((ConstSpec) prev.Spec).GetConstant (rc) as EnumConstant; + try { + return c.Increment ().Resolve (rc); + } 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 ()); - TypeBuilder = builder.DefineNestedType ( - Basename, TypeAttr, TypeManager.enum_type); + return New.Constantify (current.Parent.Definition).Resolve (rc); + } } - ec.ContainerType = TypeBuilder; - - // - // Call MapToInternalType for corlib - // - TypeBuilder.DefineField ("value__", UnderlyingType, - FieldAttributes.Public | FieldAttributes.SpecialName - | FieldAttributes.RTSpecialName); - - TypeManager.AddEnumType (Name, TypeBuilder, 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; + public override void Emit (EmitContext ec) + { + throw new NotSupportedException ("Missing Resolve call"); + } } - 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; - } + public static readonly string UnderlyingValueField = "value__"; - return null; - } + const Modifiers AllowedModifiers = + Modifiers.NEW | + Modifiers.PUBLIC | + Modifiers.PROTECTED | + Modifiers.INTERNAL | + Modifiers.PRIVATE; - void Error_ConstantValueCannotBeConverted (object val, Location loc) + public Enum (NamespaceEntry ns, DeclSpace parent, TypeExpression type, + Modifiers mod_flags, MemberName name, Attributes attrs) + : base (ns, parent, name, attrs, MemberKind.Enum) { - if (val is Constant) - Report.Error (31, loc, "Constant value '" + ((Constant) val).AsString () + - "' cannot be converted" + - " to a " + TypeManager.CSharpName (UnderlyingType)); - else - Report.Error (31, loc, "Constant value '" + val + - "' cannot be converted" + - " to a " + TypeManager.CSharpName (UnderlyingType)); - return; + base_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); } - /// - /// Determines if a standard implicit conversion exists from - /// expr_type to target_type - /// - public static bool ImplicitConversionExists (Type expr_type, Type target_type) - { - expr_type = TypeManager.TypeToCoreType (expr_type); + #region Properties - 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; + public override AttributeTargets AttributeTargets { + get { + return AttributeTargets.Enum; + } } - /// - /// 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 - /// - 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; + public TypeExpr BaseTypeExpression { + get { + return base_type_expr; } + } - // - // 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 (have: " + val + ")"); - return null; - } - - c = (Constant) val; - default_value = c.GetValue (); - - if (default_value == null) { - Error_ConstantValueCannotBeConverted (c, loc); - 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; - } - } + protected override TypeAttributes TypeAttr { + get { + return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel) | + TypeAttributes.Class | TypeAttributes.Sealed | base.TypeAttr; } + } - EnumMember em = (EnumMember) defined_names [name]; - em.DefineMember (TypeBuilder); - - bool fail; - default_value = TypeManager.ChangeType (default_value, UnderlyingType, out fail); - if (fail){ - Error_ConstantValueCannotBeConverted (c, loc); - return null; + public TypeSpec UnderlyingType { + get { + return ((EnumSpec) spec).UnderlyingType; } + } - em.builder.SetConstant (default_value); - field_builders.Add (em.builder); - member_to_value [name] = default_value; + #endregion - if (!TypeManager.RegisterFieldValue (em.builder, default_value)) - return null; + public void AddEnumMember (EnumMember em) + { + if (em.Name == UnderlyingValueField) { + Report.Error (76, em.Location, "An item in an enumeration cannot have an identifier `{0}'", + UnderlyingValueField); + return; + } - return default_value; + AddConstant (em); } - public override bool DefineMembers (TypeContainer parent) + public static void Error_1008 (Location loc, Report Report) { - return true; + Report.Error (1008, loc, + "Type byte, sbyte, short, ushort, int, uint, long or ulong expected"); } - - public override bool Define () + + protected override bool DefineNestedTypes () { - // - // If there was an error during DefineEnum, return - // - if (TypeBuilder == null) - return false; + ((EnumSpec) spec).UnderlyingType = base_type_expr == null ? TypeManager.int32_type : base_type_expr.Type; - 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 { - if (name == "value__"){ - Report.Error (76, loc, "The name `value__' is reserved for enumerations"); - return false; - } + TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType.GetMetaInfo (), + FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); - EnumMember em = (EnumMember) defined_names [name]; + if (!RootContext.StdLib) + RootContext.hack_corlib_enums.Add (this); - em.DefineMember (TypeBuilder); - FieldBuilder fb = em.builder; - - if (default_value == null) { - Report.Error (543, loc, "Enumerator value for '" + name + "' is too large to " + - "fit in its type"); - return false; - } + return true; + } - bool fail; - default_value = TypeManager.ChangeType (default_value, UnderlyingType, out fail); - if (fail){ - Error_ConstantValueCannotBeConverted (default_value, loc); - return false; + 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]); } - fb.SetConstant (default_value); - field_builders.Add (fb); - member_to_value [name] = default_value; - - if (!TypeManager.RegisterFieldValue (fb, default_value)) - return false; + em.Define (); } - - default_value = GetNextDefaultValue (default_value); } return true; } - public override void Emit () + public override bool IsUnmanagedType () { - if (OptAttributes != null) { - OptAttributes.Emit (ec, this); - } - - foreach (EnumMember em in defined_names.Values) { - em.Emit (ec); - } + return true; + } - base.Emit (); + protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class) + { + base_type = TypeManager.enum_type; + base_class = base_type_expr; + return null; } - - void VerifyClsName () - { - Hashtable ht = new Hashtable (); - foreach (string name in ordered_enums) { - string locase = name.ToLower (System.Globalization.CultureInfo.InvariantCulture); - if (!ht.Contains (locase)) { - ht.Add (locase, defined_names [name]); - continue; - } - - MemberCore conflict = (MemberCore)ht [locase]; - Report.SymbolRelatedToPreviousError (conflict); - conflict = GetDefinition (name); - Report.Error (3005, conflict.Location, "Identifier '{0}' differing only in case is not CLS-compliant", conflict.GetSignatureForError ()); - } - } - - protected override bool VerifyClsCompliance (DeclSpace ds) + + protected override bool VerifyClsCompliance () { - if (!base.VerifyClsCompliance (ds)) + if (!base.VerifyClsCompliance ()) return false; - VerifyClsName (); - - if (!AttributeTester.IsClsCompliant (UnderlyingType)) { - Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (UnderlyingType)); + 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)); } 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 { - return null; - } - } + } + } - public ArrayList ValueNames { - get { - return ordered_enums; - } - } + class EnumSpec : TypeSpec + { + TypeSpec underlying; - // indexer - public Expression this [string name] { - get { - return ((EnumMember) defined_names [name]).Type; - } + public EnumSpec (TypeSpec declaringType, ITypeDefinition definition, TypeSpec underlyingType, Type info, Modifiers modifiers) + : base (MemberKind.Enum, declaringType, definition, info, modifiers | Modifiers.SEALED) + { + this.underlying = underlyingType; } - public override AttributeTargets AttributeTargets { + public TypeSpec UnderlyingType { get { - return AttributeTargets.Enum; + return underlying; } - } + set { + if (underlying != null) + throw new InternalErrorException ("UnderlyingType reset"); - protected override TypeAttributes TypeAttr { - get { - return Modifiers.TypeAttr (ModFlags, IsTopLevel) | - TypeAttributes.Class | TypeAttributes.Sealed | - base.TypeAttr; + underlying = value; } } - - protected override void VerifyObsoleteAttribute() + public static TypeSpec GetUnderlyingType (TypeSpec t) { - // UnderlyingType is never obsolete - } - - // - // Generates xml doc comments (if any), and if required, - // handle warning report. - // - internal override void GenerateDocComment (DeclSpace ds) - { - DocUtil.GenerateEnumDocComment (this, ds); - } - - // - // Represents header string for documentation comment. - // - public override string DocCommentHeader { - get { return "T:"; } + return ((EnumSpec) t.GetDefinition ()).UnderlyingType; } } }