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