**** Merged r43921 from MCS ****
authorMartin Baulig <martin@novell.com>
Tue, 10 May 2005 20:26:47 +0000 (20:26 -0000)
committerMartin Baulig <martin@novell.com>
Tue, 10 May 2005 20:26:47 +0000 (20:26 -0000)
svn path=/trunk/mcs/; revision=44348

mcs/gmcs/ChangeLog
mcs/gmcs/decl.cs
mcs/gmcs/expression.cs
mcs/gmcs/typemanager.cs

index 9e424d46533dc39fcf05dc0c5d2336fa6f99068f..6cd8c8f56b467961efea2c5ceeb60c94766da6d2 100644 (file)
 
 2005-05-03  Raja R Harinath  <rharinath@novell.com>
 
+       * typemanager.cs (IsOverride, RegisterNonOverride): New.
+       * decl.cs (MemberCache.AddMethod): Register "non-override" methods
+       that used to trigger warning -28.  Remove warning -28.
+       * expression.cs (Invocation.OverloadResolve): Use
+       TypeManager.IsOverride to distinguish override methods.
+
        Fix #74773.
        * pending.cs (VerifyPendingMethods): If a base type implements the
        requested interface, don't bother checking individual methods of
index c311ba04bbd71571cce508ea0feef4daa3b987ff..b0d1e9848d2b5d5bb13d9444b44453ad83fd5a98 100644 (file)
@@ -1728,15 +1728,6 @@ namespace Mono.CSharp {
 
                void AddMethods (BindingFlags bf, Type type)
                {
-                       //
-                       // Consider the case:
-                       //
-                       //   class X { public virtual int f() {} }
-                       //   class Y : X {}
-                       // 
-                       // When processing 'Y', the method_cache will already have a copy of 'f', 
-                       // with ReflectedType == X.  However, we want to ensure that its ReflectedType == Y
-                       // 
                        MethodBase [] members = type.GetMethods (bf);
 
                        Array.Reverse (members);
@@ -1756,23 +1747,8 @@ namespace Mono.CSharp {
                                        MethodInfo base_method = curr.GetBaseDefinition ();
 
                                        if (base_method == curr) {
-                                               //
-                                               // 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.
-                                               //
-                                               // Also, CSC 1.1 appears to emit 'Finalize' without a newslot.
-                                               //
-                                               if ((curr.Name == "Invoke" && TypeManager.IsDelegateType (curr.DeclaringType)) ||
-                                                   (curr.Name == "Finalize" && curr.GetParameters().Length == 0 && curr.DeclaringType == TypeManager.object_type))
-                                                       break;
-
-                                               Report.SymbolRelatedToPreviousError (base_method);
-                                               Report.Warning (-28, 
-                                                               "The method '{0}' is marked 'override'," + 
-                                                               " but doesn't appear to override any virtual or abstract method:" + 
-                                                               " it may be ignored during overload resolution",
-                                                               TypeManager.CSharpSignature (base_method));
+                                               // Not every virtual function needs to have a NewSlot flag.
+                                               TypeManager.RegisterNonOverride (base_method);
                                                break;
                                        }
                                        
index de209851bf4de4b73afadcff7f15757ddec7cbb6..345ebbe5ad861fe7fee0db297da7c00bf42c7c01 100644 (file)
@@ -4907,9 +4907,7 @@ namespace Mono.CSharp {
                                // We avoid doing the 'applicable' test here, since it'll anyway be applied
                                // to the base virtual function, and IsOverride is much faster than IsApplicable.
                                //
-                               if (!me.IsBase &&
-                                   methods [i].IsVirtual &&
-                                   (methods [i].Attributes & MethodAttributes.NewSlot) == 0) {
+                               if (!me.IsBase && TypeManager.IsOverride (methods [i])) {
                                        if (candidate_overrides == null)
                                                candidate_overrides = new ArrayList ();
                                        candidate_overrides.Add (methods [i]);
@@ -5105,10 +5103,10 @@ namespace Mono.CSharp {
                        // If the method is a virtual function, pick an override closer to the LHS type.
                        //
                        if (!me.IsBase && method.IsVirtual) {
-                               if ((method.Attributes & MethodAttributes.NewSlot) != MethodAttributes.NewSlot)
+                               if (TypeManager.IsOverride (method))
                                        throw new InternalErrorException (
                                                "Should not happen.  An 'override' method took part in overload resolution: " + method);
-                                                                   
+
                                if (candidate_overrides != null)
                                        foreach (MethodBase candidate in candidate_overrides) {
                                                if (IsOverride (candidate, method))
index a757619e9387d72f225f240f2074e26803470ab2..6092beb261acd5c93d460bbe852bebc47e5241c3 100644 (file)
@@ -260,6 +260,14 @@ public partial class TypeManager {
        // <remarks>
        static Hashtable method_params;
 
+       // <remarks>
+       //   It is not straightforward, using reflection, to determine if a method overrides another.
+       //   Oftentimes, a non-override is marked with both the 'virtual' and 'newslot' method attributes.
+       //   However, it's not always the case.  We use this table to store those non-override methods
+       //   that aren't so conveniently marked.
+       // <remarks>
+       static Hashtable method_non_override;
+
        // <remarks>
        //  Keeps track of methods
        // </remarks>
@@ -402,6 +410,7 @@ public partial class TypeManager {
                builder_to_method = new PtrHashtable ();
                method_arguments = new PtrHashtable ();
                method_params = new PtrHashtable ();
+               method_non_override = new PtrHashtable ();
                indexer_arguments = new PtrHashtable ();
                builder_to_ifaces = new PtrHashtable ();
                
@@ -1934,6 +1943,18 @@ public partial class TypeManager {
                return (ParameterData) pd;
        }
 
+       static public void RegisterNonOverride (MethodBase m)
+       {
+               method_non_override [m] = m;
+       }
+
+       static public bool IsOverride (MethodBase m)
+       {
+               return m.IsVirtual &&
+                       (m.Attributes & MethodAttributes.NewSlot) == 0 &&
+                       !method_non_override.Contains (m);
+       }
+
        /// <summary>
        ///    Returns the argument types for a method based on its methodbase
        ///