This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch: fix gcj deprecation support
- From: Tom Tromey <tromey at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Cc: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: 21 Feb 2003 12:54:37 -0700
- Subject: Patch: fix gcj deprecation support
- Reply-to: tromey at redhat dot com
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: