2004-11-10 Martin Baulig <martin@localhost>
[mono.git] / mcs / gmcs / typemanager.cs
index 62902959a01cdb1b6ecf108480474d1b435247de..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
@@ -361,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 ()
@@ -496,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)
        {
@@ -545,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>
@@ -1712,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
@@ -1729,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;
 
@@ -1739,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)
@@ -1900,6 +1946,48 @@ public class TypeManager {
                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);
@@ -2788,7 +2876,7 @@ public class TypeManager {
 
                        if (ma == MethodAttributes.Private)
                                return private_ok ||
-                                       IsEqual (invocation_type, mb.DeclaringType) ||
+                                       IsPrivateAccessible (invocation_type, mb.DeclaringType) ||
                                        IsNestedChildOf (invocation_type, mb.DeclaringType);
 
                        //
@@ -2839,7 +2927,7 @@ public class TypeManager {
 
                        if (fa == FieldAttributes.Private)
                                return private_ok ||
-                                       IsEqual (invocation_type, fi.DeclaringType) ||
+                                       IsPrivateAccessible (invocation_type, fi.DeclaringType) ||
                                        IsNestedChildOf (invocation_type, fi.DeclaringType);
 
                        //
@@ -2900,7 +2988,7 @@ public class TypeManager {
 
                        if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
                            (invocation_type != null) &&
-                           IsEqual (m.DeclaringType, invocation_type))
+                           IsPrivateAccessible (m.DeclaringType, invocation_type))
                                return true;
 
                        //