X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Ftypemanager.cs;h=6fa5127dbe0a066c3309ff3a1668d2375a957174;hb=215c1cd77483d5c0018469905265023f3f8df7ee;hp=d302e5a58f2ab71bfed6fbfa927e48002a311e96;hpb=9bed239dfa3c54d5e75ff14d847ca6ea774c45d5;p=mono.git diff --git a/mcs/gmcs/typemanager.cs b/mcs/gmcs/typemanager.cs index d302e5a58f2..6fa5127dbe0 100644 --- a/mcs/gmcs/typemanager.cs +++ b/mcs/gmcs/typemanager.cs @@ -80,7 +80,6 @@ public partial class TypeManager { static public Type methodimpl_attr_type; static public Type marshal_as_attr_type; static public Type param_array_type; - static public Type guid_attr_type; static public Type void_ptr_type; static public Type indexer_name_type; static public Type exception_type; @@ -89,6 +88,7 @@ public partial class TypeManager { static public Type obsolete_attribute_type; static public Type conditional_attribute_type; static public Type in_attribute_type; + static public Type out_attribute_type; static public Type anonymous_method_type; static public Type cls_compliant_attribute_type; static public Type typed_reference_type; @@ -97,6 +97,14 @@ public partial class TypeManager { static public Type struct_layout_attribute_type; static public Type field_offset_attribute_type; static public Type security_attr_type; + static public Type required_attr_type; + + /// + /// .NET 2.0 + /// + static internal Type compiler_generated_attr_type; + static internal Type fixed_buffer_attr_type; + static internal Type default_charset_type; // // An empty array of types @@ -183,10 +191,17 @@ public partial class TypeManager { static public ConstructorInfo void_decimal_ctor_five_args; static public ConstructorInfo void_decimal_ctor_int_arg; static public ConstructorInfo unverifiable_code_ctor; - static public ConstructorInfo invalid_operation_ctor; static public ConstructorInfo default_member_ctor; static public ConstructorInfo decimal_constant_attribute_ctor; + static internal ConstructorInfo struct_layout_attribute_ctor; + static public ConstructorInfo field_offset_attribute_ctor; + /// + /// A new in C# 2.0 + /// + static internal CustomAttributeBuilder compiler_generated_attr; + static internal ConstructorInfo fixed_buffer_attr_ctor; + // // Holds the Array of Assemblies that have been loaded // (either because it is the default or the user used the @@ -241,10 +256,9 @@ public partial class TypeManager { static Hashtable indexer_arguments; // - // Maybe `method_arguments' should be replaced and only - // method_internal_params should be kept? + // Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters) // - static Hashtable method_internal_params; + static Hashtable method_params; // // Keeps track of methods @@ -258,6 +272,9 @@ public partial class TypeManager { // public static Hashtable all_imported_types; + static Hashtable fieldbuilders_to_fields; + static Hashtable fields; + struct Signature { public string name; public Type [] args; @@ -276,19 +293,19 @@ public partial class TypeManager { builder_to_ifaces = null; method_arguments = null; indexer_arguments = null; - method_internal_params = null; + method_params = null; builder_to_method = null; fields = null; - references = null; - negative_hits = null; builder_to_constant = null; fieldbuilders_to_fields = null; events = null; priv_fields_events = null; properties = null; - CleanUpGenerics (); + type_hash = null; + + CleanUpGenerics (); TypeHandle.CleanUp (); } @@ -364,6 +381,15 @@ public partial class TypeManager { } static TypeManager () + { + Reset (); + + signature_filter = new MemberFilter (SignatureFilter); + InitExpressionTypes (); + InitGenerics (); + } + + static public void Reset () { assemblies = new Assembly [0]; modules = null; @@ -376,16 +402,16 @@ public partial class TypeManager { builder_to_member_cache = new PtrHashtable (); builder_to_method = new PtrHashtable (); method_arguments = new PtrHashtable (); - method_internal_params = new PtrHashtable (); + method_params = new PtrHashtable (); indexer_arguments = new PtrHashtable (); builder_to_ifaces = new PtrHashtable (); NoTypes = new Type [0]; NoTypeExprs = new TypeExpr [0]; - signature_filter = new MemberFilter (SignatureFilter); - InitGenerics (); - InitExpressionTypes (); + fieldbuilders_to_fields = new Hashtable (); + fields = new Hashtable (); + type_hash = new DoubleHash (); } public static void HandleDuplicate (string name, Type t) @@ -424,6 +450,7 @@ public partial class TypeManager { } catch { HandleDuplicate (name, t); } + user_types.Add (t); } @@ -510,7 +537,7 @@ public partial class TypeManager { return TypeHandle.GetMemberCache (t); } - public static MemberCache LookupParentInterfacesCache (Type t) + public static MemberCache LookupBaseInterfacesCache (Type t) { Type [] ifaces = t.GetInterfaces (); @@ -595,8 +622,18 @@ public partial class TypeManager { } } - static Hashtable references = new Hashtable (); - + // + // We use this hash for multiple kinds of constructed types: + // + // (T, "&") Given T, get T & + // (T, "*") Given T, get T * + // (T, "[]") Given T and a array dimension, get T [] + // (T, X) Given a type T and a simple name X, get the type T+X + // + // Accessibility tests, if necessary, should be done by the user + // + static DoubleHash type_hash = new DoubleHash (); + // // Gets the reference to T version of the Type (T&) // @@ -605,36 +642,82 @@ public partial class TypeManager { return t.MakeByRefType (); } - static Hashtable pointers = new Hashtable (); - // // Gets the pointer to T version of the Type (T*) // public static Type GetPointerType (Type t) { - string tname = t.FullName + "*"; - - Type ret = t.Assembly.GetType (tname); - - // - // If the type comes from the assembly we are building - // We need the Hashtable, because .NET 1.1 will return different instance types - // every time we call ModuleBuilder.GetType. - // - if (ret == null){ - if (pointers [t] == null) - pointers [t] = CodeGen.Module.Builder.GetType (tname); - - ret = (Type) pointers [t]; + return GetConstructedType (t, "*"); + } + + public static Type GetConstructedType (Type t, string dim) + { + object ret = null; + if (type_hash.Lookup (t, dim, out ret)) + return (Type) ret; + + ret = t.Module.GetType (t.ToString () + dim); + if (ret != null) { + type_hash.Insert (t, dim, ret); + return (Type) ret; } - return ret; + if (dim == "&") { + ret = GetReferenceType (t); + type_hash.Insert (t, dim, ret); + return (Type) ret; + } + + if (t.IsGenericParameter || t.IsGenericInstance) { + int pos = 0; + Type result = t; + while ((pos < dim.Length) && (dim [pos] == '[')) { + pos++; + + if (dim [pos] == ']') { + result = result.MakeArrayType (); + pos++; + + if (pos < dim.Length) + continue; + + type_hash.Insert (t, dim, result); + return result; + } + + int rank = 0; + while (dim [pos] == ',') { + pos++; rank++; + } + + if ((dim [pos] != ']') || (pos != dim.Length-1)) + break; + + result = result.MakeArrayType (rank + 1); + type_hash.Insert (t, dim, result); + return result; + } + } + + type_hash.Insert (t, dim, null); + return null; + } + + public static Type GetNestedType (Type t, string name) + { + object ret = null; + if (!type_hash.Lookup (t, name, out ret)) { + string lookup = t.FullName + "+" + name; + ret = t.Module.GetType (lookup); + type_hash.Insert (t, name, ret); + } + return (Type) ret; } // // Low-level lookup, cache-less // - static Type LookupTypeReflection (string name) + public static Type LookupTypeReflection (string name) { Type t; @@ -674,98 +757,6 @@ public partial class TypeManager { return null; } - static Hashtable negative_hits = new Hashtable (); - - // - // This function is used when you want to avoid the lookups, and want to go - // directly to the source. This will use the cache. - // - // Notice that bypassing the cache is bad, because on Microsoft.NET runtime - // GetType ("DynamicType[]") != GetType ("DynamicType[]"), and there is no - // way to test things other than doing a fullname compare - // - public static Type LookupTypeDirect (string name) - { - Type t = (Type) types [name]; - if (t != null) - return t; - - t = LookupTypeReflection (name); - if (t == null) - return null; - - types [name] = t; - return t; - } - - static readonly char [] dot_array = { '.' }; - - /// - /// Returns the Type associated with @name, takes care of the fact that - /// reflection expects nested types to be separated from the main type - /// with a "+" instead of a "." - /// - public static Type LookupType (string name) - { - Type t; - - // - // First lookup in user defined and cached values - // - - t = (Type) types [name]; - if (t != null) - return t; - - // Two thirds of the failures are caught here. - if (negative_hits.Contains (name)) - return null; - - // Sadly, split takes a param array, so this ends up allocating *EVERY TIME* - string [] elements = name.Split (dot_array); - int count = elements.Length; - - for (int n = 1; n <= count; n++){ - string top_level_type = String.Join (".", elements, 0, n); - - // One third of the failures are caught here. - if (negative_hits.Contains (top_level_type)) - continue; - - t = (Type) types [top_level_type]; - if (t == null){ - t = LookupTypeReflection (top_level_type); - if (t == null){ - negative_hits [top_level_type] = null; - continue; - } - } - - if (count == n){ - types [name] = t; - return t; - } - - // - // We know that System.Object does not have children, and since its the parent of - // all the objects, it always gets probbed for inner classes. - // - if (top_level_type == "System.Object") - return null; - - string newt = top_level_type + "+" + String.Join ("+", elements, n, count - n); - //Console.WriteLine ("Looking up: " + newt + " " + name); - t = LookupTypeReflection (newt); - if (t == null) - negative_hits [name] = null; - else - types [name] = t; - return t; - } - negative_hits [name] = null; - return null; - } - /// /// Computes the namespaces that we import from the assemblies we reference. /// @@ -773,6 +764,8 @@ public partial class TypeManager { { MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance|BindingFlags.NonPublic); + Hashtable cache = null; + // // First add the assembly namespaces // @@ -789,7 +782,7 @@ public partial class TypeManager { } } } else { - Hashtable cache = new Hashtable (); + cache = new Hashtable (); cache.Add ("", null); foreach (Assembly a in assemblies) { foreach (Type t in a.GetExportedTypes ()) { @@ -802,6 +795,25 @@ public partial class TypeManager { } } } + + // + // Then add module namespaces + // + foreach (Module m in modules) { + if (m == CodeGen.Module.Builder) + continue; + if (cache == null) { + cache = new Hashtable (); + cache.Add ("", null); + } + foreach (Type t in m.GetTypes ()) { + string ns = t.Namespace; + if (ns == null || cache.Contains (ns)) + continue; + Namespace.LookupNamespace (ns, true); + cache.Add (ns, null); + } + } } /// @@ -841,8 +853,19 @@ public partial class TypeManager { @"Single|Double|Char|Decimal|Byte|SByte|Object|" + @"Boolean|String|Void|Null)" + @"(\W+|\b)", - new MatchEvaluator (CSharpNameMatch)); + new MatchEvaluator (CSharpNameMatch)).Replace ('+', '.'); } + + static public string CSharpName (Type[] types) + { + StringBuilder sb = new StringBuilder (); + foreach (Type t in types) { + sb.Append (CSharpName (t)); + sb.Append (','); + } + sb.Remove (sb.Length - 1, 1); + return sb.ToString (); + } static String CSharpNameMatch (Match match) { @@ -864,7 +887,10 @@ public partial class TypeManager { /// static public string GetFullNameSignature (MemberInfo mi) { - return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name; + // Unfortunately, there's no dynamic dispatch on the arguments of a function. + return (mi is MethodBase) + ? GetFullNameSignature (mi as MethodBase) + : mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name; } static public string GetFullNameSignature (MethodBase mb) @@ -885,41 +911,45 @@ public partial class TypeManager { return mb.DeclaringType.FullName.Replace ('+', '.') + '.' + name; } - static public string GetFullName (Type t) + private static void GetFullName_recursed (StringBuilder sb, Type t, bool recursed) { - if (t.FullName == null) - return t.Name; - - string name = t.FullName.Replace ('+', '.'); + if (t.IsGenericParameter) { + sb.Append (t.Name); + return; + } - DeclSpace tc = LookupDeclSpace (t); - if ((tc != null) && tc.IsGeneric) { - TypeParameter[] tparam = tc.TypeParameters; + if (t.DeclaringType != null) { + GetFullName_recursed (sb, t.DeclaringType, true); + sb.Append ("."); + } - StringBuilder sb = new StringBuilder (name); - sb.Append ("<"); - for (int i = 0; i < tparam.Length; i++) { - if (i > 0) - sb.Append (","); - sb.Append (tparam [i].Name); + if (!recursed) { + string ns = t.Namespace; + if ((ns != null) && (ns != "")) { + sb.Append (ns); + sb.Append ("."); } - sb.Append (">"); - return sb.ToString (); - } else if (t.HasGenericArguments && !t.IsGenericInstance) { - Type[] tparam = t.GetGenericArguments (); + } + + sb.Append (SimpleName.RemoveGenericArity (t.Name)); - StringBuilder sb = new StringBuilder (name); + Type[] args = GetTypeArguments (t); + if (args.Length > 0) { sb.Append ("<"); - for (int i = 0; i < tparam.Length; i++) { + for (int i = 0; i < args.Length; i++) { if (i > 0) sb.Append (","); - sb.Append (tparam [i].Name); + sb.Append (GetFullName (args [i])); } sb.Append (">"); - return sb.ToString (); } + } - return name; + static public string GetFullName (Type t) + { + StringBuilder sb = new StringBuilder (); + GetFullName_recursed (sb, t, false); + return sb.ToString (); } /// @@ -933,7 +963,7 @@ public partial class TypeManager { MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true); string signature = GetFullNameSignature (mb); - string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0); + string arg = GetParameterData (mb).ParameterDesc (0); return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg); } @@ -944,15 +974,8 @@ public partial class TypeManager { { StringBuilder sig = new StringBuilder ("("); - // - // FIXME: We should really have a single function to do - // everything instead of the following 5 line pattern - // - ParameterData iparams = LookupParametersByBuilder (mb); + ParameterData iparams = GetParameterData (mb); - if (iparams == null) - iparams = new ReflectionParameters (mb); - // Is property if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor) return GetFullNameSignature (mb); @@ -988,13 +1011,16 @@ public partial class TypeManager { /// static Type CoreLookupType (string name) { - Type t = LookupTypeDirect (name); + Type t = null; + if (types.Contains (name)) + t = (Type) types [name]; + else + t = LookupTypeReflection (name); - if (t == null){ + if (t == null) Report.Error (518, "The predefined type `" + name + "' is not defined or imported"); - Environment.Exit (1); - } + types [name] = t; return t; } @@ -1045,7 +1071,7 @@ public partial class TypeManager { /// /// Returns the ConstructorInfo for "args" /// - static ConstructorInfo GetConstructor (Type t, Type [] args) + public static ConstructorInfo GetConstructor (Type t, Type [] args) { MemberList list; Signature sig; @@ -1133,17 +1159,12 @@ public partial class TypeManager { marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices.MarshalAsAttribute"); param_array_type = CoreLookupType ("System.ParamArrayAttribute"); in_attribute_type = CoreLookupType ("System.Runtime.InteropServices.InAttribute"); + out_attribute_type = CoreLookupType ("System.Runtime.InteropServices.OutAttribute"); typed_reference_type = CoreLookupType ("System.TypedReference"); arg_iterator_type = CoreLookupType ("System.ArgIterator"); mbr_type = CoreLookupType ("System.MarshalByRefObject"); decimal_constant_attribute_type = CoreLookupType ("System.Runtime.CompilerServices.DecimalConstantAttribute"); - // - // Sigh. Remove this before the release. Wonder what versions of Mono - // people are running. - // - guid_attr_type = LookupType ("System.Runtime.InteropServices.GuidAttribute"); - unverifiable_code_type= CoreLookupType ("System.Security.UnverifiableCodeAttribute"); void_ptr_type = CoreLookupType ("System.Void*"); @@ -1163,9 +1184,16 @@ public partial class TypeManager { struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute"); field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute"); security_attr_type = CoreLookupType ("System.Security.Permissions.SecurityAttribute"); + required_attr_type = CoreLookupType ("System.Runtime.CompilerServices.RequiredAttributeAttribute"); InitGenericCoreTypes (); + // + // .NET 2.0 + // + compiler_generated_attr_type = CoreLookupType ("System.Runtime.CompilerServices.CompilerGeneratedAttribute"); + fixed_buffer_attr_type = CoreLookupType ("System.Runtime.CompilerServices.FixedBufferAttribute"); + default_charset_type = CoreLookupType ("System.Runtime.InteropServices.DefaultCharSetAttribute"); // // When compiling corlib, store the "real" types here. // @@ -1276,7 +1304,7 @@ public partial class TypeManager { Type [] string_string_string_string = { string_type, string_type, string_type, string_type }; string_concat_string_string_string_string = GetMethod ( string_type, "Concat", string_string_string_string); - Type[] params_string = { TypeManager.LookupType ("System.String[]") }; + Type[] params_string = { GetConstructedType (string_type, "[]") }; string_concat_string_dot_dot_dot = GetMethod ( string_type, "Concat", params_string); @@ -1286,7 +1314,7 @@ public partial class TypeManager { Type [] object_object_object = { object_type, object_type, object_type }; string_concat_object_object_object = GetMethod ( string_type, "Concat", object_object_object); - Type[] params_object = { TypeManager.LookupType ("System.Object[]") }; + Type[] params_object = { GetConstructedType (object_type, "[]") }; string_concat_object_dot_dot_dot = GetMethod ( string_type, "Concat", params_object); @@ -1378,23 +1406,27 @@ public partial class TypeManager { // // Attributes // - cons_param_array_attribute = GetConstructor ( - param_array_type, void_arg); + cons_param_array_attribute = GetConstructor (param_array_type, void_arg); + unverifiable_code_ctor = GetConstructor (unverifiable_code_type, void_arg); + default_member_ctor = GetConstructor (default_member_type, string_); - unverifiable_code_ctor = GetConstructor ( - unverifiable_code_type, void_arg); + Type[] short_arg = { short_type }; + struct_layout_attribute_ctor = GetConstructor (struct_layout_attribute_type, short_arg); decimal_constant_attribute_ctor = GetConstructor (decimal_constant_attribute_type, new Type [] { byte_type, byte_type, uint32_type, uint32_type, uint32_type } ); - default_member_ctor = GetConstructor (default_member_type, string_); + field_offset_attribute_ctor = GetConstructor (field_offset_attribute_type, new Type [] + { int32_type }); // - // InvalidOperationException + // .NET 2.0 types // - invalid_operation_ctor = GetConstructor ( - invalid_operation_exception_type, void_arg); + compiler_generated_attr = new CustomAttributeBuilder ( + GetConstructor (compiler_generated_attr_type, void_arg), new object[0]); + Type[] type_int_arg = { type_type, int32_type }; + fixed_buffer_attr_ctor = GetConstructor (fixed_buffer_attr_type, type_int_arg); // Object object_ctor = GetConstructor (object_type, void_arg); @@ -1575,15 +1607,12 @@ public partial class TypeManager { // This is like IsBuiltinType, but lacks decimal_type, we should also clean up // the pieces in the code where we use IsBuiltinType and special case decimal_type. // - public static bool IsCLRType (Type t) + public static bool IsPrimitiveType (Type t) { - if (t == object_type || t == int32_type || t == uint32_type || + return (t == int32_type || t == uint32_type || t == int64_type || t == uint64_type || t == float_type || t == double_type || t == char_type || t == short_type || t == bool_type || - t == sbyte_type || t == byte_type || t == ushort_type) - return true; - else - return false; + t == sbyte_type || t == byte_type || t == ushort_type); } public static bool IsDelegateType (Type t) @@ -1625,42 +1654,52 @@ public partial class TypeManager { // public static bool IsUnmanagedType (Type t) { - if (IsBuiltinType (t) && t != TypeManager.string_type) - return true; + // builtins that are not unmanaged types + if (t == TypeManager.object_type || t == TypeManager.string_type) + return false; - if (IsEnumType (t)) + if (IsBuiltinOrEnum (t)) return true; + // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it. if (t.IsPointer) return true; - if (IsValueType (t)){ - if (t is TypeBuilder){ - TypeContainer tc = LookupTypeContainer (t); + // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)] + if (t.IsArray) + return false; - if (tc.Fields != null){ - foreach (Field f in tc.Fields){ - if (f.FieldBuilder.IsStatic) - continue; - if (!IsUnmanagedType (f.FieldBuilder.FieldType)) - return false; - } - } else - return true; - } else { - FieldInfo [] fields = t.GetFields (); + if (!IsValueType (t)) + return false; - foreach (FieldInfo f in fields){ - if (f.IsStatic) - continue; - if (!IsUnmanagedType (f.FieldType)) - return false; + if (t is TypeBuilder){ + TypeContainer tc = LookupTypeContainer (t); + if (tc.Fields == null) + return true; + foreach (Field f in tc.Fields){ + // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked. + if ((f.ModFlags & Modifiers.STATIC) != 0) + continue; + if (f.MemberType == null) + continue; + if (!IsUnmanagedType (f.MemberType)){ + Report.SymbolRelatedToPreviousError (f.Location, CSharpName (t) + "." + f.Name); + return false; } } return true; } + + FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - return false; + foreach (FieldInfo f in fields){ + if (!IsUnmanagedType (f.FieldType)){ + Report.SymbolRelatedToPreviousError (f); + return false; + } + } + + return true; } public static bool IsValueType (Type t) @@ -1677,20 +1716,20 @@ public partial class TypeManager { return tc.Kind == Kind.Interface; } - public static bool IsSubclassOf (Type type, Type parent) + public static bool IsSubclassOf (Type type, Type base_type) { TypeParameter tparam = LookupTypeParameter (type); - TypeParameter pparam = LookupTypeParameter (parent); + TypeParameter pparam = LookupTypeParameter (base_type); if ((tparam != null) && (pparam != null)) { if (tparam == pparam) return true; - return tparam.IsSubclassOf (parent); + return tparam.IsSubclassOf (base_type); } do { - if (type.Equals (parent)) + if (type.Equals (base_type)) return true; type = type.BaseType; @@ -1729,9 +1768,6 @@ public partial class TypeManager { } if (type.IsGenericInstance && parent.IsGenericInstance) { - Type tdef = type.GetGenericTypeDefinition (); - Type pdef = parent.GetGenericTypeDefinition (); - if (type.GetGenericTypeDefinition () != parent.GetGenericTypeDefinition ()) return false; @@ -1764,12 +1800,12 @@ public partial class TypeManager { } // - // Checks whether `type' is a subclass or nested child of `parent'. + // Checks whether `type' is a subclass or nested child of `base_type'. // - public static bool IsNestedFamilyAccessible (Type type, Type parent) + public static bool IsNestedFamilyAccessible (Type type, Type base_type) { do { - if (IsFamilyAccessible (type, parent)) + if (IsFamilyAccessible (type, base_type)) return true; // Handle nested types. @@ -1810,6 +1846,14 @@ public partial class TypeManager { return TypeToCoreType (t.GetElementType ()); } + /// + /// This method is not implemented by MS runtime for dynamic types + /// + public static bool HasElementType (Type t) + { + return t.IsArray || t.IsPointer || t.IsByRef; + } + /// /// Returns the User Defined Types /// @@ -1861,18 +1905,20 @@ public partial class TypeManager { args = NoTypes; method_arguments.Add (mb, args); - method_internal_params.Add (mb, ip); + method_params.Add (mb, ip); } - static public InternalParameters LookupParametersByBuilder (MethodBase mb) + static public ParameterData GetParameterData (MethodBase mb) { - if (! (mb is ConstructorBuilder || mb is MethodBuilder)) - return null; - - if (method_internal_params.Contains (mb)) - return (InternalParameters) method_internal_params [mb]; - else - throw new Exception ("Argument for Method not registered" + mb); + object pd = method_params [mb]; + if (pd == null) { + if (mb is MethodBuilder || mb is ConstructorBuilder) + throw new InternalErrorException ("Argument for Method not registered" + mb); + + method_params [mb] = pd = new ReflectionParameters (mb); + } + + return (ParameterData) pd; } /// @@ -1939,7 +1985,6 @@ public partial class TypeManager { // This is a workaround the fact that GetValue is not // supported for dynamic types // - static Hashtable fields = new Hashtable (); static public bool RegisterFieldValue (FieldBuilder fb, object value) { if (fields.Contains (fb)) @@ -1955,7 +2000,6 @@ public partial class TypeManager { return fields [fb]; } - static Hashtable fieldbuilders_to_fields = new Hashtable (); static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f) { if (fieldbuilders_to_fields.Contains (fb)) @@ -1972,6 +2016,9 @@ public partial class TypeManager { // static public FieldBase GetField (FieldInfo fb) { + if (fb.DeclaringType.IsGenericInstance) + fb = fb.Mono_GetGenericFieldDefinition (); + return (FieldBase) fieldbuilders_to_fields [fb]; } @@ -2078,8 +2125,8 @@ public partial class TypeManager { if (tc.Fields == null) return true; - foreach (Field field in tc.Fields) { - if (field.FieldBuilder.IsStatic) + foreach (FieldMember field in tc.Fields) { + if (field.FieldBuilder == null || field.FieldBuilder.IsStatic) continue; Type ftype = field.FieldBuilder.FieldType; @@ -2132,11 +2179,13 @@ public partial class TypeManager { if (texpr == null) return null; - if (!new_ifaces.Contains (texpr.Type)) - new_ifaces.Add (texpr.Type); + if (new_ifaces.Contains (texpr.Type)) + continue; + + new_ifaces.Add (texpr.Type); Type [] implementing = texpr.Type.GetInterfaces (); - + foreach (Type imp in implementing){ if (!new_ifaces.Contains (imp)) new_ifaces.Add (imp); @@ -2155,7 +2204,6 @@ public partial class TypeManager { /// public static Type [] GetInterfaces (Type t) { - Type [] cached = iface_cache [t] as Type []; if (cached != null) return cached; @@ -2173,21 +2221,25 @@ public partial class TypeManager { if (t.IsArray) t = TypeManager.array_type; - if (t is TypeBuilder){ - Type[] parent_ifaces; + if ((t is TypeBuilder) || t.IsGenericInstance) { + Type [] base_ifaces; if (t.BaseType == null) - parent_ifaces = NoTypes; + base_ifaces = NoTypes; else - parent_ifaces = GetInterfaces (t.BaseType); - Type[] type_ifaces = (Type []) builder_to_ifaces [t]; + base_ifaces = GetInterfaces (t.BaseType); + Type[] type_ifaces; + if (t.IsGenericInstance) + type_ifaces = t.GetInterfaces (); + else + type_ifaces = (Type []) builder_to_ifaces [t]; if (type_ifaces == null) type_ifaces = NoTypes; - int parent_count = parent_ifaces.Length; - Type[] result = new Type [parent_count + type_ifaces.Length]; - parent_ifaces.CopyTo (result, 0); - type_ifaces.CopyTo (result, parent_count); + int base_count = base_ifaces.Length; + Type [] result = new Type [base_count + type_ifaces.Length]; + base_ifaces.CopyTo (result, 0); + type_ifaces.CopyTo (result, base_count); iface_cache [t] = result; return result; @@ -2226,7 +2278,7 @@ public partial class TypeManager { // as soon as we hit a non-TypeBuiler in the interface // chain, we could return, as the `Type.GetInterfaces' // will return all the interfaces implement by the type - // or its parents. + // or its bases. // do { interfaces = GetInterfaces (t); @@ -2420,18 +2472,7 @@ public partial class TypeManager { /// public static bool VerifyUnManaged (Type t, Location loc) { - if (t.IsValueType || t.IsPointer){ - // - // FIXME: this is more complex, we actually need to - // make sure that the type does not contain any - // classes itself - // - return true; - } - - if (!RootContext.StdLib && (t == TypeManager.decimal_type)) - // We need this explicit check here to make it work when - // compiling corlib. + if (IsUnmanagedType (t)) return true; Report.Error ( @@ -2482,7 +2523,7 @@ public partial class TypeManager { new Type [] { typeof (Type), typeof (bool)}, null); if (declare_local_method == null){ - Report.Warning (-24, new Location (-1), + Report.Warning (-30, new Location (-1), "This version of the runtime does not support making pinned local variables. " + "This code may cause errors on a runtime with a moving GC"); return ig.DeclareLocal (t); @@ -2580,40 +2621,6 @@ public partial class TypeManager { internal Assembly invocation_assembly; internal IList almost_match; - private bool CheckValidFamilyAccess (bool is_static, MemberInfo m) - { - if (invocation_type == null) - return false; - - Debug.Assert (IsNestedFamilyAccessible (invocation_type, m.DeclaringType)); - - if (is_static) - return true; - - // A nested class has access to all the protected members visible - // to its parent. - if (qualifier_type != null - && TypeManager.IsNestedChildOf (invocation_type, qualifier_type)) - return true; - - if (invocation_type == m.DeclaringType - || invocation_type.IsSubclassOf (m.DeclaringType)) { - // Although a derived class can access protected members of - // its base class it cannot do so through an instance of the - // base class (CS1540). - // => Ancestry should be: declaring_type ->* invocation_type - // ->* qualified_type - if (qualifier_type == null - || qualifier_type == invocation_type - || qualifier_type.IsSubclassOf (invocation_type)) - return true; - } - - if (almost_match != null) - almost_match.Add (m); - return false; - } - bool Filter (MethodBase mb, object filter_criteria) { MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask; @@ -2877,7 +2884,7 @@ public partial class TypeManager { // works if we already used the cache in the first iteration of this loop. // // If we used the cache in any further iteration, we can still terminate the - // loop since the cache always looks in all parent classes. + // loop since the cache always looks in all base classes. // if (used_cache) @@ -3031,11 +3038,16 @@ public partial class TypeManager { /// There is exactly one instance of this class per type. /// public sealed class TypeHandle : IMemberContainer { - public readonly TypeHandle BaseType; + public readonly IMemberContainer BaseType; readonly int id = ++next_id; static int next_id = 0; + static TypeHandle () + { + Reset (); + } + /// /// Lookup a TypeHandle instance for the given type. If the type doesn't have /// a TypeHandle yet, a new instance of it is created. This static method @@ -3062,6 +3074,11 @@ public sealed class TypeHandle : IMemberContainer { type_hash = null; } + public static void Reset () + { + type_hash = new PtrHashtable (); + } + /// /// Returns the TypeHandle for TypeManager.object_type. /// @@ -3090,7 +3107,7 @@ public sealed class TypeHandle : IMemberContainer { } } - private static PtrHashtable type_hash = new PtrHashtable (); + private static PtrHashtable type_hash; private static TypeHandle object_type = null; private static TypeHandle array_type = null; @@ -3099,17 +3116,17 @@ public sealed class TypeHandle : IMemberContainer { private string full_name; private bool is_interface; private MemberCache member_cache; - private MemberCache parent_cache; + private MemberCache base_cache; private TypeHandle (Type type) { this.type = type; full_name = type.FullName != null ? type.FullName : type.Name; if (type.BaseType != null) { - BaseType = GetTypeHandle (type.BaseType); - parent_cache = BaseType.MemberCache; + base_cache = TypeManager.LookupMemberCache (type.BaseType); + BaseType = base_cache.Container; } else if (type.IsInterface) - parent_cache = TypeManager.LookupParentInterfacesCache (type); + base_cache = TypeManager.LookupBaseInterfacesCache (type); this.is_interface = type.IsInterface || type.IsGenericParameter; this.member_cache = new MemberCache (this); } @@ -3128,9 +3145,9 @@ public sealed class TypeHandle : IMemberContainer { } } - public MemberCache ParentCache { + public MemberCache BaseCache { get { - return parent_cache; + return base_cache; } }