2005-05-06 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / gmcs / typemanager.cs
index 336759986ae4467b0294c9c9367fed35d61d289b..6fa5127dbe0a066c3309ff3a1668d2375a957174 100644 (file)
@@ -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;
@@ -98,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
@@ -184,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;
+
        // <remarks>
        //   Holds the Array of Assemblies that have been loaded
        //   (either because it is the default or the user used the
@@ -242,10 +256,9 @@ public partial class TypeManager {
        static Hashtable indexer_arguments;
 
        // <remarks>
-       //   Maybe `method_arguments' should be replaced and only
-       //   method_internal_params should be kept?
+       //   Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters)
        // <remarks>
-       static Hashtable method_internal_params;
+       static Hashtable method_params;
 
        // <remarks>
        //  Keeps track of methods
@@ -259,6 +272,9 @@ public partial class TypeManager {
        // </remarks>
        public static Hashtable all_imported_types;
 
+       static Hashtable fieldbuilders_to_fields;
+       static Hashtable fields;
+
        struct Signature {
                public string name;
                public Type [] args;
@@ -277,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 ();
        }
 
@@ -365,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;
@@ -377,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)
@@ -425,6 +450,7 @@ public partial class TypeManager {
                } catch {
                        HandleDuplicate (name, t); 
                }
+
                user_types.Add (t);
        }
 
@@ -511,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 ();
 
@@ -596,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&)
        //
@@ -606,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;
 
@@ -675,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 = { '.' };
-
-       /// <summary>
-       ///   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 "."
-       /// </summary>
-       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;
-       }
-
        /// <summary>
        ///   Computes the namespaces that we import from the assemblies we reference.
        /// </summary>
@@ -774,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
                //
@@ -790,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 ()) {
@@ -803,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);
+                       }
+               }
        }
 
        /// <summary>
@@ -844,6 +855,17 @@ public partial class TypeManager {
                        @"(\W+|\b)", 
                        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) 
        {
@@ -865,7 +887,10 @@ public partial class TypeManager {
        /// </summary>
        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)
@@ -886,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 ();
        }
 
        /// <summary>
@@ -934,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);
        }
 
@@ -945,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);
@@ -989,13 +1011,16 @@ public partial class TypeManager {
        /// </summary>
        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;
        }
 
@@ -1046,7 +1071,7 @@ public partial class TypeManager {
        /// <summary>
        ///    Returns the ConstructorInfo for "args"
        /// </summary>
-       static ConstructorInfo GetConstructor (Type t, Type [] args)
+       public static ConstructorInfo GetConstructor (Type t, Type [] args)
        {
                MemberList list;
                Signature sig;
@@ -1140,12 +1165,6 @@ public partial class TypeManager {
                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*");
@@ -1165,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.
                //
@@ -1278,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);
 
@@ -1288,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);
 
@@ -1380,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);
@@ -1577,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)
@@ -1627,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)
@@ -1679,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;
@@ -1731,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;
 
@@ -1766,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.
@@ -1812,6 +1846,14 @@ public partial class TypeManager {
                         return TypeToCoreType (t.GetElementType ());
         }
 
+       /// <summary>
+       /// This method is not implemented by MS runtime for dynamic types
+       /// </summary>
+       public static bool HasElementType (Type t)
+       {
+               return t.IsArray || t.IsPointer || t.IsByRef;
+       }
+
        /// <summary>
        ///   Returns the User Defined Types
        /// </summary>
@@ -1863,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;
        }
 
        /// <summary>
@@ -1941,7 +1985,6 @@ public partial class TypeManager {
        //  This is a workaround the fact that GetValue is not
        //  supported for dynamic types
        // </remarks>
-       static Hashtable fields = new Hashtable ();
        static public bool RegisterFieldValue (FieldBuilder fb, object value)
        {
                if (fields.Contains (fb))
@@ -1957,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))
@@ -1974,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];
        }
        
@@ -2080,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;
@@ -2134,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);
@@ -2157,7 +2204,6 @@ public partial class TypeManager {
        /// </summary>
        public static Type [] GetInterfaces (Type t)
        {
-               
                Type [] cached = iface_cache [t] as Type [];
                if (cached != null)
                        return cached;
@@ -2175,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;
@@ -2228,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);
@@ -2422,18 +2472,7 @@ public partial class TypeManager {
        /// </summary>
        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 (
@@ -2484,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);
@@ -2582,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;
@@ -2879,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)
@@ -3033,11 +3038,16 @@ public partial class TypeManager {
 ///   There is exactly one instance of this class per type.
 /// </summary>
 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 ();
+       }
+
        /// <summary>
        ///   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
@@ -3064,6 +3074,11 @@ public sealed class TypeHandle : IMemberContainer {
                type_hash = null;
        }
 
+       public static void Reset ()
+       {
+               type_hash = new PtrHashtable ();
+       }
+
        /// <summary>
        ///   Returns the TypeHandle for TypeManager.object_type.
        /// </summary>
@@ -3092,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;
@@ -3101,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);
        }
@@ -3130,9 +3145,9 @@ public sealed class TypeHandle : IMemberContainer {
                }
        }
 
-       public MemberCache ParentCache {
+       public MemberCache BaseCache {
                get {
-                       return parent_cache;
+                       return base_cache;
                }
        }