Also update this
[mono.git] / mcs / gmcs / typemanager.cs
index 4e58f855f6c76f3cf2cbb995c094a27e04ed4a6d..93ebe7209ceb619ccd59adff2f82dad5b8378e61 100755 (executable)
@@ -75,15 +75,20 @@ public class TypeManager {
        static public Type unverifiable_code_type;
        static public Type methodimpl_attr_type;
        static public Type marshal_as_attr_type;
+       static public Type new_constraint_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;
+       static public Type activator_type;
        static public Type invalid_operation_exception_type;
        static public object obsolete_attribute_type;
        static public object conditional_attribute_type;
        static public Type in_attribute_type;
+       static public Type cls_compliant_attribute_type;
+       static public Type typed_reference_type;
+       static public Type arg_iterator_type;
 
        //
        // An empty array of types
@@ -135,7 +140,10 @@ public class TypeManager {
        static public MethodInfo string_concat_string_string;
        static public MethodInfo string_concat_string_string_string;
        static public MethodInfo string_concat_string_string_string_string;
+       static public MethodInfo string_concat_string_dot_dot_dot;
        static public MethodInfo string_concat_object_object;
+       static public MethodInfo string_concat_object_object_object;
+       static public MethodInfo string_concat_object_dot_dot_dot;
        static public MethodInfo string_isinterneted_string;
        static public MethodInfo system_type_get_type_from_handle;
        static public MethodInfo object_getcurrent_void;
@@ -157,6 +165,7 @@ public class TypeManager {
        static public MethodInfo int_array_get_lower_bound_int;
        static public MethodInfo int_array_get_upper_bound_int;
        static public MethodInfo void_array_copyto_array_int;
+       static public MethodInfo activator_create_instance;
        
        //
        // The attribute constructors.
@@ -206,6 +215,11 @@ public class TypeManager {
        // </remarks>
        static PtrHashtable builder_to_ifaces;
 
+       // <remarks>
+       //   Tracks the generic parameters.
+       // </remarks>
+       static PtrHashtable builder_to_type_param;
+
        // <remarks>
        //   Maps MethodBase.RuntimeTypeHandle to a Type array that contains
        //   the arguments to the method
@@ -236,6 +250,12 @@ public class TypeManager {
 
        static Hashtable builder_to_method;
 
+       // <remarks>
+       //  Contains all public types from referenced assemblies.
+       //  This member is used only if CLS Compliance verification is required.
+       // </remarks>
+       public static Hashtable all_imported_types;
+
        struct Signature {
                public string name;
                public Type [] args;
@@ -256,6 +276,7 @@ public class TypeManager {
                method_internal_params = null;
                builder_to_attr = null;
                builder_to_method = null;
+               builder_to_type_param = null;
                
                fields = null;
                references = null;
@@ -356,6 +377,7 @@ public class TypeManager {
                method_internal_params = new PtrHashtable ();
                indexer_arguments = new PtrHashtable ();
                builder_to_ifaces = new PtrHashtable ();
+               builder_to_type_param = new PtrHashtable ();
                
                NoTypes = new Type [0];
                NoTypeExprs = new TypeExpr [0];
@@ -459,6 +481,16 @@ public class TypeManager {
                builder_to_attr.Add (t, tc);
        }
 
+       public static void AddTypeParameter (Type t, TypeParameter tparam, TypeExpr[] ifaces)
+       {
+               if (!builder_to_type_param.Contains (t)) {
+                       builder_to_type_param.Add (t, tparam);
+
+                       if (ifaces != null)
+                               builder_to_ifaces [t] = ifaces;
+               }
+       }
+
        /// <summary>
        ///   Returns the DeclSpace whose Type is `t' or null if there is no
        ///   DeclSpace for `t' (ie, the Type comes from a library)
@@ -485,6 +517,13 @@ public class TypeManager {
                                return container;
                }
 
+               if (t is GenericTypeParameterBuilder) {
+                       IMemberContainer container = builder_to_type_param [t] as IMemberContainer;
+
+                       if (container != null)
+                               return container;
+               }
+
                return TypeHandle.GetTypeHandle (t);
        }
 
@@ -507,6 +546,27 @@ public class TypeManager {
        {
                return (TypeContainer) builder_to_attr [t];
        }
+
+       public static TypeParameter LookupTypeParameter (Type t)
+       {
+               return (TypeParameter) builder_to_type_param [t];
+       }
+
+       public static bool HasConstructorConstraint (Type t)
+       {
+               if (!t.IsGenericParameter)
+                       throw new InvalidOperationException ();
+
+               TypeParameter tparam = LookupTypeParameter (t);
+               if (tparam != null)
+                       return tparam.HasConstructorConstraint;
+               else {
+                       object[] attrs = t.GetCustomAttributes (
+                               TypeManager.new_constraint_attr_type, false);
+
+                       return attrs.Length > 0;
+               }
+       }
        
        /// <summary>
        ///   Registers an assembly to load types from.
@@ -541,6 +601,12 @@ public class TypeManager {
                modules = n;
        }
 
+       public static Module[] Modules {
+               get {
+                       return modules;
+               }
+       }
+
        static Hashtable references = new Hashtable ();
        
        //
@@ -748,6 +814,23 @@ public class TypeManager {
                }
        }
 
+       /// <summary>
+       /// Fills static table with exported types from all referenced assemblies.
+       /// This information is required for CLS Compliance tests.
+       /// </summary>
+       public static void LoadAllImportedTypes ()
+       {
+               if (!CodeGen.Assembly.IsClsCompliant)
+                       return;
+
+               all_imported_types = new Hashtable ();
+               foreach (Assembly a in assemblies) {
+                       foreach (Type t in a.GetExportedTypes ()) {
+                               all_imported_types [t.FullName] = t;
+                       }
+               }
+       }
+
        public static bool NamespaceClash (string name, Location loc)
        {
                if (Namespace.LookupNamespace (name, false) == null)
@@ -762,6 +845,9 @@ public class TypeManager {
        /// </summary>
        static public string CSharpName (Type t)
        {
+               if (t.FullName == null)
+                       return t.Name;
+
                return Regex.Replace (t.FullName, 
                        @"^System\." +
                        @"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" +
@@ -791,7 +877,48 @@ public class TypeManager {
        /// </summary>
        static public string GetFullNameSignature (MemberInfo mi)
        {
-               return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name;
+               string n = mi.Name;
+               if (n == ".ctor")
+                       n = mi.DeclaringType.Name;
+               
+               return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + n;
+       }
+
+       static public string GetFullName (Type t)
+       {
+               if (t.FullName == null)
+                       return t.Name;
+
+               string name = t.FullName.Replace ('+', '.');
+
+               DeclSpace tc = LookupDeclSpace (t);
+               if ((tc != null) && tc.IsGeneric) {
+                       TypeParameter[] tparam = tc.TypeParameters;
+
+                       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);
+                       }
+                       sb.Append (">");
+                       return sb.ToString ();
+               } else if (t.HasGenericArguments && !t.IsGenericInstance) {
+                       Type[] tparam = t.GetGenericArguments ();
+
+                       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);
+                       }
+                       sb.Append (">");
+                       return sb.ToString ();
+               }
+
+               return name;
        }
 
        /// <summary>
@@ -983,8 +1110,11 @@ public class TypeManager {
                dllimport_type       = CoreLookupType ("System.Runtime.InteropServices.DllImportAttribute");
                methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices.MethodImplAttribute");
                marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices.MarshalAsAttribute");
+               new_constraint_attr_type = CoreLookupType ("System.Runtime.CompilerServices.NewConstraintAttribute");
                param_array_type     = CoreLookupType ("System.ParamArrayAttribute");
                in_attribute_type    = CoreLookupType ("System.Runtime.InteropServices.InAttribute");
+               typed_reference_type = CoreLookupType ("System.TypedReference");
+               arg_iterator_type    = CoreLookupType ("System.ArgIterator");
 
                //
                // Sigh. Remove this before the release.  Wonder what versions of Mono
@@ -999,6 +1129,7 @@ public class TypeManager {
                indexer_name_type     = CoreLookupType ("System.Runtime.CompilerServices.IndexerNameAttribute");
 
                exception_type        = CoreLookupType ("System.Exception");
+               activator_type        = CoreLookupType ("System.Activator");
                invalid_operation_exception_type = CoreLookupType ("System.InvalidOperationException");
 
                //
@@ -1006,6 +1137,7 @@ public class TypeManager {
                //
                obsolete_attribute_type = CoreLookupType ("System.ObsoleteAttribute");
                conditional_attribute_type = CoreLookupType ("System.Diagnostics.ConditionalAttribute");
+               cls_compliant_attribute_type = CoreLookupType ("System.CLSCompliantAttribute");
 
                //
                // When compiling corlib, store the "real" types here.
@@ -1111,10 +1243,19 @@ public 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[]") };
+               string_concat_string_dot_dot_dot = GetMethod (
+                       string_type, "Concat", params_string);
 
                Type [] object_object = { object_type, object_type };
                string_concat_object_object = GetMethod (
                        string_type, "Concat", object_object);
+               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[]") };
+               string_concat_object_dot_dot_dot = GetMethod (
+                       string_type, "Concat", params_object);
 
                Type [] string_ = { string_type };
                string_isinterneted_string = GetMethod (
@@ -1218,6 +1359,10 @@ public class TypeManager {
                // Object
                object_ctor = GetConstructor (object_type, void_arg);
 
+               // Activator
+               Type [] type_arg = { type_type };
+               activator_create_instance = GetMethod (
+                       activator_type, "CreateInstance", type_arg);
        }
 
        const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
@@ -1294,7 +1439,7 @@ public class TypeManager {
        ///   our return value will already contain all inherited members and the caller don't need
        ///   to check base classes and interfaces anymore.
        /// </summary>
-       private static MemberList MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
+       private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
                                                            string name, out bool used_cache)
        {
                //
@@ -1327,6 +1472,7 @@ public class TypeManager {
                        }
 
                        // If there is no MemberCache, we need to use the "normal" FindMembers.
+                       // Note, this is a VERY uncommon route!
 
                        MemberList list;
                        Timer.StartTimer (TimerType.FindMembers);
@@ -1334,7 +1480,19 @@ public class TypeManager {
                                                 FilterWithClosure_delegate, name);
                        Timer.StopTimer (TimerType.FindMembers);
                        used_cache = false;
-                       return list;
+                       return (MemberInfo []) list;
+               }
+
+               if (t is GenericTypeParameterBuilder) {
+                       TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
+
+                       MemberList list;
+                       Timer.StartTimer (TimerType.FindMembers);
+                       list = tparam.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
+                                                  FilterWithClosure_delegate, name);
+                       Timer.StopTimer (TimerType.FindMembers);
+                       used_cache = false;
+                       return (MemberInfo []) list;
                }
 
                //
@@ -1376,6 +1534,9 @@ public class TypeManager {
 
        public static bool IsDelegateType (Type t)
        {
+               if (t.IsGenericInstance)
+                       t = t.GetGenericTypeDefinition ();
+
                if (t.IsSubclassOf (TypeManager.delegate_type))
                        return true;
                else
@@ -1410,31 +1571,38 @@ public class TypeManager {
                return ds.IsGeneric;
        }
 
-       public static bool CheckGeneric (Type t, int num_type_args)
+       public static bool HasGenericArguments (Type t)
+       {
+               return GetNumberOfTypeArguments (t) > 0;
+       }
+
+       public static int GetNumberOfTypeArguments (Type t)
        {
                DeclSpace tc = LookupDeclSpace (t);
+               if (tc != null)
+                       return tc.IsGeneric ? tc.CountTypeParameters : 0;
+               else
+                       return t.HasGenericArguments ? t.GetGenericArguments ().Length : 0;
+       }
 
+       public static Type[] GetTypeArguments (Type t)
+       {
+               DeclSpace tc = LookupDeclSpace (t);
                if (tc != null) {
                        if (!tc.IsGeneric)
-                               return num_type_args == 0;
-
-                       if (num_type_args == 0)
-                               return false;
-
-                       if (num_type_args != tc.CountTypeParameters)
-                               return false;
-               } else {
-                       if (!t.HasGenericArguments)
-                               return num_type_args == 0;
-
-                       if (num_type_args == 0)
-                               return false;
-
-                       if (num_type_args != t.GetGenericArguments ().Length)
-                               return false;
-               }
+                               throw new InvalidOperationException ();
+
+                       TypeParameter[] tparam = tc.TypeParameters;
+                       Type[] ret = new Type [tparam.Length];
+                       for (int i = 0; i < tparam.Length; i++) {
+                               ret [i] = tparam [i].Type;
+                               if (ret [i] == null)
+                                       throw new InternalErrorException ();
+                       }
 
-               return true;
+                       return ret;
+               } else
+                       return t.GetGenericArguments ();
        }
        
        //
@@ -1455,12 +1623,15 @@ public class TypeManager {
                        if (t is TypeBuilder){
                                TypeContainer tc = LookupTypeContainer (t);
 
+                               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 ();
 
@@ -1536,6 +1707,120 @@ public class TypeManager {
                        return IsEqualGenericType (a, b);
        }
 
+       public static bool MayBecomeEqualGenericTypes (Type a, Type b)
+       {
+               if (a.IsGenericParameter) {
+                       //
+                       // If a is an array of a's type, they may never
+                       // become equal.
+                       //
+                       while (b.IsArray) {
+                               b = b.GetElementType ();
+                               if (a.Equals (b))
+                                       return false;
+                       }
+
+                       //
+                       // If b is a generic parameter or an actual type,
+                       // they may become equal:
+                       //
+                       //    class X<T,U> : I<T>, I<U>
+                       //    class X<T> : I<T>, I<float>
+                       // 
+                       if (b.IsGenericParameter || !b.IsGenericInstance)
+                               return true;
+
+                       //
+                       // We're now comparing a type parameter with a
+                       // generic instance.  They may become equal unless
+                       // the type parameter appears anywhere in the
+                       // generic instance:
+                       //
+                       //    class X<T,U> : I<T>, I<X<U>>
+                       //        -> error because you could instanciate it as
+                       //           X<X<int>,int>
+                       //
+                       //    class X<T> : I<T>, I<X<T>> -> ok
+                       //
+
+                       Type[] bargs = GetTypeArguments (b);
+                       for (int i = 0; i < bargs.Length; i++) {
+                               if (a.Equals (bargs [i]))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               if (b.IsGenericParameter)
+                       return MayBecomeEqualGenericTypes (b, a);
+
+               //
+               // At this point, neither a nor b are a type parameter.
+               //
+               // If one of them is a generic instance, let
+               // MayBecomeEqualGenericInstances() compare them (if the
+               // other one is not a generic instance, they can never
+               // become equal).
+               //
+
+               if (a.IsGenericInstance || b.IsGenericInstance)
+                       return MayBecomeEqualGenericInstances (a, b);
+
+               //
+               // If both of them are arrays.
+               //
+
+               if (a.IsArray && b.IsArray) {
+                       if (a.GetArrayRank () != b.GetArrayRank ())
+                               return false;
+                       
+                       a = a.GetElementType ();
+                       b = b.GetElementType ();
+
+                       return MayBecomeEqualGenericTypes (a, b);
+               }
+
+               //
+               // Ok, two ordinary types.
+               //
+
+               return a.Equals (b);
+       }
+
+       //
+       // Checks whether two generic instances may become equal for some
+       // particular instantiation (26.3.1).
+       //
+       public static bool MayBecomeEqualGenericInstances (Type a, Type b)
+       {
+               if (!a.IsGenericInstance || !b.IsGenericInstance)
+                       return false;
+               if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+                       return false;
+
+               Type[] aargs = GetTypeArguments (a);
+               Type[] bargs = GetTypeArguments (b);
+
+               if (aargs.Length != bargs.Length)
+                       return false;
+
+               for (int i = 0; i < aargs.Length; i++) {
+                       if (MayBecomeEqualGenericTypes (aargs [i], bargs [i]))
+                               return true;
+               }
+
+               return false;
+       }
+
+       public static bool IsSubclassOf (Type type, Type parent)
+       {
+               if (type.IsGenericInstance && !parent.IsGenericInstance)
+                       type = type.GetGenericTypeDefinition ();
+
+               return type.IsSubclassOf (parent);
+       }
+
        //
        // Checks whether `type' is a subclass or nested child of `parent'.
        //
@@ -1937,6 +2222,13 @@ public class TypeManager {
 
                        iface_cache [t] = result;
                        return result;
+               } else if (t is GenericTypeParameterBuilder){
+                       TypeExpr[] type_ifaces = (TypeExpr []) builder_to_ifaces [t];
+                       if (type_ifaces == null)
+                               type_ifaces = NoTypeExprs;
+
+                       iface_cache [t] = type_ifaces;
+                       return type_ifaces;
                } else {
                        Type [] ifaces = t.GetInterfaces ();
                        if (ifaces.Length == 0)
@@ -2194,6 +2486,9 @@ public class TypeManager {
        /// </remarks>
        public static string IndexerPropertyName (Type t)
        {
+               if (t.IsGenericInstance)
+                       t = t.GetGenericTypeDefinition ();
+
                if (t is TypeBuilder) {
                        if (t.IsInterface) {
                                Interface i = LookupInterface (t);
@@ -2222,12 +2517,20 @@ public class TypeManager {
                return "Item";
        }
 
+       static MethodInfo pinned_method = null;
        public static void MakePinned (LocalBuilder builder)
        {
-               //
-               // FIXME: Flag the "LocalBuilder" type as being
-               // pinned.  Figure out API.
-               //
+               if (pinned_method == null) {
+                       pinned_method = typeof (LocalBuilder).GetMethod ("MakePinned", BindingFlags.Instance | BindingFlags.NonPublic);
+                       if (pinned_method == null) {
+                               Report.Warning (-24, new Location (-1), "Microsoft.NET does not support making pinned variables." +
+                                       "This code may cause errors on a runtime with a moving GC");
+                               
+                               return;
+                       }
+               }
+               
+               pinned_method.Invoke (builder, null);
        }
 
 
@@ -2273,7 +2576,7 @@ public class TypeManager {
        //
        // The name is assumed to be the same.
        //
-       public static ArrayList CopyNewMethods (ArrayList target_list, MemberList new_members)
+       public static ArrayList CopyNewMethods (ArrayList target_list, IList new_members)
        {
                if (target_list == null){
                        target_list = new ArrayList ();
@@ -2303,6 +2606,19 @@ public class TypeManager {
                IsObsoleteError = 1 << 1,
                ShouldIgnore = 1 << 2
        }
+
+       static public bool IsGenericMethod (MethodBase mb)
+       {
+               if (mb.DeclaringType is TypeBuilder) {
+                       MethodData method = (MethodData) builder_to_method [mb];
+                       if (method == null)
+                               return false;
+
+                       return method.GenericMethod != null;
+               }
+
+               return mb.IsGenericMethodDefinition;
+       }
        
        //
        // Returns the TypeManager.MethodFlags for this method.
@@ -2312,7 +2628,10 @@ public class TypeManager {
        static public MethodFlags GetMethodFlags (MethodBase mb, Location loc)
        {
                MethodFlags flags = 0;
-               
+
+               if (mb.Mono_IsInflatedMethod)
+                       mb = mb.GetGenericMethodDefinition ();
+
                if (mb.DeclaringType is TypeBuilder){
                        MethodData method = (MethodData) builder_to_method [mb];
                        if (method == null) {
@@ -2324,14 +2643,6 @@ public class TypeManager {
                        return method.GetMethodFlags (loc);
                }
 
-#if FIXME
-               if (mb.IsInflatedGeneric) {
-                       MethodBase generic = mb.GetGenericMethodDefinition ();
-
-                       return GetMethodFlags (generic, loc);
-               }
-#endif
-
                object [] attrs = mb.GetCustomAttributes (true);
                foreach (object ta in attrs){
                        if (!(ta is System.Attribute)){
@@ -2556,7 +2867,7 @@ public class TypeManager {
        // that might return multiple matches.
        //
        public static MemberInfo [] MemberLookup (Type invocation_type, Type qualifier_type,
-                                                 Type queried_type,  MemberTypes mt,
+                                                 Type queried_type, MemberTypes mt,
                                                  BindingFlags original_bf, string name)
        {
                Timer.StartTimer (TimerType.MemberLookup);
@@ -2591,7 +2902,7 @@ public class TypeManager {
                //
                if (invocation_type != null){
                        string invocation_name = invocation_type.FullName;
-                       if (invocation_name.IndexOf ('+') != -1){
+                       if ((invocation_name != null) && (invocation_name.IndexOf ('+') != -1)){
                                string container = queried_type.FullName + "+";
                                int container_length = container.Length;
 
@@ -2604,8 +2915,14 @@ public class TypeManager {
                        }
                }
                
+               // This is from the first time we find a method
+               // in most cases, we do not actually find a method in the base class
+               // so we can just ignore it, and save the arraylist allocation
+               MemberInfo [] first_members_list = null;
+               bool use_first_members_list = false;
+               
                do {
-                       MemberList list;
+                       MemberInfo [] list;
 
                        //
                        // `NonPublic' is lame, because it includes both protected and
@@ -2628,7 +2945,8 @@ public class TypeManager {
 
                        Timer.StopTimer (TimerType.MemberLookup);
 
-                       list = MemberLookup_FindMembers (current_type, mt, bf, name, out used_cache);
+                       list = MemberLookup_FindMembers (
+                               current_type, mt, bf, name, out used_cache);
 
                        Timer.StartTimer (TimerType.MemberLookup);
 
@@ -2659,7 +2977,7 @@ public class TypeManager {
                                        current_type = TypeManager.object_type;
                        }
                        
-                       if (list.Count == 0)
+                       if (list.Length == 0)
                                continue;
 
                        //
@@ -2667,8 +2985,8 @@ public class TypeManager {
                        // searches, which means that our above FindMembers will
                        // return two copies of the same.
                        //
-                       if (list.Count == 1 && !(list [0] is MethodBase)){
-                               return (MemberInfo []) list;
+                       if (list.Length == 1 && !(list [0] is MethodBase)){
+                               return list;
                        }
 
                        //
@@ -2676,14 +2994,14 @@ public class TypeManager {
                        // name
                        //
                        if (list [0] is PropertyInfo)
-                               return (MemberInfo []) list;
+                               return list;
 
                        //
                        // We found an event: the cache lookup returns both the event and
                        // its private field.
                        //
                        if (list [0] is EventInfo) {
-                               if ((list.Count == 2) && (list [1] is FieldInfo))
+                               if ((list.Length == 2) && (list [1] is FieldInfo))
                                        return new MemberInfo [] { list [0] };
 
                                // Oooops
@@ -2695,10 +3013,31 @@ public class TypeManager {
                        // mode.
                        //
 
-                       method_list = CopyNewMethods (method_list, list);
-                       mt &= (MemberTypes.Method | MemberTypes.Constructor);
+                       if (first_members_list != null) {
+                               if (use_first_members_list) {
+                                       method_list = CopyNewMethods (method_list, first_members_list);
+                                       use_first_members_list = false;
+                               }
+                               
+                               method_list = CopyNewMethods (method_list, list);
+                       } else {
+                               first_members_list = list;
+                               use_first_members_list = true;
+
+                               mt &= (MemberTypes.Method | MemberTypes.Constructor);
+                       }
                } while (searching);
 
+               if (use_first_members_list) {
+                       foreach (MemberInfo mi in first_members_list) {
+                               if (! (mi is MethodBase)) {
+                                       method_list = CopyNewMethods (method_list, first_members_list);
+                                       return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
+                               }
+                       }
+                       return (MemberInfo []) first_members_list;
+               }
+
                if (method_list != null && method_list.Count > 0) {
                         return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
                 }
@@ -2884,15 +3223,17 @@ public sealed class TypeHandle : IMemberContainer {
        private static TypeHandle array_type = null;
 
        private Type type;
+       private string full_name;
        private bool is_interface;
        private MemberCache member_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);
-               this.is_interface = type.IsInterface;
+               this.is_interface = type.IsInterface || type.IsGenericParameter;
                this.member_cache = new MemberCache (this);
        }
 
@@ -2900,7 +3241,7 @@ public sealed class TypeHandle : IMemberContainer {
 
        public string Name {
                get {
-                       return type.FullName;
+                       return full_name;
                }
        }
 
@@ -2925,6 +3266,8 @@ public sealed class TypeHandle : IMemberContainer {
        public MemberList GetMembers (MemberTypes mt, BindingFlags bf)
        {
                 MemberInfo [] members;
+               if (type is GenericTypeParameterBuilder)
+                       return MemberList.Empty;
                if (mt == MemberTypes.Event)
                         members = type.GetEvents (bf | BindingFlags.DeclaredOnly);
                 else
@@ -2940,7 +3283,7 @@ public sealed class TypeHandle : IMemberContainer {
        public MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name,
                                       MemberFilter filter, object criteria)
        {
-               return member_cache.FindMembers (mt, bf, name, filter, criteria);
+               return new MemberList (member_cache.FindMembers (mt, bf, name, filter, criteria));
        }
 
        public MemberCache MemberCache {