Commit f94ae540 by Tom Tromey Committed by Tom Tromey

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
parent 804b2c48
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> 2003-02-20 Nathan Sidwell <nathan@codesourcery.com>
Change base class access representation. Change base class access representation.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -341,6 +341,9 @@ This option will cause @command{gcj} not to warn when a source file is ...@@ -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 newer than its matching class file. By default @command{gcj} will warn
about this. about this.
@item -Wno-deprecated
Warn if a deprecated class, method, or field is referred to.
@item -Wunused @item -Wunused
This is the same as @command{gcc}'s @code{-Wunused}. This is the same as @command{gcc}'s @code{-Wunused}.
......
#! /usr/bin/perl #! /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 # 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 # it under the terms of the GNU General Public License as published by
...@@ -130,7 +130,7 @@ sub process_one ...@@ -130,7 +130,7 @@ sub process_one
{ {
my ($code, @fields) = @_; my ($code, @fields) = @_;
my $value = ''; my @value = ();
my $type = $fields[$CATEGORY]; my $type = $fields[$CATEGORY];
# See if the character is a valid identifier start. # See if the character is a valid identifier start.
...@@ -138,7 +138,7 @@ sub process_one ...@@ -138,7 +138,7 @@ sub process_one
|| $type eq 'Pc' # Connecting punctuation || $type eq 'Pc' # Connecting punctuation
|| $type eq 'Sc') # Currency symbol || $type eq 'Sc') # Currency symbol
{ {
$value = 'LETTER_START'; push (@value, 'LETTER_START');
} }
# See if the character is a valid identifier member. # See if the character is a valid identifier member.
...@@ -159,23 +159,29 @@ sub process_one ...@@ -159,23 +159,29 @@ sub process_one
&& $code <= 0x206f) && $code <= 0x206f)
|| $code == 0xfeff) # ZWNBSP || $code == 0xfeff) # ZWNBSP
{ {
if ($value eq '') push (@value, 'LETTER_PART');
{ }
$value = 'LETTER_PART';
} if (($type =~ /Z./
else # Java treats some values specially as non-spaces.
{ && $code != 0x00a0
$value = 'LETTER_PART | ' . $value; && $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 eq '') if (! @value)
{ {
$value = '0'; $value = '0';
} }
else else
{ {
$value = '(' . $value . ')'; $value = '(' . join (' | ', @value) . ')';
} }
$map[$code] = $value; $map[$code] = $value;
...@@ -196,7 +202,9 @@ sub print_tables ...@@ -196,7 +202,9 @@ sub print_tables
print OUT "#define GCC_CHARTABLES_H\n\n"; print OUT "#define GCC_CHARTABLES_H\n\n";
print OUT "#define LETTER_START 1\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) for ($count = 0; $count <= $last; $count += 256)
{ {
......
...@@ -176,6 +176,9 @@ extern int flag_jni; ...@@ -176,6 +176,9 @@ extern int flag_jni;
extern int flag_extraneous_semicolon; 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. */ /* When nonzero, always check for a non gcj generated classes archive. */
extern int flag_force_classes_archive_check; extern int flag_force_classes_archive_check;
......
...@@ -102,10 +102,28 @@ static void parse_source_file_1 (tree, 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_2 (void);
static void parse_source_file_3 (void); static void parse_source_file_3 (void);
static void parse_class_file (void); static void parse_class_file (void);
static void handle_deprecated (void);
static void set_source_filename (JCF *, int); static void set_source_filename (JCF *, int);
static void jcf_parse (struct JCF*); static void jcf_parse (struct JCF*);
static void load_inner_classes (tree); 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. */ /* Handle "SourceFile" attribute. */
static void static void
...@@ -200,6 +218,8 @@ set_source_filename (JCF *jcf, int index) ...@@ -200,6 +218,8 @@ set_source_filename (JCF *jcf, int index)
DECL_FUNCTION_THROWS (current_method) = nreverse (list); \ DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
} }
#define HANDLE_DEPRECATED_ATTRIBUTE() handle_deprecated ()
/* Link seen inner classes to their outer context and register the /* Link seen inner classes to their outer context and register the
inner class to its outer context. They will be later loaded. */ inner class to its outer context. They will be later loaded. */
#define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \ #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
......
...@@ -221,6 +221,13 @@ get_attribute (JCF *jcf) ...@@ -221,6 +221,13 @@ get_attribute (JCF *jcf)
} }
else else
#endif #endif
#ifdef HANDLE_DEPRECATED_ATTRIBUTE
if (MATCH_ATTRIBUTE ("Deprecated"))
{
HANDLE_DEPRECATED_ATTRIBUTE ();
}
else
#endif
{ {
#ifdef PROCESS_OTHER_ATTRIBUTE #ifdef PROCESS_OTHER_ATTRIBUTE
PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length); PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
......
...@@ -341,6 +341,7 @@ static void emit_jsr (struct jcf_block *, struct jcf_partial *); ...@@ -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 void call_cleanups (struct jcf_block *, struct jcf_partial *);
static char *make_class_file_name (tree); static char *make_class_file_name (tree);
static unsigned char *append_synthetic_attribute (struct jcf_partial *); 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 (struct jcf_partial *, tree);
static void append_innerclasses_attribute_entry (struct jcf_partial *, tree, tree); static void append_innerclasses_attribute_entry (struct jcf_partial *, tree, tree);
static void append_gcj_attribute (struct jcf_partial *, tree); static void append_gcj_attribute (struct jcf_partial *, tree);
...@@ -2871,8 +2872,11 @@ generate_classfile (tree clas, struct jcf_partial *state) ...@@ -2871,8 +2872,11 @@ generate_classfile (tree clas, struct jcf_partial *state)
if (have_value) if (have_value)
attr_count++; 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++; attr_count++;
if (FIELD_DEPRECATED (part))
attr_count++;
PUT2 (attr_count); /* attributes_count */ PUT2 (attr_count); /* attributes_count */
if (have_value) if (have_value)
...@@ -2894,6 +2898,8 @@ generate_classfile (tree clas, struct jcf_partial *state) ...@@ -2894,6 +2898,8 @@ generate_classfile (tree clas, struct jcf_partial *state)
if (FIELD_THISN (part) || FIELD_LOCAL_ALIAS (part) if (FIELD_THISN (part) || FIELD_LOCAL_ALIAS (part)
|| FIELD_SYNTHETIC (part)) || FIELD_SYNTHETIC (part))
ptr = append_synthetic_attribute (state); ptr = append_synthetic_attribute (state);
if (FIELD_DEPRECATED (part))
append_deprecated_attribute (state);
fields_count++; fields_count++;
} }
ptr = fields_count_ptr; UNSAFE_PUT2 (fields_count); ptr = fields_count_ptr; UNSAFE_PUT2 (fields_count);
...@@ -2929,6 +2935,9 @@ generate_classfile (tree clas, struct jcf_partial *state) ...@@ -2929,6 +2935,9 @@ generate_classfile (tree clas, struct jcf_partial *state)
i++; i++;
synthetic_p = 1; synthetic_p = 1;
} }
/* Make room for Deprecated attribute. */
if (METHOD_DEPRECATED (part))
i++;
PUT2 (i); /* attributes_count */ PUT2 (i); /* attributes_count */
...@@ -3069,6 +3078,10 @@ generate_classfile (tree clas, struct jcf_partial *state) ...@@ -3069,6 +3078,10 @@ generate_classfile (tree clas, struct jcf_partial *state)
PUT2 (i); PUT2 (i);
} }
} }
if (METHOD_DEPRECATED (part))
append_deprecated_attribute (state);
methods_count++; methods_count++;
current_function_decl = save_function; current_function_decl = save_function;
} }
...@@ -3092,6 +3105,9 @@ generate_classfile (tree clas, struct jcf_partial *state) ...@@ -3092,6 +3105,9 @@ generate_classfile (tree clas, struct jcf_partial *state)
i++; i++;
PUT2 (i); /* attributes_count */ PUT2 (i); /* attributes_count */
if (CLASS_DEPRECATED (TYPE_NAME (clas)))
i++;
/* generate the SourceFile attribute. */ /* generate the SourceFile attribute. */
if (SourceFile_node == NULL_TREE) if (SourceFile_node == NULL_TREE)
{ {
...@@ -3105,6 +3121,8 @@ generate_classfile (tree clas, struct jcf_partial *state) ...@@ -3105,6 +3121,8 @@ generate_classfile (tree clas, struct jcf_partial *state)
PUT2 (i); PUT2 (i);
append_gcj_attribute (state, clas); append_gcj_attribute (state, clas);
append_innerclasses_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. */ /* New finally generate the contents of the constant pool chunk. */
i = count_constant_pool_bytes (&state->cpool); i = count_constant_pool_bytes (&state->cpool);
...@@ -3134,6 +3152,17 @@ append_synthetic_attribute (struct jcf_partial *state) ...@@ -3134,6 +3152,17 @@ append_synthetic_attribute (struct jcf_partial *state)
} }
static void 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) append_gcj_attribute (struct jcf_partial *state, tree class)
{ {
unsigned char *ptr; unsigned char *ptr;
......
...@@ -55,6 +55,8 @@ DEFINE_LANG_NAME ("Java") ...@@ -55,6 +55,8 @@ DEFINE_LANG_NAME ("Java")
N_("Warn if deprecated empty statements are found") }, N_("Warn if deprecated empty statements are found") },
{ "-Wout-of-date", { "-Wout-of-date",
N_("Warn if .class files are out 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", { "-fforce-classes-archive-check",
N_("Always check for non gcj generated classes archives") }, N_("Always check for non gcj generated classes archives") },
{ "-fno-optimize-static-class-initialization", { "-fno-optimize-static-class-initialization",
......
...@@ -168,6 +168,9 @@ const char *current_encoding = NULL; ...@@ -168,6 +168,9 @@ const char *current_encoding = NULL;
/* When nonzero, report the now deprecated empty statements. */ /* When nonzero, report the now deprecated empty statements. */
int flag_extraneous_semicolon; 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. */ /* When nonzero, always check for a non gcj generated classes archive. */
int flag_force_classes_archive_check; int flag_force_classes_archive_check;
...@@ -218,7 +221,8 @@ lang_W_options[] = ...@@ -218,7 +221,8 @@ lang_W_options[] =
{ {
{ "redundant-modifiers", &flag_redundant, 1 }, { "redundant-modifiers", &flag_redundant, 1 },
{ "extraneous-semicolon", &flag_extraneous_semicolon, 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; JCF *current_jcf;
......
...@@ -51,7 +51,8 @@ static void java_store_unicode (struct java_line *, unicode_t, int); ...@@ -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_parse_escape_sequence (void);
static int java_start_char_p (unicode_t); static int java_start_char_p (unicode_t);
static int java_part_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 void java_parse_end_comment (int);
static int java_get_unicode (void); static int java_get_unicode (void);
static int java_read_unicode (java_lexer *, int *); static int java_read_unicode (java_lexer *, int *);
...@@ -673,53 +674,92 @@ java_parse_end_comment (int c) ...@@ -673,53 +674,92 @@ java_parse_end_comment (int c)
of a documentation comment line (ignoring white space and any `*' of a documentation comment line (ignoring white space and any `*'
character). Parsed keyword(s): @DEPRECATED. */ character). Parsed keyword(s): @DEPRECATED. */
static int static void
java_parse_doc_section (int c) 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 '*': /* Skip whitespace and '*'s. We must also check for the end
seen_star = 1; of the comment here. */
break; while (JAVA_WHITE_SPACE_P (c) || c == '*')
case '\n': /* ULT */ {
valid_tag = 1; last_was_star = (c == '*');
default: c = java_get_unicode ();
seen_star = 0; if (last_was_star && c == '/')
} {
c = java_get_unicode(); /* We just saw the comment terminator. */
} return;
}
}
if (c == UEOF) if (c == UEOF)
java_lex_error ("Comment not terminated at end of input", 0); goto eof;
if (seen_star && (c == '/')) if (c == '@')
return 1; /* Goto step1 in caller. */ {
const char *deprecated = "@deprecated";
int i;
/* We're parsing `@deprecated'. */ for (i = 0; deprecated[i]; ++i)
if (valid_tag && (c == '@')) {
{ if (c != deprecated[i])
char tag [11]; break;
int tag_index = 0; /* 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;
}
}
}
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 (); c = java_get_unicode ();
tag [tag_index++] = c; if (last_was_star && c == '/')
return;
} }
if (c == UEOF) if (c == UEOF)
java_lex_error ("Comment not terminated at end of input", 0); goto eof;
tag [tag_index] = '\0'; /* We have to advance past the \n. */
c = java_get_unicode ();
if (!strcmp (tag, "deprecated")) if (c == UEOF)
ctxp->deprecated = 1; 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. /* Return true if C is a valid start character for a Java identifier.
...@@ -733,7 +773,7 @@ java_start_char_p (unicode_t c) ...@@ -733,7 +773,7 @@ java_start_char_p (unicode_t c)
unsigned long val = (unsigned long) page; unsigned long val = (unsigned long) page;
int flags; int flags;
if ((val & ~ (LETTER_PART | LETTER_START)) != 0) if ((val & ~ LETTER_MASK) != 0)
flags = page[c & 255]; flags = page[c & 255];
else else
flags = val; flags = val;
...@@ -752,7 +792,7 @@ java_part_char_p (unicode_t c) ...@@ -752,7 +792,7 @@ java_part_char_p (unicode_t c)
unsigned long val = (unsigned long) page; unsigned long val = (unsigned long) page;
int flags; int flags;
if ((val & ~ (LETTER_PART | LETTER_START)) != 0) if ((val & ~ LETTER_MASK) != 0)
flags = page[c & 255]; flags = page[c & 255];
else else
flags = val; flags = val;
...@@ -760,6 +800,23 @@ java_part_char_p (unicode_t c) ...@@ -760,6 +800,23 @@ java_part_char_p (unicode_t c)
return flags & LETTER_PART; 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 static int
java_parse_escape_sequence (void) java_parse_escape_sequence (void)
{ {
...@@ -940,13 +997,19 @@ java_lex (YYSTYPE *java_lval) ...@@ -940,13 +997,19 @@ java_lex (YYSTYPE *java_lval)
case '*': case '*':
if ((c = java_get_unicode ()) == '*') if ((c = java_get_unicode ()) == '*')
{ {
if ((c = java_get_unicode ()) == '/') c = java_get_unicode ();
goto step1; /* Empty documentation comment. */ if (c == '/')
else if (java_parse_doc_section (c)) {
goto step1; /* 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);
} }
else
java_parse_end_comment ((c = java_get_unicode ())); java_parse_end_comment ((c = java_get_unicode ()));
goto step1; goto step1;
break; break;
default: default:
......
...@@ -700,6 +700,14 @@ typedef struct jdeplist_s jdeplist; ...@@ -700,6 +700,14 @@ typedef struct jdeplist_s jdeplist;
java_check_regular_methods ((CLASS)); \ 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 */ /* Using and reseting the @deprecated tag flag */
#define CHECK_DEPRECATED(DECL) \ #define CHECK_DEPRECATED(DECL) \
{ \ { \
......
...@@ -4289,7 +4289,7 @@ register_fields (int flags, tree type, tree variable_list) ...@@ -4289,7 +4289,7 @@ register_fields (int flags, tree type, tree variable_list)
else else
lineno = EXPR_WFL_LINENO (cl); lineno = EXPR_WFL_LINENO (cl);
field_decl = add_field (class_type, current_name, real_type, flags); 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 /* If the field denotes a final instance variable, then we
allocate a LANG_DECL_SPECIFIC part to keep track of its allocate a LANG_DECL_SPECIFIC part to keep track of its
...@@ -4347,6 +4347,8 @@ register_fields (int flags, tree type, tree variable_list) ...@@ -4347,6 +4347,8 @@ register_fields (int flags, tree type, tree variable_list)
DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1); DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
} }
} }
CLEAR_DEPRECATED;
lineno = saved_lineno; lineno = saved_lineno;
} }
...@@ -5460,6 +5462,10 @@ jdep_resolve_class (jdep *dep) ...@@ -5460,6 +5462,10 @@ jdep_resolve_class (jdep *dep)
decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep), decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
JDEP_DECL (dep), JDEP_WFL (dep)); JDEP_DECL (dep), JDEP_WFL (dep));
JDEP_RESOLVED (dep, decl); 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) if (!decl)
...@@ -6647,7 +6653,11 @@ process_imports (void) ...@@ -6647,7 +6653,11 @@ process_imports (void)
/* We found it, we can bail out */ /* We found it, we can bail out */
if (IDENTIFIER_CLASS_VALUE (to_be_found)) 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 /* 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 inner class. The only way for us to know is to try again
...@@ -9154,6 +9164,8 @@ resolve_expression_name (tree id, tree *orig) ...@@ -9154,6 +9164,8 @@ resolve_expression_name (tree id, tree *orig)
if (FIELD_LOCAL_ALIAS_USED (decl)) if (FIELD_LOCAL_ALIAS_USED (decl))
name = DECL_NAME (decl); name = DECL_NAME (decl);
check_deprecation (id, decl);
/* Instance variable (8.3.1.1) can't appear within /* Instance variable (8.3.1.1) can't appear within
static method, static initializer or initializer for static method, static initializer or initializer for
a static variable. */ a static variable. */
...@@ -9952,22 +9964,40 @@ not_accessible_p (tree reference, tree member, tree where, int from_super) ...@@ -9952,22 +9964,40 @@ not_accessible_p (tree reference, tree member, tree where, int from_super)
static void static void
check_deprecation (tree wfl, tree decl) 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 /* 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 in isn't compiled at the same time the file which contains its
use is */ use is */
if (DECL_DEPRECATED (decl) if (DECL_DEPRECATED (decl)
&& !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file))) && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
{ {
char the [20]; const char *the;
switch (TREE_CODE (decl)) switch (TREE_CODE (decl))
{ {
case FUNCTION_DECL: case FUNCTION_DECL:
strcpy (the, "method"); the = "method";
break; break;
case FIELD_DECL: case FIELD_DECL:
case VAR_DECL: case VAR_DECL:
strcpy (the, "field"); the = "field";
break; break;
case TYPE_DECL: case TYPE_DECL:
parse_warning_context (wfl, "The class `%s' has been deprecated", 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, ...@@ -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 /* 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) if (TREE_CODE (patch) == NEW_CLASS_EXPR)
check_deprecation (wfl, TYPE_NAME (DECL_CONTEXT (list))); 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 /* If invoking a innerclass constructor, there are hidden parameters
to pass */ to pass */
...@@ -13383,7 +13412,7 @@ patch_binop (tree node, tree wfl_op1, tree wfl_op2) ...@@ -13383,7 +13412,7 @@ patch_binop (tree node, tree wfl_op1, tree wfl_op2)
} }
break; break;
/* 15.19.1 Type Comparison Operator instaceof */ /* 15.19.1 Type Comparison Operator instanceof */
case INSTANCEOF_EXPR: case INSTANCEOF_EXPR:
TREE_TYPE (node) = boolean_type_node; TREE_TYPE (node) = boolean_type_node;
...@@ -14134,10 +14163,14 @@ resolve_type_during_patch (tree type) ...@@ -14134,10 +14163,14 @@ resolve_type_during_patch (tree type)
IDENTIFIER_POINTER (EXPR_WFL_NODE (type))); IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
return NULL_TREE; return NULL_TREE;
} }
check_deprecation (type, type_decl);
return TREE_TYPE (type_decl); return TREE_TYPE (type_decl);
} }
return type; return type;
} }
/* 5.5 Casting Conversion. error_mark_node is returned if an error is /* 5.5 Casting Conversion. error_mark_node is returned if an error is
found. Otherwise NODE or something meant to replace it is returned. */ found. Otherwise NODE or something meant to replace it is returned. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment