This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
? java-parser-split.patch
? gcc/java/parse_helper.c
Index: gcc/java/Make-lang.in
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/java/Make-lang.in,v
retrieving revision 1.151
diff -c -3 -p -r1.151 Make-lang.in
*** gcc/java/Make-lang.in 6 Dec 2004 17:59:57 -0000 1.151
--- gcc/java/Make-lang.in 29 Dec 2004 19:28:55 -0000
*************** JAVA_OBJS = java/parse.o java/class.o ja
*** 106,112 ****
java/zextract.o java/jcf-io.o java/win32-host.o java/jcf-parse.o java/mangle.o \
java/mangle_name.o java/builtins.o java/resource.o \
java/jcf-write.o java/buffer.o java/check-init.o java/jcf-depend.o \
! java/jcf-path.o java/xref.o java/boehm.o java/java-gimplify.o
GCJH_OBJS = java/gjavah.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
java/win32-host.o java/zextract.o version.o errors.o ggc-none.o \
--- 106,113 ----
java/zextract.o java/jcf-io.o java/win32-host.o java/jcf-parse.o java/mangle.o \
java/mangle_name.o java/builtins.o java/resource.o \
java/jcf-write.o java/buffer.o java/check-init.o java/jcf-depend.o \
! java/jcf-path.o java/xref.o java/boehm.o java/java-gimplify.o \
! java/parse_helper.o
GCJH_OBJS = java/gjavah.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
java/win32-host.o java/zextract.o version.o errors.o ggc-none.o \
*************** java/parse-scan.o: java/parse-scan.c $(C
*** 360,365 ****
--- 361,369 ----
java/parse.o: java/parse.c java/jcf-reader.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) function.h $(JAVA_TREE_H) $(JAVA_LEX_C) java/parse.h \
java/lex.h input.h $(GGC_H) debug.h gt-java-parse.h gtype-java.h target.h
+ java/parse_helper.o: java/parse_helper.c $(CONFIG_H) $(SYSTEM_H) java/parse.c \
+ java/lex.h input.h $(TM_H) function.h coretypes.h java/parse.h java/lex.h \
+ debug.h target.h gt-java-parse.h gtype-java.h $(JAVA_TREE_H) $(JAVA_LEX_C)
# jcf-io.o needs $(ZLIBINC) added to cflags.
java/jcf-io.o: java/jcf-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
Index: gcc/java/parse.y
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.525
diff -c -3 -p -r1.525 parse.y
*** gcc/java/parse.y 6 Dec 2004 15:32:37 -0000 1.525
--- gcc/java/parse.y 29 Dec 2004 19:28:56 -0000
*************** definitions and other extensions. */
*** 77,354 ****
#include "target.h"
/* Local function prototypes */
! static char *java_accstring_lookup (int);
! static const char *accessibility_string (int);
! static void classitf_redefinition_error (const char *,tree, tree, tree);
! static void variable_redefinition_error (tree, tree, tree, int);
! static tree create_class (int, tree, tree, tree);
! static tree create_interface (int, tree, tree);
! static void end_class_declaration (int);
! static tree find_field (tree, tree);
! static tree lookup_field_wrapper (tree, tree);
! static int duplicate_declaration_error_p (tree, tree, tree);
! static void register_fields (int, tree, tree);
! static tree parser_qualified_classname (tree);
! static int parser_check_super (tree, tree, tree);
! static int parser_check_super_interface (tree, tree, tree);
! static void check_modifiers_consistency (int);
! static tree lookup_cl (tree);
! static tree lookup_java_method2 (tree, tree, int);
! static tree method_header (int, tree, tree, tree);
! static void fix_method_argument_names (tree ,tree);
! static tree method_declarator (tree, tree);
! static void parse_warning_context (tree cl, const char *msgid, ...);
#ifdef USE_MAPPED_LOCATION
! static void issue_warning_error_from_context
(source_location, const char *msgid, va_list *);
#else
! static void issue_warning_error_from_context
(tree, const char *msgid, va_list *);
#endif
! static void parse_ctor_invocation_error (void);
! static tree parse_jdk1_1_error (const char *);
! static void complete_class_report_errors (jdep *);
! static int process_imports (void);
! static void read_import_dir (tree);
! static int find_in_imports_on_demand (tree, tree);
! static void find_in_imports (tree, tree);
! static void check_inner_class_access (tree, tree, tree);
! static int check_pkg_class_access (tree, tree, bool, tree);
! static void register_package (tree);
! static tree resolve_package (tree, tree *, tree *);
! static tree resolve_class (tree, tree, tree, tree);
! static void declare_local_variables (int, tree, tree);
! static void dump_java_tree (enum tree_dump_index, tree);
! static void source_start_java_method (tree);
! static void source_end_java_method (void);
! static tree find_name_in_single_imports (tree);
! static void check_abstract_method_header (tree);
! static tree lookup_java_interface_method2 (tree, tree);
! static tree resolve_expression_name (tree, tree *);
! static tree maybe_create_class_interface_decl (tree, tree, tree, tree);
! static int check_class_interface_creation (int, int, tree, tree, tree, tree);
! static tree patch_method_invocation (tree, tree, tree, int, int *, tree *);
! static tree resolve_and_layout (tree, tree);
! static tree qualify_and_find (tree, tree, tree);
! static tree resolve_no_layout (tree, tree);
! static int invocation_mode (tree, int);
! static tree find_applicable_accessible_methods_list (int, tree, tree, tree);
! static void search_applicable_methods_list (int, tree, tree, tree, tree *, tree *);
! static tree find_most_specific_methods_list (tree);
! static int argument_types_convertible (tree, tree);
! static tree patch_invoke (tree, tree, tree);
! static int maybe_use_access_method (int, tree *, tree *);
! static tree lookup_method_invoke (int, tree, tree, tree, tree);
! static tree register_incomplete_type (int, tree, tree, tree);
! static tree check_inner_circular_reference (tree, tree);
! static tree check_circular_reference (tree);
! static tree obtain_incomplete_type (tree);
! static tree java_complete_lhs (tree);
! static tree java_complete_tree (tree);
! static tree maybe_generate_pre_expand_clinit (tree);
! static int analyze_clinit_body (tree, tree);
! static int maybe_yank_clinit (tree);
! static void start_complete_expand_method (tree);
! static void java_complete_expand_method (tree);
! static void java_expand_method_bodies (tree);
! static int unresolved_type_p (tree, tree *);
! static void create_jdep_list (struct parser_ctxt *);
! static tree build_expr_block (tree, tree);
! static tree enter_block (void);
! static tree exit_block (void);
! static tree lookup_name_in_blocks (tree);
! static void maybe_absorb_scoping_blocks (void);
! static tree build_method_invocation (tree, tree);
! static tree build_new_invocation (tree, tree);
! static tree build_assignment (int, int, tree, tree);
! static tree build_binop (enum tree_code, int, tree, tree);
! static tree patch_assignment (tree, tree);
! static tree patch_binop (tree, tree, tree);
! static tree build_unaryop (int, int, tree);
! static tree build_incdec (int, int, tree, int);
! static tree patch_unaryop (tree, tree);
! static tree build_cast (int, tree, tree);
! static tree build_null_of_type (tree);
! static tree patch_cast (tree, tree);
! static int valid_ref_assignconv_cast_p (tree, tree, int);
! static int valid_builtin_assignconv_identity_widening_p (tree, tree);
! static int valid_cast_to_p (tree, tree);
! static int valid_method_invocation_conversion_p (tree, tree);
! static tree try_builtin_assignconv (tree, tree, tree);
! static tree try_reference_assignconv (tree, tree);
! static tree build_unresolved_array_type (tree);
! static int build_type_name_from_array_name (tree, tree *);
! static tree build_array_from_name (tree, tree, tree, tree *);
! static tree build_array_ref (int, tree, tree);
! static tree patch_array_ref (tree);
! #ifdef USE_MAPPED_LOCATION
! static tree make_qualified_name (tree, tree, source_location);
! #else
! static tree make_qualified_name (tree, tree, int);
! #endif
! static tree merge_qualified_name (tree, tree);
! static tree make_qualified_primary (tree, tree, int);
! static int resolve_qualified_expression_name (tree, tree *, tree *, tree *);
! static void qualify_ambiguous_name (tree);
! static tree resolve_field_access (tree, tree *, tree *);
! static tree build_newarray_node (tree, tree, int);
! static tree patch_newarray (tree);
! static tree resolve_type_during_patch (tree);
! static tree build_this (int);
! static tree build_wfl_wrap (tree, int);
! static tree build_return (int, tree);
! static tree patch_return (tree);
! static tree maybe_access_field (tree, tree, tree);
! static int complete_function_arguments (tree);
! static int check_for_static_method_reference (tree, tree, tree, tree, tree);
! static int not_accessible_p (tree, tree, tree, int);
! static void check_deprecation (tree, tree);
! static int class_in_current_package (tree);
! static tree build_if_else_statement (int, tree, tree, tree);
! static tree patch_if_else_statement (tree);
! static tree add_stmt_to_block (tree, tree, tree);
! static tree patch_exit_expr (tree);
! static tree build_labeled_block (int, tree);
! static tree finish_labeled_statement (tree, tree);
! static tree build_bc_statement (int, int, tree);
! static tree patch_bc_statement (tree);
! static tree patch_loop_statement (tree);
! static tree build_new_loop (tree);
! static tree build_loop_body (int, tree, int);
! static tree finish_loop_body (int, tree, tree, int);
! static tree build_debugable_stmt (int, tree);
! static tree finish_for_loop (int, tree, tree, tree);
! static tree patch_switch_statement (tree);
! static tree string_constant_concatenation (tree, tree);
! static tree build_string_concatenation (tree, tree);
! static tree patch_string_cst (tree);
! static tree patch_string (tree);
! static tree encapsulate_with_try_catch (int, tree, tree, tree);
! #ifdef USE_MAPPED_LOCATION
! static tree build_assertion (source_location, tree, tree);
! #else
! static tree build_assertion (int, tree, tree);
! #endif
! static tree build_try_statement (int, tree, tree);
! static tree build_try_finally_statement (int, tree, tree);
! static tree patch_try_statement (tree);
! static tree patch_synchronized_statement (tree, tree);
! static tree patch_throw_statement (tree, tree);
! #ifdef USE_MAPPED_LOCATION
! static void check_thrown_exceptions (source_location, tree, tree);
! #else
! static void check_thrown_exceptions (int, tree, tree);
! #endif
! static int check_thrown_exceptions_do (tree);
! static void purge_unchecked_exceptions (tree);
! static bool ctors_unchecked_throws_clause_p (tree);
! static void check_concrete_throws_clauses (tree, tree, tree, tree);
! static void check_throws_clauses (tree, tree, tree);
! static void finish_method_declaration (tree);
! static tree build_super_invocation (tree);
! static int verify_constructor_circularity (tree, tree);
! static char *constructor_circularity_msg (tree, tree);
! static tree build_this_super_qualified_invocation (int, tree, tree, int, int);
! static const char *get_printable_method_name (tree);
! static tree patch_conditional_expr (tree, tree, tree);
! static tree generate_finit (tree);
! static tree generate_instinit (tree);
! static tree build_instinit_invocation (tree);
! static void fix_constructors (tree);
! static tree build_alias_initializer_parameter_list (int, tree, tree, int *);
! static tree craft_constructor (tree, tree);
! static int verify_constructor_super (tree);
! static tree create_artificial_method (tree, int, tree, tree, tree);
! static void start_artificial_method_body (tree);
! static void end_artificial_method_body (tree);
! static int check_method_redefinition (tree, tree);
! static int check_method_types_complete (tree);
! static bool hack_is_accessible_p (tree, tree);
! static void java_check_regular_methods (tree);
! static void check_interface_throws_clauses (tree, tree);
! static void java_check_abstract_methods (tree);
! static void unreachable_stmt_error (tree);
! static int not_accessible_field_error (tree, tree);
! static tree find_expr_with_wfl (tree);
! static void missing_return_error (tree);
! static tree build_new_array_init (int, tree);
! static tree patch_new_array_init (tree, tree);
! static tree maybe_build_array_element_wfl (tree);
! static int array_constructor_check_entry (tree, tree);
! static const char *purify_type_name (const char *);
! static tree fold_constant_for_init (tree, tree);
! static jdeplist *reverse_jdep_list (struct parser_ctxt *);
! static void static_ref_err (tree, tree, tree);
! static void parser_add_interface (tree, tree, tree);
! static void add_superinterfaces (tree, tree);
! static tree jdep_resolve_class (jdep *);
! static int note_possible_classname (const char *, int);
! static void java_complete_expand_classes (void);
! static void java_complete_expand_class (tree);
! static void java_complete_expand_methods (tree);
! static tree cut_identifier_in_qualified (tree);
! static tree java_stabilize_reference (tree);
! static tree do_unary_numeric_promotion (tree);
! static char * operator_string (tree);
! static tree do_merge_string_cste (tree, const char *, int, int);
! static tree merge_string_cste (tree, tree, int);
! static tree java_refold (tree);
! static int java_decl_equiv (tree, tree);
! static int binop_compound_p (enum tree_code);
! static tree search_loop (tree);
! static int labeled_block_contains_loop_p (tree, tree);
! static int check_abstract_method_definitions (int, tree, tree);
! static void java_check_abstract_method_definitions (tree);
! static void java_debug_context_do (int);
! static void java_parser_context_push_initialized_field (void);
! static void java_parser_context_pop_initialized_field (void);
! static tree reorder_static_initialized (tree);
! static void java_parser_context_suspend (void);
! static void java_parser_context_resume (void);
! static int pop_current_osb (struct parser_ctxt *);
/* JDK 1.1 work. FIXME */
! static tree maybe_make_nested_class_name (tree);
! static int make_nested_class_name (tree);
! static void link_nested_class_to_enclosing (void);
! static tree resolve_inner_class (htab_t, tree, tree *, tree *, tree);
! static tree find_as_inner_class (tree, tree, tree);
! static tree find_as_inner_class_do (tree, tree);
! static int check_inner_class_redefinition (tree, tree);
!
! static tree build_thisn_assign (void);
! static tree build_current_thisn (tree);
! static tree build_access_to_thisn (tree, tree, int);
! static tree maybe_build_thisn_access_method (tree);
!
! static tree build_outer_field_access (tree, tree);
! static tree build_outer_field_access_methods (tree);
! static tree build_outer_field_access_expr (int, tree, tree,
tree, tree);
! static tree build_outer_method_access_method (tree);
! static tree build_new_access_id (void);
! static tree build_outer_field_access_method (tree, tree, tree,
tree, tree);
! static int outer_field_access_p (tree, tree);
! static int outer_field_expanded_access_p (tree, tree *,
tree *, tree *);
! static tree outer_field_access_fix (tree, tree, tree);
! static tree build_incomplete_class_ref (int, tree);
! static tree patch_incomplete_class_ref (tree);
! static tree create_anonymous_class (tree);
! static void patch_anonymous_class (tree, tree, tree);
! static void add_inner_class_fields (tree, tree);
!
! static tree build_dot_class_method (tree);
! static tree build_dot_class_method_invocation (tree, tree);
! static void create_new_parser_context (int);
! static tree maybe_build_class_init_for_field (tree, tree);
! static int emit_test_initialization (void **, void *);
! static char *string_convert_int_cst (tree);
/* Number of error found so far. */
int java_error_count;
--- 77,356 ----
#include "target.h"
/* Local function prototypes */
! /* ALL helper functions belong in parse_helper.c and friends */
! /* FIXME: Some helper functions lack prototypes here */
! extern char *java_accstring_lookup (int);
! extern const char *accessibility_string (int);
! extern void classitf_redefinition_error (const char *,tree, tree, tree);
! extern void variable_redefinition_error (tree, tree, tree, int);
! extern tree create_class (int, tree, tree, tree);
! extern tree create_interface (int, tree, tree);
! extern void end_class_declaration (int);
! extern tree find_field (tree, tree);
! extern tree lookup_field_wrapper (tree, tree);
! extern int duplicate_declaration_error_p (tree, tree, tree);
! extern void register_fields (int, tree, tree);
! extern tree parser_qualified_classname (tree);
! extern int parser_check_super (tree, tree, tree);
! extern int parser_check_super_interface (tree, tree, tree);
! extern void check_modifiers_consistency (int);
! extern tree lookup_cl (tree);
! extern tree lookup_java_method2 (tree, tree, int);
! extern tree method_header (int, tree, tree, tree);
! extern void fix_method_argument_names (tree ,tree);
! extern tree method_declarator (tree, tree);
! extern void parse_warning_context (tree cl, const char *msgid, ...);
#ifdef USE_MAPPED_LOCATION
! extern void issue_warning_error_from_context
(source_location, const char *msgid, va_list *);
#else
! extern void issue_warning_error_from_context
(tree, const char *msgid, va_list *);
#endif
! extern void parse_ctor_invocation_error (void);
! extern tree parse_jdk1_1_error (const char *);
! extern void complete_class_report_errors (jdep *);
! extern int process_imports (void);
! extern void read_import_dir (tree);
! extern int find_in_imports_on_demand (tree, tree);
! extern void find_in_imports (tree, tree);
! extern void check_inner_class_access (tree, tree, tree);
! extern int check_pkg_class_access (tree, tree, bool, tree);
! extern void register_package (tree);
! extern tree resolve_package (tree, tree *, tree *);
! extern tree resolve_class (tree, tree, tree, tree);
! extern void declare_local_variables (int, tree, tree);
! extern void dump_java_tree (enum tree_dump_index, tree);
! extern void source_start_java_method (tree);
! extern void source_end_java_method (void);
! extern tree find_name_in_single_imports (tree);
! extern void check_abstract_method_header (tree);
! extern tree lookup_java_interface_method2 (tree, tree);
! extern tree resolve_expression_name (tree, tree *);
! extern tree maybe_create_class_interface_decl (tree, tree, tree, tree);
! extern int check_class_interface_creation (int, int, tree, tree, tree, tree);
! extern tree patch_method_invocation (tree, tree, tree, int, int *, tree *);
! extern tree resolve_and_layout (tree, tree);
! extern tree qualify_and_find (tree, tree, tree);
! extern tree resolve_no_layout (tree, tree);
! extern int invocation_mode (tree, int);
! extern tree find_applicable_accessible_methods_list (int, tree, tree, tree);
! extern void search_applicable_methods_list (int, tree, tree, tree, tree *, tree *);
! extern tree find_most_specific_methods_list (tree);
! extern int argument_types_convertible (tree, tree);
! extern tree patch_invoke (tree, tree, tree);
! extern int maybe_use_access_method (int, tree *, tree *);
! extern tree lookup_method_invoke (int, tree, tree, tree, tree);
! extern tree register_incomplete_type (int, tree, tree, tree);
! extern tree check_inner_circular_reference (tree, tree);
! extern tree check_circular_reference (tree);
! extern tree obtain_incomplete_type (tree);
! extern tree java_complete_lhs (tree);
! extern tree java_complete_tree (tree);
! extern tree maybe_generate_pre_expand_clinit (tree);
! extern int analyze_clinit_body (tree, tree);
! extern int maybe_yank_clinit (tree);
! extern void start_complete_expand_method (tree);
! extern void java_complete_expand_method (tree);
! extern void java_expand_method_bodies (tree);
! extern int unresolved_type_p (tree, tree *);
! extern void create_jdep_list (struct parser_ctxt *);
! extern tree build_expr_block (tree, tree);
! extern tree enter_block (void);
! extern tree exit_block (void);
! extern tree lookup_name_in_blocks (tree);
! extern void maybe_absorb_scoping_blocks (void);
! extern tree build_method_invocation (tree, tree);
! extern tree build_new_invocation (tree, tree);
! extern tree build_assignment (int, int, tree, tree);
! extern tree build_binop (enum tree_code, int, tree, tree);
! extern tree patch_assignment (tree, tree);
! extern tree patch_binop (tree, tree, tree);
! extern tree build_unaryop (int, int, tree);
! extern tree build_incdec (int, int, tree, int);
! extern tree patch_unaryop (tree, tree);
! extern tree build_cast (int, tree, tree);
! extern tree build_null_of_type (tree);
! extern tree patch_cast (tree, tree);
! extern int valid_ref_assignconv_cast_p (tree, tree, int);
! extern int valid_builtin_assignconv_identity_widening_p (tree, tree);
! extern int valid_cast_to_p (tree, tree);
! extern int valid_method_invocation_conversion_p (tree, tree);
! extern tree try_builtin_assignconv (tree, tree, tree);
! extern tree try_reference_assignconv (tree, tree);
! extern tree build_unresolved_array_type (tree);
! extern int build_type_name_from_array_name (tree, tree *);
! extern tree build_array_from_name (tree, tree, tree, tree *);
! extern tree build_array_ref (int, tree, tree);
! extern tree patch_array_ref (tree);
! #ifdef USE_MAPPED_LOCATION
! extern tree make_qualified_name (tree, tree, source_location);
! #else
! extern tree make_qualified_name (tree, tree, int);
! #endif
! extern tree merge_qualified_name (tree, tree);
! extern tree make_qualified_primary (tree, tree, int);
! extern int resolve_qualified_expression_name (tree, tree *, tree *, tree *);
! extern void qualify_ambiguous_name (tree);
! extern tree resolve_field_access (tree, tree *, tree *);
! extern tree build_newarray_node (tree, tree, int);
! extern tree patch_newarray (tree);
! extern tree resolve_type_during_patch (tree);
! extern tree build_this (int);
! extern tree build_wfl_wrap (tree, int);
! extern tree build_return (int, tree);
! extern tree patch_return (tree);
! extern tree maybe_access_field (tree, tree, tree);
! extern int complete_function_arguments (tree);
! extern int check_for_static_method_reference (tree, tree, tree, tree, tree);
! extern int not_accessible_p (tree, tree, tree, int);
! extern void check_deprecation (tree, tree);
! extern int class_in_current_package (tree);
! extern tree build_if_else_statement (int, tree, tree, tree);
! extern tree patch_if_else_statement (tree);
! extern tree add_stmt_to_block (tree, tree, tree);
! extern tree patch_exit_expr (tree);
! extern tree build_labeled_block (int, tree);
! extern tree finish_labeled_statement (tree, tree);
! extern tree build_bc_statement (int, int, tree);
! extern tree patch_bc_statement (tree);
! extern tree patch_loop_statement (tree);
! extern tree build_new_loop (tree);
! extern tree build_loop_body (int, tree, int);
! extern tree finish_loop_body (int, tree, tree, int);
! extern tree build_debugable_stmt (int, tree);
! extern tree finish_for_loop (int, tree, tree, tree);
! extern tree patch_switch_statement (tree);
! extern tree string_constant_concatenation (tree, tree);
! extern tree build_string_concatenation (tree, tree);
! extern tree patch_string_cst (tree);
! extern tree patch_string (tree);
! extern tree encapsulate_with_try_catch (int, tree, tree, tree);
! #ifdef USE_MAPPED_LOCATION
! extern tree build_assertion (source_location, tree, tree);
! #else
! extern tree build_assertion (int, tree, tree);
! #endif
! extern tree build_try_statement (int, tree, tree);
! extern tree build_try_finally_statement (int, tree, tree);
! extern tree patch_try_statement (tree);
! extern tree patch_synchronized_statement (tree, tree);
! extern tree patch_throw_statement (tree, tree);
! #ifdef USE_MAPPED_LOCATION
! extern void check_thrown_exceptions (source_location, tree, tree);
! #else
! extern void check_thrown_exceptions (int, tree, tree);
! #endif
! extern int check_thrown_exceptions_do (tree);
! extern void purge_unchecked_exceptions (tree);
! extern bool ctors_unchecked_throws_clause_p (tree);
! extern void check_concrete_throws_clauses (tree, tree, tree, tree);
! extern void check_throws_clauses (tree, tree, tree);
! extern void finish_method_declaration (tree);
! extern tree build_super_invocation (tree);
! extern int verify_constructor_circularity (tree, tree);
! extern char *constructor_circularity_msg (tree, tree);
! extern tree build_this_super_qualified_invocation (int, tree, tree, int, int);
! extern const char *get_printable_method_name (tree);
! extern tree patch_conditional_expr (tree, tree, tree);
! extern tree generate_finit (tree);
! extern tree generate_instinit (tree);
! extern tree build_instinit_invocation (tree);
! extern void fix_constructors (tree);
! extern tree build_alias_initializer_parameter_list (int, tree, tree, int *);
! extern tree craft_constructor (tree, tree);
! extern int verify_constructor_super (tree);
! extern tree create_artificial_method (tree, int, tree, tree, tree);
! extern void start_artificial_method_body (tree);
! extern void end_artificial_method_body (tree);
! extern int check_method_redefinition (tree, tree);
! extern int check_method_types_complete (tree);
! extern bool hack_is_accessible_p (tree, tree);
! extern void java_check_regular_methods (tree);
! extern void check_interface_throws_clauses (tree, tree);
! extern void java_check_abstract_methods (tree);
! extern void unreachable_stmt_error (tree);
! extern int not_accessible_field_error (tree, tree);
! extern tree find_expr_with_wfl (tree);
! extern void missing_return_error (tree);
! extern tree build_new_array_init (int, tree);
! extern tree patch_new_array_init (tree, tree);
! extern tree maybe_build_array_element_wfl (tree);
! extern int array_constructor_check_entry (tree, tree);
! extern const char *purify_type_name (const char *);
! extern tree fold_constant_for_init (tree, tree);
! extern jdeplist *reverse_jdep_list (struct parser_ctxt *);
! extern void static_ref_err (tree, tree, tree);
! extern void parser_add_interface (tree, tree, tree);
! extern void add_superinterfaces (tree, tree);
! extern tree jdep_resolve_class (jdep *);
! extern int note_possible_classname (const char *, int);
! extern void java_complete_expand_classes (void);
! extern void java_complete_expand_class (tree);
! extern void java_complete_expand_methods (tree);
! extern tree cut_identifier_in_qualified (tree);
! extern tree java_stabilize_reference (tree);
! extern tree do_unary_numeric_promotion (tree);
! extern char * operator_string (tree);
! extern tree do_merge_string_cste (tree, const char *, int, int);
! extern tree merge_string_cste (tree, tree, int);
! extern tree java_refold (tree);
! extern int java_decl_equiv (tree, tree);
! extern int binop_compound_p (enum tree_code);
! extern tree search_loop (tree);
! extern int labeled_block_contains_loop_p (tree, tree);
! extern int check_abstract_method_definitions (int, tree, tree);
! extern void java_check_abstract_method_definitions (tree);
! extern void java_debug_context_do (int);
! extern void java_parser_context_push_initialized_field (void);
! extern void java_parser_context_pop_initialized_field (void);
! extern tree reorder_static_initialized (tree);
! extern void java_parser_context_suspend (void);
! extern void java_parser_context_resume (void);
! extern int pop_current_osb (struct parser_ctxt *);
/* JDK 1.1 work. FIXME */
! extern tree maybe_make_nested_class_name (tree);
! extern int make_nested_class_name (tree);
! extern void link_nested_class_to_enclosing (void);
! extern tree resolve_inner_class (htab_t, tree, tree *, tree *, tree);
! extern tree find_as_inner_class (tree, tree, tree);
! extern tree find_as_inner_class_do (tree, tree);
! extern int check_inner_class_redefinition (tree, tree);
!
! extern tree build_thisn_assign (void);
! extern tree build_current_thisn (tree);
! extern tree build_access_to_thisn (tree, tree, int);
! extern tree maybe_build_thisn_access_method (tree);
!
! extern tree build_outer_field_access (tree, tree);
! extern tree build_outer_field_access_methods (tree);
! extern tree build_outer_field_access_expr (int, tree, tree,
tree, tree);
! extern tree build_outer_method_access_method (tree);
! extern tree build_new_access_id (void);
! extern tree build_outer_field_access_method (tree, tree, tree,
tree, tree);
! extern int outer_field_access_p (tree, tree);
! extern int outer_field_expanded_access_p (tree, tree *,
tree *, tree *);
! extern tree outer_field_access_fix (tree, tree, tree);
! extern tree build_incomplete_class_ref (int, tree);
! extern tree patch_incomplete_class_ref (tree);
! extern tree create_anonymous_class (tree);
! extern void patch_anonymous_class (tree, tree, tree);
! extern void add_inner_class_fields (tree, tree);
!
! extern tree build_dot_class_method (tree);
! extern tree build_dot_class_method_invocation (tree, tree);
! extern void create_new_parser_context (int);
! extern tree maybe_build_class_init_for_field (tree, tree);
! extern int emit_test_initialization (void **, void *);
! extern char *string_convert_int_cst (tree);
/* Number of error found so far. */
int java_error_count;
*************** constant_expression:
*** 2691,3048 ****
;
%%
!
! /* Helper function to retrieve an OSB count. Should be used when the
! `dims:' rule is being used. */
!
! static int
! pop_current_osb (struct parser_ctxt *ctxp)
! {
! int to_return;
!
! if (ctxp->osb_depth < 0)
! abort ();
!
! to_return = CURRENT_OSB (ctxp);
! ctxp->osb_depth--;
!
! return to_return;
! }
!
!
!
! /* This section of the code deal with save/restoring parser contexts.
! Add mode documentation here. FIXME */
!
! /* Helper function. Create a new parser context. With
! COPY_FROM_PREVIOUS set to a nonzero value, content of the previous
! context is copied, otherwise, the new context is zeroed. The newly
! created context becomes the current one. */
!
! static void
! create_new_parser_context (int copy_from_previous)
! {
! struct parser_ctxt *new;
!
! new = ggc_alloc (sizeof (struct parser_ctxt));
! if (copy_from_previous)
! {
! memcpy (new, ctxp, sizeof (struct parser_ctxt));
! /* This flag, indicating the context saves global values,
! should only be set by java_parser_context_save_global. */
! new->saved_data_ctx = 0;
! }
! else
! memset (new, 0, sizeof (struct parser_ctxt));
!
! new->next = ctxp;
! ctxp = new;
! }
!
! /* Create a new parser context and make it the current one. */
!
! void
! java_push_parser_context (void)
! {
! create_new_parser_context (0);
! }
!
! void
! java_pop_parser_context (int generate)
! {
! tree current;
! struct parser_ctxt *next;
!
! if (!ctxp)
! return;
!
! next = ctxp->next;
! if (next)
! {
! input_location = ctxp->save_location;
! current_class = ctxp->class_type;
! }
!
! /* If the old and new lexers differ, then free the old one. */
! if (ctxp->lexer && next && ctxp->lexer != next->lexer)
! java_destroy_lexer (ctxp->lexer);
!
! /* Set the single import class file flag to 0 for the current list
! of imported things */
! for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
! IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 0;
!
! /* If we pushed a context to parse a class intended to be generated,
! we keep it so we can remember the class. What we could actually
! do is to just update a list of class names. */
! if (generate)
! {
! ctxp->next = ctxp_for_generation;
! ctxp_for_generation = ctxp;
! }
!
! /* And restore those of the previous context */
! if ((ctxp = next)) /* Assignment is really meant here */
! for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
! IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1;
! }
!
! /* Create a parser context for the use of saving some global
! variables. */
!
! void
! java_parser_context_save_global (void)
! {
! if (!ctxp)
! {
! java_push_parser_context ();
! ctxp->saved_data_ctx = 1;
! }
!
! /* If this context already stores data, create a new one suitable
! for data storage. */
! else if (ctxp->saved_data)
! {
! create_new_parser_context (1);
! ctxp->saved_data_ctx = 1;
! }
!
! ctxp->save_location = input_location;
! ctxp->class_type = current_class;
! ctxp->function_decl = current_function_decl;
! ctxp->saved_data = 1;
! }
!
! /* Restore some global variables from the previous context. Make the
! previous context the current one. */
!
! void
! java_parser_context_restore_global (void)
! {
! input_location = ctxp->save_location;
! current_class = ctxp->class_type;
! if (wfl_operator)
! #ifdef USE_MAPPED_LOCATION
! SET_EXPR_LOCATION (wfl_operator, ctxp->save_location);
! #else
! EXPR_WFL_FILENAME_NODE (wfl_operator) = get_identifier (input_filename);
! #endif
! current_function_decl = ctxp->function_decl;
! ctxp->saved_data = 0;
! if (ctxp->saved_data_ctx)
! java_pop_parser_context (0);
! }
!
! /* Suspend vital data for the current class/function being parsed so
! that an other class can be parsed. Used to let local/anonymous
! classes be parsed. */
!
! static void
! java_parser_context_suspend (void)
! {
! /* This makes debugging through java_debug_context easier */
! static const char *const name = "<inner buffer context>";
!
! /* Duplicate the previous context, use it to save the globals we're
! interested in */
! create_new_parser_context (1);
! ctxp->function_decl = current_function_decl;
! ctxp->class_type = current_class;
!
! /* Then create a new context which inherits all data from the
! previous one. This will be the new current context */
! create_new_parser_context (1);
!
! /* Help debugging */
! ctxp->next->filename = name;
! }
!
! /* Resume vital data for the current class/function being parsed so
! that an other class can be parsed. Used to let local/anonymous
! classes be parsed. The trick is the data storing file position
! informations must be restored to their current value, so parsing
! can resume as if no context was ever saved. */
!
! static void
! java_parser_context_resume (void)
! {
! struct parser_ctxt *old = ctxp; /* This one is to be discarded */
! struct parser_ctxt *saver = old->next; /* This one contain saved info */
! struct parser_ctxt *restored = saver->next; /* This one is the old current */
!
! /* We need to inherit the list of classes to complete/generate */
! restored->classd_list = old->classd_list;
! restored->class_list = old->class_list;
!
! /* Restore the current class and function from the saver */
! current_class = saver->class_type;
! current_function_decl = saver->function_decl;
!
! /* Retrieve the restored context */
! ctxp = restored;
!
! /* Re-installed the data for the parsing to carry on */
! memcpy (&ctxp->marker_begining, &old->marker_begining,
! (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
! }
!
! /* Add a new anchor node to which all statement(s) initializing static
! and non static initialized upon declaration field(s) will be
! linked. */
!
! static void
! java_parser_context_push_initialized_field (void)
! {
! tree node;
!
! node = build_tree_list (NULL_TREE, NULL_TREE);
! TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
! CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
!
! node = build_tree_list (NULL_TREE, NULL_TREE);
! TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
! CPC_INITIALIZER_LIST (ctxp) = node;
!
! node = build_tree_list (NULL_TREE, NULL_TREE);
! TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
! CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
! }
!
! /* Pop the lists of initialized field. If this lists aren't empty,
! remember them so we can use it to create and populate the finit$
! or <clinit> functions. */
!
! static void
! java_parser_context_pop_initialized_field (void)
! {
! tree stmts;
! tree class_type = TREE_TYPE (GET_CPC ());
!
! if (CPC_INITIALIZER_LIST (ctxp))
! {
! stmts = CPC_INITIALIZER_STMT (ctxp);
! CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
! if (stmts && !java_error_count)
! TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
! }
!
! if (CPC_STATIC_INITIALIZER_LIST (ctxp))
! {
! stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
! CPC_STATIC_INITIALIZER_LIST (ctxp) =
! TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
! /* Keep initialization in order to enforce 8.5 */
! if (stmts && !java_error_count)
! TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
! }
!
! /* JDK 1.1 instance initializers */
! if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
! {
! stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
! CPC_INSTANCE_INITIALIZER_LIST (ctxp) =
! TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
! if (stmts && !java_error_count)
! TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
! }
! }
!
! static tree
! reorder_static_initialized (tree list)
! {
! /* We have to keep things in order. The alias initializer have to
! come first, then the initialized regular field, in reverse to
! keep them in lexical order. */
! tree marker, previous = NULL_TREE;
! for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
! if (TREE_CODE (marker) == TREE_LIST
! && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
! break;
!
! /* No static initialized, the list is fine as is */
! if (!previous)
! list = TREE_CHAIN (marker);
!
! /* No marker? reverse the whole list */
! else if (!marker)
! list = nreverse (list);
!
! /* Otherwise, reverse what's after the marker and the new reordered
! sublist will replace the marker. */
! else
! {
! TREE_CHAIN (previous) = NULL_TREE;
! list = nreverse (list);
! list = chainon (TREE_CHAIN (marker), list);
! }
! return list;
! }
!
! /* Helper functions to dump the parser context stack. */
!
! #define TAB_CONTEXT(C) \
! {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
!
! static void
! java_debug_context_do (int tab)
! {
! struct parser_ctxt *copy = ctxp;
! while (copy)
! {
! TAB_CONTEXT (tab);
! fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
! TAB_CONTEXT (tab);
! fprintf (stderr, "filename: %s\n", copy->filename);
! TAB_CONTEXT (tab);
! fprintf (stderr, "package: %s\n",
! (copy->package ?
! IDENTIFIER_POINTER (copy->package) : "<none>"));
! TAB_CONTEXT (tab);
! fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
! TAB_CONTEXT (tab);
! fprintf (stderr, "saved data: %d\n", copy->saved_data);
! copy = copy->next;
! tab += 2;
! }
! }
!
! /* Dump the stacked up parser contexts. Intended to be called from a
! debugger. */
!
! void
! java_debug_context (void)
! {
! java_debug_context_do (0);
! }
!
!
!
! /* Flag for the error report routine to issue the error the first time
! it's called (overriding the default behavior which is to drop the
! first invocation and honor the second one, taking advantage of a
! richer context. */
! static int force_error = 0;
!
! /* Reporting an constructor invocation error. */
! static void
! parse_ctor_invocation_error (void)
! {
! if (DECL_CONSTRUCTOR_P (current_function_decl))
! yyerror ("Constructor invocation must be first thing in a constructor");
! else
! yyerror ("Only constructors can invoke constructors");
! }
!
! /* Reporting JDK1.1 features not implemented. */
!
! static tree
! parse_jdk1_1_error (const char *msg)
! {
! sorry (": %qs JDK1.1(TM) feature", msg);
! java_error_count++;
! return build_java_empty_stmt ();
! }
!
static int do_warning = 0;
void
--- 2693,2699 ----
;
%%
! /* Error stuff that must stay here */
static int do_warning = 0;
void
*************** yyerror (const char *msgid)
*** 3133,16409 ****
ctxp->prevent_ese = input_line;
}
- static void
- issue_warning_error_from_context (
- #ifdef USE_MAPPED_LOCATION
- source_location cl,
- #else
- tree cl,
- #endif
- const char *msgid, va_list *ap)
- {
- #ifdef USE_MAPPED_LOCATION
- source_location saved_location = input_location;
- expanded_location xloc = expand_location (cl);
- #else
- java_lc save_lc = ctxp->lexer->token_start;
- const char *saved = ctxp->filename, *saved_input_filename;
- #endif
- char buffer [4096];
- text_info text;
-
- text.err_no = errno;
- text.args_ptr = ap;
- text.format_spec = msgid;
- pp_format_text (global_dc->printer, &text);
- strncpy (buffer, pp_formatted_text (global_dc->printer), sizeof (buffer) - 1);
- buffer[sizeof (buffer) - 1] = '\0';
- pp_clear_output_area (global_dc->printer);
-
- force_error = 1;
-
- #ifdef USE_MAPPED_LOCATION
- if (xloc.file != NULL)
- {
- ctxp->filename = xloc.file;
- input_location = cl;
- }
- #else
- ctxp->lexer->token_start.line = EXPR_WFL_LINENO (cl);
- ctxp->lexer->token_start.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1
- : EXPR_WFL_COLNO (cl) == 0xffe ? -2
- : EXPR_WFL_COLNO (cl));
-
- /* We have a CL, that's a good reason for using it if it contains data */
- if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
- ctxp->filename = EXPR_WFL_FILENAME (cl);
- saved_input_filename = input_filename;
- input_filename = ctxp->filename;
- #endif
- java_error (NULL);
- java_error (buffer);
- #ifdef USE_MAPPED_LOCATION
- input_location = saved_location;
- #else
- ctxp->filename = saved;
- input_filename = saved_input_filename;
- ctxp->lexer->token_start = save_lc;
- #endif
- force_error = 0;
- }
-
- /* Issue an error message at a current source line CL.
- FUTURE/FIXME: change cl to be a source_location. */
-
- void
- parse_error_context (tree cl, const char *msgid, ...)
- {
- va_list ap;
- va_start (ap, msgid);
- #ifdef USE_MAPPED_LOCATION
- issue_warning_error_from_context (EXPR_LOCATION (cl), msgid, &ap);
- #else
- issue_warning_error_from_context (cl, msgid, &ap);
- #endif
- va_end (ap);
- }
-
- /* Issue a warning at a current source line CL.
- FUTURE/FIXME: change cl to be a source_location. */
-
- static void
- parse_warning_context (tree cl, const char *msgid, ...)
- {
- va_list ap;
- va_start (ap, msgid);
-
- do_warning = 1;
- #ifdef USE_MAPPED_LOCATION
- issue_warning_error_from_context (EXPR_LOCATION (cl), msgid, &ap);
- #else
- issue_warning_error_from_context (cl, msgid, &ap);
- #endif
- do_warning = 0;
- va_end (ap);
- }
-
- static tree
- find_expr_with_wfl (tree node)
- {
- while (node)
- {
- enum tree_code_class code;
- tree to_return;
-
- switch (TREE_CODE (node))
- {
- case BLOCK:
- node = BLOCK_EXPR_BODY (node);
- continue;
-
- case COMPOUND_EXPR:
- to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
- if (to_return)
- return to_return;
- node = TREE_OPERAND (node, 1);
- continue;
-
- case LOOP_EXPR:
- node = TREE_OPERAND (node, 0);
- continue;
-
- case LABELED_BLOCK_EXPR:
- node = LABELED_BLOCK_BODY (node);
- continue;
-
- default:
- code = TREE_CODE_CLASS (TREE_CODE (node));
- if (((code == tcc_unary) || (code == tcc_binary)
- || (code == tcc_expression))
- && EXPR_WFL_LINECOL (node))
- return node;
- return NULL_TREE;
- }
- }
- return NULL_TREE;
- }
-
- /* Issue a missing return statement error. Uses METHOD to figure the
- last line of the method the error occurs in. */
-
- static void
- missing_return_error (tree method)
- {
- #ifdef USE_MAPPED_LOCATION
- SET_EXPR_LOCATION (wfl_operator, DECL_FUNCTION_LAST_LINE (method));
- #else
- EXPR_WFL_SET_LINECOL (wfl_operator, DECL_FUNCTION_LAST_LINE (method), -2);
- #endif
- parse_error_context (wfl_operator, "Missing return statement");
- }
-
- /* Issue an unreachable statement error. From NODE, find the next
- statement to report appropriately. */
- static void
- unreachable_stmt_error (tree node)
- {
- /* Browse node to find the next expression node that has a WFL. Use
- the location to report the error */
- if (TREE_CODE (node) == COMPOUND_EXPR)
- node = find_expr_with_wfl (TREE_OPERAND (node, 1));
- else
- node = find_expr_with_wfl (node);
-
- if (node)
- {
- #ifdef USE_MAPPED_LOCATION
- SET_EXPR_LOCATION (wfl_operator, EXPR_LOCATION (node));
- #else
- EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
- #endif
- parse_error_context (wfl_operator, "Unreachable statement");
- }
- else
- abort ();
- }
-
- static int
- not_accessible_field_error (tree wfl, tree decl)
- {
- parse_error_context
- (wfl, "Can't access %s field %<%s.%s%> from %qs",
- accessibility_string (get_access_flags_from_decl (decl)),
- GET_TYPE_NAME (DECL_CONTEXT (decl)),
- IDENTIFIER_POINTER (DECL_NAME (decl)),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
- return 1;
- }
-
- int
- java_report_errors (void)
- {
- if (java_error_count)
- fprintf (stderr, "%d error%s",
- java_error_count, (java_error_count == 1 ? "" : "s"));
- if (java_warning_count)
- fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
- java_warning_count, (java_warning_count == 1 ? "" : "s"));
- if (java_error_count || java_warning_count)
- putc ('\n', stderr);
- return java_error_count;
- }
-
- static char *
- java_accstring_lookup (int flags)
- {
- static char buffer [80];
- #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
-
- /* Access modifier looked-up first for easier report on forbidden
- access. */
- if (flags & ACC_PUBLIC) COPY_RETURN ("public");
- if (flags & ACC_PRIVATE) COPY_RETURN ("private");
- if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
- if (flags & ACC_STATIC) COPY_RETURN ("static");
- if (flags & ACC_FINAL) COPY_RETURN ("final");
- if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
- if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
- if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
- if (flags & ACC_NATIVE) COPY_RETURN ("native");
- if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
- if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
-
- buffer [0] = '\0';
- return buffer;
- #undef COPY_RETURN
- }
-
- /* Returns a string denoting the accessibility of a class or a member as
- indicated by FLAGS. We need a separate function from
- java_accstring_lookup, as the latter can return spurious "static", etc.
- if package-private access is defined (in which case none of the
- relevant access control bits in FLAGS is set). */
-
- static const char *
- accessibility_string (int flags)
- {
- if (flags & ACC_PRIVATE) return "private";
- if (flags & ACC_PROTECTED) return "protected";
- if (flags & ACC_PUBLIC) return "public";
-
- return "package-private";
- }
-
- /* Issuing error messages upon redefinition of classes, interfaces or
- variables. */
-
- static void
- classitf_redefinition_error (const char *context, tree id, tree decl, tree cl)
- {
- parse_error_context (cl, "%s %qs already defined in %s:%d",
- context, IDENTIFIER_POINTER (id),
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
- /* Here we should point out where its redefined. It's a unicode. FIXME */
- }
-
- static void
- variable_redefinition_error (tree context, tree name, tree type, int line)
- {
- const char *type_name;
-
- /* Figure a proper name for type. We might haven't resolved it */
- if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
- type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
- else
- type_name = lang_printable_name (type, 0);
-
- parse_error_context (context,
- "Variable %qs is already defined in this method and was declared %<%s %s%> at line %d",
- IDENTIFIER_POINTER (name),
- type_name, IDENTIFIER_POINTER (name), line);
- }
-
- /* If ANAME is terminated with `[]', it indicates an array. This
- function returns the number of `[]' found and if this number is
- greater than zero, it extracts the array type name and places it in
- the node pointed to by TRIMMED unless TRIMMED is null. */
-
- static int
- build_type_name_from_array_name (tree aname, tree *trimmed)
- {
- const char *name = IDENTIFIER_POINTER (aname);
- int len = IDENTIFIER_LENGTH (aname);
- int array_dims;
-
- STRING_STRIP_BRACKETS (name, len, array_dims);
-
- if (array_dims && trimmed)
- *trimmed = get_identifier_with_length (name, len);
-
- return array_dims;
- }
-
- static tree
- build_array_from_name (tree type, tree type_wfl, tree name, tree *ret_name)
- {
- int more_dims = 0;
-
- /* Eventually get more dims */
- more_dims = build_type_name_from_array_name (name, &name);
-
- /* If we have, then craft a new type for this variable */
- if (more_dims)
- {
- tree save = type;
-
- /* If we have a pointer, use its type */
- if (TREE_CODE (type) == POINTER_TYPE)
- type = TREE_TYPE (type);
-
- /* Building the first dimension of a primitive type uses this
- function */
- if (JPRIMITIVE_TYPE_P (type))
- {
- type = build_java_array_type (type, -1);
- more_dims--;
- }
- /* Otherwise, if we have a WFL for this type, use it (the type
- is already an array on an unresolved type, and we just keep
- on adding dimensions) */
- else if (type_wfl)
- {
- type = type_wfl;
- more_dims += build_type_name_from_array_name (TYPE_NAME (save),
- NULL);
- }
-
- /* Add all the dimensions */
- while (more_dims--)
- type = build_unresolved_array_type (type);
-
- /* The type may have been incomplete in the first place */
- if (type_wfl)
- type = obtain_incomplete_type (type);
- }
-
- if (ret_name)
- *ret_name = name;
- return type;
- }
-
- /* Build something that the type identifier resolver will identify as
- being an array to an unresolved type. TYPE_WFL is a WFL on a
- identifier. */
-
- static tree
- build_unresolved_array_type (tree type_or_wfl)
- {
- const char *ptr;
- tree wfl;
-
- /* TYPE_OR_WFL might be an array on a resolved type. In this case,
- just create a array type */
- if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
- return build_java_array_type (type_or_wfl, -1);
-
- obstack_grow (&temporary_obstack,
- IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
- IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
- obstack_grow0 (&temporary_obstack, "[]", 2);
- ptr = obstack_finish (&temporary_obstack);
- #ifdef USE_MAPPED_LOCATION
- wfl = build_expr_wfl (get_identifier (ptr), EXPR_LOCATION (type_or_wfl));
- #else
- wfl = build_expr_wfl (get_identifier (ptr),
- EXPR_WFL_FILENAME (type_or_wfl),
- EXPR_WFL_LINENO (type_or_wfl),
- EXPR_WFL_COLNO (type_or_wfl));
- #endif
- /* Re-install the existing qualifications so that the type can be
- resolved properly. */
- EXPR_WFL_QUALIFICATION (wfl) = EXPR_WFL_QUALIFICATION (type_or_wfl);
- return wfl;
- }
-
- static void
- parser_add_interface (tree class_decl, tree interface_decl, tree wfl)
- {
- if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
- parse_error_context (wfl, "Interface %qs repeated",
- IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
- }
-
- /* Bulk of common class/interface checks. Return 1 if an error was
- encountered. TAG is 0 for a class, 1 for an interface. */
-
- static int
- check_class_interface_creation (int is_interface, int flags, tree raw_name,
- tree qualified_name, tree decl, tree cl)
- {
- tree node;
- int sca = 0; /* Static class allowed */
- int icaf = 0; /* Inner class allowed flags */
- int uaaf = CLASS_MODIFIERS; /* Usually allowed access flags */
-
- if (!quiet_flag)
- fprintf (stderr, " %s%s %s",
- (CPC_INNER_P () ? "inner" : ""),
- (is_interface ? "interface" : "class"),
- IDENTIFIER_POINTER (qualified_name));
-
- /* Scope of an interface/class type name:
- - Can't be imported by a single type import
- - Can't already exists in the package */
- if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
- && (node = find_name_in_single_imports (raw_name))
- && !CPC_INNER_P ())
- {
- parse_error_context
- (cl, "%s name %qs clashes with imported type %qs",
- (is_interface ? "Interface" : "Class"),
- IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
- return 1;
- }
- if (decl && CLASS_COMPLETE_P (decl))
- {
- classitf_redefinition_error ((is_interface ? "Interface" : "Class"),
- qualified_name, decl, cl);
- return 1;
- }
-
- if (check_inner_class_redefinition (raw_name, cl))
- return 1;
-
- /* If public, file name should match class/interface name, except
- when dealing with an inner class */
- if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
- {
- const char *fname = input_filename;
- const char *f;
-
- for (f = fname + strlen (fname);
- f != fname && ! IS_DIR_SEPARATOR (*f);
- f--)
- ;
- if (IS_DIR_SEPARATOR (*f))
- f++;
- if (strncmp (IDENTIFIER_POINTER (raw_name),
- f , IDENTIFIER_LENGTH (raw_name)) ||
- f [IDENTIFIER_LENGTH (raw_name)] != '.')
- parse_error_context
- (cl, "Public %s %qs must be defined in a file called %<%s.java%>",
- (is_interface ? "interface" : "class"),
- IDENTIFIER_POINTER (qualified_name),
- IDENTIFIER_POINTER (raw_name));
- }
-
- /* Static classes can be declared only in top level classes. Note:
- once static, a inner class is a top level class. */
- if (flags & ACC_STATIC)
- {
- /* Catch the specific error of declaring an class inner class
- with no toplevel enclosing class. Prevent check_modifiers from
- complaining a second time */
- if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
- {
- parse_error_context (cl, "Inner class %qs can't be static. Static classes can only occur in interfaces and top-level classes",
- IDENTIFIER_POINTER (qualified_name));
- sca = ACC_STATIC;
- }
- /* Else, in the context of a top-level class declaration, let
- `check_modifiers' do its job, otherwise, give it a go */
- else
- sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
- }
-
- /* Inner classes can be declared private or protected
- within their enclosing classes. */
- if (CPC_INNER_P ())
- {
- /* A class which is local to a block can't be public, private,
- protected or static. But it is created final, so allow this
- one. */
- if (current_function_decl)
- icaf = sca = uaaf = ACC_FINAL;
- else
- {
- check_modifiers_consistency (flags);
- icaf = ACC_PROTECTED;
- if (! CLASS_INTERFACE (GET_CPC ()))
- icaf |= ACC_PRIVATE;
- }
- }
-
- if (is_interface)
- {
- if (CPC_INNER_P ())
- uaaf = INTERFACE_INNER_MODIFIERS;
- else
- uaaf = INTERFACE_MODIFIERS;
-
- check_modifiers ("Illegal modifier %qs for interface declaration",
- flags, uaaf);
- }
- else
- check_modifiers ((current_function_decl ?
- "Illegal modifier %qs for local class declaration" :
- "Illegal modifier %qs for class declaration"),
- flags, uaaf|sca|icaf);
- return 0;
- }
-
- /* Construct a nested class name. If the final component starts with
- a digit, return true. Otherwise return false. */
- static int
- make_nested_class_name (tree cpc_list)
- {
- tree name;
-
- if (!cpc_list)
- return 0;
-
- make_nested_class_name (TREE_CHAIN (cpc_list));
-
- /* Pick the qualified name when dealing with the first upmost
- enclosing class */
- name = (TREE_CHAIN (cpc_list)
- ? TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
- obstack_grow (&temporary_obstack,
- IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
- obstack_1grow (&temporary_obstack, '$');
-
- return ISDIGIT (IDENTIFIER_POINTER (name)[0]);
- }
-
- /* Can't redefine a class already defined in an earlier scope. */
-
- static int
- check_inner_class_redefinition (tree raw_name, tree cl)
- {
- tree scope_list;
-
- for (scope_list = GET_CPC_LIST (); scope_list;
- scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
- if (raw_name == GET_CPC_UN_NODE (scope_list))
- {
- parse_error_context
- (cl, "The class name %qs is already defined in this scope. An inner class may not have the same simple name as any of its enclosing classes",
- IDENTIFIER_POINTER (raw_name));
- return 1;
- }
- return 0;
- }
-
- /* Tries to find a decl for CLASS_TYPE within ENCLOSING. If we fail,
- we remember ENCLOSING and SUPER. */
-
- static tree
- resolve_inner_class (htab_t circularity_hash, tree cl, tree *enclosing,
- tree *super, tree class_type)
- {
- tree local_enclosing = *enclosing;
- tree local_super = NULL_TREE;
-
- while (local_enclosing)
- {
- tree intermediate, decl;
-
- *htab_find_slot (circularity_hash, local_enclosing, INSERT) =
- local_enclosing;
-
- if ((decl = find_as_inner_class (local_enclosing, class_type, cl)))
- return decl;
-
- intermediate = local_enclosing;
- /* Explore enclosing contexts. */
- while (INNER_CLASS_DECL_P (intermediate))
- {
- intermediate = DECL_CONTEXT (intermediate);
- if ((decl = find_as_inner_class (intermediate, class_type, cl)))
- return decl;
- }
-
- /* Now go to the upper classes, bail out if necessary. We will
- analyze the returned SUPER and act accordingly (see
- do_resolve_class). */
- if (JPRIMITIVE_TYPE_P (TREE_TYPE (local_enclosing))
- || TREE_TYPE (local_enclosing) == void_type_node)
- {
- parse_error_context (cl, "Qualifier must be a reference");
- local_enclosing = NULL_TREE;
- break;
- }
- local_super = CLASSTYPE_SUPER (TREE_TYPE (local_enclosing));
- if (!local_super || local_super == object_type_node)
- break;
-
- if (TREE_CODE (local_super) == POINTER_TYPE)
- local_super = do_resolve_class (NULL, local_super, NULL, NULL);
- else
- local_super = TYPE_NAME (local_super);
-
- /* We may not have checked for circular inheritance yet, so do so
- here to prevent an infinite loop. */
- if (htab_find (circularity_hash, local_super) != NULL)
- {
- if (!cl)
- cl = lookup_cl (local_enclosing);
-
- parse_error_context
- (cl, "Cyclic inheritance involving %s",
- IDENTIFIER_POINTER (DECL_NAME (local_enclosing)));
- local_enclosing = NULL_TREE;
- }
- else
- local_enclosing = local_super;
- }
-
- /* We failed. Return LOCAL_SUPER and LOCAL_ENCLOSING. */
- *super = local_super;
- *enclosing = local_enclosing;
-
- return NULL_TREE;
- }
-
- /* Within ENCLOSING, find a decl for NAME and return it. NAME can be
- qualified. */
-
- static tree
- find_as_inner_class (tree enclosing, tree name, tree cl)
- {
- tree qual, to_return;
- if (!enclosing)
- return NULL_TREE;
-
- name = TYPE_NAME (name);
-
- /* First search: within the scope of `enclosing', search for name */
- if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
- qual = EXPR_WFL_QUALIFICATION (cl);
- else if (cl)
- qual = build_tree_list (cl, NULL_TREE);
- else
- qual = build_tree_list (build_unknown_wfl (name), NULL_TREE);
-
- if ((to_return = find_as_inner_class_do (qual, enclosing)))
- return to_return;
-
- /* We're dealing with a qualified name. Try to resolve thing until
- we get something that is an enclosing class. */
- if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
- {
- tree acc = NULL_TREE, decl = NULL_TREE, ptr;
-
- for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl;
- qual = TREE_CHAIN (qual))
- {
- acc = merge_qualified_name (acc,
- EXPR_WFL_NODE (TREE_PURPOSE (qual)));
- BUILD_PTR_FROM_NAME (ptr, acc);
- decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
- }
-
- /* A NULL qual and a decl means that the search ended
- successfully?!? We have to do something then. FIXME */
-
- if (decl)
- enclosing = decl;
- else
- qual = EXPR_WFL_QUALIFICATION (cl);
- }
- /* Otherwise, create a qual for the other part of the resolution. */
- else
- qual = build_tree_list (build_unknown_wfl (name), NULL_TREE);
-
- return find_as_inner_class_do (qual, enclosing);
- }
-
- /* We go inside the list of sub classes and try to find a way
- through. */
-
- static tree
- find_as_inner_class_do (tree qual, tree enclosing)
- {
- if (!qual)
- return NULL_TREE;
-
- for (; qual && enclosing; qual = TREE_CHAIN (qual))
- {
- tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
- tree next_enclosing = NULL_TREE;
- tree inner_list;
-
- for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
- inner_list; inner_list = TREE_CHAIN (inner_list))
- {
- if (TREE_VALUE (inner_list) == name_to_match)
- {
- next_enclosing = TREE_PURPOSE (inner_list);
- break;
- }
- }
- enclosing = next_enclosing;
- }
-
- return (!qual && enclosing ? enclosing : NULL_TREE);
- }
-
- static void
- link_nested_class_to_enclosing (void)
- {
- if (GET_ENCLOSING_CPC ())
- {
- tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
- DECL_INNER_CLASS_LIST (enclosing) =
- tree_cons (GET_CPC (), GET_CPC_UN (),
- DECL_INNER_CLASS_LIST (enclosing));
- }
- }
-
- static tree
- maybe_make_nested_class_name (tree name)
- {
- tree id = NULL_TREE;
-
- if (CPC_INNER_P ())
- {
- /* If we're in a function, we must append a number to create the
- nested class name. However, we don't do this if the class we
- are constructing is anonymous, because in that case we'll
- already have a number as the class name. */
- if (! make_nested_class_name (GET_CPC_LIST ())
- && current_function_decl != NULL_TREE
- && ! ISDIGIT (IDENTIFIER_POINTER (name)[0]))
- {
- char buf[10];
- sprintf (buf, "%d", anonymous_class_counter);
- ++anonymous_class_counter;
- obstack_grow (&temporary_obstack, buf, strlen (buf));
- obstack_1grow (&temporary_obstack, '$');
- }
- obstack_grow0 (&temporary_obstack,
- IDENTIFIER_POINTER (name),
- IDENTIFIER_LENGTH (name));
- id = get_identifier (obstack_finish (&temporary_obstack));
- if (ctxp->package)
- QUALIFIED_P (id) = 1;
- }
- return id;
- }
-
- /* If DECL is NULL, create and push a new DECL, record the current
- line CL and do other maintenance things. */
-
- static tree
- maybe_create_class_interface_decl (tree decl, tree raw_name,
- tree qualified_name, tree cl)
- {
- if (!decl)
- decl = push_class (make_class (), qualified_name);
-
- /* Take care of the file and line business */
- #ifdef USE_MAPPED_LOCATION
- DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (cl);
- #else
- DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
- /* If we're emitting xrefs, store the line/col number information */
- if (flag_emit_xref)
- DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
- else
- DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
- #endif
- CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
- CLASS_PARSED_P (TREE_TYPE (decl)) = 1;
- #ifdef USE_MAPPED_LOCATION
- {
- tree tmp = maybe_get_identifier (EXPR_FILENAME (cl));
- CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) =
- tmp && IS_A_COMMAND_LINE_FILENAME_P (tmp);
- }
- #else
- CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) =
- IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
- #endif
-
- PUSH_CPC (decl, raw_name);
- DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
-
- /* Link the declaration to the already seen ones */
- TREE_CHAIN (decl) = ctxp->class_list;
- ctxp->class_list = decl;
-
- /* Create a new nodes in the global lists */
- gclass_list = tree_cons (NULL_TREE, decl, gclass_list);
- all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
-
- /* Install a new dependency list element */
- create_jdep_list (ctxp);
-
- SOURCE_FRONTEND_DEBUG (("Defining class/interface %s",
- IDENTIFIER_POINTER (qualified_name)));
- return decl;
- }
-
- static void
- add_superinterfaces (tree decl, tree interface_list)
- {
- tree node;
- /* Superinterface(s): if present and defined, parser_check_super_interface ()
- takes care of ensuring that:
- - This is an accessible interface type,
- - Circularity detection.
- parser_add_interface is then called. If present but not defined,
- the check operation is delayed until the super interface gets
- defined. */
- for (node = interface_list; node; node = TREE_CHAIN (node))
- {
- tree current = TREE_PURPOSE (node);
- tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
- if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
- {
- if (!parser_check_super_interface (idecl, decl, current))
- parser_add_interface (decl, idecl, current);
- }
- else
- register_incomplete_type (JDEP_INTERFACE,
- current, decl, NULL_TREE);
- }
- }
-
- /* Create an interface in pass1 and return its decl. Return the
- interface's decl in pass 2. */
-
- static tree
- create_interface (int flags, tree id, tree super)
- {
- tree raw_name = EXPR_WFL_NODE (id);
- tree q_name = parser_qualified_classname (raw_name);
- tree decl = IDENTIFIER_CLASS_VALUE (q_name);
-
- /* Certain syntax errors are making SUPER be like ID. Avoid this
- case. */
- if (ctxp->class_err && id == super)
- super = NULL;
-
- EXPR_WFL_NODE (id) = q_name; /* Keep source location, even if refined. */
-
- /* Basic checks: scope, redefinition, modifiers */
- if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
- {
- PUSH_ERROR ();
- return NULL_TREE;
- }
-
- /* Suspend the current parsing context if we're parsing an inner
- interface */
- if (CPC_INNER_P ())
- {
- java_parser_context_suspend ();
- /* Interface members are public. */
- if (CLASS_INTERFACE (GET_CPC ()))
- flags |= ACC_PUBLIC;
- }
-
- /* Push a new context for (static) initialized upon declaration fields */
- java_parser_context_push_initialized_field ();
-
- /* Interface modifiers check
- - public/abstract allowed (already done at that point)
- - abstract is obsolete (comes first, it's a warning, or should be)
- - Can't use twice the same (checked in the modifier rule) */
- if ((flags & ACC_ABSTRACT) && flag_redundant)
- parse_warning_context
- (MODIFIER_WFL (ABSTRACT_TK),
- "Redundant use of %<abstract%> modifier. Interface %qs is implicitly abstract", IDENTIFIER_POINTER (raw_name));
-
- /* Create a new decl if DECL is NULL, otherwise fix it */
- decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
-
- /* Interfaces are always abstract. */
- flags |= ACC_ABSTRACT;
-
- /* Inner interfaces are always static. */
- if (INNER_CLASS_DECL_P (decl))
- flags |= ACC_STATIC;
-
- /* Set super info and mark the class a complete */
- set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl),
- object_type_node, ctxp->interface_number);
- ctxp->interface_number = 0;
- CLASS_COMPLETE_P (decl) = 1;
- add_superinterfaces (decl, super);
-
- /* Eventually sets the @deprecated tag flag */
- CHECK_DEPRECATED (decl);
-
- return decl;
- }
-
- /* Patch anonymous class CLASS, by either extending or implementing
- DEP. */
-
- static void
- patch_anonymous_class (tree type_decl, tree class_decl, tree wfl)
- {
- tree class = TREE_TYPE (class_decl);
- tree type = TREE_TYPE (type_decl);
- tree binfo = TYPE_BINFO (class);
-
- /* If it's an interface, implement it */
- if (CLASS_INTERFACE (type_decl))
- {
- if (parser_check_super_interface (type_decl, class_decl, wfl))
- return;
-
- if (!VEC_space (tree, BINFO_BASE_BINFOS (binfo), 1))
- {
- /* Extend the binfo - by reallocating and copying it. */
- tree new_binfo;
- tree base_binfo;
- int i;
-
- new_binfo = make_tree_binfo ((BINFO_N_BASE_BINFOS (binfo) + 1) * 2);
- for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
- BINFO_BASE_APPEND (new_binfo, base_binfo);
- CLASS_HAS_SUPER_FLAG (new_binfo) = CLASS_HAS_SUPER_FLAG (binfo);
- BINFO_VTABLE (new_binfo) = BINFO_VTABLE (binfo);
- TYPE_BINFO (class) = new_binfo;
- }
-
- /* And add the interface */
- parser_add_interface (class_decl, type_decl, wfl);
- }
- /* Otherwise, it's a type we want to extend */
- else
- {
- if (parser_check_super (type_decl, class_decl, wfl))
- return;
- BINFO_TYPE (BINFO_BASE_BINFO (binfo, 0)) = type;
- }
- }
-
- /* Create an anonymous class which extends/implements TYPE_NAME, and return
- its decl. */
-
- static tree
- create_anonymous_class (tree type_name)
- {
- char buffer [80];
- tree super = NULL_TREE, itf = NULL_TREE;
- tree id, type_decl, class;
-
- /* The unqualified name of the anonymous class. It's just a number. */
- sprintf (buffer, "%d", anonymous_class_counter++);
- id = build_wfl_node (get_identifier (buffer));
- EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL (type_name);
-
- /* We know about the type to extend/implement. We go ahead */
- if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
- {
- /* Create a class which either implements on extends the designated
- class. The class bears an inaccessible name. */
- if (CLASS_INTERFACE (type_decl))
- {
- /* It's OK to modify it here. It's been already used and
- shouldn't be reused */
- ctxp->interface_number = 1;
- /* Interfaces should presented as a list of WFLs */
- itf = build_tree_list (type_name, NULL_TREE);
- }
- else
- super = type_name;
- }
-
- class = create_class (ACC_FINAL, id, super, itf);
-
- /* We didn't know anything about the stuff. We register a dependence. */
- if (!type_decl)
- register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
-
- ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
- return class;
- }
-
- /* Create a class in pass1 and return its decl. Return class
- interface's decl in pass 2. */
-
- static tree
- create_class (int flags, tree id, tree super, tree interfaces)
- {
- tree raw_name = EXPR_WFL_NODE (id);
- tree class_id, decl;
- tree super_decl_type;
-
- /* Certain syntax errors are making SUPER be like ID. Avoid this
- case. */
- if (ctxp->class_err && id == super)
- super = NULL;
-
- class_id = parser_qualified_classname (raw_name);
- decl = IDENTIFIER_CLASS_VALUE (class_id);
- EXPR_WFL_NODE (id) = class_id;
-
- /* Basic check: scope, redefinition, modifiers */
- if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
- {
- PUSH_ERROR ();
- return NULL_TREE;
- }
-
- /* Suspend the current parsing context if we're parsing an inner
- class or an anonymous class. */
- if (CPC_INNER_P ())
- {
- java_parser_context_suspend ();
- /* Interface members are public. */
- if (CLASS_INTERFACE (GET_CPC ()))
- flags |= ACC_PUBLIC;
- }
-
- /* Push a new context for (static) initialized upon declaration fields */
- java_parser_context_push_initialized_field ();
-
- /* Class modifier check:
- - Allowed modifier (already done at that point)
- - abstract AND final forbidden
- - Public classes defined in the correct file */
- if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
- parse_error_context
- (id, "Class %qs can't be declared both abstract and final",
- IDENTIFIER_POINTER (raw_name));
-
- /* Create a new decl if DECL is NULL, otherwise fix it */
- decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
-
- /* If SUPER exists, use it, otherwise use Object */
- if (super)
- {
- /* java.lang.Object can't extend anything. */
- if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
- {
- parse_error_context (id, "%<java.lang.Object%> can't extend anything");
- return NULL_TREE;
- }
-
- super_decl_type =
- register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
- }
- else if (TREE_TYPE (decl) != object_type_node)
- super_decl_type = object_type_node;
- /* We're defining java.lang.Object */
- else
- super_decl_type = NULL_TREE;
-
- /* A class nested in an interface is implicitly static. */
- if (INNER_CLASS_DECL_P (decl)
- && CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (DECL_CONTEXT (decl)))))
- {
- flags |= ACC_STATIC;
- }
-
- /* Set super info and mark the class as complete. */
- set_super_info (flags, TREE_TYPE (decl), super_decl_type,
- ctxp->interface_number);
- ctxp->interface_number = 0;
- CLASS_COMPLETE_P (decl) = 1;
- add_superinterfaces (decl, interfaces);
-
- /* TYPE_VFIELD' is a compiler-generated field used to point to
- virtual function tables. In gcj, every class has a common base
- virtual function table in java.lang.object. */
- TYPE_VFIELD (TREE_TYPE (decl)) = TYPE_VFIELD (object_type_node);
-
- /* Add the private this$<n> field, Replicate final locals still in
- scope as private final fields mangled like val$<local_name>.
- This does not occur for top level (static) inner classes. */
- if (PURE_INNER_CLASS_DECL_P (decl))
- add_inner_class_fields (decl, current_function_decl);
-
- /* If doing xref, store the location at which the inherited class
- (if any) was seen. */
- if (flag_emit_xref && super)
- DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
-
- /* Eventually sets the @deprecated tag flag */
- CHECK_DEPRECATED (decl);
-
- /* Reset the anonymous class counter when declaring non inner classes */
- if (!INNER_CLASS_DECL_P (decl))
- anonymous_class_counter = 1;
-
- return decl;
- }
-
- /* End a class declaration: register the statements used to create
- finit$ and <clinit>, pop the current class and resume the prior
- parser context if necessary. */
-
- static void
- end_class_declaration (int resume)
- {
- /* If an error occurred, context weren't pushed and won't need to be
- popped by a resume. */
- int no_error_occurred = ctxp->next && GET_CPC () != error_mark_node;
-
- if (GET_CPC () != error_mark_node)
- dump_java_tree (TDI_class, GET_CPC ());
-
- java_parser_context_pop_initialized_field ();
- POP_CPC ();
- if (resume && no_error_occurred)
- java_parser_context_resume ();
-
- /* We're ending a class declaration, this is a good time to reset
- the interface cout. Note that might have been already done in
- create_interface, but if at that time an inner class was being
- dealt with, the interface count was reset in a context created
- for the sake of handling inner classes declaration. */
- ctxp->interface_number = 0;
- }
-
- static void
- add_inner_class_fields (tree class_decl, tree fct_decl)
- {
- tree block, marker, f;
-
- f = add_field (TREE_TYPE (class_decl),
- build_current_thisn (TREE_TYPE (class_decl)),
- build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))),
- ACC_PRIVATE);
- FIELD_THISN (f) = 1;
-
- if (!fct_decl)
- return;
-
- for (block = GET_CURRENT_BLOCK (fct_decl);
- block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
- {
- tree decl;
- for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
- {
- tree name, pname;
- tree wfl, init, list;
-
- /* Avoid non final arguments. */
- if (!LOCAL_FINAL_P (decl))
- continue;
-
- MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
- MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
- wfl = build_wfl_node (name);
- init = build_wfl_node (pname);
- /* Build an initialization for the field: it will be
- initialized by a parameter added to finit$, bearing a
- mangled name of the field itself (param$<n>.) The
- parameter is provided to finit$ by the constructor
- invoking it (hence the constructor will also feature a
- hidden parameter, set to the value of the outer context
- local at the time the inner class is created.)
-
- Note: we take into account all possible locals that can
- be accessed by the inner class. It's actually not trivial
- to minimize these aliases down to the ones really
- used. One way to do that would be to expand all regular
- methods first, then finit$ to get a picture of what's
- used. It works with the exception that we would have to
- go back on all constructor invoked in regular methods to
- have their invocation reworked (to include the right amount
- of alias initializer parameters.)
-
- The only real way around, I think, is a first pass to
- identify locals really used in the inner class. We leave
- the flag FIELD_LOCAL_ALIAS_USED around for that future
- use.
-
- On the other hand, it only affect local inner classes,
- whose constructors (and finit$ call) will be featuring
- unnecessary arguments. It's easy for a developer to keep
- this number of parameter down by using the `final'
- keyword only when necessary. For the time being, we can
- issue a warning on unnecessary finals. FIXME */
- init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl),
- wfl, init);
-
- /* Register the field. The TREE_LIST holding the part
- initialized/initializer will be marked ARG_FINAL_P so
- that the created field can be marked
- FIELD_LOCAL_ALIAS. */
- list = build_tree_list (wfl, init);
- ARG_FINAL_P (list) = 1;
- register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
- }
- }
-
- if (!CPC_INITIALIZER_STMT (ctxp))
- return;
-
- /* If we ever registered an alias field, insert and marker to
- remember where the list ends. The second part of the list (the one
- featuring initialized fields) so it can be later reversed to
- enforce 8.5. The marker will be removed during that operation. */
- marker = build_tree_list (NULL_TREE, NULL_TREE);
- TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
- SET_CPC_INITIALIZER_STMT (ctxp, marker);
- }
-
- /* Can't use lookup_field () since we don't want to load the class and
- can't set the CLASS_LOADED_P flag */
-
- static tree
- find_field (tree class, tree name)
- {
- tree decl;
- for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
- {
- if (DECL_NAME (decl) == name)
- return decl;
- }
- return NULL_TREE;
- }
-
- /* Wrap around lookup_field that doesn't potentially upset the value
- of CLASS */
-
- static tree
- lookup_field_wrapper (tree class, tree name)
- {
- tree type = class;
- tree decl = NULL_TREE;
- java_parser_context_save_global ();
-
- /* Last chance: if we're within the context of an inner class, we
- might be trying to access a local variable defined in an outer
- context. We try to look for it now. */
- if (INNER_CLASS_TYPE_P (class) && TREE_CODE (name) == IDENTIFIER_NODE)
- {
- tree new_name;
- MANGLE_OUTER_LOCAL_VARIABLE_NAME (new_name, name);
- decl = lookup_field (&type, new_name);
- if (decl && decl != error_mark_node)
- FIELD_LOCAL_ALIAS_USED (decl) = 1;
- }
- if (!decl || decl == error_mark_node)
- {
- type = class;
- decl = lookup_field (&type, name);
- }
-
- /* If the field still hasn't been found, try the next enclosing context. */
- if (!decl && INNER_CLASS_TYPE_P (class))
- {
- tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
- decl = lookup_field_wrapper (outer_type, name);
- }
-
- java_parser_context_restore_global ();
- return decl == error_mark_node ? NULL : decl;
- }
-
- /* Find duplicate field within the same class declarations and report
- the error. Returns 1 if a duplicated field was found, 0
- otherwise. */
-
- static int
- duplicate_declaration_error_p (tree new_field_name, tree new_type, tree cl)
- {
- /* This might be modified to work with method decl as well */
- tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
- if (decl)
- {
- char *t1 = xstrdup (purify_type_name
- ((TREE_CODE (new_type) == POINTER_TYPE
- && TREE_TYPE (new_type) == NULL_TREE) ?
- IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
- lang_printable_name (new_type, 1)));
- /* The type may not have been completed by the time we report
- the error */
- char *t2 = xstrdup (purify_type_name
- ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
- && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
- IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
- lang_printable_name (TREE_TYPE (decl), 1)));
- parse_error_context
- (cl, "Duplicate variable declaration: %<%s %s%> was %<%s %s%> (%s:%d)",
- t1, IDENTIFIER_POINTER (new_field_name),
- t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
- free (t1);
- free (t2);
- return 1;
- }
- return 0;
- }
-
- /* Field registration routine. If TYPE doesn't exist, field
- declarations are linked to the undefined TYPE dependency list, to
- be later resolved in java_complete_class () */
-
- static void
- register_fields (int flags, tree type, tree variable_list)
- {
- tree current, saved_type;
- tree class_type = NULL_TREE;
- location_t saved_location = input_location;
- int must_chain = 0;
- tree wfl = NULL_TREE;
-
- if (GET_CPC ())
- class_type = TREE_TYPE (GET_CPC ());
-
- if (!class_type || class_type == error_mark_node)
- return;
-
- /* If we're adding fields to interfaces, those fields are public,
- static, final */
- if (CLASS_INTERFACE (TYPE_NAME (class_type)))
- {
- OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
- flags, ACC_PUBLIC, "interface field(s)");
- OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
- flags, ACC_STATIC, "interface field(s)");
- OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
- flags, ACC_FINAL, "interface field(s)");
- check_modifiers ("Illegal interface member modifier %qs", flags,
- INTERFACE_FIELD_MODIFIERS);
- flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
- }
-
- /* Obtain a suitable type for resolution, if necessary */
- SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
-
- /* If TYPE is fully resolved and we don't have a reference, make one */
- PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
-
- for (current = variable_list, saved_type = type; current;
- current = TREE_CHAIN (current), type = saved_type)
- {
- tree real_type;
- tree field_decl;
- tree cl = TREE_PURPOSE (current);
- tree init = TREE_VALUE (current);
- tree current_name = EXPR_WFL_NODE (cl);
-
- /* Can't declare non-final static fields in inner classes */
- if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
- && !(flags & ACC_FINAL))
- parse_error_context
- (cl, "Field %qs can't be static in inner class %qs unless it is final",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
- lang_printable_name (class_type, 0));
-
- /* Process NAME, as it may specify extra dimension(s) for it */
- type = build_array_from_name (type, wfl, current_name, ¤t_name);
-
- /* Type adjustment. We may have just readjusted TYPE because
- the variable specified more dimensions. Make sure we have
- a reference if we can and don't have one already. Also
- change the name if we have an init. */
- if (type != saved_type)
- {
- PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
- if (init)
- 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 input_line to the line the field was found and create a
- declaration for it. Eventually sets the @deprecated tag flag. */
- #ifdef USE_MAPPED_LOCATION
- input_location = EXPR_LOCATION (cl);
- #else
- if (flag_emit_xref)
- input_line = EXPR_WFL_LINECOL (cl);
- else
- input_line = EXPR_WFL_LINENO (cl);
- #endif
- field_decl = add_field (class_type, current_name, real_type, flags);
- CHECK_DEPRECATED_NO_RESET (field_decl);
-
- /* If the field denotes a final instance variable, then we
- allocate a LANG_DECL_SPECIFIC part to keep track of its
- initialization. We also mark whether the field was
- initialized upon its declaration. We don't do that if the
- created field is an alias to a final local. */
- if (!ARG_FINAL_P (current) && (flags & ACC_FINAL))
- {
- MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field_decl);
- DECL_FIELD_FINAL_WFL (field_decl) = cl;
- }
-
- /* If the couple initializer/initialized is marked ARG_FINAL_P,
- we mark the created field FIELD_LOCAL_ALIAS, so that we can
- hide parameters to this inner class finit$ and
- constructors. It also means that the field isn't final per
- say. */
- if (ARG_FINAL_P (current))
- {
- FIELD_LOCAL_ALIAS (field_decl) = 1;
- FIELD_FINAL (field_decl) = 0;
- }
-
- /* Check if we must chain. */
- if (must_chain)
- register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
-
- /* If we have an initialization value tied to the field */
- if (init)
- {
- /* The field is declared static */
- if (flags & ACC_STATIC)
- {
- /* We include the field and its initialization part into
- a list used to generate <clinit>. After <clinit> is
- walked, field initializations will be processed and
- fields initialized with known constants will be taken
- out of <clinit> and have their DECL_INITIAL set
- appropriately. */
- TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
- SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
- if (TREE_OPERAND (init, 1)
- && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
- TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
- }
- /* A non-static field declared with an immediate initialization is
- to be initialized in <init>, if any. This field is remembered
- to be processed at the time of the generation of <init>. */
- else
- {
- TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
- SET_CPC_INITIALIZER_STMT (ctxp, init);
- }
- MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
- DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
- }
- }
-
- CLEAR_DEPRECATED;
- input_location = saved_location;
- }
-
- /* Generate finit$, using the list of initialized fields to populate
- its body. finit$'s parameter(s) list is adjusted to include the
- one(s) used to initialized the field(s) caching outer context
- local(s). */
-
- static tree
- generate_finit (tree class_type)
- {
- int count = 0;
- tree list = TYPE_FINIT_STMT_LIST (class_type);
- tree mdecl, current, parms;
-
- parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
- class_type, NULL_TREE,
- &count);
- CRAFTED_PARAM_LIST_FIXUP (parms);
- mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
- finit_identifier_node, parms);
- fix_method_argument_names (parms, mdecl);
- layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
- mdecl, NULL_TREE);
- DECL_FUNCTION_NAP (mdecl) = count;
- start_artificial_method_body (mdecl);
-
- for (current = list; current; current = TREE_CHAIN (current))
- java_method_add_stmt (mdecl,
- build_debugable_stmt (EXPR_WFL_LINECOL (current),
- current));
- end_artificial_method_body (mdecl);
- return mdecl;
- }
-
- /* Generate a function to run the instance initialization code. The
- private method is called `instinit$'. Unless we're dealing with an
- anonymous class, we determine whether all ctors of CLASS_TYPE
- declare a checked exception in their `throws' clause in order to
- see whether it's necessary to encapsulate the instance initializer
- statements in a try/catch/rethrow sequence. */
-
- static tree
- generate_instinit (tree class_type)
- {
- tree current;
- tree compound = NULL_TREE;
- tree parms = tree_cons (this_identifier_node,
- build_pointer_type (class_type), end_params_node);
- tree mdecl = create_artificial_method (class_type, ACC_PRIVATE,
- void_type_node,
- instinit_identifier_node, parms);
-
- layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
- mdecl, NULL_TREE);
-
- /* Gather all the statements in a compound */
- for (current = TYPE_II_STMT_LIST (class_type);
- current; current = TREE_CHAIN (current))
- compound = add_stmt_to_compound (compound, NULL_TREE, current);
-
- /* We need to encapsulate COMPOUND by a try/catch statement to
- rethrow exceptions that might occur in the instance initializer.
- We do that only if all ctors of CLASS_TYPE are set to catch a
- checked exception. This doesn't apply to anonymous classes (since
- they don't have declared ctors.) */
- if (!ANONYMOUS_CLASS_P (class_type) &&
- ctors_unchecked_throws_clause_p (class_type))
- {
- compound = encapsulate_with_try_catch (0, exception_type_node, compound,
- build1 (THROW_EXPR, NULL_TREE,
- build_wfl_node (wpv_id)));
- DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
- exception_type_node);
- }
-
- start_artificial_method_body (mdecl);
- java_method_add_stmt (mdecl, compound);
- end_artificial_method_body (mdecl);
-
- return mdecl;
- }
-
- /* FIXME */
- static tree
- build_instinit_invocation (tree class_type)
- {
- tree to_return = NULL_TREE;
-
- if (TYPE_II_STMT_LIST (class_type))
- {
- tree parm = build_tree_list (NULL_TREE,
- build_wfl_node (this_identifier_node));
- to_return =
- build_method_invocation (build_wfl_node (instinit_identifier_node),
- parm);
- }
- return to_return;
- }
-
- /* Shared across method_declarator and method_header to remember the
- patch stage that was reached during the declaration of the method.
- A method DECL is built differently is there is no patch
- (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
- pending on the currently defined method. */
-
- static int patch_stage;
-
- /* Check the method declaration and add the method to its current
- class. If the argument list is known to contain incomplete types,
- the method is partially added and the registration will be resume
- once the method arguments resolved. If TYPE is NULL, we're dealing
- with a constructor. */
-
- static tree
- method_header (int flags, tree type, tree mdecl, tree throws)
- {
- tree type_wfl = NULL_TREE;
- tree meth_name = NULL_TREE;
- tree current, orig_arg, this_class = NULL;
- tree id, meth;
- location_t saved_location;
- int constructor_ok = 0, must_chain;
- int count;
-
- if (mdecl == error_mark_node)
- return error_mark_node;
- meth = TREE_VALUE (mdecl);
- id = TREE_PURPOSE (mdecl);
-
- check_modifiers_consistency (flags);
-
- if (GET_CPC ())
- this_class = TREE_TYPE (GET_CPC ());
-
- if (!this_class || this_class == error_mark_node)
- return NULL_TREE;
-
- /* There are some forbidden modifiers for an abstract method and its
- class must be abstract as well. */
- if (type && (flags & ACC_ABSTRACT))
- {
- ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
- ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
- ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
- ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
- ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED, id, "Synchronized");
- ABSTRACT_CHECK (flags, ACC_STRICT, id, "Strictfp");
- if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
- && !CLASS_INTERFACE (TYPE_NAME (this_class)))
- parse_error_context
- (id,
- "Class %qs must be declared abstract to define abstract method %qs",
- IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())),
- IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
- }
-
- /* A native method can't be strictfp. */
- if ((flags & ACC_NATIVE) && (flags & ACC_STRICT))
- parse_error_context (id, "native method %qs can't be strictfp",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
- /* No such thing as a transient or volatile method. */
- if ((flags & ACC_TRANSIENT))
- parse_error_context (id, "method %qs can't be transient",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
- if ((flags & ACC_VOLATILE))
- parse_error_context (id, "method %qs can't be volatile",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
-
- /* Things to be checked when declaring a constructor */
- if (!type)
- {
- int ec = java_error_count;
- /* 8.6: Constructor declarations: we might be trying to define a
- method without specifying a return type. */
- if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
- parse_error_context
- (id, "Invalid method declaration, return type required");
- /* 8.6.3: Constructor modifiers */
- else
- {
- JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
- JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
- JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
- JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
- JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
- JCONSTRUCTOR_CHECK (flags, ACC_STRICT, id, "strictfp");
- }
- /* If we found error here, we don't consider it's OK to tread
- the method definition as a constructor, for the rest of this
- function */
- if (ec == java_error_count)
- constructor_ok = 1;
- }
-
- /* Method declared within the scope of an interface are implicitly
- abstract and public. Conflicts with other erroneously provided
- modifiers are checked right after. */
-
- if (CLASS_INTERFACE (TYPE_NAME (this_class)))
- {
- /* If FLAGS isn't set because of a modifier, turn the
- corresponding modifier WFL to NULL so we issue a warning on
- the obsolete use of the modifier */
- if (!(flags & ACC_PUBLIC))
- MODIFIER_WFL (PUBLIC_TK) = NULL;
- if (!(flags & ACC_ABSTRACT))
- MODIFIER_WFL (ABSTRACT_TK) = NULL;
- flags |= ACC_PUBLIC;
- flags |= ACC_ABSTRACT;
- }
-
- /* Inner class can't declare static methods */
- if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
- {
- parse_error_context
- (id, "Method %qs can't be static in inner class %qs. Only members of interfaces and top-level classes can be static",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
- lang_printable_name (this_class, 0));
- }
-
- /* Modifiers context reset moved up, so abstract method declaration
- modifiers can be later checked. */
-
- /* Set constructor returned type to void and method name to <init>,
- unless we found an error identifier the constructor (in which
- case we retain the original name) */
- if (!type)
- {
- type = void_type_node;
- if (constructor_ok)
- meth_name = init_identifier_node;
- }
- else
- meth_name = EXPR_WFL_NODE (id);
-
- /* Do the returned type resolution and registration if necessary */
- SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
-
- if (meth_name)
- type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
- EXPR_WFL_NODE (id) = meth_name;
- PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
-
- if (must_chain)
- {
- patch_stage = JDEP_METHOD_RETURN;
- register_incomplete_type (patch_stage, type_wfl, id, type);
- TREE_TYPE (meth) = GET_REAL_TYPE (type);
- }
- else
- TREE_TYPE (meth) = type;
-
- saved_location = input_location;
- /* When defining an abstract or interface method, the curly
- bracket at level 1 doesn't exist because there is no function
- body */
- #ifdef USE_MAPPED_LOCATION
- input_location = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 :
- EXPR_LOCATION (id));
- #else
- input_line = (ctxp->first_ccb_indent1 ? (int) ctxp->first_ccb_indent1 :
- EXPR_WFL_LINENO (id));
- #endif
-
- /* Remember the original argument list */
- orig_arg = TYPE_ARG_TYPES (meth);
-
- if (patch_stage) /* includes ret type and/or all args */
- {
- jdep *jdep;
- meth = add_method_1 (this_class, flags, meth_name, meth);
- /* Patch for the return type */
- if (patch_stage == JDEP_METHOD_RETURN)
- {
- jdep = CLASSD_LAST (ctxp->classd_list);
- JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
- }
- /* This is the stop JDEP. METH allows the function's signature
- to be computed. */
- register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
- }
- else
- meth = add_method (this_class, flags, meth_name,
- build_java_signature (meth));
-
- /* Remember final parameters */
- MARK_FINAL_PARMS (meth, orig_arg);
-
- /* Fix the method argument list so we have the argument name
- information */
- fix_method_argument_names (orig_arg, meth);
-
- /* Register the parameter number and re-install the current line
- number */
- DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
- input_location = saved_location;
-
- /* Register exception specified by the `throws' keyword for
- resolution and set the method decl appropriate field to the list.
- Note: the grammar ensures that what we get here are class
- types. */
- if (throws)
- {
- throws = nreverse (throws);
- for (current = throws; current; current = TREE_CHAIN (current))
- {
- register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
- NULL_TREE, NULL_TREE);
- JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) =
- &TREE_VALUE (current);
- }
- DECL_FUNCTION_THROWS (meth) = throws;
- }
-
- if (TREE_TYPE (GET_CPC ()) != object_type_node)
- DECL_FUNCTION_WFL (meth) = id;
-
- /* Set the flag if we correctly processed a constructor */
- if (constructor_ok)
- {
- DECL_CONSTRUCTOR_P (meth) = 1;
- /* Compute and store the number of artificial parameters declared
- for this constructor */
- for (count = 0, current = TYPE_FIELDS (this_class); current;
- current = TREE_CHAIN (current))
- if (FIELD_LOCAL_ALIAS (current))
- count++;
- DECL_FUNCTION_NAP (meth) = count;
- }
-
- /* Eventually set the @deprecated tag flag */
- CHECK_DEPRECATED (meth);
-
- /* If doing xref, store column and line number information instead
- of the line number only. */
- if (flag_emit_xref)
- {
- #ifdef USE_MAPPED_LOCATION
- DECL_SOURCE_LOCATION (meth) = EXPR_LOCATION (id);
- #else
- DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
- #endif
- }
-
- return meth;
- }
-
- static void
- fix_method_argument_names (tree orig_arg, tree meth)
- {
- tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
- if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
- {
- TREE_PURPOSE (arg) = this_identifier_node;
- arg = TREE_CHAIN (arg);
- }
- while (orig_arg != end_params_node)
- {
- TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
- orig_arg = TREE_CHAIN (orig_arg);
- arg = TREE_CHAIN (arg);
- }
- }
-
- /* Complete the method declaration with METHOD_BODY. */
-
- static void
- finish_method_declaration (tree method_body)
- {
- int flags;
-
- if (!current_function_decl)
- return;
-
- flags = get_access_flags_from_decl (current_function_decl);
-
- /* 8.4.5 Method Body */
- if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
- {
- tree name = DECL_NAME (current_function_decl);
- parse_error_context (DECL_FUNCTION_WFL (current_function_decl),
- "%s method %qs can't have a body defined",
- (METHOD_NATIVE (current_function_decl) ?
- "Native" : "Abstract"),
- IDENTIFIER_POINTER (name));
- method_body = NULL_TREE;
- }
- else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
- {
- tree name = DECL_NAME (current_function_decl);
- parse_error_context
- (DECL_FUNCTION_WFL (current_function_decl),
- "Non native and non abstract method %qs must have a body defined",
- IDENTIFIER_POINTER (name));
- method_body = NULL_TREE;
- }
-
- if (flag_emit_class_files && method_body
- && TREE_CODE (method_body) == NOP_EXPR
- && TREE_TYPE (current_function_decl)
- && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
- method_body = build1 (RETURN_EXPR, void_type_node, NULL);
-
- BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
- maybe_absorb_scoping_blocks ();
- /* Exit function's body */
- exit_block ();
- /* Merge last line of the function with first line, directly in the
- function decl. It will be used to emit correct debug info. */
- if (!flag_emit_xref)
- DECL_FUNCTION_LAST_LINE (current_function_decl) = ctxp->last_ccb_indent1;
-
- /* Since function's argument's list are shared, reset the
- ARG_FINAL_P parameter that might have been set on some of this
- function parameters. */
- UNMARK_FINAL_PARMS (current_function_decl);
-
- /* So we don't have an irrelevant function declaration context for
- the next static block we'll see. */
- current_function_decl = NULL_TREE;
- }
-
- /* Build a an error message for constructor circularity errors. */
-
- static char *
- constructor_circularity_msg (tree from, tree to)
- {
- static char string [4096];
- char *t = xstrdup (lang_printable_name (from, 2));
- sprintf (string, "'%s' invokes '%s'", t, lang_printable_name (to, 2));
- free (t);
- return string;
- }
-
- /* Verify a circular call to METH. Return 1 if an error is found, 0
- otherwise. */
-
- static GTY(()) tree vcc_list;
- static int
- verify_constructor_circularity (tree meth, tree current)
- {
- tree c;
-
- for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
- {
- if (TREE_VALUE (c) == meth)
- {
- char *t;
- if (vcc_list)
- {
- tree liste;
- vcc_list = nreverse (vcc_list);
- for (liste = vcc_list; liste; liste = TREE_CHAIN (liste))
- {
- parse_error_context
- (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
- constructor_circularity_msg
- (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste))));
- java_error_count--;
- }
- }
- t = xstrdup (lang_printable_name (meth, 2));
- parse_error_context (TREE_PURPOSE (c),
- "%s: recursive invocation of constructor %qs",
- constructor_circularity_msg (current, meth), t);
- free (t);
- vcc_list = NULL_TREE;
- return 1;
- }
- }
- for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
- {
- vcc_list = tree_cons (c, current, vcc_list);
- if (verify_constructor_circularity (meth, TREE_VALUE (c)))
- return 1;
- vcc_list = TREE_CHAIN (vcc_list);
- }
- return 0;
- }
-
- /* Check modifiers that can be declared but exclusively */
-
- static void
- check_modifiers_consistency (int flags)
- {
- int acc_count = 0;
- tree cl = NULL_TREE;
-
- THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
- THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
- THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
- if (acc_count > 1)
- parse_error_context
- (cl, "Inconsistent member declaration. At most one of %<public%>, %<private%>, or %<protected%> may be specified");
-
- acc_count = 0;
- cl = NULL_TREE;
- THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
- THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
- if (acc_count > 1)
- parse_error_context (cl,
- "Inconsistent member declaration. At most one of %<final%> or %<volatile%> may be specified");
- }
-
- /* Check the methode header METH for abstract specifics features */
-
- static void
- check_abstract_method_header (tree meth)
- {
- int flags = get_access_flags_from_decl (meth);
-
- OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
- ACC_ABSTRACT, "abstract method",
- IDENTIFIER_POINTER (DECL_NAME (meth)));
- OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags,
- ACC_PUBLIC, "abstract method",
- IDENTIFIER_POINTER (DECL_NAME (meth)));
-
- check_modifiers ("Illegal modifier %qs for interface method",
- flags, INTERFACE_METHOD_MODIFIERS);
- }
-
- /* Create a FUNCTION_TYPE node and start augmenting it with the
- declared function arguments. Arguments type that can't be resolved
- are left as they are, but the returned node is marked as containing
- incomplete types. */
-
- static tree
- method_declarator (tree id, tree list)
- {
- tree arg_types = NULL_TREE, current, node;
- tree meth = make_node (FUNCTION_TYPE);
- jdep *jdep;
-
- patch_stage = JDEP_NO_PATCH;
-
- if (GET_CPC () == error_mark_node)
- return error_mark_node;
-
- /* If we're dealing with an inner class constructor, we hide the
- this$<n> decl in the name field of its parameter declaration. We
- also might have to hide the outer context local alias
- initializers. Not done when the class is a toplevel class. */
- if (PURE_INNER_CLASS_DECL_P (GET_CPC ())
- && EXPR_WFL_NODE (id) == GET_CPC_UN ())
- {
- tree aliases_list, type, thisn;
- /* First the aliases, linked to the regular parameters */
- aliases_list =
- build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION,
- TREE_TYPE (GET_CPC ()),
- NULL_TREE, NULL);
- list = chainon (nreverse (aliases_list), list);
-
- /* Then this$<n> */
- type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
- thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
- list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
- list);
- }
-
- for (current = list; current; current = TREE_CHAIN (current))
- {
- int must_chain = 0;
- tree wfl_name = TREE_PURPOSE (current);
- tree type = TREE_VALUE (current);
- tree name = EXPR_WFL_NODE (wfl_name);
- tree already, arg_node;
- tree type_wfl = NULL_TREE;
- tree real_type;
-
- /* Obtain a suitable type for resolution, if necessary */
- SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
-
- /* Process NAME, as it may specify extra dimension(s) for it */
- type = build_array_from_name (type, type_wfl, name, &name);
- EXPR_WFL_NODE (wfl_name) = name;
-
- real_type = GET_REAL_TYPE (type);
- if (TREE_CODE (real_type) == RECORD_TYPE)
- {
- real_type = promote_type (real_type);
- if (TREE_CODE (type) == TREE_LIST)
- TREE_PURPOSE (type) = real_type;
- }
-
- /* Check redefinition */
- for (already = arg_types; already; already = TREE_CHAIN (already))
- if (TREE_PURPOSE (already) == name)
- {
- parse_error_context
- (wfl_name, "Variable %qs is used more than once in the argument list of method %qs",
- IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
- break;
- }
-
- /* If we've an incomplete argument type, we know there is a location
- to patch when the type get resolved, later. */
- jdep = NULL;
- if (must_chain)
- {
- patch_stage = JDEP_METHOD;
- type = register_incomplete_type (patch_stage,
- type_wfl, wfl_name, type);
- jdep = CLASSD_LAST (ctxp->classd_list);
- JDEP_MISC (jdep) = id;
- }
-
- /* The argument node: a name and a (possibly) incomplete type. */
- arg_node = build_tree_list (name, real_type);
- /* Remember arguments declared final. */
- ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
-
- if (jdep)
- JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
- TREE_CHAIN (arg_node) = arg_types;
- arg_types = arg_node;
- }
- TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
- node = build_tree_list (id, meth);
- return node;
- }
-
- static int
- unresolved_type_p (tree wfl, tree *returned)
- {
- if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
- {
- if (returned)
- {
- tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
- if (decl && current_class && (decl == TYPE_NAME (current_class)))
- *returned = TREE_TYPE (decl);
- else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
- *returned = TREE_TYPE (GET_CPC ());
- else
- *returned = NULL_TREE;
- }
- return 1;
- }
- if (returned)
- *returned = wfl;
- return 0;
- }
-
- /* From NAME, build a qualified identifier node using the
- qualification from the current package definition. */
-
- static tree
- parser_qualified_classname (tree name)
- {
- tree nested_class_name;
-
- if ((nested_class_name = maybe_make_nested_class_name (name)))
- return nested_class_name;
-
- if (ctxp->package)
- return merge_qualified_name (ctxp->package, name);
- else
- return name;
- }
-
- /* Called once the type a interface extends is resolved. Returns 0 if
- everything is OK. */
-
- static int
- parser_check_super_interface (tree super_decl, tree this_decl, tree this_wfl)
- {
- tree super_type = TREE_TYPE (super_decl);
-
- /* Has to be an interface */
- if (!CLASS_INTERFACE (super_decl))
- {
- parse_error_context
- (this_wfl, "%s %qs can't implement/extend %s %qs",
- (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ?
- "Interface" : "Class"),
- IDENTIFIER_POINTER (DECL_NAME (this_decl)),
- (TYPE_ARRAY_P (super_type) ? "array" : "class"),
- IDENTIFIER_POINTER (DECL_NAME (super_decl)));
- return 1;
- }
-
- /* Check top-level interface access. Inner classes are subject to member
- access rules (6.6.1). */
- if (! INNER_CLASS_P (super_type)
- && check_pkg_class_access (DECL_NAME (super_decl),
- NULL_TREE, true, this_decl))
- return 1;
-
- SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
- IDENTIFIER_POINTER (DECL_NAME (this_decl)),
- IDENTIFIER_POINTER (DECL_NAME (super_decl))));
- return 0;
- }
-
- /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
- 0 if everything is OK. */
-
- static int
- parser_check_super (tree super_decl, tree this_decl, tree wfl)
- {
- tree super_type = TREE_TYPE (super_decl);
-
- /* SUPER should be a CLASS (neither an array nor an interface) */
- if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
- {
- parse_error_context
- (wfl, "Class %qs can't subclass %s %qs",
- IDENTIFIER_POINTER (DECL_NAME (this_decl)),
- (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
- IDENTIFIER_POINTER (DECL_NAME (super_decl)));
- return 1;
- }
-
- if (CLASS_FINAL (TYPE_NAME (super_type)))
- {
- parse_error_context (wfl, "Can't subclass final classes: %s",
- IDENTIFIER_POINTER (DECL_NAME (super_decl)));
- return 1;
- }
-
- /* Check top-level class scope. Inner classes are subject to member access
- rules (6.6.1). */
- if (! INNER_CLASS_P (super_type)
- && (check_pkg_class_access (DECL_NAME (super_decl), wfl, true, NULL_TREE)))
- return 1;
-
- SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
- IDENTIFIER_POINTER (DECL_NAME (this_decl)),
- IDENTIFIER_POINTER (DECL_NAME (super_decl))));
- return 0;
- }
-
- /* Create a new dependency list and link it (in a LIFO manner) to the
- CTXP list of type dependency list. */
-
- static void
- create_jdep_list (struct parser_ctxt *ctxp)
- {
- jdeplist *new = xmalloc (sizeof (jdeplist));
- new->first = new->last = NULL;
- new->next = ctxp->classd_list;
- ctxp->classd_list = new;
- }
-
- static jdeplist *
- reverse_jdep_list (struct parser_ctxt *ctxp)
- {
- jdeplist *prev = NULL, *current, *next;
- for (current = ctxp->classd_list; current; current = next)
- {
- next = current->next;
- current->next = prev;
- prev = current;
- }
- return prev;
- }
-
- /* Create a fake pointer based on the ID stored in
- TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
- registered again. */
-
- static tree
- obtain_incomplete_type (tree type_name)
- {
- tree ptr = NULL_TREE, name;
-
- if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
- name = EXPR_WFL_NODE (type_name);
- else if (INCOMPLETE_TYPE_P (type_name))
- name = TYPE_NAME (type_name);
- else
- abort ();
-
- /* Workaround from build_pointer_type for incomplete types. */
- BUILD_PTR_FROM_NAME (ptr, name);
- TYPE_MODE (ptr) = ptr_mode;
- layout_type (ptr);
-
- return ptr;
- }
-
- /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
- non NULL instead of computing a new fake type based on WFL. The new
- dependency is inserted in the current type dependency list, in FIFO
- manner. */
-
- static tree
- register_incomplete_type (int kind, tree wfl, tree decl, tree ptr)
- {
- jdep *new = xmalloc (sizeof (jdep));
-
- if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
- ptr = obtain_incomplete_type (wfl);
-
- JDEP_KIND (new) = kind;
- JDEP_DECL (new) = decl;
- JDEP_TO_RESOLVE (new) = ptr;
- JDEP_WFL (new) = wfl;
- JDEP_CHAIN (new) = NULL;
- JDEP_MISC (new) = NULL_TREE;
- /* For some dependencies, set the enclosing class of the current
- class to be the enclosing context */
- if ((kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS || kind == JDEP_SUPER)
- && GET_ENCLOSING_CPC ())
- JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
- else
- JDEP_ENCLOSING (new) = GET_CPC ();
- JDEP_GET_PATCH (new) = (tree *)NULL;
-
- JDEP_INSERT (ctxp->classd_list, new);
-
- return ptr;
- }
-
- /* This checks for circular references with innerclasses. We start
- from SOURCE and should never reach TARGET. Extended/implemented
- types in SOURCE have their enclosing context checked not to reach
- TARGET. When the last enclosing context of SOURCE is reached, its
- extended/implemented types are also checked not to reach TARGET.
- In case of error, WFL of the offending type is returned; NULL_TREE
- otherwise. */
-
- static tree
- check_inner_circular_reference (tree source, tree target)
- {
- tree base_binfo;
- tree ctx, cl;
- int i;
-
- for (i = 0; BINFO_BASE_ITERATE (TYPE_BINFO (source), i, base_binfo); i++)
- {
- tree su;
-
- /* We can end up with a NULL_TREE or an incomplete type here if
- we encountered previous type resolution errors. It's safe to
- simply ignore these cases. */
- su = BINFO_TYPE (base_binfo);
- if (INCOMPLETE_TYPE_P (su))
- continue;
-
- if (inherits_from_p (su, target))
- return lookup_cl (TYPE_NAME (su));
-
- for (ctx = DECL_CONTEXT (TYPE_NAME (su)); ctx; ctx = DECL_CONTEXT (ctx))
- {
- /* An enclosing context shouldn't be TARGET */
- if (ctx == TYPE_NAME (target))
- return lookup_cl (TYPE_NAME (su));
-
- /* When we reach the enclosing last context, start a check
- on it, with the same target */
- if (! DECL_CONTEXT (ctx) &&
- (cl = check_inner_circular_reference (TREE_TYPE (ctx), target)))
- return cl;
- }
- }
- return NULL_TREE;
- }
-
- /* Explore TYPE's `extends' clause member(s) and return the WFL of the
- offending type if a circularity is detected. NULL_TREE is returned
- otherwise. TYPE can be an interface or a class. */
-
- static tree
- check_circular_reference (tree type)
- {
- tree base_binfo;
- int i;
-
- if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
- return NULL_TREE;
-
- if (! CLASS_INTERFACE (TYPE_NAME (type)))
- {
- if (inherits_from_p (CLASSTYPE_SUPER (type), type))
- return lookup_cl (TYPE_NAME (type));
- return NULL_TREE;
- }
-
- for (i = 0; BINFO_BASE_ITERATE (TYPE_BINFO (type), i, base_binfo); i++)
- {
- if (BINFO_TYPE (base_binfo) != object_type_node
- && interface_of_p (type, BINFO_TYPE (base_binfo)))
- return lookup_cl (TYPE_NAME (BINFO_TYPE (base_binfo)));
- }
- return NULL_TREE;
- }
-
- void
- java_check_circular_reference (void)
- {
- tree current;
- for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
- {
- tree type = TREE_TYPE (current);
- tree cl;
-
- cl = check_circular_reference (type);
- if (! cl)
- cl = check_inner_circular_reference (type, type);
- if (cl)
- parse_error_context (cl, "Cyclic class inheritance%s",
- (cyclic_inheritance_report ?
- cyclic_inheritance_report : ""));
- }
- }
-
- /* Augment the parameter list PARM with parameters crafted to
- initialize outer context locals aliases. Through ARTIFICIAL, a
- count is kept of the number of crafted parameters. MODE governs
- what eventually gets created: something suitable for a function
- creation or a function invocation, either the constructor or
- finit$. */
-
- static tree
- build_alias_initializer_parameter_list (int mode, tree class_type, tree parm,
- int *artificial)
- {
- tree field;
- tree additional_parms = NULL_TREE;
-
- for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
- if (FIELD_LOCAL_ALIAS (field))
- {
- const char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
- tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
- tree mangled_id;
-
- switch (mode)
- {
- case AIPL_FUNCTION_DECLARATION:
- MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id,
- &buffer [4]);
- purpose = build_wfl_node (mangled_id);
- if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
- value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
- else
- value = TREE_TYPE (field);
- break;
-
- case AIPL_FUNCTION_CREATION:
- MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (purpose,
- &buffer [4]);
- value = TREE_TYPE (field);
- break;
-
- case AIPL_FUNCTION_FINIT_INVOCATION:
- MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id,
- &buffer [4]);
- /* Now, this is wrong. purpose should always be the NAME
- of something and value its matching value (decl, type,
- etc...) FIXME -- but there is a lot to fix. */
-
- /* When invoked for this kind of operation, we already
- know whether a field is used or not. */
- purpose = TREE_TYPE (field);
- value = build_wfl_node (mangled_id);
- break;
-
- case AIPL_FUNCTION_CTOR_INVOCATION:
- /* There are two case: the constructor invocation happens
- outside the local inner, in which case, locales from the outer
- context are directly used.
-
- Otherwise, we fold to using the alias directly. */
- if (class_type == current_class)
- value = field;
- else
- {
- name = get_identifier (&buffer[4]);
- value = IDENTIFIER_LOCAL_VALUE (name);
- }
- break;
- }
- additional_parms = tree_cons (purpose, value, additional_parms);
- if (artificial)
- *artificial +=1;
- }
- if (additional_parms)
- {
- if (ANONYMOUS_CLASS_P (class_type)
- && mode == AIPL_FUNCTION_CTOR_INVOCATION)
- additional_parms = nreverse (additional_parms);
- parm = chainon (additional_parms, parm);
- }
-
- return parm;
- }
-
- /* Craft a constructor for CLASS_DECL -- what we should do when none
- where found. ARGS is non NULL when a special signature must be
- enforced. This is the case for anonymous classes. */
-
- static tree
- craft_constructor (tree class_decl, tree args)
- {
- tree class_type = TREE_TYPE (class_decl);
- tree parm = NULL_TREE;
- /* Inherit access flags for the constructor from its enclosing class. */
- int valid_ctor_flags = ACC_PUBLIC | ACC_PROTECTED | ACC_PRIVATE;
- int flags = (get_access_flags_from_decl (class_decl) & valid_ctor_flags);
- int i = 0, artificial = 0;
- tree decl, ctor_name;
- char buffer [80];
-
- ctor_name = init_identifier_node;
-
- /* If we're dealing with an inner class constructor, we hide the
- this$<n> decl in the name field of its parameter declaration. */
- if (PURE_INNER_CLASS_TYPE_P (class_type))
- {
- tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
- parm = tree_cons (build_current_thisn (class_type),
- build_pointer_type (type), parm);
-
- /* Some more arguments to be hidden here. The values of the local
- variables of the outer context that the inner class needs to see. */
- parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
- class_type, parm,
- &artificial);
- }
-
- /* Then if there are any args to be enforced, enforce them now */
- for (; args && args != end_params_node; args = TREE_CHAIN (args))
- {
- /* If we see a `void *', we need to change it to Object. */
- if (TREE_VALUE (args) == TREE_TYPE (null_pointer_node))
- TREE_VALUE (args) = object_ptr_type_node;
-
- sprintf (buffer, "parm%d", i++);
- parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
- }
-
- CRAFTED_PARAM_LIST_FIXUP (parm);
- decl = create_artificial_method (class_type, flags, void_type_node,
- ctor_name, parm);
- fix_method_argument_names (parm, decl);
- /* Now, mark the artificial parameters. */
- DECL_FUNCTION_NAP (decl) = artificial;
- DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
- DECL_INLINE (decl) = 1;
- return decl;
- }
-
-
- /* Fix the constructors. This will be called right after circular
- references have been checked. It is necessary to fix constructors
- early even if no code generation will take place for that class:
- some generated constructor might be required by the class whose
- compilation triggered this one to be simply loaded. */
-
- void
- java_fix_constructors (void)
- {
- tree current;
-
- for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
- {
- tree class_type = TREE_TYPE (current);
- int saw_ctor = 0;
- tree decl;
-
- if (CLASS_INTERFACE (TYPE_NAME (class_type)))
- continue;
-
- output_class = current_class = class_type;
- for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
- {
- if (DECL_CONSTRUCTOR_P (decl))
- {
- fix_constructors (decl);
- saw_ctor = 1;
- }
- }
-
- /* Anonymous class constructor can't be generated that early. */
- if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
- craft_constructor (current, NULL_TREE);
- }
- }
-
- /* safe_layout_class just makes sure that we can load a class without
- disrupting the current_class, input_file, input_line, etc, information
- about the class processed currently. */
-
- void
- safe_layout_class (tree class)
- {
- tree save_current_class = current_class;
- location_t save_location = input_location;
-
- layout_class (class);
-
- current_class = save_current_class;
- input_location = save_location;
- }
-
- static tree
- jdep_resolve_class (jdep *dep)
- {
- tree decl;
-
- if (JDEP_RESOLVED_P (dep))
- decl = JDEP_RESOLVED_DECL (dep);
- else
- {
- decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
- JDEP_DECL (dep), JDEP_WFL (dep));
- JDEP_RESOLVED (dep, decl);
- /* If there is no WFL, that's ok. We generate this warning
- elsewhere. */
- if (decl && JDEP_WFL (dep) != NULL_TREE)
- check_deprecation (JDEP_WFL (dep), decl);
- }
-
- if (!decl)
- complete_class_report_errors (dep);
- else if (INNER_CLASS_DECL_P (decl))
- {
- tree inner = TREE_TYPE (decl);
- if (! CLASS_LOADED_P (inner))
- {
- safe_layout_class (inner);
- if (TYPE_SIZE (inner) == error_mark_node)
- TYPE_SIZE (inner) = NULL_TREE;
- }
- check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
- }
- return decl;
- }
-
- /* Complete