2004-11-10 Martin Baulig <martin@localhost>
[mono.git] / mcs / gmcs / typemanager.cs
index 7172e05b22d29164f69252717cf4d434f52f8802..7e08cc98e869e2dc961c620cfd63933cef7e337e 100755 (executable)
@@ -70,6 +70,7 @@ public class TypeManager {
        static public Type intptr_type;
        static public Type monitor_type;
        static public Type runtime_field_handle_type;
+       static public Type runtime_argument_handle_type;
        static public Type attribute_type;
        static public Type attribute_usage_type;
        static public Type dllimport_type;
@@ -84,8 +85,9 @@ public class TypeManager {
        static public Type exception_type;
        static public Type activator_type;
        static public Type invalid_operation_exception_type;
+       static public Type not_supported_exception_type;
        static public Type obsolete_attribute_type;
-       static public object conditional_attribute_type;
+       static public Type conditional_attribute_type;
        static public Type in_attribute_type;
        static public Type cls_compliant_attribute_type;
        static public Type typed_reference_type;
@@ -94,6 +96,9 @@ public class TypeManager {
        static public Type struct_layout_attribute_type;
        static public Type field_offset_attribute_type;
 
+       static public Type generic_ienumerator_type;
+       static public Type generic_ienumerable_type;
+
        //
        // An empty array of types
        //
@@ -116,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
@@ -179,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
@@ -355,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 ()
@@ -410,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);
@@ -418,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)
@@ -460,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);
@@ -476,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>
@@ -503,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)
        {
@@ -522,9 +525,13 @@ public class TypeManager {
                return TypeHandle.GetTypeHandle (t);
        }
 
-       public static Interface LookupInterface (Type t)
+       public static TypeContainer LookupInterface (Type t)
        {
-               return builder_to_declspace [t] as Interface;
+               TypeContainer tc = (TypeContainer) builder_to_declspace [t];
+               if ((tc == null) || (tc.Kind != Kind.Interface))
+                       return null;
+
+               return tc;
        }
 
        public static Delegate LookupDelegate (Type t)
@@ -548,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>
@@ -582,6 +594,11 @@ public class TypeManager {
                assemblies = n;
        }
 
+        public static Assembly [] GetAssemblies ()
+        {
+                return assemblies;
+        }
+
        /// <summary>
        ///  Registers a module builder to lookup types from
        /// </summary>
@@ -697,16 +714,11 @@ public class TypeManager {
                if (t != null)
                        return t;
 
-               if (negative_hits.Contains (name))
-                       return null;
-
                t = LookupTypeReflection (name);
-               
                if (t == null)
-                       negative_hits [name] = null;
-               else
+                       return null;
+
                types [name] = t;
-               
                return t;
        }
 
@@ -822,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 ()) {
@@ -854,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));
        }       
@@ -879,11 +888,25 @@ public class TypeManager {
        /// </summary>
        static public string GetFullNameSignature (MemberInfo mi)
        {
-               string n = mi.Name;
-               if (n == ".ctor")
-                       n = mi.DeclaringType.Name;
+               return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name;
+       }
                
-               return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + n;
+       static public string GetFullNameSignature (MethodBase mb)
+       {
+               string name = mb.Name;
+               if (name == ".ctor")
+                       name = mb.DeclaringType.Name;
+
+               if (mb.IsSpecialName) {
+                       if (name.StartsWith ("get_") || name.StartsWith ("set_")) {
+                               name = name.Remove (0, 4);
+                       }
+
+                       if (name == "Item")
+                               name = "this";
+               }
+
+               return mb.DeclaringType.FullName.Replace ('+', '.') + '.' + name;
        }
 
        static public string GetFullName (Type t)
@@ -943,7 +966,7 @@ public class TypeManager {
         /// </summary>
         static public string CSharpSignature (MethodBase mb)
         {
-                string sig = "(";
+               StringBuilder sig = new StringBuilder ("(");
 
                //
                // FIXME: We should really have a single function to do
@@ -954,15 +977,25 @@ public class TypeManager {
                if (iparams == null)
                        iparams = new ReflectionParameters (mb);
                
+               // Is property
+               if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor)
+                       return GetFullNameSignature (mb);
+               
                 for (int i = 0; i < iparams.Count; i++) {
                         if (i > 0) {
-                                sig += ", ";
+                               sig.Append (", ");
                         }
-                        sig += iparams.ParameterDesc(i);
+                       sig.Append (iparams.ParameterDesc (i));
                 }
-                sig += ")";
+               sig.Append (")");
 
-                return GetFullNameSignature (mb) + sig;
+               // Is indexer
+               if (mb.IsSpecialName && iparams.Count == 1 && !mb.IsConstructor) {
+                       sig.Replace ('(', '[');
+                       sig.Replace (')', ']');
+               }
+
+               return GetFullNameSignature (mb) + sig.ToString ();
         }
 
        /// <summary>
@@ -1095,6 +1128,7 @@ public class TypeManager {
                type_type     = CoreLookupType ("System.Type");
 
                runtime_field_handle_type = CoreLookupType ("System.RuntimeFieldHandle");
+               runtime_argument_handle_type = CoreLookupType ("System.RuntimeArgumentHandle");
                runtime_helpers_type = CoreLookupType ("System.Runtime.CompilerServices.RuntimeHelpers");
                default_member_type  = CoreLookupType ("System.Reflection.DefaultMemberAttribute");
                runtime_handle_type  = CoreLookupType ("System.RuntimeTypeHandle");
@@ -1135,6 +1169,7 @@ public class TypeManager {
                exception_type        = CoreLookupType ("System.Exception");
                activator_type        = CoreLookupType ("System.Activator");
                invalid_operation_exception_type = CoreLookupType ("System.InvalidOperationException");
+               not_supported_exception_type = CoreLookupType ("System.NotSupportedException");
 
                //
                // Attribute types
@@ -1145,6 +1180,13 @@ public class TypeManager {
                struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute");
                field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute");
 
+               //
+               // Generic types
+               //
+               generic_ienumerator_type     = CoreLookupType (MemberName.MakeName ("System.Collections.Generic.IEnumerator", 1));
+               generic_ienumerable_type     = CoreLookupType (MemberName.MakeName ("System.Collections.Generic.IEnumerable", 1));
+
+
                //
                // When compiling corlib, store the "real" types here.
                //
@@ -1355,6 +1397,8 @@ public class TypeManager {
                unverifiable_code_ctor = GetConstructor (
                        unverifiable_code_type, void_arg);
 
+               default_member_ctor = GetConstructor (default_member_type, string_);
+
                //
                // InvalidOperationException
                //
@@ -1401,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.
@@ -1556,7 +1610,7 @@ public class TypeManager {
        
        public static bool IsEnumType (Type t)
        {
-               if (t == TypeManager.enum_type || t.IsSubclassOf (TypeManager.enum_type))
+               if (t.IsSubclassOf (TypeManager.enum_type))
                        return true;
                else
                        return false;
@@ -1666,16 +1720,18 @@ public class TypeManager {
        
        public static bool IsInterfaceType (Type t)
        {
-               Interface iface = builder_to_declspace [t] as Interface;
-
-               if (iface != null)
-                       return true;
-               else
+               TypeContainer tc = (TypeContainer) builder_to_declspace [t];
+               if (tc == null)
                        return false;
+
+               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
@@ -1691,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;
 
@@ -1701,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)
@@ -1824,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 type.IsSubclassOf (parent);
+                       return tparam.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.
@@ -1854,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;
@@ -1925,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)
@@ -1956,20 +2131,24 @@ public class TypeManager {
        /// </summary>
        static public Type [] GetArgumentTypes (MethodBase mb)
        {
-               if (method_arguments.Contains (mb))
-                       return (Type []) method_arguments [mb];
-               else {
+               object t = method_arguments [mb];
+               if (t != null)
+                       return (Type []) t;
+
                        ParameterInfo [] pi = mb.GetParameters ();
                        int c = pi.Length;
-                       Type [] types = new Type [c];
+               Type [] types;
                        
+               if (c == 0) {
+                       types = NoTypes;
+               } else {
+                       types = new Type [c];
                        for (int i = 0; i < c; i++)
                                types [i] = pi [i].ParameterType;
-
+               }
                        method_arguments.Add (mb, types);
                        return types;
                }
-       }
 
        /// <summary>
        ///    Returns the argument types for an indexer based on its PropertyInfo
@@ -2045,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)
@@ -2064,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)
@@ -2074,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;
@@ -2136,7 +2312,7 @@ public class TypeManager {
        public static bool CheckStructCycles (TypeContainer tc, Hashtable seen,
                                              Hashtable hash)
        {
-               if (!(tc is Struct) || IsBuiltinType (tc))
+               if ((tc.Kind != Kind.Struct) || IsBuiltinType (tc))
                        return true;
 
                //
@@ -2194,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;
        }
@@ -2220,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;
                
@@ -2241,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>
@@ -2293,7 +2466,7 @@ public class TypeManager {
        /// </remarks>
        public static bool ImplementsInterface (Type t, Type iface)
        {
-               TypeExpr [] interfaces;
+               Type [] interfaces;
 
                //
                // FIXME OPTIMIZATION:
@@ -2306,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;
                                }
                        }
@@ -2518,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>
@@ -2528,21 +2701,8 @@ public class TypeManager {
                        t = t.GetGenericTypeDefinition ();
 
                if (t is TypeBuilder) {
-                       if (t.IsInterface) {
-                               Interface 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 (
@@ -2552,26 +2712,30 @@ public class TypeManager {
                        return dma.MemberName;
                }
 
-               return "Item";
+               return TypeContainer.DefaultIndexerName;
        }
 
-       static MethodInfo pinned_method = null;
-       public static void MakePinned (LocalBuilder builder)
-       {
-               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." +
+       static MethodInfo declare_local_method = null;
+       
+       public static LocalBuilder DeclareLocalPinned (ILGenerator ig, Type t)
+       {
+               if (declare_local_method == null){
+                       declare_local_method = typeof (ILGenerator).GetMethod (
+                               "DeclareLocal",
+                               BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
+                               null, 
+                               new Type [] { typeof (Type), typeof (bool)},
+                               null);
+                       if (declare_local_method == null){
+                               Report.Warning (-24, 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;
+                               return ig.DeclareLocal (t);
                        }
                }
-               
-               pinned_method.Invoke (builder, null);
+               return (LocalBuilder) declare_local_method.Invoke (ig, new object [] { t, true });
        }
 
-
        //
        // Returns whether the array of memberinfos contains the given method
        //
@@ -2638,11 +2802,6 @@ public class TypeManager {
                return target_list;
        }
 
-       [Flags]
-       public enum MethodFlags {
-               ShouldIgnore = 1 << 2
-       }
-
        static public bool IsGenericMethod (MethodBase mb)
        {
                if (mb.DeclaringType is TypeBuilder) {
@@ -2656,121 +2815,82 @@ public class TypeManager {
                return mb.IsGenericMethodDefinition;
        }
        
-       //
-       // Returns the TypeManager.MethodFlags for this method.
-       // This emits an error 619 / warning 618 if the method is obsolete.
-       // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
-       //
-       static public MethodFlags GetMethodFlags (MethodBase mb)
-       {
-               MethodFlags flags = 0;
-
-               if (mb.Mono_IsInflatedMethod)
-                       mb = mb.GetGenericMethodDefinition ();
-
-               if (mb.DeclaringType is TypeBuilder){
-                       IMethodData method = (IMethodData) builder_to_method [mb];
-                       if (method == null) {
-                               // FIXME: implement Obsolete attribute on Property,
-                               //        Indexer and Event.
-                               return 0;
-                       }
-
-                       if (method.ShouldIgnore ())
-                               flags |= MethodFlags.ShouldIgnore;
-
-                       return flags;
-               }
-
-               object [] attrs = mb.GetCustomAttributes (true);
-               foreach (object ta in attrs){
-                       if (!(ta is System.Attribute)){
-                               Console.WriteLine ("Unknown type in GetMethodFlags: " + ta);
-                               continue;
-                       }
-                       System.Attribute a = (System.Attribute) ta;
-                       
-                       //
-                       // Skip over conditional code.
-                       //
-                       if (a.TypeId == TypeManager.conditional_attribute_type){
-                               ConditionalAttribute ca = (ConditionalAttribute) a;
-
-                               if (RootContext.AllDefines [ca.ConditionString] == null)
-                                       flags |= MethodFlags.ShouldIgnore;
-                       }
-               }
-
-               return flags;
-       }
-       
 #region MemberLookup implementation
        
        //
        // Whether we allow private members in the result (since FindMembers
        // uses NonPublic for both protected and private), we need to distinguish.
        //
-       static bool     closure_private_ok;
-
-       //
-       // Who is invoking us and which type is being queried currently.
-       //
-       static Type     closure_invocation_type;
-       static Type     closure_qualifier_type;
-
-       //
-       // The assembly that defines the type is that is calling us
-       //
-       static Assembly closure_invocation_assembly;
 
        static internal bool FilterNone (MemberInfo m, object filter_criteria)
        {
                return true;
        }
-       
-       //
-       // This filter filters by name + whether it is ok to include private
-       // members in the search
-       //
-       static internal bool FilterWithClosure (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;
+       internal class Closure {
+               internal bool     private_ok;
 
-               if (((closure_qualifier_type == null) || (closure_qualifier_type == closure_invocation_type)) &&
-                   (closure_invocation_type != null) && IsEqual (m.DeclaringType, closure_invocation_type))
-                       return true;
+               // Who is invoking us and which type is being queried currently.
+               internal Type     invocation_type;
+               internal Type     qualifier_type;
 
-               //
-               // 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;
+               // 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;
+
+                       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;
 
                        if (ma == MethodAttributes.Private)
-                               return closure_private_ok ||
-                                       IsEqual (closure_invocation_type, m.DeclaringType) ||
-                                       IsNestedChildOf (closure_invocation_type, m.DeclaringType);
+                               return private_ok ||
+                                       IsPrivateAccessible (invocation_type, mb.DeclaringType) ||
+                                       IsNestedChildOf (invocation_type, mb.DeclaringType);
 
                        //
                        // FamAndAssem requires that we not only derivate, but we are on the
                        // same assembly.  
                        //
                        if (ma == MethodAttributes.FamANDAssem){
-                               if (closure_invocation_assembly != mb.DeclaringType.Assembly)
+                               if (invocation_assembly != mb.DeclaringType.Assembly)
                                        return false;
                        }
 
                        // Assembly and FamORAssem succeed if we're in the same assembly.
                        if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
-                               if (closure_invocation_assembly == mb.DeclaringType.Assembly)
+                               if (invocation_assembly == mb.DeclaringType.Assembly)
                                        return true;
                        }
 
@@ -2780,18 +2900,18 @@ public class TypeManager {
 
                        // Family and FamANDAssem require that we derive.
                        if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem)){
-                               if (closure_invocation_type == null)
+                               if (invocation_type == null)
                                        return false;
 
-                               if (!IsSubclassOrNestedChildOf (closure_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 && (closure_invocation_type != closure_qualifier_type) &&
-                                   (closure_qualifier_type != null) &&
-                                   closure_invocation_type.IsSubclassOf (closure_qualifier_type) &&
-                                   !TypeManager.IsNestedChildOf (closure_invocation_type, closure_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;
 
                                return true;
@@ -2801,27 +2921,27 @@ 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 closure_private_ok ||
-                                       IsEqual (closure_invocation_type, m.DeclaringType) ||
-                                       IsNestedChildOf (closure_invocation_type, m.DeclaringType);
+                               return private_ok ||
+                                       IsPrivateAccessible (invocation_type, fi.DeclaringType) ||
+                                       IsNestedChildOf (invocation_type, fi.DeclaringType);
 
                        //
                        // FamAndAssem requires that we not only derivate, but we are on the
                        // same assembly.  
                        //
                        if (fa == FieldAttributes.FamANDAssem){
-                               if (closure_invocation_assembly != fi.DeclaringType.Assembly)
+                               if (invocation_assembly != fi.DeclaringType.Assembly)
                                        return false;
                        }
 
                        // Assembly and FamORAssem succeed if we're in the same assembly.
                        if ((fa == FieldAttributes.Assembly) || (fa == FieldAttributes.FamORAssem)){
-                               if (closure_invocation_assembly == fi.DeclaringType.Assembly)
+                               if (invocation_assembly == fi.DeclaringType.Assembly)
                                        return true;
                        }
 
@@ -2831,18 +2951,18 @@ public class TypeManager {
 
                        // Family and FamANDAssem require that we derive.
                        if ((fa == FieldAttributes.Family) || (fa == FieldAttributes.FamANDAssem)){
-                               if (closure_invocation_type == null)
+                               if (invocation_type == null)
                                        return false;
 
-                               if (!IsSubclassOrNestedChildOf (closure_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 && (closure_invocation_type != closure_qualifier_type) &&
-                                   (closure_qualifier_type != null) &&
-                                   closure_invocation_type.IsSubclassOf (closure_qualifier_type) &&
-                                   !TypeManager.IsNestedChildOf (closure_invocation_type, closure_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;
 
                                return true;
@@ -2851,16 +2971,46 @@ public class TypeManager {
                        // Public.
                        return true;
                }
-
+               
                //
-               // EventInfos and PropertyInfos, return true because they lack permission
-               // informaiton, 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 MemberFilter FilterWithClosure_delegate = new MemberFilter (FilterWithClosure);
-       static MemberFilter FilterNone_delegate = new MemberFilter (FilterNone);
+       static Closure closure = new Closure ();
+       static MemberFilter FilterWithClosure_delegate = new MemberFilter (closure.Filter);
 
        //
        // Looks up a member called `name' in the `queried_type'.  This lookup
@@ -2887,17 +3037,19 @@ public class TypeManager {
        // is allowed to access (using the specified `qualifier_type' if given); only use
        // BindingFlags.NonPublic to bypass the permission check.
        //
+       // The 'almost_match' argument is used for reporting error CS1540.
+       //
        // Returns an array of a single element for everything but Methods/Constructors
        // that might return multiple matches.
        //
        public static MemberInfo [] MemberLookup (Type invocation_type, Type qualifier_type,
                                                  Type queried_type, MemberTypes mt,
-                                                 BindingFlags original_bf, string name)
+                                                 BindingFlags original_bf, string name, IList almost_match)
        {
                Timer.StartTimer (TimerType.MemberLookup);
 
                MemberInfo[] retval = RealMemberLookup (invocation_type, qualifier_type,
-                                                       queried_type, mt, original_bf, name);
+                                                       queried_type, mt, original_bf, name, almost_match);
 
                Timer.StopTimer (TimerType.MemberLookup);
 
@@ -2906,7 +3058,7 @@ public class TypeManager {
 
        static MemberInfo [] RealMemberLookup (Type invocation_type, Type qualifier_type,
                                               Type queried_type, MemberTypes mt,
-                                              BindingFlags original_bf, string name)
+                                              BindingFlags original_bf, string name, IList almost_match)
        {
                BindingFlags bf = original_bf;
                
@@ -2916,9 +3068,10 @@ public class TypeManager {
                bool skip_iface_check = true, used_cache = false;
                bool always_ok_flag = false;
 
-               closure_invocation_type = invocation_type;
-               closure_invocation_assembly = invocation_type != null ? invocation_type.Assembly : null;
-               closure_qualifier_type = qualifier_type;
+               closure.invocation_type = invocation_type;
+               closure.invocation_assembly = invocation_type != null ? invocation_type.Assembly : null;
+               closure.qualifier_type = qualifier_type;
+               closure.almost_match = almost_match;
 
                //
                // If we are a nested class, we always have access to our container
@@ -2965,7 +3118,7 @@ public class TypeManager {
                        else
                                bf = original_bf;
 
-                       closure_private_ok = (original_bf & BindingFlags.NonPublic) != 0;
+                       closure.private_ok = (original_bf & BindingFlags.NonPublic) != 0;
 
                        Timer.StopTimer (TimerType.MemberLookup);
 
@@ -3082,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);
+                       x = MemberLookup (null, null, itype, mt, bf, name, null);
                        if (x != null)
                                return x;
                }
@@ -3097,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;
        }
                
@@ -3275,7 +3373,7 @@ public sealed class TypeHandle : IMemberContainer {
                }
        }
 
-       public IMemberContainer Parent {
+       public IMemberContainer ParentContainer {
                get {
                        return BaseType;
                }