2 // enum.cs: Enum handling.
4 // Author: Miguel de Icaza (miguel@gnu.org)
6 // Licensed under the terms of the GNU GPL
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
12 using System.Collections;
13 using System.Reflection;
14 using System.Reflection.Emit;
18 public class Enum : DeclSpace {
20 ArrayList ordered_enums;
21 public readonly string BaseType;
22 public readonly string EnumName;
24 public TypeBuilder EnumBuilder;
25 public Attributes OptAttributes;
29 public readonly RootContext RootContext;
31 public const int AllowedModifiers =
38 public Enum (RootContext rc, string type, int mod_flags, string name, Attributes attrs, Location l)
44 this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PUBLIC);
45 OptAttributes = attrs;
46 ordered_enums = new ArrayList ();
50 // Adds @name to the enumeration space, with @expr
51 // being its definition.
53 public AdditionResult AddEnumMember (string name, Expression expr)
55 if (defined_names.Contains (name))
56 return AdditionResult.NameExists;
58 DefineName (name, expr);
60 ordered_enums.Add (name);
61 return AdditionResult.Success;
64 public void DefineEnum (object parent_builder)
66 TypeAttributes attr = TypeAttributes.Class | TypeAttributes.Sealed;
68 UnderlyingType = RootContext.TypeManager.LookupType (BaseType);
70 if (parent_builder is ModuleBuilder) {
71 ModuleBuilder builder = (ModuleBuilder) parent_builder;
73 if ((ModFlags & Modifiers.PUBLIC) != 0)
74 attr |= TypeAttributes.Public;
76 attr |= TypeAttributes.NotPublic;
78 EnumBuilder = builder.DefineType (EnumName, attr, TypeManager.enum_type);
81 TypeBuilder builder = (TypeBuilder) parent_builder;
83 if ((ModFlags & Modifiers.PUBLIC) != 0)
84 attr |= TypeAttributes.NestedPublic;
86 attr |= TypeAttributes.NestedPrivate;
88 EnumBuilder = builder.DefineNestedType (EnumName, attr, TypeManager.enum_type);
91 EnumBuilder.DefineField ("value__", UnderlyingType,
92 FieldAttributes.Public | FieldAttributes.SpecialName);
94 RootContext.TypeManager.AddEnumType (EnumName, EnumBuilder, this);
97 bool IsValidEnumLiteral (Expression e)
102 if (e is IntLiteral || e is UIntLiteral || e is LongLiteral || e is ULongLiteral)
108 public void Emit (TypeContainer tc)
110 EmitContext ec = new EmitContext (tc, null, UnderlyingType, ModFlags);
112 int default_value = 0;
114 FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static
115 | FieldAttributes.Literal;
117 foreach (string name in ordered_enums) {
118 Expression e = this [name];
121 e = Expression.Reduce (ec, e);
123 if (IsValidEnumLiteral (e))
124 default_value = (int) ((Literal) e).GetValue ();
126 Report.Error (1008, Location,
127 "Type byte, sbyte, short, ushort, int, uint, long, or ulong expected");
132 FieldBuilder fb = EnumBuilder.DefineField (name, UnderlyingType, attr);
134 fb.SetConstant (default_value++);
137 if (OptAttributes != null) {
138 if (OptAttributes.AttributeSections != null) {
139 foreach (AttributeSection asec in OptAttributes.AttributeSections) {
140 if (asec.Attributes != null) {
141 foreach (Attribute a in asec.Attributes) {
142 CustomAttributeBuilder cb = a.Resolve (ec);
144 EnumBuilder.SetCustomAttribute (cb);
153 public void CloseEnum ()
155 EnumBuilder.CreateType ();
158 public ArrayList ValueNames {
160 return ordered_enums;
164 public int ModFlags {
171 public Expression this [string name] {
173 return (Expression) defined_names [name];