2005-05-06 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / gmcs / typemanager.cs
index fd4631e42a124fb0fa3f5d155d7c938f80e60d88..6fa5127dbe0a066c3309ff3a1668d2375a957174 100644 (file)
@@ -104,6 +104,7 @@ public partial class TypeManager {
        ///
        static internal Type compiler_generated_attr_type;
        static internal Type fixed_buffer_attr_type;
+       static internal Type default_charset_type;
 
        //
        // An empty array of types
@@ -193,7 +194,8 @@ public partial class TypeManager {
        static public ConstructorInfo default_member_ctor;
        static public ConstructorInfo decimal_constant_attribute_ctor;
        static internal ConstructorInfo struct_layout_attribute_ctor;
-
+       static public ConstructorInfo field_offset_attribute_ctor;
+       
        ///
        /// A new in C# 2.0
        /// 
@@ -704,7 +706,6 @@ public partial class TypeManager {
        public static Type GetNestedType (Type t, string name)
        {
                object ret = null;
-               Report.Debug (64, "GET NESTED TYPE", t, t.FullName, t.Name, name);
                if (!type_hash.Lookup (t, name, out ret)) {
                        string lookup = t.FullName + "+" + name;
                        ret = t.Module.GetType (lookup);
@@ -910,41 +911,45 @@ public partial class TypeManager {
                return mb.DeclaringType.FullName.Replace ('+', '.') + '.' + name;
        }
 
-       static public string GetFullName (Type t)
+       private static void GetFullName_recursed (StringBuilder sb, Type t, bool recursed)
        {
-               if (t.FullName == null)
-                       return t.Name;
-
-               string name = t.FullName.Replace ('+', '.');
+               if (t.IsGenericParameter) {
+                       sb.Append (t.Name);
+                       return;
+               }
 
-               DeclSpace tc = LookupDeclSpace (t);
-               if ((tc != null) && tc.IsGeneric) {
-                       TypeParameter[] tparam = tc.TypeParameters;
+               if (t.DeclaringType != null) {
+                       GetFullName_recursed (sb, t.DeclaringType, true);
+                       sb.Append (".");
+               }
 
-                       StringBuilder sb = new StringBuilder (name);
-                       sb.Append ("<");
-                       for (int i = 0; i < tparam.Length; i++) {
-                               if (i > 0)
-                                       sb.Append (",");
-                               sb.Append (tparam [i].Name);
+               if (!recursed) {
+                       string ns = t.Namespace;
+                       if ((ns != null) && (ns != "")) {
+                               sb.Append (ns);
+                               sb.Append (".");
                        }
-                       sb.Append (">");
-                       return sb.ToString ();
-               } else if (t.HasGenericArguments && !t.IsGenericInstance) {
-                       Type[] tparam = t.GetGenericArguments ();
+               }
 
-                       StringBuilder sb = new StringBuilder (name);
+               sb.Append (SimpleName.RemoveGenericArity (t.Name));
+
+               Type[] args = GetTypeArguments (t);
+               if (args.Length > 0) {
                        sb.Append ("<");
-                       for (int i = 0; i < tparam.Length; i++) {
+                       for (int i = 0; i < args.Length; i++) {
                                if (i > 0)
                                        sb.Append (",");
-                               sb.Append (tparam [i].Name);
+                               sb.Append (GetFullName (args [i]));
                        }
                        sb.Append (">");
-                       return sb.ToString ();
                }
+       }
 
-               return name;
+       static public string GetFullName (Type t)
+       {
+               StringBuilder sb = new StringBuilder ();
+               GetFullName_recursed (sb, t, false);
+               return sb.ToString ();
        }
 
        /// <summary>
@@ -1188,6 +1193,7 @@ public partial class TypeManager {
                //
                compiler_generated_attr_type = CoreLookupType ("System.Runtime.CompilerServices.CompilerGeneratedAttribute");
                fixed_buffer_attr_type = CoreLookupType ("System.Runtime.CompilerServices.FixedBufferAttribute");
+               default_charset_type = CoreLookupType ("System.Runtime.InteropServices.DefaultCharSetAttribute");
                //
                // When compiling corlib, store the "real" types here.
                //
@@ -1410,6 +1416,8 @@ public partial class TypeManager {
                decimal_constant_attribute_ctor = GetConstructor (decimal_constant_attribute_type, new Type []
                        { byte_type, byte_type, uint32_type, uint32_type, uint32_type } );
 
+               field_offset_attribute_ctor = GetConstructor (field_offset_attribute_type, new Type []
+                       { int32_type });
 
                //
                // .NET 2.0 types
@@ -1599,15 +1607,12 @@ public partial class TypeManager {
        // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
        // the pieces in the code where we use IsBuiltinType and special case decimal_type.
        // 
-       public static bool IsCLRType (Type t)
+       public static bool IsPrimitiveType (Type t)
        {
-               if (t == object_type || t == int32_type || t == uint32_type ||
+               return (t == int32_type || t == uint32_type ||
                    t == int64_type || t == uint64_type || t == float_type || t == double_type ||
                    t == char_type || t == short_type || t == bool_type ||
-                   t == sbyte_type || t == byte_type || t == ushort_type)
-                       return true;
-               else
-                       return false;
+                   t == sbyte_type || t == byte_type || t == ushort_type);
        }
 
        public static bool IsDelegateType (Type t)
@@ -1656,32 +1661,43 @@ public partial class TypeManager {
                if (IsBuiltinOrEnum (t))
                        return true;
 
+               // Someone did the work of checking if the ElementType of t is unmanaged.  Let's not repeat it.
                if (t.IsPointer)
                        return true;
 
+               // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)]
+               if (t.IsArray)
+                       return false;
+
                if (!IsValueType (t))
                        return false;
 
                if (t is TypeBuilder){
                        TypeContainer tc = LookupTypeContainer (t);
-                       
                        if (tc.Fields == null)
                                return true;
                        foreach (Field f in tc.Fields){
                                // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked.
                                if ((f.ModFlags & Modifiers.STATIC) != 0)
                                        continue;
-                               if (!IsUnmanagedType (f.MemberType))
+                               if (f.MemberType == null)
+                                       continue;
+                               if (!IsUnmanagedType (f.MemberType)){
+                                       Report.SymbolRelatedToPreviousError (f.Location, CSharpName (t) + "." + f.Name);
                                        return false;
+                               }
                        }
                        return true;
                }
                
                FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
 
-               foreach (FieldInfo f in fields)
-                       if (!IsUnmanagedType (f.FieldType))
+               foreach (FieldInfo f in fields){
+                       if (!IsUnmanagedType (f.FieldType)){
+                               Report.SymbolRelatedToPreviousError (f);
                                return false;
+                       }
+               }
 
                return true;
        }
@@ -2163,11 +2179,13 @@ public partial class TypeManager {
                        if (texpr == null)
                                return null;
 
-                       if (!new_ifaces.Contains (texpr.Type))
-                               new_ifaces.Add (texpr.Type);
+                       if (new_ifaces.Contains (texpr.Type))
+                               continue;
+
+                       new_ifaces.Add (texpr.Type);
                        
                        Type [] implementing = texpr.Type.GetInterfaces ();
-                       
+
                        foreach (Type imp in implementing){
                                if (!new_ifaces.Contains (imp))
                                        new_ifaces.Add (imp);
@@ -2186,7 +2204,6 @@ public partial class TypeManager {
        /// </summary>
        public static Type [] GetInterfaces (Type t)
        {
-               
                Type [] cached = iface_cache [t] as Type [];
                if (cached != null)
                        return cached;
@@ -2204,14 +2221,18 @@ public partial class TypeManager {
                if (t.IsArray)
                        t = TypeManager.array_type;
                
-               if (t is TypeBuilder){
+               if ((t is TypeBuilder) || t.IsGenericInstance) {
                        Type [] base_ifaces;
                        
                        if (t.BaseType == null)
                                base_ifaces = NoTypes;
                        else
                                base_ifaces = GetInterfaces (t.BaseType);
-                       Type[] type_ifaces = (Type []) builder_to_ifaces [t];
+                       Type[] type_ifaces;
+                       if (t.IsGenericInstance)
+                               type_ifaces = t.GetInterfaces ();
+                       else
+                               type_ifaces = (Type []) builder_to_ifaces [t];
                        if (type_ifaces == null)
                                type_ifaces = NoTypes;
 
@@ -2454,10 +2475,6 @@ public partial class TypeManager {
                if (IsUnmanagedType (t))
                        return true;
 
-               // We need this explicit check here to make it work when compiling corlib.
-               if (!RootContext.StdLib && (t == TypeManager.decimal_type))
-                       return true;
-
                Report.Error (
                        208, loc,
                        "Cannot take the address or size of a variable of a managed type ('" +
@@ -2506,7 +2523,7 @@ public partial class TypeManager {
                                new Type [] { typeof (Type), typeof (bool)},
                                null);
                        if (declare_local_method == null){
-                               Report.Warning (-24, new Location (-1),
+                               Report.Warning (-30, new Location (-1),
                                                "This version of the runtime does not support making pinned local variables.  " +
                                        "This code may cause errors on a runtime with a moving GC");
                                return ig.DeclareLocal (t);
@@ -2604,40 +2621,6 @@ public partial class TypeManager {
                internal Assembly invocation_assembly;
                internal IList almost_match;
 
-               private bool CheckValidFamilyAccess (bool is_static, MemberInfo m)
-               {
-                       if (invocation_type == null)
-                               return false;
-
-                       Debug.Assert (IsNestedFamilyAccessible (invocation_type, m.DeclaringType));
-
-                       if (is_static)
-                               return true;
-                       
-                       // A nested class has access to all the protected members visible
-                       // to its parent.
-                       if (qualifier_type != null
-                           && TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
-                               return true;
-
-                       if (invocation_type == m.DeclaringType
-                           || invocation_type.IsSubclassOf (m.DeclaringType)) {
-                               // Although a derived class can access protected members of
-                               // its base class it cannot do so through an instance of the
-                               // base class (CS1540).
-                               // => Ancestry should be: declaring_type ->* invocation_type
-                               //      ->*  qualified_type
-                               if (qualifier_type == null
-                                   || qualifier_type == invocation_type
-                                   || qualifier_type.IsSubclassOf (invocation_type))
-                                       return true;
-                       }
-       
-                       if (almost_match != null)
-                               almost_match.Add (m);
-                       return false;
-               }
-
                bool Filter (MethodBase mb, object filter_criteria)
                {
                        MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;