This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: fix gcj deprecation support


Anthony recently noticed that we weren't emitting deprecation
information in our .class files.

This patch fixes the problem.  It fixes bugs in recognizing
@deprecated in the javadoc, and it changes the bytecode generator to
emit Deprecated attributes for methods, fields, and classes.

I tested this on various test cases here.  I haven't checked in any
new test cases as there is no need -- our nightly japi comparisons
will quickly show any problems here.  (That is how Anthony discovered
this in the first place.)

I also used this patch to rebuild libgcj from scratch.  I ran the test
suite with no regressions.

Ok for trunk and 3.3?  (The particular patch appended is against 3.3.
A slightly different patch is required for the trunk, to account for
function declaration changes.)

Tom

Index: ChangeLog
from  Tom Tromey  <tromey at redhat dot com>

	* jcf-write.c (append_deprecated_attribute): New function.
	(generate_classfile): Generate deprecated attribute when
	appropriate.
	* lex.c (java_parse_doc_section): Return type now void.  Rewrote.
	(java_lex) [case '*']: Simplify logic.

Index: jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.110.2.2
diff -u -r1.110.2.2 jcf-write.c
--- jcf-write.c 24 Jan 2003 23:15:30 -0000 1.110.2.2
+++ jcf-write.c 21 Feb 2003 11:16:43 -0000
@@ -1,5 +1,6 @@
 /* Write out a Java(TM) class file.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -343,6 +344,7 @@
 static void call_cleanups PARAMS ((struct jcf_block *, struct jcf_partial *));
 static char *make_class_file_name PARAMS ((tree));
 static unsigned char *append_synthetic_attribute PARAMS ((struct jcf_partial *));
+static void append_deprecated_attribute PARAMS ((struct jcf_partial *));
 static void append_innerclasses_attribute PARAMS ((struct jcf_partial *, tree));
 static void append_innerclasses_attribute_entry PARAMS ((struct jcf_partial *, tree, tree));
 static void append_gcj_attribute PARAMS ((struct jcf_partial *, tree));
@@ -2967,7 +2969,10 @@
       if (have_value)
 	attr_count++;
 
-      if (FIELD_THISN (part) || FIELD_LOCAL_ALIAS (part) || FIELD_SYNTHETIC (part))
+      if (FIELD_THISN (part) || FIELD_LOCAL_ALIAS (part)
+	  || FIELD_SYNTHETIC (part))
+	attr_count++;
+      if (FIELD_DEPRECATED (part))
 	attr_count++;
 
       PUT2 (attr_count);  /* attributes_count */
@@ -2990,6 +2995,8 @@
       if (FIELD_THISN (part) || FIELD_LOCAL_ALIAS (part)
 	  || FIELD_SYNTHETIC (part))
 	ptr = append_synthetic_attribute (state);
+      if (FIELD_DEPRECATED (part))
+	append_deprecated_attribute (state);
       fields_count++;
     }
   ptr = fields_count_ptr;  UNSAFE_PUT2 (fields_count);
@@ -3025,6 +3032,9 @@
 	  i++;
 	  synthetic_p = 1;
 	}
+      /* Make room for Deprecated attribute.  */
+      if (METHOD_DEPRECATED (part))
+	i++;
 
       PUT2 (i);   /* attributes_count */
 
@@ -3165,6 +3175,10 @@
 	      PUT2 (i);
 	    }
 	}
+
+      if (METHOD_DEPRECATED (part))
+	append_deprecated_attribute (state);
+
       methods_count++;
       current_function_decl = save_function;
     }
@@ -3186,6 +3200,9 @@
     i++;
   if (clas == object_type_node)
     i++;
+  if (CLASS_DEPRECATED (TYPE_NAME (clas)))
+    i++;
+
   PUT2 (i);			/* attributes_count */
 
   /* generate the SourceFile attribute. */
@@ -3201,6 +3218,8 @@
   PUT2 (i);
   append_gcj_attribute (state, clas);
   append_innerclasses_attribute (state, clas);
+  if (CLASS_DEPRECATED (TYPE_NAME (clas)))
+    append_deprecated_attribute (state);
 
   /* New finally generate the contents of the constant pool chunk. */
   i = count_constant_pool_bytes (&state->cpool);
@@ -3228,6 +3247,18 @@
   PUT4 (0);		/* Attribute length */
 
   return ptr;
+}
+
+static void
+append_deprecated_attribute (state)
+     struct jcf_partial *state;
+{
+  unsigned char *ptr = append_chunk (NULL, 6, state);
+  int i;
+
+  i = find_utf8_constant (&state->cpool, get_identifier ("Deprecated"));
+  PUT2 (i);		/* Attribute string index */
+  PUT4 (0);		/* Attribute length */
 }
 
 static void
Index: lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lex.c,v
retrieving revision 1.97.2.1
diff -u -r1.97.2.1 lex.c
--- lex.c 28 Jan 2003 18:48:16 -0000 1.97.2.1
+++ lex.c 21 Feb 2003 11:16:44 -0000
@@ -1,5 +1,6 @@
 /* Language lexer for the GNU compiler for the Java(TM) language.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
    Contributed by Alexandre Petit-Bianco (apbianco at cygnus dot com)
 
 This file is part of GNU CC.
@@ -50,7 +51,7 @@
 static int java_parse_escape_sequence PARAMS ((void));
 static int java_start_char_p PARAMS ((unicode_t));
 static int java_part_char_p PARAMS ((unicode_t));
-static int java_parse_doc_section PARAMS ((int));
+static void java_parse_doc_section PARAMS ((int));
 static void java_parse_end_comment PARAMS ((int));
 static int java_get_unicode PARAMS ((void));
 static int java_read_unicode PARAMS ((java_lexer *, int *));
@@ -684,58 +685,105 @@
     }
 }
 
-/* Parse the documentation section. Keywords must be at the beginning
+/* Parse the documentation section.  Keywords must be at the beginning
    of a documentation comment line (ignoring white space and any `*'
-   character). Parsed keyword(s): @DEPRECATED.  */
+   character).  Parsed keyword(s): ` at deprecated'.  */
 
-static int
+static void
 java_parse_doc_section (c)
      int c;
 {
-  int valid_tag = 0, seen_star = 0;
+  int saw_deprecated = 0;
+  int last_was_star;
+  int first_time = 1;
+
+  /* We loop over all the lines of the comment.  We'll eventually exit
+     if we hit EOF prematurely, or when we see the comment
+     terminator.  */
+  while (1)
+    {
+      /* These first steps need only be done if we're still looking
+	 for the deprecated tag.  If we've already seen it, we might
+	 as well skip looking for it again.  */
+      if (! saw_deprecated)
+	{
+	  /* Skip leading white space.  */
+	  while (JAVA_WHITE_SPACE_P (c))
+	    c = java_get_unicode ();
+
+	  if (c == UEOF)
+	    goto eof;
+
+	  /* If we saw a '*' then we want to check for a following
+	     @deprecated.  Also, if we are still processing the first
+	     line, then @deprecated should be expected -- we've
+	     already processed the '**'.  */
+	  if (c == '*' || first_time)
+	    {
+	      /* Skip spaces and '*'s.  We must also check for the end
+		 of the comment here.  */
+	      while (JAVA_WHITE_SPACE_P (c) || c == '*')
+		{
+		  last_was_star = (c == '*');
+		  c = java_get_unicode ();
+		  if (last_was_star && c == '/')
+		    {
+		      /* We just saw the comment terminator.  */
+		      return;
+		    }
+		}
 
-  while (JAVA_WHITE_SPACE_P (c) || (c == '*') || c == '\n')
-    {
-      switch (c)
-	{
-	case '*':
-	  seen_star = 1;
-	  break;
-	case '\n': /* ULT */
-	  valid_tag = 1;
-	default:
-	  seen_star = 0;
-	}
-      c = java_get_unicode();
-    }
+	      if (c == UEOF)
+		goto eof;
 
-  if (c == UEOF)
-    java_lex_error ("Comment not terminated at end of input", 0);
+	      if (c == '@')
+		{
+		  const char *deprecated = "@deprecated";
+		  int i;
 
-  if (seen_star && (c == '/'))
-    return 1;			/* Goto step1 in caller.  */
+		  for (i = 0; deprecated[i]; ++i)
+		    {
+		      if (c != deprecated[i])
+			break;
+		      /* We write the code in this way, with the
+			 update at the end, so that after the loop
+			 we're left with the next character in C.  */
+		      c = java_get_unicode ();
+		    }
 
-  /* We're parsing ` at deprecated'.  */
-  if (valid_tag && (c == '@'))
-    {
-      char tag [11];
-      int  tag_index = 0;
+		  if (c == UEOF)
+		    goto eof;
+		  if (! deprecated[i])
+		    {
+		      saw_deprecated = 1;
+		      ctxp->deprecated = 1;
+		    }
+		}
+	    }
+	}
 
-      while (tag_index < 10 && c != UEOF && c != ' ' && c != '\n')
+      /* We've examined the relevant content from this line.  Now we
+	 skip the remaining characters and start over with the next
+	 line.  We also check for end of comment here.  */
+      while (c != '\n' && c != UEOF)
 	{
+	  last_was_star = (c == '*');
 	  c = java_get_unicode ();
-	  tag [tag_index++] = c;
+	  if (last_was_star && c == '/')
+	    return;
 	}
 
       if (c == UEOF)
-	java_lex_error ("Comment not terminated at end of input", 0);
-      tag [tag_index] = '\0';
-
-      if (!strcmp (tag, "deprecated"))
-	ctxp->deprecated = 1;
+	goto eof;
+      /* We have to advance past the \n.  */
+      c = java_get_unicode ();
+      if (c == UEOF)
+	goto eof;
+      first_time = 0;
     }
-  java_unget_unicode ();
-  return 0;
+
+ eof:
+  java_lex_error ("Comment not terminated at end of input", 0);
 }
 
 /* Return true if C is a valid start character for a Java identifier.
@@ -962,13 +1010,16 @@
 	case '*':
 	  if ((c = java_get_unicode ()) == '*')
 	    {
-	      if ((c = java_get_unicode ()) == '/')
-		goto step1;	/* Empty documentation comment.  */
-	      else if (java_parse_doc_section (c))
-		goto step1;
+	      c = java_get_unicode ();
+	      if (c == '/')
+		{
+		  /* Empty documentation comment.  */
+		}
+	      else
+		java_parse_doc_section (c);
 	    }
-
-	  java_parse_end_comment ((c = java_get_unicode ()));
+	  else
+	    java_parse_end_comment ((c = java_get_unicode ()));
 	  goto step1;
 	  break;
 	default:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]