Commit c877974e by Alexandre Petit-Bianco Committed by Alexandre Petit-Bianco

class.c (unmangle_classname): Set QUALIFIED_P when appropriate.

Wed Nov 18 23:54:53 1998  Alexandre Petit-Bianco  <apbianco@cygnus.com>
	* class.c (unmangle_classname): Set QUALIFIED_P when appropriate.
	(layout_class): Cope with methods featuring WFL in decl names.
	* decl.c (unqualified_object_id_node): New global variable,
 	initialized.
	(build_decl_no_layout): Removed.
	* expr.c (build_primtype_type_ref): Handle Double.
	(java_lang_expand_expr): Fixed indentations.
	* java-tree.h (CLASS_METHOD_CHECKED_P): Flag deleted.
	(flag_wall, flag_redundant, flag_not_overriding,
 	flag_static_local_jdk1_1, unqualified_object_id_node): Global
 	variable declarations.
	(build_decl_no_layout): Removed prototype.
	(java_get_real_method_name): Added prototype.
	(IS_UNCHECKED_EXPRESSION_P): Renamed IS_UNCHECKED_EXCEPTION_P.
	(java_parse_abort_on_error): Macro now just returns.
	* jcf-parse.c (jcf_parse_source): Check fclose returned
 	value. Call emit_register_classes if java_report_errors returns
 	zero.
	* lanc.c (flag_wall, flag_redundant, flag_not_overriding,
 	flag_static_local_jdk1_1): New integer flags.
	(lang_decode_option): New flags set here.
	* parse.h (GET_REAL_TYPE, GET_METHOD_NAME): New macros.
	(OBSOLETE_MODIFIER_WARNING): Issue error message conditionally to
 	the flag_redundant variable.
	(SET_TYPE_FOR_RESOLUTION): Consider Object being java.lang.Object
 	when parsing java.lang.Object class.
	(BUILD_MONITOR_ENTER, BUILD_MONITOR_EXIT): Added terminal
 	NULL_TREE to build.
	(resolve_qualified_expression_name): Fixed indentation.
	(patch_array_ref): Changed prototype.
	(not_initialized_as_it_should_p): Prototype removed.
	(java_report_errors): Added function prototype.
	* parse.y (formal_parameter:): Changed error message for not yet
 	supported final parameters.
	(class_type_list:): Set both PURPOSE and VALUE of created
 	TREE_LIST to be class_type.
	(primary_no_new_array:): Handle class literals on primitive types.
	(parse_warning_context): Reinstalled correct force_error and
 	do_warning flags setups.
	(java_report_errors): Changed prototype. Return java_error_count
 	value.
	(variable_redefinition_error): Consider treating variable type as
 	a fake pointer.
	(create_interface): Warn about redundant abstract modifier if
 	flag_redundant is set. Changed error message.
	(lookup_field_wrapper): Save/restore globals before/after looking
 	up field.
	(duplicate_declaration_error_p): Consider treating declaration
 	type as a fake pointer.
	(register_fields): Extract real type from dependency node. Check
 	for duplicate field declaration after type adjustment. Use
 	DECL_INITIAL to store static final initialized values.
	(method_header): Extract real function type from dependency node.
	(check_abstract_method_header): Use GET_METHOD_NAME.
	(obtain_incomplete_type): Layout fake pointer type.
	(safe_layout_class): Don't try to check for methods before layout.
	(java_complete_class): Don't check for correct throws clause
 	elements inheritance here.
	(resolve_and_layout): Broadened name parameter meaning.
	(reset_method_name): Use GET_METHOD_NAME.
	(java_get_real_method_name): New function.
	(java_check_regular_methods): Don't check methods in
 	java.lang.Object.  Verify lineage of throws clause elements. Use
 	flag_no_overriding in warning report.
	(check_throws_clauses): Don't check if class was from
 	bytecode. Use IS_UNCHECKED_EXCEPTION_P macro.
	(java_check_methods): Don't set CLASS_METHOD_CHECKED_P flag.
	(declare_local_variables): Use flag_static_local_jdk1_1 to report
 	warning on unsupported final local variables. Use build_decl
 	instead of build_decl_no_layout. Get real local variable type from
 	dependency node.
	(source_start_java_method): Get real parameter type from
 	dependency node. Call build_decl instead of build_decl_no_layout.
	(java_layout_classes): Reverse tree and layout type and class as
 	required. Mark class as loaded when done.
	(resolve_field_access): Fixed indentation. Restricted condition
 	leading to static field access code generation. Set field_type
 	decl's TREE_TYPE if QUAL_DECL_TYPE not available.
	(resolve_qualified_expression_name): Initialize type_found to
 	null. Handle static field resolved during qualification. Fixed
 	layout on non primitive field decl types.
	(not_accessible_p): Fixed typo in comment.
	(patch_method_invocation): Resolve and layout class to search from
 	type.
	(lookup_method_invoke): Keep integer constant 0 as is. Resolve and
 	layout non primitive type, if necessary. Make method node only to
 	report errors.
	(find_applicable_accessible_methods_list): Consider WFL'ed method
 	decl names. Fixed indentation.
	(argument_types_convertible): Resolve and layout target type if
 	necessary.
	(java_complete_tree): Fixed indentation problems. Rewrote
 	CALL_EXPR thrown exceptions check. Re-installed further processing
 	of the assignment in certain cases.
	(patch_assignment): Call maybe_build_primttype_type_ref to perform
 	inlining on class literals.
	(valid_builtin_assignconv_identity_widening_p): Cope with constant
 	0 literal.
	(valid_method_invocation_conversion_p): Likewise.
	(patch_string): Temporary disable forbidden use of `this' in
 	explicit constructor invocations when doing string concatenation
 	within their scope.
	(patch_unaryop): Added comment. Reinstalled code to disable
 	further check on assignment operation with cast expression RHS.
	(patch_switch_statement): Fixed indentation.
	(build_try_statement): Call build_decl instead of
 	build_decl_no_layout.
	(patch_synchronized_statement): Likewise.
	(patch_throw_statement): Use IS_UNCHECKED_EXCEPTION_P instead of
 	IS_UNCHECKED_EXPRESSION_P.
	(check_thrown_exceptions_do): Changed leading comment. Resolve and
 	layout argument exception type.
	(purge_unchecked_exceptions): Use IS_UNCHECKED_EXCEPTION_P instead
 	of IS_UNCHECKED_EXPRESSION_P.
Fixed problems found when compiling a mixture of .class and .java
files in the same package. Some support for the compilation of libjava.

From-SVN: r23704
parent 42316565
Wed Nov 18 23:54:53 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
* class.c (unmangle_classname): Set QUALIFIED_P when appropriate.
(layout_class): Cope with methods featuring WFL in decl names.
* decl.c (unqualified_object_id_node): New global variable,
initialized.
(build_decl_no_layout): Removed.
* expr.c (build_primtype_type_ref): Handle Double.
(java_lang_expand_expr): Fixed indentations.
* java-tree.h (CLASS_METHOD_CHECKED_P): Flag deleted.
(flag_wall, flag_redundant, flag_not_overriding,
flag_static_local_jdk1_1, unqualified_object_id_node): Global
variable declarations.
(build_decl_no_layout): Removed prototype.
(java_get_real_method_name): Added prototype.
(IS_UNCHECKED_EXPRESSION_P): Renamed IS_UNCHECKED_EXCEPTION_P.
(java_parse_abort_on_error): Macro now just returns.
* jcf-parse.c (jcf_parse_source): Check fclose returned
value. Call emit_register_classes if java_report_errors returns
zero.
* lanc.c (flag_wall, flag_redundant, flag_not_overriding,
flag_static_local_jdk1_1): New integer flags.
(lang_decode_option): New flags set here.
* parse.h (GET_REAL_TYPE, GET_METHOD_NAME): New macros.
(OBSOLETE_MODIFIER_WARNING): Issue error message conditionally to
the flag_redundant variable.
(SET_TYPE_FOR_RESOLUTION): Consider Object being java.lang.Object
when parsing java.lang.Object class.
(BUILD_MONITOR_ENTER, BUILD_MONITOR_EXIT): Added terminal
NULL_TREE to build.
(resolve_qualified_expression_name): Fixed indentation.
(patch_array_ref): Changed prototype.
(not_initialized_as_it_should_p): Prototype removed.
(java_report_errors): Added function prototype.
* parse.y (formal_parameter:): Changed error message for not yet
supported final parameters.
(class_type_list:): Set both PURPOSE and VALUE of created
TREE_LIST to be class_type.
(primary_no_new_array:): Handle class literals on primitive types.
(parse_warning_context): Reinstalled correct force_error and
do_warning flags setups.
(java_report_errors): Changed prototype. Return java_error_count
value.
(variable_redefinition_error): Consider treating variable type as
a fake pointer.
(create_interface): Warn about redundant abstract modifier if
flag_redundant is set. Changed error message.
(lookup_field_wrapper): Save/restore globals before/after looking
up field.
(duplicate_declaration_error_p): Consider treating declaration
type as a fake pointer.
(register_fields): Extract real type from dependency node. Check
for duplicate field declaration after type adjustment. Use
DECL_INITIAL to store static final initialized values.
(method_header): Extract real function type from dependency node.
(check_abstract_method_header): Use GET_METHOD_NAME.
(obtain_incomplete_type): Layout fake pointer type.
(safe_layout_class): Don't try to check for methods before layout.
(java_complete_class): Don't check for correct throws clause
elements inheritance here.
(resolve_and_layout): Broadened name parameter meaning.
(reset_method_name): Use GET_METHOD_NAME.
(java_get_real_method_name): New function.
(java_check_regular_methods): Don't check methods in
java.lang.Object. Verify lineage of throws clause elements. Use
flag_no_overriding in warning report.
(check_throws_clauses): Don't check if class was from
bytecode. Use IS_UNCHECKED_EXCEPTION_P macro.
(java_check_methods): Don't set CLASS_METHOD_CHECKED_P flag.
(declare_local_variables): Use flag_static_local_jdk1_1 to report
warning on unsupported final local variables. Use build_decl
instead of build_decl_no_layout. Get real local variable type from
dependency node.
(source_start_java_method): Get real parameter type from
dependency node. Call build_decl instead of build_decl_no_layout.
(java_layout_classes): Reverse tree and layout type and class as
required. Mark class as loaded when done.
(resolve_field_access): Fixed indentation. Restricted condition
leading to static field access code generation. Set field_type
decl's TREE_TYPE if QUAL_DECL_TYPE not available.
(resolve_qualified_expression_name): Initialize type_found to
null. Handle static field resolved during qualification. Fixed
layout on non primitive field decl types.
(not_accessible_p): Fixed typo in comment.
(patch_method_invocation): Resolve and layout class to search from
type.
(lookup_method_invoke): Keep integer constant 0 as is. Resolve and
layout non primitive type, if necessary. Make method node only to
report errors.
(find_applicable_accessible_methods_list): Consider WFL'ed method
decl names. Fixed indentation.
(argument_types_convertible): Resolve and layout target type if
necessary.
(java_complete_tree): Fixed indentation problems. Rewrote
CALL_EXPR thrown exceptions check. Re-installed further processing
of the assignment in certain cases.
(patch_assignment): Call maybe_build_primttype_type_ref to perform
inlining on class literals.
(valid_builtin_assignconv_identity_widening_p): Cope with constant
0 literal.
(valid_method_invocation_conversion_p): Likewise.
(patch_string): Temporary disable forbidden use of `this' in
explicit constructor invocations when doing string concatenation
within their scope.
(patch_unaryop): Added comment. Reinstalled code to disable
further check on assignment operation with cast expression RHS.
(patch_switch_statement): Fixed indentation.
(build_try_statement): Call build_decl instead of
build_decl_no_layout.
(patch_synchronized_statement): Likewise.
(patch_throw_statement): Use IS_UNCHECKED_EXCEPTION_P instead of
IS_UNCHECKED_EXPRESSION_P.
(check_thrown_exceptions_do): Changed leading comment. Resolve and
layout argument exception type.
(purge_unchecked_exceptions): Use IS_UNCHECKED_EXCEPTION_P instead
of IS_UNCHECKED_EXPRESSION_P.
Sun Nov 15 17:14:17 1998 Per Bothner <bothner@cygnus.com> Sun Nov 15 17:14:17 1998 Per Bothner <bothner@cygnus.com>
* jvgenmain.c: Need to #include "gansidecl.h" (to get PROTO). * jvgenmain.c: Need to #include "gansidecl.h" (to get PROTO).
......
...@@ -138,7 +138,10 @@ tree ...@@ -138,7 +138,10 @@ tree
unmangle_classname (name, name_length) unmangle_classname (name, name_length)
const char *name; int name_length; const char *name; int name_length;
{ {
return ident_subst (name, name_length, "", '/', '.', ""); tree to_return = ident_subst (name, name_length, "", '/', '.', "");
if (to_return != get_identifier ((char *)name))
QUALIFIED_P (to_return) = 1;
return to_return;
} }
tree tree
...@@ -1375,6 +1378,10 @@ layout_class (this_class) ...@@ -1375,6 +1378,10 @@ layout_class (this_class)
char buf[8]; char buf[8];
char *asm_name; char *asm_name;
tree method_name = DECL_NAME (method_decl); tree method_name = DECL_NAME (method_decl);
int method_name_is_wfl =
(TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION);
if (method_name_is_wfl)
method_name = java_get_real_method_name (method_decl);
#if 1 #if 1
/* Remove this once we no longer need old (Kaffe / JDK 1.0) mangling. */ /* Remove this once we no longer need old (Kaffe / JDK 1.0) mangling. */
if (! flag_assume_compiled && METHOD_NATIVE (method_decl)) if (! flag_assume_compiled && METHOD_NATIVE (method_decl))
...@@ -1492,7 +1499,10 @@ layout_class (this_class) ...@@ -1492,7 +1499,10 @@ layout_class (this_class)
if (*ptr++ == '.') if (*ptr++ == '.')
p = ptr; p = ptr;
} }
DECL_NAME (method_decl) = get_identifier (p); if (method_name_is_wfl)
EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p);
else
DECL_NAME (method_decl) = get_identifier (p);
DECL_CONSTRUCTOR_P (method_decl) = 1; DECL_CONSTRUCTOR_P (method_decl) = 1;
} }
else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl)) else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl))
......
...@@ -247,6 +247,7 @@ tree current_function_decl; ...@@ -247,6 +247,7 @@ tree current_function_decl;
tree char_type_node; tree char_type_node;
tree object_type_node; tree object_type_node;
tree unqualified_object_id_node;
tree object_ptr_type_node; tree object_ptr_type_node;
tree string_type_node; tree string_type_node;
tree throwable_type_node; tree throwable_type_node;
...@@ -520,6 +521,7 @@ init_decl_processing () ...@@ -520,6 +521,7 @@ init_decl_processing ()
double_type_node)); double_type_node));
layout_type (double_type_node); layout_type (double_type_node);
unqualified_object_id_node = get_identifier ("Object");
object_type_node = lookup_class (get_identifier ("java.lang.Object")); object_type_node = lookup_class (get_identifier ("java.lang.Object"));
object_ptr_type_node = promote_type (object_type_node); object_ptr_type_node = promote_type (object_type_node);
string_type_node = lookup_class (get_identifier ("java.lang.String")); string_type_node = lookup_class (get_identifier ("java.lang.String"));
...@@ -1596,13 +1598,3 @@ end_java_method () ...@@ -1596,13 +1598,3 @@ end_java_method ()
current_function_decl = NULL_TREE; current_function_decl = NULL_TREE;
permanent_allocation (1); permanent_allocation (1);
} }
tree
build_decl_no_layout (code, name, type)
enum tree_code code;
tree name, type;
{
tree decl = build_decl (TYPE_DECL, name, type);
TREE_SET_CODE (decl, code);
return decl;
}
...@@ -1674,6 +1674,8 @@ build_primtype_type_ref (self_name) ...@@ -1674,6 +1674,8 @@ build_primtype_type_ref (self_name)
typ = long_type_node; typ = long_type_node;
else if (strncmp(class_name, "Float", 5) == 0) else if (strncmp(class_name, "Float", 5) == 0)
typ = float_type_node; typ = float_type_node;
else if (strncmp(class_name, "Double", 6) == 0)
typ = double_type_node;
else if (strncmp(class_name, "Boolean", 7) == 0) else if (strncmp(class_name, "Boolean", 7) == 0)
typ = boolean_type_node; typ = boolean_type_node;
else if (strncmp(class_name, "Char", 4) == 0) else if (strncmp(class_name, "Char", 4) == 0)
...@@ -1761,7 +1763,8 @@ java_lang_expand_expr (exp, target, tmode, modifier) ...@@ -1761,7 +1763,8 @@ java_lang_expand_expr (exp, target, tmode, modifier)
{ {
tree duplicate; tree duplicate;
if (pushcase (TREE_OPERAND (exp, 0), case_identity, if (pushcase (TREE_OPERAND (exp, 0), case_identity,
build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), &duplicate) == 2) build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
&duplicate) == 2)
{ {
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp); EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
parse_error_context parse_error_context
...@@ -1772,7 +1775,8 @@ java_lang_expand_expr (exp, target, tmode, modifier) ...@@ -1772,7 +1775,8 @@ java_lang_expand_expr (exp, target, tmode, modifier)
} }
case DEFAULT_EXPR: case DEFAULT_EXPR:
pushcase (NULL_TREE, 0, build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL); pushcase (NULL_TREE, 0,
build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
return const0_rtx; return const0_rtx;
case SWITCH_EXPR: case SWITCH_EXPR:
......
...@@ -58,7 +58,6 @@ struct JCF; ...@@ -58,7 +58,6 @@ struct JCF;
6: CAN_COMPLETE_NORMALLY (in statement nodes). 6: CAN_COMPLETE_NORMALLY (in statement nodes).
Usage of TYPE_LANG_FLAG_?: Usage of TYPE_LANG_FLAG_?:
0: CLASS_METHOD_CHECKED_P (in RECORD_TYPE)
1: TYPE_ARRAY_P (in RECORD_TYPE). 1: TYPE_ARRAY_P (in RECORD_TYPE).
2: CLASS_LOADED_P (in RECORD_TYPE). 2: CLASS_LOADED_P (in RECORD_TYPE).
3: CLASS_FROM_SOURCE_P (in RECORD_TYPE). 3: CLASS_FROM_SOURCE_P (in RECORD_TYPE).
...@@ -125,6 +124,12 @@ extern int flag_assume_compiled; ...@@ -125,6 +124,12 @@ extern int flag_assume_compiled;
extern int flag_emit_class_files; extern int flag_emit_class_files;
/* Turned to 1 if -Wall was encountered. See lang.c for their meanings. */
extern int flag_wall;
extern int flag_redundant;
extern int flag_not_overriding;
extern int flag_static_local_jdk1_1;
/* The Java .class file that provides main_class; the main input file. */ /* The Java .class file that provides main_class; the main input file. */
extern struct JCF main_jcf[1], *current_jcf; extern struct JCF main_jcf[1], *current_jcf;
...@@ -182,6 +187,7 @@ extern tree float_type_node; ...@@ -182,6 +187,7 @@ extern tree float_type_node;
extern tree double_type_node; extern tree double_type_node;
extern tree object_type_node; extern tree object_type_node;
extern tree unqualified_object_id_node;
extern tree object_ptr_type_node; extern tree object_ptr_type_node;
extern tree string_type_node; extern tree string_type_node;
extern tree throwable_type_node; extern tree throwable_type_node;
...@@ -518,7 +524,6 @@ extern tree build_field_ref PROTO ((tree, tree, tree)); ...@@ -518,7 +524,6 @@ extern tree build_field_ref PROTO ((tree, tree, tree));
extern void pushdecl_force_head PROTO ((tree)); extern void pushdecl_force_head PROTO ((tree));
extern tree build_java_binop PROTO ((enum tree_code, tree, tree, tree)); extern tree build_java_binop PROTO ((enum tree_code, tree, tree, tree));
extern tree binary_numeric_promotion PROTO ((tree, tree, tree *, tree *)); extern tree binary_numeric_promotion PROTO ((tree, tree, tree *, tree *));
extern tree build_decl_no_layout PROTO ((enum tree_code, tree, tree));
extern tree build_java_arrayaccess PROTO ((tree, tree, tree)); extern tree build_java_arrayaccess PROTO ((tree, tree, tree));
extern tree build_newarray PROTO ((int, tree)); extern tree build_newarray PROTO ((int, tree));
extern tree build_anewarray PROTO ((tree, tree)); extern tree build_anewarray PROTO ((tree, tree));
...@@ -548,6 +553,7 @@ extern void write_classfile PROTO ((tree)); ...@@ -548,6 +553,7 @@ extern void write_classfile PROTO ((tree));
extern char *print_int_node PROTO ((tree)); extern char *print_int_node PROTO ((tree));
extern void parse_error_context VPROTO ((tree cl, char *msg, ...)); extern void parse_error_context VPROTO ((tree cl, char *msg, ...));
extern tree build_primtype_type_ref PROTO ((char *)); extern tree build_primtype_type_ref PROTO ((char *));
extern tree java_get_real_method_name PROTO ((tree));
/* Access flags etc for a method (a FUNCTION_DECL): */ /* Access flags etc for a method (a FUNCTION_DECL): */
...@@ -679,9 +685,6 @@ extern tree *type_map; ...@@ -679,9 +685,6 @@ extern tree *type_map;
/* FIXME this use of TREE_TYPE conflicts with something or other. */ /* FIXME this use of TREE_TYPE conflicts with something or other. */
#define TYPE_ARRAY_ELEMENT(ATYPE) TREE_TYPE(ATYPE) #define TYPE_ARRAY_ELEMENT(ATYPE) TREE_TYPE(ATYPE)
/* True if methods in class TYPE have been checked. */
#define CLASS_METHOD_CHECKED_P(TYPE) TYPE_LANG_FLAG_0 (TYPE)
/* True if class TYPE has been loaded. */ /* True if class TYPE has been loaded. */
#define CLASS_LOADED_P(TYPE) TYPE_LANG_FLAG_2 (TYPE) #define CLASS_LOADED_P(TYPE) TYPE_LANG_FLAG_2 (TYPE)
...@@ -819,8 +822,8 @@ extern tree *type_map; ...@@ -819,8 +822,8 @@ extern tree *type_map;
/* Using a CATCH_EXPR node */ /* Using a CATCH_EXPR node */
#define CATCH_EXPR_GET_EXPR(NODE, V) (V ? LABELED_BLOCK_BODY (NODE) : (NODE)) #define CATCH_EXPR_GET_EXPR(NODE, V) (V ? LABELED_BLOCK_BODY (NODE) : (NODE))
/* Non zero if TYPE is an unchecked expression */ /* Non zero if TYPE is an unchecked exception */
#define IS_UNCHECKED_EXPRESSION_P(TYPE) \ #define IS_UNCHECKED_EXCEPTION_P(TYPE) \
(inherits_from_p ((TYPE), runtime_exception_type_node) \ (inherits_from_p ((TYPE), runtime_exception_type_node) \
|| inherits_from_p ((TYPE), error_exception_type_node)) || inherits_from_p ((TYPE), error_exception_type_node))
...@@ -830,8 +833,5 @@ extern tree *type_map; ...@@ -830,8 +833,5 @@ extern tree *type_map;
{ \ { \
extern int java_error_count; \ extern int java_error_count; \
if (java_error_count) \ if (java_error_count) \
{ \ return; \
java_report_errors (); \
return; \
} \
} }
...@@ -271,12 +271,10 @@ get_constant (jcf, index) ...@@ -271,12 +271,10 @@ get_constant (jcf, index)
#ifdef REAL_ARITHMETIC #ifdef REAL_ARITHMETIC
d = REAL_VALUE_FROM_TARGET_DOUBLE (num); d = REAL_VALUE_FROM_TARGET_DOUBLE (num);
#else #else
{ union { double d; jint i[2]; } u;
union { double d; jint i[2]; } u; u.i[0] = (jint) num[0];
u.i[0] = (jint) num[0]; u.i[1] = (jint) num[1];
u.i[1] = (jint) num[1]; d = u.d;
d = u.d;
}
#endif #endif
value = build_real (double_type_node, d); value = build_real (double_type_node, d);
break; break;
...@@ -529,6 +527,9 @@ jcf_parse_source (jcf) ...@@ -529,6 +527,9 @@ jcf_parse_source (jcf)
fatal ("input file `%s' just disappeared - jcf_parse_source", fatal ("input file `%s' just disappeared - jcf_parse_source",
input_filename); input_filename);
parse_source_file (file); parse_source_file (file);
if (fclose (finput))
fatal ("can't close input file `%s' stream - jcf_parse_source",
input_filename);
java_pop_parser_context (IS_A_COMMAND_LINE_FILENAME_P (file)); java_pop_parser_context (IS_A_COMMAND_LINE_FILENAME_P (file));
java_parser_context_restore_global (); java_parser_context_restore_global ();
} }
...@@ -782,8 +783,13 @@ yyparse () ...@@ -782,8 +783,13 @@ yyparse ()
break; break;
} }
} }
if (main_jcf->read_state && fclose (main_jcf->read_state))
fatal ("failed to close input file `%s' - yyparse",
(main_jcf->filename ? main_jcf->filename : "<unknown>"));
java_expand_classes (); java_expand_classes ();
if (! flag_emit_class_files) if (!java_report_errors () && !flag_emit_class_files)
emit_register_classes (); emit_register_classes ();
return 0; return 0;
} }
......
...@@ -87,7 +87,19 @@ int flag_assume_compiled = 1; ...@@ -87,7 +87,19 @@ int flag_assume_compiled = 1;
int flag_emit_class_files = 0; int flag_emit_class_files = 0;
/* From gcc/flags.h, and idicates if exceptions are turned on or not. */ /* When non zero, -Wall was turned on. */
int flag_wall = 0;
/* When non zero, check for redundant modifier uses. */
int flag_redundant = 0;
/* When non zero, warns about overridings that don't occur. */
int flag_not_overriding = 0;
/* When non zero, warns that final local are treated as non final. */
int flag_static_local_jdk1_1 = 0;
/* From gcc/flags.h, and indicates if exceptions are turned on or not. */
extern int flag_new_exceptions; extern int flag_new_exceptions;
extern int flag_exceptions; extern int flag_exceptions;
...@@ -187,6 +199,14 @@ lang_decode_option (argc, argv) ...@@ -187,6 +199,14 @@ lang_decode_option (argc, argv)
return found; return found;
} }
if (strcmp (p, "-Wall") == 0)
{
flag_wall = 1;
flag_redundant = 1;
flag_not_overriding = 1;
flag_static_local_jdk1_1 = 1;
}
if (strcmp (p, "-MD") == 0) if (strcmp (p, "-MD") == 0)
{ {
jcf_dependency_init (1); jcf_dependency_init (1);
......
...@@ -525,24 +525,24 @@ static const short yyrline[] = { 0, ...@@ -525,24 +525,24 @@ static const short yyrline[] = { 0,
1324, 1326, 1332, 1338, 1342, 1344, 1348, 1351, 1353, 1357, 1324, 1326, 1332, 1338, 1342, 1344, 1348, 1351, 1353, 1357,
1360, 1362, 1364, 1368, 1371, 1373, 1375, 1379, 1382, 1384, 1360, 1362, 1364, 1368, 1371, 1373, 1375, 1379, 1382, 1384,
1386, 1390, 1396, 1398, 1402, 1409, 1411, 1413, 1415, 1419, 1386, 1390, 1396, 1398, 1402, 1409, 1411, 1413, 1415, 1419,
1427, 1430, 1432, 1434, 1438, 1440, 1447, 1455, 1473, 1475, 1427, 1430, 1432, 1434, 1438, 1440, 1447, 1455, 1472, 1474,
1477, 1481, 1487, 1492, 1494, 1497, 1499, 1501, 1503, 1504, 1476, 1480, 1486, 1491, 1493, 1496, 1498, 1500, 1502, 1503,
1505, 1506, 1510, 1512, 1514, 1519, 1521, 1523, 1525, 1527, 1504, 1505, 1509, 1511, 1513, 1518, 1520, 1522, 1524, 1526,
1531, 1534, 1539, 1541, 1546, 1547, 1548, 1549, 1550, 1552, 1530, 1533, 1538, 1540, 1545, 1546, 1547, 1548, 1549, 1551,
1554, 1556, 1558, 1560, 1564, 1566, 1569, 1575, 1580, 1584, 1553, 1555, 1557, 1559, 1563, 1565, 1568, 1574, 1579, 1583,
1587, 1589, 1591, 1595, 1597, 1599, 1601, 1605, 1608, 1612, 1586, 1588, 1590, 1594, 1596, 1598, 1600, 1604, 1607, 1611,
1618, 1620, 1628, 1631, 1633, 1637, 1640, 1648, 1652, 1655, 1617, 1619, 1627, 1630, 1632, 1636, 1641, 1649, 1653, 1656,
1657, 1668, 1679, 1684, 1693, 1695, 1699, 1702, 1704, 1709, 1658, 1669, 1680, 1685, 1694, 1696, 1700, 1703, 1705, 1710,
1714, 1719, 1726, 1728, 1729, 1730, 1733, 1738, 1743, 1745, 1715, 1720, 1727, 1729, 1730, 1731, 1734, 1739, 1744, 1746,
1746, 1748, 1750, 1751, 1753, 1757, 1760, 1764, 1767, 1771, 1747, 1749, 1751, 1752, 1754, 1758, 1761, 1765, 1768, 1772,
1773, 1775, 1777, 1778, 1780, 1784, 1792, 1794, 1796, 1808, 1774, 1776, 1778, 1779, 1781, 1785, 1793, 1795, 1797, 1809,
1810, 1816, 1818, 1820, 1824, 1826, 1831, 1836, 1841, 1843, 1811, 1817, 1819, 1821, 1825, 1827, 1832, 1837, 1842, 1844,
1845, 1849, 1851, 1856, 1861, 1863, 1867, 1869, 1874, 1879, 1846, 1850, 1852, 1857, 1862, 1864, 1868, 1870, 1875, 1880,
1884, 1886, 1888, 1892, 1894, 1899, 1904, 1909, 1914, 1916, 1885, 1887, 1889, 1893, 1895, 1900, 1905, 1910, 1915, 1917,
1918, 1920, 1922, 1924, 1928, 1930, 1935, 1940, 1942, 1946, 1919, 1921, 1923, 1925, 1929, 1931, 1936, 1941, 1943, 1947,
1948, 1953, 1957, 1959, 1964, 1968, 1970, 1975, 1979, 1981, 1949, 1954, 1958, 1960, 1965, 1969, 1971, 1976, 1980, 1982,
1986, 1990, 1992, 1997, 2001, 2003, 2008, 2014, 2016, 2020, 1987, 1991, 1993, 1998, 2002, 2004, 2009, 2015, 2017, 2021,
2022, 2025, 2028, 2036, 2038, 2039, 2042, 2044, 2047, 2051 2023, 2026, 2029, 2037, 2039, 2040, 2043, 2045, 2048, 2052
}; };
#endif #endif
...@@ -2985,7 +2985,7 @@ case 123: ...@@ -2985,7 +2985,7 @@ case 123:
break;} break;}
case 124: case 124:
#line 705 "./parse.y" #line 705 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("final local"); ; { yyval.node = parse_jdk1_1_error ("final parameters"); ;
break;} break;}
case 125: case 125:
#line 707 "./parse.y" #line 707 "./parse.y"
...@@ -3012,11 +3012,11 @@ case 129: ...@@ -3012,11 +3012,11 @@ case 129:
break;} break;}
case 130: case 130:
#line 725 "./parse.y" #line 725 "./parse.y"
{ yyval.node = build_tree_list (NULL_TREE, yyvsp[0].node); ; { yyval.node = build_tree_list (yyvsp[0].node, yyvsp[0].node); ;
break;} break;}
case 131: case 131:
#line 727 "./parse.y" #line 727 "./parse.y"
{ yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyvsp[-2].node); ; { yyval.node = tree_cons (yyvsp[0].node, yyvsp[0].node, yyvsp[-2].node); ;
break;} break;}
case 132: case 132:
#line 729 "./parse.y" #line 729 "./parse.y"
...@@ -3074,7 +3074,7 @@ case 144: ...@@ -3074,7 +3074,7 @@ case 144:
case 145: case 145:
#line 788 "./parse.y" #line 788 "./parse.y"
{ {
BLOCK_EXPR_BODY (yyvsp[0].node) = size_zero_node; BLOCK_EXPR_BODY (yyvsp[0].node) = empty_stmt_node;
yyval.node = yyvsp[0].node; yyval.node = yyvsp[0].node;
; ;
break;} break;}
...@@ -3259,7 +3259,7 @@ case 186: ...@@ -3259,7 +3259,7 @@ case 186:
break;} break;}
case 187: case 187:
#line 954 "./parse.y" #line 954 "./parse.y"
{ yyval.node = size_zero_node; ; { yyval.node = empty_stmt_node; ;
break;} break;}
case 188: case 188:
#line 956 "./parse.y" #line 956 "./parse.y"
...@@ -3304,7 +3304,7 @@ case 204: ...@@ -3304,7 +3304,7 @@ case 204:
break;} break;}
case 221: case 221:
#line 1036 "./parse.y" #line 1036 "./parse.y"
{ yyval.node = size_zero_node; ; { yyval.node = empty_stmt_node; ;
break;} break;}
case 222: case 222:
#line 1041 "./parse.y" #line 1041 "./parse.y"
...@@ -3550,7 +3550,7 @@ case 281: ...@@ -3550,7 +3550,7 @@ case 281:
yyval.node = complete_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node); yyval.node = complete_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
/* We have not condition, so we get rid of the EXIT_EXPR */ /* We have not condition, so we get rid of the EXIT_EXPR */
LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY (yyval.node), 0) = LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY (yyval.node), 0) =
size_zero_node; empty_stmt_node;
; ;
break;} break;}
case 282: case 282:
...@@ -3575,7 +3575,7 @@ case 286: ...@@ -3575,7 +3575,7 @@ case 286:
yyval.node = complete_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node); yyval.node = complete_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
/* We have not condition, so we get rid of the EXIT_EXPR */ /* We have not condition, so we get rid of the EXIT_EXPR */
LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY (yyval.node), 0) = LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY (yyval.node), 0) =
size_zero_node; empty_stmt_node;
; ;
break;} break;}
case 287: case 287:
...@@ -3609,7 +3609,7 @@ case 290: ...@@ -3609,7 +3609,7 @@ case 290:
break;} break;}
case 291: case 291:
#line 1325 "./parse.y" #line 1325 "./parse.y"
{ yyval.node = size_zero_node; ; { yyval.node = empty_stmt_node; ;
break;} break;}
case 292: case 292:
#line 1327 "./parse.y" #line 1327 "./parse.y"
...@@ -3633,7 +3633,7 @@ case 294: ...@@ -3633,7 +3633,7 @@ case 294:
break;} break;}
case 295: case 295:
#line 1343 "./parse.y" #line 1343 "./parse.y"
{yyval.node = size_zero_node;; {yyval.node = empty_stmt_node;;
break;} break;}
case 296: case 296:
#line 1345 "./parse.y" #line 1345 "./parse.y"
...@@ -3784,10 +3784,9 @@ case 328: ...@@ -3784,10 +3784,9 @@ case 328:
declared initialized by the appropriate function declared initialized by the appropriate function
call */ call */
tree ccpb = enter_block (); tree ccpb = enter_block ();
tree init = /* flag_emit_class_files ? NULL_TREE tree init = build_assignment (ASSIGN_TK, yyvsp[-2].operator.location,
: */ build_assignment (ASSIGN_TK, yyvsp[-2].operator.location, TREE_PURPOSE (yyvsp[-1].node),
TREE_PURPOSE (yyvsp[-1].node), soft_exceptioninfo_call_node);
soft_exceptioninfo_call_node);
declare_local_variables (0, TREE_VALUE (yyvsp[-1].node), declare_local_variables (0, TREE_VALUE (yyvsp[-1].node),
build_tree_list (TREE_PURPOSE (yyvsp[-1].node), build_tree_list (TREE_PURPOSE (yyvsp[-1].node),
init)); init));
...@@ -3796,179 +3795,179 @@ case 328: ...@@ -3796,179 +3795,179 @@ case 328:
; ;
break;} break;}
case 329: case 329:
#line 1474 "./parse.y" #line 1473 "./parse.y"
{yyerror ("'(' expected"); RECOVER;; {yyerror ("'(' expected"); RECOVER;;
break;} break;}
case 330: case 330:
#line 1476 "./parse.y" #line 1475 "./parse.y"
{yyerror ("Missing term or ')' expected"); DRECOVER (2);; {yyerror ("Missing term or ')' expected"); DRECOVER (2);;
break;} break;}
case 331: case 331:
#line 1478 "./parse.y" #line 1477 "./parse.y"
{yyerror ("')' expected"); DRECOVER (1);; {yyerror ("')' expected"); DRECOVER (1);;
break;} break;}
case 332: case 332:
#line 1483 "./parse.y" #line 1482 "./parse.y"
{ {
yyval.node = build (FINALLY_EXPR, NULL_TREE, yyval.node = build (FINALLY_EXPR, NULL_TREE,
create_label_decl (generate_name ()), yyvsp[0].node); create_label_decl (generate_name ()), yyvsp[0].node);
; ;
break;} break;}
case 333: case 333:
#line 1488 "./parse.y" #line 1487 "./parse.y"
{yyerror ("'{' expected"); RECOVER; ; {yyerror ("'{' expected"); RECOVER; ;
break;} break;}
case 337: case 337:
#line 1500 "./parse.y" #line 1499 "./parse.y"
{ yyval.node = build_this (yyvsp[0].operator.location); ; { yyval.node = build_this (yyvsp[0].operator.location); ;
break;} break;}
case 338: case 338:
#line 1502 "./parse.y" #line 1501 "./parse.y"
{yyval.node = yyvsp[-1].node;; {yyval.node = yyvsp[-1].node;;
break;} break;}
case 343: case 343:
#line 1511 "./parse.y" #line 1510 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("class literals"); ; { yyval.node = parse_jdk1_1_error ("named class literals"); ;
break;} break;}
case 344: case 344:
#line 1513 "./parse.y" #line 1512 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("class literals"); ; { yyval.node = build_class_ref (yyvsp[-2].node); ;
break;} break;}
case 345: case 345:
#line 1515 "./parse.y" #line 1514 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("class literals"); ; { yyval.node = build_class_ref (void_type_node); ;
break;} break;}
case 346: case 346:
#line 1520 "./parse.y" #line 1519 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("class literals"); ; { yyval.node = parse_jdk1_1_error ("class literals"); ;
break;} break;}
case 347: case 347:
#line 1522 "./parse.y" #line 1521 "./parse.y"
{yyerror ("')' expected"); RECOVER;; {yyerror ("')' expected"); RECOVER;;
break;} break;}
case 348: case 348:
#line 1524 "./parse.y" #line 1523 "./parse.y"
{yyerror ("'class' or 'this' expected" ); RECOVER;; {yyerror ("'class' or 'this' expected" ); RECOVER;;
break;} break;}
case 349: case 349:
#line 1526 "./parse.y" #line 1525 "./parse.y"
{yyerror ("'class' expected" ); RECOVER;; {yyerror ("'class' expected" ); RECOVER;;
break;} break;}
case 350: case 350:
#line 1528 "./parse.y" #line 1527 "./parse.y"
{yyerror ("'class' expected" ); RECOVER;; {yyerror ("'class' expected" ); RECOVER;;
break;} break;}
case 351: case 351:
#line 1533 "./parse.y" #line 1532 "./parse.y"
{ yyval.node = build_new_invocation (yyvsp[-3].node, yyvsp[-1].node); ; { yyval.node = build_new_invocation (yyvsp[-3].node, yyvsp[-1].node); ;
break;} break;}
case 352: case 352:
#line 1535 "./parse.y" #line 1534 "./parse.y"
{ yyval.node = build_new_invocation (yyvsp[-2].node, NULL_TREE); ; { yyval.node = build_new_invocation (yyvsp[-2].node, NULL_TREE); ;
break;} break;}
case 353: case 353:
#line 1540 "./parse.y" #line 1539 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("inner class instance creation"); ; { yyval.node = parse_jdk1_1_error ("inner class instance creation"); ;
break;} break;}
case 354: case 354:
#line 1542 "./parse.y" #line 1541 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("inner class instance creation"); ; { yyval.node = parse_jdk1_1_error ("inner class instance creation"); ;
break;} break;}
case 359: case 359:
#line 1551 "./parse.y" #line 1550 "./parse.y"
{yyerror ("'(' expected"); DRECOVER(new_1);; {yyerror ("'(' expected"); DRECOVER(new_1);;
break;} break;}
case 360: case 360:
#line 1553 "./parse.y" #line 1552 "./parse.y"
{yyerror ("'(' expected"); RECOVER;; {yyerror ("'(' expected"); RECOVER;;
break;} break;}
case 361: case 361:
#line 1555 "./parse.y" #line 1554 "./parse.y"
{yyerror ("')' or term expected"); RECOVER;; {yyerror ("')' or term expected"); RECOVER;;
break;} break;}
case 362: case 362:
#line 1557 "./parse.y" #line 1556 "./parse.y"
{yyerror ("')' expected"); RECOVER;; {yyerror ("')' expected"); RECOVER;;
break;} break;}
case 363: case 363:
#line 1559 "./parse.y" #line 1558 "./parse.y"
{YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;; {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;;
break;} break;}
case 364: case 364:
#line 1561 "./parse.y" #line 1560 "./parse.y"
{yyerror ("'(' expected"); RECOVER;; {yyerror ("'(' expected"); RECOVER;;
break;} break;}
case 367: case 367:
#line 1571 "./parse.y" #line 1570 "./parse.y"
{ {
yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, NULL_TREE); yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, NULL_TREE);
ctxp->formal_parameter_number = 1; ctxp->formal_parameter_number = 1;
; ;
break;} break;}
case 368: case 368:
#line 1576 "./parse.y" #line 1575 "./parse.y"
{ {
ctxp->formal_parameter_number += 1; ctxp->formal_parameter_number += 1;
yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyvsp[-2].node); yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyvsp[-2].node);
; ;
break;} break;}
case 369: case 369:
#line 1581 "./parse.y" #line 1580 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 370: case 370:
#line 1586 "./parse.y" #line 1585 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ; { yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ;
break;} break;}
case 371: case 371:
#line 1588 "./parse.y" #line 1587 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ; { yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ;
break;} break;}
case 372: case 372:
#line 1590 "./parse.y" #line 1589 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, ctxp->osb_number); ; { yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, ctxp->osb_number); ;
break;} break;}
case 373: case 373:
#line 1592 "./parse.y" #line 1591 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, ctxp->osb_number); ; { yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, ctxp->osb_number); ;
break;} break;}
case 374: case 374:
#line 1596 "./parse.y" #line 1595 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("anonymous array"); ; { yyval.node = parse_jdk1_1_error ("anonymous array"); ;
break;} break;}
case 375: case 375:
#line 1598 "./parse.y" #line 1597 "./parse.y"
{ yyval.node = parse_jdk1_1_error ("anonymous array"); ; { yyval.node = parse_jdk1_1_error ("anonymous array"); ;
break;} break;}
case 376: case 376:
#line 1600 "./parse.y" #line 1599 "./parse.y"
{yyerror ("'[' expected"); DRECOVER ("]");; {yyerror ("'[' expected"); DRECOVER ("]");;
break;} break;}
case 377: case 377:
#line 1602 "./parse.y" #line 1601 "./parse.y"
{yyerror ("']' expected"); RECOVER;; {yyerror ("']' expected"); RECOVER;;
break;} break;}
case 378: case 378:
#line 1607 "./parse.y" #line 1606 "./parse.y"
{ yyval.node = build_tree_list (NULL_TREE, yyvsp[0].node); ; { yyval.node = build_tree_list (NULL_TREE, yyvsp[0].node); ;
break;} break;}
case 379: case 379:
#line 1609 "./parse.y" #line 1608 "./parse.y"
{ yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyval.node); ; { yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyval.node); ;
break;} break;}
case 380: case 380:
#line 1614 "./parse.y" #line 1613 "./parse.y"
{ {
EXPR_WFL_LINECOL (yyvsp[-1].node) = yyvsp[-2].operator.location; EXPR_WFL_LINECOL (yyvsp[-1].node) = yyvsp[-2].operator.location;
yyval.node = yyvsp[-1].node; yyval.node = yyvsp[-1].node;
; ;
break;} break;}
case 381: case 381:
#line 1619 "./parse.y" #line 1618 "./parse.y"
{yyerror ("']' expected"); RECOVER;; {yyerror ("']' expected"); RECOVER;;
break;} break;}
case 382: case 382:
#line 1621 "./parse.y" #line 1620 "./parse.y"
{ {
yyerror ("Missing term"); yyerror ("Missing term");
yyerror ("']' expected"); yyerror ("']' expected");
...@@ -3976,23 +3975,23 @@ case 382: ...@@ -3976,23 +3975,23 @@ case 382:
; ;
break;} break;}
case 383: case 383:
#line 1630 "./parse.y" #line 1629 "./parse.y"
{ ctxp->osb_number = 1; ; { ctxp->osb_number = 1; ;
break;} break;}
case 384: case 384:
#line 1632 "./parse.y" #line 1631 "./parse.y"
{ ctxp->osb_number++; ; { ctxp->osb_number++; ;
break;} break;}
case 385: case 385:
#line 1634 "./parse.y" #line 1633 "./parse.y"
{ yyerror ("']' expected"); RECOVER;; { yyerror ("']' expected"); RECOVER;;
break;} break;}
case 386: case 386:
#line 1639 "./parse.y" #line 1638 "./parse.y"
{ yyval.node = make_qualified_primary (yyvsp[-2].node, yyvsp[0].node, yyvsp[-1].operator.location); ; { yyval.node = make_qualified_primary (yyvsp[-2].node, yyvsp[0].node, yyvsp[-1].operator.location); ;
break;} break;}
case 387: case 387:
#line 1641 "./parse.y" #line 1642 "./parse.y"
{ {
tree super_wfl = tree super_wfl =
build_wfl_node (super_identifier_node, build_wfl_node (super_identifier_node,
...@@ -4002,19 +4001,19 @@ case 387: ...@@ -4002,19 +4001,19 @@ case 387:
; ;
break;} break;}
case 388: case 388:
#line 1649 "./parse.y" #line 1650 "./parse.y"
{yyerror ("Field expected"); DRECOVER (super_field_acces);; {yyerror ("Field expected"); DRECOVER (super_field_acces);;
break;} break;}
case 389: case 389:
#line 1654 "./parse.y" #line 1655 "./parse.y"
{ yyval.node = build_method_invocation (yyvsp[-2].node, NULL_TREE); ; { yyval.node = build_method_invocation (yyvsp[-2].node, NULL_TREE); ;
break;} break;}
case 390: case 390:
#line 1656 "./parse.y" #line 1657 "./parse.y"
{ yyval.node = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node); ; { yyval.node = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node); ;
break;} break;}
case 391: case 391:
#line 1658 "./parse.y" #line 1659 "./parse.y"
{ {
if (TREE_CODE (yyvsp[-4].node) == THIS_EXPR) if (TREE_CODE (yyvsp[-4].node) == THIS_EXPR)
yyval.node = build_this_super_qualified_invocation yyval.node = build_this_super_qualified_invocation
...@@ -4027,7 +4026,7 @@ case 391: ...@@ -4027,7 +4026,7 @@ case 391:
; ;
break;} break;}
case 392: case 392:
#line 1669 "./parse.y" #line 1670 "./parse.y"
{ {
if (TREE_CODE (yyvsp[-5].node) == THIS_EXPR) if (TREE_CODE (yyvsp[-5].node) == THIS_EXPR)
yyval.node = build_this_super_qualified_invocation yyval.node = build_this_super_qualified_invocation
...@@ -4040,121 +4039,121 @@ case 392: ...@@ -4040,121 +4039,121 @@ case 392:
; ;
break;} break;}
case 393: case 393:
#line 1680 "./parse.y" #line 1681 "./parse.y"
{ {
yyval.node = build_this_super_qualified_invocation yyval.node = build_this_super_qualified_invocation
(0, yyvsp[-2].node, NULL_TREE, yyvsp[-4].operator.location, yyvsp[-3].operator.location); (0, yyvsp[-2].node, NULL_TREE, yyvsp[-4].operator.location, yyvsp[-3].operator.location);
; ;
break;} break;}
case 394: case 394:
#line 1685 "./parse.y" #line 1686 "./parse.y"
{ {
yyval.node = build_this_super_qualified_invocation yyval.node = build_this_super_qualified_invocation
(0, yyvsp[-3].node, yyvsp[-1].node, yyvsp[-5].operator.location, yyvsp[-4].operator.location); (0, yyvsp[-3].node, yyvsp[-1].node, yyvsp[-5].operator.location, yyvsp[-4].operator.location);
; ;
break;} break;}
case 395: case 395:
#line 1694 "./parse.y" #line 1695 "./parse.y"
{ yyerror ("'(' expected"); DRECOVER (method_invocation); ; { yyerror ("'(' expected"); DRECOVER (method_invocation); ;
break;} break;}
case 396: case 396:
#line 1696 "./parse.y" #line 1697 "./parse.y"
{ yyerror ("'(' expected"); DRECOVER (method_invocation); ; { yyerror ("'(' expected"); DRECOVER (method_invocation); ;
break;} break;}
case 397: case 397:
#line 1701 "./parse.y" #line 1702 "./parse.y"
{ yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ; { yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ;
break;} break;}
case 398: case 398:
#line 1703 "./parse.y" #line 1704 "./parse.y"
{ yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ; { yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ;
break;} break;}
case 399: case 399:
#line 1705 "./parse.y" #line 1706 "./parse.y"
{ {
yyerror ("Missing term and ']' expected"); yyerror ("Missing term and ']' expected");
DRECOVER(array_access); DRECOVER(array_access);
; ;
break;} break;}
case 400: case 400:
#line 1710 "./parse.y" #line 1711 "./parse.y"
{ {
yyerror ("']' expected"); yyerror ("']' expected");
DRECOVER(array_access); DRECOVER(array_access);
; ;
break;} break;}
case 401: case 401:
#line 1715 "./parse.y" #line 1716 "./parse.y"
{ {
yyerror ("Missing term and ']' expected"); yyerror ("Missing term and ']' expected");
DRECOVER(array_access); DRECOVER(array_access);
; ;
break;} break;}
case 402: case 402:
#line 1720 "./parse.y" #line 1721 "./parse.y"
{ {
yyerror ("']' expected"); yyerror ("']' expected");
DRECOVER(array_access); DRECOVER(array_access);
; ;
break;} break;}
case 407: case 407:
#line 1735 "./parse.y" #line 1736 "./parse.y"
{ yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ; { yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ;
break;} break;}
case 408: case 408:
#line 1740 "./parse.y" #line 1741 "./parse.y"
{ yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ; { yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ;
break;} break;}
case 411: case 411:
#line 1747 "./parse.y" #line 1748 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ; {yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;} break;}
case 412: case 412:
#line 1749 "./parse.y" #line 1750 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ; {yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;} break;}
case 414: case 414:
#line 1752 "./parse.y" #line 1753 "./parse.y"
{yyerror ("Missing term"); RECOVER; {yyerror ("Missing term"); RECOVER;
break;} break;}
case 415: case 415:
#line 1754 "./parse.y" #line 1755 "./parse.y"
{yyerror ("Missing term"); RECOVER; {yyerror ("Missing term"); RECOVER;
break;} break;}
case 416: case 416:
#line 1759 "./parse.y" #line 1760 "./parse.y"
{yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ; {yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ;
break;} break;}
case 417: case 417:
#line 1761 "./parse.y" #line 1762 "./parse.y"
{yyerror ("Missing term"); RECOVER; {yyerror ("Missing term"); RECOVER;
break;} break;}
case 418: case 418:
#line 1766 "./parse.y" #line 1767 "./parse.y"
{yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ; {yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ;
break;} break;}
case 419: case 419:
#line 1768 "./parse.y" #line 1769 "./parse.y"
{yyerror ("Missing term"); RECOVER; {yyerror ("Missing term"); RECOVER;
break;} break;}
case 421: case 421:
#line 1774 "./parse.y" #line 1775 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ; {yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;} break;}
case 422: case 422:
#line 1776 "./parse.y" #line 1777 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ; {yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;} break;}
case 424: case 424:
#line 1779 "./parse.y" #line 1780 "./parse.y"
{yyerror ("Missing term"); RECOVER; {yyerror ("Missing term"); RECOVER;
break;} break;}
case 425: case 425:
#line 1781 "./parse.y" #line 1782 "./parse.y"
{yyerror ("Missing term"); RECOVER; {yyerror ("Missing term"); RECOVER;
break;} break;}
case 426: case 426:
#line 1786 "./parse.y" #line 1787 "./parse.y"
{ {
tree type = yyvsp[-3].node; tree type = yyvsp[-3].node;
while (ctxp->osb_number--) while (ctxp->osb_number--)
...@@ -4163,15 +4162,15 @@ case 426: ...@@ -4163,15 +4162,15 @@ case 426:
; ;
break;} break;}
case 427: case 427:
#line 1793 "./parse.y" #line 1794 "./parse.y"
{ yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ; { yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;} break;}
case 428: case 428:
#line 1795 "./parse.y" #line 1796 "./parse.y"
{ yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ; { yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;} break;}
case 429: case 429:
#line 1797 "./parse.y" #line 1798 "./parse.y"
{ {
char *ptr; char *ptr;
while (ctxp->osb_number--) while (ctxp->osb_number--)
...@@ -4185,11 +4184,11 @@ case 429: ...@@ -4185,11 +4184,11 @@ case 429:
; ;
break;} break;}
case 430: case 430:
#line 1809 "./parse.y" #line 1810 "./parse.y"
{yyerror ("']' expected, invalid type expression");; {yyerror ("']' expected, invalid type expression");;
break;} break;}
case 431: case 431:
#line 1811 "./parse.y" #line 1812 "./parse.y"
{ {
if (ctxp->prevent_ese != lineno) if (ctxp->prevent_ese != lineno)
yyerror ("Invalid type expression"); RECOVER; yyerror ("Invalid type expression"); RECOVER;
...@@ -4197,243 +4196,243 @@ case 431: ...@@ -4197,243 +4196,243 @@ case 431:
; ;
break;} break;}
case 432: case 432:
#line 1817 "./parse.y" #line 1818 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 433: case 433:
#line 1819 "./parse.y" #line 1820 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 434: case 434:
#line 1821 "./parse.y" #line 1822 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 436: case 436:
#line 1827 "./parse.y" #line 1828 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token),
yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 437: case 437:
#line 1832 "./parse.y" #line 1833 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 438: case 438:
#line 1837 "./parse.y" #line 1838 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 439: case 439:
#line 1842 "./parse.y" #line 1843 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 440: case 440:
#line 1844 "./parse.y" #line 1845 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 441: case 441:
#line 1846 "./parse.y" #line 1847 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 443: case 443:
#line 1852 "./parse.y" #line 1853 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 444: case 444:
#line 1857 "./parse.y" #line 1858 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 445: case 445:
#line 1862 "./parse.y" #line 1863 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 446: case 446:
#line 1864 "./parse.y" #line 1865 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 448: case 448:
#line 1870 "./parse.y" #line 1871 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 449: case 449:
#line 1875 "./parse.y" #line 1876 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 450: case 450:
#line 1880 "./parse.y" #line 1881 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 451: case 451:
#line 1885 "./parse.y" #line 1886 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 452: case 452:
#line 1887 "./parse.y" #line 1888 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 453: case 453:
#line 1889 "./parse.y" #line 1890 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 455: case 455:
#line 1895 "./parse.y" #line 1896 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 456: case 456:
#line 1900 "./parse.y" #line 1901 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 457: case 457:
#line 1905 "./parse.y" #line 1906 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 458: case 458:
#line 1910 "./parse.y" #line 1911 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 459: case 459:
#line 1915 "./parse.y" #line 1916 "./parse.y"
{ yyval.node = build_binop (INSTANCEOF_EXPR, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ; { yyval.node = build_binop (INSTANCEOF_EXPR, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;} break;}
case 460: case 460:
#line 1917 "./parse.y" #line 1918 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 461: case 461:
#line 1919 "./parse.y" #line 1920 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 462: case 462:
#line 1921 "./parse.y" #line 1922 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 463: case 463:
#line 1923 "./parse.y" #line 1924 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 464: case 464:
#line 1925 "./parse.y" #line 1926 "./parse.y"
{yyerror ("Invalid reference type"); RECOVER;; {yyerror ("Invalid reference type"); RECOVER;;
break;} break;}
case 466: case 466:
#line 1931 "./parse.y" #line 1932 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 467: case 467:
#line 1936 "./parse.y" #line 1937 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 468: case 468:
#line 1941 "./parse.y" #line 1942 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 469: case 469:
#line 1943 "./parse.y" #line 1944 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 471: case 471:
#line 1949 "./parse.y" #line 1950 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 472: case 472:
#line 1954 "./parse.y" #line 1955 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 474: case 474:
#line 1960 "./parse.y" #line 1961 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 475: case 475:
#line 1965 "./parse.y" #line 1966 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 477: case 477:
#line 1971 "./parse.y" #line 1972 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 478: case 478:
#line 1976 "./parse.y" #line 1977 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 480: case 480:
#line 1982 "./parse.y" #line 1983 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 481: case 481:
#line 1987 "./parse.y" #line 1988 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 483: case 483:
#line 1993 "./parse.y" #line 1994 "./parse.y"
{ {
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location, yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node); yyvsp[-2].node, yyvsp[0].node);
; ;
break;} break;}
case 484: case 484:
#line 1998 "./parse.y" #line 1999 "./parse.y"
{yyerror ("Missing term"); RECOVER;; {yyerror ("Missing term"); RECOVER;;
break;} break;}
case 486: case 486:
#line 2004 "./parse.y" #line 2005 "./parse.y"
{ {
yyval.node = build (CONDITIONAL_EXPR, NULL_TREE, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); yyval.node = build (CONDITIONAL_EXPR, NULL_TREE, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);
EXPR_WFL_LINECOL (yyval.node) = yyvsp[-3].operator.location; EXPR_WFL_LINECOL (yyval.node) = yyvsp[-3].operator.location;
; ;
break;} break;}
case 487: case 487:
#line 2009 "./parse.y" #line 2010 "./parse.y"
{ {
YYERROR_NOW; YYERROR_NOW;
yyerror ("Missing term"); yyerror ("Missing term");
...@@ -4441,19 +4440,19 @@ case 487: ...@@ -4441,19 +4440,19 @@ case 487:
; ;
break;} break;}
case 488: case 488:
#line 2015 "./parse.y" #line 2016 "./parse.y"
{yyerror ("Missing term"); DRECOVER (2);; {yyerror ("Missing term"); DRECOVER (2);;
break;} break;}
case 489: case 489:
#line 2017 "./parse.y" #line 2018 "./parse.y"
{yyerror ("Missing term"); DRECOVER (3);; {yyerror ("Missing term"); DRECOVER (3);;
break;} break;}
case 492: case 492:
#line 2027 "./parse.y" #line 2028 "./parse.y"
{ yyval.node = build_assignment (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ; { yyval.node = build_assignment (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;} break;}
case 493: case 493:
#line 2029 "./parse.y" #line 2030 "./parse.y"
{ {
if (ctxp->prevent_ese != lineno) if (ctxp->prevent_ese != lineno)
yyerror ("Missing term"); yyerror ("Missing term");
...@@ -4658,7 +4657,7 @@ yyerrhandle: ...@@ -4658,7 +4657,7 @@ yyerrhandle:
yystate = yyn; yystate = yyn;
goto yynewstate; goto yynewstate;
} }
#line 2055 "./parse.y" #line 2056 "./parse.y"
...@@ -4772,7 +4771,7 @@ parse_jdk1_1_error (msg) ...@@ -4772,7 +4771,7 @@ parse_jdk1_1_error (msg)
{ {
sorry (": `%s' JDK1.1(TM) feature", msg); sorry (": `%s' JDK1.1(TM) feature", msg);
java_error_count++; java_error_count++;
return size_zero_node; return empty_stmt_node;
} }
static int do_warning = 0; static int do_warning = 0;
...@@ -4904,13 +4903,13 @@ parse_warning_context VPROTO ((tree cl, char *msg, ...)) ...@@ -4904,13 +4903,13 @@ parse_warning_context VPROTO ((tree cl, char *msg, ...))
msg = va_arg (ap, char *); msg = va_arg (ap, char *);
#endif #endif
do_warning = 1; force_error = do_warning = 1;
issue_warning_error_from_context (cl, msg, ap); issue_warning_error_from_context (cl, msg, ap);
force_error = 0; do_warning = force_error = 0;
va_end (ap); va_end (ap);
} }
void int
java_report_errors () java_report_errors ()
{ {
if (java_error_count) if (java_error_count)
...@@ -4921,6 +4920,7 @@ java_report_errors () ...@@ -4921,6 +4920,7 @@ java_report_errors ()
java_warning_count, (java_warning_count == 1 ? "" : "s")); java_warning_count, (java_warning_count == 1 ? "" : "s"));
if (java_error_count || java_warning_count) if (java_error_count || java_warning_count)
putc ('\n', stderr); putc ('\n', stderr);
return java_error_count;
} }
static char * static char *
...@@ -4971,8 +4971,8 @@ variable_redefinition_error (context, name, type, line) ...@@ -4971,8 +4971,8 @@ variable_redefinition_error (context, name, type, line)
char *type_name; char *type_name;
/* Figure a proper name for type. We might haven't resolved it */ /* Figure a proper name for type. We might haven't resolved it */
if (TREE_CODE (type) == TREE_LIST) if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
type_name = IDENTIFIER_POINTER (TYPE_NAME (TREE_PURPOSE (type))); type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
else else
type_name = lang_printable_name (type, 0); type_name = lang_printable_name (type, 0);
...@@ -5235,10 +5235,10 @@ create_interface (flags, id, super) ...@@ -5235,10 +5235,10 @@ create_interface (flags, id, super)
- public/abstract allowed (already done at that point) - public/abstract allowed (already done at that point)
- abstract is obsolete (comes first, it's a warning, or should be) - abstract is obsolete (comes first, it's a warning, or should be)
- Can't use twice the same (checked in the modifier rule) */ - Can't use twice the same (checked in the modifier rule) */
if (flags & ACC_ABSTRACT) if ((flags & ACC_ABSTRACT) && flag_redundant)
parse_warning_context parse_warning_context
(MODIFIER_WFL (ABSTRACT_TK), (MODIFIER_WFL (ABSTRACT_TK),
"Obsolete use of `abstract' modifier. Interface `%s' is implicitely " "Redundant use of `abstract' modifier. Interface `%s' is implicitely "
"abstract", IDENTIFIER_POINTER (raw_name)); "abstract", IDENTIFIER_POINTER (raw_name));
if (flags & ACC_PUBLIC && flags & ACC_ABSTRACT) if (flags & ACC_PUBLIC && flags & ACC_ABSTRACT)
parse_error_context parse_error_context
...@@ -5357,7 +5357,9 @@ lookup_field_wrapper (class, name) ...@@ -5357,7 +5357,9 @@ lookup_field_wrapper (class, name)
tree class, name; tree class, name;
{ {
tree type = class; tree type = class;
java_parser_context_save_global ();
return lookup_field (&type, name); return lookup_field (&type, name);
java_parser_context_restore_global ();
} }
/* Find duplicate field within the same class declarations and report /* Find duplicate field within the same class declarations and report
...@@ -5374,11 +5376,12 @@ duplicate_declaration_error_p (new_field_name, new_type, cl) ...@@ -5374,11 +5376,12 @@ duplicate_declaration_error_p (new_field_name, new_type, cl)
if (decl) if (decl)
{ {
char *t1 = strdup (lang_printable_name (new_type, 1)); char *t1 = strdup (lang_printable_name (new_type, 1));
char *t2 = /* The type may not have been completed by the time we report
strdup ((TREE_CODE (TREE_TYPE (decl)) == TREE_LIST ? the error */
IDENTIFIER_POINTER (TYPE_NAME char *t2 = strdup (((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
(TREE_PURPOSE (TREE_TYPE (decl)))) : && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
lang_printable_name (TREE_TYPE (decl), 1))); IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
lang_printable_name (TREE_TYPE (decl), 1)));
parse_error_context parse_error_context
(cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)",
t1, IDENTIFIER_POINTER (new_field_name), t1, IDENTIFIER_POINTER (new_field_name),
...@@ -5433,6 +5436,7 @@ register_fields (flags, type, variable_list) ...@@ -5433,6 +5436,7 @@ register_fields (flags, type, variable_list)
for (current = variable_list, saved_type = type; current; for (current = variable_list, saved_type = type; current;
current = TREE_CHAIN (current), type = saved_type) current = TREE_CHAIN (current), type = saved_type)
{ {
tree real_type;
tree field_decl; tree field_decl;
tree cl = TREE_PURPOSE (current); tree cl = TREE_PURPOSE (current);
tree init = TREE_VALUE (current); tree init = TREE_VALUE (current);
...@@ -5441,10 +5445,6 @@ register_fields (flags, type, variable_list) ...@@ -5441,10 +5445,6 @@ register_fields (flags, type, variable_list)
/* Process NAME, as it may specify extra dimension(s) for it */ /* Process NAME, as it may specify extra dimension(s) for it */
type = build_array_from_name (type, wfl, current_name, &current_name); type = build_array_from_name (type, wfl, current_name, &current_name);
/* Check for redeclarations */
if (duplicate_declaration_error_p (current_name, type, cl))
continue;
/* Type adjustment. We may have just readjusted TYPE because /* Type adjustment. We may have just readjusted TYPE because
the variable specified more dimensions. Make sure we have the variable specified more dimensions. Make sure we have
a reference if we can and don't have one already. Also a reference if we can and don't have one already. Also
...@@ -5457,10 +5457,15 @@ register_fields (flags, type, variable_list) ...@@ -5457,10 +5457,15 @@ register_fields (flags, type, variable_list)
EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name; EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
} }
real_type = GET_REAL_TYPE (type);
/* Check for redeclarations */
if (duplicate_declaration_error_p (current_name, real_type, cl))
continue;
/* Set lineno to the line the field was found and create a /* Set lineno to the line the field was found and create a
declaration for it. Eventually sets the @deprecated tag flag. */ declaration for it. Eventually sets the @deprecated tag flag. */
lineno = EXPR_WFL_LINENO (cl); lineno = EXPR_WFL_LINENO (cl);
field_decl = add_field (class_type, current_name, type, flags); field_decl = add_field (class_type, current_name, real_type, flags);
CHECK_DEPRECATED (field_decl); CHECK_DEPRECATED (field_decl);
/* Check if we must chain. */ /* Check if we must chain. */
...@@ -5485,6 +5490,8 @@ register_fields (flags, type, variable_list) ...@@ -5485,6 +5490,8 @@ register_fields (flags, type, variable_list)
permalloc (sizeof (struct lang_decl_var)); permalloc (sizeof (struct lang_decl_var));
DECL_LOCAL_STATIC_VALUE (field_decl) = DECL_LOCAL_STATIC_VALUE (field_decl) =
TREE_OPERAND (init, 1); TREE_OPERAND (init, 1);
if (TREE_CONSTANT (TREE_OPERAND (init, 1)))
DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
} }
/* Otherwise, the field should be initialized in <clinit>. /* Otherwise, the field should be initialized in <clinit>.
This field is remembered so we can generate <clinit> later */ This field is remembered so we can generate <clinit> later */
...@@ -5679,9 +5686,11 @@ method_header (flags, type, mdecl, throws) ...@@ -5679,9 +5686,11 @@ method_header (flags, type, mdecl, throws)
TREE_TYPE (meth) = returned_type; TREE_TYPE (meth) = returned_type;
else else
{ {
tree itype;
patch_stage = JDEP_METHOD_RETURN; patch_stage = JDEP_METHOD_RETURN;
TREE_TYPE (meth) = itype = register_incomplete_type (patch_stage, type, id, NULL_TREE);
register_incomplete_type (patch_stage, type, id, NULL_TREE); TREE_TYPE (meth) = (TREE_CODE (itype) == TREE_LIST ?
TREE_PURPOSE (itype) : itype);
} }
} }
else else
...@@ -5883,8 +5892,7 @@ check_abstract_method_header (meth) ...@@ -5883,8 +5892,7 @@ check_abstract_method_header (meth)
{ {
int flags = get_access_flags_from_decl (meth); int flags = get_access_flags_from_decl (meth);
/* DECL_NAME might still be a WFL node */ /* DECL_NAME might still be a WFL node */
tree name = (TREE_CODE (DECL_NAME (meth)) == EXPR_WITH_FILE_LOCATION ? tree name = GET_METHOD_NAME (meth);
EXPR_WFL_NODE (DECL_NAME (meth)) : DECL_NAME (meth));
OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags, OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags,
ACC_ABSTRACT, "abstract method `%s'", ACC_ABSTRACT, "abstract method `%s'",
...@@ -6115,6 +6123,7 @@ obtain_incomplete_type (wfl) ...@@ -6115,6 +6123,7 @@ obtain_incomplete_type (wfl)
tree core; tree core;
push_obstacks (&permanent_obstack, &permanent_obstack); push_obstacks (&permanent_obstack, &permanent_obstack);
BUILD_PTR_FROM_NAME (core, name); BUILD_PTR_FROM_NAME (core, name);
layout_type (core);
ptr = build_tree_list (core, NULL_TREE); ptr = build_tree_list (core, NULL_TREE);
pop_obstacks (); pop_obstacks ();
TREE_CHAIN (ptr) = ctxp->incomplete_class; TREE_CHAIN (ptr) = ctxp->incomplete_class;
...@@ -6196,10 +6205,6 @@ safe_layout_class (class) ...@@ -6196,10 +6205,6 @@ safe_layout_class (class)
push_obstacks (&permanent_obstack, &permanent_obstack); push_obstacks (&permanent_obstack, &permanent_obstack);
if (!CLASS_METHOD_CHECKED_P (class))
CHECK_METHODS (TYPE_NAME (class));
CLASS_METHOD_CHECKED_P (class) = 1;
layout_class (class); layout_class (class);
pop_obstacks (); pop_obstacks ();
...@@ -6252,7 +6257,7 @@ java_complete_class () ...@@ -6252,7 +6257,7 @@ java_complete_class ()
/* Rever things so we have the right order */ /* Rever things so we have the right order */
ctxp->class_list = nreverse (ctxp->class_list); ctxp->class_list = nreverse (ctxp->class_list);
ctxp->classd_list = reverse_jdep_list (ctxp); ctxp->classd_list = reverse_jdep_list (ctxp);
for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
cclass && cclassd; cclass && cclassd;
cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd)) cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
...@@ -6261,7 +6266,6 @@ java_complete_class () ...@@ -6261,7 +6266,6 @@ java_complete_class ()
for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep)) for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
{ {
tree decl; tree decl;
if (!(decl = jdep_resolve_class (dep))) if (!(decl = jdep_resolve_class (dep)))
continue; continue;
...@@ -6357,21 +6361,10 @@ java_complete_class () ...@@ -6357,21 +6361,10 @@ java_complete_class ()
break; break;
case JDEP_EXCEPTION: case JDEP_EXCEPTION:
/* Check for righteous inheritance here */ JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
if (!inherits_from_p (TREE_TYPE (decl), throwable_type_node)) SOURCE_FRONTEND_DEBUG
{ (("Completing `%s' `throws' argument node",
parse_error_context IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
(JDEP_WFL (dep), "Class `%s' in `throws' clause must be "
"a subclass of class `java.lang.Throwable'",
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
}
else
{
JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
SOURCE_FRONTEND_DEBUG
(("Completing `%s' `throws' argument node",
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
}
break; break;
default: default:
...@@ -6496,11 +6489,23 @@ do_resolve_class (class_type, decl, cl) ...@@ -6496,11 +6489,23 @@ do_resolve_class (class_type, decl, cl)
parsed class). Return a decl node. */ parsed class). Return a decl node. */
static tree static tree
resolve_and_layout (name, cl) resolve_and_layout (something, cl)
tree name; tree something;
tree cl; tree cl;
{ {
tree decl = resolve_no_layout (name, cl); tree decl;
if (TREE_CODE (something) == POINTER_TYPE)
something = TREE_TYPE (something);
if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
return NULL_TREE;
if (TREE_CODE (something) != IDENTIFIER_NODE)
something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
decl = resolve_no_layout (something, cl);
if (decl && TREE_TYPE (decl) != current_class if (decl && TREE_TYPE (decl) != current_class
&& !CLASS_LOADED_P (TREE_TYPE (decl))) && !CLASS_LOADED_P (TREE_TYPE (decl)))
safe_layout_class (TREE_TYPE (decl)); safe_layout_class (TREE_TYPE (decl));
...@@ -6640,16 +6645,30 @@ reset_method_name (method) ...@@ -6640,16 +6645,30 @@ reset_method_name (method)
{ {
/* NAME is just the plain name when Object is being defined */ /* NAME is just the plain name when Object is being defined */
if (DECL_CONTEXT (method) != object_type_node) if (DECL_CONTEXT (method) != object_type_node)
DECL_NAME (method) = DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ?
(DECL_CONSTRUCTOR_P (method) ? init_identifier_node : init_identifier_node : GET_METHOD_NAME (method));
(TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION ?
EXPR_WFL_NODE (DECL_NAME (method)) : DECL_NAME (method)));
return 0; return 0;
} }
else else
return 1; return 1;
} }
/* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
tree
java_get_real_method_name (method_decl)
tree method_decl;
{
tree method_name = DECL_NAME (method_decl);
if (DECL_CONSTRUCTOR_P (method_decl))
return init_identifier_node;
else if (ctxp
&& ctxp->current_parsed_class_un == EXPR_WFL_NODE (method_name))
return init_identifier_node;
else
return EXPR_WFL_NODE (method_name);
}
/* Track method being redefined inside the same class. As a side /* Track method being redefined inside the same class. As a side
effect, set DECL_NAME to an IDENTIFIER (prior entering this 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 */
...@@ -6703,6 +6722,11 @@ java_check_regular_methods (class_decl) ...@@ -6703,6 +6722,11 @@ java_check_regular_methods (class_decl)
tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl)); tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
tree super_class = CLASSTYPE_SUPER (class); tree super_class = CLASSTYPE_SUPER (class);
tree saved_found_wfl = NULL_TREE, found = NULL_TREE; tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
tree mthrows;
/* It is not necessary to check methods defined in java.lang.Object */
if (class == object_type_node)
return;
TYPE_METHODS (class) = nreverse (TYPE_METHODS (class)); TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
...@@ -6731,6 +6755,19 @@ java_check_regular_methods (class_decl) ...@@ -6731,6 +6755,19 @@ java_check_regular_methods (class_decl)
continue; continue;
} }
/* We verify things thrown by the method. They must inherits from
java.lang.Throwable */
for (mthrows = DECL_FUNCTION_THROWS (method);
mthrows; mthrows = TREE_CHAIN (mthrows))
{
if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
parse_error_context
(TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be "
"a subclass of class `java.lang.Throwable'",
IDENTIFIER_POINTER
(DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
}
sig = build_java_argument_signature (TREE_TYPE (method)); sig = build_java_argument_signature (TREE_TYPE (method));
found = lookup_argument_method (super_class, DECL_NAME (method), sig); found = lookup_argument_method (super_class, DECL_NAME (method), sig);
...@@ -6820,7 +6857,8 @@ java_check_regular_methods (class_decl) ...@@ -6820,7 +6857,8 @@ java_check_regular_methods (class_decl)
the match was found in java.lang.Object. */ the match was found in java.lang.Object. */
if (DECL_CONTEXT (found) != object_type_node if (DECL_CONTEXT (found) != object_type_node
&& (!aflags || (aflags > ACC_PROTECTED)) && (!aflags || (aflags > ACC_PROTECTED))
&& !class_in_current_package (DECL_CONTEXT (found))) && !class_in_current_package (DECL_CONTEXT (found))
&& flag_not_overriding)
parse_warning_context parse_warning_context
(method_wfl, "Method `%s' in class `%s' does not " (method_wfl, "Method `%s' in class `%s' does not "
"override the corresponding method in class `%s', which is " "override the corresponding method in class `%s', which is "
...@@ -6867,11 +6905,15 @@ check_throws_clauses (method, method_wfl, found) ...@@ -6867,11 +6905,15 @@ check_throws_clauses (method, method_wfl, found)
{ {
tree mthrows, fthrows; tree mthrows, fthrows;
/* Can't check these things with class loaded from bytecode. FIXME */
if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
return;
for (mthrows = DECL_FUNCTION_THROWS (method); for (mthrows = DECL_FUNCTION_THROWS (method);
mthrows; mthrows = TREE_CHAIN (mthrows)) mthrows; mthrows = TREE_CHAIN (mthrows))
{ {
/* We don't verify unchecked expressions */ /* We don't verify unchecked expressions */
if (IS_UNCHECKED_EXPRESSION_P (TREE_VALUE (mthrows))) if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
continue; continue;
/* Checked expression must be compatible */ /* Checked expression must be compatible */
for (fthrows = DECL_FUNCTION_THROWS (found); for (fthrows = DECL_FUNCTION_THROWS (found);
...@@ -6980,10 +7022,7 @@ java_check_methods () ...@@ -6980,10 +7022,7 @@ java_check_methods ()
tree current; tree current;
for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current)) for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current)))) if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
{ CHECK_METHODS (TREE_VALUE (current));
CHECK_METHODS (TREE_VALUE (current));
CLASS_METHOD_CHECKED_P (TREE_TYPE (TREE_VALUE (current))) = 1;
}
} }
/* Lookup methods in interfaces using their name and partial /* Lookup methods in interfaces using their name and partial
...@@ -7454,12 +7493,20 @@ declare_local_variables (modifier, type, vlist) ...@@ -7454,12 +7493,20 @@ declare_local_variables (modifier, type, vlist)
{ {
int i; int i;
for (i = 0; i <= 10; i++) if (1 << i & modifier) break; for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
parse_error_context if (modifier == ACC_FINAL)
(ctxp->modifier_ctx [i], {
(modifier == ACC_FINAL ? if (flag_static_local_jdk1_1)
"Unsupported JDK1.1 `final' locals" : parse_warning_context (ctxp->modifier_ctx [i],
"Only `final' is allowed as a local variables modifier")); "Unsupported JDK1.1 `final' local variable "
return; "(treated as non final)");
}
else
{
parse_error_context
(ctxp->modifier_ctx [i],
"Only `final' is allowed as a local variables modifier");
return;
}
} }
/* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
...@@ -7475,7 +7522,7 @@ declare_local_variables (modifier, type, vlist) ...@@ -7475,7 +7522,7 @@ declare_local_variables (modifier, type, vlist)
for (current = vlist, saved_type = type; current; for (current = vlist, saved_type = type; current;
current = TREE_CHAIN (current), type = saved_type) current = TREE_CHAIN (current), type = saved_type)
{ {
tree other; tree other, real_type;
tree wfl = TREE_PURPOSE (current); tree wfl = TREE_PURPOSE (current);
tree name = EXPR_WFL_NODE (wfl); tree name = EXPR_WFL_NODE (wfl);
tree init = TREE_VALUE (current); tree init = TREE_VALUE (current);
...@@ -7497,10 +7544,11 @@ declare_local_variables (modifier, type, vlist) ...@@ -7497,10 +7544,11 @@ declare_local_variables (modifier, type, vlist)
if (type != saved_type && !must_chain if (type != saved_type && !must_chain
&& (TREE_CODE (type) == RECORD_TYPE)) && (TREE_CODE (type) == RECORD_TYPE))
type = promote_type (type); type = promote_type (type);
real_type = GET_REAL_TYPE (type);
/* Never layout this decl. This will be done when its scope /* Never layout this decl. This will be done when its scope
will be entered */ will be entered */
decl = build_decl_no_layout (VAR_DECL, name, type); decl = build_decl (VAR_DECL, name, real_type);
BLOCK_CHAIN_DECL (decl); BLOCK_CHAIN_DECL (decl);
/* Don't try to use an INIT statement when an error was found */ /* Don't try to use an INIT statement when an error was found */
...@@ -7556,8 +7604,8 @@ source_start_java_method (fndecl) ...@@ -7556,8 +7604,8 @@ source_start_java_method (fndecl)
if (INCOMPLETE_TYPE_P (type)) if (INCOMPLETE_TYPE_P (type))
{ {
jdep *jdep; jdep *jdep;
parm_decl = build_decl_no_layout (PARM_DECL, name, type); tree real_type = GET_REAL_TYPE (type);
parm_decl = build_decl (PARM_DECL, name, real_type);
register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type); register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
jdep = CLASSD_LAST (ctxp->classd_list); jdep = CLASSD_LAST (ctxp->classd_list);
JDEP_MISC (jdep) = name; JDEP_MISC (jdep) = name;
...@@ -7752,17 +7800,39 @@ java_layout_classes () ...@@ -7752,17 +7800,39 @@ java_layout_classes ()
{ {
current_class = TREE_TYPE (TREE_VALUE (current)); current_class = TREE_TYPE (TREE_VALUE (current));
/* Reverse the fields if it's necessary (they've already /* Reverse the fields, but leave the dummy field in front.
reversed if the dummy field has been inserted at the Fields are already ordered for Object and Class */
beginning of the list */ if (TYPE_FIELDS (current_class) && current_class != object_type_node
if (TYPE_FIELDS (current_class) && current_class != class_type_node)
&& !DECL_IGNORED_P (TYPE_FIELDS (current_class))) {
TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class)); /* Always leave the dummy field in front if its already there,
and layout the class for proper field offets. */
if (!DECL_NAME (TYPE_FIELDS (current_class)))
{
tree fields = TYPE_FIELDS (current_class);
TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
TYPE_SIZE (current_class) = NULL_TREE;
layout_type (current_class);
}
/* It's time to layout the class */
else
{
TYPE_FIELDS (current_class) =
nreverse (TYPE_FIELDS (current_class));
TYPE_SIZE (current_class) = NULL_TREE;
layout_class (current_class);
}
}
/* Do a layout if necessary */ /* Do a layout if necessary */
if (!TYPE_SIZE (current_class) || (current_class == object_type_node)) if (!TYPE_SIZE (current_class)
|| (current_class == object_type_node)
|| current_class == class_type_node)
safe_layout_class (current_class); safe_layout_class (current_class);
/* From now on, the class is considered completely loaded */
CLASS_LOADED_P (current_class) = 1;
/* Error reported by the caller */ /* Error reported by the caller */
if (java_error_count) if (java_error_count)
return; return;
...@@ -7847,6 +7917,8 @@ java_complete_expand_method (mdecl) ...@@ -7847,6 +7917,8 @@ java_complete_expand_method (mdecl)
/* Expand functions that have a body */ /* Expand functions that have a body */
if (DECL_FUNCTION_BODY (mdecl)) if (DECL_FUNCTION_BODY (mdecl))
{ {
tree fbody = DECL_FUNCTION_BODY (mdecl);
tree block_body = BLOCK_EXPR_BODY (fbody);
expand_start_java_method (mdecl); expand_start_java_method (mdecl);
current_this current_this
...@@ -7859,9 +7931,16 @@ java_complete_expand_method (mdecl) ...@@ -7859,9 +7931,16 @@ java_complete_expand_method (mdecl)
/* Install exceptions thrown with `throws' */ /* Install exceptions thrown with `throws' */
PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl)); PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl))) if (block_body != NULL_TREE)
java_complete_tree (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl))); block_body = java_complete_tree (block_body);
BLOCK_EXPR_BODY (fbody) = block_body;
if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
&& TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
{
parse_error_context (fbody, "Missing return statement");
}
/* Don't go any further if we've found error(s) during the /* Don't go any further if we've found error(s) during the
expansion */ expansion */
if (!java_error_count) if (!java_error_count)
...@@ -8289,15 +8368,15 @@ resolve_field_access (qual_wfl, field_decl, field_type) ...@@ -8289,15 +8368,15 @@ resolve_field_access (qual_wfl, field_decl, field_type)
type_found, DECL_NAME (decl)); type_found, DECL_NAME (decl));
if (field_ref == error_mark_node) if (field_ref == error_mark_node)
return error_mark_node; return error_mark_node;
if (is_static && !static_final_found if (is_static && !static_final_found && !flag_emit_class_files)
&& ! flag_emit_class_files)
{ {
field_ref = build_class_init (type_found, field_ref); field_ref = build_class_init (type_found, field_ref);
/* If the static field was identified by an expression that /* If the static field was identified by an expression that
needs to be generated, make the field access a compound needs to be generated, make the field access a compound
expression whose first part of the evaluation of the expression whose first part of the evaluation of the
field selector part. */ field selector part. */
if (where_found && TREE_CODE (where_found) != TYPE_DECL) if (where_found && TREE_CODE (where_found) != TYPE_DECL
&& TREE_CODE (where_found) != RECORD_TYPE)
{ {
tree type = QUAL_DECL_TYPE (field_ref); tree type = QUAL_DECL_TYPE (field_ref);
field_ref = build (COMPOUND_EXPR, type, where_found, field_ref); field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
...@@ -8310,7 +8389,8 @@ resolve_field_access (qual_wfl, field_decl, field_type) ...@@ -8310,7 +8389,8 @@ resolve_field_access (qual_wfl, field_decl, field_type)
if (field_decl) if (field_decl)
*field_decl = decl; *field_decl = decl;
if (field_type) if (field_type)
*field_type = QUAL_DECL_TYPE (decl); *field_type = (QUAL_DECL_TYPE (decl) ?
QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
return field_ref; return field_ref;
} }
...@@ -8326,7 +8406,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -8326,7 +8406,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
int previous_call_static = 0; int previous_call_static = 0;
int is_static; int is_static;
tree decl = NULL_TREE, type = NULL_TREE, q; tree decl = NULL_TREE, type = NULL_TREE, q;
*where_found = NULL_TREE; *type_found = *where_found = NULL_TREE;
for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q)) for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
{ {
...@@ -8517,10 +8597,16 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -8517,10 +8597,16 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
if (!from_super && QUAL_RESOLUTION (q)) if (!from_super && QUAL_RESOLUTION (q))
{ {
decl = QUAL_RESOLUTION (q); decl = QUAL_RESOLUTION (q);
if (!type && !FIELD_STATIC (decl)) if (!type)
{ {
*where_found = current_this; if (!FIELD_STATIC (decl))
*type_found = type; *where_found = current_this;
else
{
*where_found = TREE_TYPE (decl);
if (TREE_CODE (*where_found) == POINTER_TYPE)
*where_found = TREE_TYPE (*where_found);
}
} }
} }
...@@ -8556,15 +8642,19 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -8556,15 +8642,19 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
} }
/* Layout the type of field_decl, since we may need /* Layout the type of field_decl, since we may need
it. Don't do primitive types or loaded classes */ it. Don't do primitive types or loaded classes. The
situation of non primitive arrays may not handled
properly here. FIXME */
if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE) if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
field_decl_type = TREE_TYPE (TREE_TYPE (field_decl)); field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
else else
field_decl_type = TREE_TYPE (field_decl); field_decl_type = TREE_TYPE (field_decl);
if (!JPRIMITIVE_TYPE_P (field_decl_type) if (!JPRIMITIVE_TYPE_P (field_decl_type)
&& !CLASS_LOADED_P (field_decl_type)) && !CLASS_LOADED_P (field_decl_type)
resolve_and_layout (DECL_NAME (TYPE_NAME (field_decl_type)), && !TYPE_ARRAY_P (field_decl_type))
NULL_TREE); resolve_and_layout (field_decl_type, NULL_TREE);
if (TYPE_ARRAY_P (field_decl_type))
CLASS_LOADED_P (field_decl_type) = 1;
/* Check on accessibility here */ /* Check on accessibility here */
if (not_accessible_p (type, field_decl, from_super)) if (not_accessible_p (type, field_decl, from_super))
...@@ -8648,32 +8738,19 @@ int not_accessible_p (reference, member, from_super) ...@@ -8648,32 +8738,19 @@ int not_accessible_p (reference, member, from_super)
if (class_in_current_package (DECL_CONTEXT (member))) if (class_in_current_package (DECL_CONTEXT (member)))
return 0; return 0;
if (TREE_CODE (member) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (member)) /* If accessed with the form `super.member', then access is granted */
{ if (from_super)
/* Access from SUPER is granted */ return 0;
if (from_super)
return 0;
/* Otherwise, access isn't granted */
return 1;
}
else
{
/* If accessed with the form `super.member', then access is
granted */
if (from_super)
return 0;
/* Otherwise, access is granted if occuring from the class where /* Otherwise, access is granted if occuring from the class where
member is declared or a subclass of it */ member is declared or a subclass of it */
if (inherits_from_p (reference, current_class)) if (inherits_from_p (reference, current_class))
return 0; return 0;
}
return 1; return 1;
} }
/* Check access on private members. Access is granted only if it /* Check access on private members. Access is granted only if it
occurs from within the class in witch it is declared*/ occurs from within the class in witch it is declared */
if (access_flag & ACC_PRIVATE) if (access_flag & ACC_PRIVATE)
return (current_class == DECL_CONTEXT (member) ? 0 : 1); return (current_class == DECL_CONTEXT (member) ? 0 : 1);
...@@ -8872,9 +8949,9 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super) ...@@ -8872,9 +8949,9 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
/* 2- Do the layout of the class where the last field /* 2- Do the layout of the class where the last field
was found, so we can search it. */ was found, so we can search it. */
class_decl = class_decl = resolve_and_layout (type, NULL_TREE);
resolve_and_layout (DECL_NAME (TYPE_NAME (type)), NULL_TREE); type = TREE_TYPE (class_decl);
/* 3- Retrieve a filtered list of method matches, Refine /* 3- Retrieve a filtered list of method matches, Refine
if necessary. In any cases, point out errors. */ if necessary. In any cases, point out errors. */
list = lookup_method_invoke (0, identifier_wfl, type, list = lookup_method_invoke (0, identifier_wfl, type,
...@@ -8956,6 +9033,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super) ...@@ -8956,6 +9033,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
/* NAME is a simple identifier or comes from a primary. Search /* NAME is a simple identifier or comes from a primary. Search
in the class whose declaration contain the method being in the class whose declaration contain the method being
invoked. */ invoked. */
resolve_and_layout (class_to_search, NULL_TREE);
list = lookup_method_invoke (lc, wfl, class_to_search, name, args); list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
/* Don't continue if no method were found, as the next statement /* Don't continue if no method were found, as the next statement
...@@ -8984,7 +9062,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super) ...@@ -8984,7 +9062,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
/* Check accessibility, position the is_static flag, build and /* Check accessibility, position the is_static flag, build and
return the call */ return the call */
if (not_accessible_p (DECL_CONTEXT (list), list, 0)) if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
{ {
char *fct_name = strdup (lang_printable_name (list, 0)); char *fct_name = strdup (lang_printable_name (list, 0));
parse_error_context parse_error_context
...@@ -9170,20 +9248,26 @@ lookup_method_invoke (lc, cl, class, name, arg_list) ...@@ -9170,20 +9248,26 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
tree cl; tree cl;
tree class, name, arg_list; tree class, name, arg_list;
{ {
tree method = make_node (FUNCTION_TYPE);
tree atl = NULL_TREE; /* Arg Type List */ tree atl = NULL_TREE; /* Arg Type List */
tree signature, list, node; tree method, signature, list, node;
char *candidates; /* Used for error report */ char *candidates; /* Used for error report */
/* Fix the arguments */ /* Fix the arguments */
for (node = arg_list; node; node = TREE_CHAIN (node)) for (node = arg_list; node; node = TREE_CHAIN (node))
{ {
tree current_arg = TREE_TYPE (TREE_VALUE (node)); tree current_arg = TREE_VALUE (node);
/* Integer constant 0 passed as itself, not as a type */
if (current_arg != integer_zero_node)
current_arg = TREE_TYPE (TREE_VALUE (node));
/* Non primitive type may have to be resolved */
if (current_arg != integer_zero_node
&& !JPRIMITIVE_TYPE_P (current_arg))
resolve_and_layout (current_arg, NULL_TREE);
/* And promoted */
if (TREE_CODE (current_arg) == RECORD_TYPE) if (TREE_CODE (current_arg) == RECORD_TYPE)
current_arg = promote_type (current_arg); current_arg = promote_type (current_arg);
atl = tree_cons (NULL_TREE, current_arg, atl); atl = tree_cons (NULL_TREE, current_arg, atl);
} }
TYPE_ARG_TYPES (method) = atl;
/* Find all candidates and then refine the list, searching for the /* Find all candidates and then refine the list, searching for the
most specific method. */ most specific method. */
...@@ -9217,6 +9301,11 @@ lookup_method_invoke (lc, cl, class, name, arg_list) ...@@ -9217,6 +9301,11 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
candidates = obstack_finish (&temporary_obstack); candidates = obstack_finish (&temporary_obstack);
} }
/* Issue the error message */ /* Issue the error message */
for (node = atl; node; node = TREE_CHAIN (node))
if (TREE_VALUE (node) == integer_zero_node)
TREE_VALUE (node) = long_type_node;
method = make_node (FUNCTION_TYPE);
TYPE_ARG_TYPES (method) = atl;
signature = build_java_argument_signature (method); signature = build_java_argument_signature (method);
parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s", parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
(lc ? "constructor" : "method"), (lc ? "constructor" : "method"),
...@@ -9248,13 +9337,14 @@ find_applicable_accessible_methods_list (lc, class, name, arglist) ...@@ -9248,13 +9337,14 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
if (lc && !DECL_CONSTRUCTOR_P (method)) if (lc && !DECL_CONSTRUCTOR_P (method))
continue; continue;
else if (!lc && (DECL_CONSTRUCTOR_P (method) else if (!lc && (DECL_CONSTRUCTOR_P (method)
|| DECL_NAME (method) != name)) || (GET_METHOD_NAME (method) != name)))
continue; continue;
if (argument_types_convertible (method, arglist)) if (argument_types_convertible (method, arglist))
{ {
/* Retain accessible methods only */ /* Retain accessible methods only */
if (!not_accessible_p (class, method, 0)) if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
method, 0))
list = tree_cons (NULL_TREE, method, list); list = tree_cons (NULL_TREE, method, list);
else else
/* Also retain all selected method here */ /* Also retain all selected method here */
...@@ -9361,6 +9451,7 @@ argument_types_convertible (m1, m2_or_arglist) ...@@ -9361,6 +9451,7 @@ argument_types_convertible (m1, m2_or_arglist)
while (m1_arg && m2_arg) while (m1_arg && m2_arg)
{ {
resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg), if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
TREE_VALUE (m2_arg))) TREE_VALUE (m2_arg)))
break; break;
...@@ -9492,7 +9583,8 @@ qualify_ambiguous_name (id) ...@@ -9492,7 +9583,8 @@ qualify_ambiguous_name (id)
} }
/* Method call are expression name */ /* Method call are expression name */
else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR) else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
|| TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF)
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1; RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
/* Check here that NAME isn't declared by more than one /* Check here that NAME isn't declared by more than one
...@@ -9553,22 +9645,6 @@ breakdown_qualified (left, right, source) ...@@ -9553,22 +9645,6 @@ breakdown_qualified (left, right, source)
return 0; return 0;
} }
static int
not_initialized_as_it_should_p (decl)
tree decl;
{
if (DECL_P (decl))
{
if (FIELD_FINAL (decl))
return 0;
if (TREE_CODE (decl) == FIELD_DECL
&& (METHOD_STATIC (current_function_decl)))
return 0;
return DECL_P (decl) && !INITIALIZED_P (decl);
}
return 0;
}
/* Patch tree nodes in a function body. When a BLOCK is found, push /* Patch tree nodes in a function body. When a BLOCK is found, push
local variable decls if present. */ local variable decls if present. */
...@@ -9610,7 +9686,8 @@ java_complete_tree (node) ...@@ -9610,7 +9686,8 @@ java_complete_tree (node)
int error_seen = 0; int error_seen = 0;
if (TREE_CODE (stmt) == COMPOUND_EXPR) if (TREE_CODE (stmt) == COMPOUND_EXPR)
{ {
/* Re-order from (((A; B); C); ...; Z) to (A; (B; (C ; (...; Z)))). /* Re-order from (((A; B); C); ...; Z) to
(A; (B; (C ; (...; Z)))).
This makes it easier to scan the statements left-to-right This makes it easier to scan the statements left-to-right
without using recursion (which might overflow the stack without using recursion (which might overflow the stack
if the block has many statements. */ if the block has many statements. */
...@@ -9626,7 +9703,8 @@ java_complete_tree (node) ...@@ -9626,7 +9703,8 @@ java_complete_tree (node)
BLOCK_EXPR_BODY (node) = stmt; BLOCK_EXPR_BODY (node) = stmt;
} }
/* Now do the actual complete, without deep recursion for long blocks. */ /* Now do the actual complete, without deep recursion for
long blocks. */
ptr = &BLOCK_EXPR_BODY (node); ptr = &BLOCK_EXPR_BODY (node);
while (TREE_CODE (*ptr) == COMPOUND_EXPR) while (TREE_CODE (*ptr) == COMPOUND_EXPR)
{ {
...@@ -9651,7 +9729,8 @@ java_complete_tree (node) ...@@ -9651,7 +9729,8 @@ java_complete_tree (node)
&& TREE_CODE (wfl_op2) != DEFAULT_EXPR) && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
{ {
SET_WFL_OPERATOR (wfl_operator, *ptr, wfl_op2); SET_WFL_OPERATOR (wfl_operator, *ptr, wfl_op2);
parse_error_context (wfl_operator, "Unreachable statement"); parse_error_context (wfl_operator,
"Unreachable statement");
} }
} }
ptr = next; ptr = next;
...@@ -9719,7 +9798,8 @@ java_complete_tree (node) ...@@ -9719,7 +9798,8 @@ java_complete_tree (node)
nn = ctxp->current_loop; nn = ctxp->current_loop;
/* It must be assignable to the type of the switch expression. */ /* It must be assignable to the type of the switch expression. */
if (!try_builtin_assignconv (NULL_TREE, TREE_TYPE (TREE_OPERAND (nn, 0)), cn)) if (!try_builtin_assignconv (NULL_TREE,
TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
{ {
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node); EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
parse_error_context parse_error_context
...@@ -9735,6 +9815,7 @@ java_complete_tree (node) ...@@ -9735,6 +9815,7 @@ java_complete_tree (node)
value is checked during code generation. The case value is checked during code generation. The case
expression is allright so far. */ expression is allright so far. */
TREE_OPERAND (node, 0) = cn; TREE_OPERAND (node, 0) = cn;
TREE_TYPE (node) = void_type_node;
CAN_COMPLETE_NORMALLY (node) = 1; CAN_COMPLETE_NORMALLY (node) = 1;
break; break;
...@@ -9750,6 +9831,7 @@ java_complete_tree (node) ...@@ -9750,6 +9831,7 @@ java_complete_tree (node)
} }
else else
SWITCH_HAS_DEFAULT (nn) = 1; SWITCH_HAS_DEFAULT (nn) = 1;
TREE_TYPE (node) = void_type_node;
CAN_COMPLETE_NORMALLY (node) = 1; CAN_COMPLETE_NORMALLY (node) = 1;
break; break;
...@@ -9896,18 +9978,17 @@ java_complete_tree (node) ...@@ -9896,18 +9978,17 @@ java_complete_tree (node)
tree decl, wfl = TREE_OPERAND (node, 0); tree decl, wfl = TREE_OPERAND (node, 0);
int in_this = CALL_THIS_CONSTRUCTOR_P (node); int in_this = CALL_THIS_CONSTRUCTOR_P (node);
node = patch_method_invocation (node, NULL_TREE, node = patch_method_invocation (node, NULL_TREE,
NULL_TREE, 0, &decl, 0); NULL_TREE, 0, &decl, 0);
if (node != error_mark_node) if (node == error_mark_node)
{ return error_mark_node;
check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
/* If we call this(...), register signature and positions */ check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
if (in_this) /* If we call this(...), register signature and positions */
DECL_CONSTRUCTOR_CALLS (current_function_decl) = if (in_this)
tree_cons (wfl, decl, DECL_CONSTRUCTOR_CALLS (current_function_decl) =
DECL_CONSTRUCTOR_CALLS (current_function_decl)); tree_cons (wfl, decl,
DECL_CONSTRUCTOR_CALLS (current_function_decl));
}
return node; return node;
} }
...@@ -9937,6 +10018,13 @@ java_complete_tree (node) ...@@ -9937,6 +10018,13 @@ java_complete_tree (node)
nn = java_complete_tree (TREE_OPERAND (node, 1)); nn = java_complete_tree (TREE_OPERAND (node, 1));
if (nn == error_mark_node) if (nn == error_mark_node)
{ {
/* It's hopeless, but we can further things on to discover
an error during the assignment. In any cases, the
assignment operation fails. */
if (TREE_CODE (TREE_OPERAND (node, 1)) != EXPR_WITH_FILE_LOCATION
&& TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node)
patch_assignment (node, wfl_op1, wfl_op2);
/* Now, we still mark the lhs as initialized */ /* Now, we still mark the lhs as initialized */
if (DECL_P (TREE_OPERAND (node, 0))) if (DECL_P (TREE_OPERAND (node, 0)))
INITIALIZED_P (TREE_OPERAND (node, 0)) = 1; INITIALIZED_P (TREE_OPERAND (node, 0)) = 1;
...@@ -10033,7 +10121,14 @@ java_complete_tree (node) ...@@ -10033,7 +10121,14 @@ java_complete_tree (node)
return error_mark_node; return error_mark_node;
if (!flag_emit_class_files) if (!flag_emit_class_files)
TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1)); TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
return patch_array_ref (node, wfl_op1, wfl_op2); return patch_array_ref (node);
#if 0
COMPONENT_REF:
/* Planned re-write FIXME */
TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
break;
#endif
case THIS_EXPR: case THIS_EXPR:
/* Can't use THIS in a static environment */ /* Can't use THIS in a static environment */
...@@ -10098,11 +10193,6 @@ complete_function_arguments (node) ...@@ -10098,11 +10193,6 @@ complete_function_arguments (node)
parm = maybe_build_primttype_type_ref (parm, wfl); parm = maybe_build_primttype_type_ref (parm, wfl);
TREE_VALUE (cn) = parm; TREE_VALUE (cn) = parm;
if (not_initialized_as_it_should_p (parm))
{
ERROR_VARIABLE_NOT_INITIALIZED (wfl, EXPR_WFL_NODE (wfl));
INITIALIZED_P (parm) = 1;
}
} }
ctxp->explicit_constructor_p -= (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0); ctxp->explicit_constructor_p -= (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
return flag; return flag;
...@@ -10230,14 +10320,14 @@ maybe_absorb_scoping_blocks () ...@@ -10230,14 +10320,14 @@ maybe_absorb_scoping_blocks ()
are building incomplete tree nodes and the patch_* functions that are building incomplete tree nodes and the patch_* functions that
are completing them. */ are completing them. */
/* Build a super() constructor invocation. Returns size_zero_node if /* Build a super() constructor invocation. Returns empty_stmt_node if
we're currently dealing with the class java.lang.Object. */ we're currently dealing with the class java.lang.Object. */
static tree static tree
build_super_invocation () build_super_invocation ()
{ {
if (current_class == object_type_node) if (current_class == object_type_node)
return size_zero_node; return empty_stmt_node;
else else
{ {
tree super_wfl = build_wfl_node (super_identifier_node, tree super_wfl = build_wfl_node (super_identifier_node,
...@@ -10488,29 +10578,12 @@ patch_assignment (node, wfl_op1, wfl_op2) ...@@ -10488,29 +10578,12 @@ patch_assignment (node, wfl_op1, wfl_op2)
error_found = 1; error_found = 1;
} }
/* Before reporting type incompatibility errors, check that the rhs
is initialized, if a variable */
if (not_initialized_as_it_should_p (rhs))
{
ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (rhs));
INITIALIZED_P (rhs) = 1;
}
/* Inline read access to java.lang.PRIMTYPE.TYPE */ /* Inline read access to java.lang.PRIMTYPE.TYPE */
rhs = maybe_build_primttype_type_ref (rhs, wfl_op2); rhs = maybe_build_primttype_type_ref (rhs, wfl_op2);
if (TREE_CODE (rhs) == COMPOUND_EXPR) /* Inline read access to java.lang.PRIMTYPE.TYPE */
{ if (new_rhs)
tree n = TREE_OPERAND (rhs, 1); new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
if (TREE_CODE (n) == VAR_DECL
&& DECL_NAME (n) == TYPE_identifier_node
&& rhs_type == class_ptr_type)
{
char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op2));
if (!strncmp (self_name, "java.lang.", 10))
rhs = build_primtype_type_ref (self_name);
}
}
if (error_found) if (error_found)
return error_mark_node; return error_mark_node;
...@@ -10613,6 +10686,11 @@ valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type) ...@@ -10613,6 +10686,11 @@ valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
if (lhs_type == rhs_type) if (lhs_type == rhs_type)
return 1; return 1;
/* Sometimes, instead of passing a type, we pass integer_zero_node
so we know that an integral type can accomodate it */
if (JINTEGRAL_TYPE_P (lhs_type) && (rhs_type == integer_zero_node))
return 1;
all_primitive = all_primitive =
JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type); JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type);
...@@ -10793,7 +10871,7 @@ static int ...@@ -10793,7 +10871,7 @@ static int
valid_method_invocation_conversion_p (dest, source) valid_method_invocation_conversion_p (dest, source)
tree dest, source; tree dest, source;
{ {
return ((JPRIMITIVE_TYPE_P (source) return (((JPRIMITIVE_TYPE_P (source) || (source == integer_zero_node))
&& JPRIMITIVE_TYPE_P (dest) && JPRIMITIVE_TYPE_P (dest)
&& valid_builtin_assignconv_identity_widening_p (dest, source)) && valid_builtin_assignconv_identity_widening_p (dest, source))
|| ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source)) || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
...@@ -10894,24 +10972,8 @@ patch_binop (node, wfl_op1, wfl_op2) ...@@ -10894,24 +10972,8 @@ patch_binop (node, wfl_op1, wfl_op2)
after checking for the initialization of the RHS */ after checking for the initialization of the RHS */
int error_found = 0; int error_found = 0;
/* Figure what is going to be checked first for initialization prior
its use. If NODE is part of a compound assignment, we check the
second operand first, otherwise the first one first. We also
initialize the matching WFL for the error report. `cfi' stands
for Check For Initialization */
tree cfi = (COMPOUND_ASSIGN_P (node) ? op2 : op1);
tree cfi_wfl = (COMPOUND_ASSIGN_P (node) ? wfl_op2 : wfl_op1);
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node); EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
/* Check initialization of LHS first. We then silence further error
message if the variable wasn't initialized */
if (not_initialized_as_it_should_p (cfi))
{
ERROR_VARIABLE_NOT_INITIALIZED (cfi_wfl, DECL_NAME (cfi));
INITIALIZED_P (op1) = 1;
}
switch (code) switch (code)
{ {
/* 15.16 Multiplicative operators */ /* 15.16 Multiplicative operators */
...@@ -11189,16 +11251,6 @@ patch_binop (node, wfl_op1, wfl_op2) ...@@ -11189,16 +11251,6 @@ patch_binop (node, wfl_op1, wfl_op2)
break; break;
} }
/* Then check the initialization of the RHS. We don't do that if
we're dealing with a node that is part of a compound
assignment. We then silence further error message if the variable
wasn't initialized */
if (not_initialized_as_it_should_p (op2) && !COMPOUND_ASSIGN_P (node))
{
ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (op2));
INITIALIZED_P (op2) = 1;
}
if (error_found) if (error_found)
return error_mark_node; return error_mark_node;
...@@ -11374,8 +11426,15 @@ patch_string (node) ...@@ -11374,8 +11426,15 @@ patch_string (node)
return patch_string_cst (node); return patch_string_cst (node);
else if (IS_CRAFTED_STRING_BUFFER_P (node)) else if (IS_CRAFTED_STRING_BUFFER_P (node))
{ {
int saved = ctxp->explicit_constructor_p;
tree invoke = build_method_invocation (wfl_to_string, NULL_TREE); tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
return java_complete_tree (make_qualified_primary (node, invoke, 0)); tree ret;
/* Temporary disable forbid the use of `this'. */
ctxp->explicit_constructor_p = 0;
ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
/* Restore it at its previous value */
ctxp->explicit_constructor_p = saved;
return ret;
} }
return NULL_TREE; return NULL_TREE;
} }
...@@ -11573,6 +11632,8 @@ patch_unaryop (node, wfl_op) ...@@ -11573,6 +11632,8 @@ patch_unaryop (node, wfl_op)
if (TREE_CODE (op_type) != BOOLEAN_TYPE) if (TREE_CODE (op_type) != BOOLEAN_TYPE)
{ {
ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type); ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
/* But the type is known. We will report an error if further
attempt of a assignment is made with this rhs */
TREE_TYPE (node) = boolean_type_node; TREE_TYPE (node) = boolean_type_node;
error_found = 1; error_found = 1;
} }
...@@ -11584,8 +11645,15 @@ patch_unaryop (node, wfl_op) ...@@ -11584,8 +11645,15 @@ patch_unaryop (node, wfl_op)
case CONVERT_EXPR: case CONVERT_EXPR:
value = patch_cast (node, wfl_operator); value = patch_cast (node, wfl_operator);
if (value == error_mark_node) if (value == error_mark_node)
return value; {
node = value; /* If this cast is part of an assignment, we tell the code
that deals with it not to complain about a mismatch,
because things have been cast, anyways */
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
else
node = value;
break; break;
} }
...@@ -11725,8 +11793,8 @@ build_array_ref (location, array, index) ...@@ -11725,8 +11793,8 @@ build_array_ref (location, array, index)
/* 15.12 Array Access Expression */ /* 15.12 Array Access Expression */
static tree static tree
patch_array_ref (node, wfl_array, wfl_index) patch_array_ref (node)
tree node, wfl_array, wfl_index; tree node;
{ {
tree array = TREE_OPERAND (node, 0); tree array = TREE_OPERAND (node, 0);
tree array_type = TREE_TYPE (array); tree array_type = TREE_TYPE (array);
...@@ -12032,10 +12100,8 @@ build_if_else_statement (location, expression, if_body, else_body) ...@@ -12032,10 +12100,8 @@ build_if_else_statement (location, expression, if_body, else_body)
tree expression, if_body, else_body; tree expression, if_body, else_body;
{ {
tree node; tree node;
/* FIXME: make else body be a void node, where this function is
called */
if (!else_body) if (!else_body)
else_body = build (COMPOUND_EXPR, void_type_node, NULL_TREE, NULL_TREE); else_body = empty_stmt_node;
node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body); node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
EXPR_WFL_LINECOL (node) = location; EXPR_WFL_LINECOL (node) = location;
node = build_debugable_stmt (location, node); node = build_debugable_stmt (location, node);
...@@ -12065,8 +12131,8 @@ patch_if_else_statement (node) ...@@ -12065,8 +12131,8 @@ patch_if_else_statement (node)
TREE_TYPE (node) = void_type_node; TREE_TYPE (node) = void_type_node;
TREE_SIDE_EFFECTS (node) = 1; TREE_SIDE_EFFECTS (node) = 1;
CAN_COMPLETE_NORMALLY (node) CAN_COMPLETE_NORMALLY (node)
= CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0)) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
| CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)); | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
return node; return node;
} }
...@@ -12192,7 +12258,7 @@ build_loop_body (location, condition, reversed) ...@@ -12192,7 +12258,7 @@ build_loop_body (location, condition, reversed)
second = (reversed ? condition : body); second = (reversed ? condition : body);
return return
build (COMPOUND_EXPR, NULL_TREE, build (COMPOUND_EXPR, NULL_TREE,
build (COMPOUND_EXPR, NULL_TREE, first, second), size_zero_node); build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
} }
/* Install CONDITION (if any) and loop BODY (using REVERSED to tell /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
...@@ -12439,7 +12505,7 @@ static tree ...@@ -12439,7 +12505,7 @@ static tree
patch_switch_statement (node) patch_switch_statement (node)
tree node; tree node;
{ {
tree se = TREE_OPERAND (node, 0), se_type, sb; tree se = TREE_OPERAND (node, 0), se_type;
/* Complete the switch expression */ /* Complete the switch expression */
se = TREE_OPERAND (node, 0) = java_complete_tree (se); se = TREE_OPERAND (node, 0) = java_complete_tree (se);
...@@ -12468,7 +12534,8 @@ patch_switch_statement (node) ...@@ -12468,7 +12534,8 @@ patch_switch_statement (node)
TREE_TYPE (node) = void_type_node; TREE_TYPE (node) = void_type_node;
TREE_SIDE_EFFECTS (node) = 1; TREE_SIDE_EFFECTS (node) = 1;
CAN_COMPLETE_NORMALLY (node) CAN_COMPLETE_NORMALLY (node)
= CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) || ! SWITCH_HAS_DEFAULT (node); = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
|| ! SWITCH_HAS_DEFAULT (node);
return node; return node;
} }
...@@ -12516,8 +12583,7 @@ build_try_statement (location, try_block, catches, finally) ...@@ -12516,8 +12583,7 @@ build_try_statement (location, try_block, catches, finally)
sequence. It hold a local variable used to return from the sequence. It hold a local variable used to return from the
finally using a computed goto. We call it finally using a computed goto. We call it
return_from_finally (RFF). */ return_from_finally (RFF). */
rff = build_decl_no_layout (VAR_DECL, generate_name (), rff = build_decl (VAR_DECL, generate_name (), return_address_type_node);
return_address_type_node);
/* Modification of the try block. */ /* Modification of the try block. */
try_block = build_jump_to_finally (try_block, rff, try_block = build_jump_to_finally (try_block, rff,
...@@ -12552,8 +12618,7 @@ build_try_statement (location, try_block, catches, finally) ...@@ -12552,8 +12618,7 @@ build_try_statement (location, try_block, catches, finally)
CALL_EXPR CALL_EXPR
Jv_ReThrow Jv_ReThrow
exception_parameter */ exception_parameter */
catch_decl = build_decl_no_layout (VAR_DECL, generate_name (), catch_decl = build_decl (VAR_DECL, generate_name (), ptr_type_node);
ptr_type_node);
BUILD_ASSIGN_EXCEPTION_INFO (stmt, catch_decl); BUILD_ASSIGN_EXCEPTION_INFO (stmt, catch_decl);
catch_block = build_expr_block (stmt, NULL_TREE); catch_block = build_expr_block (stmt, NULL_TREE);
catch_block = build_jump_to_finally (catch_block, rff, catch_block = build_jump_to_finally (catch_block, rff,
...@@ -12685,7 +12750,6 @@ patch_try_statement (node) ...@@ -12685,7 +12750,6 @@ patch_try_statement (node)
break; break;
} }
} }
/* Complete the catch clause block */ /* Complete the catch clause block */
catch_block = java_complete_tree (TREE_OPERAND (current, 0)); catch_block = java_complete_tree (TREE_OPERAND (current, 0));
if (catch_block == error_mark_node) if (catch_block == error_mark_node)
...@@ -12704,7 +12768,6 @@ patch_try_statement (node) ...@@ -12704,7 +12768,6 @@ patch_try_statement (node)
/* Link this type to the caught type list */ /* Link this type to the caught type list */
caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list); caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
} }
PUSH_EXCEPTIONS (caught_type_list); PUSH_EXCEPTIONS (caught_type_list);
...@@ -12782,7 +12845,7 @@ patch_synchronized_statement (node, wfl_op1) ...@@ -12782,7 +12845,7 @@ patch_synchronized_statement (node, wfl_op1)
try_block = build_expr_block (compound, NULL_TREE); try_block = build_expr_block (compound, NULL_TREE);
/* CATCH_ALL block */ /* CATCH_ALL block */
decl = build_decl_no_layout (VAR_DECL, generate_name (), ptr_type_node); decl = build_decl (VAR_DECL, generate_name (), ptr_type_node);
BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl); BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl);
compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt); compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt);
BUILD_MONITOR_EXIT (stmt, expr); BUILD_MONITOR_EXIT (stmt, expr);
...@@ -12824,7 +12887,7 @@ patch_throw_statement (node, wfl_op1) ...@@ -12824,7 +12887,7 @@ patch_throw_statement (node, wfl_op1)
/* The type of the throw expression is a not checked exception, /* The type of the throw expression is a not checked exception,
i.e. is a unchecked expression. */ i.e. is a unchecked expression. */
unchecked_ok = IS_UNCHECKED_EXPRESSION_P (TREE_TYPE (type)); unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
/* Throw is contained in a try statement and at least one catch /* Throw is contained in a try statement and at least one catch
clause can receive the thrown expression or the current method is clause can receive the thrown expression or the current method is
...@@ -12897,7 +12960,7 @@ check_thrown_exceptions (location, decl) ...@@ -12897,7 +12960,7 @@ check_thrown_exceptions (location, decl)
} }
} }
/* Return 1 if EXCEPTION is caught at the current nesting level of /* Return 1 if checked EXCEPTION is caught at the current nesting level of
try-catch blocks, OR is listed in the `throws' clause of the try-catch blocks, OR is listed in the `throws' clause of the
current method. */ current method. */
...@@ -12906,8 +12969,11 @@ check_thrown_exceptions_do (exception) ...@@ -12906,8 +12969,11 @@ check_thrown_exceptions_do (exception)
tree exception; tree exception;
{ {
tree list = currently_caught_type_list; tree list = currently_caught_type_list;
resolve_and_layout (exception, NULL_TREE);
/* First, all the nested try-catch-finally at that stage. The /* First, all the nested try-catch-finally at that stage. The
last element contains `throws' clause exceptions, if any. */ last element contains `throws' clause exceptions, if any. */
if (IS_UNCHECKED_EXCEPTION_P (exception))
return 1;
while (list) while (list)
{ {
tree caught; tree caught;
...@@ -12929,7 +12995,7 @@ purge_unchecked_exceptions (mdecl) ...@@ -12929,7 +12995,7 @@ purge_unchecked_exceptions (mdecl)
while (throws) while (throws)
{ {
tree next = TREE_CHAIN (throws); tree next = TREE_CHAIN (throws);
if (!IS_UNCHECKED_EXPRESSION_P (TREE_VALUE (throws))) if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
{ {
TREE_CHAIN (throws) = new; TREE_CHAIN (throws) = new;
new = throws; new = throws;
......
...@@ -122,11 +122,18 @@ extern tree stabilize_reference PROTO ((tree)); ...@@ -122,11 +122,18 @@ extern tree stabilize_reference PROTO ((tree));
(s1 [0]=='S' ? "Supertype" : "supertype") : \ (s1 [0]=='S' ? "Supertype" : "supertype") : \
(s1 [0] > 'A' ? "Type" : "type"))) (s1 [0] > 'A' ? "Type" : "type")))
#define GET_REAL_TYPE(TYPE) \
(TREE_CODE (TYPE) == TREE_LIST ? TREE_PURPOSE (TYPE) : TYPE)
#define GET_METHOD_NAME(METHOD) \
(TREE_CODE (DECL_NAME (METHOD)) == EXPR_WITH_FILE_LOCATION ? \
EXPR_WFL_NODE (DECL_NAME (METHOD)) : DECL_NAME (METHOD))
/* Pedantic warning on obsolete modifiers. Note: when cl is NULL, /* Pedantic warning on obsolete modifiers. Note: when cl is NULL,
flags was set artificially, such as for a interface method */ flags was set artificially, such as for a interface method */
#define OBSOLETE_MODIFIER_WARNING(cl, flags, modifier, format, arg) \ #define OBSOLETE_MODIFIER_WARNING(cl, flags, modifier, format, arg) \
{ \ { \
if ((cl) && ((flags) & (modifier))) \ if (flag_redundant && (cl) && ((flags) & (modifier))) \
parse_warning_context (cl, \ parse_warning_context (cl, \
"Discouraged redundant use of `%s' modifier " \ "Discouraged redundant use of `%s' modifier " \
"in declaration of " format, \ "in declaration of " format, \
...@@ -411,22 +418,31 @@ static jdeplist *reverse_jdep_list (); ...@@ -411,22 +418,31 @@ static jdeplist *reverse_jdep_list ();
/* if TYPE can't be resolved, obtain something suitable for its /* if TYPE can't be resolved, obtain something suitable for its
resolution (TYPE is saved in SAVE before being changed). and set resolution (TYPE is saved in SAVE before being changed). and set
CHAIN to 1. Otherwise, type is set to something usable. CHAIN is CHAIN to 1. Otherwise, type is set to something usable. CHAIN is
usually used to determine that a new DEP must be installed on TYPE. */ usually used to determine that a new DEP must be installed on TYPE.
#define SET_TYPE_FOR_RESOLUTION(TYPE, SAVE, CHAIN) \ Note that when compiling java.lang.Object, references to Object are
{ \ java.lang.Object. */
tree returned_type; \ #define SET_TYPE_FOR_RESOLUTION(TYPE, SAVE, CHAIN) \
(CHAIN) = 0; \ { \
if (unresolved_type_p (type, &returned_type)) \ tree returned_type; \
{ \ (CHAIN) = 0; \
if (returned_type) \ if (TREE_TYPE (ctxp->current_parsed_class) == object_type_node \
(TYPE) = returned_type; \ && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION \
else \ && EXPR_WFL_NODE (TYPE) == unqualified_object_id_node) \
{ \ (TYPE) = object_type_node; \
(SAVE) = (TYPE); \ else \
(TYPE) = obtain_incomplete_type (TYPE); \ { \
CHAIN = 1; \ if (unresolved_type_p (type, &returned_type)) \
} \ { \
} \ if (returned_type) \
(TYPE) = returned_type; \
else \
{ \
(SAVE) = (TYPE); \
(TYPE) = obtain_incomplete_type (TYPE); \
CHAIN = 1; \
} \
} \
} \
} }
/* Insert a DECL in the current block */ /* Insert a DECL in the current block */
...@@ -489,7 +505,8 @@ static jdeplist *reverse_jdep_list (); ...@@ -489,7 +505,8 @@ static jdeplist *reverse_jdep_list ();
{ \ { \
(WHERE) = build (CALL_EXPR, int_type_node, \ (WHERE) = build (CALL_EXPR, int_type_node, \
build_address_of (soft_monitorenter_node), \ build_address_of (soft_monitorenter_node), \
build_tree_list (NULL_TREE, (ARG))); \ build_tree_list (NULL_TREE, (ARG)), \
NULL_TREE); \
TREE_SIDE_EFFECTS (WHERE) = 1; \ TREE_SIDE_EFFECTS (WHERE) = 1; \
} }
...@@ -497,7 +514,8 @@ static jdeplist *reverse_jdep_list (); ...@@ -497,7 +514,8 @@ static jdeplist *reverse_jdep_list ();
{ \ { \
(WHERE) = build (CALL_EXPR, int_type_node, \ (WHERE) = build (CALL_EXPR, int_type_node, \
build_address_of (soft_monitorexit_node), \ build_address_of (soft_monitorexit_node), \
build_tree_list (NULL_TREE, (ARG))); \ build_tree_list (NULL_TREE, (ARG)), \
NULL_TREE); \
TREE_SIDE_EFFECTS (WHERE) = 1; \ TREE_SIDE_EFFECTS (WHERE) = 1; \
} }
...@@ -709,18 +727,18 @@ static tree try_reference_assignconv PROTO ((tree, tree)); ...@@ -709,18 +727,18 @@ static tree try_reference_assignconv PROTO ((tree, tree));
static tree build_unresolved_array_type PROTO ((tree)); static tree build_unresolved_array_type PROTO ((tree));
static tree build_array_from_name PROTO ((tree, tree, tree, tree *)); static tree build_array_from_name PROTO ((tree, tree, tree, tree *));
static tree build_array_ref PROTO ((int, tree, tree)); static tree build_array_ref PROTO ((int, tree, tree));
static tree patch_array_ref PROTO ((tree, tree, tree)); static tree patch_array_ref PROTO ((tree));
static tree make_qualified_name PROTO ((tree, tree, int)); static tree make_qualified_name PROTO ((tree, tree, int));
static tree merge_qualified_name PROTO ((tree, tree)); static tree merge_qualified_name PROTO ((tree, tree));
static tree make_qualified_primary PROTO ((tree, tree, int)); static tree make_qualified_primary PROTO ((tree, tree, int));
static int resolve_qualified_expression_name PROTO ((tree, tree *, tree *, tree *)); static int resolve_qualified_expression_name PROTO ((tree, tree *,
tree *, tree *));
static void qualify_ambiguous_name PROTO ((tree)); static void qualify_ambiguous_name PROTO ((tree));
static void maybe_generate_clinit PROTO ((void)); static void maybe_generate_clinit PROTO ((void));
static tree resolve_field_access PROTO ((tree, tree *, tree *)); static tree resolve_field_access PROTO ((tree, tree *, tree *));
static tree build_newarray_node PROTO ((tree, tree, int)); static tree build_newarray_node PROTO ((tree, tree, int));
static tree patch_newarray PROTO ((tree)); static tree patch_newarray PROTO ((tree));
static tree resolve_type_during_patch PROTO ((tree)); static tree resolve_type_during_patch PROTO ((tree));
static int not_initialized_as_it_should_p PROTO ((tree));
static tree build_this PROTO ((int)); static tree build_this PROTO ((int));
static tree build_return PROTO ((int, tree)); static tree build_return PROTO ((int, tree));
static tree patch_return PROTO ((tree)); static tree patch_return PROTO ((tree));
...@@ -791,6 +809,7 @@ tree java_method_add_stmt PROTO ((tree, tree)); ...@@ -791,6 +809,7 @@ tree java_method_add_stmt PROTO ((tree, tree));
char *java_get_line_col PROTO ((char *, int, int)); char *java_get_line_col PROTO ((char *, int, int));
void java_expand_switch PROTO ((tree)); void java_expand_switch PROTO ((tree));
tree java_get_catch_block PROTO ((tree, int)); tree java_get_catch_block PROTO ((tree, int));
int java_report_errors PROTO (());
#endif /* JC1_LITE */ #endif /* JC1_LITE */
/* Always in use, no matter what you compile */ /* Always in use, no matter what you compile */
......
...@@ -701,8 +701,8 @@ formal_parameter: ...@@ -701,8 +701,8 @@ formal_parameter:
{ {
$$ = build_tree_list ($2, $1); $$ = build_tree_list ($2, $1);
} }
| modifiers type variable_declarator_id /* Added, JDK1.1 final locals */ | modifiers type variable_declarator_id /* Added, JDK1.1 final parms */
{ $$ = parse_jdk1_1_error ("final local"); } { $$ = parse_jdk1_1_error ("final parameters"); }
| type error | type error
{yyerror ("Missing identifier"); RECOVER;} {yyerror ("Missing identifier"); RECOVER;}
| modifiers type error | modifiers type error
...@@ -722,9 +722,9 @@ throws: ...@@ -722,9 +722,9 @@ throws:
class_type_list: class_type_list:
class_type class_type
{ $$ = build_tree_list (NULL_TREE, $1); } { $$ = build_tree_list ($1, $1); }
| class_type_list C_TK class_type | class_type_list C_TK class_type
{ $$ = tree_cons (NULL_TREE, $3, $1); } { $$ = tree_cons ($3, $3, $1); }
| class_type_list C_TK error | class_type_list C_TK error
{yyerror ("Missing class type term"); RECOVER;} {yyerror ("Missing class type term"); RECOVER;}
; ;
...@@ -1507,11 +1507,11 @@ primary_no_new_array: ...@@ -1507,11 +1507,11 @@ primary_no_new_array:
'type' into its components. Missing is something for array, 'type' into its components. Missing is something for array,
which will complete the reference_type part. FIXME */ which will complete the reference_type part. FIXME */
| name DOT_TK CLASS_TK /* Added, JDK1.1 class literals */ | name DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
{ $$ = parse_jdk1_1_error ("class literals"); } { $$ = parse_jdk1_1_error ("named class literals"); }
| primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */ | primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
{ $$ = parse_jdk1_1_error ("class literals"); } { $$ = build_class_ref ($1); }
| VOID_TK DOT_TK CLASS_TK /* Added, JDK1.1 class literals */ | VOID_TK DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
{ $$ = parse_jdk1_1_error ("class literals"); } { $$ = build_class_ref (void_type_node); }
/* Added, JDK1.1 inner classes. Documentation is wrong /* Added, JDK1.1 inner classes. Documentation is wrong
refering to a 'ClassName' (class_name) rule that doesn't refering to a 'ClassName' (class_name) rule that doesn't
exist. Used name instead. */ exist. Used name instead. */
...@@ -2298,13 +2298,13 @@ parse_warning_context VPROTO ((tree cl, char *msg, ...)) ...@@ -2298,13 +2298,13 @@ parse_warning_context VPROTO ((tree cl, char *msg, ...))
msg = va_arg (ap, char *); msg = va_arg (ap, char *);
#endif #endif
do_warning = 1; force_error = do_warning = 1;
issue_warning_error_from_context (cl, msg, ap); issue_warning_error_from_context (cl, msg, ap);
force_error = 0; do_warning = force_error = 0;
va_end (ap); va_end (ap);
} }
void int
java_report_errors () java_report_errors ()
{ {
if (java_error_count) if (java_error_count)
...@@ -2315,6 +2315,7 @@ java_report_errors () ...@@ -2315,6 +2315,7 @@ java_report_errors ()
java_warning_count, (java_warning_count == 1 ? "" : "s")); java_warning_count, (java_warning_count == 1 ? "" : "s"));
if (java_error_count || java_warning_count) if (java_error_count || java_warning_count)
putc ('\n', stderr); putc ('\n', stderr);
return java_error_count;
} }
static char * static char *
...@@ -2365,8 +2366,8 @@ variable_redefinition_error (context, name, type, line) ...@@ -2365,8 +2366,8 @@ variable_redefinition_error (context, name, type, line)
char *type_name; char *type_name;
/* Figure a proper name for type. We might haven't resolved it */ /* Figure a proper name for type. We might haven't resolved it */
if (TREE_CODE (type) == TREE_LIST) if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
type_name = IDENTIFIER_POINTER (TYPE_NAME (TREE_PURPOSE (type))); type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
else else
type_name = lang_printable_name (type, 0); type_name = lang_printable_name (type, 0);
...@@ -2629,10 +2630,10 @@ create_interface (flags, id, super) ...@@ -2629,10 +2630,10 @@ create_interface (flags, id, super)
- public/abstract allowed (already done at that point) - public/abstract allowed (already done at that point)
- abstract is obsolete (comes first, it's a warning, or should be) - abstract is obsolete (comes first, it's a warning, or should be)
- Can't use twice the same (checked in the modifier rule) */ - Can't use twice the same (checked in the modifier rule) */
if (flags & ACC_ABSTRACT) if ((flags & ACC_ABSTRACT) && flag_redundant)
parse_warning_context parse_warning_context
(MODIFIER_WFL (ABSTRACT_TK), (MODIFIER_WFL (ABSTRACT_TK),
"Obsolete use of `abstract' modifier. Interface `%s' is implicitely " "Redundant use of `abstract' modifier. Interface `%s' is implicitely "
"abstract", IDENTIFIER_POINTER (raw_name)); "abstract", IDENTIFIER_POINTER (raw_name));
if (flags & ACC_PUBLIC && flags & ACC_ABSTRACT) if (flags & ACC_PUBLIC && flags & ACC_ABSTRACT)
parse_error_context parse_error_context
...@@ -2751,7 +2752,9 @@ lookup_field_wrapper (class, name) ...@@ -2751,7 +2752,9 @@ lookup_field_wrapper (class, name)
tree class, name; tree class, name;
{ {
tree type = class; tree type = class;
java_parser_context_save_global ();
return lookup_field (&type, name); return lookup_field (&type, name);
java_parser_context_restore_global ();
} }
/* Find duplicate field within the same class declarations and report /* Find duplicate field within the same class declarations and report
...@@ -2768,11 +2771,12 @@ duplicate_declaration_error_p (new_field_name, new_type, cl) ...@@ -2768,11 +2771,12 @@ duplicate_declaration_error_p (new_field_name, new_type, cl)
if (decl) if (decl)
{ {
char *t1 = strdup (lang_printable_name (new_type, 1)); char *t1 = strdup (lang_printable_name (new_type, 1));
char *t2 = /* The type may not have been completed by the time we report
strdup ((TREE_CODE (TREE_TYPE (decl)) == TREE_LIST ? the error */
IDENTIFIER_POINTER (TYPE_NAME char *t2 = strdup (((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
(TREE_PURPOSE (TREE_TYPE (decl)))) : && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
lang_printable_name (TREE_TYPE (decl), 1))); IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
lang_printable_name (TREE_TYPE (decl), 1)));
parse_error_context parse_error_context
(cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)",
t1, IDENTIFIER_POINTER (new_field_name), t1, IDENTIFIER_POINTER (new_field_name),
...@@ -2827,6 +2831,7 @@ register_fields (flags, type, variable_list) ...@@ -2827,6 +2831,7 @@ register_fields (flags, type, variable_list)
for (current = variable_list, saved_type = type; current; for (current = variable_list, saved_type = type; current;
current = TREE_CHAIN (current), type = saved_type) current = TREE_CHAIN (current), type = saved_type)
{ {
tree real_type;
tree field_decl; tree field_decl;
tree cl = TREE_PURPOSE (current); tree cl = TREE_PURPOSE (current);
tree init = TREE_VALUE (current); tree init = TREE_VALUE (current);
...@@ -2835,10 +2840,6 @@ register_fields (flags, type, variable_list) ...@@ -2835,10 +2840,6 @@ register_fields (flags, type, variable_list)
/* Process NAME, as it may specify extra dimension(s) for it */ /* Process NAME, as it may specify extra dimension(s) for it */
type = build_array_from_name (type, wfl, current_name, &current_name); type = build_array_from_name (type, wfl, current_name, &current_name);
/* Check for redeclarations */
if (duplicate_declaration_error_p (current_name, type, cl))
continue;
/* Type adjustment. We may have just readjusted TYPE because /* Type adjustment. We may have just readjusted TYPE because
the variable specified more dimensions. Make sure we have the variable specified more dimensions. Make sure we have
a reference if we can and don't have one already. Also a reference if we can and don't have one already. Also
...@@ -2851,10 +2852,15 @@ register_fields (flags, type, variable_list) ...@@ -2851,10 +2852,15 @@ register_fields (flags, type, variable_list)
EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name; EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
} }
real_type = GET_REAL_TYPE (type);
/* Check for redeclarations */
if (duplicate_declaration_error_p (current_name, real_type, cl))
continue;
/* Set lineno to the line the field was found and create a /* Set lineno to the line the field was found and create a
declaration for it. Eventually sets the @deprecated tag flag. */ declaration for it. Eventually sets the @deprecated tag flag. */
lineno = EXPR_WFL_LINENO (cl); lineno = EXPR_WFL_LINENO (cl);
field_decl = add_field (class_type, current_name, type, flags); field_decl = add_field (class_type, current_name, real_type, flags);
CHECK_DEPRECATED (field_decl); CHECK_DEPRECATED (field_decl);
/* Check if we must chain. */ /* Check if we must chain. */
...@@ -2879,6 +2885,8 @@ register_fields (flags, type, variable_list) ...@@ -2879,6 +2885,8 @@ register_fields (flags, type, variable_list)
permalloc (sizeof (struct lang_decl_var)); permalloc (sizeof (struct lang_decl_var));
DECL_LOCAL_STATIC_VALUE (field_decl) = DECL_LOCAL_STATIC_VALUE (field_decl) =
TREE_OPERAND (init, 1); TREE_OPERAND (init, 1);
if (TREE_CONSTANT (TREE_OPERAND (init, 1)))
DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
} }
/* Otherwise, the field should be initialized in <clinit>. /* Otherwise, the field should be initialized in <clinit>.
This field is remembered so we can generate <clinit> later */ This field is remembered so we can generate <clinit> later */
...@@ -3073,9 +3081,11 @@ method_header (flags, type, mdecl, throws) ...@@ -3073,9 +3081,11 @@ method_header (flags, type, mdecl, throws)
TREE_TYPE (meth) = returned_type; TREE_TYPE (meth) = returned_type;
else else
{ {
tree itype;
patch_stage = JDEP_METHOD_RETURN; patch_stage = JDEP_METHOD_RETURN;
TREE_TYPE (meth) = itype = register_incomplete_type (patch_stage, type, id, NULL_TREE);
register_incomplete_type (patch_stage, type, id, NULL_TREE); TREE_TYPE (meth) = (TREE_CODE (itype) == TREE_LIST ?
TREE_PURPOSE (itype) : itype);
} }
} }
else else
...@@ -3277,8 +3287,7 @@ check_abstract_method_header (meth) ...@@ -3277,8 +3287,7 @@ check_abstract_method_header (meth)
{ {
int flags = get_access_flags_from_decl (meth); int flags = get_access_flags_from_decl (meth);
/* DECL_NAME might still be a WFL node */ /* DECL_NAME might still be a WFL node */
tree name = (TREE_CODE (DECL_NAME (meth)) == EXPR_WITH_FILE_LOCATION ? tree name = GET_METHOD_NAME (meth);
EXPR_WFL_NODE (DECL_NAME (meth)) : DECL_NAME (meth));
OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags, OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags,
ACC_ABSTRACT, "abstract method `%s'", ACC_ABSTRACT, "abstract method `%s'",
...@@ -3509,6 +3518,7 @@ obtain_incomplete_type (wfl) ...@@ -3509,6 +3518,7 @@ obtain_incomplete_type (wfl)
tree core; tree core;
push_obstacks (&permanent_obstack, &permanent_obstack); push_obstacks (&permanent_obstack, &permanent_obstack);
BUILD_PTR_FROM_NAME (core, name); BUILD_PTR_FROM_NAME (core, name);
layout_type (core);
ptr = build_tree_list (core, NULL_TREE); ptr = build_tree_list (core, NULL_TREE);
pop_obstacks (); pop_obstacks ();
TREE_CHAIN (ptr) = ctxp->incomplete_class; TREE_CHAIN (ptr) = ctxp->incomplete_class;
...@@ -3590,10 +3600,6 @@ safe_layout_class (class) ...@@ -3590,10 +3600,6 @@ safe_layout_class (class)
push_obstacks (&permanent_obstack, &permanent_obstack); push_obstacks (&permanent_obstack, &permanent_obstack);
if (!CLASS_METHOD_CHECKED_P (class))
CHECK_METHODS (TYPE_NAME (class));
CLASS_METHOD_CHECKED_P (class) = 1;
layout_class (class); layout_class (class);
pop_obstacks (); pop_obstacks ();
...@@ -3646,7 +3652,7 @@ java_complete_class () ...@@ -3646,7 +3652,7 @@ java_complete_class ()
/* Rever things so we have the right order */ /* Rever things so we have the right order */
ctxp->class_list = nreverse (ctxp->class_list); ctxp->class_list = nreverse (ctxp->class_list);
ctxp->classd_list = reverse_jdep_list (ctxp); ctxp->classd_list = reverse_jdep_list (ctxp);
for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
cclass && cclassd; cclass && cclassd;
cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd)) cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
...@@ -3655,7 +3661,6 @@ java_complete_class () ...@@ -3655,7 +3661,6 @@ java_complete_class ()
for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep)) for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
{ {
tree decl; tree decl;
if (!(decl = jdep_resolve_class (dep))) if (!(decl = jdep_resolve_class (dep)))
continue; continue;
...@@ -3751,21 +3756,10 @@ java_complete_class () ...@@ -3751,21 +3756,10 @@ java_complete_class ()
break; break;
case JDEP_EXCEPTION: case JDEP_EXCEPTION:
/* Check for righteous inheritance here */ JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
if (!inherits_from_p (TREE_TYPE (decl), throwable_type_node)) SOURCE_FRONTEND_DEBUG
{ (("Completing `%s' `throws' argument node",
parse_error_context IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
(JDEP_WFL (dep), "Class `%s' in `throws' clause must be "
"a subclass of class `java.lang.Throwable'",
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
}
else
{
JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
SOURCE_FRONTEND_DEBUG
(("Completing `%s' `throws' argument node",
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
}
break; break;
default: default:
...@@ -3890,11 +3884,23 @@ do_resolve_class (class_type, decl, cl) ...@@ -3890,11 +3884,23 @@ do_resolve_class (class_type, decl, cl)
parsed class). Return a decl node. */ parsed class). Return a decl node. */
static tree static tree
resolve_and_layout (name, cl) resolve_and_layout (something, cl)
tree name; tree something;
tree cl; tree cl;
{ {
tree decl = resolve_no_layout (name, cl); tree decl;
if (TREE_CODE (something) == POINTER_TYPE)
something = TREE_TYPE (something);
if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
return NULL_TREE;
if (TREE_CODE (something) != IDENTIFIER_NODE)
something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
decl = resolve_no_layout (something, cl);
if (decl && TREE_TYPE (decl) != current_class if (decl && TREE_TYPE (decl) != current_class
&& !CLASS_LOADED_P (TREE_TYPE (decl))) && !CLASS_LOADED_P (TREE_TYPE (decl)))
safe_layout_class (TREE_TYPE (decl)); safe_layout_class (TREE_TYPE (decl));
...@@ -4034,16 +4040,30 @@ reset_method_name (method) ...@@ -4034,16 +4040,30 @@ reset_method_name (method)
{ {
/* NAME is just the plain name when Object is being defined */ /* NAME is just the plain name when Object is being defined */
if (DECL_CONTEXT (method) != object_type_node) if (DECL_CONTEXT (method) != object_type_node)
DECL_NAME (method) = DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ?
(DECL_CONSTRUCTOR_P (method) ? init_identifier_node : init_identifier_node : GET_METHOD_NAME (method));
(TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION ?
EXPR_WFL_NODE (DECL_NAME (method)) : DECL_NAME (method)));
return 0; return 0;
} }
else else
return 1; return 1;
} }
/* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
tree
java_get_real_method_name (method_decl)
tree method_decl;
{
tree method_name = DECL_NAME (method_decl);
if (DECL_CONSTRUCTOR_P (method_decl))
return init_identifier_node;
else if (ctxp
&& ctxp->current_parsed_class_un == EXPR_WFL_NODE (method_name))
return init_identifier_node;
else
return EXPR_WFL_NODE (method_name);
}
/* Track method being redefined inside the same class. As a side /* Track method being redefined inside the same class. As a side
effect, set DECL_NAME to an IDENTIFIER (prior entering this 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 */
...@@ -4097,6 +4117,11 @@ java_check_regular_methods (class_decl) ...@@ -4097,6 +4117,11 @@ java_check_regular_methods (class_decl)
tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl)); tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
tree super_class = CLASSTYPE_SUPER (class); tree super_class = CLASSTYPE_SUPER (class);
tree saved_found_wfl = NULL_TREE, found = NULL_TREE; tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
tree mthrows;
/* It is not necessary to check methods defined in java.lang.Object */
if (class == object_type_node)
return;
TYPE_METHODS (class) = nreverse (TYPE_METHODS (class)); TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
...@@ -4125,6 +4150,19 @@ java_check_regular_methods (class_decl) ...@@ -4125,6 +4150,19 @@ java_check_regular_methods (class_decl)
continue; continue;
} }
/* We verify things thrown by the method. They must inherits from
java.lang.Throwable */
for (mthrows = DECL_FUNCTION_THROWS (method);
mthrows; mthrows = TREE_CHAIN (mthrows))
{
if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
parse_error_context
(TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be "
"a subclass of class `java.lang.Throwable'",
IDENTIFIER_POINTER
(DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
}
sig = build_java_argument_signature (TREE_TYPE (method)); sig = build_java_argument_signature (TREE_TYPE (method));
found = lookup_argument_method (super_class, DECL_NAME (method), sig); found = lookup_argument_method (super_class, DECL_NAME (method), sig);
...@@ -4208,14 +4246,14 @@ java_check_regular_methods (class_decl) ...@@ -4208,14 +4246,14 @@ java_check_regular_methods (class_decl)
exceptions, if any */ exceptions, if any */
check_throws_clauses (method, method_wfl, found); check_throws_clauses (method, method_wfl, found);
#if 0
/* If the method has default access in an other package, then /* If the method has default access in an other package, then
issue a warning that the current method doesn't override the issue a warning that the current method doesn't override the
one that was found elsewhere. Do not issue this warning when one that was found elsewhere. Do not issue this warning when
the match was found in java.lang.Object. */ the match was found in java.lang.Object. */
if (DECL_CONTEXT (found) != object_type_node if (DECL_CONTEXT (found) != object_type_node
&& (!aflags || (aflags > ACC_PROTECTED)) && (!aflags || (aflags > ACC_PROTECTED))
&& !class_in_current_package (DECL_CONTEXT (found))) && !class_in_current_package (DECL_CONTEXT (found))
&& flag_not_overriding)
parse_warning_context parse_warning_context
(method_wfl, "Method `%s' in class `%s' does not " (method_wfl, "Method `%s' in class `%s' does not "
"override the corresponding method in class `%s', which is " "override the corresponding method in class `%s', which is "
...@@ -4223,7 +4261,6 @@ java_check_regular_methods (class_decl) ...@@ -4223,7 +4261,6 @@ java_check_regular_methods (class_decl)
lang_printable_name (found, 0), lang_printable_name (found, 0),
IDENTIFIER_POINTER (DECL_NAME (class_decl)), IDENTIFIER_POINTER (DECL_NAME (class_decl)),
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found))))); IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
#endif
/* Inheriting multiple methods with the same signature. FIXME */ /* Inheriting multiple methods with the same signature. FIXME */
} }
...@@ -4263,11 +4300,15 @@ check_throws_clauses (method, method_wfl, found) ...@@ -4263,11 +4300,15 @@ check_throws_clauses (method, method_wfl, found)
{ {
tree mthrows, fthrows; tree mthrows, fthrows;
/* Can't check these things with class loaded from bytecode. FIXME */
if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
return;
for (mthrows = DECL_FUNCTION_THROWS (method); for (mthrows = DECL_FUNCTION_THROWS (method);
mthrows; mthrows = TREE_CHAIN (mthrows)) mthrows; mthrows = TREE_CHAIN (mthrows))
{ {
/* We don't verify unchecked expressions */ /* We don't verify unchecked expressions */
if (IS_UNCHECKED_EXPRESSION_P (TREE_VALUE (mthrows))) if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
continue; continue;
/* Checked expression must be compatible */ /* Checked expression must be compatible */
for (fthrows = DECL_FUNCTION_THROWS (found); for (fthrows = DECL_FUNCTION_THROWS (found);
...@@ -4376,10 +4417,7 @@ java_check_methods () ...@@ -4376,10 +4417,7 @@ java_check_methods ()
tree current; tree current;
for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current)) for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current)))) if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
{ CHECK_METHODS (TREE_VALUE (current));
CHECK_METHODS (TREE_VALUE (current));
CLASS_METHOD_CHECKED_P (TREE_TYPE (TREE_VALUE (current))) = 1;
}
} }
/* Lookup methods in interfaces using their name and partial /* Lookup methods in interfaces using their name and partial
...@@ -4850,12 +4888,20 @@ declare_local_variables (modifier, type, vlist) ...@@ -4850,12 +4888,20 @@ declare_local_variables (modifier, type, vlist)
{ {
int i; int i;
for (i = 0; i <= 10; i++) if (1 << i & modifier) break; for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
parse_error_context if (modifier == ACC_FINAL)
(ctxp->modifier_ctx [i], {
(modifier == ACC_FINAL ? if (flag_static_local_jdk1_1)
"Unsupported JDK1.1 `final' locals" : parse_warning_context (ctxp->modifier_ctx [i],
"Only `final' is allowed as a local variables modifier")); "Unsupported JDK1.1 `final' local variable "
return; "(treated as non final)");
}
else
{
parse_error_context
(ctxp->modifier_ctx [i],
"Only `final' is allowed as a local variables modifier");
return;
}
} }
/* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
...@@ -4871,7 +4917,7 @@ declare_local_variables (modifier, type, vlist) ...@@ -4871,7 +4917,7 @@ declare_local_variables (modifier, type, vlist)
for (current = vlist, saved_type = type; current; for (current = vlist, saved_type = type; current;
current = TREE_CHAIN (current), type = saved_type) current = TREE_CHAIN (current), type = saved_type)
{ {
tree other; tree other, real_type;
tree wfl = TREE_PURPOSE (current); tree wfl = TREE_PURPOSE (current);
tree name = EXPR_WFL_NODE (wfl); tree name = EXPR_WFL_NODE (wfl);
tree init = TREE_VALUE (current); tree init = TREE_VALUE (current);
...@@ -4893,10 +4939,11 @@ declare_local_variables (modifier, type, vlist) ...@@ -4893,10 +4939,11 @@ declare_local_variables (modifier, type, vlist)
if (type != saved_type && !must_chain if (type != saved_type && !must_chain
&& (TREE_CODE (type) == RECORD_TYPE)) && (TREE_CODE (type) == RECORD_TYPE))
type = promote_type (type); type = promote_type (type);
real_type = GET_REAL_TYPE (type);
/* Never layout this decl. This will be done when its scope /* Never layout this decl. This will be done when its scope
will be entered */ will be entered */
decl = build_decl_no_layout (VAR_DECL, name, type); decl = build_decl (VAR_DECL, name, real_type);
BLOCK_CHAIN_DECL (decl); BLOCK_CHAIN_DECL (decl);
/* Don't try to use an INIT statement when an error was found */ /* Don't try to use an INIT statement when an error was found */
...@@ -4952,8 +4999,8 @@ source_start_java_method (fndecl) ...@@ -4952,8 +4999,8 @@ source_start_java_method (fndecl)
if (INCOMPLETE_TYPE_P (type)) if (INCOMPLETE_TYPE_P (type))
{ {
jdep *jdep; jdep *jdep;
parm_decl = build_decl_no_layout (PARM_DECL, name, type); tree real_type = GET_REAL_TYPE (type);
parm_decl = build_decl (PARM_DECL, name, real_type);
register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type); register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
jdep = CLASSD_LAST (ctxp->classd_list); jdep = CLASSD_LAST (ctxp->classd_list);
JDEP_MISC (jdep) = name; JDEP_MISC (jdep) = name;
...@@ -5148,17 +5195,39 @@ java_layout_classes () ...@@ -5148,17 +5195,39 @@ java_layout_classes ()
{ {
current_class = TREE_TYPE (TREE_VALUE (current)); current_class = TREE_TYPE (TREE_VALUE (current));
/* Reverse the fields if it's necessary (they've already /* Reverse the fields, but leave the dummy field in front.
reversed if the dummy field has been inserted at the Fields are already ordered for Object and Class */
beginning of the list */ if (TYPE_FIELDS (current_class) && current_class != object_type_node
if (TYPE_FIELDS (current_class) && current_class != class_type_node)
&& !DECL_IGNORED_P (TYPE_FIELDS (current_class))) {
TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class)); /* Always leave the dummy field in front if its already there,
and layout the class for proper field offets. */
if (!DECL_NAME (TYPE_FIELDS (current_class)))
{
tree fields = TYPE_FIELDS (current_class);
TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
TYPE_SIZE (current_class) = NULL_TREE;
layout_type (current_class);
}
/* It's time to layout the class */
else
{
TYPE_FIELDS (current_class) =
nreverse (TYPE_FIELDS (current_class));
TYPE_SIZE (current_class) = NULL_TREE;
layout_class (current_class);
}
}
/* Do a layout if necessary */ /* Do a layout if necessary */
if (!TYPE_SIZE (current_class) || (current_class == object_type_node)) if (!TYPE_SIZE (current_class)
|| (current_class == object_type_node)
|| current_class == class_type_node)
safe_layout_class (current_class); safe_layout_class (current_class);
/* From now on, the class is considered completely loaded */
CLASS_LOADED_P (current_class) = 1;
/* Error reported by the caller */ /* Error reported by the caller */
if (java_error_count) if (java_error_count)
return; return;
...@@ -5694,15 +5763,15 @@ resolve_field_access (qual_wfl, field_decl, field_type) ...@@ -5694,15 +5763,15 @@ resolve_field_access (qual_wfl, field_decl, field_type)
type_found, DECL_NAME (decl)); type_found, DECL_NAME (decl));
if (field_ref == error_mark_node) if (field_ref == error_mark_node)
return error_mark_node; return error_mark_node;
if (is_static && !static_final_found if (is_static && !static_final_found && !flag_emit_class_files)
&& ! flag_emit_class_files)
{ {
field_ref = build_class_init (type_found, field_ref); field_ref = build_class_init (type_found, field_ref);
/* If the static field was identified by an expression that /* If the static field was identified by an expression that
needs to be generated, make the field access a compound needs to be generated, make the field access a compound
expression whose first part of the evaluation of the expression whose first part of the evaluation of the
field selector part. */ field selector part. */
if (where_found && TREE_CODE (where_found) != TYPE_DECL) if (where_found && TREE_CODE (where_found) != TYPE_DECL
&& TREE_CODE (where_found) != RECORD_TYPE)
{ {
tree type = QUAL_DECL_TYPE (field_ref); tree type = QUAL_DECL_TYPE (field_ref);
field_ref = build (COMPOUND_EXPR, type, where_found, field_ref); field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
...@@ -5715,7 +5784,8 @@ resolve_field_access (qual_wfl, field_decl, field_type) ...@@ -5715,7 +5784,8 @@ resolve_field_access (qual_wfl, field_decl, field_type)
if (field_decl) if (field_decl)
*field_decl = decl; *field_decl = decl;
if (field_type) if (field_type)
*field_type = QUAL_DECL_TYPE (decl); *field_type = (QUAL_DECL_TYPE (decl) ?
QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
return field_ref; return field_ref;
} }
...@@ -5731,7 +5801,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -5731,7 +5801,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
int previous_call_static = 0; int previous_call_static = 0;
int is_static; int is_static;
tree decl = NULL_TREE, type = NULL_TREE, q; tree decl = NULL_TREE, type = NULL_TREE, q;
*where_found = NULL_TREE; *type_found = *where_found = NULL_TREE;
for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q)) for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
{ {
...@@ -5922,10 +5992,16 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -5922,10 +5992,16 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
if (!from_super && QUAL_RESOLUTION (q)) if (!from_super && QUAL_RESOLUTION (q))
{ {
decl = QUAL_RESOLUTION (q); decl = QUAL_RESOLUTION (q);
if (!type && !FIELD_STATIC (decl)) if (!type)
{ {
*where_found = current_this; if (!FIELD_STATIC (decl))
*type_found = type; *where_found = current_this;
else
{
*where_found = TREE_TYPE (decl);
if (TREE_CODE (*where_found) == POINTER_TYPE)
*where_found = TREE_TYPE (*where_found);
}
} }
} }
...@@ -5961,15 +6037,19 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -5961,15 +6037,19 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
} }
/* Layout the type of field_decl, since we may need /* Layout the type of field_decl, since we may need
it. Don't do primitive types or loaded classes */ it. Don't do primitive types or loaded classes. The
situation of non primitive arrays may not handled
properly here. FIXME */
if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE) if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
field_decl_type = TREE_TYPE (TREE_TYPE (field_decl)); field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
else else
field_decl_type = TREE_TYPE (field_decl); field_decl_type = TREE_TYPE (field_decl);
if (!JPRIMITIVE_TYPE_P (field_decl_type) if (!JPRIMITIVE_TYPE_P (field_decl_type)
&& !CLASS_LOADED_P (field_decl_type)) && !CLASS_LOADED_P (field_decl_type)
resolve_and_layout (DECL_NAME (TYPE_NAME (field_decl_type)), && !TYPE_ARRAY_P (field_decl_type))
NULL_TREE); resolve_and_layout (field_decl_type, NULL_TREE);
if (TYPE_ARRAY_P (field_decl_type))
CLASS_LOADED_P (field_decl_type) = 1;
/* Check on accessibility here */ /* Check on accessibility here */
if (not_accessible_p (type, field_decl, from_super)) if (not_accessible_p (type, field_decl, from_super))
...@@ -6065,8 +6145,7 @@ int not_accessible_p (reference, member, from_super) ...@@ -6065,8 +6145,7 @@ int not_accessible_p (reference, member, from_super)
} }
/* Check access on private members. Access is granted only if it /* Check access on private members. Access is granted only if it
occurs from within the class in witch it is declared*/ occurs from within the class in witch it is declared */
if (access_flag & ACC_PRIVATE) if (access_flag & ACC_PRIVATE)
return (current_class == DECL_CONTEXT (member) ? 0 : 1); return (current_class == DECL_CONTEXT (member) ? 0 : 1);
...@@ -6265,9 +6344,9 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super) ...@@ -6265,9 +6344,9 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
/* 2- Do the layout of the class where the last field /* 2- Do the layout of the class where the last field
was found, so we can search it. */ was found, so we can search it. */
class_decl = class_decl = resolve_and_layout (type, NULL_TREE);
resolve_and_layout (DECL_NAME (TYPE_NAME (type)), NULL_TREE); type = TREE_TYPE (class_decl);
/* 3- Retrieve a filtered list of method matches, Refine /* 3- Retrieve a filtered list of method matches, Refine
if necessary. In any cases, point out errors. */ if necessary. In any cases, point out errors. */
list = lookup_method_invoke (0, identifier_wfl, type, list = lookup_method_invoke (0, identifier_wfl, type,
...@@ -6349,6 +6428,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super) ...@@ -6349,6 +6428,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
/* NAME is a simple identifier or comes from a primary. Search /* NAME is a simple identifier or comes from a primary. Search
in the class whose declaration contain the method being in the class whose declaration contain the method being
invoked. */ invoked. */
resolve_and_layout (class_to_search, NULL_TREE);
list = lookup_method_invoke (lc, wfl, class_to_search, name, args); list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
/* Don't continue if no method were found, as the next statement /* Don't continue if no method were found, as the next statement
...@@ -6563,20 +6643,26 @@ lookup_method_invoke (lc, cl, class, name, arg_list) ...@@ -6563,20 +6643,26 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
tree cl; tree cl;
tree class, name, arg_list; tree class, name, arg_list;
{ {
tree method = make_node (FUNCTION_TYPE);
tree atl = NULL_TREE; /* Arg Type List */ tree atl = NULL_TREE; /* Arg Type List */
tree signature, list, node; tree method, signature, list, node;
char *candidates; /* Used for error report */ char *candidates; /* Used for error report */
/* Fix the arguments */ /* Fix the arguments */
for (node = arg_list; node; node = TREE_CHAIN (node)) for (node = arg_list; node; node = TREE_CHAIN (node))
{ {
tree current_arg = TREE_TYPE (TREE_VALUE (node)); tree current_arg = TREE_VALUE (node);
/* Integer constant 0 passed as itself, not as a type */
if (current_arg != integer_zero_node)
current_arg = TREE_TYPE (TREE_VALUE (node));
/* Non primitive type may have to be resolved */
if (current_arg != integer_zero_node
&& !JPRIMITIVE_TYPE_P (current_arg))
resolve_and_layout (current_arg, NULL_TREE);
/* And promoted */
if (TREE_CODE (current_arg) == RECORD_TYPE) if (TREE_CODE (current_arg) == RECORD_TYPE)
current_arg = promote_type (current_arg); current_arg = promote_type (current_arg);
atl = tree_cons (NULL_TREE, current_arg, atl); atl = tree_cons (NULL_TREE, current_arg, atl);
} }
TYPE_ARG_TYPES (method) = atl;
/* Find all candidates and then refine the list, searching for the /* Find all candidates and then refine the list, searching for the
most specific method. */ most specific method. */
...@@ -6610,6 +6696,11 @@ lookup_method_invoke (lc, cl, class, name, arg_list) ...@@ -6610,6 +6696,11 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
candidates = obstack_finish (&temporary_obstack); candidates = obstack_finish (&temporary_obstack);
} }
/* Issue the error message */ /* Issue the error message */
for (node = atl; node; node = TREE_CHAIN (node))
if (TREE_VALUE (node) == integer_zero_node)
TREE_VALUE (node) = long_type_node;
method = make_node (FUNCTION_TYPE);
TYPE_ARG_TYPES (method) = atl;
signature = build_java_argument_signature (method); signature = build_java_argument_signature (method);
parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s", parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
(lc ? "constructor" : "method"), (lc ? "constructor" : "method"),
...@@ -6641,13 +6732,14 @@ find_applicable_accessible_methods_list (lc, class, name, arglist) ...@@ -6641,13 +6732,14 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
if (lc && !DECL_CONSTRUCTOR_P (method)) if (lc && !DECL_CONSTRUCTOR_P (method))
continue; continue;
else if (!lc && (DECL_CONSTRUCTOR_P (method) else if (!lc && (DECL_CONSTRUCTOR_P (method)
|| DECL_NAME (method) != name)) || (GET_METHOD_NAME (method) != name)))
continue; continue;
if (argument_types_convertible (method, arglist)) if (argument_types_convertible (method, arglist))
{ {
/* Retain accessible methods only */ /* Retain accessible methods only */
if (!not_accessible_p (DECL_CONTEXT (current_function_decl), method, 0)) if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
method, 0))
list = tree_cons (NULL_TREE, method, list); list = tree_cons (NULL_TREE, method, list);
else else
/* Also retain all selected method here */ /* Also retain all selected method here */
...@@ -6754,6 +6846,7 @@ argument_types_convertible (m1, m2_or_arglist) ...@@ -6754,6 +6846,7 @@ argument_types_convertible (m1, m2_or_arglist)
while (m1_arg && m2_arg) while (m1_arg && m2_arg)
{ {
resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg), if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
TREE_VALUE (m2_arg))) TREE_VALUE (m2_arg)))
break; break;
...@@ -6988,7 +7081,8 @@ java_complete_tree (node) ...@@ -6988,7 +7081,8 @@ java_complete_tree (node)
int error_seen = 0; int error_seen = 0;
if (TREE_CODE (stmt) == COMPOUND_EXPR) if (TREE_CODE (stmt) == COMPOUND_EXPR)
{ {
/* Re-order from (((A; B); C); ...; Z) to (A; (B; (C ; (...; Z)))). /* Re-order from (((A; B); C); ...; Z) to
(A; (B; (C ; (...; Z)))).
This makes it easier to scan the statements left-to-right This makes it easier to scan the statements left-to-right
without using recursion (which might overflow the stack without using recursion (which might overflow the stack
if the block has many statements. */ if the block has many statements. */
...@@ -7004,7 +7098,8 @@ java_complete_tree (node) ...@@ -7004,7 +7098,8 @@ java_complete_tree (node)
BLOCK_EXPR_BODY (node) = stmt; BLOCK_EXPR_BODY (node) = stmt;
} }
/* Now do the actual complete, without deep recursion for long blocks. */ /* Now do the actual complete, without deep recursion for
long blocks. */
ptr = &BLOCK_EXPR_BODY (node); ptr = &BLOCK_EXPR_BODY (node);
while (TREE_CODE (*ptr) == COMPOUND_EXPR) while (TREE_CODE (*ptr) == COMPOUND_EXPR)
{ {
...@@ -7029,7 +7124,8 @@ java_complete_tree (node) ...@@ -7029,7 +7124,8 @@ java_complete_tree (node)
&& TREE_CODE (wfl_op2) != DEFAULT_EXPR) && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
{ {
SET_WFL_OPERATOR (wfl_operator, *ptr, wfl_op2); SET_WFL_OPERATOR (wfl_operator, *ptr, wfl_op2);
parse_error_context (wfl_operator, "Unreachable statement"); parse_error_context (wfl_operator,
"Unreachable statement");
} }
} }
ptr = next; ptr = next;
...@@ -7097,7 +7193,8 @@ java_complete_tree (node) ...@@ -7097,7 +7193,8 @@ java_complete_tree (node)
nn = ctxp->current_loop; nn = ctxp->current_loop;
/* It must be assignable to the type of the switch expression. */ /* It must be assignable to the type of the switch expression. */
if (!try_builtin_assignconv (NULL_TREE, TREE_TYPE (TREE_OPERAND (nn, 0)), cn)) if (!try_builtin_assignconv (NULL_TREE,
TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
{ {
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node); EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
parse_error_context parse_error_context
...@@ -7276,18 +7373,17 @@ java_complete_tree (node) ...@@ -7276,18 +7373,17 @@ java_complete_tree (node)
tree decl, wfl = TREE_OPERAND (node, 0); tree decl, wfl = TREE_OPERAND (node, 0);
int in_this = CALL_THIS_CONSTRUCTOR_P (node); int in_this = CALL_THIS_CONSTRUCTOR_P (node);
node = patch_method_invocation (node, NULL_TREE, node = patch_method_invocation (node, NULL_TREE,
NULL_TREE, 0, &decl, 0); NULL_TREE, 0, &decl, 0);
if (node != error_mark_node) if (node == error_mark_node)
{ return error_mark_node;
check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
/* If we call this(...), register signature and positions */ check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
if (in_this) /* If we call this(...), register signature and positions */
DECL_CONSTRUCTOR_CALLS (current_function_decl) = if (in_this)
tree_cons (wfl, decl, DECL_CONSTRUCTOR_CALLS (current_function_decl) =
DECL_CONSTRUCTOR_CALLS (current_function_decl)); tree_cons (wfl, decl,
DECL_CONSTRUCTOR_CALLS (current_function_decl));
}
return node; return node;
} }
...@@ -7317,6 +7413,13 @@ java_complete_tree (node) ...@@ -7317,6 +7413,13 @@ java_complete_tree (node)
nn = java_complete_tree (TREE_OPERAND (node, 1)); nn = java_complete_tree (TREE_OPERAND (node, 1));
if (nn == error_mark_node) if (nn == error_mark_node)
{ {
/* It's hopeless, but we can further things on to discover
an error during the assignment. In any cases, the
assignment operation fails. */
if (TREE_CODE (TREE_OPERAND (node, 1)) != EXPR_WITH_FILE_LOCATION
&& TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node)
patch_assignment (node, wfl_op1, wfl_op2);
/* Now, we still mark the lhs as initialized */ /* Now, we still mark the lhs as initialized */
if (DECL_P (TREE_OPERAND (node, 0))) if (DECL_P (TREE_OPERAND (node, 0)))
INITIALIZED_P (TREE_OPERAND (node, 0)) = 1; INITIALIZED_P (TREE_OPERAND (node, 0)) = 1;
...@@ -7413,7 +7516,7 @@ java_complete_tree (node) ...@@ -7413,7 +7516,7 @@ java_complete_tree (node)
return error_mark_node; return error_mark_node;
if (!flag_emit_class_files) if (!flag_emit_class_files)
TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1)); TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
return patch_array_ref (node, wfl_op1, wfl_op2); return patch_array_ref (node);
#if 0 #if 0
COMPONENT_REF: COMPONENT_REF:
...@@ -7873,18 +7976,9 @@ patch_assignment (node, wfl_op1, wfl_op2) ...@@ -7873,18 +7976,9 @@ patch_assignment (node, wfl_op1, wfl_op2)
/* Inline read access to java.lang.PRIMTYPE.TYPE */ /* Inline read access to java.lang.PRIMTYPE.TYPE */
rhs = maybe_build_primttype_type_ref (rhs, wfl_op2); rhs = maybe_build_primttype_type_ref (rhs, wfl_op2);
if (TREE_CODE (rhs) == COMPOUND_EXPR) /* Inline read access to java.lang.PRIMTYPE.TYPE */
{ if (new_rhs)
tree n = TREE_OPERAND (rhs, 1); new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
if (TREE_CODE (n) == VAR_DECL
&& DECL_NAME (n) == TYPE_identifier_node
&& rhs_type == class_ptr_type)
{
char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op2));
if (!strncmp (self_name, "java.lang.", 10))
rhs = build_primtype_type_ref (self_name);
}
}
if (error_found) if (error_found)
return error_mark_node; return error_mark_node;
...@@ -7987,6 +8081,11 @@ valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type) ...@@ -7987,6 +8081,11 @@ valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
if (lhs_type == rhs_type) if (lhs_type == rhs_type)
return 1; return 1;
/* Sometimes, instead of passing a type, we pass integer_zero_node
so we know that an integral type can accomodate it */
if (JINTEGRAL_TYPE_P (lhs_type) && (rhs_type == integer_zero_node))
return 1;
all_primitive = all_primitive =
JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type); JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type);
...@@ -8167,7 +8266,7 @@ static int ...@@ -8167,7 +8266,7 @@ static int
valid_method_invocation_conversion_p (dest, source) valid_method_invocation_conversion_p (dest, source)
tree dest, source; tree dest, source;
{ {
return ((JPRIMITIVE_TYPE_P (source) return (((JPRIMITIVE_TYPE_P (source) || (source == integer_zero_node))
&& JPRIMITIVE_TYPE_P (dest) && JPRIMITIVE_TYPE_P (dest)
&& valid_builtin_assignconv_identity_widening_p (dest, source)) && valid_builtin_assignconv_identity_widening_p (dest, source))
|| ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source)) || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
...@@ -8268,14 +8367,6 @@ patch_binop (node, wfl_op1, wfl_op2) ...@@ -8268,14 +8367,6 @@ patch_binop (node, wfl_op1, wfl_op2)
after checking for the initialization of the RHS */ after checking for the initialization of the RHS */
int error_found = 0; int error_found = 0;
/* Figure what is going to be checked first for initialization prior
its use. If NODE is part of a compound assignment, we check the
second operand first, otherwise the first one first. We also
initialize the matching WFL for the error report. `cfi' stands
for Check For Initialization */
tree cfi = (COMPOUND_ASSIGN_P (node) ? op2 : op1);
tree cfi_wfl = (COMPOUND_ASSIGN_P (node) ? wfl_op2 : wfl_op1);
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node); EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
switch (code) switch (code)
...@@ -8730,8 +8821,15 @@ patch_string (node) ...@@ -8730,8 +8821,15 @@ patch_string (node)
return patch_string_cst (node); return patch_string_cst (node);
else if (IS_CRAFTED_STRING_BUFFER_P (node)) else if (IS_CRAFTED_STRING_BUFFER_P (node))
{ {
int saved = ctxp->explicit_constructor_p;
tree invoke = build_method_invocation (wfl_to_string, NULL_TREE); tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
return java_complete_tree (make_qualified_primary (node, invoke, 0)); tree ret;
/* Temporary disable forbid the use of `this'. */
ctxp->explicit_constructor_p = 0;
ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
/* Restore it at its previous value */
ctxp->explicit_constructor_p = saved;
return ret;
} }
return NULL_TREE; return NULL_TREE;
} }
...@@ -8929,6 +9027,8 @@ patch_unaryop (node, wfl_op) ...@@ -8929,6 +9027,8 @@ patch_unaryop (node, wfl_op)
if (TREE_CODE (op_type) != BOOLEAN_TYPE) if (TREE_CODE (op_type) != BOOLEAN_TYPE)
{ {
ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type); ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
/* But the type is known. We will report an error if further
attempt of a assignment is made with this rhs */
TREE_TYPE (node) = boolean_type_node; TREE_TYPE (node) = boolean_type_node;
error_found = 1; error_found = 1;
} }
...@@ -8940,8 +9040,15 @@ patch_unaryop (node, wfl_op) ...@@ -8940,8 +9040,15 @@ patch_unaryop (node, wfl_op)
case CONVERT_EXPR: case CONVERT_EXPR:
value = patch_cast (node, wfl_operator); value = patch_cast (node, wfl_operator);
if (value == error_mark_node) if (value == error_mark_node)
return value; {
node = value; /* If this cast is part of an assignment, we tell the code
that deals with it not to complain about a mismatch,
because things have been cast, anyways */
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
else
node = value;
break; break;
} }
...@@ -9081,8 +9188,8 @@ build_array_ref (location, array, index) ...@@ -9081,8 +9188,8 @@ build_array_ref (location, array, index)
/* 15.12 Array Access Expression */ /* 15.12 Array Access Expression */
static tree static tree
patch_array_ref (node, wfl_array, wfl_index) patch_array_ref (node)
tree node, wfl_array, wfl_index; tree node;
{ {
tree array = TREE_OPERAND (node, 0); tree array = TREE_OPERAND (node, 0);
tree array_type = TREE_TYPE (array); tree array_type = TREE_TYPE (array);
...@@ -9793,7 +9900,7 @@ static tree ...@@ -9793,7 +9900,7 @@ static tree
patch_switch_statement (node) patch_switch_statement (node)
tree node; tree node;
{ {
tree se = TREE_OPERAND (node, 0), se_type, sb; tree se = TREE_OPERAND (node, 0), se_type;
/* Complete the switch expression */ /* Complete the switch expression */
se = TREE_OPERAND (node, 0) = java_complete_tree (se); se = TREE_OPERAND (node, 0) = java_complete_tree (se);
...@@ -9822,7 +9929,8 @@ patch_switch_statement (node) ...@@ -9822,7 +9929,8 @@ patch_switch_statement (node)
TREE_TYPE (node) = void_type_node; TREE_TYPE (node) = void_type_node;
TREE_SIDE_EFFECTS (node) = 1; TREE_SIDE_EFFECTS (node) = 1;
CAN_COMPLETE_NORMALLY (node) CAN_COMPLETE_NORMALLY (node)
= CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) || ! SWITCH_HAS_DEFAULT (node); = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
|| ! SWITCH_HAS_DEFAULT (node);
return node; return node;
} }
...@@ -9870,8 +9978,7 @@ build_try_statement (location, try_block, catches, finally) ...@@ -9870,8 +9978,7 @@ build_try_statement (location, try_block, catches, finally)
sequence. It hold a local variable used to return from the sequence. It hold a local variable used to return from the
finally using a computed goto. We call it finally using a computed goto. We call it
return_from_finally (RFF). */ return_from_finally (RFF). */
rff = build_decl_no_layout (VAR_DECL, generate_name (), rff = build_decl (VAR_DECL, generate_name (), return_address_type_node);
return_address_type_node);
/* Modification of the try block. */ /* Modification of the try block. */
try_block = build_jump_to_finally (try_block, rff, try_block = build_jump_to_finally (try_block, rff,
...@@ -9906,8 +10013,7 @@ build_try_statement (location, try_block, catches, finally) ...@@ -9906,8 +10013,7 @@ build_try_statement (location, try_block, catches, finally)
CALL_EXPR CALL_EXPR
Jv_ReThrow Jv_ReThrow
exception_parameter */ exception_parameter */
catch_decl = build_decl_no_layout (VAR_DECL, generate_name (), catch_decl = build_decl (VAR_DECL, generate_name (), ptr_type_node);
ptr_type_node);
BUILD_ASSIGN_EXCEPTION_INFO (stmt, catch_decl); BUILD_ASSIGN_EXCEPTION_INFO (stmt, catch_decl);
catch_block = build_expr_block (stmt, NULL_TREE); catch_block = build_expr_block (stmt, NULL_TREE);
catch_block = build_jump_to_finally (catch_block, rff, catch_block = build_jump_to_finally (catch_block, rff,
...@@ -10039,7 +10145,6 @@ patch_try_statement (node) ...@@ -10039,7 +10145,6 @@ patch_try_statement (node)
break; break;
} }
} }
/* Complete the catch clause block */ /* Complete the catch clause block */
catch_block = java_complete_tree (TREE_OPERAND (current, 0)); catch_block = java_complete_tree (TREE_OPERAND (current, 0));
if (catch_block == error_mark_node) if (catch_block == error_mark_node)
...@@ -10058,7 +10163,6 @@ patch_try_statement (node) ...@@ -10058,7 +10163,6 @@ patch_try_statement (node)
/* Link this type to the caught type list */ /* Link this type to the caught type list */
caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list); caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
} }
PUSH_EXCEPTIONS (caught_type_list); PUSH_EXCEPTIONS (caught_type_list);
...@@ -10136,7 +10240,7 @@ patch_synchronized_statement (node, wfl_op1) ...@@ -10136,7 +10240,7 @@ patch_synchronized_statement (node, wfl_op1)
try_block = build_expr_block (compound, NULL_TREE); try_block = build_expr_block (compound, NULL_TREE);
/* CATCH_ALL block */ /* CATCH_ALL block */
decl = build_decl_no_layout (VAR_DECL, generate_name (), ptr_type_node); decl = build_decl (VAR_DECL, generate_name (), ptr_type_node);
BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl); BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl);
compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt); compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt);
BUILD_MONITOR_EXIT (stmt, expr); BUILD_MONITOR_EXIT (stmt, expr);
...@@ -10178,7 +10282,7 @@ patch_throw_statement (node, wfl_op1) ...@@ -10178,7 +10282,7 @@ patch_throw_statement (node, wfl_op1)
/* The type of the throw expression is a not checked exception, /* The type of the throw expression is a not checked exception,
i.e. is a unchecked expression. */ i.e. is a unchecked expression. */
unchecked_ok = IS_UNCHECKED_EXPRESSION_P (TREE_TYPE (type)); unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
/* Throw is contained in a try statement and at least one catch /* Throw is contained in a try statement and at least one catch
clause can receive the thrown expression or the current method is clause can receive the thrown expression or the current method is
...@@ -10251,7 +10355,7 @@ check_thrown_exceptions (location, decl) ...@@ -10251,7 +10355,7 @@ check_thrown_exceptions (location, decl)
} }
} }
/* Return 1 if EXCEPTION is caught at the current nesting level of /* Return 1 if checked EXCEPTION is caught at the current nesting level of
try-catch blocks, OR is listed in the `throws' clause of the try-catch blocks, OR is listed in the `throws' clause of the
current method. */ current method. */
...@@ -10260,8 +10364,11 @@ check_thrown_exceptions_do (exception) ...@@ -10260,8 +10364,11 @@ check_thrown_exceptions_do (exception)
tree exception; tree exception;
{ {
tree list = currently_caught_type_list; tree list = currently_caught_type_list;
resolve_and_layout (exception, NULL_TREE);
/* First, all the nested try-catch-finally at that stage. The /* First, all the nested try-catch-finally at that stage. The
last element contains `throws' clause exceptions, if any. */ last element contains `throws' clause exceptions, if any. */
if (IS_UNCHECKED_EXCEPTION_P (exception))
return 1;
while (list) while (list)
{ {
tree caught; tree caught;
...@@ -10283,7 +10390,7 @@ purge_unchecked_exceptions (mdecl) ...@@ -10283,7 +10390,7 @@ purge_unchecked_exceptions (mdecl)
while (throws) while (throws)
{ {
tree next = TREE_CHAIN (throws); tree next = TREE_CHAIN (throws);
if (!IS_UNCHECKED_EXPRESSION_P (TREE_VALUE (throws))) if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
{ {
TREE_CHAIN (throws) = new; TREE_CHAIN (throws) = new;
new = throws; new = throws;
......
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