* TypeDef.cs: Make types into value types if specified. Also
[mono.git] / mcs / ilasm / codegen / TypeDef.cs
index 534f8e2448bdab9b9657480399c6ddbbdaf61bd4..bf94e092e3b8adc04c028528e8cc2cf825427ec0 100644 (file)
@@ -26,11 +26,22 @@ namespace Mono.ILASM {
                 private Hashtable field_table;
                 private Hashtable method_table;
                 private ArrayList data_list;
+                private ArrayList customattr_list;
+                private ArrayList event_list;
+                private ArrayList property_list;
+                private ArrayList typar_list;
+                private Hashtable constraint_table;
                 private TypeDef outer;
 
+                private EventDef current_event;
+                private PropertyDef current_property;
+
                 private int size;
                 private int pack;
 
+               private bool is_value_class;
+               private bool is_enum_class;
+
                 public TypeDef (PEAPI.TypeAttr attr, string name_space, string name,
                                 IClassRef parent, ArrayList impl_list, Location location)
                 {
@@ -48,6 +59,9 @@ namespace Mono.ILASM {
 
                         is_defined = false;
                         is_intransit = false;
+
+                       is_value_class = false;
+                       is_value_class = false;
                 }
 
                 public string Name {
@@ -71,10 +85,32 @@ namespace Mono.ILASM {
                         get { return classdef; }
                 }
 
+                public bool IsGenericType {
+                        get { return (typar_list == null); }
+                }
+
                 public bool IsDefined {
                         get { return is_defined; }
                 }
 
+                public EventDef CurrentEvent {
+                        get { return current_event; }
+                }
+
+                public PropertyDef CurrentProperty {
+                        get { return current_property; }
+                }
+
+               public void MakeValueClass ()
+               {
+                       is_value_class = true;
+               }
+
+               public void MakeEnumClass ()
+               {
+                       is_enum_class = true;
+               }
+
                 public void SetSize (int size)
                 {
                         this.size = size;
@@ -100,6 +136,64 @@ namespace Mono.ILASM {
                         method_table.Add (methoddef.Signature, methoddef);
                 }
 
+                public void BeginEventDef (EventDef event_def)
+                {
+                        if (current_event != null)
+                                throw new Exception ("An event definition was not closed.");
+
+                        current_event = event_def;
+                }
+
+                public void EndEventDef ()
+                {
+                        if (event_list == null)
+                                event_list = new ArrayList ();
+
+                        event_list.Add (current_event);
+                        current_event = null;
+                }
+
+                public void BeginPropertyDef (PropertyDef property_def)
+                {
+                        if (current_property != null)
+                                throw new Exception ("A property definition was not closed.");
+
+                        current_property = property_def;
+                }
+
+                public void EndPropertyDef ()
+                {
+                        if (property_list == null)
+                                property_list = new ArrayList ();
+
+                        property_list.Add (current_property);
+                        current_property = null;
+                }
+
+                public void AddCustomAttribute (CustomAttr customattr)
+                {
+                        if (customattr_list == null)
+                                customattr_list = new ArrayList ();
+
+                        customattr_list.Add (customattr);
+                }
+
+                public void AddGenericParam (string id)
+                {
+                        if (typar_list == null)
+                                typar_list = new ArrayList ();
+
+                        typar_list.Add (id);
+                }
+
+                public void AddGenericConstraint (int index, ITypeRef constraint)
+                {
+                        if (constraint_table == null)
+                                constraint_table = new Hashtable ();
+
+                        constraint_table.Add (index, constraint);
+                }
+
                 public void Define (CodeGen code_gen)
                 {
                         if (is_defined)
@@ -124,8 +218,14 @@ namespace Mono.ILASM {
                                         classdef = outer.PeapiType.AddNestedClass (attr,
                                                         name_space, name, parent.PeapiClass);
                                 } else {
-                                        classdef = code_gen.PEFile.AddClass (attr,
-                                                name_space, name, parent.PeapiClass);
+                                       if (is_value_class) {
+                                               // Should probably confirm that the parent is System.ValueType
+                                               classdef = code_gen.PEFile.AddValueClass (attr,
+                                                       name_space, name);
+                                       } else {
+                                               classdef = code_gen.PEFile.AddClass (attr,
+                                                       name_space, name, parent.PeapiClass);
+                                       }
                                 }
                         } else {
                                 if (outer != null) {
@@ -134,14 +234,32 @@ namespace Mono.ILASM {
                                         classdef = outer.PeapiType.AddNestedClass (attr,
                                                 name_space, name);
                                 } else {
-                                        classdef = code_gen.PEFile.AddClass (attr,
-                                                name_space, name);
+                                       if (is_value_class) {
+                                               classdef = code_gen.PEFile.AddValueClass (attr,
+                                                       name_space, name);
+                                       } else {
+                                               classdef = code_gen.PEFile.AddClass (attr,
+                                                       name_space, name);
+                                       }
                                 }
                         }
 
                         if (size != -1)
                                 classdef.AddLayoutInfo (pack, size);
 
+                        if (typar_list != null) {
+                                short index = 0;
+                                foreach (string id in typar_list) {
+                                        if (constraint_table != null && constraint_table.Contains ((int) index)) {
+                                                ITypeRef constraint = (ITypeRef) constraint_table[(int) index];
+                                                constraint.Resolve (code_gen);
+                                                classdef.AddGenericParameter (index++, id, constraint.PeapiType);
+                                        } else {
+                                                classdef.AddGenericParameter (index++, id);
+                                        }
+                                }
+                        }
+
                         is_intransit = false;
                         is_defined = true;
 
@@ -157,15 +275,42 @@ namespace Mono.ILASM {
                         foreach (MethodDef methoddef in method_table.Values) {
                                 methoddef.Define (code_gen, classdef);
                         }
+
+                        if (event_list != null) {
+                                foreach (EventDef eventdef in event_list) {
+                                        eventdef.Define (code_gen, classdef);
+                                }
+                        }
+
+                        if (property_list != null) {
+                                foreach (PropertyDef propdef in property_list) {
+                                        propdef.Define (code_gen, classdef);
+                                }
+
+                        }
+
+                        if (customattr_list != null) {
+                                foreach (CustomAttr customattr in customattr_list)
+                                        customattr.AddTo (code_gen, classdef);
+                        }
                 }
 
-                public PEAPI.Method ResolveMethod (string signature, CodeGen code_gen)
+                public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
                 {
                         MethodDef methoddef = (MethodDef) method_table[signature];
 
                         return methoddef.Resolve (code_gen, classdef);
                 }
 
+                public PEAPI.Method ResolveVarargMethod (string signature,
+                                CodeGen code_gen, PEAPI.Type[] opt)
+                {
+                        MethodDef methoddef = (MethodDef) method_table[signature];
+                        methoddef.Resolve (code_gen, classdef);
+
+                        return methoddef.GetVarargSig (opt);
+                }
+
                 public PEAPI.Field ResolveField (string name, CodeGen code_gen)
                 {
                         FieldDef fielddef = (FieldDef) field_table[name];