* MethodDef.cs: Report when defining methods just like MS.
[mono.git] / mcs / ilasm / codegen / TypeDef.cs
index b3906845b6a63b463698f8398c123c2e0b232a7e..2aee3ebd80ae915c71fa40505ff70a9987fef852 100644 (file)
@@ -15,6 +15,11 @@ namespace Mono.ILASM {
 
         public class TypeDef {
 
+                protected class GenericInfo {
+                        public string Id;
+                        public ArrayList ConstraintList;
+                }
+
                 private PEAPI.TypeAttr attr;
                 private string name_space;
                 private string name;
@@ -25,12 +30,12 @@ namespace Mono.ILASM {
                 private PEAPI.ClassDef classdef;
                 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 ArrayList override_list;
+                private ArrayList override_long_list;
                 private TypeDef outer;
 
                 private EventDef current_event;
@@ -39,6 +44,9 @@ namespace Mono.ILASM {
                 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)
                 {
@@ -49,13 +57,15 @@ namespace Mono.ILASM {
                         this.impl_list = impl_list;
                         field_table = new Hashtable ();
                         method_table = new Hashtable ();
-                        data_list = new ArrayList ();
 
                         size = -1;
                         pack = -1;
 
                         is_defined = false;
                         is_intransit = false;
+
+                        is_value_class = false;
+                        is_value_class = false;
                 }
 
                 public string Name {
@@ -95,6 +105,33 @@ namespace Mono.ILASM {
                         get { return current_property; }
                 }
 
+
+                public void AddOverride (MethodDef body, ITypeRef parent, string name)
+                {
+                        if (override_list == null)
+                                override_list = new ArrayList ();
+                        override_list.Add (new DictionaryEntry (body,
+                                           new DictionaryEntry (parent, name)));
+                }
+
+                public void AddOverride (string sig, IMethodRef decl)
+                {
+                        if (override_long_list == null)
+                                override_long_list = new ArrayList ();
+                        override_long_list.Add (new DictionaryEntry (sig,
+                                                                decl));
+                }
+
+                public void MakeValueClass ()
+                {
+                        is_value_class = true;
+                }
+
+                public void MakeEnumClass ()
+                {
+                        is_enum_class = true;
+                }
+
                 public void SetSize (int size)
                 {
                         this.size = size;
@@ -110,11 +147,6 @@ namespace Mono.ILASM {
                         field_table.Add (fielddef.Name, fielddef);
                 }
 
-                public void AddDataDef (DataDef datadef)
-                {
-                        data_list.Add (datadef);
-                }
-
                 public void AddMethodDef (MethodDef methoddef)
                 {
                         method_table.Add (methoddef.Signature, methoddef);
@@ -167,15 +199,19 @@ namespace Mono.ILASM {
                         if (typar_list == null)
                                 typar_list = new ArrayList ();
 
-                        typar_list.Add (id);
+                        GenericInfo gi = new GenericInfo ();
+                        gi.Id = id;
+
+                        typar_list.Add (gi);
                 }
 
                 public void AddGenericConstraint (int index, ITypeRef constraint)
                 {
-                        if (constraint_table == null)
-                                constraint_table = new Hashtable ();
+                        GenericInfo gi = (GenericInfo) typar_list[index];
 
-                        constraint_table.Add (index, constraint);
+                        if (gi.ConstraintList == null)
+                                gi.ConstraintList = new ArrayList ();
+                        gi.ConstraintList.Add (constraint);
                 }
 
                 public void Define (CodeGen code_gen)
@@ -202,8 +238,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) {
@@ -212,23 +254,37 @@ 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 (FullName == "System.Object")
+                                        classdef.SpecialNoSuper ();
                         }
 
                         if (size != -1)
                                 classdef.AddLayoutInfo (pack, size);
 
+                        if (impl_list != null) {
+                                foreach (IClassRef impl in impl_list) {
+                                        impl.Resolve (code_gen);
+                                        classdef.AddImplementedInterface (impl.PeapiClass);
+                                }
+                        }
+
                         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);
+                                foreach (GenericInfo gi in typar_list) {
+                                        PEAPI.GenericParameter gp = classdef.AddGenericParameter (index++, gi.Id);
+                                        if (gi.ConstraintList != null) {
+                                                foreach (ITypeRef cnst in gi.ConstraintList) {
+                                                        cnst.Resolve (code_gen);
+                                                        gp.AddConstraint (cnst.PeapiType);
+                                                }
                                         }
                                 }
                         }
@@ -246,7 +302,7 @@ namespace Mono.ILASM {
                         }
 
                         foreach (MethodDef methoddef in method_table.Values) {
-                                methoddef.Define (code_gen, classdef);
+                                methoddef.Define (code_gen, this);
                         }
 
                         if (event_list != null) {
@@ -266,12 +322,43 @@ namespace Mono.ILASM {
                                 foreach (CustomAttr customattr in customattr_list)
                                         customattr.AddTo (code_gen, classdef);
                         }
+
+                        if (override_list != null) {
+                                foreach (DictionaryEntry entry in override_list) {
+                                        MethodDef body = (MethodDef) entry.Key;
+                                        DictionaryEntry decl = (DictionaryEntry) entry.Value;
+                                        ITypeRef parent_type = (ITypeRef) decl.Key;
+                                        parent_type.Resolve (code_gen);
+                                        string over_name = (string) decl.Value;
+                                        IMethodRef over_meth = parent_type.GetMethodRef (body.RetType,
+                                                        body.CallConv, over_name, body.ParamTypeList ());
+                                        over_meth.Resolve (code_gen);
+                                        classdef.AddMethodOverride (over_meth.PeapiMethod,
+                                                        body.PeapiMethodDef);
+                                }
+                        }
+
+                        if (override_long_list != null) {
+                                foreach (DictionaryEntry entry in override_long_list) {
+                                        string sig = (string) entry.Key;
+                                        IMethodRef decl = (IMethodRef) entry.Value;
+                                        MethodDef body = (MethodDef) method_table[sig];
+                                        decl.Resolve (code_gen);
+                                        classdef.AddMethodOverride (decl.PeapiMethod,
+                                                        body.PeapiMethodDef);
+                                }
+                        }
                 }
 
                 public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
                 {
                         MethodDef methoddef = (MethodDef) method_table[signature];
 
+                        if (methoddef == null) {
+                                code_gen.Report.Error ("Unable to resolve method: " + signature);
+                                Environment.Exit (1);
+                        }
+
                         return methoddef.Resolve (code_gen, classdef);
                 }
 
@@ -279,8 +366,13 @@ namespace Mono.ILASM {
                                 CodeGen code_gen, PEAPI.Type[] opt)
                 {
                         MethodDef methoddef = (MethodDef) method_table[signature];
-                        methoddef.Resolve (code_gen, classdef);
 
+                        if (methoddef == null) {
+                                code_gen.Report.Error ("Unable to resolve method: " + signature);
+                                Environment.Exit (1);
+                        }
+
+                        methoddef.Resolve (code_gen, classdef);
                         return methoddef.GetVarargSig (opt);
                 }