2004-11-10 Martin Baulig <martin@localhost>
[mono.git] / mcs / gmcs / typemanager.cs
index 5edfc8279e27391315072b498d60845cec377c48..7e08cc98e869e2dc961c620cfd63933cef7e337e 100755 (executable)
@@ -121,6 +121,7 @@ public class TypeManager {
        static public TypeExpr system_asynccallback_expr;
        static public TypeExpr system_iasyncresult_expr;
        static public TypeExpr system_valuetype_expr;
+       static public TypeExpr system_intptr_expr;
 
        //
        // This is only used when compiling corlib
@@ -184,6 +185,7 @@ public class TypeManager {
        static public ConstructorInfo void_decimal_ctor_five_args;
        static public ConstructorInfo unverifiable_code_ctor;
        static public ConstructorInfo invalid_operation_ctor;
+       static public ConstructorInfo default_member_ctor;
        
        // <remarks>
        //   Holds the Array of Assemblies that have been loaded
@@ -360,6 +362,7 @@ public class TypeManager {
                system_asynccallback_expr = new TypeLookupExpression ("System.AsyncCallback");
                system_iasyncresult_expr = new TypeLookupExpression ("System.IAsyncResult");
                system_valuetype_expr  = new TypeLookupExpression ("System.ValueType");
+               system_intptr_expr  = new TypeLookupExpression ("System.IntPtr");
        }
 
        static TypeManager ()
@@ -415,7 +418,7 @@ public class TypeManager {
                types.Add (name, t);
        }
        
-       public static void AddUserType (string name, TypeBuilder t, TypeExpr[] ifaces)
+       public static void AddUserType (string name, TypeBuilder t)
        {
                try {
                        types.Add (name, t);
@@ -423,25 +426,22 @@ public class TypeManager {
                        HandleDuplicate (name, t); 
                }
                user_types.Add (t);
-                       
-               if (ifaces != null)
-                       builder_to_ifaces [t] = ifaces;
        }
 
        //
        // This entry point is used by types that we define under the covers
        // 
-       public static void RegisterBuilder (TypeBuilder tb, TypeExpr [] ifaces)
+       public static void RegisterBuilder (Type tb, Type [] ifaces)
        {
                if (ifaces != null)
                        builder_to_ifaces [tb] = ifaces;
        }
        
-       public static void AddUserType (string name, TypeBuilder t, TypeContainer tc, TypeExpr [] ifaces)
+       public static void AddUserType (string name, TypeBuilder t, TypeContainer tc)
        {
                builder_to_declspace.Add (t, tc);
                typecontainers.Add (name, tc);
-               AddUserType (name, t, ifaces);
+               AddUserType (name, t);
        }
 
        public static void AddDelegateType (string name, TypeBuilder t, Delegate del)
@@ -465,12 +465,6 @@ public class TypeManager {
                builder_to_declspace.Add (t, en);
        }
 
-       public static void AddUserInterface (string name, TypeBuilder t, Interface i, TypeExpr [] ifaces)
-       {
-               AddUserType (name, t, ifaces);
-               builder_to_declspace.Add (t, i);
-       }
-
        public static void AddMethod (MethodBase builder, IMethodData method)
        {
                builder_to_method.Add (builder, method);
@@ -481,14 +475,10 @@ public class TypeManager {
                return (IMethodData) builder_to_method [builder];
        }
 
-       public static void AddTypeParameter (Type t, TypeParameter tparam, TypeExpr[] ifaces)
+       public static void AddTypeParameter (Type t, TypeParameter tparam)
        {
-               if (!builder_to_type_param.Contains (t)) {
+               if (!builder_to_type_param.Contains (t))
                        builder_to_type_param.Add (t, tparam);
-
-                       if (ifaces != null)
-                               builder_to_ifaces [t] = ifaces;
-               }
        }
 
        /// <summary>
@@ -508,6 +498,14 @@ public class TypeManager {
        {
                return builder_to_declspace [t] as TypeContainer;
        }
+
+       public static TypeContainer LookupGenericTypeContainer (Type t)
+       {
+               while (t.IsGenericInstance)
+                       t = t.GetGenericTypeDefinition ();
+
+               return LookupTypeContainer (t);
+       }
        
        public static IMemberContainer LookupMemberContainer (Type t)
        {
@@ -557,19 +555,24 @@ public class TypeManager {
        }
 
        public static bool HasConstructorConstraint (Type t)
+       {
+               GenericConstraints gc = GetTypeParameterConstraints (t);
+               if (gc == null)
+                       return false;
+
+               return (gc.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
+       }
+
+       public static GenericConstraints GetTypeParameterConstraints (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 tparam.GenericConstraints;
 
-                       return attrs.Length > 0;
-               }
+               return new ReflectionConstraints (t);
        }
        
        /// <summary>
@@ -831,9 +834,6 @@ public class TypeManager {
        /// </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 ()) {
@@ -863,7 +863,7 @@ public class TypeManager {
                        @"^System\." +
                        @"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" +
                        @"Single|Double|Char|Decimal|Byte|SByte|Object|" +
-                       @"Boolean|String|Void)" +
+                       @"Boolean|String|Void|Null)" +
                        @"(\W+|\b)", 
                        new MatchEvaluator (CSharpNameMatch));
        }       
@@ -978,7 +978,7 @@ public class TypeManager {
                        iparams = new ReflectionParameters (mb);
                
                // Is property
-               if (mb.IsSpecialName && iparams.Count == 0)
+               if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor)
                        return GetFullNameSignature (mb);
                
                 for (int i = 0; i < iparams.Count; i++) {
@@ -990,7 +990,7 @@ public class TypeManager {
                sig.Append (")");
 
                // Is indexer
-               if (mb.IsSpecialName && iparams.Count == 1) {
+               if (mb.IsSpecialName && iparams.Count == 1 && !mb.IsConstructor) {
                        sig.Replace ('(', '[');
                        sig.Replace (')', ']');
                }
@@ -1397,6 +1397,8 @@ public class TypeManager {
                unverifiable_code_ctor = GetConstructor (
                        unverifiable_code_type, void_arg);
 
+               default_member_ctor = GetConstructor (default_member_type, string_);
+
                //
                // InvalidOperationException
                //
@@ -1443,6 +1445,16 @@ public class TypeManager {
                if (t.IsSubclassOf (TypeManager.array_type))
                        return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria));
 
+               if (t is GenericTypeParameterBuilder) {
+                       TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
+
+                       Timer.StartTimer (TimerType.FindMembers);
+                       MemberList list = tparam.FindMembers (
+                               mt, bf | BindingFlags.DeclaredOnly, filter, criteria);
+                       Timer.StopTimer (TimerType.FindMembers);
+                       return list;
+               }
+
                //
                // Since FindMembers will not lookup both static and instance
                // members, we emulate this behaviour here.
@@ -1715,8 +1727,11 @@ public class TypeManager {
                return tc.Kind == Kind.Interface;
        }
 
-       public static bool IsEqualGenericType (Type a, Type b)
+       public static bool IsEqual (Type a, Type b)
        {
+               if (a.Equals (b))
+                       return true;
+
                if ((a is TypeBuilder) && a.IsGenericTypeDefinition && b.IsGenericInstance) {
                        //
                        // `a' is a generic type definition's TypeBuilder and `b' is a
@@ -1732,6 +1747,9 @@ public class TypeManager {
                        // The first argument of `Test' will be the generic instance
                        // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
                        //
+                       //
+                       // We hit this via Closure.Filter() for gen-82.cs.
+                       //
                        if (a != b.GetGenericTypeDefinition ())
                                return false;
 
@@ -1742,21 +1760,46 @@ public class TypeManager {
                                return false;
 
                        for (int i = 0; i < aparams.Length; i++)
-                               if (!aparams [i].Equals (bparams [i]))
+                               if (!IsEqual (aparams [i], bparams [i]))
                                        return false;
 
                        return true;
                }
 
-               return false;
-       }
+               if (a.IsGenericParameter && b.IsGenericParameter) {
+                       if ((a.DeclaringMethod == null) || (b.DeclaringMethod == null))
+                               return false;
+                       return a.GenericParameterPosition == b.GenericParameterPosition;
+               }
+
+               if (a.IsArray && b.IsArray) {
+                       if (a.GetArrayRank () != b.GetArrayRank ())
+                               return false;
+                       return IsEqual (a.GetElementType (), b.GetElementType ());
+               }
+
+               if (a.IsGenericInstance && b.IsGenericInstance) {
+                       Type at = a.GetGenericTypeDefinition ();
+                       Type bt = b.GetGenericTypeDefinition ();
+
+                       if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+                               return false;
+
+                       Type[] aargs = a.GetGenericArguments ();
+                       Type[] bargs = b.GetGenericArguments ();
+
+                       if (aargs.Length != bargs.Length)
+                               return false;
+
+                       for (int i = 0; i < aargs.Length; i++) {
+                               if (!IsEqual (aargs [i], bargs [i]))
+                                       return false;
+                       }
 
-       public static bool IsEqual (Type a, Type b)
-       {
-               if (a.Equals (b))
                        return true;
-               else
-                       return IsEqualGenericType (a, b);
+               }
+
+               return false;
        }
 
        public static bool MayBecomeEqualGenericTypes (Type a, Type b)
@@ -1865,22 +1908,115 @@ public class TypeManager {
                return false;
        }
 
-       public static bool IsSubclassOf (Type type, Type parent)
+       public static bool IsEqualGenericInstance (Type type, Type parent)
        {
-               if (type.IsGenericInstance && !parent.IsGenericInstance)
+               int tcount = GetNumberOfTypeArguments (type);
+               int pcount = GetNumberOfTypeArguments (parent);
+
+               if (type.IsGenericInstance)
                        type = type.GetGenericTypeDefinition ();
+               if (parent.IsGenericInstance)
+                       parent = parent.GetGenericTypeDefinition ();
+
+               if (tcount != pcount)
+                       return false;
+
+               return type.Equals (parent);
+       }
+
+       public static bool IsSubclassOf (Type type, Type parent)
+       {
+               TypeParameter tparam = LookupTypeParameter (type);
+               TypeParameter pparam = LookupTypeParameter (parent);
+
+               if ((tparam != null) && (pparam != null)) {
+                       if (tparam == pparam)
+                               return true;
+
+                       return tparam.IsSubclassOf (parent);
+               }
+
+               do {
+                       if (type.Equals (parent))
+                               return true;
+
+                       type = type.BaseType;
+               } while (type != null);
+
+               return false;
+       }
+
+       public static bool IsPrivateAccessible (Type type, Type parent)
+       {
+               if (type.Equals (parent))
+                       return true;
+
+               if ((type is TypeBuilder) && type.IsGenericTypeDefinition && parent.IsGenericInstance) {
+                       //
+                       // `a' is a generic type definition's TypeBuilder and `b' is a
+                       // generic instance of the same type.
+                       //
+                       // Example:
+                       //
+                       // class Stack<T>
+                       // {
+                       //     void Test (Stack<T> stack) { }
+                       // }
+                       //
+                       // The first argument of `Test' will be the generic instance
+                       // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
+                       //
+                       //
+                       // We hit this via Closure.Filter() for gen-82.cs.
+                       //
+                       if (type != parent.GetGenericTypeDefinition ())
+                               return false;
+
+                       return true;
+               }
+
+               if (type.IsGenericInstance && parent.IsGenericInstance) {
+                       Type tdef = type.GetGenericTypeDefinition ();
+                       Type pdef = parent.GetGenericTypeDefinition ();
+
+                       if (type.GetGenericTypeDefinition () != parent.GetGenericTypeDefinition ())
+                               return false;
+
+                       return true;
+               }
+
+               return false;
+       }
+
+       public static bool IsFamilyAccessible (Type type, Type parent)
+       {
+               TypeParameter tparam = LookupTypeParameter (type);
+               TypeParameter pparam = LookupTypeParameter (parent);
+
+               if ((tparam != null) && (pparam != null)) {
+                       if (tparam == pparam)
+                               return true;
+
+                       return tparam.IsSubclassOf (parent);
+               }
 
-               return type.IsSubclassOf (parent);
+               do {
+                       if (IsEqualGenericInstance (type, parent))
+                               return true;
+
+                       type = type.BaseType;
+               } while (type != null);
+
+               return false;
        }
 
        //
        // Checks whether `type' is a subclass or nested child of `parent'.
        //
-       public static bool IsSubclassOrNestedChildOf (Type type, Type parent)
+       public static bool IsNestedFamilyAccessible (Type type, Type parent)
        {
                do {
-                       if ((type == parent) || type.IsSubclassOf (parent) ||
-                           IsEqualGenericType (type, parent))
+                       if (IsFamilyAccessible (type, parent))
                                return true;
 
                        // Handle nested types.
@@ -1895,12 +2031,12 @@ public class TypeManager {
        //
        public static bool IsNestedChildOf (Type type, Type parent)
        {
-               if (type == parent)
+               if (IsEqual (type, parent))
                        return false;
 
                type = type.DeclaringType;
                while (type != null) {
-                       if (type == parent)
+                       if (IsEqual (type, parent))
                                return true;
 
                        type = type.DeclaringType;
@@ -1966,15 +2102,13 @@ public class TypeManager {
        ///   for anything which is dynamic, and we need this in a number of places,
        ///   we register this information here, and use it afterwards.
        /// </remarks>
-       static public bool RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
+       static public void RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
        {
                if (args == null)
                        args = NoTypes;
                                
                method_arguments.Add (mb, args);
                method_internal_params.Add (mb, ip);
-               
-               return true;
        }
        
        static public InternalParameters LookupParametersByBuilder (MethodBase mb)
@@ -2090,17 +2224,14 @@ public class TypeManager {
        
        static Hashtable events;
 
-       static public bool RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
+       static public void RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
        {
                if (events == null)
                        events = new Hashtable ();
 
-               if (events.Contains (eb))
-                       return false;
-
+               if (!events.Contains (eb)) {
                events.Add (eb, new Pair (add, remove));
-
-               return true;
+               }
        }
 
        static public MethodInfo GetAddMethod (EventInfo ei)
@@ -2109,8 +2240,8 @@ public class TypeManager {
                        Pair pair = (Pair) events [ei];
 
                        return (MethodInfo) pair.First;
-               } else
-                       return ei.GetAddMethod ();
+               }
+               return ei.GetAddMethod (true);
        }
 
        static public MethodInfo GetRemoveMethod (EventInfo ei)
@@ -2119,8 +2250,8 @@ public class TypeManager {
                        Pair pair = (Pair) events [ei];
 
                        return (MethodInfo) pair.Second;
-               } else
-                       return ei.GetRemoveMethod ();
+               }
+               return ei.GetRemoveMethod (true);
        }
 
        static Hashtable priv_fields_events;
@@ -2239,22 +2370,26 @@ public class TypeManager {
        ///   This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
        ///   be IA, IB, IC.
        /// </remarks>
-       public static TypeExpr[] ExpandInterfaces (TypeExpr [] base_interfaces)
+       public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces)
        {
                ArrayList new_ifaces = new ArrayList ();
                
                foreach (TypeExpr iface in base_interfaces){
-                       if (!new_ifaces.Contains (iface))
-                               new_ifaces.Add (iface);
+                       Type itype = iface.ResolveType (ec);
+                       if (itype == null)
+                               return null;
+
+                       if (!new_ifaces.Contains (itype))
+                               new_ifaces.Add (itype);
                        
-                       TypeExpr [] implementing = iface.GetInterfaces ();
+                       Type [] implementing = itype.GetInterfaces ();
                        
-                       foreach (TypeExpr imp in implementing){
+                       foreach (Type imp in implementing){
                                if (!new_ifaces.Contains (imp))
                                        new_ifaces.Add (imp);
                        }
                }
-               TypeExpr [] ret = new TypeExpr [new_ifaces.Count];
+               Type [] ret = new Type [new_ifaces.Count];
                new_ifaces.CopyTo (ret, 0);
                return ret;
        }
@@ -2265,10 +2400,10 @@ public class TypeManager {
        ///   This function returns the interfaces in the type `t'.  Works with
        ///   both types and TypeBuilders.
        /// </summary>
-       public static TypeExpr [] GetInterfaces (Type t)
+       public static Type [] GetInterfaces (Type t)
        {
                
-               TypeExpr [] cached = iface_cache [t] as TypeExpr [];
+               Type [] cached = iface_cache [t] as Type [];
                if (cached != null)
                        return cached;
                
@@ -2286,50 +2421,43 @@ public class TypeManager {
                        t = TypeManager.array_type;
                
                if (t is TypeBuilder){
-                       TypeExpr [] parent_ifaces;
+                       Type[] parent_ifaces;
                        
                        if (t.BaseType == null)
-                               parent_ifaces = NoTypeExprs;
+                               parent_ifaces = NoTypes;
                        else
                                parent_ifaces = GetInterfaces (t.BaseType);
-                       TypeExpr [] type_ifaces = (TypeExpr []) builder_to_ifaces [t];
+                       Type[] type_ifaces = (Type []) builder_to_ifaces [t];
                        if (type_ifaces == null)
-                               type_ifaces = NoTypeExprs;
+                               type_ifaces = NoTypes;
 
                        int parent_count = parent_ifaces.Length;
-                       TypeExpr [] result = new TypeExpr [parent_count + type_ifaces.Length];
+                       Type[] result = new Type [parent_count + type_ifaces.Length];
                        parent_ifaces.CopyTo (result, 0);
                        type_ifaces.CopyTo (result, parent_count);
 
                        iface_cache [t] = result;
                        return result;
                } else if (t is GenericTypeParameterBuilder){
-                       TypeExpr[] type_ifaces = (TypeExpr []) builder_to_ifaces [t];
+                       Type[] type_ifaces = (Type []) builder_to_ifaces [t];
                        if (type_ifaces == null)
-                               type_ifaces = NoTypeExprs;
+                               type_ifaces = NoTypes;
 
                        iface_cache [t] = type_ifaces;
                        return type_ifaces;
                } else {
-                       Type [] ifaces = t.GetInterfaces ();
-                       if (ifaces.Length == 0)
-                               return NoTypeExprs;
-
-                       TypeExpr [] result = new TypeExpr [ifaces.Length];
-                       for (int i = 0; i < ifaces.Length; i++)
-                               result [i] = new TypeExpression (ifaces [i], Location.Null);
-                       
-                       iface_cache [t] = result;
-                       return result;
+                       Type[] ifaces = t.GetInterfaces ();
+                       iface_cache [t] = ifaces;
+                       return ifaces;
                }
        }
        
        //
        // gets the interfaces that are declared explicitly on t
        //
-       public static TypeExpr [] GetExplicitInterfaces (TypeBuilder t)
+       public static Type [] GetExplicitInterfaces (TypeBuilder t)
        {
-               return (TypeExpr []) builder_to_ifaces [t];
+               return (Type []) builder_to_ifaces [t];
        }
        
        /// <remarks>
@@ -2338,7 +2466,7 @@ public class TypeManager {
        /// </remarks>
        public static bool ImplementsInterface (Type t, Type iface)
        {
-               TypeExpr [] interfaces;
+               Type [] interfaces;
 
                //
                // FIXME OPTIMIZATION:
@@ -2351,8 +2479,8 @@ public class TypeManager {
                        interfaces = GetInterfaces (t);
 
                        if (interfaces != null){
-                               foreach (TypeExpr i in interfaces){
-                                       if (i.Type == iface)
+                               foreach (Type i in interfaces){
+                                       if (i == iface)
                                                return true;
                                }
                        }
@@ -2563,7 +2691,7 @@ public class TypeManager {
        /// </summary>
        /// <remarks>
        ///   The default is not always `Item'.  The user can change this behaviour by
-       ///   using the DefaultMemberAttribute in the class.
+       ///   using the IndexerNameAttribute in the container.
        ///
        ///   For example, the String class indexer is named `Chars' not `Item' 
        /// </remarks>
@@ -2573,21 +2701,8 @@ public class TypeManager {
                        t = t.GetGenericTypeDefinition ();
 
                if (t is TypeBuilder) {
-                       if (t.IsInterface) {
-                               TypeContainer i = LookupInterface (t);
-
-                               if ((i == null) || (i.IndexerName == null))
-                                       return "Item";
-
-                               return i.IndexerName;
-                       } else {
-                               TypeContainer tc = LookupTypeContainer (t);
-
-                               if ((tc == null) || (tc.IndexerName == null))
-                                       return "Item";
-
-                               return tc.IndexerName;
-                       }
+                       TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t);
+                       return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName;
                }
                
                System.Attribute attr = System.Attribute.GetCustomAttribute (
@@ -2597,7 +2712,7 @@ public class TypeManager {
                        return dma.MemberName;
                }
 
-               return "Item";
+               return TypeContainer.DefaultIndexerName;
        }
 
        static MethodInfo declare_local_method = null;
@@ -2715,75 +2830,54 @@ public class TypeManager {
        internal class Closure {
                internal bool     private_ok;
 
-       // Who is invoking us and which type is being queried currently.
+               // Who is invoking us and which type is being queried currently.
                internal Type     invocation_type;
                internal Type     qualifier_type;
 
-       // The assembly that defines the type is that is calling us
+               // The assembly that defines the type is that is calling us
                internal Assembly invocation_assembly;
                internal IList almost_match;
 
                private bool CheckValidFamilyAccess (bool is_static, MemberInfo m)
-       {
+               {
                        if (invocation_type == null)
                                return false;
 
-                       Debug.Assert (IsSubclassOrNestedChildOf (invocation_type, m.DeclaringType));
-
                        if (is_static)
                                return true;
                        
-                       // A nested class has access to all the protected members visible to its parent.
+                       // 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
+                               // 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;
-       }
+                                       return true;
+                       }
        
                        if (almost_match != null)
                                almost_match.Add (m);
                        return false;
                }
-               
-       //
-       // This filter filters by name + whether it is ok to include private
-       // members in the search
-       //
-               internal bool Filter (MemberInfo m, object filter_criteria)
-       {
-               //
-               // Hack: we know that the filter criteria will always be in the `closure'
-               // fields. 
-               //
-
-               if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
-                       return false;
-
-               if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
-                   (invocation_type != null) && IsEqual (m.DeclaringType, invocation_type))
-                       return true;
 
-               //
-               // Ugly: we need to find out the type of `m', and depending
-               // on this, tell whether we accept or not
-               //
-               if (m is MethodBase){
-                       MethodBase mb = (MethodBase) m;
+               bool Filter (MethodBase mb, object filter_criteria)
+               {
                        MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
 
                        if (ma == MethodAttributes.Private)
                                return private_ok ||
-                                       IsEqual (invocation_type, m.DeclaringType) ||
-                                       IsNestedChildOf (invocation_type, m.DeclaringType);
+                                       IsPrivateAccessible (invocation_type, mb.DeclaringType) ||
+                                       IsNestedChildOf (invocation_type, mb.DeclaringType);
 
                        //
                        // FamAndAssem requires that we not only derivate, but we are on the
@@ -2809,14 +2903,14 @@ public class TypeManager {
                                if (invocation_type == null)
                                        return false;
 
-                               if (!IsSubclassOrNestedChildOf (invocation_type, mb.DeclaringType))
+                               if (!IsNestedFamilyAccessible (invocation_type, mb.DeclaringType))
                                        return false;
 
                                // Although a derived class can access protected members of its base class
                                // it cannot do so through an instance of the base class (CS1540).
-                               if (!mb.IsStatic && (invocation_type != qualifier_type) &&
-                                   (qualifier_type != null) &&
-                                   invocation_type.IsSubclassOf (qualifier_type) &&
+                               if (!mb.IsStatic && (qualifier_type != null) &&
+                                   !IsEqualGenericInstance (invocation_type, qualifier_type) &&
+                                   TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) &&
                                    !TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
                                        return false;
 
@@ -2827,14 +2921,14 @@ public class TypeManager {
                        return true;
                }
 
-               if (m is FieldInfo){
-                       FieldInfo fi = (FieldInfo) m;
+               bool Filter (FieldInfo fi, object filter_criteria)
+               {
                        FieldAttributes fa = fi.Attributes & FieldAttributes.FieldAccessMask;
 
                        if (fa == FieldAttributes.Private)
                                return private_ok ||
-                                       IsEqual (invocation_type, m.DeclaringType) ||
-                                       IsNestedChildOf (invocation_type, m.DeclaringType);
+                                       IsPrivateAccessible (invocation_type, fi.DeclaringType) ||
+                                       IsNestedChildOf (invocation_type, fi.DeclaringType);
 
                        //
                        // FamAndAssem requires that we not only derivate, but we are on the
@@ -2860,14 +2954,14 @@ public class TypeManager {
                                if (invocation_type == null)
                                        return false;
 
-                               if (!IsSubclassOrNestedChildOf (invocation_type, fi.DeclaringType))
+                               if (!IsNestedFamilyAccessible (invocation_type, fi.DeclaringType))
                                        return false;
 
                                // Although a derived class can access protected members of its base class
                                // it cannot do so through an instance of the base class (CS1540).
-                               if (!fi.IsStatic && (invocation_type != qualifier_type) &&
-                                   (qualifier_type != null) &&
-                                   invocation_type.IsSubclassOf (qualifier_type) &&
+                               if (!fi.IsStatic && (qualifier_type != null) &&
+                                   !IsEqualGenericInstance (invocation_type, qualifier_type) &&
+                                   TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) &&
                                    !TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
                                        return false;
 
@@ -2877,18 +2971,46 @@ public class TypeManager {
                        // Public.
                        return true;
                }
-
+               
                //
-               // EventInfos and PropertyInfos, return true because they lack permission
-                       // information, so we need to check later on the methods.
+               // This filter filters by name + whether it is ok to include private
+               // members in the search
                //
-               return true;
-       }
+               internal bool Filter (MemberInfo m, object filter_criteria)
+               {
+                       //
+                       // Hack: we know that the filter criteria will always be in the
+                       // `closure' // fields. 
+                       //
+
+                       if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
+                               return false;
+
+                       if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
+                           (invocation_type != null) &&
+                           IsPrivateAccessible (m.DeclaringType, invocation_type))
+                               return true;
+
+                       //
+                       // Ugly: we need to find out the type of `m', and depending
+                       // on this, tell whether we accept or not
+                       //
+                       if (m is MethodBase)
+                               return Filter ((MethodBase) m, filter_criteria);
+
+                       if (m is FieldInfo)
+                               return Filter ((FieldInfo) m, filter_criteria);
+
+                       //
+                       // EventInfos and PropertyInfos, return true because they lack
+                       // permission information, so we need to check later on the methods.
+                       //
+                       return true;
+               }
        }
 
        static Closure closure = new Closure ();
        static MemberFilter FilterWithClosure_delegate = new MemberFilter (closure.Filter);
-       static MemberFilter FilterNone_delegate = new MemberFilter (FilterNone);
 
        //
        // Looks up a member called `name' in the `queried_type'.  This lookup
@@ -3113,14 +3235,14 @@ public class TypeManager {
                if (queried_type.IsArray)
                        queried_type = TypeManager.array_type;
                
-               TypeExpr [] ifaces = GetInterfaces (queried_type);
+               Type [] ifaces = GetInterfaces (queried_type);
                if (ifaces == null)
                        return null;
                
-               foreach (TypeExpr itype in ifaces){
+               foreach (Type itype in ifaces){
                        MemberInfo [] x;
 
-                       x = MemberLookup (null, null, itype.Type, mt, bf, name, null);
+                       x = MemberLookup (null, null, itype, mt, bf, name, null);
                        if (x != null)
                                return x;
                }
@@ -3128,85 +3250,30 @@ public class TypeManager {
                return null;
        }
 
-       //
-       // This is used to extract properties and event declarations from a type
-       //
-       static MemberInfo [] SpecialContainerLookup (Type t, bool is_static)
-       {
-               BindingFlags bf = BindingFlags.DeclaredOnly | (is_static ? BindingFlags.Static : BindingFlags.Instance);
-
-               bf |= BindingFlags.Public | BindingFlags.NonPublic;
-               
-               if (t is TypeBuilder) {
-                       DeclSpace decl = (DeclSpace) builder_to_declspace [t];
-
-                       return (MemberInfo []) decl.FindMembers (
-                               MemberTypes.Property | MemberTypes.Event,
-                               bf, FilterNone_delegate, null);
-               } else {
-                       return t.FindMembers (MemberTypes.Property | MemberTypes.Event,
-                                             bf, FilterNone_delegate, null);
-
-               }
-       }
-       
+       // Tests whether external method is really special
        public static bool IsSpecialMethod (MethodBase mb)
        {
-               Type t = mb.DeclaringType;
-               
-               MemberInfo [] matches = TypeManager.SpecialContainerLookup (t, mb.IsStatic);
-               if (matches == null)
-                       return false;
-               
-               foreach (MemberInfo mi in matches){
-                       if (mi is PropertyBuilder){
-                               Pair p = (Pair) properties [mi];
-
-                               if (p.First == mb || p.Second == mb)
-                                       return true;
-                       } else if (mi is PropertyInfo){
-                               MethodInfo [] methods = ((PropertyInfo) mi).GetAccessors (true);
-                               
-                               foreach (MethodInfo m in methods){
-                                       if (m == mb)
-                                               return true;
-                               }
-                       } else if (mi is MyEventBuilder){
-                               Pair p = (Pair) events [mi];
-
-                               if (p.First == mb || p.Second == mb)
-                                       return true;
-                       } else if (mi is EventInfo){
-                               EventInfo ei = ((EventInfo) mi);
-                               
-                               if (ei.GetAddMethod (true) == mb)
-                                       return true;
-                               
-                               if (ei.GetRemoveMethod (true) == mb)
-                                       return true;
+               string name = mb.Name;
+               if (name.StartsWith ("get_") || name.StartsWith ("set_"))
+                       return mb.DeclaringType.GetProperty (name.Substring (4)) != null;
                                
-                               if (ei.GetRaiseMethod (true) == mb)
-                                       return true;
-                       }
-               }
+               if (name.StartsWith ("add_"))
+                       return mb.DeclaringType.GetEvent (name.Substring (4)) != null;
 
-               //
-               // Now check if it is an operator method
-               //
-               string s = mb.Name;
+               if (name.StartsWith ("remove_"))
+                       return mb.DeclaringType.GetEvent (name.Substring (7)) != null;
 
-               if (s.StartsWith ("op_")){
-                       foreach (string name in Unary.oper_names){
-                               if (s == name)
+               if (name.StartsWith ("op_")){
+                       foreach (string oname in Unary.oper_names) {
+                               if (oname == name)
                                        return true;
                        }
 
-                       foreach (string name in Binary.oper_names){
-                               if (s == name)
+                       foreach (string oname in Binary.oper_names) {
+                               if (oname == name)
                                        return true;
                        }
                }
-               
                return false;
        }
                
@@ -3306,7 +3373,7 @@ public sealed class TypeHandle : IMemberContainer {
                }
        }
 
-       public IMemberContainer Parent {
+       public IMemberContainer ParentContainer {
                get {
                        return BaseType;
                }