2001-11-18 Ravi Pratap <ravi@ximian.com>
[mono.git] / mcs / mcs / enum.cs
index 8c479d3860b78470d7c42e9f3d4453b938d190f8..5d7f2509619e61bc28690bbec4c5181e7126d3a4 100755 (executable)
@@ -2,6 +2,7 @@
 // enum.cs: Enum handling.
 //
 // Author: Miguel de Icaza (miguel@gnu.org)
+//         Ravi Pratap     (ravi@ximian.com)
 //
 // Licensed under the terms of the GNU GPL
 //
@@ -23,13 +24,14 @@ namespace CIR {
                int mod_flags;
                public TypeBuilder EnumBuilder;
                public Attributes  OptAttributes;
-
+               
                Type UnderlyingType;
 
                public readonly RootContext RootContext;
 
                Hashtable member_to_location;
-               
+               ArrayList field_builders;
+
                public const int AllowedModifiers =
                        Modifiers.NEW |
                        Modifiers.PUBLIC |
@@ -47,6 +49,7 @@ namespace CIR {
                        OptAttributes = attrs;
                        ordered_enums = new ArrayList ();
                        member_to_location = new Hashtable ();
+                       field_builders = new ArrayList ();
                }
 
                // <summary>
@@ -72,6 +75,15 @@ namespace CIR {
 
                        UnderlyingType = RootContext.TypeManager.LookupType (BaseType);
 
+                       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");
+                               return;
+                       }
+
                        if (parent_builder is ModuleBuilder) {
                                ModuleBuilder builder = (ModuleBuilder) parent_builder;
 
@@ -93,11 +105,12 @@ namespace CIR {
                                EnumBuilder = builder.DefineNestedType (EnumName, attr, TypeManager.enum_type);
                        }
 
-
                        EnumBuilder.DefineField ("value__", UnderlyingType,
                                                 FieldAttributes.Public | FieldAttributes.SpecialName);
-                       
+
                        RootContext.TypeManager.AddEnumType (EnumName, EnumBuilder, this);
+
+                       return;
                }
 
                bool IsValidEnumLiteral (Expression e)
@@ -182,8 +195,15 @@ namespace CIR {
                        return;
                }
                
-               public void Emit (TypeContainer tc)
+               public void Populate (TypeContainer tc)
                {
+                       //
+                       // If there was an error during DefineEnum, return
+                       //
+                       if (EnumBuilder == null){
+                               return;
+                       }
+                       
                        EmitContext ec = new EmitContext (tc, null, UnderlyingType, ModFlags);
                        
                        object default_value = 0;
@@ -229,8 +249,12 @@ namespace CIR {
                                        error31 ((Literal) e, loc);
                                        return;
                                }
-                               
+
                                fb.SetConstant (default_value);
+                               field_builders.Add (fb);
+
+                               if (!TypeManager.RegisterField (fb, default_value))
+                                       return;
 
                                default_value = GetNextDefaultValue (default_value);
                        }
@@ -255,6 +279,30 @@ namespace CIR {
                                }
                        }
                }
+               
+               //
+               // Hack around System.Reflection as found everywhere else
+               //
+               public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
+               {
+                       ArrayList members = new ArrayList ();
+
+                       if ((mt & MemberTypes.Field) != 0) {
+                               foreach (FieldBuilder fb in field_builders)
+                                       if (filter (fb, criteria) == true)
+                                               members.Add (fb);
+                       }
+
+                       int count = members.Count;
+
+                       if (count > 0) {
+                               MemberInfo [] mi = new MemberInfo [count];
+                               members.CopyTo (mi, 0);
+                               return mi;
+                       }
+
+                       return null;
+               }
 
                public void CloseEnum ()
                {