re GNATS gcj/30 (gcj not reporting unimplemented methods)
authorAlexandre Petit-Bianco <apbianco@cygnus.com>
Sun, 22 Aug 1999 18:38:07 +0000 (18:38 +0000)
committerAlexandre Petit-Bianco <apbianco@gcc.gnu.org>
Sun, 22 Aug 1999 18:38:07 +0000 (11:38 -0700)
Sun Aug 22 11:07:41 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>

* parse.y (check_method_redefinition): Changed leading comment.
(check_abstract_method_definitions): New function.
(java_check_abstract_method_definitions): New function.
(java_check_regular_methods): Call it.
(verify_constructor_super): Fixed indentation.
(lookup_method_invoke): Likewise.

(This fixes the Java net PR #30,
 http://sourceware.cygnus.com/ml/java-prs/1999-q3/msg00034.html)

From-SVN: r28805

gcc/java/ChangeLog
gcc/java/parse.c
gcc/java/parse.y

index de425bb782c2d08bebcbfb2f97c020d61dc55f0e..b44dae02b8afe41cc7120305111f488d1a10f478 100644 (file)
@@ -1,3 +1,12 @@
+Sun Aug 22 11:07:41 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>
+
+       * parse.y (check_method_redefinition): Changed leading comment.
+       (check_abstract_method_definitions): New function.
+       (java_check_abstract_method_definitions): New function.
+       (java_check_regular_methods): Call it.
+       (verify_constructor_super): Fixed indentation.
+       (lookup_method_invoke): Likewise.
+
 Thu Aug 19 10:26:18 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>
 
        * parse.y (method_header): Return a null pointer if the current
index 2c7cf889851969e11e568fdab456af7fea4e86e2..ba242a2f8b15251e7afa1e3adafd98af1e604fe4 100644 (file)
@@ -7134,7 +7134,7 @@ java_get_real_method_name (method_decl)
 
 /* Track method being redefined inside the same class. As a side
    effect, set DECL_NAME to an IDENTIFIER (prior entering this
-   function it's a FWL, so we can track errors more accurately */
+   function it's a FWL, so we can track errors more accurately.)  */
 
 static int
 check_method_redefinition (class, method)
@@ -7170,9 +7170,126 @@ check_method_redefinition (class, method)
   return 0;
 }
 
-/* Check all the methods of CLASS. Methods are first completed then
-   checked according to regular method existance rules.
-   If no constructor were encountered, then build its declaration. */
+static void
+check_abstract_method_definitions (do_interface, class_decl, type)
+     int do_interface;
+     tree class_decl, type;
+{
+  tree class = TREE_TYPE (class_decl);
+  tree method, end_type;
+
+  end_type = (do_interface ? object_type_node : type);
+  for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
+    {
+      tree other_super, other_method, method_sig, method_name;
+      int found = 0;
+      
+      if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
+       continue;
+      
+      /* Now verify that somewhere in between TYPE and CLASS,
+        abstract method METHOD gets a non abstract definition
+        that is inherited by CLASS.  */
+      
+      method_sig = build_java_signature (TREE_TYPE (method));
+      method_name = DECL_NAME (method);
+      if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
+       method_name = EXPR_WFL_NODE (method_name);
+
+      for (other_super = class; other_super != end_type; 
+          other_super = CLASSTYPE_SUPER (other_super))
+       {
+         for (other_method = TYPE_METHODS (other_super); other_method;
+              other_method = TREE_CHAIN (other_method))
+           {
+             tree s = build_java_signature (TREE_TYPE (other_method));
+             tree other_name = DECL_NAME (other_method);
+
+             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
+               other_name = EXPR_WFL_NODE (other_name);
+             if (!IS_CLINIT (other_method)
+                 && !DECL_CONSTRUCTOR_P (other_method)
+                 && method_name == other_name && method_sig == s)
+               {
+                 found = 1;
+                 break;
+               }
+           }
+       }
+      
+      /* Report that abstract METHOD didn't find an implementation
+        that CLASS can use. */
+      if (!found)
+       {
+         char *t = strdup (lang_printable_name 
+                           (TREE_TYPE (TREE_TYPE (method)), 0));
+         tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
+         tree saved_wfl = NULL_TREE;
+         
+         if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
+           {
+             saved_wfl = DECL_NAME (method);
+             DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
+           }
+         
+         parse_error_context 
+           (lookup_cl (class_decl),
+            "Class `%s' doesn't define the abstract method `%s %s' from "
+            "%s `%s'. This method must be defined or %s `%s' must be "
+            "declared abstract",
+            IDENTIFIER_POINTER (DECL_NAME (class_decl)),
+            t, lang_printable_name (method, 0), 
+            (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
+             "interface" : "class"),
+            IDENTIFIER_POINTER (ccn),
+            (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
+            IDENTIFIER_POINTER (DECL_NAME (class_decl)));
+         
+         free (t);
+         
+         if (saved_wfl)
+           DECL_NAME (method) = saved_wfl;
+       }
+    }
+}
+
+/* Check that CLASS_DECL somehoow implements all inherited abstract
+   methods.  */
+
+static void
+java_check_abstract_method_definitions (class_decl)
+     tree class_decl;
+{
+  tree class = TREE_TYPE (class_decl);
+  tree super, vector;
+  int i;
+
+  if (CLASS_ABSTRACT (class_decl))
+    return;
+
+  /* Check for inherited types */
+  for (super = CLASSTYPE_SUPER (class); super != object_type_node; 
+       super = CLASSTYPE_SUPER (super))
+    {
+      if (!CLASS_ABSTRACT (TYPE_NAME (super)))
+       continue;
+
+      check_abstract_method_definitions (0, class_decl, super);
+    }
+
+  /* Check for implemented interfaces. */
+  vector = TYPE_BINFO_BASETYPES (class);
+  for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
+    {
+      super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
+      check_abstract_method_definitions (1, class_decl, super);
+    }
+}
+
+/* Check all the methods of CLASS_DECL. Methods are first completed
+   then checked according to regular method existance rules.  If no
+   constructor for CLASS_DECL were encountered, then build its
+   declaration.  */
 
 static void
 java_check_regular_methods (class_decl)
@@ -7348,7 +7465,7 @@ java_check_regular_methods (class_decl)
   
   /* Don't forget eventual pending found and saved_found_wfl. Take
      into account that we might have exited because we saw an
-     aritifical method as the last entry. */
+     artificial method as the last entry. */
 
   if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
     DECL_NAME (found) = saved_found_wfl;
@@ -7356,6 +7473,10 @@ java_check_regular_methods (class_decl)
   if (!TYPE_NVIRTUALS (class))
     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
 
+  /* Search for inherited abstract method not yet implemented in this
+     class.  */
+  java_check_abstract_method_definitions (class_decl);
+
   if (!saw_constructor)
     {
       /* No constructor seen, we craft one, at line 0. Since this
@@ -8692,7 +8813,8 @@ verify_constructor_super ()
       for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
        {
          if (DECL_CONSTRUCTOR_P (mdecl)
-             && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) == end_params_node)
+             && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) 
+                == end_params_node)
            return 0;
        }
     }
@@ -10027,7 +10149,7 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
   parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
                       (lc ? "constructor" : "method"),
                       (lc ? 
-                       IDENTIFIER_POINTER(DECL_NAME (TYPE_NAME (class))) :
+                       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))) :
                        IDENTIFIER_POINTER (name)),
                       IDENTIFIER_POINTER (signature),
                       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))),
index d62b2770b66c0f17d127ce139bd981afb96eca7f..06426ba4a684540f8d58bc1ad8596e1d5e4c9f79 100644 (file)
@@ -4547,7 +4547,7 @@ java_get_real_method_name (method_decl)
 
 /* Track method being redefined inside the same class. As a side
    effect, set DECL_NAME to an IDENTIFIER (prior entering this
-   function it's a FWL, so we can track errors more accurately */
+   function it's a FWL, so we can track errors more accurately.)  */
 
 static int
 check_method_redefinition (class, method)
@@ -4583,9 +4583,126 @@ check_method_redefinition (class, method)
   return 0;
 }
 
-/* Check all the methods of CLASS. Methods are first completed then
-   checked according to regular method existance rules.
-   If no constructor were encountered, then build its declaration. */
+static void
+check_abstract_method_definitions (do_interface, class_decl, type)
+     int do_interface;
+     tree class_decl, type;
+{
+  tree class = TREE_TYPE (class_decl);
+  tree method, end_type;
+
+  end_type = (do_interface ? object_type_node : type);
+  for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
+    {
+      tree other_super, other_method, method_sig, method_name;
+      int found = 0;
+      
+      if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
+       continue;
+      
+      /* Now verify that somewhere in between TYPE and CLASS,
+        abstract method METHOD gets a non abstract definition
+        that is inherited by CLASS.  */
+      
+      method_sig = build_java_signature (TREE_TYPE (method));
+      method_name = DECL_NAME (method);
+      if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
+       method_name = EXPR_WFL_NODE (method_name);
+
+      for (other_super = class; other_super != end_type; 
+          other_super = CLASSTYPE_SUPER (other_super))
+       {
+         for (other_method = TYPE_METHODS (other_super); other_method;
+              other_method = TREE_CHAIN (other_method))
+           {
+             tree s = build_java_signature (TREE_TYPE (other_method));
+             tree other_name = DECL_NAME (other_method);
+
+             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
+               other_name = EXPR_WFL_NODE (other_name);
+             if (!IS_CLINIT (other_method)
+                 && !DECL_CONSTRUCTOR_P (other_method)
+                 && method_name == other_name && method_sig == s)
+               {
+                 found = 1;
+                 break;
+               }
+           }
+       }
+      
+      /* Report that abstract METHOD didn't find an implementation
+        that CLASS can use. */
+      if (!found)
+       {
+         char *t = strdup (lang_printable_name 
+                           (TREE_TYPE (TREE_TYPE (method)), 0));
+         tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
+         tree saved_wfl = NULL_TREE;
+         
+         if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
+           {
+             saved_wfl = DECL_NAME (method);
+             DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
+           }
+         
+         parse_error_context 
+           (lookup_cl (class_decl),
+            "Class `%s' doesn't define the abstract method `%s %s' from "
+            "%s `%s'. This method must be defined or %s `%s' must be "
+            "declared abstract",
+            IDENTIFIER_POINTER (DECL_NAME (class_decl)),
+            t, lang_printable_name (method, 0), 
+            (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
+             "interface" : "class"),
+            IDENTIFIER_POINTER (ccn),
+            (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
+            IDENTIFIER_POINTER (DECL_NAME (class_decl)));
+         
+         free (t);
+         
+         if (saved_wfl)
+           DECL_NAME (method) = saved_wfl;
+       }
+    }
+}
+
+/* Check that CLASS_DECL somehoow implements all inherited abstract
+   methods.  */
+
+static void
+java_check_abstract_method_definitions (class_decl)
+     tree class_decl;
+{
+  tree class = TREE_TYPE (class_decl);
+  tree super, vector;
+  int i;
+
+  if (CLASS_ABSTRACT (class_decl))
+    return;
+
+  /* Check for inherited types */
+  for (super = CLASSTYPE_SUPER (class); super != object_type_node; 
+       super = CLASSTYPE_SUPER (super))
+    {
+      if (!CLASS_ABSTRACT (TYPE_NAME (super)))
+       continue;
+
+      check_abstract_method_definitions (0, class_decl, super);
+    }
+
+  /* Check for implemented interfaces. */
+  vector = TYPE_BINFO_BASETYPES (class);
+  for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
+    {
+      super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
+      check_abstract_method_definitions (1, class_decl, super);
+    }
+}
+
+/* Check all the methods of CLASS_DECL. Methods are first completed
+   then checked according to regular method existance rules.  If no
+   constructor for CLASS_DECL were encountered, then build its
+   declaration.  */
 
 static void
 java_check_regular_methods (class_decl)
@@ -4761,7 +4878,7 @@ java_check_regular_methods (class_decl)
   
   /* Don't forget eventual pending found and saved_found_wfl. Take
      into account that we might have exited because we saw an
-     aritifical method as the last entry. */
+     artificial method as the last entry. */
 
   if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
     DECL_NAME (found) = saved_found_wfl;
@@ -4769,6 +4886,10 @@ java_check_regular_methods (class_decl)
   if (!TYPE_NVIRTUALS (class))
     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
 
+  /* Search for inherited abstract method not yet implemented in this
+     class.  */
+  java_check_abstract_method_definitions (class_decl);
+
   if (!saw_constructor)
     {
       /* No constructor seen, we craft one, at line 0. Since this
@@ -6105,7 +6226,8 @@ verify_constructor_super ()
       for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
        {
          if (DECL_CONSTRUCTOR_P (mdecl)
-             && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) == end_params_node)
+             && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) 
+                == end_params_node)
            return 0;
        }
     }
@@ -7440,7 +7562,7 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
   parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
                       (lc ? "constructor" : "method"),
                       (lc ? 
-                       IDENTIFIER_POINTER(DECL_NAME (TYPE_NAME (class))) :
+                       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))) :
                        IDENTIFIER_POINTER (name)),
                       IDENTIFIER_POINTER (signature),
                       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))),