X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Filasm%2Fcodegen%2FTypeDef.cs;h=0f6bbe49c493883a9c7d8b66a6c639e2e4137df2;hb=3d83362455bfb2fa6f6a89bb95f8314f2e278a97;hp=2f62229b5d8ec98ef2350395bd4270dcecb404d1;hpb=509a0e4811aec54fcf83fce1f2206afef83307b3;p=mono.git diff --git a/mcs/ilasm/codegen/TypeDef.cs b/mcs/ilasm/codegen/TypeDef.cs index 2f62229b5d8..0f6bbe49c49 100644 --- a/mcs/ilasm/codegen/TypeDef.cs +++ b/mcs/ilasm/codegen/TypeDef.cs @@ -10,31 +10,28 @@ using System; using System.Collections; +using System.Security; namespace Mono.ILASM { - public class TypeDef : ICustomAttrTarget { - - protected class GenericInfo { - public string Id; - public ArrayList ConstraintList; - } + public class TypeDef : ICustomAttrTarget, IDeclSecurityTarget, IComparable { private PEAPI.TypeAttr attr; private string name_space; private string name; private bool is_defined; private bool is_intransit; - private IClassRef parent; + private BaseClassRef parent; private ArrayList impl_list; private PEAPI.ClassDef classdef; private Hashtable field_table; private ArrayList field_list; private Hashtable method_table; private ArrayList customattr_list; + private DeclSecurity decl_sec; private ArrayList event_list; private ArrayList property_list; - private ArrayList typar_list; + private GenericParameters gen_params; private ArrayList override_list; private ArrayList override_long_list; private TypeDef outer; @@ -48,14 +45,17 @@ namespace Mono.ILASM { private bool is_value_class; private bool is_enum_class; + private Location location; + public TypeDef (PEAPI.TypeAttr attr, string name_space, string name, - IClassRef parent, ArrayList impl_list, Location location) + BaseClassRef parent, ArrayList impl_list, Location location, GenericParameters gen_params, TypeDef outer) { this.attr = attr; - this.name_space = name_space; - this.name = name; this.parent = parent; this.impl_list = impl_list; + this.gen_params = gen_params; + this.outer = outer; + this.location = location; field_table = new Hashtable (); field_list = new ArrayList (); @@ -70,6 +70,25 @@ namespace Mono.ILASM { is_value_class = false; is_enum_class = false; + + ResolveGenParams (); + + int lastdot = name.LastIndexOf ('.'); + /* Namespace . name split should not be done for nested classes */ + if (lastdot >= 0 && outer == null) { + if (name_space == null || name_space == "") + this.name_space = name.Substring (0, lastdot); + else + this.name_space = name_space + "." + name.Substring (0, lastdot); + this.name = name.Substring (lastdot + 1); + } else { + this.name_space = name_space; + this.name = name; + } + + //Fixup attributes + if (IsInterface) + this.attr |= PEAPI.TypeAttr.Abstract; } public string Name { @@ -80,9 +99,12 @@ namespace Mono.ILASM { get { return MakeFullName (); } } + public string NestedFullName { + get { return (outer == null ? FullName : (outer.NestedFullName + "/" + FullName)); } + } + public TypeDef OuterType { get { return outer; } - set { outer = value; } } public PEAPI.ClassDef PeapiType { @@ -94,7 +116,7 @@ namespace Mono.ILASM { } public bool IsGenericType { - get { return (typar_list == null); } + get { return (gen_params == null); } } public bool IsDefined { @@ -113,7 +135,23 @@ namespace Mono.ILASM { get { return (attr & PEAPI.TypeAttr.Interface) != 0; } } - public void AddOverride (MethodDef body, ITypeRef parent, string name) + public bool IsAbstract { + get { return (attr & PEAPI.TypeAttr.Abstract) != 0; } + } + + public GenericParameters TypeParameters { + get { return gen_params; } + } + + public DeclSecurity DeclSecurity { + get { + if (decl_sec == null) + decl_sec = new DeclSecurity (); + return decl_sec; + } + } + + public void AddOverride (MethodDef body, BaseTypeRef parent, string name) { if (override_list == null) override_list = new ArrayList (); @@ -121,7 +159,7 @@ namespace Mono.ILASM { new DictionaryEntry (parent, name))); } - public void AddOverride (string sig, IMethodRef decl) + public void AddOverride (string sig, BaseMethodRef decl) { if (override_long_list == null) override_long_list = new ArrayList (); @@ -152,28 +190,34 @@ namespace Mono.ILASM { public void AddFieldDef (FieldDef fielddef) { if (IsInterface && !fielddef.IsStatic) { - Console.WriteLine ("warning -- Non-static field in interface, set to such"); + Report.Warning ("Non-static field in interface, set to such"); fielddef.Attributes |= PEAPI.FieldAttr.Static; } - field_table.Add (fielddef.Name, fielddef); + DictionaryEntry entry = new DictionaryEntry (fielddef.Name, fielddef.Type.FullName); + if (field_table [entry] != null) + Report.Error ("Duplicate field declaration: " + fielddef.Type.FullName + " " + fielddef.Name); + field_table.Add (entry, fielddef); field_list.Add (fielddef); } public void AddMethodDef (MethodDef methoddef) { - if (IsInterface && !(methoddef.IsVirtual || methoddef.IsAbstract)) { - Console.WriteLine ("warning -- 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; } + if (method_table [methoddef.Signature] != null) + Report.Error (methoddef.StartLocation, "Duplicate method declaration: " + methoddef.Signature); + 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."); + Report.Error ("An event definition was not closed."); current_event = event_def; } @@ -190,7 +234,7 @@ namespace Mono.ILASM { public void BeginPropertyDef (PropertyDef property_def) { if (current_property != null) - throw new Exception ("A property definition was not closed."); + Report.Error ("A property definition was not closed."); current_property = property_def; } @@ -212,24 +256,60 @@ namespace Mono.ILASM { customattr_list.Add (customattr); } - public void AddGenericParam (string id) + public GenericParameter GetGenericParam (string id) { - if (typar_list == null) - typar_list = new ArrayList (); + if (gen_params == null) + return null; + + return gen_params.GetGenericParam (id); + } - GenericInfo gi = new GenericInfo (); - gi.Id = id; + public GenericParameter GetGenericParam (int index) + { + if (gen_params == null || index < 0 || index >= gen_params.Count) + return null; + + return gen_params [index]; + } - typar_list.Add (gi); + public int GetGenericParamNum (string id) + { + if (gen_params == null) + return -1; + + return gen_params.GetGenericParamNum (id); } - public void AddGenericConstraint (int index, ITypeRef constraint) + /* Resolve any GenParams in constraints, parent & impl_list */ + private void ResolveGenParams () { - GenericInfo gi = (GenericInfo) typar_list[index]; + if (gen_params == null) + return; + + gen_params.ResolveConstraints (gen_params, null); - if (gi.ConstraintList == null) - gi.ConstraintList = new ArrayList (); - gi.ConstraintList.Add (constraint); + BaseGenericTypeRef gtr = parent as BaseGenericTypeRef; + if (gtr != null) + gtr.Resolve (gen_params, null); + + if (impl_list == null) + return; + + foreach (BaseClassRef impl in impl_list) { + gtr = impl as BaseGenericTypeRef; + if (gtr != null) + gtr.Resolve (gen_params, null); + } + } + + private bool IsValueType (string ns, string name) + { + return (ns == "System" && name == "ValueType"); + } + + private bool IsEnumType (string ns, string name) + { + return (ns == "System" && name == "Enum"); } public void Define (CodeGen code_gen) @@ -239,27 +319,41 @@ namespace Mono.ILASM { if (is_intransit) { // Circular definition - throw new Exception ("Circular definition of class: " + FullName); + Report.Error ("Circular definition of class: " + FullName); } + if (outer != null) { + PEAPI.TypeAttr vis = attr & PEAPI.TypeAttr.VisibilityMask; + + if (vis == PEAPI.TypeAttr.Private || vis == PEAPI.TypeAttr.Public) { + /* Nested class, but attr not set accordingly. */ + Report.Warning (location, String.Format ("Nested class '{0}' has non-nested visibility, set to such.", NestedFullName)); + attr = attr ^ vis; + attr |= (vis == PEAPI.TypeAttr.Public ? PEAPI.TypeAttr.NestedPublic : PEAPI.TypeAttr.NestedPrivate); + } + } + if (parent != null) { is_intransit = true; parent.Resolve (code_gen); + is_intransit = false; if (parent.PeapiClass == null) { - throw new Exception ("this type can not be a base type: " + Report.Error ("this type can not be a base type: " + parent); } - if (parent.PeapiClass.nameSpace != null && - parent.PeapiClass.nameSpace.CompareTo ("System") == 0) { - - if (parent.PeapiClass.name.CompareTo ("ValueType") == 0) - is_value_class = true; - else - if (parent.PeapiClass.name.CompareTo ("Enum") == 0 ) - is_enum_class = true; - } + if (IsValueType (parent.PeapiClass.nameSpace, parent.PeapiClass.name)) + is_value_class = true; + else if (IsEnumType (parent.PeapiClass.nameSpace, parent.PeapiClass.name)) + is_enum_class = true; + + 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; + } if (outer != null) { if (!outer.IsDefined) @@ -295,31 +389,22 @@ namespace Mono.ILASM { classdef.SpecialNoSuper (); } - if (size != -1) - classdef.AddLayoutInfo (pack, size); + is_defined = true; + + if (size != -1 || pack != -1) + classdef.AddLayoutInfo ( (pack == -1) ? 1 : pack, (size == -1) ? 0 : size); if (impl_list != null) { - foreach (IClassRef impl in impl_list) { + foreach (BaseClassRef impl in impl_list) { impl.Resolve (code_gen); classdef.AddImplementedInterface (impl.PeapiClass); } } - if (typar_list != null) { - short index = 0; - 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); - } - } - } - } + if (gen_params != null) + gen_params.Resolve (code_gen, classdef); is_intransit = false; - is_defined = true; code_gen.AddToDefineContentsList (this); } @@ -335,7 +420,7 @@ namespace Mono.ILASM { classdef.SetFieldOrder (fielddef_list); foreach (MethodDef methoddef in method_table.Values) { - methoddef.Define (code_gen, this); + methoddef.Define (code_gen); } if (event_list != null) { @@ -352,19 +437,28 @@ namespace Mono.ILASM { } if (customattr_list != null) { - foreach (CustomAttr customattr in customattr_list) + foreach (CustomAttr customattr in customattr_list) { customattr.AddTo (code_gen, classdef); + if (customattr.IsSuppressUnmanaged (code_gen)) + classdef.AddAttribute (PEAPI.TypeAttr.HasSecurity); + } } + + /// Add declarative security to this class + if (decl_sec != null) { + decl_sec.AddTo (code_gen, classdef); + classdef.AddAttribute (PEAPI.TypeAttr.HasSecurity); + } 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; + BaseTypeRef parent_type = (BaseTypeRef) 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 ()); + BaseMethodRef over_meth = parent_type.GetMethodRef (body.RetType, + body.CallConv, over_name, body.ParamTypeList (), body.GenParamCount); over_meth.Resolve (code_gen); classdef.AddMethodOverride (over_meth.PeapiMethod, body.PeapiMethodDef); @@ -374,7 +468,7 @@ namespace Mono.ILASM { if (override_long_list != null) { foreach (DictionaryEntry entry in override_long_list) { string sig = (string) entry.Key; - IMethodRef decl = (IMethodRef) entry.Value; + BaseMethodRef decl = (BaseMethodRef) entry.Value; MethodDef body = (MethodDef) method_table[sig]; decl.Resolve (code_gen); classdef.AddMethodOverride (decl.PeapiMethod, @@ -383,37 +477,52 @@ namespace Mono.ILASM { } } - public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen) + 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); 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); + if (methoddef != null) + return methoddef.Resolve (code_gen, classdef); + return ResolveAsMethodRef (ret_type, call_conv, name, param, gen_param_count, code_gen); } - public PEAPI.Method ResolveVarargMethod (string signature, - CodeGen code_gen, PEAPI.Type[] opt) + 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); MethodDef methoddef = (MethodDef) method_table[signature]; - if (methoddef == null) { - code_gen.Report.Error ("Unable to resolve method: " + signature); - Environment.Exit (1); + if (methoddef != null) { + methoddef.Resolve (code_gen, classdef); + return methoddef.GetVarargSig (opt); } + + return ResolveAsMethodRef (ret_type, call_conv, name, param, gen_param_count, code_gen); + } - methoddef.Resolve (code_gen, classdef); - return methoddef.GetVarargSig (opt); + private PEAPI.Method ResolveAsMethodRef (BaseTypeRef ret_type, PEAPI.CallConv call_conv, + string name, BaseTypeRef [] param, int gen_param_count, CodeGen code_gen) + { + ExternTypeRef type_ref = code_gen.ThisModule.GetTypeRef (FullName, false); + ExternMethodRef methodref = (ExternMethodRef) type_ref.GetMethodRef (ret_type, call_conv, name, param, gen_param_count); + methodref.Resolve (code_gen); + + return methodref.PeapiMethod; } - public PEAPI.Field ResolveField (string name, CodeGen code_gen) + public PEAPI.Field ResolveField (string name, BaseTypeRef ret_type, CodeGen code_gen) { - FieldDef fielddef = (FieldDef) field_table[name]; + FieldDef fielddef = (FieldDef) field_table[new DictionaryEntry (name, ret_type.FullName)]; + if (fielddef !=null) + return fielddef.Resolve (code_gen, classdef); + + ExternTypeRef type_ref = code_gen.ThisModule.GetTypeRef (FullName, false); + IFieldRef fieldref = type_ref.GetFieldRef (ret_type, name); + fieldref.Resolve (code_gen); - return fielddef.Resolve (code_gen, classdef); + return fieldref.PeapiField; } private string MakeFullName () @@ -423,6 +532,13 @@ namespace Mono.ILASM { return name_space + "." + name; } + + public int CompareTo (object obj) + { + TypeDef type_def = (TypeDef) obj; + + return FullName.CompareTo (type_def.FullName); + } } }