Author: raja
Date: 2005-03-28 05:43:07 -0500 (Mon, 28 Mar 2005)
New Revision: 42304

Modified:
   trunk/mcs/mcs/ChangeLog
   trunk/mcs/mcs/decl.cs
   trunk/mcs/mcs/typemanager.cs
Log:
Some changes based on Martin's request to make it easier to merge into gmcs.

* typemanager.cs (TypeHandle.BaseType): Make into an IMemberContainer.
(TypeHandle.TypeHandle): Use LookupMemberCache rather than
GetTypeHandle.  It is possible for a reflected type to derive from
a TypeBuilder (e.g., int[] derives from the TypeBuilder
System.Array during mscorlib compilation).
* decl.cs (MemberCache.MemberCache): If the base cache doesn't
contain a method_hash, don't create one either.  Don't create a
deep copy of the base cache's method_hash.
(MemberCache.SetupCache): Rename back from DeepCopy.
(MemberCache.AddMethods): Rewrite, now that method_hash isn't
already initialized.  If we see an override function, add its
underlying base virtual function to the member_hash too.


Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog     2005-03-28 10:30:17 UTC (rev 42303)
+++ trunk/mcs/mcs/ChangeLog     2005-03-28 10:43:07 UTC (rev 42304)
@@ -1,5 +1,18 @@
 2005-03-28  Raja R Harinath  <[EMAIL PROTECTED]>
 
+       * typemanager.cs (TypeHandle.BaseType): Make into an IMemberContainer.
+       (TypeHandle.TypeHandle): Use LookupMemberCache rather than
+       GetTypeHandle.  It is possible for a reflected type to derive from
+       a TypeBuilder (e.g., int[] derives from the TypeBuilder
+       System.Array during mscorlib compilation).
+       * decl.cs (MemberCache.MemberCache): If the base cache doesn't
+       contain a method_hash, don't create one either.  Don't create a
+       deep copy of the base cache's method_hash.
+       (MemberCache.SetupCache): Rename back from DeepCopy.
+       (MemberCache.AddMethods): Rewrite, now that method_hash isn't
+       already initialized.  If we see an override function, add its
+       underlying base virtual function to the member_hash too.
+
        * enum.cs (Enum.LookupEnumValue): Remove debugging code.
 
 2005-03-26  Raja R Harinath  <[EMAIL PROTECTED]>

Modified: trunk/mcs/mcs/decl.cs
===================================================================
--- trunk/mcs/mcs/decl.cs       2005-03-28 10:30:17 UTC (rev 42303)
+++ trunk/mcs/mcs/decl.cs       2005-03-28 10:43:07 UTC (rev 42304)
@@ -1248,18 +1248,16 @@
                        // If we have a base class (we have a base class unless 
we're
                        // TypeManager.object_type), we deep-copy its 
MemberCache here.
                        if (Container.BaseCache != null)
-                               member_hash = DeepCopy 
(Container.BaseCache.member_hash);
+                               member_hash = SetupCache (Container.BaseCache);
                        else
                                member_hash = new Hashtable ();
 
                        // If this is neither a dynamic type nor an interface, 
create a special
                        // method cache with all declared and inherited methods.
                        Type type = container.Type;
-                       if (!(type is TypeBuilder) && !type.IsInterface) {
-                               if (Container.BaseCache != null)
-                                       method_hash = DeepCopy 
(Container.BaseCache.method_hash);
-                               else
-                                       method_hash = new Hashtable ();
+                       if (!(type is TypeBuilder) && !type.IsInterface &&
+                           (Container.BaseCache == null || 
Container.BaseCache.method_hash != null)) {
+                               method_hash = new Hashtable ();
                                AddMethods (type);
                        }
 
@@ -1286,16 +1284,16 @@
                }
 
                /// <summary>
-               ///   Return a a deep-copy of the hashtable @other.
+               ///   Bootstrap this member cache by doing a deep-copy of our 
base.
                /// </summary>
-               Hashtable DeepCopy (Hashtable other)
+               Hashtable SetupCache (MemberCache base_class)
                {
                        Hashtable hash = new Hashtable ();
 
-                       if (other == null)
+                       if (base_class == null)
                                return hash;
 
-                       IDictionaryEnumerator it = other.GetEnumerator ();
+                       IDictionaryEnumerator it = 
base_class.member_hash.GetEnumerator ();
                        while (it.MoveNext ()) {
                                hash [it.Key] = ((ArrayList) it.Value).Clone ();
                         }
@@ -1420,26 +1418,59 @@
                                        method_hash.Add (name, list);
                                }
 
-                               Type declaring_type = member.DeclaringType;
-                               if (declaring_type == type) {
-                                       list.Add (new CacheEntry (Container, 
member, MemberTypes.Method, bf | BindingFlags.DeclaredOnly));
-                                       continue;
-                               }
+                               if (member.IsVirtual &&
+                                   (member.Attributes & 
MethodAttributes.NewSlot) == 0) {
+                                       MethodInfo base_method = ((MethodInfo) 
member).GetBaseDefinition ();
 
-                               int n = list.Count;
-                               while (n-- > 0) {
-                                       CacheEntry entry = (CacheEntry) list 
[n];
-                                       MethodBase old = entry.Member as 
MethodBase;
+                                       if (base_method == member) {
+                                               //
+                                               // Both mcs and CSC 1.1 seem to 
emit a somewhat broken
+                                               // ...Invoke () function for 
delegates: it's missing a 'newslot'.
+                                               // CSC 2.0 emits a 'newslot' 
for a delegate's Invoke.
+                                               //
+                                               if (member.Name != "Invoke" ||
+                                                   !type.IsSubclassOf 
(TypeManager.multicast_delegate_type)) {
+                                                       
Report.SymbolRelatedToPreviousError (base_method);
+                                                       Report.Warning (-28, 
+                                                               "{0} contains a 
method '{1}' that is marked " + 
+                                                               " virtual, but 
doesn't appear to have a slot." + 
+                                                               "  The method 
may be ignored during overload resolution", 
+                                                               type, 
base_method);
+                                               }
+                                               goto skip;
+                                       }
 
-                                       if (member.MethodHandle.Value == 
old.MethodHandle.Value && 
-                                           declaring_type == 
old.DeclaringType) {
-                                               list [n] = new CacheEntry 
(entry, member);
-                                               break;
+                                       for (;;) {
+                                               list.Add (new CacheEntry (null, 
base_method, MemberTypes.Method, bf));
+                                               if ((base_method.Attributes & 
MethodAttributes.NewSlot) != 0)
+                                                       break;
+
+                                               //
+                                               // Shouldn't get here.  Mono 
appears to be buggy.
+                                               //
+                                               MethodInfo new_base_method = 
base_method.GetBaseDefinition ();
+                                               if (new_base_method == 
base_method) {
+                                                       
Report.SymbolRelatedToPreviousError (base_method);
+                                                       Report.Warning (-28, 
+                                                               "{0} contains a 
method '{1}' that is marked " + 
+                                                               " virtual, but 
doesn't appear to have a slot." + 
+                                                               "  The method 
may be ignored during overload resolution", 
+                                                               type, 
base_method);
+                                               }
+                                               base_method = new_base_method;
                                        }
+
+
                                }
+                       skip:
 
-                               if (n < 0)
-                                       throw new InternalErrorException 
("cannot find inherited member " + member + " in base classes of " + type);
+                               // Unfortunately, the elements returned by 
Type.GetMethods() aren't
+                               // sorted so we need to do this check for every 
member.
+                               BindingFlags new_bf = bf;
+                               if (member.DeclaringType == type)
+                                       new_bf |= BindingFlags.DeclaredOnly;
+
+                               list.Add (new CacheEntry (Container, member, 
MemberTypes.Method, new_bf));
                        }
                }
 
@@ -1541,13 +1572,6 @@
                                this.EntryType = GetEntryType (mt, bf);
                        }
 
-                       public CacheEntry (CacheEntry other, MemberInfo update)
-                       {
-                               this.Container = other.Container;
-                               this.EntryType = other.EntryType & 
~EntryType.Declared;
-                               this.Member = update;
-                       }
-
                        public override string ToString ()
                        {
                                return String.Format ("CacheEntry 
({0}:{1}:{2})", Container.Name,

Modified: trunk/mcs/mcs/typemanager.cs
===================================================================
--- trunk/mcs/mcs/typemanager.cs        2005-03-28 10:30:17 UTC (rev 42303)
+++ trunk/mcs/mcs/typemanager.cs        2005-03-28 10:43:07 UTC (rev 42304)
@@ -2797,7 +2797,7 @@
 ///   There is exactly one instance of this class per type.
 /// </summary>
 public sealed class TypeHandle : IMemberContainer {
-       public readonly TypeHandle BaseType;
+       public readonly IMemberContainer BaseType;
 
        readonly int id = ++next_id;
        static int next_id = 0;
@@ -2880,8 +2880,8 @@
        {
                this.type = type;
                if (type.BaseType != null) {
-                       BaseType = GetTypeHandle (type.BaseType);
-                       base_cache = BaseType.MemberCache;
+                       base_cache = TypeManager.LookupMemberCache 
(type.BaseType);
+                       BaseType = base_cache.Container;
                } else if (type.IsInterface)
                        base_cache = TypeManager.LookupBaseInterfacesCache 
(type);
                this.is_interface = type.IsInterface;

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to