[ilasm] Adds noautoinherit option
[mono.git] / mcs / ilasm / codegen / TypeDef.cs
index 2aab8489de4dcda1d1ce21f24e7cb0b1194803eb..f35dca0bd4a4216d1a8a9f7cdca45ec62799c43c 100644 (file)
@@ -27,6 +27,7 @@ namespace Mono.ILASM {
                 private Hashtable field_table;
                 private ArrayList field_list;
                 private Hashtable method_table;
+                private ArrayList method_list;
                 private ArrayList customattr_list;
                 private DeclSecurity decl_sec;
                 private ArrayList event_list;
@@ -61,6 +62,7 @@ namespace Mono.ILASM {
                         field_list = new ArrayList ();
 
                         method_table = new Hashtable ();
+                        method_list = new ArrayList ();
 
                         size = -1;
                         pack = -1;
@@ -85,8 +87,14 @@ namespace Mono.ILASM {
                                 this.name_space = name_space;
                                 this.name = name;
                         }
+
+                        //Fixup attributes
+                        if (IsInterface)
+                                this.attr |= PEAPI.TypeAttr.Abstract;
                 }
 
+                               public bool NoAutoInherit { get; set; }
+
                 public string Name {
                         get { return name; }
                 }
@@ -199,8 +207,8 @@ namespace Mono.ILASM {
 
                 public void AddMethodDef (MethodDef methoddef)
                 {
-                        if (IsInterface && !(methoddef.IsVirtual || methoddef.IsAbstract)) {
-                                Report.Warning (methoddef.StartLocation, "Non-virtual, non-abstract instance method in interface, set to such");
+                        if (IsInterface && !methoddef.IsStatic && (!methoddef.IsVirtual || !methoddef.IsAbstract)) {
+                                Report.Warning (methoddef.StartLocation, "Non-virtual or non-abstract instance method in interface, set to such");
                                 methoddef.Attributes |= PEAPI.MethAttr.Abstract | PEAPI.MethAttr.Virtual;
                         }
 
@@ -208,6 +216,7 @@ namespace Mono.ILASM {
                                 Report.Error (methoddef.StartLocation, "Duplicate method declaration: " + methoddef.Signature);
 
                         method_table.Add (methoddef.Signature, methoddef);
+                        method_list.Add (methoddef);
                 }
 
                 public void BeginEventDef (EventDef event_def)
@@ -341,13 +350,14 @@ namespace Mono.ILASM {
 
                                 if (IsValueType (parent.PeapiClass.nameSpace, parent.PeapiClass.name))
                                         is_value_class = true;
-                                else if (IsEnumType (parent.PeapiClass.nameSpace, parent.PeapiClass.name))
+                                else if (IsEnumType (parent.PeapiClass.nameSpace, parent.PeapiClass.name)) {
                                         is_enum_class = true;
+                                        is_value_class = false;
+                                }
 
                                 if (!IsValueType (name_space, name) && !IsEnumType (name_space, name) &&
                                         is_value_class && (attr & PEAPI.TypeAttr.Sealed) == 0) {
 
-                                        Report.Warning (location, "Non-sealed value class, made sealed.");
                                         attr |= PEAPI.TypeAttr.Sealed;
                                 }
 
@@ -381,7 +391,7 @@ namespace Mono.ILASM {
                                                         name_space, name);
                                         }
                                 }
-                                if (FullName == "System.Object")
+                                if (FullName == "System.Object" || NoAutoInherit)
                                         classdef.SpecialNoSuper ();
                         }
 
@@ -409,13 +419,17 @@ namespace Mono.ILASM {
                 {
                         ArrayList fielddef_list = new ArrayList ();
                         foreach (FieldDef fielddef in field_list) {
+                                if (is_enum_class && fielddef.Name == "value__") {
+                                    fielddef.Attributes |= PEAPI.FieldAttr.SpecialName | PEAPI.FieldAttr.RTSpecialName;
+                                }
+
                                 fielddef.Define (code_gen, classdef);
                                 fielddef_list.Add (fielddef.PeapiFieldDef);
                         }
 
                         classdef.SetFieldOrder (fielddef_list);
 
-                        foreach (MethodDef methoddef in method_table.Values) {
+                        foreach (MethodDef methoddef in method_list) {
                                 methoddef.Define (code_gen);
                         }
 
@@ -476,7 +490,7 @@ namespace Mono.ILASM {
                 public PEAPI.Method ResolveMethod (BaseTypeRef ret_type, PEAPI.CallConv call_conv,
                         string name, BaseTypeRef [] param, int gen_param_count, CodeGen code_gen)
                 {
-                        string signature = MethodDef.CreateSignature (ret_type, name, param, gen_param_count);
+                        string signature = MethodDef.CreateSignature (ret_type, call_conv, name, param, gen_param_count, false);
                         MethodDef methoddef = (MethodDef) method_table[signature];
 
                         if (methoddef != null)
@@ -487,12 +501,14 @@ namespace Mono.ILASM {
                 public PEAPI.Method ResolveVarargMethod (BaseTypeRef ret_type, PEAPI.CallConv call_conv,
                         string name, BaseTypeRef [] param, int gen_param_count, PEAPI.Type [] opt, CodeGen code_gen)
                 {
-                        string signature = MethodDef.CreateVarargSignature (ret_type, name, param);
+                        // Only MethodDef sig required to lookup in the method_table
+                        string signature = MethodDef.CreateSignature (ret_type, call_conv, name, param, 0, false);
                         MethodDef methoddef = (MethodDef) method_table[signature];
-
                         if (methoddef != null) {
                                 methoddef.Resolve (code_gen, classdef);
-                                return methoddef.GetVarargSig (opt);
+                                return methoddef.GetVarargSig (
+                                                opt,
+                                                MethodDef.CreateSignature (ret_type, call_conv, name, param, 0, true));
                         }
                         
                         return ResolveAsMethodRef (ret_type, call_conv, name, param, gen_param_count, code_gen);