lang-options.h: Added -Wdeprecated.

* lang-options.h: Added -Wdeprecated.
	* gcj.texi (Warnings): Document -Wdeprecated.
	* java-tree.h (flag_deprecated): Declare.
	* lang.c (lang_W_options): Added deprecated.
	(flag_deprecated): New global.
	* chartables.h: Rebuilt.
	* gen-table.pl (process_one): Look at whitespace.
	(print_tables): Define LETTER_SPACE, LETTER_MASK.
	* parse.h (CLEAR_DEPRECATED): New macro.
	(CHECK_DEPRECATED_NO_RESET): New macro.
	* jcf-parse.c (handle_deprecated): New function.
	(HANDLE_DEPRECATED_ATTRIBUTE): New define.
	* jcf-reader.c (get_attribute): Handle Deprecated attribute.
	* parse.y (resolve_type_during_patch): Check deprecation.
	(jdep_resolve_class): Likewise.
	(process_imports): Likewise.
	(resolve_expression_name): Likewise.
	(check_deprecation): Strip arrays from decl.  Check
	flag_deprecated.
	(patch_method_invocation): Also check the particular constructor
	for deprecation.
	(register_fields): Use CHECK_DEPRECATED_NO_RESET in loop.
	* 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.
	(java_start_char_p): Use LETTER_MASK.
	(java_part_char_p): Likewise.
	(java_space_char_p): New function.

From-SVN: r63350
This commit is contained in:
Tom Tromey 2003-02-24 02:14:49 +00:00 committed by Tom Tromey
parent 804b2c48ea
commit f94ae54025
13 changed files with 2821 additions and 2601 deletions

View file

@ -1,3 +1,36 @@
2003-02-23 Tom Tromey <tromey@redhat.com>
* lang-options.h: Added -Wdeprecated.
* gcj.texi (Warnings): Document -Wdeprecated.
* java-tree.h (flag_deprecated): Declare.
* lang.c (lang_W_options): Added deprecated.
(flag_deprecated): New global.
* chartables.h: Rebuilt.
* gen-table.pl (process_one): Look at whitespace.
(print_tables): Define LETTER_SPACE, LETTER_MASK.
* parse.h (CLEAR_DEPRECATED): New macro.
(CHECK_DEPRECATED_NO_RESET): New macro.
* jcf-parse.c (handle_deprecated): New function.
(HANDLE_DEPRECATED_ATTRIBUTE): New define.
* jcf-reader.c (get_attribute): Handle Deprecated attribute.
* parse.y (resolve_type_during_patch): Check deprecation.
(jdep_resolve_class): Likewise.
(process_imports): Likewise.
(resolve_expression_name): Likewise.
(check_deprecation): Strip arrays from decl. Check
flag_deprecated.
(patch_method_invocation): Also check the particular constructor
for deprecation.
(register_fields): Use CHECK_DEPRECATED_NO_RESET in loop.
* 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.
(java_start_char_p): Use LETTER_MASK.
(java_part_char_p): Likewise.
(java_space_char_p): New function.
2003-02-20 Nathan Sidwell <nathan@codesourcery.com>
Change base class access representation.

File diff suppressed because it is too large Load diff

View file

@ -341,6 +341,9 @@ This option will cause @command{gcj} not to warn when a source file is
newer than its matching class file. By default @command{gcj} will warn
about this.
@item -Wno-deprecated
Warn if a deprecated class, method, or field is referred to.
@item -Wunused
This is the same as @command{gcc}'s @code{-Wunused}.

View file

@ -1,6 +1,6 @@
#! /usr/bin/perl
# Copyright (C) 2000, 2001 Free Software Foundation
# Copyright (C) 2000, 2001, 2003 Free Software Foundation
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -130,7 +130,7 @@ sub process_one
{
my ($code, @fields) = @_;
my $value = '';
my @value = ();
my $type = $fields[$CATEGORY];
# See if the character is a valid identifier start.
@ -138,7 +138,7 @@ sub process_one
|| $type eq 'Pc' # Connecting punctuation
|| $type eq 'Sc') # Currency symbol
{
$value = 'LETTER_START';
push (@value, 'LETTER_START');
}
# See if the character is a valid identifier member.
@ -159,23 +159,29 @@ sub process_one
&& $code <= 0x206f)
|| $code == 0xfeff) # ZWNBSP
{
if ($value eq '')
{
$value = 'LETTER_PART';
}
else
{
$value = 'LETTER_PART | ' . $value;
}
push (@value, 'LETTER_PART');
}
if ($value eq '')
if (($type =~ /Z./
# Java treats some values specially as non-spaces.
&& $code != 0x00a0
&& $code != 0x2007
&& $code != 0x202f)
# And for our purposes there are some that should be specially
# treated as spaces.
|| $code == 0x000b
|| ($code >= 0x001c && $code <= 0x001f))
{
push (@value, 'LETTER_SPACE');
}
if (! @value)
{
$value = '0';
}
else
{
$value = '(' . $value . ')';
$value = '(' . join (' | ', @value) . ')';
}
$map[$code] = $value;
@ -196,7 +202,9 @@ sub print_tables
print OUT "#define GCC_CHARTABLES_H\n\n";
print OUT "#define LETTER_START 1\n";
print OUT "#define LETTER_PART 2\n\n";
print OUT "#define LETTER_PART 2\n";
print OUT "#define LETTER_SPACE 4\n\n";
print OUT "#define LETTER_MASK 7\n\n";
for ($count = 0; $count <= $last; $count += 256)
{

View file

@ -176,6 +176,9 @@ extern int flag_jni;
extern int flag_extraneous_semicolon;
/* When nonzero, report use of deprecated classes, methods, or fields. */
extern int flag_deprecated;
/* When nonzero, always check for a non gcj generated classes archive. */
extern int flag_force_classes_archive_check;

View file

@ -102,10 +102,28 @@ static void parse_source_file_1 (tree, FILE *);
static void parse_source_file_2 (void);
static void parse_source_file_3 (void);
static void parse_class_file (void);
static void handle_deprecated (void);
static void set_source_filename (JCF *, int);
static void jcf_parse (struct JCF*);
static void load_inner_classes (tree);
/* Handle "Deprecated" attribute. */
static void
handle_deprecated (void)
{
if (current_field != NULL_TREE)
FIELD_DEPRECATED (current_field) = 1;
else if (current_method != NULL_TREE)
METHOD_DEPRECATED (current_method) = 1;
else if (current_class != NULL_TREE)
CLASS_DEPRECATED (TYPE_NAME (current_class)) = 1;
else
{
/* Shouldn't happen. */
abort ();
}
}
/* Handle "SourceFile" attribute. */
static void
@ -200,6 +218,8 @@ set_source_filename (JCF *jcf, int index)
DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
}
#define HANDLE_DEPRECATED_ATTRIBUTE() handle_deprecated ()
/* Link seen inner classes to their outer context and register the
inner class to its outer context. They will be later loaded. */
#define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \

View file

@ -220,6 +220,13 @@ get_attribute (JCF *jcf)
HANDLE_GCJCOMPILED_ATTRIBUTE ();
}
else
#endif
#ifdef HANDLE_DEPRECATED_ATTRIBUTE
if (MATCH_ATTRIBUTE ("Deprecated"))
{
HANDLE_DEPRECATED_ATTRIBUTE ();
}
else
#endif
{
#ifdef PROCESS_OTHER_ATTRIBUTE

View file

@ -341,6 +341,7 @@ static void emit_jsr (struct jcf_block *, struct jcf_partial *);
static void call_cleanups (struct jcf_block *, struct jcf_partial *);
static char *make_class_file_name (tree);
static unsigned char *append_synthetic_attribute (struct jcf_partial *);
static void append_deprecated_attribute (struct jcf_partial *);
static void append_innerclasses_attribute (struct jcf_partial *, tree);
static void append_innerclasses_attribute_entry (struct jcf_partial *, tree, tree);
static void append_gcj_attribute (struct jcf_partial *, tree);
@ -2871,8 +2872,11 @@ generate_classfile (tree clas, struct jcf_partial *state)
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 */
if (have_value)
@ -2894,6 +2898,8 @@ generate_classfile (tree clas, struct jcf_partial *state)
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);
@ -2929,6 +2935,9 @@ generate_classfile (tree clas, struct jcf_partial *state)
i++;
synthetic_p = 1;
}
/* Make room for Deprecated attribute. */
if (METHOD_DEPRECATED (part))
i++;
PUT2 (i); /* attributes_count */
@ -3069,6 +3078,10 @@ generate_classfile (tree clas, struct jcf_partial *state)
PUT2 (i);
}
}
if (METHOD_DEPRECATED (part))
append_deprecated_attribute (state);
methods_count++;
current_function_decl = save_function;
}
@ -3092,6 +3105,9 @@ generate_classfile (tree clas, struct jcf_partial *state)
i++;
PUT2 (i); /* attributes_count */
if (CLASS_DEPRECATED (TYPE_NAME (clas)))
i++;
/* generate the SourceFile attribute. */
if (SourceFile_node == NULL_TREE)
{
@ -3105,6 +3121,8 @@ generate_classfile (tree clas, struct jcf_partial *state)
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);
@ -3133,6 +3151,17 @@ append_synthetic_attribute (struct jcf_partial *state)
return ptr;
}
static void
append_deprecated_attribute (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
append_gcj_attribute (struct jcf_partial *state, tree class)
{

View file

@ -55,6 +55,8 @@ DEFINE_LANG_NAME ("Java")
N_("Warn if deprecated empty statements are found") },
{ "-Wout-of-date",
N_("Warn if .class files are out of date") },
{ "-Wdeprecated",
N_("Warn if deprecated class, method, or field is used") },
{ "-fforce-classes-archive-check",
N_("Always check for non gcj generated classes archives") },
{ "-fno-optimize-static-class-initialization",

View file

@ -168,6 +168,9 @@ const char *current_encoding = NULL;
/* When nonzero, report the now deprecated empty statements. */
int flag_extraneous_semicolon;
/* When nonzero, report use of deprecated classes, methods, or fields. */
int flag_deprecated = 1;
/* When nonzero, always check for a non gcj generated classes archive. */
int flag_force_classes_archive_check;
@ -218,7 +221,8 @@ lang_W_options[] =
{
{ "redundant-modifiers", &flag_redundant, 1 },
{ "extraneous-semicolon", &flag_extraneous_semicolon, 1 },
{ "out-of-date", &flag_newer, 1 }
{ "out-of-date", &flag_newer, 1 },
{ "deprecated", &flag_deprecated, 1 }
};
JCF *current_jcf;

View file

@ -51,7 +51,8 @@ static void java_store_unicode (struct java_line *, unicode_t, int);
static int java_parse_escape_sequence (void);
static int java_start_char_p (unicode_t);
static int java_part_char_p (unicode_t);
static int java_parse_doc_section (int);
static int java_space_char_p (unicode_t);
static void java_parse_doc_section (int);
static void java_parse_end_comment (int);
static int java_get_unicode (void);
static int java_read_unicode (java_lexer *, int *);
@ -673,53 +674,92 @@ java_parse_end_comment (int c)
of a documentation comment line (ignoring white space and any `*'
character). Parsed keyword(s): @DEPRECATED. */
static int
static void
java_parse_doc_section (int c)
{
int valid_tag = 0, seen_star = 0;
int last_was_star;
while (JAVA_WHITE_SPACE_P (c) || (c == '*') || c == '\n')
/* We reset this here, because only the most recent doc comment
applies to the following declaration. */
ctxp->deprecated = 0;
/* 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)
{
switch (c)
/* 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 (! ctxp->deprecated)
{
case '*':
seen_star = 1;
break;
case '\n': /* ULT */
valid_tag = 1;
default:
seen_star = 0;
/* Skip whitespace 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;
}
}
if (c == UEOF)
goto eof;
if (c == '@')
{
const char *deprecated = "@deprecated";
int i;
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 ();
}
if (c == UEOF)
goto eof;
/* @deprecated must be followed by a space or newline.
We also allow a '*' in case it appears just before
the end of a comment. In this position only we also
must allow any Unicode space character. */
if (c == ' ' || c == '\n' || c == '*' || java_space_char_p (c))
{
if (! deprecated[i])
ctxp->deprecated = 1;
}
}
}
c = java_get_unicode();
}
if (c == UEOF)
java_lex_error ("Comment not terminated at end of input", 0);
if (seen_star && (c == '/'))
return 1; /* Goto step1 in caller. */
/* We're parsing `@deprecated'. */
if (valid_tag && (c == '@'))
{
char tag [11];
int tag_index = 0;
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;
}
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.
@ -733,7 +773,7 @@ java_start_char_p (unicode_t c)
unsigned long val = (unsigned long) page;
int flags;
if ((val & ~ (LETTER_PART | LETTER_START)) != 0)
if ((val & ~ LETTER_MASK) != 0)
flags = page[c & 255];
else
flags = val;
@ -752,7 +792,7 @@ java_part_char_p (unicode_t c)
unsigned long val = (unsigned long) page;
int flags;
if ((val & ~ (LETTER_PART | LETTER_START)) != 0)
if ((val & ~ LETTER_MASK) != 0)
flags = page[c & 255];
else
flags = val;
@ -760,6 +800,23 @@ java_part_char_p (unicode_t c)
return flags & LETTER_PART;
}
/* Return true if C is whitespace. */
static int
java_space_char_p (unicode_t c)
{
unsigned int hi = c / 256;
const char *const page = type_table[hi];
unsigned long val = (unsigned long) page;
int flags;
if ((val & ~ LETTER_MASK) != 0)
flags = page[c & 255];
else
flags = val;
return flags & LETTER_SPACE;
}
static int
java_parse_escape_sequence (void)
{
@ -940,13 +997,19 @@ java_lex (YYSTYPE *java_lval)
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. We have to reset
the deprecation marker as only the most recent
doc comment applies. */
ctxp->deprecated = 0;
}
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:

View file

@ -700,6 +700,14 @@ typedef struct jdeplist_s jdeplist;
java_check_regular_methods ((CLASS)); \
}
#define CLEAR_DEPRECATED ctxp->deprecated = 0
#define CHECK_DEPRECATED_NO_RESET(DECL) \
{ \
if (ctxp->deprecated) \
DECL_DEPRECATED (DECL) = 1; \
}
/* Using and reseting the @deprecated tag flag */
#define CHECK_DEPRECATED(DECL) \
{ \

View file

@ -4289,7 +4289,7 @@ register_fields (int flags, tree type, tree variable_list)
else
lineno = EXPR_WFL_LINENO (cl);
field_decl = add_field (class_type, current_name, real_type, flags);
CHECK_DEPRECATED (field_decl);
CHECK_DEPRECATED_NO_RESET (field_decl);
/* If the field denotes a final instance variable, then we
allocate a LANG_DECL_SPECIFIC part to keep track of its
@ -4347,6 +4347,8 @@ register_fields (int flags, tree type, tree variable_list)
DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
}
}
CLEAR_DEPRECATED;
lineno = saved_lineno;
}
@ -5460,6 +5462,10 @@ jdep_resolve_class (jdep *dep)
decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
JDEP_DECL (dep), JDEP_WFL (dep));
JDEP_RESOLVED (dep, decl);
/* If there is no WFL, that's ok. We generate this warning
elsewhere. */
if (JDEP_WFL (dep) != NULL_TREE)
check_deprecation (JDEP_WFL (dep), decl);
}
if (!decl)
@ -6647,7 +6653,11 @@ process_imports (void)
/* We found it, we can bail out */
if (IDENTIFIER_CLASS_VALUE (to_be_found))
break;
{
check_deprecation (TREE_PURPOSE (import),
IDENTIFIER_CLASS_VALUE (to_be_found));
break;
}
/* We haven't found it. Maybe we're trying to access an
inner class. The only way for us to know is to try again
@ -9154,6 +9164,8 @@ resolve_expression_name (tree id, tree *orig)
if (FIELD_LOCAL_ALIAS_USED (decl))
name = DECL_NAME (decl);
check_deprecation (id, decl);
/* Instance variable (8.3.1.1) can't appear within
static method, static initializer or initializer for
a static variable. */
@ -9952,22 +9964,40 @@ not_accessible_p (tree reference, tree member, tree where, int from_super)
static void
check_deprecation (tree wfl, tree decl)
{
const char *file = DECL_SOURCE_FILE (decl);
const char *file;
tree elt;
if (! flag_deprecated)
return;
/* We want to look at the element type of arrays here, so we strip
all surrounding array types. */
if (TYPE_ARRAY_P (TREE_TYPE (decl)))
{
elt = TREE_TYPE (decl);
while (TYPE_ARRAY_P (elt))
elt = TYPE_ARRAY_ELEMENT (elt);
/* We'll end up with a pointer type, so we use TREE_TYPE to go
to the record. */
decl = TYPE_NAME (TREE_TYPE (elt));
}
file = DECL_SOURCE_FILE (decl);
/* Complain if the field is deprecated and the file it was defined
in isn't compiled at the same time the file which contains its
use is */
if (DECL_DEPRECATED (decl)
&& !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
{
char the [20];
const char *the;
switch (TREE_CODE (decl))
{
case FUNCTION_DECL:
strcpy (the, "method");
the = "method";
break;
case FIELD_DECL:
case VAR_DECL:
strcpy (the, "field");
the = "field";
break;
case TYPE_DECL:
parse_warning_context (wfl, "The class `%s' has been deprecated",
@ -10336,11 +10366,10 @@ patch_method_invocation (tree patch, tree primary, tree where, int from_super,
}
/* Deprecation check: check whether the method being invoked or the
instance-being-created's type are deprecated. */
instance-being-created's type are deprecated. */
if (TREE_CODE (patch) == NEW_CLASS_EXPR)
check_deprecation (wfl, TYPE_NAME (DECL_CONTEXT (list)));
else
check_deprecation (wfl, list);
check_deprecation (wfl, list);
/* If invoking a innerclass constructor, there are hidden parameters
to pass */
@ -13383,7 +13412,7 @@ patch_binop (tree node, tree wfl_op1, tree wfl_op2)
}
break;
/* 15.19.1 Type Comparison Operator instaceof */
/* 15.19.1 Type Comparison Operator instanceof */
case INSTANCEOF_EXPR:
TREE_TYPE (node) = boolean_type_node;
@ -14134,10 +14163,14 @@ resolve_type_during_patch (tree type)
IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
return NULL_TREE;
}
check_deprecation (type, type_decl);
return TREE_TYPE (type_decl);
}
return type;
}
/* 5.5 Casting Conversion. error_mark_node is returned if an error is
found. Otherwise NODE or something meant to replace it is returned. */