2000-04-25 Alexandre Petit-Bianco <apbianco@cygnus.com>
[official-gcc.git] / gcc / java / parse.y
blob0b14bcae7aa98218413b818f80e03ac154b18301
1 /* Source code parsing and tree node generation for the GNU compiler
2 for the Java(TM) language.
3 Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
4 Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc. */
27 /* This file parses java source code and issues a tree node image
28 suitable for code generation (byte code and targeted CPU assembly
29 language).
31 The grammar conforms to the Java grammar described in "The Java(TM)
32 Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
33 1996, ISBN 0-201-63451-1"
35 The following modifications were brought to the original grammar:
37 method_body: added the rule '| block SC_TK'
38 static_initializer: added the rule 'static block SC_TK'.
40 Note: All the extra rules described above should go away when the
41 empty_statement rule will work.
43 statement_nsi: 'nsi' should be read no_short_if.
45 Some rules have been modified to support JDK1.1 inner classes
46 definitions and other extensions. */
49 #include "config.h"
50 #include "system.h"
51 #include <dirent.h>
52 #include "tree.h"
53 #include "rtl.h"
54 #include "obstack.h"
55 #include "toplev.h"
56 #include "flags.h"
57 #include "java-tree.h"
58 #include "jcf.h"
59 #include "lex.h"
60 #include "parse.h"
61 #include "zipfile.h"
62 #include "convert.h"
63 #include "buffer.h"
64 #include "xref.h"
65 #include "function.h"
66 #include "except.h"
67 #include "defaults.h"
69 #ifndef DIR_SEPARATOR
70 #define DIR_SEPARATOR '/'
71 #endif
73 /* Local function prototypes */
74 static char *java_accstring_lookup PARAMS ((int));
75 static void classitf_redefinition_error PARAMS ((const char *,tree, tree, tree));
76 static void variable_redefinition_error PARAMS ((tree, tree, tree, int));
77 static tree create_class PARAMS ((int, tree, tree, tree));
78 static tree create_interface PARAMS ((int, tree, tree));
79 static void end_class_declaration PARAMS ((int));
80 static tree find_field PARAMS ((tree, tree));
81 static tree lookup_field_wrapper PARAMS ((tree, tree));
82 static int duplicate_declaration_error_p PARAMS ((tree, tree, tree));
83 static void register_fields PARAMS ((int, tree, tree));
84 static tree parser_qualified_classname PARAMS ((int, tree));
85 static int parser_check_super PARAMS ((tree, tree, tree));
86 static int parser_check_super_interface PARAMS ((tree, tree, tree));
87 static void check_modifiers_consistency PARAMS ((int));
88 static tree lookup_cl PARAMS ((tree));
89 static tree lookup_java_method2 PARAMS ((tree, tree, int));
90 static tree method_header PARAMS ((int, tree, tree, tree));
91 static void fix_method_argument_names PARAMS ((tree ,tree));
92 static tree method_declarator PARAMS ((tree, tree));
93 static void parse_warning_context PARAMS ((tree cl, const char *msg, ...))
94 ATTRIBUTE_PRINTF_2;
95 static void issue_warning_error_from_context PARAMS ((tree, const char *msg, va_list));
96 static void parse_ctor_invocation_error PARAMS ((void));
97 static tree parse_jdk1_1_error PARAMS ((const char *));
98 static void complete_class_report_errors PARAMS ((jdep *));
99 static int process_imports PARAMS ((void));
100 static void read_import_dir PARAMS ((tree));
101 static int find_in_imports_on_demand PARAMS ((tree));
102 static int find_in_imports PARAMS ((tree));
103 static int check_pkg_class_access PARAMS ((tree, tree));
104 static tree resolve_package PARAMS ((tree, tree *));
105 static tree lookup_package_type PARAMS ((const char *, int));
106 static tree lookup_package_type_and_set_next PARAMS ((const char *, int, tree *));
107 static tree resolve_class PARAMS ((tree, tree, tree, tree));
108 static void declare_local_variables PARAMS ((int, tree, tree));
109 static void source_start_java_method PARAMS ((tree));
110 static void source_end_java_method PARAMS ((void));
111 static void expand_start_java_method PARAMS ((tree));
112 static tree find_name_in_single_imports PARAMS ((tree));
113 static void check_abstract_method_header PARAMS ((tree));
114 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
115 static tree resolve_expression_name PARAMS ((tree, tree *));
116 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
117 static int check_class_interface_creation PARAMS ((int, int, tree,
118 tree, tree, tree));
119 static tree patch_method_invocation PARAMS ((tree, tree, tree,
120 int *, tree *));
121 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
122 static tree resolve_and_layout PARAMS ((tree, tree));
123 static tree resolve_no_layout PARAMS ((tree, tree));
124 static int invocation_mode PARAMS ((tree, int));
125 static tree find_applicable_accessible_methods_list PARAMS ((int, tree,
126 tree, tree));
127 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree,
128 tree *, tree *));
129 static tree find_most_specific_methods_list PARAMS ((tree));
130 static int argument_types_convertible PARAMS ((tree, tree));
131 static tree patch_invoke PARAMS ((tree, tree, tree));
132 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
133 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
134 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
135 static tree obtain_incomplete_type PARAMS ((tree));
136 static tree java_complete_lhs PARAMS ((tree));
137 static tree java_complete_tree PARAMS ((tree));
138 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
139 static void java_complete_expand_method PARAMS ((tree));
140 static int unresolved_type_p PARAMS ((tree, tree *));
141 static void create_jdep_list PARAMS ((struct parser_ctxt *));
142 static tree build_expr_block PARAMS ((tree, tree));
143 static tree enter_block PARAMS ((void));
144 static tree enter_a_block PARAMS ((tree));
145 static tree exit_block PARAMS ((void));
146 static tree lookup_name_in_blocks PARAMS ((tree));
147 static void maybe_absorb_scoping_blocks PARAMS ((void));
148 static tree build_method_invocation PARAMS ((tree, tree));
149 static tree build_new_invocation PARAMS ((tree, tree));
150 static tree build_assignment PARAMS ((int, int, tree, tree));
151 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
152 static int check_final_assignment PARAMS ((tree ,tree));
153 static tree patch_assignment PARAMS ((tree, tree, tree ));
154 static tree patch_binop PARAMS ((tree, tree, tree));
155 static tree build_unaryop PARAMS ((int, int, tree));
156 static tree build_incdec PARAMS ((int, int, tree, int));
157 static tree patch_unaryop PARAMS ((tree, tree));
158 static tree build_cast PARAMS ((int, tree, tree));
159 static tree build_null_of_type PARAMS ((tree));
160 static tree patch_cast PARAMS ((tree, tree));
161 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
162 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
163 static int valid_cast_to_p PARAMS ((tree, tree));
164 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
165 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
166 static tree try_reference_assignconv PARAMS ((tree, tree));
167 static tree build_unresolved_array_type PARAMS ((tree));
168 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
169 static tree build_array_ref PARAMS ((int, tree, tree));
170 static tree patch_array_ref PARAMS ((tree));
171 static tree make_qualified_name PARAMS ((tree, tree, int));
172 static tree merge_qualified_name PARAMS ((tree, tree));
173 static tree make_qualified_primary PARAMS ((tree, tree, int));
174 static int resolve_qualified_expression_name PARAMS ((tree, tree *,
175 tree *, tree *));
176 static void qualify_ambiguous_name PARAMS ((tree));
177 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
178 static tree build_newarray_node PARAMS ((tree, tree, int));
179 static tree patch_newarray PARAMS ((tree));
180 static tree resolve_type_during_patch PARAMS ((tree));
181 static tree build_this PARAMS ((int));
182 static tree build_wfl_wrap PARAMS ((tree));
183 static tree build_return PARAMS ((int, tree));
184 static tree patch_return PARAMS ((tree));
185 static tree maybe_access_field PARAMS ((tree, tree, tree));
186 static int complete_function_arguments PARAMS ((tree));
187 static int check_for_static_method_reference PARAMS ((tree, tree, tree,
188 tree, tree));
189 static int not_accessible_p PARAMS ((tree, tree, int));
190 static void check_deprecation PARAMS ((tree, tree));
191 static int class_in_current_package PARAMS ((tree));
192 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
193 static tree patch_if_else_statement PARAMS ((tree));
194 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
195 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
196 static tree patch_exit_expr PARAMS ((tree));
197 static tree build_labeled_block PARAMS ((int, tree));
198 static tree finish_labeled_statement PARAMS ((tree, tree));
199 static tree build_bc_statement PARAMS ((int, int, tree));
200 static tree patch_bc_statement PARAMS ((tree));
201 static tree patch_loop_statement PARAMS ((tree));
202 static tree build_new_loop PARAMS ((tree));
203 static tree build_loop_body PARAMS ((int, tree, int));
204 static tree finish_loop_body PARAMS ((int, tree, tree, int));
205 static tree build_debugable_stmt PARAMS ((int, tree));
206 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
207 static tree patch_switch_statement PARAMS ((tree));
208 static tree string_constant_concatenation PARAMS ((tree, tree));
209 static tree build_string_concatenation PARAMS ((tree, tree));
210 static tree patch_string_cst PARAMS ((tree));
211 static tree patch_string PARAMS ((tree));
212 static tree build_try_statement PARAMS ((int, tree, tree));
213 static tree build_try_finally_statement PARAMS ((int, tree, tree));
214 static tree patch_try_statement PARAMS ((tree));
215 static tree patch_synchronized_statement PARAMS ((tree, tree));
216 static tree patch_throw_statement PARAMS ((tree, tree));
217 static void check_thrown_exceptions PARAMS ((int, tree));
218 static int check_thrown_exceptions_do PARAMS ((tree));
219 static void purge_unchecked_exceptions PARAMS ((tree));
220 static void check_throws_clauses PARAMS ((tree, tree, tree));
221 static void finish_method_declaration PARAMS ((tree));
222 static tree build_super_invocation PARAMS ((tree));
223 static int verify_constructor_circularity PARAMS ((tree, tree));
224 static char *constructor_circularity_msg PARAMS ((tree, tree));
225 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
226 int, int));
227 static const char *get_printable_method_name PARAMS ((tree));
228 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
229 static tree generate_finit PARAMS ((tree));
230 static void add_instance_initializer PARAMS ((tree));
231 static void fix_constructors PARAMS ((tree));
232 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
233 tree, int *));
234 static void craft_constructor PARAMS ((tree, tree));
235 static int verify_constructor_super PARAMS ((tree));
236 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
237 static void start_artificial_method_body PARAMS ((tree));
238 static void end_artificial_method_body PARAMS ((tree));
239 static int check_method_redefinition PARAMS ((tree, tree));
240 static int reset_method_name PARAMS ((tree));
241 static int check_method_types_complete PARAMS ((tree));
242 static void java_check_regular_methods PARAMS ((tree));
243 static void java_check_abstract_methods PARAMS ((tree));
244 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
245 static void unreachable_stmt_error PARAMS ((tree));
246 static tree find_expr_with_wfl PARAMS ((tree));
247 static void missing_return_error PARAMS ((tree));
248 static tree build_new_array_init PARAMS ((int, tree));
249 static tree patch_new_array_init PARAMS ((tree, tree));
250 static tree maybe_build_array_element_wfl PARAMS ((tree));
251 static int array_constructor_check_entry PARAMS ((tree, tree));
252 static const char *purify_type_name PARAMS ((const char *));
253 static tree fold_constant_for_init PARAMS ((tree, tree));
254 static tree strip_out_static_field_access_decl PARAMS ((tree));
255 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
256 static void static_ref_err PARAMS ((tree, tree, tree));
257 static void parser_add_interface PARAMS ((tree, tree, tree));
258 static void add_superinterfaces PARAMS ((tree, tree));
259 static tree jdep_resolve_class PARAMS ((jdep *));
260 static int note_possible_classname PARAMS ((const char *, int));
261 static void java_complete_expand_classes PARAMS ((void));
262 static void java_complete_expand_class PARAMS ((tree));
263 static void java_complete_expand_methods PARAMS ((tree));
264 static tree cut_identifier_in_qualified PARAMS ((tree));
265 static tree java_stabilize_reference PARAMS ((tree));
266 static tree do_unary_numeric_promotion PARAMS ((tree));
267 static char * operator_string PARAMS ((tree));
268 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
269 static tree merge_string_cste PARAMS ((tree, tree, int));
270 static tree java_refold PARAMS ((tree));
271 static int java_decl_equiv PARAMS ((tree, tree));
272 static int binop_compound_p PARAMS ((enum tree_code));
273 static tree search_loop PARAMS ((tree));
274 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
275 static void check_abstract_method_definitions PARAMS ((int, tree, tree));
276 static void java_check_abstract_method_definitions PARAMS ((tree));
277 static void java_debug_context_do PARAMS ((int));
278 static void java_parser_context_push_initialized_field PARAMS ((void));
279 static void java_parser_context_pop_initialized_field PARAMS ((void));
280 static tree reorder_static_initialized PARAMS ((tree));
281 static void java_parser_context_suspend PARAMS ((void));
282 static void java_parser_context_resume PARAMS ((void));
284 /* JDK 1.1 work. FIXME */
286 static tree maybe_make_nested_class_name PARAMS ((tree));
287 static void make_nested_class_name PARAMS ((tree));
288 static void set_nested_class_simple_name_value PARAMS ((tree, int));
289 static void link_nested_class_to_enclosing PARAMS ((void));
290 static tree find_as_inner_class PARAMS ((tree, tree, tree));
291 static tree find_as_inner_class_do PARAMS ((tree, tree));
292 static int check_inner_class_redefinition PARAMS ((tree, tree));
294 static tree build_thisn_assign PARAMS ((void));
295 static tree build_current_thisn PARAMS ((tree));
296 static tree build_access_to_thisn PARAMS ((tree, tree, int));
297 static tree maybe_build_thisn_access_method PARAMS ((tree));
299 static tree build_outer_field_access PARAMS ((tree, tree));
300 static tree build_outer_field_access_methods PARAMS ((tree));
301 static tree build_outer_field_access_expr PARAMS ((int, tree, tree,
302 tree, tree));
303 static tree build_outer_method_access_method PARAMS ((tree));
304 static tree build_new_access_id PARAMS ((void));
305 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
306 tree, tree));
308 static int outer_field_access_p PARAMS ((tree, tree));
309 static int outer_field_expanded_access_p PARAMS ((tree, tree *,
310 tree *, tree *));
311 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
312 static tree build_incomplete_class_ref PARAMS ((int, tree));
313 static tree patch_incomplete_class_ref PARAMS ((tree));
314 static tree create_anonymous_class PARAMS ((int, tree));
315 static void patch_anonymous_class PARAMS ((tree, tree, tree));
316 static void add_inner_class_fields PARAMS ((tree, tree));
318 static tree build_dot_class_method PARAMS ((tree));
319 static tree build_dot_class_method_invocation PARAMS ((tree));
320 static void create_new_parser_context PARAMS ((int));
322 /* Number of error found so far. */
323 int java_error_count;
324 /* Number of warning found so far. */
325 int java_warning_count;
326 /* Tell when not to fold, when doing xrefs */
327 int do_not_fold;
328 /* Cyclic inheritance report, as it can be set by layout_class */
329 char *cyclic_inheritance_report;
331 /* Tell when we're within an instance initializer */
332 static int in_instance_initializer;
334 /* The current parser context */
335 struct parser_ctxt *ctxp;
337 /* List of things that were analyzed for which code will be generated */
338 static struct parser_ctxt *ctxp_for_generation = NULL;
340 /* binop_lookup maps token to tree_code. It is used where binary
341 operations are involved and required by the parser. RDIV_EXPR
342 covers both integral/floating point division. The code is changed
343 once the type of both operator is worked out. */
345 static enum tree_code binop_lookup[19] =
347 PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
348 LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR,
349 BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
350 TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
351 EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
353 #define BINOP_LOOKUP(VALUE) \
354 binop_lookup [((VALUE) - PLUS_TK)% \
355 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
357 /* This is the end index for binary operators that can also be used
358 in compound assignements. */
359 #define BINOP_COMPOUND_CANDIDATES 11
361 /* Fake WFL used to report error message. It is initialized once if
362 needed and reused with it's location information is overriden. */
363 tree wfl_operator = NULL_TREE;
365 /* The "$L" identifier we use to create labels. */
366 static tree label_id = NULL_TREE;
368 /* The "StringBuffer" identifier used for the String `+' operator. */
369 static tree wfl_string_buffer = NULL_TREE;
371 /* The "append" identifier used for String `+' operator. */
372 static tree wfl_append = NULL_TREE;
374 /* The "toString" identifier used for String `+' operator. */
375 static tree wfl_to_string = NULL_TREE;
377 /* The "java.lang" import qualified name. */
378 static tree java_lang_id = NULL_TREE;
380 /* The generated `inst$' identifier used for generated enclosing
381 instance/field access functions. */
382 static tree inst_id = NULL_TREE;
384 /* The "java.lang.Cloneable" qualified name. */
385 static tree java_lang_cloneable = NULL_TREE;
387 /* Context and flag for static blocks */
388 static tree current_static_block = NULL_TREE;
390 /* The generated `write_parm_value$' identifier. */
391 static tree wpv_id;
393 /* The list of all packages we've seen so far */
394 static tree package_list = NULL_TREE;
396 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
397 line and point it out. */
398 /* Should point out the one that don't fit. ASCII/unicode, going
399 backward. FIXME */
401 #define check_modifiers(__message, __value, __mask) do { \
402 if ((__value) & ~(__mask)) \
404 int i, remainder = (__value) & ~(__mask); \
405 for (i = 0; i <= 10; i++) \
406 if ((1 << i) & remainder) \
407 parse_error_context (ctxp->modifier_ctx [i], (__message), \
408 java_accstring_lookup (1 << i)); \
410 } while (0)
414 %union {
415 tree node;
416 int sub_token;
417 struct {
418 int token;
419 int location;
420 } operator;
421 int value;
425 #include "lex.c"
428 %pure_parser
430 /* Things defined here have to match the order of what's in the
431 binop_lookup table. */
433 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
434 %token LS_TK SRS_TK ZRS_TK
435 %token AND_TK XOR_TK OR_TK
436 %token BOOL_AND_TK BOOL_OR_TK
437 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
439 /* This maps to the same binop_lookup entry than the token above */
441 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
442 %token REM_ASSIGN_TK
443 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
444 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
447 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
449 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
450 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
451 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
452 %token PAD_TK ABSTRACT_TK MODIFIER_TK
454 /* Keep those two in order, too */
455 %token DECR_TK INCR_TK
457 /* From now one, things can be in any order */
459 %token DEFAULT_TK IF_TK THROW_TK
460 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
461 %token THROWS_TK BREAK_TK IMPORT_TK
462 %token ELSE_TK INSTANCEOF_TK RETURN_TK
463 %token VOID_TK CATCH_TK INTERFACE_TK
464 %token CASE_TK EXTENDS_TK FINALLY_TK
465 %token SUPER_TK WHILE_TK CLASS_TK
466 %token SWITCH_TK CONST_TK TRY_TK
467 %token FOR_TK NEW_TK CONTINUE_TK
468 %token GOTO_TK PACKAGE_TK THIS_TK
470 %token BYTE_TK SHORT_TK INT_TK LONG_TK
471 %token CHAR_TK INTEGRAL_TK
473 %token FLOAT_TK DOUBLE_TK FP_TK
475 %token ID_TK
477 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
479 %token ASSIGN_ANY_TK ASSIGN_TK
480 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
482 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
483 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
485 %type <value> modifiers MODIFIER_TK final synchronized
487 %type <node> super ID_TK identifier
488 %type <node> name simple_name qualified_name
489 %type <node> type_declaration compilation_unit
490 field_declaration method_declaration extends_interfaces
491 interfaces interface_type_list
492 class_member_declaration
493 import_declarations package_declaration
494 type_declarations interface_body
495 interface_member_declaration constant_declaration
496 interface_member_declarations interface_type
497 abstract_method_declaration interface_type_list
498 %type <node> class_body_declaration class_member_declaration
499 static_initializer constructor_declaration block
500 %type <node> class_body_declarations constructor_header
501 %type <node> class_or_interface_type class_type class_type_list
502 constructor_declarator explicit_constructor_invocation
503 %type <node> dim_expr dim_exprs this_or_super throws
505 %type <node> variable_declarator_id variable_declarator
506 variable_declarators variable_initializer
507 variable_initializers constructor_body
508 array_initializer
510 %type <node> class_body block_end constructor_block_end
511 %type <node> statement statement_without_trailing_substatement
512 labeled_statement if_then_statement label_decl
513 if_then_else_statement while_statement for_statement
514 statement_nsi labeled_statement_nsi do_statement
515 if_then_else_statement_nsi while_statement_nsi
516 for_statement_nsi statement_expression_list for_init
517 for_update statement_expression expression_statement
518 primary_no_new_array expression primary
519 array_creation_expression array_type
520 class_instance_creation_expression field_access
521 method_invocation array_access something_dot_new
522 argument_list postfix_expression while_expression
523 post_increment_expression post_decrement_expression
524 unary_expression_not_plus_minus unary_expression
525 pre_increment_expression pre_decrement_expression
526 unary_expression_not_plus_minus cast_expression
527 multiplicative_expression additive_expression
528 shift_expression relational_expression
529 equality_expression and_expression
530 exclusive_or_expression inclusive_or_expression
531 conditional_and_expression conditional_or_expression
532 conditional_expression assignment_expression
533 left_hand_side assignment for_header for_begin
534 constant_expression do_statement_begin empty_statement
535 switch_statement synchronized_statement throw_statement
536 try_statement switch_expression switch_block
537 catches catch_clause catch_clause_parameter finally
538 anonymous_class_creation
539 %type <node> return_statement break_statement continue_statement
541 %type <operator> ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
542 %type <operator> REM_ASSIGN_TK PLUS_ASSIGN_TK MINUS_ASSIGN_TK
543 %type <operator> LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
544 %type <operator> AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
545 %type <operator> ASSIGN_ANY_TK assignment_operator
546 %token <operator> EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK
547 %token <operator> BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
548 %token <operator> DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
549 %token <operator> NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
550 %token <operator> OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
551 %type <operator> THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK
552 %type <operator> CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
553 %type <operator> NEW_TK
555 %type <node> method_body
557 %type <node> literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
558 STRING_LIT_TK NULL_TK VOID_TK
560 %type <node> IF_TK WHILE_TK FOR_TK
562 %type <node> formal_parameter_list formal_parameter
563 method_declarator method_header
565 %type <node> primitive_type reference_type type
566 BOOLEAN_TK INTEGRAL_TK FP_TK
568 /* Added or modified JDK 1.1 rule types */
569 %type <node> type_literals array_type_literal
572 /* 19.2 Production from 2.3: The Syntactic Grammar */
573 goal:
574 compilation_unit
578 /* 19.3 Productions from 3: Lexical structure */
579 literal:
580 INT_LIT_TK
581 | FP_LIT_TK
582 | BOOL_LIT_TK
583 | CHAR_LIT_TK
584 | STRING_LIT_TK
585 | NULL_TK
588 /* 19.4 Productions from 4: Types, Values and Variables */
589 type:
590 primitive_type
591 | reference_type
594 primitive_type:
595 INTEGRAL_TK
596 | FP_TK
597 | BOOLEAN_TK
600 reference_type:
601 class_or_interface_type
602 | array_type
605 class_or_interface_type:
606 name
609 class_type:
610 class_or_interface_type /* Default rule */
613 interface_type:
614 class_or_interface_type
617 array_type:
618 primitive_type OSB_TK CSB_TK
620 $$ = build_java_array_type ($1, -1);
621 CLASS_LOADED_P ($$) = 1;
623 | name OSB_TK CSB_TK
624 { $$ = build_unresolved_array_type ($1); }
625 | array_type OSB_TK CSB_TK
626 { $$ = build_unresolved_array_type ($1); }
627 | primitive_type OSB_TK error
628 {RULE ("']' expected"); RECOVER;}
629 | array_type OSB_TK error
630 {RULE ("']' expected"); RECOVER;}
633 /* 19.5 Productions from 6: Names */
634 name:
635 simple_name /* Default rule */
636 | qualified_name /* Default rule */
639 simple_name:
640 identifier /* Default rule */
643 qualified_name:
644 name DOT_TK identifier
645 { $$ = make_qualified_name ($1, $3, $2.location); }
648 identifier:
649 ID_TK
652 /* 19.6: Production from 7: Packages */
653 compilation_unit:
654 {$$ = NULL;}
655 | package_declaration
656 | import_declarations
657 | type_declarations
658 | package_declaration import_declarations
659 | package_declaration type_declarations
660 | import_declarations type_declarations
661 | package_declaration import_declarations type_declarations
664 import_declarations:
665 import_declaration
667 $$ = NULL;
669 | import_declarations import_declaration
671 $$ = NULL;
675 type_declarations:
676 type_declaration
677 | type_declarations type_declaration
680 package_declaration:
681 PACKAGE_TK name SC_TK
683 ctxp->package = EXPR_WFL_NODE ($2);
684 package_list = tree_cons (ctxp->package, NULL, package_list);
686 | PACKAGE_TK error
687 {yyerror ("Missing name"); RECOVER;}
688 | PACKAGE_TK name error
689 {yyerror ("';' expected"); RECOVER;}
692 import_declaration:
693 single_type_import_declaration
694 | type_import_on_demand_declaration
697 single_type_import_declaration:
698 IMPORT_TK name SC_TK
700 tree name = EXPR_WFL_NODE ($2), node, last_name;
701 int i = IDENTIFIER_LENGTH (name)-1;
702 const char *last = &IDENTIFIER_POINTER (name)[i];
703 while (last != IDENTIFIER_POINTER (name))
705 if (last [0] == '.')
706 break;
707 last--;
709 last_name = get_identifier (++last);
710 if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
712 tree err = find_name_in_single_imports (last_name);
713 if (err && err != name)
714 parse_error_context
715 ($2, "Ambiguous class: `%s' and `%s'",
716 IDENTIFIER_POINTER (name),
717 IDENTIFIER_POINTER (err));
718 else
719 REGISTER_IMPORT ($2, last_name)
721 else
722 REGISTER_IMPORT ($2, last_name);
724 | IMPORT_TK error
725 {yyerror ("Missing name"); RECOVER;}
726 | IMPORT_TK name error
727 {yyerror ("';' expected"); RECOVER;}
730 type_import_on_demand_declaration:
731 IMPORT_TK name DOT_TK MULT_TK SC_TK
733 tree name = EXPR_WFL_NODE ($2);
734 /* Don't import java.lang.* twice. */
735 if (name != java_lang_id)
737 tree node = build_tree_list ($2, NULL_TREE);
738 read_import_dir ($2);
739 TREE_CHAIN (node) = ctxp->import_demand_list;
740 ctxp->import_demand_list = node;
743 | IMPORT_TK name DOT_TK error
744 {yyerror ("'*' expected"); RECOVER;}
745 | IMPORT_TK name DOT_TK MULT_TK error
746 {yyerror ("';' expected"); RECOVER;}
749 type_declaration:
750 class_declaration
751 { end_class_declaration (0); }
752 | interface_declaration
753 { end_class_declaration (0); }
754 | SC_TK
755 { $$ = NULL; }
756 | error
758 YYERROR_NOW;
759 yyerror ("Class or interface declaration expected");
763 /* 19.7 Shortened from the original:
764 modifiers: modifier | modifiers modifier
765 modifier: any of public... */
766 modifiers:
767 MODIFIER_TK
769 $$ = (1 << $1);
771 | modifiers MODIFIER_TK
773 int acc = (1 << $2);
774 if ($$ & acc)
775 parse_error_context
776 (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
777 java_accstring_lookup (acc));
778 else
780 $$ |= acc;
785 /* 19.8.1 Production from $8.1: Class Declaration */
786 class_declaration:
787 modifiers CLASS_TK identifier super interfaces
788 { create_class ($1, $3, $4, $5); }
789 class_body
790 | CLASS_TK identifier super interfaces
791 { create_class (0, $2, $3, $4); }
792 class_body
793 | modifiers CLASS_TK error
794 {yyerror ("Missing class name"); RECOVER;}
795 | CLASS_TK error
796 {yyerror ("Missing class name"); RECOVER;}
797 | CLASS_TK identifier error
799 if (!ctxp->class_err) yyerror ("'{' expected");
800 DRECOVER(class1);
802 | modifiers CLASS_TK identifier error
803 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
806 super:
807 { $$ = NULL; }
808 | EXTENDS_TK class_type
809 { $$ = $2; }
810 | EXTENDS_TK class_type error
811 {yyerror ("'{' expected"); ctxp->class_err=1;}
812 | EXTENDS_TK error
813 {yyerror ("Missing super class name"); ctxp->class_err=1;}
816 interfaces:
817 { $$ = NULL_TREE; }
818 | IMPLEMENTS_TK interface_type_list
819 { $$ = $2; }
820 | IMPLEMENTS_TK error
822 ctxp->class_err=1;
823 yyerror ("Missing interface name");
827 interface_type_list:
828 interface_type
830 ctxp->interface_number = 1;
831 $$ = build_tree_list ($1, NULL_TREE);
833 | interface_type_list C_TK interface_type
835 ctxp->interface_number++;
836 $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
838 | interface_type_list C_TK error
839 {yyerror ("Missing interface name"); RECOVER;}
842 class_body:
843 OCB_TK CCB_TK
845 /* Store the location of the `}' when doing xrefs */
846 if (flag_emit_xref)
847 DECL_END_SOURCE_LINE (GET_CPC ()) =
848 EXPR_WFL_ADD_COL ($2.location, 1);
849 $$ = GET_CPC ();
851 | OCB_TK class_body_declarations CCB_TK
853 /* Store the location of the `}' when doing xrefs */
854 if (flag_emit_xref)
855 DECL_END_SOURCE_LINE (GET_CPC ()) =
856 EXPR_WFL_ADD_COL ($3.location, 1);
857 $$ = GET_CPC ();
861 class_body_declarations:
862 class_body_declaration
863 | class_body_declarations class_body_declaration
866 class_body_declaration:
867 class_member_declaration
868 | static_initializer
869 | constructor_declaration
870 | block /* Added, JDK1.1, instance initializer */
872 TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
873 SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
877 class_member_declaration:
878 field_declaration
879 | field_declaration SC_TK
880 { $$ = $1; }
881 | method_declaration
882 | class_declaration /* Added, JDK1.1 inner classes */
883 { end_class_declaration (1); }
884 | interface_declaration /* Added, JDK1.1 inner interfaces */
885 { end_class_declaration (1); }
888 /* 19.8.2 Productions from 8.3: Field Declarations */
889 field_declaration:
890 type variable_declarators SC_TK
891 { register_fields (0, $1, $2); }
892 | modifiers type variable_declarators SC_TK
894 check_modifiers
895 ("Illegal modifier `%s' for field declaration",
896 $1, FIELD_MODIFIERS);
897 check_modifiers_consistency ($1);
898 register_fields ($1, $2, $3);
902 variable_declarators:
903 /* Should we use build_decl_list () instead ? FIXME */
904 variable_declarator /* Default rule */
905 | variable_declarators C_TK variable_declarator
906 { $$ = chainon ($1, $3); }
907 | variable_declarators C_TK error
908 {yyerror ("Missing term"); RECOVER;}
911 variable_declarator:
912 variable_declarator_id
913 { $$ = build_tree_list ($1, NULL_TREE); }
914 | variable_declarator_id ASSIGN_TK variable_initializer
916 if (java_error_count)
917 $3 = NULL_TREE;
918 $$ = build_tree_list
919 ($1, build_assignment ($2.token, $2.location, $1, $3));
921 | variable_declarator_id ASSIGN_TK error
923 yyerror ("Missing variable initializer");
924 $$ = build_tree_list ($1, NULL_TREE);
925 RECOVER;
927 | variable_declarator_id ASSIGN_TK variable_initializer error
929 yyerror ("';' expected");
930 $$ = build_tree_list ($1, NULL_TREE);
931 RECOVER;
935 variable_declarator_id:
936 identifier
937 | variable_declarator_id OSB_TK CSB_TK
938 { $$ = build_unresolved_array_type ($1); }
939 | identifier error
940 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
941 | variable_declarator_id OSB_TK error
942 {yyerror ("']' expected"); DRECOVER(vdi);}
943 | variable_declarator_id CSB_TK error
944 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
947 variable_initializer:
948 expression
949 | array_initializer
952 /* 19.8.3 Productions from 8.4: Method Declarations */
953 method_declaration:
954 method_header
956 current_function_decl = $1;
957 if (current_function_decl
958 && TREE_CODE (current_function_decl) == FUNCTION_DECL)
959 source_start_java_method (current_function_decl);
960 else
961 current_function_decl = NULL_TREE;
963 method_body
964 { finish_method_declaration ($3); }
965 | method_header error
966 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
969 method_header:
970 type method_declarator throws
971 { $$ = method_header (0, $1, $2, $3); }
972 | VOID_TK method_declarator throws
973 { $$ = method_header (0, void_type_node, $2, $3); }
974 | modifiers type method_declarator throws
975 { $$ = method_header ($1, $2, $3, $4); }
976 | modifiers VOID_TK method_declarator throws
977 { $$ = method_header ($1, void_type_node, $3, $4); }
978 | type error
980 yyerror ("Invalid method declaration, method name required");
981 RECOVER;
983 | modifiers type error
984 {RECOVER;}
985 | VOID_TK error
986 {yyerror ("Identifier expected"); RECOVER;}
987 | modifiers VOID_TK error
988 {yyerror ("Identifier expected"); RECOVER;}
989 | modifiers error
991 yyerror ("Invalid method declaration, return type required");
992 RECOVER;
996 method_declarator:
997 identifier OP_TK CP_TK
999 ctxp->formal_parameter_number = 0;
1000 $$ = method_declarator ($1, NULL_TREE);
1002 | identifier OP_TK formal_parameter_list CP_TK
1003 { $$ = method_declarator ($1, $3); }
1004 | method_declarator OSB_TK CSB_TK
1006 EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1007 TREE_PURPOSE ($1) =
1008 build_unresolved_array_type (TREE_PURPOSE ($1));
1009 parse_warning_context
1010 (wfl_operator,
1011 "Discouraged form of returned type specification");
1013 | identifier OP_TK error
1014 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1015 | method_declarator OSB_TK error
1016 {yyerror ("']' expected"); RECOVER;}
1019 formal_parameter_list:
1020 formal_parameter
1022 ctxp->formal_parameter_number = 1;
1024 | formal_parameter_list C_TK formal_parameter
1026 ctxp->formal_parameter_number += 1;
1027 $$ = chainon ($1, $3);
1029 | formal_parameter_list C_TK error
1030 { yyerror ("Missing formal parameter term"); RECOVER; }
1033 formal_parameter:
1034 type variable_declarator_id
1036 $$ = build_tree_list ($2, $1);
1038 | final type variable_declarator_id /* Added, JDK1.1 final parms */
1040 $$ = build_tree_list ($3, $2);
1041 ARG_FINAL_P ($$) = 1;
1043 | type error
1045 yyerror ("Missing identifier"); RECOVER;
1046 $$ = NULL_TREE;
1048 | final type error
1050 yyerror ("Missing identifier"); RECOVER;
1051 $$ = NULL_TREE;
1055 final:
1056 modifiers
1058 check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1059 $1, ACC_FINAL);
1060 if ($1 != ACC_FINAL)
1061 MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1065 throws:
1066 { $$ = NULL_TREE; }
1067 | THROWS_TK class_type_list
1068 { $$ = $2; }
1069 | THROWS_TK error
1070 {yyerror ("Missing class type term"); RECOVER;}
1073 class_type_list:
1074 class_type
1075 { $$ = build_tree_list ($1, $1); }
1076 | class_type_list C_TK class_type
1077 { $$ = tree_cons ($3, $3, $1); }
1078 | class_type_list C_TK error
1079 {yyerror ("Missing class type term"); RECOVER;}
1082 method_body:
1083 block
1084 | block SC_TK
1085 | SC_TK
1086 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
1089 /* 19.8.4 Productions from 8.5: Static Initializers */
1090 static_initializer:
1091 static block
1093 TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1094 SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1096 | static block SC_TK /* Shouldn't be here. FIXME */
1098 TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1099 SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1103 static: /* Test lval.sub_token here */
1104 modifiers
1106 check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1107 /* Can't have a static initializer in an innerclass */
1108 if ($1 | ACC_STATIC &&
1109 GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1110 parse_error_context
1111 (MODIFIER_WFL (STATIC_TK),
1112 "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1113 IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1114 SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1118 /* 19.8.5 Productions from 8.6: Constructor Declarations */
1119 constructor_declaration:
1120 constructor_header
1122 current_function_decl = $1;
1123 source_start_java_method (current_function_decl);
1125 constructor_body
1126 { finish_method_declaration ($3); }
1129 constructor_header:
1130 constructor_declarator throws
1131 { $$ = method_header (0, NULL_TREE, $1, $2); }
1132 | modifiers constructor_declarator throws
1133 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1136 constructor_declarator:
1137 simple_name OP_TK CP_TK
1139 ctxp->formal_parameter_number = 0;
1140 $$ = method_declarator ($1, NULL_TREE);
1142 | simple_name OP_TK formal_parameter_list CP_TK
1143 { $$ = method_declarator ($1, $3); }
1146 constructor_body:
1147 /* Unlike regular method, we always need a complete (empty)
1148 body so we can safely perform all the required code
1149 addition (super invocation and field initialization) */
1150 block_begin constructor_block_end
1152 BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1153 $$ = $2;
1155 | block_begin explicit_constructor_invocation constructor_block_end
1156 { $$ = $3; }
1157 | block_begin block_statements constructor_block_end
1158 { $$ = $3; }
1159 | block_begin explicit_constructor_invocation block_statements constructor_block_end
1160 { $$ = $4; }
1163 constructor_block_end:
1164 block_end
1165 | block_end SC_TK
1167 /* Error recovery for that rule moved down expression_statement: rule. */
1168 explicit_constructor_invocation:
1169 this_or_super OP_TK CP_TK SC_TK
1171 $$ = build_method_invocation ($1, NULL_TREE);
1172 $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1173 $$ = java_method_add_stmt (current_function_decl, $$);
1175 | this_or_super OP_TK argument_list CP_TK SC_TK
1177 $$ = build_method_invocation ($1, $3);
1178 $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1179 $$ = java_method_add_stmt (current_function_decl, $$);
1181 /* Added, JDK1.1 inner classes. Modified because the rule
1182 'primary' couldn't work. */
1183 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1184 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1185 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1186 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1189 this_or_super: /* Added, simplifies error diagnostics */
1190 THIS_TK
1192 tree wfl = build_wfl_node (this_identifier_node);
1193 EXPR_WFL_LINECOL (wfl) = $1.location;
1194 $$ = wfl;
1196 | SUPER_TK
1198 tree wfl = build_wfl_node (super_identifier_node);
1199 EXPR_WFL_LINECOL (wfl) = $1.location;
1200 $$ = wfl;
1204 /* 19.9 Productions from 9: Interfaces */
1205 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
1206 interface_declaration:
1207 INTERFACE_TK identifier
1208 { create_interface (0, $2, NULL_TREE); }
1209 interface_body
1210 | modifiers INTERFACE_TK identifier
1211 { create_interface ($1, $3, NULL_TREE); }
1212 interface_body
1213 | INTERFACE_TK identifier extends_interfaces
1214 { create_interface (0, $2, $3); }
1215 interface_body
1216 | modifiers INTERFACE_TK identifier extends_interfaces
1217 { create_interface ($1, $3, $4); }
1218 interface_body
1219 | INTERFACE_TK identifier error
1220 {yyerror ("'{' expected"); RECOVER;}
1221 | modifiers INTERFACE_TK identifier error
1222 {yyerror ("'{' expected"); RECOVER;}
1225 extends_interfaces:
1226 EXTENDS_TK interface_type
1228 ctxp->interface_number = 1;
1229 $$ = build_tree_list ($2, NULL_TREE);
1231 | extends_interfaces C_TK interface_type
1233 ctxp->interface_number++;
1234 $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1236 | EXTENDS_TK error
1237 {yyerror ("Invalid interface type"); RECOVER;}
1238 | extends_interfaces C_TK error
1239 {yyerror ("Missing term"); RECOVER;}
1242 interface_body:
1243 OCB_TK CCB_TK
1244 { $$ = NULL_TREE; }
1245 | OCB_TK interface_member_declarations CCB_TK
1246 { $$ = NULL_TREE; }
1249 interface_member_declarations:
1250 interface_member_declaration
1251 | interface_member_declarations interface_member_declaration
1254 interface_member_declaration:
1255 constant_declaration
1256 | abstract_method_declaration
1257 | class_declaration /* Added, JDK1.1 inner classes */
1258 { end_class_declaration (1); }
1259 | interface_declaration /* Added, JDK1.1 inner interfaces */
1260 { end_class_declaration (1); }
1263 constant_declaration:
1264 field_declaration
1267 abstract_method_declaration:
1268 method_header SC_TK
1270 check_abstract_method_header ($1);
1271 current_function_decl = NULL_TREE; /* FIXME ? */
1273 | method_header error
1274 {yyerror ("';' expected"); RECOVER;}
1277 /* 19.10 Productions from 10: Arrays */
1278 array_initializer:
1279 OCB_TK CCB_TK
1280 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1281 | OCB_TK variable_initializers CCB_TK
1282 { $$ = build_new_array_init ($1.location, $2); }
1283 | OCB_TK variable_initializers C_TK CCB_TK
1284 { $$ = build_new_array_init ($1.location, $2); }
1287 variable_initializers:
1288 variable_initializer
1290 $$ = tree_cons (maybe_build_array_element_wfl ($1),
1291 $1, NULL_TREE);
1293 | variable_initializers C_TK variable_initializer
1295 $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1297 | variable_initializers C_TK error
1298 {yyerror ("Missing term"); RECOVER;}
1301 /* 19.11 Production from 14: Blocks and Statements */
1302 block:
1303 OCB_TK CCB_TK
1305 /* Store the location of the `}' when doing xrefs */
1306 if (current_function_decl && flag_emit_xref)
1307 DECL_END_SOURCE_LINE (current_function_decl) =
1308 EXPR_WFL_ADD_COL ($2.location, 1);
1309 $$ = empty_stmt_node;
1311 | block_begin block_statements block_end
1312 { $$ = $3; }
1315 block_begin:
1316 OCB_TK
1317 { enter_block (); }
1320 block_end:
1321 CCB_TK
1323 maybe_absorb_scoping_blocks ();
1324 /* Store the location of the `}' when doing xrefs */
1325 if (current_function_decl && flag_emit_xref)
1326 DECL_END_SOURCE_LINE (current_function_decl) =
1327 EXPR_WFL_ADD_COL ($1.location, 1);
1328 $$ = exit_block ();
1332 block_statements:
1333 block_statement
1334 | block_statements block_statement
1337 block_statement:
1338 local_variable_declaration_statement
1339 | statement
1340 { java_method_add_stmt (current_function_decl, $1); }
1341 | class_declaration /* Added, JDK1.1 local classes */
1343 LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1344 end_class_declaration (1);
1348 local_variable_declaration_statement:
1349 local_variable_declaration SC_TK /* Can't catch missing ';' here */
1352 local_variable_declaration:
1353 type variable_declarators
1354 { declare_local_variables (0, $1, $2); }
1355 | final type variable_declarators /* Added, JDK1.1 final locals */
1356 { declare_local_variables ($1, $2, $3); }
1359 statement:
1360 statement_without_trailing_substatement
1361 | labeled_statement
1362 | if_then_statement
1363 | if_then_else_statement
1364 | while_statement
1365 | for_statement
1366 { $$ = exit_block (); }
1369 statement_nsi:
1370 statement_without_trailing_substatement
1371 | labeled_statement_nsi
1372 | if_then_else_statement_nsi
1373 | while_statement_nsi
1374 | for_statement_nsi
1375 { $$ = exit_block (); }
1378 statement_without_trailing_substatement:
1379 block
1380 | empty_statement
1381 | expression_statement
1382 | switch_statement
1383 | do_statement
1384 | break_statement
1385 | continue_statement
1386 | return_statement
1387 | synchronized_statement
1388 | throw_statement
1389 | try_statement
1392 empty_statement:
1393 SC_TK
1394 { $$ = empty_stmt_node; }
1397 label_decl:
1398 identifier REL_CL_TK
1400 $$ = build_labeled_block (EXPR_WFL_LINECOL ($1),
1401 EXPR_WFL_NODE ($1));
1402 pushlevel (2);
1403 push_labeled_block ($$);
1404 PUSH_LABELED_BLOCK ($$);
1408 labeled_statement:
1409 label_decl statement
1410 { $$ = finish_labeled_statement ($1, $2); }
1411 | identifier error
1412 {yyerror ("':' expected"); RECOVER;}
1415 labeled_statement_nsi:
1416 label_decl statement_nsi
1417 { $$ = finish_labeled_statement ($1, $2); }
1420 /* We concentrate here a bunch of error handling rules that we couldn't write
1421 earlier, because expression_statement catches a missing ';'. */
1422 expression_statement:
1423 statement_expression SC_TK
1425 /* We have a statement. Generate a WFL around it so
1426 we can debug it */
1427 $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1428 /* We know we have a statement, so set the debug
1429 info to be eventually generate here. */
1430 $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1432 | error SC_TK
1434 if (ctxp->prevent_ese != lineno)
1435 yyerror ("Invalid expression statement");
1436 DRECOVER (expr_stmt);
1438 | error OCB_TK
1440 if (ctxp->prevent_ese != lineno)
1441 yyerror ("Invalid expression statement");
1442 DRECOVER (expr_stmt);
1444 | error CCB_TK
1446 if (ctxp->prevent_ese != lineno)
1447 yyerror ("Invalid expression statement");
1448 DRECOVER (expr_stmt);
1450 | this_or_super OP_TK error
1451 {yyerror ("')' expected"); RECOVER;}
1452 | this_or_super OP_TK CP_TK error
1454 parse_ctor_invocation_error ();
1455 RECOVER;
1457 | this_or_super OP_TK argument_list error
1458 {yyerror ("')' expected"); RECOVER;}
1459 | this_or_super OP_TK argument_list CP_TK error
1461 parse_ctor_invocation_error ();
1462 RECOVER;
1464 | name DOT_TK SUPER_TK error
1465 {yyerror ("'(' expected"); RECOVER;}
1466 | name DOT_TK SUPER_TK OP_TK error
1467 {yyerror ("')' expected"); RECOVER;}
1468 | name DOT_TK SUPER_TK OP_TK argument_list error
1469 {yyerror ("')' expected"); RECOVER;}
1470 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1471 {yyerror ("';' expected"); RECOVER;}
1472 | name DOT_TK SUPER_TK OP_TK CP_TK error
1473 {yyerror ("';' expected"); RECOVER;}
1476 statement_expression:
1477 assignment
1478 | pre_increment_expression
1479 | pre_decrement_expression
1480 | post_increment_expression
1481 | post_decrement_expression
1482 | method_invocation
1483 | class_instance_creation_expression
1486 if_then_statement:
1487 IF_TK OP_TK expression CP_TK statement
1489 $$ = build_if_else_statement ($2.location, $3,
1490 $5, NULL_TREE);
1492 | IF_TK error
1493 {yyerror ("'(' expected"); RECOVER;}
1494 | IF_TK OP_TK error
1495 {yyerror ("Missing term"); RECOVER;}
1496 | IF_TK OP_TK expression error
1497 {yyerror ("')' expected"); RECOVER;}
1500 if_then_else_statement:
1501 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1502 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1505 if_then_else_statement_nsi:
1506 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1507 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1510 switch_statement:
1511 switch_expression
1513 enter_block ();
1515 switch_block
1517 /* Make into "proper list" of COMPOUND_EXPRs.
1518 I.e. make the last statment also have its own
1519 COMPOUND_EXPR. */
1520 maybe_absorb_scoping_blocks ();
1521 TREE_OPERAND ($1, 1) = exit_block ();
1522 $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1526 switch_expression:
1527 SWITCH_TK OP_TK expression CP_TK
1529 $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1530 EXPR_WFL_LINECOL ($$) = $2.location;
1532 | SWITCH_TK error
1533 {yyerror ("'(' expected"); RECOVER;}
1534 | SWITCH_TK OP_TK error
1535 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1536 | SWITCH_TK OP_TK expression CP_TK error
1537 {yyerror ("'{' expected"); RECOVER;}
1540 /* Default assignment is there to avoid type node on switch_block
1541 node. */
1543 switch_block:
1544 OCB_TK CCB_TK
1545 { $$ = NULL_TREE; }
1546 | OCB_TK switch_labels CCB_TK
1547 { $$ = NULL_TREE; }
1548 | OCB_TK switch_block_statement_groups CCB_TK
1549 { $$ = NULL_TREE; }
1550 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
1551 { $$ = NULL_TREE; }
1554 switch_block_statement_groups:
1555 switch_block_statement_group
1556 | switch_block_statement_groups switch_block_statement_group
1559 switch_block_statement_group:
1560 switch_labels block_statements
1563 switch_labels:
1564 switch_label
1565 | switch_labels switch_label
1568 switch_label:
1569 CASE_TK constant_expression REL_CL_TK
1571 tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1572 EXPR_WFL_LINECOL (lab) = $1.location;
1573 java_method_add_stmt (current_function_decl, lab);
1575 | DEFAULT_TK REL_CL_TK
1577 tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1578 EXPR_WFL_LINECOL (lab) = $1.location;
1579 java_method_add_stmt (current_function_decl, lab);
1581 | CASE_TK error
1582 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1583 | CASE_TK constant_expression error
1584 {yyerror ("':' expected"); RECOVER;}
1585 | DEFAULT_TK error
1586 {yyerror ("':' expected"); RECOVER;}
1589 while_expression:
1590 WHILE_TK OP_TK expression CP_TK
1592 tree body = build_loop_body ($2.location, $3, 0);
1593 $$ = build_new_loop (body);
1597 while_statement:
1598 while_expression statement
1599 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1600 | WHILE_TK error
1601 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1602 | WHILE_TK OP_TK error
1603 {yyerror ("Missing term and ')' expected"); RECOVER;}
1604 | WHILE_TK OP_TK expression error
1605 {yyerror ("')' expected"); RECOVER;}
1608 while_statement_nsi:
1609 while_expression statement_nsi
1610 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1613 do_statement_begin:
1614 DO_TK
1616 tree body = build_loop_body (0, NULL_TREE, 1);
1617 $$ = build_new_loop (body);
1619 /* Need error handing here. FIXME */
1622 do_statement:
1623 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1624 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1627 for_statement:
1628 for_begin SC_TK expression SC_TK for_update CP_TK statement
1629 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7); }
1630 | for_begin SC_TK SC_TK for_update CP_TK statement
1632 $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1633 /* We have not condition, so we get rid of the EXIT_EXPR */
1634 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
1635 empty_stmt_node;
1637 | for_begin SC_TK error
1638 {yyerror ("Invalid control expression"); RECOVER;}
1639 | for_begin SC_TK expression SC_TK error
1640 {yyerror ("Invalid update expression"); RECOVER;}
1641 | for_begin SC_TK SC_TK error
1642 {yyerror ("Invalid update expression"); RECOVER;}
1645 for_statement_nsi:
1646 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1647 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1648 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1650 $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1651 /* We have not condition, so we get rid of the EXIT_EXPR */
1652 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
1653 empty_stmt_node;
1657 for_header:
1658 FOR_TK OP_TK
1660 /* This scope defined for local variable that may be
1661 defined within the scope of the for loop */
1662 enter_block ();
1664 | FOR_TK error
1665 {yyerror ("'(' expected"); DRECOVER(for_1);}
1666 | FOR_TK OP_TK error
1667 {yyerror ("Invalid init statement"); RECOVER;}
1670 for_begin:
1671 for_header for_init
1673 /* We now declare the loop body. The loop is
1674 declared as a for loop. */
1675 tree body = build_loop_body (0, NULL_TREE, 0);
1676 $$ = build_new_loop (body);
1677 FOR_LOOP_P ($$) = 1;
1678 /* The loop is added to the current block the for
1679 statement is defined within */
1680 java_method_add_stmt (current_function_decl, $$);
1683 for_init: /* Can be empty */
1684 { $$ = empty_stmt_node; }
1685 | statement_expression_list
1687 /* Init statement recorded within the previously
1688 defined block scope */
1689 $$ = java_method_add_stmt (current_function_decl, $1);
1691 | local_variable_declaration
1693 /* Local variable are recorded within the previously
1694 defined block scope */
1695 $$ = NULL_TREE;
1697 | statement_expression_list error
1698 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1701 for_update: /* Can be empty */
1702 {$$ = empty_stmt_node;}
1703 | statement_expression_list
1704 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1707 statement_expression_list:
1708 statement_expression
1709 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1710 | statement_expression_list C_TK statement_expression
1711 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1712 | statement_expression_list C_TK error
1713 {yyerror ("Missing term"); RECOVER;}
1716 break_statement:
1717 BREAK_TK SC_TK
1718 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1719 | BREAK_TK identifier SC_TK
1720 { $$ = build_bc_statement ($1.location, 1, $2); }
1721 | BREAK_TK error
1722 {yyerror ("Missing term"); RECOVER;}
1723 | BREAK_TK identifier error
1724 {yyerror ("';' expected"); RECOVER;}
1727 continue_statement:
1728 CONTINUE_TK SC_TK
1729 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1730 | CONTINUE_TK identifier SC_TK
1731 { $$ = build_bc_statement ($1.location, 0, $2); }
1732 | CONTINUE_TK error
1733 {yyerror ("Missing term"); RECOVER;}
1734 | CONTINUE_TK identifier error
1735 {yyerror ("';' expected"); RECOVER;}
1738 return_statement:
1739 RETURN_TK SC_TK
1740 { $$ = build_return ($1.location, NULL_TREE); }
1741 | RETURN_TK expression SC_TK
1742 { $$ = build_return ($1.location, $2); }
1743 | RETURN_TK error
1744 {yyerror ("Missing term"); RECOVER;}
1745 | RETURN_TK expression error
1746 {yyerror ("';' expected"); RECOVER;}
1749 throw_statement:
1750 THROW_TK expression SC_TK
1752 $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1753 EXPR_WFL_LINECOL ($$) = $1.location;
1755 | THROW_TK error
1756 {yyerror ("Missing term"); RECOVER;}
1757 | THROW_TK expression error
1758 {yyerror ("';' expected"); RECOVER;}
1761 synchronized_statement:
1762 synchronized OP_TK expression CP_TK block
1764 $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1765 EXPR_WFL_LINECOL ($$) =
1766 EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1768 | synchronized OP_TK expression CP_TK error
1769 {yyerror ("'{' expected"); RECOVER;}
1770 | synchronized error
1771 {yyerror ("'(' expected"); RECOVER;}
1772 | synchronized OP_TK error CP_TK
1773 {yyerror ("Missing term"); RECOVER;}
1774 | synchronized OP_TK error
1775 {yyerror ("Missing term"); RECOVER;}
1778 synchronized:
1779 modifiers
1781 check_modifiers (
1782 "Illegal modifier `%s'. Only `synchronized' was expected here",
1783 $1, ACC_SYNCHRONIZED);
1784 if ($1 != ACC_SYNCHRONIZED)
1785 MODIFIER_WFL (SYNCHRONIZED_TK) =
1786 build_wfl_node (NULL_TREE);
1790 try_statement:
1791 TRY_TK block catches
1792 { $$ = build_try_statement ($1.location, $2, $3); }
1793 | TRY_TK block finally
1794 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1795 | TRY_TK block catches finally
1796 { $$ = build_try_finally_statement
1797 ($1.location, build_try_statement ($1.location,
1798 $2, $3), $4);
1800 | TRY_TK error
1801 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1804 catches:
1805 catch_clause
1806 | catches catch_clause
1808 TREE_CHAIN ($2) = $1;
1809 $$ = $2;
1813 catch_clause:
1814 catch_clause_parameter block
1816 java_method_add_stmt (current_function_decl, $2);
1817 exit_block ();
1818 $$ = $1;
1821 catch_clause_parameter:
1822 CATCH_TK OP_TK formal_parameter CP_TK
1824 /* We add a block to define a scope for
1825 formal_parameter (CCBP). The formal parameter is
1826 declared initialized by the appropriate function
1827 call */
1828 tree ccpb = enter_block ();
1829 tree init = build_assignment (ASSIGN_TK, $2.location,
1830 TREE_PURPOSE ($3),
1831 soft_exceptioninfo_call_node);
1832 declare_local_variables (0, TREE_VALUE ($3),
1833 build_tree_list (TREE_PURPOSE ($3),
1834 init));
1835 $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1836 EXPR_WFL_LINECOL ($$) = $1.location;
1838 | CATCH_TK error
1839 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1840 | CATCH_TK OP_TK error
1842 yyerror ("Missing term or ')' expected");
1843 RECOVER; $$ = NULL_TREE;
1845 | CATCH_TK OP_TK error CP_TK /* That's for () */
1846 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1849 finally:
1850 FINALLY_TK block
1851 { $$ = $2; }
1852 | FINALLY_TK error
1853 {yyerror ("'{' expected"); RECOVER; }
1856 /* 19.12 Production from 15: Expressions */
1857 primary:
1858 primary_no_new_array
1859 | array_creation_expression
1862 primary_no_new_array:
1863 literal
1864 | THIS_TK
1865 { $$ = build_this ($1.location); }
1866 | OP_TK expression CP_TK
1867 {$$ = $2;}
1868 | class_instance_creation_expression
1869 | field_access
1870 | method_invocation
1871 | array_access
1872 | type_literals
1873 /* Added, JDK1.1 inner classes. Documentation is wrong
1874 refering to a 'ClassName' (class_name) rule that doesn't
1875 exist. Used name: instead. */
1876 | name DOT_TK THIS_TK
1878 tree wfl = build_wfl_node (this_identifier_node);
1879 $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1881 | OP_TK expression error
1882 {yyerror ("')' expected"); RECOVER;}
1883 | name DOT_TK error
1884 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1885 | primitive_type DOT_TK error
1886 {yyerror ("'class' expected" ); RECOVER;}
1887 | VOID_TK DOT_TK error
1888 {yyerror ("'class' expected" ); RECOVER;}
1891 /* Added, JDK1.1 type literals. We can't use `type' directly, so we
1892 broke the rule down a bit. */
1894 array_type_literal:
1895 primitive_type OSB_TK CSB_TK
1897 $$ = build_java_array_type ($1, -1);
1898 CLASS_LOADED_P ($$) = 1;
1900 | name OSB_TK CSB_TK
1901 { $$ = build_unresolved_array_type ($1); }
1902 /* This triggers two reduce/reduce conflict between array_type_literal and
1903 dims. FIXME.
1904 | array_type OSB_TK CSB_TK
1905 { $$ = build_unresolved_array_type ($1); }
1909 type_literals:
1910 name DOT_TK CLASS_TK
1911 { $$ = build_incomplete_class_ref ($2.location, $1); }
1912 | array_type_literal DOT_TK CLASS_TK
1913 { $$ = build_incomplete_class_ref ($2.location, $1); }
1914 | primitive_type DOT_TK CLASS_TK
1915 { $$ = build_class_ref ($1); }
1916 | VOID_TK DOT_TK CLASS_TK
1917 { $$ = build_class_ref (void_type_node); }
1920 class_instance_creation_expression:
1921 NEW_TK class_type OP_TK argument_list CP_TK
1922 { $$ = build_new_invocation ($2, $4); }
1923 | NEW_TK class_type OP_TK CP_TK
1924 { $$ = build_new_invocation ($2, NULL_TREE); }
1925 | anonymous_class_creation
1926 /* Added, JDK1.1 inner classes, modified to use name or
1927 primary instead of primary solely which couldn't work in
1928 all situations. */
1929 | something_dot_new identifier OP_TK CP_TK
1931 tree ctor = build_new_invocation ($2, NULL_TREE);
1932 $$ = make_qualified_primary ($1, ctor,
1933 EXPR_WFL_LINECOL ($1));
1935 | something_dot_new identifier OP_TK CP_TK class_body
1936 | something_dot_new identifier OP_TK argument_list CP_TK
1938 tree ctor = build_new_invocation ($2, $4);
1939 $$ = make_qualified_primary ($1, ctor,
1940 EXPR_WFL_LINECOL ($1));
1942 | something_dot_new identifier OP_TK argument_list CP_TK class_body
1943 | NEW_TK error SC_TK
1944 {yyerror ("'(' expected"); DRECOVER(new_1);}
1945 | NEW_TK class_type error
1946 {yyerror ("'(' expected"); RECOVER;}
1947 | NEW_TK class_type OP_TK error
1948 {yyerror ("')' or term expected"); RECOVER;}
1949 | NEW_TK class_type OP_TK argument_list error
1950 {yyerror ("')' expected"); RECOVER;}
1951 | something_dot_new error
1952 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1953 | something_dot_new identifier error
1954 {yyerror ("'(' expected"); RECOVER;}
1957 /* Created after JDK1.1 rules originally added to
1958 class_instance_creation_expression, but modified to use
1959 'class_type' instead of 'TypeName' (type_name) which is mentionned
1960 in the documentation but doesn't exist. */
1962 anonymous_class_creation:
1963 NEW_TK class_type OP_TK argument_list CP_TK
1964 { create_anonymous_class ($1.location, $2); }
1965 class_body
1967 tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
1968 EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
1970 end_class_declaration (1);
1972 /* Now we can craft the new expression */
1973 $$ = build_new_invocation (id, $4);
1975 /* Note that we can't possibly be here if
1976 `class_type' is an interface (in which case the
1977 anonymous class extends Object and implements
1978 `class_type', hence its constructor can't have
1979 arguments.) */
1981 /* Otherwise, the innerclass must feature a
1982 constructor matching `argument_list'. Anonymous
1983 classes are a bit special: it's impossible to
1984 define constructor for them, hence constructors
1985 must be generated following the hints provided by
1986 the `new' expression. Whether a super constructor
1987 of that nature exists or not is to be verified
1988 later on in verify_constructor_super.
1990 It's during the expansion of a `new' statement
1991 refering to an anonymous class that a ctor will
1992 be generated for the anonymous class, with the
1993 right arguments. */
1996 | NEW_TK class_type OP_TK CP_TK
1997 { create_anonymous_class ($1.location, $2); }
1998 class_body
2000 tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2001 EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2003 end_class_declaration (1);
2005 /* Now we can craft the new expression. The
2006 statement doesn't need to be remember so that a
2007 constructor can be generated, since its signature
2008 is already known. */
2009 $$ = build_new_invocation (id, NULL_TREE);
2013 something_dot_new: /* Added, not part of the specs. */
2014 name DOT_TK NEW_TK
2015 { $$ = $1; }
2016 | primary DOT_TK NEW_TK
2017 { $$ = $1; }
2020 argument_list:
2021 expression
2023 $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2024 ctxp->formal_parameter_number = 1;
2026 | argument_list C_TK expression
2028 ctxp->formal_parameter_number += 1;
2029 $$ = tree_cons (NULL_TREE, $3, $1);
2031 | argument_list C_TK error
2032 {yyerror ("Missing term"); RECOVER;}
2035 array_creation_expression:
2036 NEW_TK primitive_type dim_exprs
2037 { $$ = build_newarray_node ($2, $3, 0); }
2038 | NEW_TK class_or_interface_type dim_exprs
2039 { $$ = build_newarray_node ($2, $3, 0); }
2040 | NEW_TK primitive_type dim_exprs dims
2041 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2042 | NEW_TK class_or_interface_type dim_exprs dims
2043 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2044 /* Added, JDK1.1 anonymous array. Initial documentation rule
2045 modified */
2046 | NEW_TK class_or_interface_type dims array_initializer
2048 char *sig;
2049 while (CURRENT_OSB (ctxp)--)
2050 obstack_1grow (&temporary_obstack, '[');
2051 sig = obstack_finish (&temporary_obstack);
2052 $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2053 $2, get_identifier (sig), $4);
2055 | NEW_TK primitive_type dims array_initializer
2057 tree type = $2;
2058 while (CURRENT_OSB (ctxp)--)
2059 type = build_java_array_type (type, -1);
2060 $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2061 build_pointer_type (type), NULL_TREE, $4);
2063 | NEW_TK error CSB_TK
2064 {yyerror ("'[' expected"); DRECOVER ("]");}
2065 | NEW_TK error OSB_TK
2066 {yyerror ("']' expected"); RECOVER;}
2069 dim_exprs:
2070 dim_expr
2071 { $$ = build_tree_list (NULL_TREE, $1); }
2072 | dim_exprs dim_expr
2073 { $$ = tree_cons (NULL_TREE, $2, $$); }
2076 dim_expr:
2077 OSB_TK expression CSB_TK
2079 EXPR_WFL_LINECOL ($2) = $1.location;
2080 $$ = $2;
2082 | OSB_TK expression error
2083 {yyerror ("']' expected"); RECOVER;}
2084 | OSB_TK error
2086 yyerror ("Missing term");
2087 yyerror ("']' expected");
2088 RECOVER;
2092 dims:
2093 OSB_TK CSB_TK
2095 int allocate = 0;
2096 /* If not initialized, allocate memory for the osb
2097 numbers stack */
2098 if (!ctxp->osb_limit)
2100 allocate = ctxp->osb_limit = 32;
2101 ctxp->osb_depth = -1;
2103 /* If capacity overflown, reallocate a bigger chunk */
2104 else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2105 allocate = ctxp->osb_limit << 1;
2107 if (allocate)
2109 allocate *= sizeof (int);
2110 if (ctxp->osb_number)
2111 ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2112 allocate);
2113 else
2114 ctxp->osb_number = (int *)xmalloc (allocate);
2116 ctxp->osb_depth++;
2117 CURRENT_OSB (ctxp) = 1;
2119 | dims OSB_TK CSB_TK
2120 { CURRENT_OSB (ctxp)++; }
2121 | dims OSB_TK error
2122 { yyerror ("']' expected"); RECOVER;}
2125 field_access:
2126 primary DOT_TK identifier
2127 { $$ = make_qualified_primary ($1, $3, $2.location); }
2128 /* FIXME - REWRITE TO:
2129 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2130 | SUPER_TK DOT_TK identifier
2132 tree super_wfl =
2133 build_wfl_node (super_identifier_node);
2134 EXPR_WFL_LINECOL (super_wfl) = $1.location;
2135 $$ = make_qualified_name (super_wfl, $3, $2.location);
2137 | SUPER_TK error
2138 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2141 method_invocation:
2142 name OP_TK CP_TK
2143 { $$ = build_method_invocation ($1, NULL_TREE); }
2144 | name OP_TK argument_list CP_TK
2145 { $$ = build_method_invocation ($1, $3); }
2146 | primary DOT_TK identifier OP_TK CP_TK
2148 if (TREE_CODE ($1) == THIS_EXPR)
2149 $$ = build_this_super_qualified_invocation
2150 (1, $3, NULL_TREE, 0, $2.location);
2151 else
2153 tree invok = build_method_invocation ($3, NULL_TREE);
2154 $$ = make_qualified_primary ($1, invok, $2.location);
2157 | primary DOT_TK identifier OP_TK argument_list CP_TK
2159 if (TREE_CODE ($1) == THIS_EXPR)
2160 $$ = build_this_super_qualified_invocation
2161 (1, $3, $5, 0, $2.location);
2162 else
2164 tree invok = build_method_invocation ($3, $5);
2165 $$ = make_qualified_primary ($1, invok, $2.location);
2168 | SUPER_TK DOT_TK identifier OP_TK CP_TK
2170 $$ = build_this_super_qualified_invocation
2171 (0, $3, NULL_TREE, $1.location, $2.location);
2173 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2175 $$ = build_this_super_qualified_invocation
2176 (0, $3, $5, $1.location, $2.location);
2178 /* Screws up thing. I let it here until I'm convinced it can
2179 be removed. FIXME
2180 | primary DOT_TK error
2181 {yyerror ("'(' expected"); DRECOVER(bad);} */
2182 | SUPER_TK DOT_TK error CP_TK
2183 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2184 | SUPER_TK DOT_TK error DOT_TK
2185 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2188 array_access:
2189 name OSB_TK expression CSB_TK
2190 { $$ = build_array_ref ($2.location, $1, $3); }
2191 | primary_no_new_array OSB_TK expression CSB_TK
2192 { $$ = build_array_ref ($2.location, $1, $3); }
2193 | name OSB_TK error
2195 yyerror ("Missing term and ']' expected");
2196 DRECOVER(array_access);
2198 | name OSB_TK expression error
2200 yyerror ("']' expected");
2201 DRECOVER(array_access);
2203 | primary_no_new_array OSB_TK error
2205 yyerror ("Missing term and ']' expected");
2206 DRECOVER(array_access);
2208 | primary_no_new_array OSB_TK expression error
2210 yyerror ("']' expected");
2211 DRECOVER(array_access);
2215 postfix_expression:
2216 primary
2217 | name
2218 | post_increment_expression
2219 | post_decrement_expression
2222 post_increment_expression:
2223 postfix_expression INCR_TK
2224 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2227 post_decrement_expression:
2228 postfix_expression DECR_TK
2229 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2232 unary_expression:
2233 pre_increment_expression
2234 | pre_decrement_expression
2235 | PLUS_TK unary_expression
2236 {$$ = build_unaryop ($1.token, $1.location, $2); }
2237 | MINUS_TK unary_expression
2238 {$$ = build_unaryop ($1.token, $1.location, $2); }
2239 | unary_expression_not_plus_minus
2240 | PLUS_TK error
2241 {yyerror ("Missing term"); RECOVER}
2242 | MINUS_TK error
2243 {yyerror ("Missing term"); RECOVER}
2246 pre_increment_expression:
2247 INCR_TK unary_expression
2248 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2249 | INCR_TK error
2250 {yyerror ("Missing term"); RECOVER}
2253 pre_decrement_expression:
2254 DECR_TK unary_expression
2255 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2256 | DECR_TK error
2257 {yyerror ("Missing term"); RECOVER}
2260 unary_expression_not_plus_minus:
2261 postfix_expression
2262 | NOT_TK unary_expression
2263 {$$ = build_unaryop ($1.token, $1.location, $2); }
2264 | NEG_TK unary_expression
2265 {$$ = build_unaryop ($1.token, $1.location, $2); }
2266 | cast_expression
2267 | NOT_TK error
2268 {yyerror ("Missing term"); RECOVER}
2269 | NEG_TK error
2270 {yyerror ("Missing term"); RECOVER}
2273 cast_expression: /* Error handling here is potentially weak */
2274 OP_TK primitive_type dims CP_TK unary_expression
2276 tree type = $2;
2277 while (CURRENT_OSB (ctxp)--)
2278 type = build_java_array_type (type, -1);
2279 ctxp->osb_depth--;
2280 $$ = build_cast ($1.location, type, $5);
2282 | OP_TK primitive_type CP_TK unary_expression
2283 { $$ = build_cast ($1.location, $2, $4); }
2284 | OP_TK expression CP_TK unary_expression_not_plus_minus
2285 { $$ = build_cast ($1.location, $2, $4); }
2286 | OP_TK name dims CP_TK unary_expression_not_plus_minus
2288 const char *ptr;
2289 while (CURRENT_OSB (ctxp)--)
2290 obstack_1grow (&temporary_obstack, '[');
2291 ctxp->osb_depth--;
2292 obstack_grow0 (&temporary_obstack,
2293 IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2294 IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2295 ptr = obstack_finish (&temporary_obstack);
2296 EXPR_WFL_NODE ($2) = get_identifier (ptr);
2297 $$ = build_cast ($1.location, $2, $5);
2299 | OP_TK primitive_type OSB_TK error
2300 {yyerror ("']' expected, invalid type expression");}
2301 | OP_TK error
2303 if (ctxp->prevent_ese != lineno)
2304 yyerror ("Invalid type expression"); RECOVER;
2305 RECOVER;
2307 | OP_TK primitive_type dims CP_TK error
2308 {yyerror ("Missing term"); RECOVER;}
2309 | OP_TK primitive_type CP_TK error
2310 {yyerror ("Missing term"); RECOVER;}
2311 | OP_TK name dims CP_TK error
2312 {yyerror ("Missing term"); RECOVER;}
2315 multiplicative_expression:
2316 unary_expression
2317 | multiplicative_expression MULT_TK unary_expression
2319 $$ = build_binop (BINOP_LOOKUP ($2.token),
2320 $2.location, $1, $3);
2322 | multiplicative_expression DIV_TK unary_expression
2324 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2325 $1, $3);
2327 | multiplicative_expression REM_TK unary_expression
2329 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2330 $1, $3);
2332 | multiplicative_expression MULT_TK error
2333 {yyerror ("Missing term"); RECOVER;}
2334 | multiplicative_expression DIV_TK error
2335 {yyerror ("Missing term"); RECOVER;}
2336 | multiplicative_expression REM_TK error
2337 {yyerror ("Missing term"); RECOVER;}
2340 additive_expression:
2341 multiplicative_expression
2342 | additive_expression PLUS_TK multiplicative_expression
2344 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2345 $1, $3);
2347 | additive_expression MINUS_TK multiplicative_expression
2349 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2350 $1, $3);
2352 | additive_expression PLUS_TK error
2353 {yyerror ("Missing term"); RECOVER;}
2354 | additive_expression MINUS_TK error
2355 {yyerror ("Missing term"); RECOVER;}
2358 shift_expression:
2359 additive_expression
2360 | shift_expression LS_TK additive_expression
2362 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2363 $1, $3);
2365 | shift_expression SRS_TK additive_expression
2367 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2368 $1, $3);
2370 | shift_expression ZRS_TK additive_expression
2372 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2373 $1, $3);
2375 | shift_expression LS_TK error
2376 {yyerror ("Missing term"); RECOVER;}
2377 | shift_expression SRS_TK error
2378 {yyerror ("Missing term"); RECOVER;}
2379 | shift_expression ZRS_TK error
2380 {yyerror ("Missing term"); RECOVER;}
2383 relational_expression:
2384 shift_expression
2385 | relational_expression LT_TK shift_expression
2387 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2388 $1, $3);
2390 | relational_expression GT_TK shift_expression
2392 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2393 $1, $3);
2395 | relational_expression LTE_TK shift_expression
2397 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2398 $1, $3);
2400 | relational_expression GTE_TK shift_expression
2402 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2403 $1, $3);
2405 | relational_expression INSTANCEOF_TK reference_type
2406 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2407 | relational_expression LT_TK error
2408 {yyerror ("Missing term"); RECOVER;}
2409 | relational_expression GT_TK error
2410 {yyerror ("Missing term"); RECOVER;}
2411 | relational_expression LTE_TK error
2412 {yyerror ("Missing term"); RECOVER;}
2413 | relational_expression GTE_TK error
2414 {yyerror ("Missing term"); RECOVER;}
2415 | relational_expression INSTANCEOF_TK error
2416 {yyerror ("Invalid reference type"); RECOVER;}
2419 equality_expression:
2420 relational_expression
2421 | equality_expression EQ_TK relational_expression
2423 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2424 $1, $3);
2426 | equality_expression NEQ_TK relational_expression
2428 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2429 $1, $3);
2431 | equality_expression EQ_TK error
2432 {yyerror ("Missing term"); RECOVER;}
2433 | equality_expression NEQ_TK error
2434 {yyerror ("Missing term"); RECOVER;}
2437 and_expression:
2438 equality_expression
2439 | and_expression AND_TK equality_expression
2441 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2442 $1, $3);
2444 | and_expression AND_TK error
2445 {yyerror ("Missing term"); RECOVER;}
2448 exclusive_or_expression:
2449 and_expression
2450 | exclusive_or_expression XOR_TK and_expression
2452 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2453 $1, $3);
2455 | exclusive_or_expression XOR_TK error
2456 {yyerror ("Missing term"); RECOVER;}
2459 inclusive_or_expression:
2460 exclusive_or_expression
2461 | inclusive_or_expression OR_TK exclusive_or_expression
2463 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2464 $1, $3);
2466 | inclusive_or_expression OR_TK error
2467 {yyerror ("Missing term"); RECOVER;}
2470 conditional_and_expression:
2471 inclusive_or_expression
2472 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
2474 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2475 $1, $3);
2477 | conditional_and_expression BOOL_AND_TK error
2478 {yyerror ("Missing term"); RECOVER;}
2481 conditional_or_expression:
2482 conditional_and_expression
2483 | conditional_or_expression BOOL_OR_TK conditional_and_expression
2485 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2486 $1, $3);
2488 | conditional_or_expression BOOL_OR_TK error
2489 {yyerror ("Missing term"); RECOVER;}
2492 conditional_expression: /* Error handling here is weak */
2493 conditional_or_expression
2494 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2496 $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2497 EXPR_WFL_LINECOL ($$) = $2.location;
2499 | conditional_or_expression REL_QM_TK REL_CL_TK error
2501 YYERROR_NOW;
2502 yyerror ("Missing term");
2503 DRECOVER (1);
2505 | conditional_or_expression REL_QM_TK error
2506 {yyerror ("Missing term"); DRECOVER (2);}
2507 | conditional_or_expression REL_QM_TK expression REL_CL_TK error
2508 {yyerror ("Missing term"); DRECOVER (3);}
2511 assignment_expression:
2512 conditional_expression
2513 | assignment
2516 assignment:
2517 left_hand_side assignment_operator assignment_expression
2518 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2519 | left_hand_side assignment_operator error
2521 if (ctxp->prevent_ese != lineno)
2522 yyerror ("Missing term");
2523 DRECOVER (assign);
2527 left_hand_side:
2528 name
2529 | field_access
2530 | array_access
2533 assignment_operator:
2534 ASSIGN_ANY_TK
2535 | ASSIGN_TK
2538 expression:
2539 assignment_expression
2542 constant_expression:
2543 expression
2549 /* This section of the code deal with save/restoring parser contexts.
2550 Add mode documentation here. FIXME */
2552 /* Helper function. Create a new parser context. With
2553 COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2554 context is copied, otherwise, the new context is zeroed. The newly
2555 created context becomes the current one. */
2557 static void
2558 create_new_parser_context (copy_from_previous)
2559 int copy_from_previous;
2561 struct parser_ctxt *new;
2563 new = (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2564 if (copy_from_previous)
2566 memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2567 new->saved_data_ctx = 1;
2569 else
2570 bzero ((PTR) new, sizeof (struct parser_ctxt));
2572 new->next = ctxp;
2573 ctxp = new;
2576 /* Create a new parser context and make it the current one. */
2578 void
2579 java_push_parser_context ()
2581 create_new_parser_context (0);
2582 if (ctxp->next)
2584 ctxp->incomplete_class = ctxp->next->incomplete_class;
2585 ctxp->gclass_list = ctxp->next->gclass_list;
2589 void
2590 java_pop_parser_context (generate)
2591 int generate;
2593 tree current;
2594 struct parser_ctxt *toFree, *next;
2596 if (!ctxp)
2597 return;
2599 toFree = ctxp;
2600 next = ctxp->next;
2601 if (next)
2603 next->incomplete_class = ctxp->incomplete_class;
2604 next->gclass_list = ctxp->gclass_list;
2605 lineno = ctxp->lineno;
2606 finput = ctxp->finput;
2607 current_class = ctxp->current_class;
2610 /* Set the single import class file flag to 0 for the current list
2611 of imported things */
2612 for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2613 IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2615 /* And restore those of the previous context */
2616 if ((ctxp = next)) /* Assignment is really meant here */
2617 for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2618 IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2620 /* If we pushed a context to parse a class intended to be generated,
2621 we keep it so we can remember the class. What we could actually
2622 do is to just update a list of class names. */
2623 if (generate)
2625 toFree->next = ctxp_for_generation;
2626 ctxp_for_generation = toFree;
2628 else
2629 free (toFree);
2632 /* Create a parser context for the use of saving some global
2633 variables. */
2635 void
2636 java_parser_context_save_global ()
2638 if (!ctxp)
2640 java_push_parser_context ();
2641 ctxp->saved_data_ctx = 1;
2644 /* If this context already stores data, create a new one suitable
2645 for data storage. */
2646 else if (ctxp->saved_data)
2647 create_new_parser_context (1);
2649 ctxp->finput = finput;
2650 ctxp->lineno = lineno;
2651 ctxp->current_class = current_class;
2652 ctxp->filename = input_filename;
2653 ctxp->current_function_decl = current_function_decl;
2654 ctxp->saved_data = 1;
2657 /* Restore some global variables from the previous context. Make the
2658 previous context the current one. */
2660 void
2661 java_parser_context_restore_global ()
2663 finput = ctxp->finput;
2664 lineno = ctxp->lineno;
2665 current_class = ctxp->current_class;
2666 input_filename = ctxp->filename;
2667 current_function_decl = ctxp->current_function_decl;
2668 ctxp->saved_data = 0;
2669 if (ctxp->saved_data_ctx)
2670 java_pop_parser_context (0);
2673 /* Suspend vital data for the current class/function being parsed so
2674 that an other class can be parsed. Used to let local/anonymous
2675 classes be parsed. */
2677 static void
2678 java_parser_context_suspend ()
2680 /* This makes debugging through java_debug_context easier */
2681 static char *name = "<inner buffer context>";
2683 /* Duplicate the previous context, use it to save the globals we're
2684 interested in */
2685 create_new_parser_context (1);
2686 ctxp->current_function_decl = current_function_decl;
2687 ctxp->current_class = current_class;
2689 /* Then create a new context which inherits all data from the
2690 previous one. This will be the new current context */
2691 create_new_parser_context (1);
2693 /* Help debugging */
2694 ctxp->next->filename = name;
2697 /* Resume vital data for the current class/function being parsed so
2698 that an other class can be parsed. Used to let local/anonymous
2699 classes be parsed. The trick is the data storing file position
2700 informations must be restored to their current value, so parsing
2701 can resume as if no context was ever saved. */
2703 static void
2704 java_parser_context_resume ()
2706 struct parser_ctxt *old = ctxp; /* This one is to be discarded */
2707 struct parser_ctxt *saver = old->next; /* This one contain saved info */
2708 struct parser_ctxt *restored = saver->next; /* This one is the old current */
2710 /* We need to inherit the list of classes to complete/generate */
2711 restored->incomplete_class = old->incomplete_class;
2712 restored->gclass_list = old->gclass_list;
2713 restored->classd_list = old->classd_list;
2714 restored->class_list = old->class_list;
2716 /* Restore the current class and function from the saver */
2717 current_class = saver->current_class;
2718 current_function_decl = saver->current_function_decl;
2720 /* Retrive the restored context */
2721 ctxp = restored;
2723 /* Re-installed the data for the parsing to carry on */
2724 bcopy (&old->marker_begining, &ctxp->marker_begining,
2725 (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2727 /* Buffer context can now be discarded */
2728 free (saver);
2729 free (old);
2732 /* Add a new anchor node to which all statement(s) initializing static
2733 and non static initialized upon declaration field(s) will be
2734 linked. */
2736 static void
2737 java_parser_context_push_initialized_field ()
2739 tree node;
2741 node = build_tree_list (NULL_TREE, NULL_TREE);
2742 TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2743 CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2745 node = build_tree_list (NULL_TREE, NULL_TREE);
2746 TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2747 CPC_INITIALIZER_LIST (ctxp) = node;
2749 node = build_tree_list (NULL_TREE, NULL_TREE);
2750 TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2751 CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2754 /* Pop the lists of initialized field. If this lists aren't empty,
2755 remember them so we can use it to create and populate the $finit$
2756 or <clinit> functions. */
2758 static void
2759 java_parser_context_pop_initialized_field ()
2761 tree stmts;
2762 tree class_type = TREE_TYPE (GET_CPC ());
2764 if (CPC_INITIALIZER_LIST (ctxp))
2766 stmts = CPC_INITIALIZER_STMT (ctxp);
2767 CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2768 if (stmts && !java_error_count)
2769 TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2772 if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2774 stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2775 CPC_STATIC_INITIALIZER_LIST (ctxp) =
2776 TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2777 /* Keep initialization in order to enforce 8.5 */
2778 if (stmts && !java_error_count)
2779 TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2782 /* JDK 1.1 instance initializers */
2783 if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2785 stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2786 CPC_INSTANCE_INITIALIZER_LIST (ctxp) =
2787 TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2788 if (stmts && !java_error_count)
2789 TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2793 static tree
2794 reorder_static_initialized (list)
2795 tree list;
2797 /* We have to keep things in order. The alias initializer have to
2798 come first, then the initialized regular field, in reverse to
2799 keep them in lexical order. */
2800 tree marker, previous = NULL_TREE;
2801 for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2802 if (TREE_CODE (marker) == TREE_LIST
2803 && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2804 break;
2806 /* No static initialized, the list is fine as is */
2807 if (!previous)
2808 list = TREE_CHAIN (marker);
2810 /* No marker? reverse the whole list */
2811 else if (!marker)
2812 list = nreverse (list);
2814 /* Otherwise, reverse what's after the marker and the new reordered
2815 sublist will replace the marker. */
2816 else
2818 TREE_CHAIN (previous) = NULL_TREE;
2819 list = nreverse (list);
2820 list = chainon (TREE_CHAIN (marker), list);
2822 return list;
2825 /* Helper functions to dump the parser context stack. */
2827 #define TAB_CONTEXT(C) \
2828 {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2830 static void
2831 java_debug_context_do (tab)
2832 int tab;
2834 struct parser_ctxt *copy = ctxp;
2835 while (copy)
2837 TAB_CONTEXT (tab);
2838 fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2839 TAB_CONTEXT (tab);
2840 fprintf (stderr, "filename: %s\n", copy->filename);
2841 TAB_CONTEXT (tab);
2842 fprintf (stderr, "lineno: %d\n", copy->lineno);
2843 TAB_CONTEXT (tab);
2844 fprintf (stderr, "package: %s\n",
2845 (copy->package ?
2846 IDENTIFIER_POINTER (copy->package) : "<none>"));
2847 TAB_CONTEXT (tab);
2848 fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2849 TAB_CONTEXT (tab);
2850 fprintf (stderr, "saved data: %d\n", copy->saved_data);
2851 copy = copy->next;
2852 tab += 2;
2856 /* Dump the stacked up parser contexts. Intended to be called from a
2857 debugger. */
2859 void
2860 java_debug_context ()
2862 java_debug_context_do (0);
2867 /* Flag for the error report routine to issue the error the first time
2868 it's called (overriding the default behavior which is to drop the
2869 first invocation and honor the second one, taking advantage of a
2870 richer context. */
2871 static int force_error = 0;
2873 /* Reporting an constructor invocation error. */
2874 static void
2875 parse_ctor_invocation_error ()
2877 if (DECL_CONSTRUCTOR_P (current_function_decl))
2878 yyerror ("Constructor invocation must be first thing in a constructor");
2879 else
2880 yyerror ("Only constructors can invoke constructors");
2883 /* Reporting JDK1.1 features not implemented. */
2885 static tree
2886 parse_jdk1_1_error (msg)
2887 const char *msg;
2889 sorry (": `%s' JDK1.1(TM) feature", msg);
2890 java_error_count++;
2891 return empty_stmt_node;
2894 static int do_warning = 0;
2896 void
2897 yyerror (msg)
2898 const char *msg;
2900 static java_lc elc;
2901 static int prev_lineno;
2902 static const char *prev_msg;
2904 int save_lineno;
2905 char *remainder, *code_from_source;
2906 extern struct obstack temporary_obstack;
2908 if (!force_error && prev_lineno == lineno)
2909 return;
2911 /* Save current error location but report latter, when the context is
2912 richer. */
2913 if (ctxp->java_error_flag == 0)
2915 ctxp->java_error_flag = 1;
2916 elc = ctxp->elc;
2917 /* Do something to use the previous line if we're reaching the
2918 end of the file... */
2919 #ifdef VERBOSE_SKELETON
2920 printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2921 #endif
2922 return;
2925 /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2926 if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2927 return;
2929 ctxp->java_error_flag = 0;
2930 if (do_warning)
2931 java_warning_count++;
2932 else
2933 java_error_count++;
2935 if (elc.col == 0 && msg && msg[1] == ';')
2937 elc.col = ctxp->p_line->char_col-1;
2938 elc.line = ctxp->p_line->lineno;
2941 save_lineno = lineno;
2942 prev_lineno = lineno = elc.line;
2943 prev_msg = msg;
2945 code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2946 obstack_grow0 (&temporary_obstack,
2947 code_from_source, strlen (code_from_source));
2948 remainder = obstack_finish (&temporary_obstack);
2949 if (do_warning)
2950 warning ("%s.\n%s", msg, remainder);
2951 else
2952 error ("%s.\n%s", msg, remainder);
2954 /* This allow us to cheaply avoid an extra 'Invalid expression
2955 statement' error report when errors have been already reported on
2956 the same line. This occurs when we report an error but don't have
2957 a synchronization point other than ';', which
2958 expression_statement is the only one to take care of. */
2959 ctxp->prevent_ese = lineno = save_lineno;
2962 static void
2963 issue_warning_error_from_context (cl, msg, ap)
2964 tree cl;
2965 const char *msg;
2966 va_list ap;
2968 char *saved, *saved_input_filename;
2969 char buffer [4096];
2970 vsprintf (buffer, msg, ap);
2971 force_error = 1;
2973 ctxp->elc.line = EXPR_WFL_LINENO (cl);
2974 ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 :
2975 (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
2977 /* We have a CL, that's a good reason for using it if it contains data */
2978 saved = ctxp->filename;
2979 if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
2980 ctxp->filename = EXPR_WFL_FILENAME (cl);
2981 saved_input_filename = input_filename;
2982 input_filename = ctxp->filename;
2983 java_error (NULL);
2984 java_error (buffer);
2985 ctxp->filename = saved;
2986 input_filename = saved_input_filename;
2987 force_error = 0;
2990 /* Issue an error message at a current source line CL */
2992 void
2993 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
2995 #ifndef ANSI_PROTOTYPES
2996 tree cl;
2997 const char *msg;
2998 #endif
2999 va_list ap;
3001 VA_START (ap, msg);
3002 #ifndef ANSI_PROTOTYPES
3003 cl = va_arg (ap, tree);
3004 msg = va_arg (ap, const char *);
3005 #endif
3006 issue_warning_error_from_context (cl, msg, ap);
3007 va_end (ap);
3010 /* Issue a warning at a current source line CL */
3012 static void
3013 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3015 #ifndef ANSI_PROTOTYPES
3016 tree cl;
3017 const char *msg;
3018 #endif
3019 va_list ap;
3021 VA_START (ap, msg);
3022 #ifndef ANSI_PROTOTYPES
3023 cl = va_arg (ap, tree);
3024 msg = va_arg (ap, const char *);
3025 #endif
3027 force_error = do_warning = 1;
3028 issue_warning_error_from_context (cl, msg, ap);
3029 do_warning = force_error = 0;
3030 va_end (ap);
3033 static tree
3034 find_expr_with_wfl (node)
3035 tree node;
3037 while (node)
3039 char code;
3040 tree to_return;
3042 switch (TREE_CODE (node))
3044 case BLOCK:
3045 node = BLOCK_EXPR_BODY (node);
3046 continue;
3048 case COMPOUND_EXPR:
3049 to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3050 if (to_return)
3051 return to_return;
3052 node = TREE_OPERAND (node, 1);
3053 continue;
3055 case LOOP_EXPR:
3056 node = TREE_OPERAND (node, 0);
3057 continue;
3059 case LABELED_BLOCK_EXPR:
3060 node = TREE_OPERAND (node, 1);
3061 continue;
3063 default:
3064 code = TREE_CODE_CLASS (TREE_CODE (node));
3065 if (((code == '1') || (code == '2') || (code == 'e'))
3066 && EXPR_WFL_LINECOL (node))
3067 return node;
3068 return NULL_TREE;
3071 return NULL_TREE;
3074 /* Issue a missing return statement error. Uses METHOD to figure the
3075 last line of the method the error occurs in. */
3077 static void
3078 missing_return_error (method)
3079 tree method;
3081 EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3082 parse_error_context (wfl_operator, "Missing return statement");
3085 /* Issue an unreachable statement error. From NODE, find the next
3086 statement to report appropriately. */
3087 static void
3088 unreachable_stmt_error (node)
3089 tree node;
3091 /* Browse node to find the next expression node that has a WFL. Use
3092 the location to report the error */
3093 if (TREE_CODE (node) == COMPOUND_EXPR)
3094 node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3095 else
3096 node = find_expr_with_wfl (node);
3098 if (node)
3100 EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3101 parse_error_context (wfl_operator, "Unreachable statement");
3103 else
3104 fatal ("Can't get valid statement - unreachable_stmt_error");
3108 java_report_errors ()
3110 if (java_error_count)
3111 fprintf (stderr, "%d error%s",
3112 java_error_count, (java_error_count == 1 ? "" : "s"));
3113 if (java_warning_count)
3114 fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3115 java_warning_count, (java_warning_count == 1 ? "" : "s"));
3116 if (java_error_count || java_warning_count)
3117 putc ('\n', stderr);
3118 return java_error_count;
3121 static char *
3122 java_accstring_lookup (flags)
3123 int flags;
3125 static char buffer [80];
3126 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3128 /* Access modifier looked-up first for easier report on forbidden
3129 access. */
3130 if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3131 if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3132 if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3133 if (flags & ACC_STATIC) COPY_RETURN ("static");
3134 if (flags & ACC_FINAL) COPY_RETURN ("final");
3135 if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3136 if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3137 if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3138 if (flags & ACC_NATIVE) COPY_RETURN ("native");
3139 if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3140 if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3142 buffer [0] = '\0';
3143 return buffer;
3144 #undef COPY_RETURN
3147 /* Issuing error messages upon redefinition of classes, interfaces or
3148 variables. */
3150 static void
3151 classitf_redefinition_error (context, id, decl, cl)
3152 const char *context;
3153 tree id, decl, cl;
3155 parse_error_context (cl, "%s `%s' already defined in %s:%d",
3156 context, IDENTIFIER_POINTER (id),
3157 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3158 /* Here we should point out where its redefined. It's a unicode. FIXME */
3161 static void
3162 variable_redefinition_error (context, name, type, line)
3163 tree context, name, type;
3164 int line;
3166 const char *type_name;
3168 /* Figure a proper name for type. We might haven't resolved it */
3169 if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3170 type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3171 else
3172 type_name = lang_printable_name (type, 0);
3174 parse_error_context (context,
3175 "Variable `%s' is already defined in this method and was declared `%s %s' at line %d",
3176 IDENTIFIER_POINTER (name),
3177 type_name, IDENTIFIER_POINTER (name), line);
3180 static tree
3181 build_array_from_name (type, type_wfl, name, ret_name)
3182 tree type, type_wfl, name, *ret_name;
3184 int more_dims = 0;
3185 const char *string;
3187 /* Eventually get more dims */
3188 string = IDENTIFIER_POINTER (name);
3189 while (string [more_dims] == '[')
3190 more_dims++;
3192 /* If we have, then craft a new type for this variable */
3193 if (more_dims)
3195 name = get_identifier (&string [more_dims]);
3197 /* If we have a pointer, use its type */
3198 if (TREE_CODE (type) == POINTER_TYPE)
3199 type = TREE_TYPE (type);
3201 /* Building the first dimension of a primitive type uses this
3202 function */
3203 if (JPRIMITIVE_TYPE_P (type))
3205 type = build_java_array_type (type, -1);
3206 CLASS_LOADED_P (type) = 1;
3207 more_dims--;
3209 /* Otherwise, if we have a WFL for this type, use it (the type
3210 is already an array on an unresolved type, and we just keep
3211 on adding dimensions) */
3212 else if (type_wfl)
3213 type = type_wfl;
3215 /* Add all the dimensions */
3216 while (more_dims--)
3217 type = build_unresolved_array_type (type);
3219 /* The type may have been incomplete in the first place */
3220 if (type_wfl)
3221 type = obtain_incomplete_type (type);
3224 if (ret_name)
3225 *ret_name = name;
3226 return type;
3229 /* Build something that the type identifier resolver will identify as
3230 being an array to an unresolved type. TYPE_WFL is a WFL on a
3231 identifier. */
3233 static tree
3234 build_unresolved_array_type (type_or_wfl)
3235 tree type_or_wfl;
3237 const char *ptr;
3239 /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3240 just create a array type */
3241 if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3243 tree type = build_java_array_type (type_or_wfl, -1);
3244 CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
3245 return type;
3248 obstack_1grow (&temporary_obstack, '[');
3249 obstack_grow0 (&temporary_obstack,
3250 IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3251 IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3252 ptr = obstack_finish (&temporary_obstack);
3253 return build_expr_wfl (get_identifier (ptr),
3254 EXPR_WFL_FILENAME (type_or_wfl),
3255 EXPR_WFL_LINENO (type_or_wfl),
3256 EXPR_WFL_COLNO (type_or_wfl));
3259 static void
3260 parser_add_interface (class_decl, interface_decl, wfl)
3261 tree class_decl, interface_decl, wfl;
3263 if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3264 parse_error_context (wfl, "Interface `%s' repeated",
3265 IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3268 /* Bulk of common class/interface checks. Return 1 if an error was
3269 encountered. TAG is 0 for a class, 1 for an interface. */
3271 static int
3272 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3273 int is_interface, flags;
3274 tree raw_name, qualified_name, decl, cl;
3276 tree node;
3277 int sca = 0; /* Static class allowed */
3278 int icaf = 0; /* Inner class allowed flags */
3279 int uaaf = CLASS_MODIFIERS; /* Usually allowed access flags */
3281 if (!quiet_flag)
3282 fprintf (stderr, " %s%s %s",
3283 (CPC_INNER_P () ? "inner" : ""),
3284 (is_interface ? "interface" : "class"),
3285 IDENTIFIER_POINTER (qualified_name));
3287 /* Scope of an interface/class type name:
3288 - Can't be imported by a single type import
3289 - Can't already exists in the package */
3290 if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3291 && (node = find_name_in_single_imports (raw_name)))
3293 parse_error_context
3294 (cl, "%s name `%s' clashes with imported type `%s'",
3295 (is_interface ? "Interface" : "Class"),
3296 IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3297 return 1;
3299 if (decl && CLASS_COMPLETE_P (decl))
3301 classitf_redefinition_error ((is_interface ? "Interface" : "Class"),
3302 qualified_name, decl, cl);
3303 return 1;
3306 if (check_inner_class_redefinition (raw_name, cl))
3307 return 1;
3309 /* If public, file name should match class/interface name, except
3310 when dealing with an inner class */
3311 if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3313 const char *f;
3315 /* Contains OS dependent assumption on path separator. FIXME */
3316 for (f = &input_filename [strlen (input_filename)];
3317 f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3318 f--)
3320 if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3321 f++;
3322 if (strncmp (IDENTIFIER_POINTER (raw_name),
3323 f , IDENTIFIER_LENGTH (raw_name)) ||
3324 f [IDENTIFIER_LENGTH (raw_name)] != '.')
3325 parse_error_context
3326 (cl, "Public %s `%s' must be defined in a file called `%s.java'",
3327 (is_interface ? "interface" : "class"),
3328 IDENTIFIER_POINTER (qualified_name),
3329 IDENTIFIER_POINTER (raw_name));
3332 /* Static classes can be declared only in top level classes. Note:
3333 once static, a inner class is a top level class. */
3334 if (flags & ACC_STATIC)
3336 /* Catch the specific error of declaring an class inner class
3337 with no toplevel enclosing class. Prevent check_modifiers from
3338 complaining a second time */
3339 if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3341 parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes",
3342 IDENTIFIER_POINTER (qualified_name));
3343 sca = ACC_STATIC;
3345 /* Else, in the context of a top-level class declaration, let
3346 `check_modifiers' do its job, otherwise, give it a go */
3347 else
3348 sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3351 /* Inner classes can be declared private or protected
3352 within their enclosing classes. */
3353 if (CPC_INNER_P ())
3355 /* A class which is local to a block can't be public, private,
3356 protected or static. But it is created final, so allow this
3357 one. */
3358 if (current_function_decl)
3359 icaf = sca = uaaf = ACC_FINAL;
3360 else
3362 check_modifiers_consistency (flags);
3363 icaf = ACC_PRIVATE|ACC_PROTECTED;
3367 if (is_interface)
3369 if (CPC_INNER_P ())
3370 uaaf = INTERFACE_INNER_MODIFIERS;
3371 else
3372 uaaf = INTERFACE_MODIFIERS;
3374 check_modifiers ("Illegal modifier `%s' for interface declaration",
3375 flags, uaaf);
3377 else
3378 check_modifiers ((current_function_decl ?
3379 "Illegal modifier `%s' for local class declaration" :
3380 "Illegal modifier `%s' for class declaration"),
3381 flags, uaaf|sca|icaf);
3382 return 0;
3385 static void
3386 make_nested_class_name (cpc_list)
3387 tree cpc_list;
3389 tree name;
3391 if (!cpc_list)
3392 return;
3393 else
3394 make_nested_class_name (TREE_CHAIN (cpc_list));
3396 /* Pick the qualified name when dealing with the first upmost
3397 enclosing class */
3398 name = (TREE_CHAIN (cpc_list) ?
3399 TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3400 obstack_grow (&temporary_obstack,
3401 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3402 /* Why is NO_DOLLAR_IN_LABEL defined? */
3403 #if 0
3404 #ifdef NO_DOLLAR_IN_LABEL
3405 fatal ("make_nested_class_name: Can't use '$' as a separator "
3406 "for inner classes");
3407 #endif
3408 #endif
3409 obstack_1grow (&temporary_obstack, '$');
3412 /* Can't redefine a class already defined in an earlier scope. */
3414 static int
3415 check_inner_class_redefinition (raw_name, cl)
3416 tree raw_name, cl;
3418 tree scope_list;
3420 for (scope_list = GET_CPC_LIST (); scope_list;
3421 scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3422 if (raw_name == GET_CPC_UN_NODE (scope_list))
3424 parse_error_context
3425 (cl, "The class name `%s' is already defined in this scope. An inner class may not have the same simple name as any of its enclosing classes",
3426 IDENTIFIER_POINTER (raw_name));
3427 return 1;
3429 return 0;
3432 static tree
3433 find_as_inner_class (enclosing, name, cl)
3434 tree enclosing, name, cl;
3436 tree qual, to_return;
3437 if (!enclosing)
3438 return NULL_TREE;
3440 name = TYPE_NAME (name);
3442 /* First search: within the scope of `enclosing', search for name */
3443 if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3444 qual = EXPR_WFL_QUALIFICATION (cl);
3445 else if (cl)
3446 qual = build_tree_list (cl, NULL_TREE);
3447 else
3448 qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3450 if ((to_return = find_as_inner_class_do (qual, enclosing)))
3451 return to_return;
3453 /* We're dealing with a qualified name. Try to resolve thing until
3454 we get something that is an enclosing class. */
3455 if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3457 tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3459 for(qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl;
3460 qual = TREE_CHAIN (qual))
3462 acc = merge_qualified_name (acc,
3463 EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3464 BUILD_PTR_FROM_NAME (ptr, acc);
3465 decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3468 /* A NULL qual and a decl means that the search ended
3469 successfully?!? We have to do something then. FIXME */
3471 if (decl)
3472 enclosing = decl;
3473 else
3474 qual = EXPR_WFL_QUALIFICATION (cl);
3476 /* Otherwise, create a qual for the other part of the resolution. */
3477 else
3478 qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3480 return find_as_inner_class_do (qual, enclosing);
3483 /* We go inside the list of sub classes and try to find a way
3484 through. */
3486 static tree
3487 find_as_inner_class_do (qual, enclosing)
3488 tree qual, enclosing;
3490 if (!qual)
3491 return NULL_TREE;
3493 for (; qual && enclosing; qual = TREE_CHAIN (qual))
3495 tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3496 tree next_enclosing = NULL_TREE;
3497 tree inner_list;
3499 for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3500 inner_list; inner_list = TREE_CHAIN (inner_list))
3502 if (TREE_VALUE (inner_list) == name_to_match)
3504 next_enclosing = TREE_PURPOSE (inner_list);
3505 break;
3508 enclosing = next_enclosing;
3511 return (!qual && enclosing ? enclosing : NULL_TREE);
3514 /* Reach all inner classes and tie their unqualified name to a
3515 DECL. */
3517 static void
3518 set_nested_class_simple_name_value (outer, set)
3519 tree outer;
3520 int set;
3522 tree l;
3524 for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3525 IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ?
3526 TREE_PURPOSE (l) : NULL_TREE);
3529 static void
3530 link_nested_class_to_enclosing ()
3532 if (GET_ENCLOSING_CPC ())
3534 tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3535 DECL_INNER_CLASS_LIST (enclosing) =
3536 tree_cons (GET_CPC (), GET_CPC_UN (),
3537 DECL_INNER_CLASS_LIST (enclosing));
3538 enclosing = enclosing;
3542 static tree
3543 maybe_make_nested_class_name (name)
3544 tree name;
3546 tree id = NULL_TREE;
3548 if (CPC_INNER_P ())
3550 make_nested_class_name (GET_CPC_LIST ());
3551 obstack_grow0 (&temporary_obstack,
3552 IDENTIFIER_POINTER (name),
3553 IDENTIFIER_LENGTH (name));
3554 id = get_identifier (obstack_finish (&temporary_obstack));
3555 if (ctxp->package)
3556 QUALIFIED_P (id) = 1;
3558 return id;
3561 /* If DECL is NULL, create and push a new DECL, record the current
3562 line CL and do other maintenance things. */
3564 static tree
3565 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3566 tree decl, raw_name, qualified_name, cl;
3568 if (!decl)
3569 decl = push_class (make_class (), qualified_name);
3571 /* Take care of the file and line business */
3572 DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3573 /* If we're emiting xrefs, store the line/col number information */
3574 if (flag_emit_xref)
3575 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3576 else
3577 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3578 CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3579 CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
3580 IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3582 PUSH_CPC (decl, raw_name);
3583 DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3585 /* Link the declaration to the already seen ones */
3586 TREE_CHAIN (decl) = ctxp->class_list;
3587 ctxp->class_list = decl;
3589 /* Create a new nodes in the global lists */
3590 ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
3591 all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3593 /* Install a new dependency list element */
3594 create_jdep_list (ctxp);
3596 SOURCE_FRONTEND_DEBUG (("Defining class/interface %s",
3597 IDENTIFIER_POINTER (qualified_name)));
3598 return decl;
3601 static void
3602 add_superinterfaces (decl, interface_list)
3603 tree decl, interface_list;
3605 tree node;
3606 /* Superinterface(s): if present and defined, parser_check_super_interface ()
3607 takes care of ensuring that:
3608 - This is an accessible interface type,
3609 - Circularity detection.
3610 parser_add_interface is then called. If present but not defined,
3611 the check operation is delayed until the super interface gets
3612 defined. */
3613 for (node = interface_list; node; node = TREE_CHAIN (node))
3615 tree current = TREE_PURPOSE (node);
3616 tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3617 if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3619 if (!parser_check_super_interface (idecl, decl, current))
3620 parser_add_interface (decl, idecl, current);
3622 else
3623 register_incomplete_type (JDEP_INTERFACE,
3624 current, decl, NULL_TREE);
3628 /* Create an interface in pass1 and return its decl. Return the
3629 interface's decl in pass 2. */
3631 static tree
3632 create_interface (flags, id, super)
3633 int flags;
3634 tree id, super;
3636 tree raw_name = EXPR_WFL_NODE (id);
3637 tree q_name = parser_qualified_classname (flags & ACC_STATIC, raw_name);
3638 tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3640 EXPR_WFL_NODE (id) = q_name; /* Keep source location, even if refined. */
3642 /* Basic checks: scope, redefinition, modifiers */
3643 if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3645 PUSH_ERROR ();
3646 return NULL_TREE;
3649 /* Suspend the current parsing context if we're parsing an inner
3650 interface */
3651 if (CPC_INNER_P ())
3652 java_parser_context_suspend ();
3654 /* Push a new context for (static) initialized upon declaration fields */
3655 java_parser_context_push_initialized_field ();
3657 /* Interface modifiers check
3658 - public/abstract allowed (already done at that point)
3659 - abstract is obsolete (comes first, it's a warning, or should be)
3660 - Can't use twice the same (checked in the modifier rule) */
3661 if ((flags & ACC_ABSTRACT) && flag_redundant)
3662 parse_warning_context
3663 (MODIFIER_WFL (ABSTRACT_TK),
3664 "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3666 /* Create a new decl if DECL is NULL, otherwise fix it */
3667 decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3669 /* Set super info and mark the class a complete */
3670 set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl),
3671 object_type_node, ctxp->interface_number);
3672 ctxp->interface_number = 0;
3673 CLASS_COMPLETE_P (decl) = 1;
3674 add_superinterfaces (decl, super);
3676 return decl;
3679 /* Anonymous class counter. Will be reset to 1 every time a non
3680 anonymous class gets created. */
3681 static int anonymous_class_counter = 1;
3683 /* Patch anonymous class CLASS, by either extending or implementing
3684 DEP. */
3686 static void
3687 patch_anonymous_class (type_decl, class_decl, wfl)
3688 tree type_decl, class_decl, wfl;
3690 tree class = TREE_TYPE (class_decl);
3691 tree type = TREE_TYPE (type_decl);
3692 tree binfo = TYPE_BINFO (class);
3694 /* If it's an interface, implement it */
3695 if (CLASS_INTERFACE (type_decl))
3697 tree s_binfo;
3698 int length;
3700 if (parser_check_super_interface (type_decl, class_decl, wfl))
3701 return;
3703 s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3704 length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3705 TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3706 TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3707 /* And add the interface */
3708 parser_add_interface (class_decl, type_decl, wfl);
3710 /* Otherwise, it's a type we want to extend */
3711 else
3713 if (parser_check_super (type_decl, class_decl, wfl))
3714 return;
3715 BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3719 static tree
3720 create_anonymous_class (location, type_name)
3721 int location;
3722 tree type_name;
3724 char buffer [80];
3725 tree super = NULL_TREE, itf = NULL_TREE;
3726 tree id, type_decl, class;
3728 /* The unqualified name of the anonymous class. It's just a number. */
3729 sprintf (buffer, "%d", anonymous_class_counter++);
3730 id = build_wfl_node (get_identifier (buffer));
3731 EXPR_WFL_LINECOL (id) = location;
3733 /* We know about the type to extend/implement. We go ahead */
3734 if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3736 /* Create a class which either implements on extends the designated
3737 class. The class bears an innacessible name. */
3738 if (CLASS_INTERFACE (type_decl))
3740 /* It's OK to modify it here. It's been already used and
3741 shouldn't be reused */
3742 ctxp->interface_number = 1;
3743 /* Interfaces should presented as a list of WFLs */
3744 itf = build_tree_list (type_name, NULL_TREE);
3746 else
3747 super = type_name;
3750 class = create_class (ACC_FINAL, id, super, itf);
3752 /* We didn't know anything about the stuff. We register a dependence. */
3753 if (!type_decl)
3754 register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3756 ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3757 return class;
3760 /* Create a class in pass1 and return its decl. Return class
3761 interface's decl in pass 2. */
3763 static tree
3764 create_class (flags, id, super, interfaces)
3765 int flags;
3766 tree id, super, interfaces;
3768 tree raw_name = EXPR_WFL_NODE (id);
3769 tree class_id, decl;
3770 tree super_decl_type;
3772 class_id = parser_qualified_classname (0, raw_name);
3773 decl = IDENTIFIER_CLASS_VALUE (class_id);
3774 EXPR_WFL_NODE (id) = class_id;
3776 /* Basic check: scope, redefinition, modifiers */
3777 if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3779 PUSH_ERROR ();
3780 return NULL_TREE;
3783 /* Suspend the current parsing context if we're parsing an inner
3784 class or an anonymous class. */
3785 if (CPC_INNER_P ())
3786 java_parser_context_suspend ();
3787 /* Push a new context for (static) initialized upon declaration fields */
3788 java_parser_context_push_initialized_field ();
3790 /* Class modifier check:
3791 - Allowed modifier (already done at that point)
3792 - abstract AND final forbidden
3793 - Public classes defined in the correct file */
3794 if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3795 parse_error_context
3796 (id, "Class `%s' can't be declared both abstract and final",
3797 IDENTIFIER_POINTER (raw_name));
3799 /* Create a new decl if DECL is NULL, otherwise fix it */
3800 decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3802 /* If SUPER exists, use it, otherwise use Object */
3803 if (super)
3805 /* Can't extend java.lang.Object */
3806 if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3808 parse_error_context (id, "Can't extend `java.lang.Object'");
3809 return NULL_TREE;
3812 super_decl_type =
3813 register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3815 else if (TREE_TYPE (decl) != object_type_node)
3816 super_decl_type = object_type_node;
3817 /* We're defining java.lang.Object */
3818 else
3819 super_decl_type = NULL_TREE;
3821 /* Set super info and mark the class a complete */
3822 set_super_info (flags, TREE_TYPE (decl), super_decl_type,
3823 ctxp->interface_number);
3824 ctxp->interface_number = 0;
3825 CLASS_COMPLETE_P (decl) = 1;
3826 add_superinterfaces (decl, interfaces);
3828 /* If the class is a top level inner class, install an alias. */
3829 if (INNER_CLASS_DECL_P (decl) && CLASS_STATIC (decl))
3831 tree alias = parser_qualified_classname (1, raw_name);
3832 IDENTIFIER_GLOBAL_VALUE (alias) = decl;
3835 /* Add the private this$<n> field, Replicate final locals still in
3836 scope as private final fields mangled like val$<local_name>.
3837 This doesn't not occur for top level (static) inner classes. */
3838 if (PURE_INNER_CLASS_DECL_P (decl))
3839 add_inner_class_fields (decl, current_function_decl);
3841 /* If doing xref, store the location at which the inherited class
3842 (if any) was seen. */
3843 if (flag_emit_xref && super)
3844 DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3846 /* Eventually sets the @deprecated tag flag */
3847 CHECK_DEPRECATED (decl);
3849 /* Reset the anonymous class counter when declaring non inner classes */
3850 if (!INNER_CLASS_DECL_P (decl))
3851 anonymous_class_counter = 1;
3853 return decl;
3856 /* End a class declaration: register the statements used to create
3857 $finit$ and <clinit>, pop the current class and resume the prior
3858 parser context if necessary. */
3860 static void
3861 end_class_declaration (resume)
3862 int resume;
3864 /* If an error occured, context weren't pushed and won't need to be
3865 popped by a resume. */
3866 int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
3868 java_parser_context_pop_initialized_field ();
3869 POP_CPC ();
3870 if (resume && no_error_occured)
3871 java_parser_context_resume ();
3873 /* We're ending a class declaration, this is a good time to reset
3874 the interface cout. Note that might have been already done in
3875 create_interface, but if at that time an inner class was being
3876 dealt with, the interface count was reset in a context created
3877 for the sake of handling inner classes declaration. */
3878 ctxp->interface_number = 0;
3881 static void
3882 add_inner_class_fields (class_decl, fct_decl)
3883 tree class_decl;
3884 tree fct_decl;
3886 tree block, marker, f;
3888 f = add_field (TREE_TYPE (class_decl),
3889 build_current_thisn (TREE_TYPE (class_decl)),
3890 build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))),
3891 ACC_PRIVATE);
3892 FIELD_THISN (f) = 1;
3894 if (!fct_decl)
3895 return;
3897 for (block = GET_CURRENT_BLOCK (fct_decl);
3898 block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
3900 tree decl;
3901 for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
3903 char *name, *pname;
3904 tree wfl, init, list;
3906 /* Avoid non final arguments. */
3907 if (!LOCAL_FINAL (decl))
3908 continue;
3910 MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
3911 MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
3912 wfl = build_wfl_node (get_identifier (name));
3913 init = build_wfl_node (get_identifier (pname));
3914 /* Build an initialization for the field: it will be
3915 initialized by a parameter added to $finit$, bearing a
3916 mangled name of the field itself (param$<n>.) The
3917 parameter is provided to $finit$ by the constructor
3918 invoking it (hence the constructor will also feature a
3919 hidden parameter, set to the value of the outer context
3920 local at the time the inner class is created.)
3922 Note: we take into account all possible locals that can
3923 be accessed by the inner class. It's actually not trivial
3924 to minimize these aliases down to the ones really
3925 used. One way to do that would be to expand all regular
3926 methods first, then $finit$ to get a picture of what's
3927 used. It works with the exception that we would have to
3928 go back on all constructor invoked in regular methods to
3929 have their invokation reworked (to include the right amount
3930 of alias initializer parameters.)
3932 The only real way around, I think, is a first pass to
3933 identify locals really used in the inner class. We leave
3934 the flag FIELD_LOCAL_ALIAS_USED around for that future
3935 use.
3937 On the other hand, it only affect local inner classes,
3938 whose constructors (and $finit$ call) will be featuring
3939 unecessary arguments. It's easy for a developper to keep
3940 this number of parameter down by using the `final'
3941 keyword only when necessary. For the time being, we can
3942 issue a warning on unecessary finals. FIXME */
3943 init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl),
3944 wfl, init);
3946 /* Register the field. The TREE_LIST holding the part
3947 initialized/initializer will be marked ARG_FINAL_P so
3948 that the created field can be marked
3949 FIELD_LOCAL_ALIAS. */
3950 list = build_tree_list (wfl, init);
3951 ARG_FINAL_P (list) = 1;
3952 register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
3956 if (!CPC_INITIALIZER_STMT (ctxp))
3957 return;
3959 /* If we ever registered an alias field, insert and marker to
3960 remeber where the list ends. The second part of the list (the one
3961 featuring initialized fields) so it can be later reversed to
3962 enforce 8.5. The marker will be removed during that operation. */
3963 marker = build_tree_list (NULL_TREE, NULL_TREE);
3964 TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
3965 SET_CPC_INITIALIZER_STMT (ctxp, marker);
3968 /* Can't use lookup_field () since we don't want to load the class and
3969 can't set the CLASS_LOADED_P flag */
3971 static tree
3972 find_field (class, name)
3973 tree class;
3974 tree name;
3976 tree decl;
3977 for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
3979 if (DECL_NAME (decl) == name)
3980 return decl;
3982 return NULL_TREE;
3985 /* Wrap around lookup_field that doesn't potentially upset the value
3986 of CLASS */
3988 static tree
3989 lookup_field_wrapper (class, name)
3990 tree class, name;
3992 tree type = class;
3993 tree decl;
3994 java_parser_context_save_global ();
3995 decl = lookup_field (&type, name);
3997 /* Last chance: if we're within the context of an inner class, we
3998 might be trying to access a local variable defined in an outer
3999 context. We try to look for it now. */
4000 if (INNER_CLASS_TYPE_P (class) && (!decl || decl == error_mark_node))
4002 char *alias_buffer;
4003 MANGLE_OUTER_LOCAL_VARIABLE_NAME (alias_buffer, name);
4004 name = get_identifier (alias_buffer);
4005 type = class;
4006 decl = lookup_field (&type, name);
4007 if (decl && decl != error_mark_node)
4008 FIELD_LOCAL_ALIAS_USED (decl) = 1;
4011 java_parser_context_restore_global ();
4012 return decl == error_mark_node ? NULL : decl;
4015 /* Find duplicate field within the same class declarations and report
4016 the error. Returns 1 if a duplicated field was found, 0
4017 otherwise. */
4019 static int
4020 duplicate_declaration_error_p (new_field_name, new_type, cl)
4021 tree new_field_name, new_type, cl;
4023 /* This might be modified to work with method decl as well */
4024 tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4025 if (decl)
4027 char *t1 = xstrdup (purify_type_name
4028 ((TREE_CODE (new_type) == POINTER_TYPE
4029 && TREE_TYPE (new_type) == NULL_TREE) ?
4030 IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4031 lang_printable_name (new_type, 1)));
4032 /* The type may not have been completed by the time we report
4033 the error */
4034 char *t2 = xstrdup (purify_type_name
4035 ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
4036 && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4037 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4038 lang_printable_name (TREE_TYPE (decl), 1)));
4039 parse_error_context
4040 (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)",
4041 t1, IDENTIFIER_POINTER (new_field_name),
4042 t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4043 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4044 free (t1);
4045 free (t2);
4046 return 1;
4048 return 0;
4051 /* Field registration routine. If TYPE doesn't exist, field
4052 declarations are linked to the undefined TYPE dependency list, to
4053 be later resolved in java_complete_class () */
4055 static void
4056 register_fields (flags, type, variable_list)
4057 int flags;
4058 tree type, variable_list;
4060 tree current, saved_type;
4061 tree class_type = NULL_TREE;
4062 int saved_lineno = lineno;
4063 int must_chain = 0;
4064 tree wfl = NULL_TREE;
4066 if (GET_CPC ())
4067 class_type = TREE_TYPE (GET_CPC ());
4069 if (!class_type || class_type == error_mark_node)
4070 return;
4072 /* If we're adding fields to interfaces, those fields are public,
4073 static, final */
4074 if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4076 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4077 flags, ACC_PUBLIC, "interface field(s)");
4078 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4079 flags, ACC_STATIC, "interface field(s)");
4080 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4081 flags, ACC_FINAL, "interface field(s)");
4082 check_modifiers ("Illegal interface member modifier `%s'", flags,
4083 INTERFACE_FIELD_MODIFIERS);
4084 flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4087 /* Obtain a suitable type for resolution, if necessary */
4088 SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4090 /* If TYPE is fully resolved and we don't have a reference, make one */
4091 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4093 for (current = variable_list, saved_type = type; current;
4094 current = TREE_CHAIN (current), type = saved_type)
4096 tree real_type;
4097 tree field_decl;
4098 tree cl = TREE_PURPOSE (current);
4099 tree init = TREE_VALUE (current);
4100 tree current_name = EXPR_WFL_NODE (cl);
4102 /* Can't declare static fields in inner classes */
4103 if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4104 && !CLASS_INTERFACE (TYPE_NAME (class_type)))
4105 parse_error_context
4106 (cl, "Field `%s' can't be static in innerclass `%s'. Only members of interfaces and top-level classes can be static",
4107 IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4108 lang_printable_name (class_type, 0));
4110 /* Process NAME, as it may specify extra dimension(s) for it */
4111 type = build_array_from_name (type, wfl, current_name, &current_name);
4113 /* Type adjustment. We may have just readjusted TYPE because
4114 the variable specified more dimensions. Make sure we have
4115 a reference if we can and don't have one already. Also
4116 change the name if we have an init. */
4117 if (type != saved_type)
4119 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4120 if (init)
4121 EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4124 real_type = GET_REAL_TYPE (type);
4125 /* Check for redeclarations */
4126 if (duplicate_declaration_error_p (current_name, real_type, cl))
4127 continue;
4129 /* Set lineno to the line the field was found and create a
4130 declaration for it. Eventually sets the @deprecated tag flag. */
4131 if (flag_emit_xref)
4132 lineno = EXPR_WFL_LINECOL (cl);
4133 else
4134 lineno = EXPR_WFL_LINENO (cl);
4135 field_decl = add_field (class_type, current_name, real_type, flags);
4136 CHECK_DEPRECATED (field_decl);
4138 /* If the couple initializer/initialized is marked ARG_FINAL_P, we
4139 mark the created field FIELD_LOCAL_ALIAS, so that we can
4140 hide parameters to this inner class $finit$ and constructors. */
4141 if (ARG_FINAL_P (current))
4142 FIELD_LOCAL_ALIAS (field_decl) = 1;
4144 /* Check if we must chain. */
4145 if (must_chain)
4146 register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4148 /* If we have an initialization value tied to the field */
4149 if (init)
4151 /* The field is declared static */
4152 if (flags & ACC_STATIC)
4154 /* We include the field and its initialization part into
4155 a list used to generate <clinit>. After <clinit> is
4156 walked, field initializations will be processed and
4157 fields initialized with known constants will be taken
4158 out of <clinit> and have their DECL_INITIAL set
4159 appropriately. */
4160 TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4161 SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4162 if (TREE_OPERAND (init, 1)
4163 && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4164 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4166 /* A non-static field declared with an immediate initialization is
4167 to be initialized in <init>, if any. This field is remembered
4168 to be processed at the time of the generation of <init>. */
4169 else
4171 TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4172 SET_CPC_INITIALIZER_STMT (ctxp, init);
4174 MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4175 DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4178 lineno = saved_lineno;
4181 /* Generate $finit$, using the list of initialized fields to populate
4182 its body. $finit$'s parameter(s) list is adjusted to include the
4183 one(s) used to initialized the field(s) caching outer context
4184 local(s). */
4186 static tree
4187 generate_finit (class_type)
4188 tree class_type;
4190 int count = 0;
4191 tree list = TYPE_FINIT_STMT_LIST (class_type);
4192 tree mdecl, current, parms;
4194 parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
4195 class_type, NULL_TREE,
4196 &count);
4197 CRAFTED_PARAM_LIST_FIXUP (parms);
4198 mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4199 finit_identifier_node, parms);
4200 fix_method_argument_names (parms, mdecl);
4201 layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4202 mdecl, NULL_TREE);
4203 DECL_FUNCTION_NAP (mdecl) = count;
4204 start_artificial_method_body (mdecl);
4206 for (current = list; current; current = TREE_CHAIN (current))
4207 java_method_add_stmt (mdecl,
4208 build_debugable_stmt (EXPR_WFL_LINECOL (current),
4209 current));
4210 end_artificial_method_body (mdecl);
4211 return mdecl;
4214 static void
4215 add_instance_initializer (mdecl)
4216 tree mdecl;
4218 tree current;
4219 tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
4220 tree compound = NULL_TREE;
4222 if (stmt_list)
4224 for (current = stmt_list; current; current = TREE_CHAIN (current))
4225 compound = add_stmt_to_compound (compound, NULL_TREE, current);
4227 java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
4228 NULL_TREE, compound));
4232 /* Shared accros method_declarator and method_header to remember the
4233 patch stage that was reached during the declaration of the method.
4234 A method DECL is built differently is there is no patch
4235 (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4236 pending on the currently defined method. */
4238 static int patch_stage;
4240 /* Check the method declaration and add the method to its current
4241 class. If the argument list is known to contain incomplete types,
4242 the method is partially added and the registration will be resume
4243 once the method arguments resolved. If TYPE is NULL, we're dealing
4244 with a constructor. */
4246 static tree
4247 method_header (flags, type, mdecl, throws)
4248 int flags;
4249 tree type, mdecl, throws;
4251 tree meth = TREE_VALUE (mdecl);
4252 tree id = TREE_PURPOSE (mdecl);
4253 tree type_wfl = NULL_TREE;
4254 tree meth_name = NULL_TREE;
4255 tree current, orig_arg, this_class = NULL;
4256 int saved_lineno;
4257 int constructor_ok = 0, must_chain;
4258 int count;
4260 check_modifiers_consistency (flags);
4262 if (GET_CPC ())
4263 this_class = TREE_TYPE (GET_CPC ());
4265 if (!this_class || this_class == error_mark_node)
4266 return NULL_TREE;
4268 /* There are some forbidden modifiers for an abstract method and its
4269 class must be abstract as well. */
4270 if (type && (flags & ACC_ABSTRACT))
4272 ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4273 ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4274 ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4275 ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4276 ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4277 if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4278 && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4279 parse_error_context
4280 (id, "Class `%s' must be declared abstract to define abstract method `%s'",
4281 IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
4282 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4285 /* Things to be checked when declaring a constructor */
4286 if (!type)
4288 int ec = java_error_count;
4289 /* 8.6: Constructor declarations: we might be trying to define a
4290 method without specifying a return type. */
4291 if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4292 parse_error_context
4293 (id, "Invalid method declaration, return type required");
4294 /* 8.6.3: Constructor modifiers */
4295 else
4297 JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4298 JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4299 JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4300 JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4301 JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4303 /* If we found error here, we don't consider it's OK to tread
4304 the method definition as a constructor, for the rest of this
4305 function */
4306 if (ec == java_error_count)
4307 constructor_ok = 1;
4310 /* Method declared within the scope of an interface are implicitly
4311 abstract and public. Conflicts with other erroneously provided
4312 modifiers are checked right after. */
4314 if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4316 /* If FLAGS isn't set because of a modifier, turn the
4317 corresponding modifier WFL to NULL so we issue a warning on
4318 the obsolete use of the modifier */
4319 if (!(flags & ACC_PUBLIC))
4320 MODIFIER_WFL (PUBLIC_TK) = NULL;
4321 if (!(flags & ACC_ABSTRACT))
4322 MODIFIER_WFL (ABSTRACT_TK) = NULL;
4323 flags |= ACC_PUBLIC;
4324 flags |= ACC_ABSTRACT;
4327 /* Inner class can't declare static methods */
4328 if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4330 parse_error_context
4331 (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4332 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4333 lang_printable_name (this_class, 0));
4336 /* Modifiers context reset moved up, so abstract method declaration
4337 modifiers can be later checked. */
4339 /* Set constructor returned type to void and method name to <init>,
4340 unless we found an error identifier the constructor (in which
4341 case we retain the original name) */
4342 if (!type)
4344 type = void_type_node;
4345 if (constructor_ok)
4346 meth_name = init_identifier_node;
4348 else
4349 meth_name = EXPR_WFL_NODE (id);
4351 /* Do the returned type resolution and registration if necessary */
4352 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4354 if (meth_name)
4355 type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4356 EXPR_WFL_NODE (id) = meth_name;
4357 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4359 if (must_chain)
4361 patch_stage = JDEP_METHOD_RETURN;
4362 register_incomplete_type (patch_stage, type_wfl, id, type);
4363 TREE_TYPE (meth) = GET_REAL_TYPE (type);
4365 else
4366 TREE_TYPE (meth) = type;
4368 saved_lineno = lineno;
4369 /* When defining an abstract or interface method, the curly
4370 bracket at level 1 doesn't exist because there is no function
4371 body */
4372 lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 :
4373 EXPR_WFL_LINENO (id));
4375 /* Remember the original argument list */
4376 orig_arg = TYPE_ARG_TYPES (meth);
4378 if (patch_stage) /* includes ret type and/or all args */
4380 jdep *jdep;
4381 meth = add_method_1 (this_class, flags, meth_name, meth);
4382 /* Patch for the return type */
4383 if (patch_stage == JDEP_METHOD_RETURN)
4385 jdep = CLASSD_LAST (ctxp->classd_list);
4386 JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4388 /* This is the stop JDEP. METH allows the function's signature
4389 to be computed. */
4390 register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4392 else
4393 meth = add_method (this_class, flags, meth_name,
4394 build_java_signature (meth));
4396 /* Remember final parameters */
4397 MARK_FINAL_PARMS (meth, orig_arg);
4399 /* Fix the method argument list so we have the argument name
4400 information */
4401 fix_method_argument_names (orig_arg, meth);
4403 /* Register the parameter number and re-install the current line
4404 number */
4405 DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4406 lineno = saved_lineno;
4408 /* Register exception specified by the `throws' keyword for
4409 resolution and set the method decl appropriate field to the list.
4410 Note: the grammar ensures that what we get here are class
4411 types. */
4412 if (throws)
4414 throws = nreverse (throws);
4415 for (current = throws; current; current = TREE_CHAIN (current))
4417 register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4418 NULL_TREE, NULL_TREE);
4419 JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) =
4420 &TREE_VALUE (current);
4422 DECL_FUNCTION_THROWS (meth) = throws;
4425 /* We set the DECL_NAME to ID so we can track the location where
4426 the function was declared. This allow us to report
4427 redefinition error accurately. When method are verified,
4428 DECL_NAME is reinstalled properly (using the content of the
4429 WFL node ID) (see check_method_redefinition). We don't do that
4430 when Object is being defined. Constructor <init> names will be
4431 reinstalled the same way. */
4432 if (TREE_TYPE (GET_CPC ()) != object_type_node)
4433 DECL_NAME (meth) = id;
4435 /* Set the flag if we correctly processed a constructor */
4436 if (constructor_ok)
4438 DECL_CONSTRUCTOR_P (meth) = 1;
4439 /* Compute and store the number of artificial parameters declared
4440 for this constructor */
4441 for (count = 0, current = TYPE_FIELDS (this_class); current;
4442 current = TREE_CHAIN (current))
4443 if (FIELD_LOCAL_ALIAS (current))
4444 count++;
4445 DECL_FUNCTION_NAP (meth) = count;
4448 /* Eventually set the @deprecated tag flag */
4449 CHECK_DEPRECATED (meth);
4451 /* If doing xref, store column and line number information instead
4452 of the line number only. */
4453 if (flag_emit_xref)
4454 DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4456 return meth;
4459 static void
4460 fix_method_argument_names (orig_arg, meth)
4461 tree orig_arg, meth;
4463 tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4464 if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4466 TREE_PURPOSE (arg) = this_identifier_node;
4467 arg = TREE_CHAIN (arg);
4469 while (orig_arg != end_params_node)
4471 TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4472 orig_arg = TREE_CHAIN (orig_arg);
4473 arg = TREE_CHAIN (arg);
4477 /* Complete the method declaration with METHOD_BODY. */
4479 static void
4480 finish_method_declaration (method_body)
4481 tree method_body;
4483 int flags;
4485 if (!current_function_decl)
4486 return;
4488 flags = get_access_flags_from_decl (current_function_decl);
4490 /* 8.4.5 Method Body */
4491 if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4493 tree wfl = DECL_NAME (current_function_decl);
4494 parse_error_context (wfl,
4495 "%s method `%s' can't have a body defined",
4496 (METHOD_NATIVE (current_function_decl) ?
4497 "Native" : "Abstract"),
4498 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4499 method_body = NULL_TREE;
4501 else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4503 tree wfl = DECL_NAME (current_function_decl);
4504 parse_error_context
4505 (wfl,
4506 "Non native and non abstract method `%s' must have a body defined",
4507 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4508 method_body = NULL_TREE;
4511 if (flag_emit_class_files && method_body
4512 && TREE_CODE (method_body) == NOP_EXPR
4513 && TREE_TYPE (current_function_decl)
4514 && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4515 method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4517 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4518 maybe_absorb_scoping_blocks ();
4519 /* Exit function's body */
4520 exit_block ();
4521 /* Merge last line of the function with first line, directly in the
4522 function decl. It will be used to emit correct debug info. */
4523 if (!flag_emit_xref)
4524 DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4526 /* Since function's argument's list are shared, reset the
4527 ARG_FINAL_P parameter that might have been set on some of this
4528 function parameters. */
4529 UNMARK_FINAL_PARMS (current_function_decl);
4531 /* So we don't have an irrelevant function declaration context for
4532 the next static block we'll see. */
4533 current_function_decl = NULL_TREE;
4536 /* Build a an error message for constructor circularity errors. */
4538 static char *
4539 constructor_circularity_msg (from, to)
4540 tree from, to;
4542 static char string [4096];
4543 char *t = xstrdup (lang_printable_name (from, 0));
4544 sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4545 free (t);
4546 return string;
4549 /* Verify a circular call to METH. Return 1 if an error is found, 0
4550 otherwise. */
4552 static int
4553 verify_constructor_circularity (meth, current)
4554 tree meth, current;
4556 static tree list = NULL_TREE;
4557 tree c;
4558 for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4560 if (TREE_VALUE (c) == meth)
4562 char *t;
4563 if (list)
4565 tree liste;
4566 list = nreverse (list);
4567 for (liste = list; liste; liste = TREE_CHAIN (liste))
4569 parse_error_context
4570 (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4571 constructor_circularity_msg
4572 (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste))));
4573 java_error_count--;
4576 t = xstrdup (lang_printable_name (meth, 0));
4577 parse_error_context (TREE_PURPOSE (c),
4578 "%s: recursive invocation of constructor `%s'",
4579 constructor_circularity_msg (current, meth), t);
4580 free (t);
4581 list = NULL_TREE;
4582 return 1;
4585 for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4587 list = tree_cons (c, current, list);
4588 if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4589 return 1;
4590 list = TREE_CHAIN (list);
4592 return 0;
4595 /* Check modifiers that can be declared but exclusively */
4597 static void
4598 check_modifiers_consistency (flags)
4599 int flags;
4601 int acc_count = 0;
4602 tree cl = NULL_TREE;
4604 THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4605 THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4606 THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4607 if (acc_count > 1)
4608 parse_error_context
4609 (cl, "Inconsistent member declaration. At most one of `public', `private', or `protected' may be specified");
4611 acc_count = 0;
4612 cl = NULL_TREE;
4613 THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK - PUBLIC_TK,
4614 acc_count, cl);
4615 THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK - PUBLIC_TK,
4616 acc_count, cl);
4617 if (acc_count > 1)
4618 parse_error_context (cl,
4619 "Inconsistent member declaration. At most one of `final' or `volatile' may be specified");
4622 /* Check the methode header METH for abstract specifics features */
4624 static void
4625 check_abstract_method_header (meth)
4626 tree meth;
4628 int flags = get_access_flags_from_decl (meth);
4629 /* DECL_NAME might still be a WFL node */
4630 tree name = GET_METHOD_NAME (meth);
4632 OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4633 ACC_ABSTRACT, "abstract method",
4634 IDENTIFIER_POINTER (name));
4635 OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags,
4636 ACC_PUBLIC, "abstract method",
4637 IDENTIFIER_POINTER (name));
4639 check_modifiers ("Illegal modifier `%s' for interface method",
4640 flags, INTERFACE_METHOD_MODIFIERS);
4643 /* Create a FUNCTION_TYPE node and start augmenting it with the
4644 declared function arguments. Arguments type that can't be resolved
4645 are left as they are, but the returned node is marked as containing
4646 incomplete types. */
4648 static tree
4649 method_declarator (id, list)
4650 tree id, list;
4652 tree arg_types = NULL_TREE, current, node;
4653 tree meth = make_node (FUNCTION_TYPE);
4654 jdep *jdep;
4656 patch_stage = JDEP_NO_PATCH;
4658 /* If we're dealing with an inner class constructor, we hide the
4659 this$<n> decl in the name field of its parameter declaration. We
4660 also might have to hide the outer context local alias
4661 initializers. Not done when the class is a toplevel class. */
4662 if (PURE_INNER_CLASS_DECL_P (GET_CPC ())
4663 && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4665 tree aliases_list, type, thisn;
4666 /* First the aliases, linked to the regular parameters */
4667 aliases_list =
4668 build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION,
4669 TREE_TYPE (GET_CPC ()),
4670 NULL_TREE, NULL);
4671 list = chainon (nreverse (aliases_list), list);
4673 /* Then this$<n> */
4674 type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4675 thisn = build_current_thisn (TYPE_NAME (GET_CPC ()));
4676 list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4677 list);
4680 for (current = list; current; current = TREE_CHAIN (current))
4682 int must_chain = 0;
4683 tree wfl_name = TREE_PURPOSE (current);
4684 tree type = TREE_VALUE (current);
4685 tree name = EXPR_WFL_NODE (wfl_name);
4686 tree already, arg_node;
4687 tree type_wfl = NULL_TREE;
4688 tree real_type;
4690 /* Obtain a suitable type for resolution, if necessary */
4691 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4693 /* Process NAME, as it may specify extra dimension(s) for it */
4694 type = build_array_from_name (type, type_wfl, name, &name);
4695 EXPR_WFL_NODE (wfl_name) = name;
4697 real_type = GET_REAL_TYPE (type);
4698 if (TREE_CODE (real_type) == RECORD_TYPE)
4700 real_type = promote_type (real_type);
4701 if (TREE_CODE (type) == TREE_LIST)
4702 TREE_PURPOSE (type) = real_type;
4705 /* Check redefinition */
4706 for (already = arg_types; already; already = TREE_CHAIN (already))
4707 if (TREE_PURPOSE (already) == name)
4709 parse_error_context
4710 (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4711 IDENTIFIER_POINTER (name),
4712 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4713 break;
4716 /* If we've an incomplete argument type, we know there is a location
4717 to patch when the type get resolved, later. */
4718 jdep = NULL;
4719 if (must_chain)
4721 patch_stage = JDEP_METHOD;
4722 type = register_incomplete_type (patch_stage,
4723 type_wfl, wfl_name, type);
4724 jdep = CLASSD_LAST (ctxp->classd_list);
4725 JDEP_MISC (jdep) = id;
4728 /* The argument node: a name and a (possibly) incomplete type. */
4729 arg_node = build_tree_list (name, real_type);
4730 /* Remeber arguments declared final. */
4731 ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
4733 if (jdep)
4734 JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
4735 TREE_CHAIN (arg_node) = arg_types;
4736 arg_types = arg_node;
4738 TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
4739 node = build_tree_list (id, meth);
4740 return node;
4743 static int
4744 unresolved_type_p (wfl, returned)
4745 tree wfl;
4746 tree *returned;
4749 if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
4751 if (returned)
4753 tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
4754 if (decl && current_class && (decl == TYPE_NAME (current_class)))
4755 *returned = TREE_TYPE (decl);
4756 else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
4757 *returned = TREE_TYPE (GET_CPC ());
4758 else
4759 *returned = NULL_TREE;
4761 return 1;
4763 if (returned)
4764 *returned = wfl;
4765 return 0;
4768 /* From NAME, build a qualified identifier node using the
4769 qualification from the current package definition. */
4771 static tree
4772 parser_qualified_classname (is_static, name)
4773 int is_static;
4774 tree name;
4776 tree nested_class_name;
4778 if (!is_static
4779 && (nested_class_name = maybe_make_nested_class_name (name)))
4780 return nested_class_name;
4782 if (ctxp->package)
4783 return merge_qualified_name (ctxp->package, name);
4784 else
4785 return name;
4788 /* Called once the type a interface extends is resolved. Returns 0 if
4789 everything is OK. */
4791 static int
4792 parser_check_super_interface (super_decl, this_decl, this_wfl)
4793 tree super_decl, this_decl, this_wfl;
4795 tree super_type = TREE_TYPE (super_decl);
4797 /* Has to be an interface */
4798 if (!CLASS_INTERFACE (super_decl))
4800 parse_error_context
4801 (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
4802 (TYPE_ARRAY_P (super_type) ? "array" : "class"),
4803 IDENTIFIER_POINTER (DECL_NAME (super_decl)),
4804 (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ?
4805 "interface" : "class"),
4806 IDENTIFIER_POINTER (DECL_NAME (this_decl)));
4807 return 1;
4810 /* Check scope: same package OK, other package: OK if public */
4811 if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
4812 return 1;
4814 SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
4815 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4816 IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4817 return 0;
4820 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
4821 0 if everthing is OK. */
4823 static int
4824 parser_check_super (super_decl, this_decl, wfl)
4825 tree super_decl, this_decl, wfl;
4827 tree super_type = TREE_TYPE (super_decl);
4829 /* SUPER should be a CLASS (neither an array nor an interface) */
4830 if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
4832 parse_error_context
4833 (wfl, "Class `%s' can't subclass %s `%s'",
4834 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4835 (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
4836 IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4837 return 1;
4840 if (CLASS_FINAL (TYPE_NAME (super_type)))
4842 parse_error_context (wfl, "Can't subclass final classes: %s",
4843 IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4844 return 1;
4847 /* Check scope: same package OK, other package: OK if public */
4848 if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
4849 return 1;
4851 SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
4852 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4853 IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4854 return 0;
4857 /* Create a new dependency list and link it (in a LIFO manner) to the
4858 CTXP list of type dependency list. */
4860 static void
4861 create_jdep_list (ctxp)
4862 struct parser_ctxt *ctxp;
4864 jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));
4865 new->first = new->last = NULL;
4866 new->next = ctxp->classd_list;
4867 ctxp->classd_list = new;
4870 static jdeplist *
4871 reverse_jdep_list (ctxp)
4872 struct parser_ctxt *ctxp;
4874 register jdeplist *prev = NULL, *current, *next;
4875 for (current = ctxp->classd_list; current; current = next)
4877 next = current->next;
4878 current->next = prev;
4879 prev = current;
4881 return prev;
4884 /* Create a fake pointer based on the ID stored in
4885 TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
4886 registered again. */
4888 static tree
4889 obtain_incomplete_type (type_name)
4890 tree type_name;
4892 tree ptr, name;
4894 if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
4895 name = EXPR_WFL_NODE (type_name);
4896 else if (INCOMPLETE_TYPE_P (type_name))
4897 name = TYPE_NAME (type_name);
4898 else
4899 fatal ("invalid type name - obtain_incomplete_type");
4901 for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
4902 if (TYPE_NAME (ptr) == name)
4903 break;
4905 if (!ptr)
4907 push_obstacks (&permanent_obstack, &permanent_obstack);
4908 BUILD_PTR_FROM_NAME (ptr, name);
4909 layout_type (ptr);
4910 pop_obstacks ();
4911 TREE_CHAIN (ptr) = ctxp->incomplete_class;
4912 ctxp->incomplete_class = ptr;
4915 return ptr;
4918 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
4919 non NULL instead of computing a new fake type based on WFL. The new
4920 dependency is inserted in the current type dependency list, in FIFO
4921 manner. */
4923 static tree
4924 register_incomplete_type (kind, wfl, decl, ptr)
4925 int kind;
4926 tree wfl, decl, ptr;
4928 jdep *new = (jdep *)xmalloc (sizeof (jdep));
4930 if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
4931 ptr = obtain_incomplete_type (wfl);
4933 JDEP_KIND (new) = kind;
4934 JDEP_DECL (new) = decl;
4935 JDEP_SOLV (new) = ptr;
4936 JDEP_WFL (new) = wfl;
4937 JDEP_CHAIN (new) = NULL;
4938 JDEP_MISC (new) = NULL_TREE;
4939 /* For some dependencies, set the enclosing class of the current
4940 class to be the enclosing context */
4941 if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS)
4942 && GET_ENCLOSING_CPC ())
4943 JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
4944 else
4945 JDEP_ENCLOSING (new) = GET_CPC ();
4946 JDEP_GET_PATCH (new) = (tree *)NULL;
4948 JDEP_INSERT (ctxp->classd_list, new);
4950 return ptr;
4953 void
4954 java_check_circular_reference ()
4956 tree current;
4957 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4959 tree type = TREE_TYPE (current);
4960 if (CLASS_INTERFACE (current))
4962 /* Check all interfaces this class extends */
4963 tree basetype_vec = TYPE_BINFO_BASETYPES (type);
4964 int n, i;
4966 if (!basetype_vec)
4967 return;
4968 n = TREE_VEC_LENGTH (basetype_vec);
4969 for (i = 0; i < n; i++)
4971 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4972 if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node
4973 && interface_of_p (type, BINFO_TYPE (vec_elt)))
4974 parse_error_context (lookup_cl (current),
4975 "Cyclic interface inheritance");
4978 else
4979 if (inherits_from_p (CLASSTYPE_SUPER (type), type))
4980 parse_error_context (lookup_cl (current),
4981 "Cyclic class inheritance%s",
4982 (cyclic_inheritance_report ?
4983 cyclic_inheritance_report : ""));
4987 /* Augment the parameter list PARM with parameters crafted to
4988 initialize outer context locals aliases. Through ARTIFICIAL, a
4989 count is kept of the number of crafted parameters. MODE governs
4990 what eventually gets created: something suitable for a function
4991 creation or a function invocation, either the constructor or
4992 $finit$. */
4994 static tree
4995 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
4996 int mode;
4997 tree class_type, parm;
4998 int *artificial;
5000 tree field;
5001 for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5002 if (FIELD_LOCAL_ALIAS (field))
5004 char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5005 tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5007 switch (mode)
5009 case AIPL_FUNCTION_DECLARATION:
5010 MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5011 purpose = build_wfl_node (get_identifier (buffer));
5012 if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5013 value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5014 else
5015 value = TREE_TYPE (field);
5016 break;
5018 case AIPL_FUNCTION_CREATION:
5019 MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5020 purpose = get_identifier (buffer);
5021 value = TREE_TYPE (field);
5022 break;
5024 case AIPL_FUNCTION_FINIT_INVOCATION:
5025 MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5026 /* Now, this is wrong. purpose should always be the NAME
5027 of something and value its matching value (decl, type,
5028 etc...) FIXME -- but there is a lot to fix. */
5030 /* When invoked for this kind of operation, we already
5031 know whether a field is used or not. */
5032 purpose = TREE_TYPE (field);
5033 value = build_wfl_node (get_identifier (buffer));
5034 break;
5036 case AIPL_FUNCTION_CTOR_INVOCATION:
5037 /* There are two case: the constructor invokation happends
5038 outside the local inner, in which case, locales from the outer
5039 context are directly used.
5041 Otherwise, we fold to using the alias directly. */
5042 if (class_type == current_class)
5043 value = field;
5044 else
5046 name = get_identifier (&buffer[4]);
5047 value = IDENTIFIER_LOCAL_VALUE (name);
5049 break;
5051 parm = tree_cons (purpose, value, parm);
5052 if (artificial)
5053 *artificial +=1;
5055 return parm;
5058 /* Craft a constructor for CLASS_DECL -- what we should do when none
5059 where found. ARGS is non NULL when a special signature must be
5060 enforced. This is the case for anonymous classes. */
5062 static void
5063 craft_constructor (class_decl, args)
5064 tree class_decl, args;
5066 tree class_type = TREE_TYPE (class_decl);
5067 tree parm = NULL_TREE;
5068 int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5069 ACC_PUBLIC : 0);
5070 int i = 0, artificial = 0;
5071 tree decl, ctor_name;
5072 char buffer [80];
5074 push_obstacks (&permanent_obstack, &permanent_obstack);
5076 /* The constructor name is <init> unless we're dealing with an
5077 anonymous class, in which case the name will be fixed after having
5078 be expanded. */
5079 if (ANONYMOUS_CLASS_P (class_type))
5080 ctor_name = DECL_NAME (class_decl);
5081 else
5082 ctor_name = init_identifier_node;
5084 /* If we're dealing with an inner class constructor, we hide the
5085 this$<n> decl in the name field of its parameter declaration. */
5086 if (PURE_INNER_CLASS_TYPE_P (class_type))
5088 tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5089 parm = tree_cons (build_current_thisn (class_type),
5090 build_pointer_type (type), parm);
5092 /* Some more arguments to be hidden here. The values of the local
5093 variables of the outer context that the inner class needs to see. */
5094 parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5095 class_type, parm,
5096 &artificial);
5099 /* Then if there are any args to be enforced, enforce them now */
5100 for (; args && args != end_params_node; args = TREE_CHAIN (args))
5102 sprintf (buffer, "parm%d", i++);
5103 parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5106 CRAFTED_PARAM_LIST_FIXUP (parm);
5107 decl = create_artificial_method (class_type, flags, void_type_node,
5108 ctor_name, parm);
5109 fix_method_argument_names (parm, decl);
5110 /* Now, mark the artificial parameters. */
5111 DECL_FUNCTION_NAP (decl) = artificial;
5113 pop_obstacks ();
5114 DECL_CONSTRUCTOR_P (decl) = 1;
5118 /* Fix the constructors. This will be called right after circular
5119 references have been checked. It is necessary to fix constructors
5120 early even if no code generation will take place for that class:
5121 some generated constructor might be required by the class whose
5122 compilation triggered this one to be simply loaded. */
5124 void
5125 java_fix_constructors ()
5127 tree current;
5129 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5131 tree class_type = TREE_TYPE (current);
5132 int saw_ctor = 0;
5133 tree decl;
5135 if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5136 continue;
5138 for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5140 if (DECL_CONSTRUCTOR_P (decl))
5142 fix_constructors (decl);
5143 saw_ctor = 1;
5147 /* Anonymous class constructor can't be generated that early. */
5148 if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5149 craft_constructor (current, NULL_TREE);
5153 /* safe_layout_class just makes sure that we can load a class without
5154 disrupting the current_class, input_file, lineno, etc, information
5155 about the class processed currently. */
5157 void
5158 safe_layout_class (class)
5159 tree class;
5161 tree save_current_class = current_class;
5162 char *save_input_filename = input_filename;
5163 int save_lineno = lineno;
5165 push_obstacks (&permanent_obstack, &permanent_obstack);
5167 layout_class (class);
5168 pop_obstacks ();
5170 current_class = save_current_class;
5171 input_filename = save_input_filename;
5172 lineno = save_lineno;
5173 CLASS_LOADED_P (class) = 1;
5176 static tree
5177 jdep_resolve_class (dep)
5178 jdep *dep;
5180 tree decl;
5182 if (JDEP_RESOLVED_P (dep))
5183 decl = JDEP_RESOLVED_DECL (dep);
5184 else
5186 decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5187 JDEP_DECL (dep), JDEP_WFL (dep));
5188 JDEP_RESOLVED (dep, decl);
5191 if (!decl)
5192 complete_class_report_errors (dep);
5194 return decl;
5197 /* Complete unsatisfied class declaration and their dependencies */
5199 void
5200 java_complete_class ()
5202 tree cclass;
5203 jdeplist *cclassd;
5204 int error_found;
5205 tree type;
5207 push_obstacks (&permanent_obstack, &permanent_obstack);
5209 /* Process imports and reverse the import on demand list */
5210 process_imports ();
5211 if (ctxp->import_demand_list)
5212 ctxp->import_demand_list = nreverse (ctxp->import_demand_list);
5214 /* Rever things so we have the right order */
5215 ctxp->class_list = nreverse (ctxp->class_list);
5216 ctxp->classd_list = reverse_jdep_list (ctxp);
5218 for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
5219 cclass && cclassd;
5220 cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5222 jdep *dep;
5223 for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5225 tree decl;
5226 if (!(decl = jdep_resolve_class (dep)))
5227 continue;
5229 /* Now it's time to patch */
5230 switch (JDEP_KIND (dep))
5232 case JDEP_SUPER:
5233 /* Simply patch super */
5234 if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5235 continue;
5236 BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO
5237 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5238 break;
5240 case JDEP_FIELD:
5242 /* We do part of the job done in add_field */
5243 tree field_decl = JDEP_DECL (dep);
5244 tree field_type = TREE_TYPE (decl);
5245 push_obstacks (&permanent_obstack, &permanent_obstack);
5246 if (TREE_CODE (field_type) == RECORD_TYPE)
5247 field_type = promote_type (field_type);
5248 pop_obstacks ();
5249 TREE_TYPE (field_decl) = field_type;
5250 DECL_ALIGN (field_decl) = 0;
5251 layout_decl (field_decl, 0);
5252 SOURCE_FRONTEND_DEBUG
5253 (("Completed field/var decl `%s' with `%s'",
5254 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5255 IDENTIFIER_POINTER (DECL_NAME (decl))));
5256 break;
5258 case JDEP_METHOD: /* We start patching a method */
5259 case JDEP_METHOD_RETURN:
5260 error_found = 0;
5261 while (1)
5263 if (decl)
5265 type = TREE_TYPE(decl);
5266 if (TREE_CODE (type) == RECORD_TYPE)
5267 type = promote_type (type);
5268 JDEP_APPLY_PATCH (dep, type);
5269 SOURCE_FRONTEND_DEBUG
5270 (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5271 "Completing fct `%s' with ret type `%s'":
5272 "Completing arg `%s' with type `%s'"),
5273 IDENTIFIER_POINTER (EXPR_WFL_NODE
5274 (JDEP_DECL_WFL (dep))),
5275 IDENTIFIER_POINTER (DECL_NAME (decl))));
5277 else
5278 error_found = 1;
5279 dep = JDEP_CHAIN (dep);
5280 if (JDEP_KIND (dep) == JDEP_METHOD_END)
5281 break;
5282 else
5283 decl = jdep_resolve_class (dep);
5285 if (!error_found)
5287 tree mdecl = JDEP_DECL (dep), signature;
5288 push_obstacks (&permanent_obstack, &permanent_obstack);
5289 /* Recompute and reset the signature, check first that
5290 all types are now defined. If they're not,
5291 dont build the signature. */
5292 if (check_method_types_complete (mdecl))
5294 signature = build_java_signature (TREE_TYPE (mdecl));
5295 set_java_signature (TREE_TYPE (mdecl), signature);
5297 pop_obstacks ();
5299 else
5300 continue;
5301 break;
5303 case JDEP_INTERFACE:
5304 if (parser_check_super_interface (decl, JDEP_DECL (dep),
5305 JDEP_WFL (dep)))
5306 continue;
5307 parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5308 break;
5310 case JDEP_PARM:
5311 case JDEP_VARIABLE:
5312 type = TREE_TYPE(decl);
5313 if (TREE_CODE (type) == RECORD_TYPE)
5314 type = promote_type (type);
5315 JDEP_APPLY_PATCH (dep, type);
5316 break;
5318 case JDEP_TYPE:
5319 JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5320 SOURCE_FRONTEND_DEBUG
5321 (("Completing a random type dependency on a '%s' node",
5322 tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5323 break;
5325 case JDEP_EXCEPTION:
5326 JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5327 SOURCE_FRONTEND_DEBUG
5328 (("Completing `%s' `throws' argument node",
5329 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5330 break;
5332 case JDEP_ANONYMOUS:
5333 patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5334 break;
5336 default:
5337 fatal ("Can't handle patch code %d - java_complete_class",
5338 JDEP_KIND (dep));
5342 pop_obstacks ();
5343 return;
5346 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5347 array. */
5349 static tree
5350 resolve_class (enclosing, class_type, decl, cl)
5351 tree enclosing, class_type, decl, cl;
5353 const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5354 const char *base = name;
5355 tree resolved_type = TREE_TYPE (class_type);
5356 tree resolved_type_decl;
5358 if (resolved_type != NULL_TREE)
5360 tree resolved_type_decl = TYPE_NAME (resolved_type);
5361 if (resolved_type_decl == NULL_TREE
5362 || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5364 resolved_type_decl = build_decl (TYPE_DECL,
5365 TYPE_NAME (class_type),
5366 resolved_type);
5368 return resolved_type_decl;
5371 /* 1- Check to see if we have an array. If true, find what we really
5372 want to resolve */
5373 while (name[0] == '[')
5374 name++;
5375 if (base != name)
5376 TYPE_NAME (class_type) = get_identifier (name);
5378 /* 2- Resolve the bare type */
5379 if (!(resolved_type_decl = do_resolve_class (enclosing, class_type,
5380 decl, cl)))
5381 return NULL_TREE;
5382 resolved_type = TREE_TYPE (resolved_type_decl);
5384 /* 3- If we have and array, reconstruct the array down to its nesting */
5385 if (base != name)
5387 while (base != name)
5389 if (TREE_CODE (resolved_type) == RECORD_TYPE)
5390 resolved_type = promote_type (resolved_type);
5391 resolved_type = build_java_array_type (resolved_type, -1);
5392 CLASS_LOADED_P (resolved_type) = 1;
5393 name--;
5395 /* Build a fake decl for this, since this is what is expected to
5396 be returned. */
5397 resolved_type_decl =
5398 build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
5399 /* Figure how those two things are important for error report. FIXME */
5400 DECL_SOURCE_LINE (resolved_type_decl) = 0;
5401 DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
5402 TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
5404 TREE_TYPE (class_type) = resolved_type;
5405 return resolved_type_decl;
5408 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5409 are used to report error messages. */
5411 tree
5412 do_resolve_class (enclosing, class_type, decl, cl)
5413 tree enclosing, class_type, decl, cl;
5415 tree new_class_decl;
5416 tree original_name = NULL_TREE;
5418 /* Do not try to replace TYPE_NAME (class_type) by a variable, since
5419 its is changed by find_in_imports{_on_demand} */
5421 /* 0- Search in the current class as an inner class */
5423 /* Maybe some code here should be added to load the class or
5424 something, at least if the class isn't an inner class and ended
5425 being loaded from class file. FIXME. */
5426 while (enclosing)
5428 tree name;
5430 if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
5431 return new_class_decl;
5433 /* Now go to the upper classes, bail out if necessary. */
5434 enclosing = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
5435 if (!enclosing || enclosing == object_type_node)
5436 break;
5438 if (TREE_CODE (enclosing) == RECORD_TYPE)
5440 enclosing = TYPE_NAME (enclosing);
5441 continue;
5444 if (TREE_CODE (enclosing) == IDENTIFIER_NODE)
5446 BUILD_PTR_FROM_NAME (name, enclosing);
5448 else
5449 name = enclosing;
5450 enclosing = do_resolve_class (NULL, name, NULL, NULL);
5453 /* 1- Check for the type in single imports */
5454 if (find_in_imports (class_type))
5455 return NULL_TREE;
5457 /* 2- And check for the type in the current compilation unit. If it fails,
5458 try with a name qualified with the package name we've seen so far */
5459 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5461 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5462 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5463 load_class (TYPE_NAME (class_type), 0);
5464 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5467 original_name = TYPE_NAME (class_type);
5468 if (!QUALIFIED_P (TYPE_NAME (class_type)))
5470 tree package;
5471 for (package = package_list; package; package = TREE_CHAIN (package))
5473 tree new_qualified;
5475 new_qualified = merge_qualified_name (TREE_PURPOSE (package),
5476 original_name);
5477 TYPE_NAME (class_type) = new_qualified;
5478 new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5479 if (!new_class_decl)
5480 load_class (TYPE_NAME (class_type), 0);
5481 new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5482 if (new_class_decl)
5484 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5485 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5486 load_class (TYPE_NAME (class_type), 0);
5487 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5492 TYPE_NAME (class_type) = original_name;
5494 /* 3- Check an other compilation unit that bears the name of type */
5495 load_class (TYPE_NAME (class_type), 0);
5496 if (check_pkg_class_access (TYPE_NAME (class_type),
5497 (cl ? cl : lookup_cl (decl))))
5498 return NULL_TREE;
5500 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5501 return new_class_decl;
5503 /* 4- Check the import on demands. Don't allow bar.baz to be
5504 imported from foo.* */
5505 if (!QUALIFIED_P (TYPE_NAME (class_type)))
5506 if (find_in_imports_on_demand (class_type))
5507 return NULL_TREE;
5509 /* 5- Last call for a resolution */
5510 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5513 /* Resolve NAME and lay it out (if not done and if not the current
5514 parsed class). Return a decl node. This function is meant to be
5515 called when type resolution is necessary during the walk pass. */
5517 static tree
5518 resolve_and_layout (something, cl)
5519 tree something;
5520 tree cl;
5522 tree decl;
5524 /* Don't do that on the current class */
5525 if (something == current_class)
5526 return TYPE_NAME (current_class);
5528 /* Don't do anything for void and other primitive types */
5529 if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5530 return NULL_TREE;
5532 /* Pointer types can be reall pointer types or fake pointers. When
5533 finding a real pointer, recheck for primitive types */
5534 if (TREE_CODE (something) == POINTER_TYPE)
5536 if (TREE_TYPE (something))
5538 something = TREE_TYPE (something);
5539 if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5540 return NULL_TREE;
5542 else
5543 something = TYPE_NAME (something);
5546 /* Don't do anything for arrays of primitive types */
5547 if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5548 && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5549 return NULL_TREE;
5551 /* Something might be a WFL */
5552 if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5553 something = EXPR_WFL_NODE (something);
5555 /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5556 TYPE_DECL or a real TYPE */
5557 else if (TREE_CODE (something) != IDENTIFIER_NODE)
5558 something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5559 DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5561 if (!(decl = resolve_no_layout (something, cl)))
5562 return NULL_TREE;
5564 /* Resolve and layout if necessary */
5565 layout_class_methods (TREE_TYPE (decl));
5566 /* Check methods, but only once */
5567 if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl))
5568 && !CLASS_LOADED_P (TREE_TYPE (decl)))
5569 CHECK_METHODS (decl);
5570 if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
5571 safe_layout_class (TREE_TYPE (decl));
5573 return decl;
5576 /* Resolve a class, returns its decl but doesn't perform any
5577 layout. The current parsing context is saved and restored */
5579 static tree
5580 resolve_no_layout (name, cl)
5581 tree name, cl;
5583 tree ptr, decl;
5584 BUILD_PTR_FROM_NAME (ptr, name);
5585 java_parser_context_save_global ();
5586 decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5587 java_parser_context_restore_global ();
5589 return decl;
5592 /* Called when reporting errors. Skip leader '[' in a complex array
5593 type description that failed to be resolved. */
5595 static const char *
5596 purify_type_name (name)
5597 const char *name;
5599 while (*name && *name == '[')
5600 name++;
5601 return name;
5604 /* The type CURRENT refers to can't be found. We print error messages. */
5606 static void
5607 complete_class_report_errors (dep)
5608 jdep *dep;
5610 const char *name;
5612 if (!JDEP_WFL (dep))
5613 return;
5615 name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5616 switch (JDEP_KIND (dep))
5618 case JDEP_SUPER:
5619 parse_error_context
5620 (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5621 purify_type_name (name),
5622 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5623 break;
5624 case JDEP_FIELD:
5625 parse_error_context
5626 (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5627 purify_type_name (name),
5628 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5629 break;
5630 case JDEP_METHOD: /* Covers arguments */
5631 parse_error_context
5632 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5633 purify_type_name (name),
5634 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5635 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5636 break;
5637 case JDEP_METHOD_RETURN: /* Covers return type */
5638 parse_error_context
5639 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'",
5640 purify_type_name (name),
5641 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
5642 break;
5643 case JDEP_INTERFACE:
5644 parse_error_context
5645 (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
5646 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
5647 (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
5648 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5649 break;
5650 case JDEP_VARIABLE:
5651 parse_error_context
5652 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'",
5653 purify_type_name (IDENTIFIER_POINTER
5654 (EXPR_WFL_NODE (JDEP_WFL (dep)))),
5655 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5656 break;
5657 case JDEP_EXCEPTION: /* As specified by `throws' */
5658 parse_error_context
5659 (JDEP_WFL (dep), "Class `%s' not found in `throws'",
5660 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
5661 break;
5662 default:
5663 /* Fix for -Wall. Just break doing nothing. The error will be
5664 caught later */
5665 break;
5669 /* Return a static string containing the DECL prototype string. If
5670 DECL is a constructor, use the class name instead of the form
5671 <init> */
5673 static const char *
5674 get_printable_method_name (decl)
5675 tree decl;
5677 const char *to_return;
5678 tree name = NULL_TREE;
5680 if (DECL_CONSTRUCTOR_P (decl))
5682 name = DECL_NAME (decl);
5683 DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
5686 to_return = lang_printable_name (decl, 0);
5687 if (DECL_CONSTRUCTOR_P (decl))
5688 DECL_NAME (decl) = name;
5690 return to_return;
5693 /* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
5694 nevertheless needs to be verfied, 1 otherwise. */
5696 static int
5697 reset_method_name (method)
5698 tree method;
5700 if (!DECL_CLINIT_P (method) && !DECL_FINIT_P (method))
5702 /* NAME is just the plain name when Object is being defined */
5703 if (DECL_CONTEXT (method) != object_type_node)
5704 DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ?
5705 init_identifier_node : GET_METHOD_NAME (method));
5706 return 0;
5708 else
5709 return 1;
5712 /* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
5714 tree
5715 java_get_real_method_name (method_decl)
5716 tree method_decl;
5718 tree method_name = DECL_NAME (method_decl);
5719 if (DECL_CONSTRUCTOR_P (method_decl))
5720 return init_identifier_node;
5722 /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
5723 and still can be a constructor. FIXME */
5725 /* Don't confuse method only bearing the name of their class as
5726 constructors */
5727 else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
5728 && ctxp
5729 && GET_CPC_UN () == EXPR_WFL_NODE (method_name)
5730 && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
5731 && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
5732 return init_identifier_node;
5733 else
5734 return EXPR_WFL_NODE (method_name);
5737 /* Track method being redefined inside the same class. As a side
5738 effect, set DECL_NAME to an IDENTIFIER (prior entering this
5739 function it's a FWL, so we can track errors more accurately.) */
5741 static int
5742 check_method_redefinition (class, method)
5743 tree class, method;
5745 tree redef, name;
5746 tree cl = DECL_NAME (method);
5747 tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
5748 /* decl name of artificial <clinit> and $finit$ doesn't need to be
5749 fixed and checked */
5751 /* Reset the method name before running the check. If it returns 1,
5752 the method doesn't need to be verified with respect to method
5753 redeclaration and we return 0 */
5754 if (reset_method_name (method))
5755 return 0;
5757 name = DECL_NAME (method);
5758 for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
5760 if (redef == method)
5761 break;
5762 if (DECL_NAME (redef) == name
5763 && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
5765 parse_error_context
5766 (cl, "Duplicate %s declaration `%s'",
5767 (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
5768 get_printable_method_name (redef));
5769 return 1;
5772 return 0;
5775 static void
5776 check_abstract_method_definitions (do_interface, class_decl, type)
5777 int do_interface;
5778 tree class_decl, type;
5780 tree class = TREE_TYPE (class_decl);
5781 tree method, end_type;
5783 end_type = (do_interface ? object_type_node : type);
5784 for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
5786 tree other_super, other_method, method_sig, method_name;
5787 int found = 0;
5788 int end_type_reached = 0;
5790 if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
5791 continue;
5793 /* Now verify that somewhere in between TYPE and CLASS,
5794 abstract method METHOD gets a non abstract definition
5795 that is inherited by CLASS. */
5797 method_sig = build_java_signature (TREE_TYPE (method));
5798 method_name = DECL_NAME (method);
5799 if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
5800 method_name = EXPR_WFL_NODE (method_name);
5802 other_super = class;
5803 do {
5804 if (other_super == end_type)
5805 end_type_reached = 1;
5807 /* Method search */
5808 for (other_method = TYPE_METHODS (other_super); other_method;
5809 other_method = TREE_CHAIN (other_method))
5811 tree s = build_java_signature (TREE_TYPE (other_method));
5812 tree other_name = DECL_NAME (other_method);
5814 if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
5815 other_name = EXPR_WFL_NODE (other_name);
5816 if (!DECL_CLINIT_P (other_method)
5817 && !DECL_CONSTRUCTOR_P (other_method)
5818 && method_name == other_name && method_sig == s)
5820 found = 1;
5821 break;
5824 other_super = CLASSTYPE_SUPER (other_super);
5825 } while (!end_type_reached);
5827 /* Report that abstract METHOD didn't find an implementation
5828 that CLASS can use. */
5829 if (!found)
5831 char *t = xstrdup (lang_printable_name
5832 (TREE_TYPE (TREE_TYPE (method)), 0));
5833 tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
5834 tree saved_wfl = NULL_TREE;
5836 if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
5838 saved_wfl = DECL_NAME (method);
5839 DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
5842 parse_error_context
5843 (lookup_cl (class_decl),
5844 "Class `%s' doesn't define the abstract method `%s %s' from %s `%s'. This method must be defined or %s `%s' must be declared abstract",
5845 IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5846 t, lang_printable_name (method, 0),
5847 (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ?
5848 "interface" : "class"),
5849 IDENTIFIER_POINTER (ccn),
5850 (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
5851 IDENTIFIER_POINTER (DECL_NAME (class_decl)));
5853 free (t);
5855 if (saved_wfl)
5856 DECL_NAME (method) = saved_wfl;
5861 /* Check that CLASS_DECL somehow implements all inherited abstract
5862 methods. */
5864 static void
5865 java_check_abstract_method_definitions (class_decl)
5866 tree class_decl;
5868 tree class = TREE_TYPE (class_decl);
5869 tree super, vector;
5870 int i;
5872 if (CLASS_ABSTRACT (class_decl))
5873 return;
5875 /* Check for inherited types */
5876 super = class;
5877 do {
5878 super = CLASSTYPE_SUPER (super);
5879 check_abstract_method_definitions (0, class_decl, super);
5880 } while (super != object_type_node);
5882 /* Check for implemented interfaces. */
5883 vector = TYPE_BINFO_BASETYPES (class);
5884 for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
5886 super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5887 check_abstract_method_definitions (1, class_decl, super);
5891 /* Check all the types method DECL uses and return 1 if all of them
5892 are now complete, 0 otherwise. This is used to check whether its
5893 safe to build a method signature or not. */
5895 static int
5896 check_method_types_complete (decl)
5897 tree decl;
5899 tree type = TREE_TYPE (decl);
5900 tree args;
5902 if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
5903 return 0;
5905 args = TYPE_ARG_TYPES (type);
5906 if (TREE_CODE (type) == METHOD_TYPE)
5907 args = TREE_CHAIN (args);
5908 for (; args != end_params_node; args = TREE_CHAIN (args))
5909 if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
5910 return 0;
5912 return 1;
5915 /* Check all the methods of CLASS_DECL. Methods are first completed
5916 then checked according to regular method existance rules. If no
5917 constructor for CLASS_DECL were encountered, then build its
5918 declaration. */
5920 static void
5921 java_check_regular_methods (class_decl)
5922 tree class_decl;
5924 int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
5925 tree method;
5926 tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
5927 tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
5928 tree mthrows;
5930 /* It is not necessary to check methods defined in java.lang.Object */
5931 if (class == object_type_node)
5932 return;
5934 if (!TYPE_NVIRTUALS (class))
5935 TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
5937 /* Should take interfaces into account. FIXME */
5938 for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
5940 tree sig;
5941 tree method_wfl = DECL_NAME (method);
5942 int aflags;
5944 /* If we previously found something and its name was saved,
5945 reinstall it now */
5946 if (found && saved_found_wfl)
5948 DECL_NAME (found) = saved_found_wfl;
5949 saved_found_wfl = NULL_TREE;
5952 /* Check for redefinitions */
5953 if (check_method_redefinition (class, method))
5954 continue;
5956 /* If we see one constructor a mark so we don't generate the
5957 default one. Also skip other verifications: constructors
5958 can't be inherited hence hiden or overriden */
5959 if (DECL_CONSTRUCTOR_P (method))
5961 saw_constructor = 1;
5962 continue;
5965 /* We verify things thrown by the method. They must inherits from
5966 java.lang.Throwable */
5967 for (mthrows = DECL_FUNCTION_THROWS (method);
5968 mthrows; mthrows = TREE_CHAIN (mthrows))
5970 if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
5971 parse_error_context
5972 (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
5973 IDENTIFIER_POINTER
5974 (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
5977 sig = build_java_argument_signature (TREE_TYPE (method));
5978 found = lookup_argument_method2 (class, DECL_NAME (method), sig);
5980 /* Inner class can't declare static methods */
5981 if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
5983 char *t = xstrdup (lang_printable_name (class, 0));
5984 parse_error_context
5985 (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
5986 lang_printable_name (method, 0), t);
5987 free (t);
5990 /* Nothing overrides or it's a private method. */
5991 if (!found)
5992 continue;
5993 if (METHOD_PRIVATE (found))
5995 found = NULL_TREE;
5996 continue;
5999 /* If found wasn't verified, it's DECL_NAME won't be set properly.
6000 We set it temporarily for the sake of the error report. */
6001 saved_found_wfl = DECL_NAME (found);
6002 reset_method_name (found);
6004 /* If `found' is declared in an interface, make sure the
6005 modifier matches. */
6006 if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6007 && clinit_identifier_node != DECL_NAME (found)
6008 && !METHOD_PUBLIC (method))
6010 tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6011 parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6012 IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6013 lang_printable_name (method, 0),
6014 IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6017 /* Can't override a method with the same name and different return
6018 types. */
6019 if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6021 char *t = xstrdup
6022 (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6023 parse_error_context
6024 (method_wfl,
6025 "Method `%s' was defined with return type `%s' in class `%s'",
6026 lang_printable_name (found, 0), t,
6027 IDENTIFIER_POINTER
6028 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6029 free (t);
6032 aflags = get_access_flags_from_decl (found);
6033 /* If the method has default, access in an other package, then
6034 issue a warning that the current method doesn't override the
6035 one that was found elsewhere. Do not issue this warning when
6036 the match was found in java.lang.Object. */
6037 if (DECL_CONTEXT (found) != object_type_node
6038 && ((aflags & ACC_VISIBILITY) == 0)
6039 && !class_in_current_package (DECL_CONTEXT (found))
6040 && !DECL_CLINIT_P (found)
6041 && flag_not_overriding)
6043 parse_warning_context
6044 (method_wfl, "Method `%s' in class `%s' does not override the corresponding method in class `%s', which is private to a different package",
6045 lang_printable_name (found, 0),
6046 IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6047 IDENTIFIER_POINTER (DECL_NAME
6048 (TYPE_NAME (DECL_CONTEXT (found)))));
6049 continue;
6052 /* Can't override final. Can't override static. */
6053 if (METHOD_FINAL (found) || METHOD_STATIC (found))
6055 /* Static *can* override static */
6056 if (METHOD_STATIC (found) && METHOD_STATIC (method))
6057 continue;
6058 parse_error_context
6059 (method_wfl,
6060 "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6061 (METHOD_FINAL (found) ? "Final" : "Static"),
6062 lang_printable_name (found, 0),
6063 (METHOD_FINAL (found) ? "final" : "static"),
6064 IDENTIFIER_POINTER
6065 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6066 continue;
6069 /* Static method can't override instance method. */
6070 if (METHOD_STATIC (method))
6072 parse_error_context
6073 (method_wfl,
6074 "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6075 lang_printable_name (found, 0),
6076 IDENTIFIER_POINTER
6077 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6078 continue;
6081 /* - Overriding/hiding public must be public
6082 - Overriding/hiding protected must be protected or public
6083 - If the overriden or hidden method has default (package)
6084 access, then the overriding or hiding method must not be
6085 private; otherwise, a compile-time error occurs. If
6086 `found' belongs to an interface, things have been already
6087 taken care of. */
6088 if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6089 && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6090 || (METHOD_PROTECTED (found)
6091 && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6092 || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6093 && METHOD_PRIVATE (method))))
6095 parse_error_context
6096 (method_wfl,
6097 "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6098 (METHOD_PUBLIC (method) ? "public" :
6099 (METHOD_PRIVATE (method) ? "private" : "protected")),
6100 IDENTIFIER_POINTER (DECL_NAME
6101 (TYPE_NAME (DECL_CONTEXT (found)))));
6102 continue;
6105 /* Overriding methods must have compatible `throws' clauses on checked
6106 exceptions, if any */
6107 check_throws_clauses (method, method_wfl, found);
6109 /* Inheriting multiple methods with the same signature. FIXME */
6112 /* Don't forget eventual pending found and saved_found_wfl. Take
6113 into account that we might have exited because we saw an
6114 artificial method as the last entry. */
6116 if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
6117 DECL_NAME (found) = saved_found_wfl;
6119 if (!TYPE_NVIRTUALS (class))
6120 TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6122 /* Search for inherited abstract method not yet implemented in this
6123 class. */
6124 java_check_abstract_method_definitions (class_decl);
6126 if (!saw_constructor)
6127 fatal ("No constructor found");
6130 /* Return a non zero value if the `throws' clause of METHOD (if any)
6131 is incompatible with the `throws' clause of FOUND (if any). */
6133 static void
6134 check_throws_clauses (method, method_wfl, found)
6135 tree method, method_wfl, found;
6137 tree mthrows, fthrows;
6139 /* Can't check these things with class loaded from bytecode. FIXME */
6140 if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6141 return;
6143 for (mthrows = DECL_FUNCTION_THROWS (method);
6144 mthrows; mthrows = TREE_CHAIN (mthrows))
6146 /* We don't verify unchecked expressions */
6147 if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6148 continue;
6149 /* Checked expression must be compatible */
6150 for (fthrows = DECL_FUNCTION_THROWS (found);
6151 fthrows; fthrows = TREE_CHAIN (fthrows))
6152 if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6153 break;
6154 if (!fthrows)
6156 parse_error_context
6157 (method_wfl, "Invalid checked exception class `%s' in `throws' clause. The exception must be a subclass of an exception thrown by `%s' from class `%s'",
6158 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6159 lang_printable_name (found, 0),
6160 IDENTIFIER_POINTER
6161 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6166 /* Check abstract method of interface INTERFACE */
6168 static void
6169 java_check_abstract_methods (interface_decl)
6170 tree interface_decl;
6172 int i, n;
6173 tree method, basetype_vec, found;
6174 tree interface = TREE_TYPE (interface_decl);
6176 for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6178 tree method_wfl = DECL_NAME (method);
6180 /* 2- Check for double definition inside the defining interface */
6181 if (check_method_redefinition (interface, method))
6182 continue;
6184 /* 3- Overriding is OK as far as we preserve the return type and
6185 the thrown exceptions (FIXME) */
6186 found = lookup_java_interface_method2 (interface, method);
6187 if (found)
6189 char *t;
6190 tree saved_found_wfl = DECL_NAME (found);
6191 reset_method_name (found);
6192 t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6193 parse_error_context
6194 (method_wfl,
6195 "Method `%s' was defined with return type `%s' in class `%s'",
6196 lang_printable_name (found, 0), t,
6197 IDENTIFIER_POINTER
6198 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6199 free (t);
6200 DECL_NAME (found) = saved_found_wfl;
6201 continue;
6205 /* 4- Inherited methods can't differ by their returned types */
6206 if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6207 return;
6208 n = TREE_VEC_LENGTH (basetype_vec);
6209 for (i = 0; i < n; i++)
6211 tree sub_interface_method, sub_interface;
6212 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6213 if (!vec_elt)
6214 continue;
6215 sub_interface = BINFO_TYPE (vec_elt);
6216 for (sub_interface_method = TYPE_METHODS (sub_interface);
6217 sub_interface_method;
6218 sub_interface_method = TREE_CHAIN (sub_interface_method))
6220 found = lookup_java_interface_method2 (interface,
6221 sub_interface_method);
6222 if (found && (found != sub_interface_method))
6224 tree saved_found_wfl = DECL_NAME (found);
6225 reset_method_name (found);
6226 parse_error_context
6227 (lookup_cl (sub_interface_method),
6228 "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6229 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6230 lang_printable_name (found, 0),
6231 IDENTIFIER_POINTER
6232 (DECL_NAME (TYPE_NAME
6233 (DECL_CONTEXT (sub_interface_method)))),
6234 IDENTIFIER_POINTER
6235 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6236 DECL_NAME (found) = saved_found_wfl;
6242 /* Lookup methods in interfaces using their name and partial
6243 signature. Return a matching method only if their types differ. */
6245 static tree
6246 lookup_java_interface_method2 (class, method_decl)
6247 tree class, method_decl;
6249 int i, n;
6250 tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6252 if (!basetype_vec)
6253 return NULL_TREE;
6255 n = TREE_VEC_LENGTH (basetype_vec);
6256 for (i = 0; i < n; i++)
6258 tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6259 if ((BINFO_TYPE (vec_elt) != object_type_node)
6260 && (to_return =
6261 lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6262 return to_return;
6264 for (i = 0; i < n; i++)
6266 to_return = lookup_java_interface_method2
6267 (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6268 if (to_return)
6269 return to_return;
6272 return NULL_TREE;
6275 /* Lookup method using their name and partial signature. Return a
6276 matching method only if their types differ. */
6278 static tree
6279 lookup_java_method2 (clas, method_decl, do_interface)
6280 tree clas, method_decl;
6281 int do_interface;
6283 tree method, method_signature, method_name, method_type, name;
6285 method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6286 name = DECL_NAME (method_decl);
6287 method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6288 EXPR_WFL_NODE (name) : name);
6289 method_type = TREE_TYPE (TREE_TYPE (method_decl));
6291 while (clas != NULL_TREE)
6293 for (method = TYPE_METHODS (clas);
6294 method != NULL_TREE; method = TREE_CHAIN (method))
6296 tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6297 tree name = DECL_NAME (method);
6298 if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6299 EXPR_WFL_NODE (name) : name) == method_name
6300 && method_sig == method_signature
6301 && TREE_TYPE (TREE_TYPE (method)) != method_type)
6302 return method;
6304 clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6306 return NULL_TREE;
6309 /* Return the line that matches DECL line number, and try its best to
6310 position the column number. Used during error reports. */
6312 static tree
6313 lookup_cl (decl)
6314 tree decl;
6316 static tree cl = NULL_TREE;
6317 char *line, *found;
6319 if (!decl)
6320 return NULL_TREE;
6322 if (cl == NULL_TREE)
6323 cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6325 EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6326 EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6328 line = java_get_line_col (IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (cl)),
6329 EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6331 found = strstr ((const char *)line,
6332 (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6333 if (found)
6334 EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6336 return cl;
6339 /* Look for a simple name in the single-type import list */
6341 static tree
6342 find_name_in_single_imports (name)
6343 tree name;
6345 tree node;
6347 for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6348 if (TREE_VALUE (node) == name)
6349 return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6351 return NULL_TREE;
6354 /* Process all single-type import. */
6356 static int
6357 process_imports ()
6359 tree import;
6360 int error_found;
6362 for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6364 tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6366 /* Don't load twice something already defined. */
6367 if (IDENTIFIER_CLASS_VALUE (to_be_found))
6368 continue;
6369 QUALIFIED_P (to_be_found) = 1;
6370 load_class (to_be_found, 0);
6371 error_found =
6372 check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6373 if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6375 parse_error_context (TREE_PURPOSE (import),
6376 "Class or interface `%s' not found in import",
6377 IDENTIFIER_POINTER (to_be_found));
6378 return 1;
6380 if (error_found)
6381 return 1;
6383 return 0;
6386 /* Possibly find a class imported by a single-type import statement. Return
6387 1 if an error occured, 0 otherwise. */
6389 static int
6390 find_in_imports (class_type)
6391 tree class_type;
6393 tree import;
6395 for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6396 if (TREE_VALUE (import) == TYPE_NAME (class_type))
6398 TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6399 QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6401 return 0;
6404 static int
6405 note_possible_classname (name, len)
6406 const char *name;
6407 int len;
6409 tree node;
6410 if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6411 len = len - 5;
6412 else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6413 len = len - 6;
6414 else
6415 return 0;
6416 node = ident_subst (name, len, "", '/', '.', "");
6417 IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6418 QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6419 return 1;
6422 /* Read a import directory, gathering potential match for further type
6423 references. Indifferently reads a filesystem or a ZIP archive
6424 directory. */
6426 static void
6427 read_import_dir (wfl)
6428 tree wfl;
6430 tree package_id = EXPR_WFL_NODE (wfl);
6431 const char *package_name = IDENTIFIER_POINTER (package_id);
6432 int package_length = IDENTIFIER_LENGTH (package_id);
6433 DIR *dirp = NULL;
6434 JCF *saved_jcf = current_jcf;
6436 int found = 0;
6437 int k;
6438 void *entry;
6439 struct buffer filename[1];
6442 if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6443 return;
6444 IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6446 BUFFER_INIT (filename);
6447 buffer_grow (filename, package_length + 100);
6449 for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6451 const char *entry_name = jcf_path_name (entry);
6452 int entry_length = strlen (entry_name);
6453 if (jcf_path_is_zipfile (entry))
6455 ZipFile *zipf;
6456 buffer_grow (filename, entry_length);
6457 memcpy (filename->data, entry_name, entry_length - 1);
6458 filename->data[entry_length-1] = '\0';
6459 zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6460 if (zipf == NULL)
6461 error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6462 else
6464 ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6465 BUFFER_RESET (filename);
6466 for (k = 0; k < package_length; k++)
6468 char ch = package_name[k];
6469 *filename->ptr++ = ch == '.' ? '/' : ch;
6471 *filename->ptr++ = '/';
6473 for (k = 0; k < zipf->count; k++, zipd = ZIPDIR_NEXT (zipd))
6475 const char *current_entry = ZIPDIR_FILENAME (zipd);
6476 int current_entry_len = zipd->filename_length;
6478 if (current_entry_len >= BUFFER_LENGTH (filename)
6479 && strncmp (filename->data, current_entry,
6480 BUFFER_LENGTH (filename)) != 0)
6481 continue;
6482 found |= note_possible_classname (current_entry,
6483 current_entry_len);
6487 else
6489 BUFFER_RESET (filename);
6490 buffer_grow (filename, entry_length + package_length + 4);
6491 strcpy (filename->data, entry_name);
6492 filename->ptr = filename->data + entry_length;
6493 for (k = 0; k < package_length; k++)
6495 char ch = package_name[k];
6496 *filename->ptr++ = ch == '.' ? '/' : ch;
6498 *filename->ptr = '\0';
6500 dirp = opendir (filename->data);
6501 if (dirp == NULL)
6502 continue;
6503 *filename->ptr++ = '/';
6504 for (;;)
6506 int len;
6507 const char *d_name;
6508 struct dirent *direntp = readdir (dirp);
6509 if (!direntp)
6510 break;
6511 d_name = direntp->d_name;
6512 len = strlen (direntp->d_name);
6513 buffer_grow (filename, len+1);
6514 strcpy (filename->ptr, d_name);
6515 found |= note_possible_classname (filename->data + entry_length,
6516 package_length+len+1);
6518 if (dirp)
6519 closedir (dirp);
6523 free (filename->data);
6525 /* Here we should have a unified way of retrieving an entry, to be
6526 indexed. */
6527 if (!found)
6529 static int first = 1;
6530 if (first)
6532 error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6533 java_error_count++;
6534 first = 0;
6536 else
6537 parse_error_context (wfl, "Package `%s' not found in import",
6538 package_name);
6539 current_jcf = saved_jcf;
6540 return;
6542 current_jcf = saved_jcf;
6545 /* Possibly find a type in the import on demands specified
6546 types. Returns 1 if an error occured, 0 otherwise. Run throught the
6547 entire list, to detected potential double definitions. */
6549 static int
6550 find_in_imports_on_demand (class_type)
6551 tree class_type;
6553 tree node, import, node_to_use = NULL_TREE;
6554 int seen_once = -1;
6555 tree cl = NULL_TREE;
6557 for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6559 const char *id_name;
6560 obstack_grow (&temporary_obstack,
6561 IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6562 IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6563 obstack_1grow (&temporary_obstack, '.');
6564 obstack_grow0 (&temporary_obstack,
6565 IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6566 IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6567 id_name = obstack_finish (&temporary_obstack);
6569 node = maybe_get_identifier (id_name);
6570 if (node && IS_A_CLASSFILE_NAME (node))
6572 if (seen_once < 0)
6574 cl = TREE_PURPOSE (import);
6575 seen_once = 1;
6576 node_to_use = node;
6578 else
6580 seen_once++;
6581 parse_error_context
6582 (import, "Type `%s' also potentially defined in package `%s'",
6583 IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6584 IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6589 if (seen_once == 1)
6591 /* Setup lineno so that it refers to the line of the import (in
6592 case we parse a class file and encounter errors */
6593 tree decl;
6594 int saved_lineno = lineno;
6595 lineno = EXPR_WFL_LINENO (cl);
6596 TYPE_NAME (class_type) = node_to_use;
6597 QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6598 decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6599 /* If there is no DECL set for the class or if the class isn't
6600 loaded and not seen in source yet, the load */
6601 if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6602 && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6603 load_class (node_to_use, 0);
6604 lineno = saved_lineno;
6605 return check_pkg_class_access (TYPE_NAME (class_type), cl);
6607 else
6608 return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6611 static tree
6612 resolve_package (pkg, next)
6613 tree pkg, *next;
6615 tree current, acc;
6616 tree type_name = NULL_TREE;
6617 const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6619 /* The trick is to determine when the package name stops and were
6620 the name of something contained in the package starts. Then we
6621 return a fully qualified name of what we want to get. */
6623 /* Do a quick search on well known package names */
6624 if (!strncmp (name, "java.lang.reflect", 17))
6626 *next =
6627 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6628 type_name = lookup_package_type (name, 17);
6630 else if (!strncmp (name, "java.lang", 9))
6632 *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6633 type_name = lookup_package_type (name, 9);
6636 /* If we found something here, return */
6637 if (type_name)
6638 return type_name;
6640 *next = EXPR_WFL_QUALIFICATION (pkg);
6642 /* Try the current package. */
6643 if (ctxp->package && !strncmp (name, IDENTIFIER_POINTER (ctxp->package),
6644 IDENTIFIER_LENGTH (ctxp->package)))
6646 type_name =
6647 lookup_package_type_and_set_next (name,
6648 IDENTIFIER_LENGTH (ctxp->package),
6649 next );
6650 if (type_name)
6651 return type_name;
6654 /* Search in imported package */
6655 for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
6657 tree current_pkg_name = EXPR_WFL_NODE (TREE_PURPOSE (current));
6658 int len = IDENTIFIER_LENGTH (current_pkg_name);
6659 if (!strncmp (name, IDENTIFIER_POINTER (current_pkg_name), len))
6661 tree left, dummy;
6663 breakdown_qualified (&left, &dummy, current_pkg_name);
6664 len = IDENTIFIER_LENGTH (left);
6665 type_name = lookup_package_type_and_set_next (name, len, next);
6666 if (type_name)
6667 break;
6671 /* Try to progressively construct a type name */
6672 if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6673 for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg);
6674 current; current = TREE_CHAIN (current))
6676 acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
6677 if ((type_name = resolve_no_layout (acc, NULL_TREE)))
6679 type_name = acc;
6680 *next = TREE_CHAIN (current);
6681 break;
6684 return type_name;
6687 static tree
6688 lookup_package_type_and_set_next (name, len, next)
6689 const char *name;
6690 int len;
6691 tree *next;
6693 const char *ptr;
6694 tree type_name = lookup_package_type (name, len);
6696 if (!type_name)
6697 return NULL;
6699 ptr = IDENTIFIER_POINTER (type_name);
6700 while (ptr && (ptr = strchr (ptr, '.')))
6702 *next = TREE_CHAIN (*next);
6703 ptr++;
6705 return type_name;
6708 static tree
6709 lookup_package_type (name, from)
6710 const char *name;
6711 int from;
6713 char subname [128];
6714 const char *sub = &name[from+1];
6715 while (*sub != '.' && *sub)
6716 sub++;
6717 strncpy (subname, name, sub-name);
6718 subname [sub-name] = '\0';
6719 return get_identifier (subname);
6722 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
6723 access violations were found, 1 otherwise. */
6725 static int
6726 check_pkg_class_access (class_name, cl)
6727 tree class_name;
6728 tree cl;
6730 tree type;
6732 if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
6733 return 0;
6735 if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
6736 return 0;
6738 if (!CLASS_PUBLIC (TYPE_NAME (type)))
6740 /* Access to a private class within the same package is
6741 allowed. */
6742 tree l, r;
6743 breakdown_qualified (&l, &r, class_name);
6744 if (l == ctxp->package)
6745 return 0;
6747 parse_error_context
6748 (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
6749 (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
6750 IDENTIFIER_POINTER (class_name));
6751 return 1;
6753 return 0;
6756 /* Local variable declaration. */
6758 static void
6759 declare_local_variables (modifier, type, vlist)
6760 int modifier;
6761 tree type;
6762 tree vlist;
6764 tree decl, current, saved_type;
6765 tree type_wfl = NULL_TREE;
6766 int must_chain = 0;
6767 int final_p = 0;
6769 /* Push a new block if statements were seen between the last time we
6770 pushed a block and now. Keep a cound of block to close */
6771 if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
6773 tree body = GET_CURRENT_BLOCK (current_function_decl);
6774 tree b = enter_block ();
6775 BLOCK_EXPR_ORIGIN (b) = body;
6778 if (modifier)
6780 int i;
6781 for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
6782 if (modifier == ACC_FINAL)
6783 final_p = 1;
6784 else
6786 parse_error_context
6787 (ctxp->modifier_ctx [i],
6788 "Only `final' is allowed as a local variables modifier");
6789 return;
6793 /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
6794 hold the TYPE value if a new incomplete has to be created (as
6795 opposed to being found already existing and reused). */
6796 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
6798 /* If TYPE is fully resolved and we don't have a reference, make one */
6799 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6801 /* Go through all the declared variables */
6802 for (current = vlist, saved_type = type; current;
6803 current = TREE_CHAIN (current), type = saved_type)
6805 tree other, real_type;
6806 tree wfl = TREE_PURPOSE (current);
6807 tree name = EXPR_WFL_NODE (wfl);
6808 tree init = TREE_VALUE (current);
6810 /* Process NAME, as it may specify extra dimension(s) for it */
6811 type = build_array_from_name (type, type_wfl, name, &name);
6813 /* Variable redefinition check */
6814 if ((other = lookup_name_in_blocks (name)))
6816 variable_redefinition_error (wfl, name, TREE_TYPE (other),
6817 DECL_SOURCE_LINE (other));
6818 continue;
6821 /* Type adjustment. We may have just readjusted TYPE because
6822 the variable specified more dimensions. Make sure we have
6823 a reference if we can and don't have one already. */
6824 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6826 real_type = GET_REAL_TYPE (type);
6827 /* Never layout this decl. This will be done when its scope
6828 will be entered */
6829 decl = build_decl (VAR_DECL, name, real_type);
6830 LOCAL_FINAL (decl) = final_p;
6831 BLOCK_CHAIN_DECL (decl);
6833 /* If doing xreferencing, replace the line number with the WFL
6834 compound value */
6835 if (flag_emit_xref)
6836 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
6838 /* Don't try to use an INIT statement when an error was found */
6839 if (init && java_error_count)
6840 init = NULL_TREE;
6842 /* Add the initialization function to the current function's code */
6843 if (init)
6845 /* Name might have been readjusted */
6846 EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
6847 MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
6848 java_method_add_stmt (current_function_decl,
6849 build_debugable_stmt (EXPR_WFL_LINECOL (init),
6850 init));
6853 /* Setup dependency the type of the decl */
6854 if (must_chain)
6856 jdep *dep;
6857 register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
6858 dep = CLASSD_LAST (ctxp->classd_list);
6859 JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
6862 SOURCE_FRONTEND_DEBUG (("Defined locals"));
6865 /* Called during parsing. Build decls from argument list. */
6867 static void
6868 source_start_java_method (fndecl)
6869 tree fndecl;
6871 tree tem;
6872 tree parm_decl;
6873 int i;
6875 if (!fndecl)
6876 return;
6878 current_function_decl = fndecl;
6880 /* New scope for the function */
6881 enter_block ();
6882 for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
6883 tem != end_params_node; tem = TREE_CHAIN (tem), i++)
6885 tree type = TREE_VALUE (tem);
6886 tree name = TREE_PURPOSE (tem);
6888 /* If type is incomplete. Create an incomplete decl and ask for
6889 the decl to be patched later */
6890 if (INCOMPLETE_TYPE_P (type))
6892 jdep *jdep;
6893 tree real_type = GET_REAL_TYPE (type);
6894 parm_decl = build_decl (PARM_DECL, name, real_type);
6895 type = obtain_incomplete_type (type);
6896 register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
6897 jdep = CLASSD_LAST (ctxp->classd_list);
6898 JDEP_MISC (jdep) = name;
6899 JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
6901 else
6902 parm_decl = build_decl (PARM_DECL, name, type);
6904 /* Remember if a local variable was declared final (via its
6905 TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
6906 if (ARG_FINAL_P (tem))
6907 LOCAL_FINAL (parm_decl) = 1;
6909 BLOCK_CHAIN_DECL (parm_decl);
6911 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
6912 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
6913 nreverse (tem);
6914 DECL_ARG_SLOT_COUNT (current_function_decl) = i;
6915 DECL_MAX_LOCALS (current_function_decl) = i;
6918 /* Called during parsing. Creates an artificial method declaration. */
6920 static tree
6921 create_artificial_method (class, flags, type, name, args)
6922 tree class;
6923 int flags;
6924 tree type, name, args;
6926 tree mdecl;
6928 java_parser_context_save_global ();
6929 lineno = 0;
6930 mdecl = make_node (FUNCTION_TYPE);
6931 TREE_TYPE (mdecl) = type;
6932 TYPE_ARG_TYPES (mdecl) = args;
6933 mdecl = add_method (class, flags, name, build_java_signature (mdecl));
6934 java_parser_context_restore_global ();
6935 DECL_ARTIFICIAL (mdecl) = 1;
6936 return mdecl;
6939 /* Starts the body if an artifical method. */
6941 static void
6942 start_artificial_method_body (mdecl)
6943 tree mdecl;
6945 DECL_SOURCE_LINE (mdecl) = 1;
6946 DECL_SOURCE_LINE_MERGE (mdecl, 1);
6947 source_start_java_method (mdecl);
6948 enter_block ();
6951 static void
6952 end_artificial_method_body (mdecl)
6953 tree mdecl;
6955 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
6956 exit_block ();
6959 /* Called during expansion. Push decls formerly built from argument
6960 list so they're usable during expansion. */
6962 static void
6963 expand_start_java_method (fndecl)
6964 tree fndecl;
6966 tree tem, *ptr;
6968 current_function_decl = fndecl;
6970 if (! quiet_flag)
6971 fprintf (stderr, " [%s.", lang_printable_name (DECL_CONTEXT (fndecl), 0));
6972 announce_function (fndecl);
6973 if (! quiet_flag)
6974 fprintf (stderr, "]");
6976 pushlevel (1); /* Prepare for a parameter push */
6977 ptr = &DECL_ARGUMENTS (fndecl);
6978 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
6979 while (tem)
6981 tree next = TREE_CHAIN (tem);
6982 tree type = TREE_TYPE (tem);
6983 if (PROMOTE_PROTOTYPES
6984 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
6985 && INTEGRAL_TYPE_P (type))
6986 type = integer_type_node;
6987 DECL_ARG_TYPE (tem) = type;
6988 layout_decl (tem, 0);
6989 pushdecl (tem);
6990 *ptr = tem;
6991 ptr = &TREE_CHAIN (tem);
6992 tem = next;
6994 *ptr = NULL_TREE;
6995 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
6996 lineno = DECL_SOURCE_LINE_FIRST (fndecl);
6999 /* Terminate a function and expand its body. */
7001 static void
7002 source_end_java_method ()
7004 tree fndecl = current_function_decl;
7005 int flag_asynchronous_exceptions = asynchronous_exceptions;
7007 if (!fndecl)
7008 return;
7010 java_parser_context_save_global ();
7011 lineno = ctxp->last_ccb_indent1;
7013 /* Set EH language codes */
7014 java_set_exception_lang_code ();
7016 /* Turn function bodies with only a NOP expr null, so they don't get
7017 generated at all and we won't get warnings when using the -W
7018 -Wall flags. */
7019 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7020 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7022 /* Generate function's code */
7023 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7024 && ! flag_emit_class_files
7025 && ! flag_emit_xref)
7026 expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7028 /* pop out of its parameters */
7029 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7030 poplevel (1, 0, 1);
7031 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7033 /* Generate rtl for function exit. */
7034 if (! flag_emit_class_files && ! flag_emit_xref)
7036 lineno = DECL_SOURCE_LINE_LAST (fndecl);
7037 /* Emit catch-finally clauses */
7038 emit_handlers ();
7039 expand_function_end (input_filename, lineno, 0);
7041 /* FIXME: If the current method contains any exception handlers,
7042 force asynchronous_exceptions: this is necessary because signal
7043 handlers in libjava may throw exceptions. This is far from being
7044 a perfect solution, but it's better than doing nothing at all.*/
7045 if (catch_clauses)
7046 asynchronous_exceptions = 1;
7048 /* Run the optimizers and output assembler code for this function. */
7049 rest_of_compilation (fndecl);
7052 current_function_decl = NULL_TREE;
7053 permanent_allocation (1);
7054 java_parser_context_restore_global ();
7055 asynchronous_exceptions = flag_asynchronous_exceptions;
7058 /* Record EXPR in the current function block. Complements compound
7059 expression second operand if necessary. */
7061 tree
7062 java_method_add_stmt (fndecl, expr)
7063 tree fndecl, expr;
7065 if (!GET_CURRENT_BLOCK (fndecl))
7066 return NULL_TREE;
7067 return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7070 static tree
7071 add_stmt_to_block (b, type, stmt)
7072 tree b, type, stmt;
7074 tree body = BLOCK_EXPR_BODY (b), c;
7076 if (java_error_count)
7077 return body;
7079 if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7080 return body;
7082 BLOCK_EXPR_BODY (b) = c;
7083 TREE_SIDE_EFFECTS (c) = 1;
7084 return c;
7087 /* Add STMT to EXISTING if possible, otherwise create a new
7088 COMPOUND_EXPR and add STMT to it. */
7090 static tree
7091 add_stmt_to_compound (existing, type, stmt)
7092 tree existing, type, stmt;
7094 if (existing)
7095 return build (COMPOUND_EXPR, type, existing, stmt);
7096 else
7097 return stmt;
7100 /* Hold THIS for the scope of the current public method decl. */
7101 static tree current_this;
7103 void java_layout_seen_class_methods ()
7105 tree previous_list = all_class_list;
7106 tree end = NULL_TREE;
7107 tree current;
7109 while (1)
7111 for (current = previous_list;
7112 current != end; current = TREE_CHAIN (current))
7113 layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7115 if (previous_list != all_class_list)
7117 end = previous_list;
7118 previous_list = all_class_list;
7120 else
7121 break;
7125 void
7126 java_reorder_fields ()
7128 static tree stop_reordering = NULL_TREE;
7130 tree current;
7131 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7133 current_class = TREE_TYPE (TREE_VALUE (current));
7135 if (current_class == stop_reordering)
7136 break;
7138 /* Reverse the fields, but leave the dummy field in front.
7139 Fields are already ordered for Object and Class */
7140 if (TYPE_FIELDS (current_class) && current_class != object_type_node
7141 && current_class != class_type_node)
7143 /* If the dummy field is there, reverse the right fields and
7144 just layout the type for proper fields offset */
7145 if (!DECL_NAME (TYPE_FIELDS (current_class)))
7147 tree fields = TYPE_FIELDS (current_class);
7148 TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7149 TYPE_SIZE (current_class) = NULL_TREE;
7151 /* We don't have a dummy field, we need to layout the class,
7152 after having reversed the fields */
7153 else
7155 TYPE_FIELDS (current_class) =
7156 nreverse (TYPE_FIELDS (current_class));
7157 TYPE_SIZE (current_class) = NULL_TREE;
7161 stop_reordering = TREE_TYPE (TREE_VALUE (ctxp->gclass_list));
7164 /* Layout the methods of all classes loaded in one way on an
7165 other. Check methods of source parsed classes. Then reorder the
7166 fields and layout the classes or the type of all source parsed
7167 classes */
7169 void
7170 java_layout_classes ()
7172 tree current;
7173 int save_error_count = java_error_count;
7175 /* Layout the methods of all classes seen so far */
7176 java_layout_seen_class_methods ();
7177 java_parse_abort_on_error ();
7178 all_class_list = NULL_TREE;
7180 /* Then check the methods of all parsed classes */
7181 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7182 if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7183 CHECK_METHODS (TREE_VALUE (current));
7184 java_parse_abort_on_error ();
7186 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7188 current_class = TREE_TYPE (TREE_VALUE (current));
7189 layout_class (current_class);
7191 /* From now on, the class is considered completely loaded */
7192 CLASS_LOADED_P (current_class) = 1;
7194 /* Error reported by the caller */
7195 if (java_error_count)
7196 return;
7199 /* We might have reloaded classes durign the process of laying out
7200 classes for code generation. We must layout the methods of those
7201 late additions, as constructor checks might use them */
7202 java_layout_seen_class_methods ();
7203 java_parse_abort_on_error ();
7206 /* Expand methods in the current set of classes rememebered for
7207 generation. */
7209 static void
7210 java_complete_expand_classes ()
7212 tree current;
7214 do_not_fold = flag_emit_xref;
7216 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7217 if (!INNER_CLASS_DECL_P (current))
7218 java_complete_expand_class (current);
7221 /* Expand the methods found in OUTER, starting first by OUTER's inner
7222 classes, if any. */
7224 static void
7225 java_complete_expand_class (outer)
7226 tree outer;
7228 tree inner_list;
7230 set_nested_class_simple_name_value (outer, 1); /* Set */
7232 /* We need to go after all inner classes and start expanding them,
7233 starting with most nested ones. We have to do that because nested
7234 classes might add functions to outer classes */
7236 for (inner_list = DECL_INNER_CLASS_LIST (outer);
7237 inner_list; inner_list = TREE_CHAIN (inner_list))
7238 java_complete_expand_class (TREE_PURPOSE (inner_list));
7240 java_complete_expand_methods (outer);
7241 set_nested_class_simple_name_value (outer, 0); /* Reset */
7244 /* Expand methods registered in CLASS_DECL. The general idea is that
7245 we expand regular methods first. This allows us get an estimate on
7246 how outer context local alias fields are really used so we can add
7247 to the constructor just enough code to initialize them properly (it
7248 also lets us generate $finit$ correctly.) Then we expand the
7249 constructors and then <clinit>. */
7251 static void
7252 java_complete_expand_methods (class_decl)
7253 tree class_decl;
7255 tree clinit, finit, decl, first_decl;
7257 current_class = TREE_TYPE (class_decl);
7259 /* Initialize a new constant pool */
7260 init_outgoing_cpool ();
7262 /* Pre-expand <clinit> to figure whether we really need it or
7263 not. If we do need it, we pre-expand the static fields so they're
7264 ready to be used somewhere else. <clinit> will be fully expanded
7265 after we processed the constructors. */
7266 first_decl = TYPE_METHODS (current_class);
7267 clinit = maybe_generate_pre_expand_clinit (current_class);
7269 /* Then generate $finit$ (if we need to) because constructor will
7270 try to use it.*/
7271 if (TYPE_FINIT_STMT_LIST (current_class))
7273 finit = generate_finit (current_class);
7274 java_complete_expand_method (finit);
7277 /* Now do the constructors */
7278 for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7280 int no_body;
7282 if (!DECL_CONSTRUCTOR_P (decl))
7283 continue;
7285 no_body = !DECL_FUNCTION_BODY (decl);
7286 /* Don't generate debug info on line zero when expanding a
7287 generated constructor. */
7288 if (no_body)
7289 restore_line_number_status (1);
7291 java_complete_expand_method (decl);
7293 if (no_body)
7294 restore_line_number_status (0);
7297 /* First, do the ordinary methods. */
7298 for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7300 /* Skip abstract or native methods -- but do handle native
7301 methods when generating JNI stubs. */
7302 if (METHOD_ABSTRACT (decl)
7303 || (! flag_jni && METHOD_NATIVE (decl))
7304 || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7305 continue;
7307 if (METHOD_NATIVE (decl))
7309 tree body = build_jni_stub (decl);
7310 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7313 java_complete_expand_method (decl);
7316 /* If there is indeed a <clinit>, fully expand it now */
7317 if (clinit)
7319 /* Prevent the use of `this' inside <clinit> */
7320 ctxp->explicit_constructor_p = 1;
7321 java_complete_expand_method (clinit);
7322 ctxp->explicit_constructor_p = 0;
7325 /* We might have generated a class$ that we now want to expand */
7326 if (TYPE_DOT_CLASS (current_class))
7327 java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7329 /* Now verify constructor circularity (stop after the first one we
7330 prove wrong.) */
7331 if (!CLASS_INTERFACE (class_decl))
7332 for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7333 if (DECL_CONSTRUCTOR_P (decl)
7334 && verify_constructor_circularity (decl, decl))
7335 break;
7337 /* Save the constant pool. We'll need to restore it later. */
7338 TYPE_CPOOL (current_class) = outgoing_cpool;
7341 /* Hold a list of catch clauses list. The first element of this list is
7342 the list of the catch clauses of the currently analysed try block. */
7343 static tree currently_caught_type_list;
7345 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7346 safely used in some other methods/constructors. */
7348 static tree
7349 maybe_generate_pre_expand_clinit (class_type)
7350 tree class_type;
7352 tree current, mdecl;
7354 if (!TYPE_CLINIT_STMT_LIST (class_type))
7355 return NULL_TREE;
7357 /* Go through all static fields and pre expand them */
7358 for (current = TYPE_FIELDS (class_type); current;
7359 current = TREE_CHAIN (current))
7360 if (FIELD_STATIC (current))
7361 build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7363 /* Then build the <clinit> method */
7364 mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7365 clinit_identifier_node, end_params_node);
7366 layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7367 mdecl, NULL_TREE);
7368 start_artificial_method_body (mdecl);
7370 /* We process the list of assignment we produced as the result of
7371 the declaration of initialized static field and add them as
7372 statement to the <clinit> method. */
7373 for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7374 current = TREE_CHAIN (current))
7376 /* We build the assignment expression that will initialize the
7377 field to its value. There are strict rules on static
7378 initializers (8.5). FIXME */
7379 tree stmt = build_debugable_stmt (EXPR_WFL_LINECOL (current), current);
7380 java_method_add_stmt (mdecl, stmt);
7383 end_artificial_method_body (mdecl);
7385 /* Now we want to place <clinit> as the last method for interface so
7386 that it doesn't interfere with the dispatch table based
7387 lookup. */
7388 if (CLASS_INTERFACE (TYPE_NAME (class_type))
7389 && TREE_CHAIN (TYPE_METHODS (class_type)))
7391 tree current =
7392 TYPE_METHODS (class_type) = TREE_CHAIN (TYPE_METHODS (class_type));
7394 while (TREE_CHAIN (current))
7395 current = TREE_CHAIN (current);
7396 TREE_CHAIN (current) = mdecl;
7397 TREE_CHAIN (mdecl) = NULL_TREE;
7400 return mdecl;
7403 /* Complete and expand a method. */
7405 static void
7406 java_complete_expand_method (mdecl)
7407 tree mdecl;
7409 current_function_decl = mdecl;
7410 /* Fix constructors before expanding them */
7411 if (DECL_CONSTRUCTOR_P (mdecl))
7412 fix_constructors (mdecl);
7414 /* Expand functions that have a body */
7415 if (DECL_FUNCTION_BODY (mdecl))
7417 tree fbody = DECL_FUNCTION_BODY (mdecl);
7418 tree block_body = BLOCK_EXPR_BODY (fbody);
7419 tree exception_copy = NULL_TREE;
7420 expand_start_java_method (mdecl);
7421 build_result_decl (mdecl);
7423 current_this
7424 = (!METHOD_STATIC (mdecl) ?
7425 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7427 /* Purge the `throws' list of unchecked exceptions. If we're
7428 doing xref, save a copy of the list and re-install it
7429 later. */
7430 if (flag_emit_xref)
7431 exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7433 purge_unchecked_exceptions (mdecl);
7435 /* Install exceptions thrown with `throws' */
7436 PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7438 if (block_body != NULL_TREE)
7440 block_body = java_complete_tree (block_body);
7442 if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
7443 check_for_initialization (block_body);
7444 ctxp->explicit_constructor_p = 0;
7447 BLOCK_EXPR_BODY (fbody) = block_body;
7449 /* If we saw a return but couldn't evaluate it properly, we'll
7450 have an error_mark_node here. */
7451 if (block_body != error_mark_node
7452 && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7453 && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7454 && !flag_emit_xref)
7455 missing_return_error (current_function_decl);
7457 complete_start_java_method (mdecl);
7459 /* Don't go any further if we've found error(s) during the
7460 expansion */
7461 if (!java_error_count)
7462 source_end_java_method ();
7463 else
7465 pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7466 poplevel (1, 0, 1);
7469 /* Pop the exceptions and sanity check */
7470 POP_EXCEPTIONS();
7471 if (currently_caught_type_list)
7472 fatal ("Exception list non empty - java_complete_expand_method");
7474 if (flag_emit_xref)
7475 DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7481 /* This section of the code deals with accessing enclosing context
7482 fields either directly by using the relevant access to this$<n> or
7483 by invoking an access method crafted for that purpose. */
7485 /* Build the necessary access from an inner class to an outer
7486 class. This routine could be optimized to cache previous result
7487 (decl, current_class and returned access). When an access method
7488 needs to be generated, it always takes the form of a read. It might
7489 be later turned into a write by calling outer_field_access_fix. */
7491 static tree
7492 build_outer_field_access (id, decl)
7493 tree id, decl;
7495 tree access = NULL_TREE;
7496 tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7498 /* If decl's class is the direct outer class of the current_class,
7499 build the access as `this$<n>.<field>'. Not that we will break
7500 the `private' barrier if we're not emitting bytecodes. */
7501 if (ctx == DECL_CONTEXT (decl)
7502 && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7504 tree thisn = build_current_thisn (current_class);
7505 access = make_qualified_primary (build_wfl_node (thisn),
7506 id, EXPR_WFL_LINECOL (id));
7508 /* Otherwise, generate access methods to outer this and access the
7509 field (either using an access method or by direct access.) */
7510 else
7512 int lc = EXPR_WFL_LINECOL (id);
7514 /* Now we chain the required number of calls to the access$0 to
7515 get a hold to the enclosing instance we need, and the we
7516 build the field access. */
7517 access = build_access_to_thisn (ctx, DECL_CONTEXT (decl), lc);
7519 /* If the field is private and we're generating bytecode, then
7520 we generate an access method */
7521 if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7523 tree name = build_outer_field_access_methods (decl);
7524 access = build_outer_field_access_expr (lc, DECL_CONTEXT (decl),
7525 name, access, NULL_TREE);
7527 /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7528 Once again we break the `private' access rule from a foreign
7529 class. */
7530 else
7531 access = make_qualified_primary (access, id, lc);
7533 return resolve_expression_name (access, NULL);
7536 /* Return a non zero value if NODE describes an outer field inner
7537 access. */
7539 static int
7540 outer_field_access_p (type, decl)
7541 tree type, decl;
7543 if (!INNER_CLASS_TYPE_P (type)
7544 || TREE_CODE (decl) != FIELD_DECL
7545 || DECL_CONTEXT (decl) == type)
7546 return 0;
7548 for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7549 type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7551 if (type == DECL_CONTEXT (decl))
7552 return 1;
7553 if (!DECL_CONTEXT (TYPE_NAME (type)))
7554 break;
7557 return 0;
7560 /* Return a non zero value if NODE represents an outer field inner
7561 access that was been already expanded. As a side effect, it returns
7562 the name of the field being accessed and the argument passed to the
7563 access function, suitable for a regeneration of the access method
7564 call if necessary. */
7566 static int
7567 outer_field_expanded_access_p (node, name, arg_type, arg)
7568 tree node, *name, *arg_type, *arg;
7570 int identified = 0;
7572 if (TREE_CODE (node) != CALL_EXPR)
7573 return 0;
7575 /* Well, gcj generates slightly different tree nodes when compiling
7576 to native or bytecodes. It's the case for function calls. */
7578 if (flag_emit_class_files
7579 && TREE_CODE (node) == CALL_EXPR
7580 && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7581 identified = 1;
7582 else if (!flag_emit_class_files)
7584 node = TREE_OPERAND (node, 0);
7586 if (node && TREE_OPERAND (node, 0)
7587 && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7589 node = TREE_OPERAND (node, 0);
7590 if (TREE_OPERAND (node, 0)
7591 && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7592 && (OUTER_FIELD_ACCESS_IDENTIFIER_P
7593 (DECL_NAME (TREE_OPERAND (node, 0)))))
7594 identified = 1;
7598 if (identified && name && arg_type && arg)
7600 tree argument = TREE_OPERAND (node, 1);
7601 *name = DECL_NAME (TREE_OPERAND (node, 0));
7602 *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7603 *arg = TREE_VALUE (argument);
7605 return identified;
7608 /* Detect in NODE an outer field read access from an inner class and
7609 transform it into a write with RHS as an argument. This function is
7610 called from the java_complete_lhs when an assignment to a LHS can
7611 be identified. */
7613 static tree
7614 outer_field_access_fix (wfl, node, rhs)
7615 tree wfl, node, rhs;
7617 tree name, arg_type, arg;
7619 if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7621 /* At any rate, check whether we're trying to assign a value to
7622 a final. */
7623 tree accessed = (JDECL_P (node) ? node :
7624 (TREE_CODE (node) == COMPONENT_REF ?
7625 TREE_OPERAND (node, 1) : node));
7626 if (check_final_assignment (accessed, wfl))
7627 return error_mark_node;
7629 node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl),
7630 arg_type, name, arg, rhs);
7631 return java_complete_tree (node);
7633 return NULL_TREE;
7636 /* Construct the expression that calls an access method:
7637 <type>.access$<n>(<arg1> [, <arg2>]);
7639 ARG2 can be NULL and will be omitted in that case. It will denote a
7640 read access. */
7642 static tree
7643 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
7644 int lc;
7645 tree type, access_method_name, arg1, arg2;
7647 tree args, cn, access;
7649 args = arg1 ? arg1 :
7650 build_wfl_node (build_current_thisn (current_class));
7651 args = build_tree_list (NULL_TREE, args);
7653 if (arg2)
7654 args = tree_cons (NULL_TREE, arg2, args);
7656 access = build_method_invocation (build_wfl_node (access_method_name), args);
7657 cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
7658 return make_qualified_primary (cn, access, lc);
7661 static tree
7662 build_new_access_id ()
7664 static int access_n_counter = 1;
7665 char buffer [128];
7667 sprintf (buffer, "access$%d", access_n_counter++);
7668 return get_identifier (buffer);
7671 /* Create the static access functions for the outer field DECL. We define a
7672 read:
7673 TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
7674 return inst$.field;
7676 and a write access:
7677 TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
7678 TREE_TYPE (<field>) value$) {
7679 return inst$.field = value$;
7681 We should have a usage flags on the DECL so we can lazily turn the ones
7682 we're using for code generation. FIXME.
7685 static tree
7686 build_outer_field_access_methods (decl)
7687 tree decl;
7689 tree id, args, stmt, mdecl;
7691 /* Check point, to be removed. FIXME */
7692 if (FIELD_INNER_ACCESS (decl)
7693 && TREE_CODE (FIELD_INNER_ACCESS (decl)) != IDENTIFIER_NODE)
7694 abort ();
7696 if (FIELD_INNER_ACCESS (decl))
7697 return FIELD_INNER_ACCESS (decl);
7699 push_obstacks (&permanent_obstack, &permanent_obstack);
7701 /* Create the identifier and a function named after it. */
7702 id = build_new_access_id ();
7704 /* The identifier is marked as bearing the name of a generated write
7705 access function for outer field accessed from inner classes. */
7706 OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7708 /* Create the read access */
7709 args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7710 TREE_CHAIN (args) = end_params_node;
7711 stmt = make_qualified_primary (build_wfl_node (inst_id),
7712 build_wfl_node (DECL_NAME (decl)), 0);
7713 stmt = build_return (0, stmt);
7714 mdecl = build_outer_field_access_method (DECL_CONTEXT (decl),
7715 TREE_TYPE (decl), id, args, stmt);
7716 DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7718 /* Create the write access method */
7719 args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7720 TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
7721 TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
7722 stmt = make_qualified_primary (build_wfl_node (inst_id),
7723 build_wfl_node (DECL_NAME (decl)), 0);
7724 stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
7725 build_wfl_node (wpv_id)));
7727 mdecl = build_outer_field_access_method (DECL_CONTEXT (decl),
7728 TREE_TYPE (decl), id, args, stmt);
7729 DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7730 pop_obstacks ();
7732 /* Return the access name */
7733 return FIELD_INNER_ACCESS (decl) = id;
7736 /* Build an field access method NAME. */
7738 static tree
7739 build_outer_field_access_method (class, type, name, args, body)
7740 tree class, type, name, args, body;
7742 tree saved_current_function_decl, mdecl;
7744 /* Create the method */
7745 mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
7746 fix_method_argument_names (args, mdecl);
7747 layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7749 /* Attach the method body. */
7750 saved_current_function_decl = current_function_decl;
7751 start_artificial_method_body (mdecl);
7752 java_method_add_stmt (mdecl, body);
7753 end_artificial_method_body (mdecl);
7754 current_function_decl = saved_current_function_decl;
7756 return mdecl;
7760 /* This section deals with building access function necessary for
7761 certain kinds of method invocation from inner classes. */
7763 static tree
7764 build_outer_method_access_method (decl)
7765 tree decl;
7767 tree saved_current_function_decl, mdecl;
7768 tree args = NULL_TREE, call_args = NULL_TREE;
7769 tree carg, id, body, class;
7770 char buffer [80];
7771 int parm_id_count = 0;
7773 /* Test this abort with an access to a private field */
7774 if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
7775 abort ();
7777 /* Check the cache first */
7778 if (DECL_FUNCTION_INNER_ACCESS (decl))
7779 return DECL_FUNCTION_INNER_ACCESS (decl);
7781 class = DECL_CONTEXT (decl);
7783 /* Obtain an access identifier and mark it */
7784 id = build_new_access_id ();
7785 OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7787 push_obstacks (&permanent_obstack, &permanent_obstack);
7789 carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
7790 /* Create the arguments, as much as the original */
7791 for (; carg && carg != end_params_node;
7792 carg = TREE_CHAIN (carg))
7794 sprintf (buffer, "write_parm_value$%d", parm_id_count++);
7795 args = chainon (args, build_tree_list (get_identifier (buffer),
7796 TREE_VALUE (carg)));
7798 args = chainon (args, end_params_node);
7800 /* Create the method */
7801 mdecl = create_artificial_method (class, ACC_STATIC,
7802 TREE_TYPE (TREE_TYPE (decl)), id, args);
7803 layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7804 /* There is a potential bug here. We should be able to use
7805 fix_method_argument_names, but then arg names get mixed up and
7806 eventually a constructor will have its this$0 altered and the
7807 outer context won't be assignment properly. The test case is
7808 stub.java FIXME */
7809 TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
7811 /* Attach the method body. */
7812 saved_current_function_decl = current_function_decl;
7813 start_artificial_method_body (mdecl);
7815 /* The actual method invocation uses the same args. When invoking a
7816 static methods that way, we don't want to skip the first
7817 argument. */
7818 carg = args;
7819 if (!METHOD_STATIC (decl))
7820 carg = TREE_CHAIN (carg);
7821 for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
7822 call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
7823 call_args);
7825 body = build_method_invocation (build_wfl_node (DECL_NAME (decl)),
7826 call_args);
7827 if (!METHOD_STATIC (decl))
7828 body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)),
7829 body, 0);
7830 if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
7831 body = build_return (0, body);
7832 java_method_add_stmt (mdecl,body);
7833 end_artificial_method_body (mdecl);
7834 current_function_decl = saved_current_function_decl;
7835 pop_obstacks ();
7837 /* Back tag the access function so it know what it accesses */
7838 DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
7840 /* Tag the current method so it knows it has an access generated */
7841 return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
7845 /* This section of the code deals with building expressions to access
7846 the enclosing instance of an inner class. The enclosing instance is
7847 kept in a generated field called this$<n>, with <n> being the
7848 inner class nesting level (starting from 0.) */
7850 /* Build an access to a given this$<n>, possibly by chaining access
7851 call to others. Access methods to this$<n> are build on the fly if
7852 necessary */
7854 static tree
7855 build_access_to_thisn (from, to, lc)
7856 tree from, to;
7857 int lc;
7859 tree access = NULL_TREE;
7861 while (from != to)
7863 tree access0_wfl, cn;
7865 maybe_build_thisn_access_method (from);
7866 access0_wfl = build_wfl_node (access0_identifier_node);
7867 cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
7868 EXPR_WFL_LINECOL (access0_wfl) = lc;
7870 if (!access)
7872 access = build_current_thisn (current_class);
7873 access = build_wfl_node (access);
7875 access = build_tree_list (NULL_TREE, access);
7876 access = build_method_invocation (access0_wfl, access);
7877 access = make_qualified_primary (cn, access, lc);
7879 from = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (from)));
7881 return access;
7884 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
7885 is returned if nothing needs to be generated. Otherwise, the method
7886 generated, fully walked and a method decl is returned.
7888 NOTE: These generated methods should be declared in a class file
7889 attribute so that they can't be referred to directly. */
7891 static tree
7892 maybe_build_thisn_access_method (type)
7893 tree type;
7895 tree mdecl, args, stmt, rtype;
7896 tree saved_current_function_decl;
7898 /* If TYPE is a top-level class, no access method is required.
7899 If there already is such an access method, bail out. */
7900 if (CLASS_ACCESS0_GENERATED_P (type) || !INNER_CLASS_TYPE_P (type))
7901 return NULL_TREE;
7903 /* We generate the method. The method looks like:
7904 static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
7906 push_obstacks (&permanent_obstack, &permanent_obstack);
7907 args = build_tree_list (inst_id, build_pointer_type (type));
7908 TREE_CHAIN (args) = end_params_node;
7909 rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
7910 mdecl = create_artificial_method (type, ACC_STATIC, rtype,
7911 access0_identifier_node, args);
7912 fix_method_argument_names (args, mdecl);
7913 layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
7914 stmt = build_current_thisn (type);
7915 stmt = make_qualified_primary (build_wfl_node (inst_id),
7916 build_wfl_node (stmt), 0);
7917 stmt = build_return (0, stmt);
7919 saved_current_function_decl = current_function_decl;
7920 start_artificial_method_body (mdecl);
7921 java_method_add_stmt (mdecl, stmt);
7922 end_artificial_method_body (mdecl);
7923 current_function_decl = saved_current_function_decl;
7924 pop_obstacks ();
7926 CLASS_ACCESS0_GENERATED_P (type) = 1;
7928 return mdecl;
7931 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
7932 the first level of innerclassing. this$1 for the next one, etc...
7933 This function can be invoked with TYPE to NULL, available and then
7934 has to count the parser context. */
7936 static tree
7937 build_current_thisn (type)
7938 tree type;
7940 static int saved_i = -1;
7941 static tree saved_thisn = NULL_TREE;
7943 tree decl;
7944 char buffer [80];
7945 int i = 0;
7947 if (type)
7949 static tree saved_type = NULL_TREE;
7950 static int saved_type_i = 0;
7952 if (type == saved_type)
7953 i = saved_type_i;
7954 else
7956 for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type));
7957 decl; decl = DECL_CONTEXT (decl), i++)
7960 saved_type = type;
7961 saved_type_i = i;
7964 else
7965 i = list_length (GET_CPC_LIST ())-2;
7967 if (i == saved_i)
7968 return saved_thisn;
7970 sprintf (buffer, "this$%d", i);
7971 saved_i = i;
7972 saved_thisn = get_identifier (buffer);
7973 return saved_thisn;
7976 /* Return the assignement to the hidden enclosing context `this$<n>'
7977 by the second incoming parameter to the innerclass constructor. The
7978 form used is `this.this$<n> = this$<n>;'. */
7980 static tree
7981 build_thisn_assign ()
7983 if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
7985 tree thisn = build_current_thisn (current_class);
7986 tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
7987 build_wfl_node (thisn), 0);
7988 tree rhs = build_wfl_node (thisn);
7989 EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
7990 return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
7992 return NULL_TREE;
7996 /* Building the synthetic `class$' used to implement the `.class' 1.1
7997 extension for non primitive types. This method looks like:
7999 static Class class$(String type) throws NoClassDefFoundError
8001 try {return (java.lang.Class.forName (String));}
8002 catch (ClassNotFoundException e) {
8003 throw new NoClassDefFoundError(e.getMessage());}
8004 } */
8006 static tree
8007 build_dot_class_method (class)
8008 tree class;
8010 #define BWF(S) build_wfl_node (get_identifier ((S)))
8011 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8012 tree args, tmp, saved_current_function_decl, mdecl;
8013 tree stmt, throw_stmt, catch, catch_block, try_block;
8014 tree catch_clause_param;
8015 tree class_not_found_exception, no_class_def_found_error;
8017 static tree get_message_wfl, type_parm_wfl;
8019 if (!get_message_wfl)
8021 get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8022 type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8025 /* Build the arguments */
8026 args = build_tree_list (get_identifier ("type$"),
8027 build_pointer_type (string_type_node));
8028 TREE_CHAIN (args) = end_params_node;
8030 /* Build the qualified name java.lang.Class.forName */
8031 tmp = MQN (MQN (MQN (BWF ("java"),
8032 BWF ("lang")), BWF ("Class")), BWF ("forName"));
8034 /* For things we have to catch and throw */
8035 class_not_found_exception =
8036 lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8037 no_class_def_found_error =
8038 lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8039 load_class (class_not_found_exception, 1);
8040 load_class (no_class_def_found_error, 1);
8042 /* Create the "class$" function */
8043 mdecl = create_artificial_method (class, ACC_STATIC,
8044 build_pointer_type (class_type_node),
8045 get_identifier ("class$"), args);
8046 DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8047 no_class_def_found_error);
8049 /* We start by building the try block. We need to build:
8050 return (java.lang.Class.forName (type)); */
8051 stmt = build_method_invocation (tmp,
8052 build_tree_list (NULL_TREE, type_parm_wfl));
8053 stmt = build_return (0, stmt);
8054 /* Put it in a block. That's the try block */
8055 try_block = build_expr_block (stmt, NULL_TREE);
8057 /* Now onto the catch block. We start by building the expression
8058 throwing a new exception:
8059 throw new NoClassDefFoundError (_.getMessage); */
8060 throw_stmt = make_qualified_name (build_wfl_node (wpv_id),
8061 get_message_wfl, 0);
8062 throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8064 /* Build new NoClassDefFoundError (_.getMessage) */
8065 throw_stmt = build_new_invocation
8066 (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8067 build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8069 /* Build the throw, (it's too early to use BUILD_THROW) */
8070 throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8072 /* Build the catch block to encapsulate all this. We begin by
8073 building an decl for the catch clause parameter and link it to
8074 newly created block, the catch block. */
8075 catch_clause_param =
8076 build_decl (VAR_DECL, wpv_id,
8077 build_pointer_type (class_not_found_exception));
8078 catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8080 /* We initialize the variable with the exception handler. */
8081 catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8082 soft_exceptioninfo_call_node);
8083 add_stmt_to_block (catch_block, NULL_TREE, catch);
8085 /* We add the statement throwing the new exception */
8086 add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8088 /* Build a catch expression for all this */
8089 catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8091 /* Build the try/catch sequence */
8092 stmt = build_try_statement (0, try_block, catch_block);
8094 fix_method_argument_names (args, mdecl);
8095 layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8096 saved_current_function_decl = current_function_decl;
8097 start_artificial_method_body (mdecl);
8098 java_method_add_stmt (mdecl, stmt);
8099 end_artificial_method_body (mdecl);
8100 current_function_decl = saved_current_function_decl;
8101 TYPE_DOT_CLASS (class) = mdecl;
8103 return mdecl;
8106 static tree
8107 build_dot_class_method_invocation (name)
8108 tree name;
8110 tree s = make_node (STRING_CST);
8111 TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (name);
8112 TREE_STRING_POINTER (s) = obstack_alloc (expression_obstack,
8113 TREE_STRING_LENGTH (s)+1);
8114 strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (name));
8115 return build_method_invocation (build_wfl_node (get_identifier ("class$")),
8116 build_tree_list (NULL_TREE, s));
8119 /* This section of the code deals with constructor. */
8121 /* Craft a body for default constructor. Patch existing constructor
8122 bodies with call to super() and field initialization statements if
8123 necessary. */
8125 static void
8126 fix_constructors (mdecl)
8127 tree mdecl;
8129 tree body = DECL_FUNCTION_BODY (mdecl);
8130 tree thisn_assign, compound = NULL_TREE;
8131 tree class_type = DECL_CONTEXT (mdecl);
8133 if (!body)
8135 /* It is an error for the compiler to generate a default
8136 constructor if the superclass doesn't have a constructor that
8137 takes no argument, or the same args for an anonymous class */
8138 if (verify_constructor_super (mdecl))
8140 tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8141 tree save = DECL_NAME (mdecl);
8142 const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8143 DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8144 parse_error_context
8145 (lookup_cl (TYPE_NAME (class_type)),
8146 "No constructor matching `%s' found in class `%s'",
8147 lang_printable_name (mdecl, 0), n);
8148 DECL_NAME (mdecl) = save;
8151 /* The constructor body must be crafted by hand. It's the
8152 constructor we defined when we realize we didn't have the
8153 CLASSNAME() constructor */
8154 start_artificial_method_body (mdecl);
8156 /* We don't generate a super constructor invocation if we're
8157 compiling java.lang.Object. build_super_invocation takes care
8158 of that. */
8159 compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8161 /* Insert the instance initializer block right here, after the
8162 super invocation. */
8163 add_instance_initializer (mdecl);
8165 /* Insert an assignment to the this$<n> hidden field, if
8166 necessary */
8167 if ((thisn_assign = build_thisn_assign ()))
8168 java_method_add_stmt (mdecl, thisn_assign);
8170 end_artificial_method_body (mdecl);
8172 /* Search for an explicit constructor invocation */
8173 else
8175 int found = 0;
8176 tree main_block = BLOCK_EXPR_BODY (body);
8178 while (body)
8179 switch (TREE_CODE (body))
8181 case CALL_EXPR:
8182 found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8183 body = NULL_TREE;
8184 break;
8185 case COMPOUND_EXPR:
8186 case EXPR_WITH_FILE_LOCATION:
8187 body = TREE_OPERAND (body, 0);
8188 break;
8189 case BLOCK:
8190 body = BLOCK_EXPR_BODY (body);
8191 break;
8192 default:
8193 found = 0;
8194 body = NULL_TREE;
8196 /* The constructor is missing an invocation of super() */
8197 if (!found)
8198 compound = add_stmt_to_compound (compound, NULL_TREE,
8199 build_super_invocation (mdecl));
8201 /* Insert the instance initializer block right here, after the
8202 super invocation. */
8203 add_instance_initializer (mdecl);
8205 /* Generate the assignment to this$<n>, if necessary */
8206 if ((thisn_assign = build_thisn_assign ()))
8207 compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8209 /* Fix the constructor main block if we're adding extra stmts */
8210 if (compound)
8212 compound = add_stmt_to_compound (compound, NULL_TREE,
8213 BLOCK_EXPR_BODY (main_block));
8214 BLOCK_EXPR_BODY (main_block) = compound;
8219 /* Browse constructors in the super class, searching for a constructor
8220 that doesn't take any argument. Return 0 if one is found, 1
8221 otherwise. If the current class is an anonymous inner class, look
8222 for something that has the same signature. */
8224 static int
8225 verify_constructor_super (mdecl)
8226 tree mdecl;
8228 tree class = CLASSTYPE_SUPER (current_class);
8229 tree sdecl;
8231 if (!class)
8232 return 0;
8234 if (ANONYMOUS_CLASS_P (current_class))
8236 tree mdecl_arg_type;
8237 SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8238 for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8239 if (DECL_CONSTRUCTOR_P (sdecl))
8241 tree arg_type;
8242 for (arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8243 arg_type != end_params_node &&
8244 mdecl_arg_type != end_params_node;
8245 arg_type = TREE_CHAIN (arg_type),
8246 mdecl_arg_type = TREE_CHAIN (mdecl_arg_type))
8247 if (TREE_VALUE (arg_type) != TREE_VALUE (mdecl_arg_type))
8248 break;
8250 if (arg_type == end_params_node &&
8251 mdecl_arg_type == end_params_node)
8252 return 0;
8255 else
8257 for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8259 if (DECL_CONSTRUCTOR_P (sdecl)
8260 && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)))
8261 == end_params_node)
8262 return 0;
8265 return 1;
8268 /* Generate code for all context remembered for code generation. */
8270 void
8271 java_expand_classes ()
8273 int save_error_count = 0;
8274 static struct parser_ctxt *saved_ctxp = NULL;
8276 java_parse_abort_on_error ();
8277 if (!(ctxp = ctxp_for_generation))
8278 return;
8279 java_layout_classes ();
8280 java_parse_abort_on_error ();
8282 /* The list of packages declaration seen so far needs to be
8283 reversed, so that package declared in a file being compiled gets
8284 priority over packages declared as a side effect of parsing other
8285 files.*/
8286 package_list = nreverse (package_list);
8288 saved_ctxp = ctxp_for_generation;
8289 for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8291 ctxp = ctxp_for_generation;
8292 lang_init_source (2); /* Error msgs have method prototypes */
8293 java_complete_expand_classes (); /* Complete and expand classes */
8294 java_parse_abort_on_error ();
8297 /* Find anonymous classes and expand their constructor, now they
8298 have been fixed. */
8299 for (ctxp_for_generation = saved_ctxp;
8300 ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8302 tree current;
8303 ctxp = ctxp_for_generation;
8304 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8306 current_class = TREE_TYPE (current);
8307 if (ANONYMOUS_CLASS_P (current_class))
8309 tree d;
8310 for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8312 if (DECL_CONSTRUCTOR_P (d))
8314 restore_line_number_status (1);
8315 reset_method_name (d);
8316 java_complete_expand_method (d);
8317 restore_line_number_status (0);
8318 break; /* We now there are no other ones */
8325 /* If we've found error at that stage, don't try to generate
8326 anything, unless we're emitting xrefs or checking the syntax only
8327 (but not using -fsyntax-only for the purpose of generating
8328 bytecode. */
8329 if (java_error_count && !flag_emit_xref
8330 && (!flag_syntax_only && !flag_emit_class_files))
8331 return;
8333 /* Now things are stable, go for generation of the class data. */
8334 for (ctxp_for_generation = saved_ctxp;
8335 ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8337 tree current;
8338 ctxp = ctxp_for_generation;
8339 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8341 current_class = TREE_TYPE (current);
8342 outgoing_cpool = TYPE_CPOOL (current_class);
8343 if (flag_emit_class_files)
8344 write_classfile (current_class);
8345 if (flag_emit_xref)
8346 expand_xref (current_class);
8347 else if (! flag_syntax_only)
8348 finish_class ();
8353 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8354 a tree list node containing RIGHT. Fore coming RIGHTs will be
8355 chained to this hook. LOCATION contains the location of the
8356 separating `.' operator. */
8358 static tree
8359 make_qualified_primary (primary, right, location)
8360 tree primary, right;
8361 int location;
8363 tree wfl;
8365 if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8366 wfl = build_wfl_wrap (primary);
8367 else
8369 wfl = primary;
8370 /* If wfl wasn't qualified, we build a first anchor */
8371 if (!EXPR_WFL_QUALIFICATION (wfl))
8372 EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8375 /* And chain them */
8376 EXPR_WFL_LINECOL (right) = location;
8377 chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8378 PRIMARY_P (wfl) = 1;
8379 return wfl;
8382 /* Simple merge of two name separated by a `.' */
8384 static tree
8385 merge_qualified_name (left, right)
8386 tree left, right;
8388 tree node;
8389 if (!left && !right)
8390 return NULL_TREE;
8392 if (!left)
8393 return right;
8395 if (!right)
8396 return left;
8398 obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8399 IDENTIFIER_LENGTH (left));
8400 obstack_1grow (&temporary_obstack, '.');
8401 obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8402 IDENTIFIER_LENGTH (right));
8403 node = get_identifier (obstack_base (&temporary_obstack));
8404 obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8405 QUALIFIED_P (node) = 1;
8406 return node;
8409 /* Merge the two parts of a qualified name into LEFT. Set the
8410 location information of the resulting node to LOCATION, usually
8411 inherited from the location information of the `.' operator. */
8413 static tree
8414 make_qualified_name (left, right, location)
8415 tree left, right;
8416 int location;
8418 #ifdef USE_COMPONENT_REF
8419 tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8420 EXPR_WFL_LINECOL (node) = location;
8421 return node;
8422 #else
8423 tree left_id = EXPR_WFL_NODE (left);
8424 tree right_id = EXPR_WFL_NODE (right);
8425 tree wfl, merge;
8427 merge = merge_qualified_name (left_id, right_id);
8429 /* Left wasn't qualified and is now qualified */
8430 if (!QUALIFIED_P (left_id))
8432 tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8433 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8434 EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8437 wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8438 EXPR_WFL_LINECOL (wfl) = location;
8439 chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8441 EXPR_WFL_NODE (left) = merge;
8442 return left;
8443 #endif
8446 /* Extract the last identifier component of the qualified in WFL. The
8447 last identifier is removed from the linked list */
8449 static tree
8450 cut_identifier_in_qualified (wfl)
8451 tree wfl;
8453 tree q;
8454 tree previous = NULL_TREE;
8455 for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8456 if (!TREE_CHAIN (q))
8458 if (!previous)
8459 fatal ("Operating on a non qualified qualified WFL - cut_identifier_in_qualified");
8460 TREE_CHAIN (previous) = NULL_TREE;
8461 return TREE_PURPOSE (q);
8465 /* Resolve the expression name NAME. Return its decl. */
8467 static tree
8468 resolve_expression_name (id, orig)
8469 tree id;
8470 tree *orig;
8472 tree name = EXPR_WFL_NODE (id);
8473 tree decl;
8475 /* 6.5.5.1: Simple expression names */
8476 if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8478 /* 15.13.1: NAME can appear within the scope of a local variable
8479 declaration */
8480 if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8481 return decl;
8483 /* 15.13.1: NAME can appear within a class declaration */
8484 else
8486 decl = lookup_field_wrapper (current_class, name);
8487 if (decl)
8489 tree access = NULL_TREE;
8490 int fs = FIELD_STATIC (decl);
8492 /* If we're accessing an outer scope local alias, make
8493 sure we change the name of the field we're going to
8494 build access to. */
8495 if (FIELD_LOCAL_ALIAS_USED (decl))
8496 name = DECL_NAME (decl);
8498 /* Instance variable (8.3.1.1) can't appear within
8499 static method, static initializer or initializer for
8500 a static variable. */
8501 if (!fs && METHOD_STATIC (current_function_decl))
8503 static_ref_err (id, name, current_class);
8504 return error_mark_node;
8506 /* Instance variables can't appear as an argument of
8507 an explicit constructor invocation */
8508 if (!fs && ctxp->explicit_constructor_p)
8510 parse_error_context
8511 (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8512 return error_mark_node;
8515 /* If we're processing an inner class and we're trying
8516 to access a field belonging to an outer class, build
8517 the access to the field */
8518 if (!fs && outer_field_access_p (current_class, decl))
8519 return build_outer_field_access (id, decl);
8521 /* Otherwise build what it takes to access the field */
8522 access = build_field_ref ((fs ? NULL_TREE : current_this),
8523 DECL_CONTEXT (decl), name);
8524 if (fs && !flag_emit_class_files && !flag_emit_xref)
8525 access = build_class_init (DECL_CONTEXT (access), access);
8526 /* We may be asked to save the real field access node */
8527 if (orig)
8528 *orig = access;
8529 /* And we return what we got */
8530 return access;
8532 /* Fall down to error report on undefined variable */
8535 /* 6.5.5.2 Qualified Expression Names */
8536 else
8538 if (orig)
8539 *orig = NULL_TREE;
8540 qualify_ambiguous_name (id);
8541 /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8542 /* 15.10.2: Accessing Superclass Members using super */
8543 return resolve_field_access (id, orig, NULL);
8546 /* We've got an error here */
8547 parse_error_context (id, "Undefined variable `%s'",
8548 IDENTIFIER_POINTER (name));
8550 return error_mark_node;
8553 static void
8554 static_ref_err (wfl, field_id, class_type)
8555 tree wfl, field_id, class_type;
8557 parse_error_context
8558 (wfl,
8559 "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8560 IDENTIFIER_POINTER (field_id),
8561 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8564 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8565 We return something suitable to generate the field access. We also
8566 return the field decl in FIELD_DECL and its type in FIELD_TYPE. If
8567 recipient's address can be null. */
8569 static tree
8570 resolve_field_access (qual_wfl, field_decl, field_type)
8571 tree qual_wfl;
8572 tree *field_decl, *field_type;
8574 int is_static = 0;
8575 tree field_ref;
8576 tree decl, where_found, type_found;
8578 if (resolve_qualified_expression_name (qual_wfl, &decl,
8579 &where_found, &type_found))
8580 return error_mark_node;
8582 /* Resolve the LENGTH field of an array here */
8583 if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
8584 && ! flag_emit_class_files && ! flag_emit_xref)
8586 tree length = build_java_array_length_access (where_found);
8587 field_ref =
8588 build_java_arraynull_check (type_found, length, int_type_node);
8590 /* We might have been trying to resolve field.method(). In which
8591 case, the resolution is over and decl is the answer */
8592 else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
8593 field_ref = decl;
8594 else if (JDECL_P (decl))
8596 int static_final_found = 0;
8597 if (!type_found)
8598 type_found = DECL_CONTEXT (decl);
8599 is_static = JDECL_P (decl) && FIELD_STATIC (decl);
8600 if (FIELD_FINAL (decl)
8601 && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
8602 && DECL_LANG_SPECIFIC (decl)
8603 && DECL_INITIAL (decl))
8605 field_ref = DECL_INITIAL (decl);
8606 static_final_found = 1;
8608 else
8609 field_ref = build_field_ref ((is_static && !flag_emit_xref?
8610 NULL_TREE : where_found),
8611 type_found, DECL_NAME (decl));
8612 if (field_ref == error_mark_node)
8613 return error_mark_node;
8614 if (is_static && !static_final_found
8615 && !flag_emit_class_files && !flag_emit_xref)
8616 field_ref = build_class_init (type_found, field_ref);
8618 else
8619 field_ref = decl;
8621 if (field_decl)
8622 *field_decl = decl;
8623 if (field_type)
8624 *field_type = (QUAL_DECL_TYPE (decl) ?
8625 QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
8626 return field_ref;
8629 /* If NODE is an access to f static field, strip out the class
8630 initialization part and return the field decl, otherwise, return
8631 NODE. */
8633 static tree
8634 strip_out_static_field_access_decl (node)
8635 tree node;
8637 if (TREE_CODE (node) == COMPOUND_EXPR)
8639 tree op1 = TREE_OPERAND (node, 1);
8640 if (TREE_CODE (op1) == COMPOUND_EXPR)
8642 tree call = TREE_OPERAND (op1, 0);
8643 if (TREE_CODE (call) == CALL_EXPR
8644 && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
8645 && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
8646 == soft_initclass_node)
8647 return TREE_OPERAND (op1, 1);
8649 else if (JDECL_P (op1))
8650 return op1;
8652 return node;
8655 /* 6.5.5.2: Qualified Expression Names */
8657 static int
8658 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
8659 tree wfl;
8660 tree *found_decl, *type_found, *where_found;
8662 int from_type = 0; /* Field search initiated from a type */
8663 int from_super = 0, from_cast = 0, from_qualified_this = 0;
8664 int previous_call_static = 0;
8665 int is_static;
8666 tree decl = NULL_TREE, type = NULL_TREE, q;
8667 /* For certain for of inner class instantiation */
8668 tree saved_current, saved_this;
8669 #define RESTORE_THIS_AND_CURRENT_CLASS \
8670 { current_class = saved_current; current_this = saved_this;}
8672 *type_found = *where_found = NULL_TREE;
8674 for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
8676 tree qual_wfl = QUAL_WFL (q);
8677 tree ret_decl; /* for EH checking */
8678 int location; /* for EH checking */
8680 /* 15.10.1 Field Access Using a Primary */
8681 switch (TREE_CODE (qual_wfl))
8683 case CALL_EXPR:
8684 case NEW_CLASS_EXPR:
8685 /* If the access to the function call is a non static field,
8686 build the code to access it. */
8687 if (JDECL_P (decl) && !FIELD_STATIC (decl))
8689 decl = maybe_access_field (decl, *where_found,
8690 DECL_CONTEXT (decl));
8691 if (decl == error_mark_node)
8692 return 1;
8695 /* And code for the function call */
8696 if (complete_function_arguments (qual_wfl))
8697 return 1;
8699 /* We might have to setup a new current class and a new this
8700 for the search of an inner class, relative to the type of
8701 a expression resolved as `decl'. The current values are
8702 saved and restored shortly after */
8703 saved_current = current_class;
8704 saved_this = current_this;
8705 if (decl && TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
8707 current_class = type;
8708 current_this = decl;
8711 if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
8712 CALL_USING_SUPER (qual_wfl) = 1;
8713 location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
8714 EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
8715 *where_found = patch_method_invocation (qual_wfl, decl, type,
8716 &is_static, &ret_decl);
8717 if (*where_found == error_mark_node)
8719 RESTORE_THIS_AND_CURRENT_CLASS;
8720 return 1;
8722 *type_found = type = QUAL_DECL_TYPE (*where_found);
8724 /* If we're creating an inner class instance, check for that
8725 an enclosing instance is in scope */
8726 if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
8727 && INNER_ENCLOSING_SCOPE_CHECK (type))
8729 parse_error_context
8730 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
8731 lang_printable_name (type, 0),
8732 (!current_this ? "" :
8733 "; an explicit one must be provided when creating this inner class"));
8734 RESTORE_THIS_AND_CURRENT_CLASS;
8735 return 1;
8738 /* In case we had to change then to resolve a inner class
8739 instantiation using a primary qualified by a `new' */
8740 RESTORE_THIS_AND_CURRENT_CLASS;
8742 /* EH check */
8743 if (location)
8744 check_thrown_exceptions (location, ret_decl);
8746 /* If the previous call was static and this one is too,
8747 build a compound expression to hold the two (because in
8748 that case, previous function calls aren't transported as
8749 forcoming function's argument. */
8750 if (previous_call_static && is_static)
8752 decl = build (COMPOUND_EXPR, type, decl, *where_found);
8753 TREE_SIDE_EFFECTS (decl) = 1;
8755 else
8757 previous_call_static = is_static;
8758 decl = *where_found;
8760 from_type = 0;
8761 continue;
8763 case NEW_ARRAY_EXPR:
8764 case NEW_ANONYMOUS_ARRAY_EXPR:
8765 *where_found = decl = java_complete_tree (qual_wfl);
8766 if (decl == error_mark_node)
8767 return 1;
8768 *type_found = type = QUAL_DECL_TYPE (decl);
8769 CLASS_LOADED_P (type) = 1;
8770 continue;
8772 case CONVERT_EXPR:
8773 *where_found = decl = java_complete_tree (qual_wfl);
8774 if (decl == error_mark_node)
8775 return 1;
8776 *type_found = type = QUAL_DECL_TYPE (decl);
8777 from_cast = 1;
8778 continue;
8780 case CONDITIONAL_EXPR:
8781 case STRING_CST:
8782 case MODIFY_EXPR:
8783 *where_found = decl = java_complete_tree (qual_wfl);
8784 if (decl == error_mark_node)
8785 return 1;
8786 *type_found = type = QUAL_DECL_TYPE (decl);
8787 continue;
8789 case ARRAY_REF:
8790 /* If the access to the function call is a non static field,
8791 build the code to access it. */
8792 if (JDECL_P (decl) && !FIELD_STATIC (decl))
8794 decl = maybe_access_field (decl, *where_found, type);
8795 if (decl == error_mark_node)
8796 return 1;
8798 /* And code for the array reference expression */
8799 decl = java_complete_tree (qual_wfl);
8800 if (decl == error_mark_node)
8801 return 1;
8802 type = QUAL_DECL_TYPE (decl);
8803 continue;
8805 case PLUS_EXPR:
8806 if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8807 return 1;
8808 if ((type = patch_string (decl)))
8809 decl = type;
8810 *where_found = QUAL_RESOLUTION (q) = decl;
8811 *type_found = type = TREE_TYPE (decl);
8812 break;
8814 case CLASS_LITERAL:
8815 if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8816 return 1;
8817 *where_found = QUAL_RESOLUTION (q) = decl;
8818 *type_found = type = TREE_TYPE (decl);
8819 break;
8821 default:
8822 /* Fix for -Wall Just go to the next statement. Don't
8823 continue */
8824 break;
8827 /* If we fall here, we weren't processing a (static) function call. */
8828 previous_call_static = 0;
8830 /* It can be the keyword THIS */
8831 if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
8833 if (!current_this)
8835 parse_error_context
8836 (wfl, "Keyword `this' used outside allowed context");
8837 return 1;
8839 if (ctxp->explicit_constructor_p)
8841 parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
8842 return 1;
8844 /* We have to generate code for intermediate acess */
8845 if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
8847 *where_found = decl = current_this;
8848 *type_found = type = QUAL_DECL_TYPE (decl);
8850 /* We're trying to access the this from somewhere else... */
8851 else
8853 *where_found = decl = build_current_thisn (type);
8854 from_qualified_this = 1;
8857 from_type = 0;
8858 continue;
8861 /* 15.10.2 Accessing Superclass Members using SUPER */
8862 if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
8864 tree node;
8865 /* Check on the restricted use of SUPER */
8866 if (METHOD_STATIC (current_function_decl)
8867 || current_class == object_type_node)
8869 parse_error_context
8870 (wfl, "Keyword `super' used outside allowed context");
8871 return 1;
8873 /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
8874 node = build_cast (EXPR_WFL_LINECOL (qual_wfl),
8875 CLASSTYPE_SUPER (current_class),
8876 build_this (EXPR_WFL_LINECOL (qual_wfl)));
8877 *where_found = decl = java_complete_tree (node);
8878 if (decl == error_mark_node)
8879 return 1;
8880 *type_found = type = QUAL_DECL_TYPE (decl);
8881 from_super = from_type = 1;
8882 continue;
8885 /* 15.13.1: Can't search for field name in packages, so we
8886 assume a variable/class name was meant. */
8887 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
8889 tree name = resolve_package (wfl, &q);
8890 if (name)
8892 tree list;
8893 *where_found = decl = resolve_no_layout (name, qual_wfl);
8894 /* We wan't to be absolutely that the class is laid
8895 out. We're going to search something inside it. */
8896 *type_found = type = TREE_TYPE (decl);
8897 layout_class (type);
8898 from_type = 1;
8900 /* Fix them all the way down, if any are left. */
8901 if (q)
8903 list = TREE_CHAIN (q);
8904 while (list)
8906 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
8907 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
8908 list = TREE_CHAIN (list);
8912 else
8914 if (from_super || from_cast)
8915 parse_error_context
8916 ((from_cast ? qual_wfl : wfl),
8917 "No variable `%s' defined in class `%s'",
8918 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
8919 lang_printable_name (type, 0));
8920 else
8921 parse_error_context
8922 (qual_wfl, "Undefined variable or class name: `%s'",
8923 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
8924 return 1;
8928 /* We have a type name. It's been already resolved when the
8929 expression was qualified. */
8930 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
8932 if (!(decl = QUAL_RESOLUTION (q)))
8933 return 1; /* Error reported already */
8935 /* Sneak preview. If next we see a `new', we're facing a
8936 qualification with resulted in a type being selected
8937 instead of a field. Report the error */
8938 if(TREE_CHAIN (q)
8939 && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
8941 parse_error_context (qual_wfl, "Undefined variable `%s'",
8942 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
8943 return 1;
8946 if (not_accessible_p (TREE_TYPE (decl), decl, 0))
8948 parse_error_context
8949 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
8950 java_accstring_lookup (get_access_flags_from_decl (decl)),
8951 GET_TYPE_NAME (type),
8952 IDENTIFIER_POINTER (DECL_NAME (decl)),
8953 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
8954 return 1;
8956 check_deprecation (qual_wfl, decl);
8958 type = TREE_TYPE (decl);
8959 from_type = 1;
8961 /* We resolve and expression name */
8962 else
8964 tree field_decl = NULL_TREE;
8966 /* If there exists an early resolution, use it. That occurs
8967 only once and we know that there are more things to
8968 come. Don't do that when processing something after SUPER
8969 (we need more thing to be put in place below */
8970 if (!from_super && QUAL_RESOLUTION (q))
8972 decl = QUAL_RESOLUTION (q);
8973 if (!type)
8975 if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
8977 if (current_this)
8978 *where_found = current_this;
8979 else
8981 static_ref_err (qual_wfl, DECL_NAME (decl),
8982 current_class);
8983 return 1;
8986 else
8988 *where_found = TREE_TYPE (decl);
8989 if (TREE_CODE (*where_found) == POINTER_TYPE)
8990 *where_found = TREE_TYPE (*where_found);
8995 /* We have to search for a field, knowing the type of its
8996 container. The flag FROM_TYPE indicates that we resolved
8997 the last member of the expression as a type name, which
8998 means that for the resolution of this field, we'll look
8999 for other errors than if it was resolved as a member of
9000 an other field. */
9001 else
9003 int is_static;
9004 tree field_decl_type; /* For layout */
9006 if (!from_type && !JREFERENCE_TYPE_P (type))
9008 parse_error_context
9009 (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9010 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9011 lang_printable_name (type, 0),
9012 IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9013 return 1;
9016 field_decl = lookup_field_wrapper (type,
9017 EXPR_WFL_NODE (qual_wfl));
9018 if (field_decl == NULL_TREE)
9020 parse_error_context
9021 (qual_wfl, "No variable `%s' defined in type `%s'",
9022 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9023 GET_TYPE_NAME (type));
9024 return 1;
9026 if (field_decl == error_mark_node)
9027 return 1;
9029 /* Layout the type of field_decl, since we may need
9030 it. Don't do primitive types or loaded classes. The
9031 situation of non primitive arrays may not handled
9032 properly here. FIXME */
9033 if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9034 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9035 else
9036 field_decl_type = TREE_TYPE (field_decl);
9037 if (!JPRIMITIVE_TYPE_P (field_decl_type)
9038 && !CLASS_LOADED_P (field_decl_type)
9039 && !TYPE_ARRAY_P (field_decl_type))
9040 resolve_and_layout (field_decl_type, NULL_TREE);
9041 if (TYPE_ARRAY_P (field_decl_type))
9042 CLASS_LOADED_P (field_decl_type) = 1;
9044 /* Check on accessibility here */
9045 if (not_accessible_p (type, field_decl, from_super))
9047 parse_error_context
9048 (qual_wfl,
9049 "Can't access %s field `%s.%s' from `%s'",
9050 java_accstring_lookup
9051 (get_access_flags_from_decl (field_decl)),
9052 GET_TYPE_NAME (type),
9053 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9054 IDENTIFIER_POINTER
9055 (DECL_NAME (TYPE_NAME (current_class))));
9056 return 1;
9058 check_deprecation (qual_wfl, field_decl);
9060 /* There are things to check when fields are accessed
9061 from type. There are no restrictions on a static
9062 declaration of the field when it is accessed from an
9063 interface */
9064 is_static = FIELD_STATIC (field_decl);
9065 if (!from_super && from_type
9066 && !TYPE_INTERFACE_P (type)
9067 && !is_static
9068 && (current_function_decl
9069 && METHOD_STATIC (current_function_decl)))
9071 static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9072 return 1;
9074 from_cast = from_super = 0;
9076 /* It's an access from a type but it isn't static, we
9077 make it relative to `this'. */
9078 if (!is_static && from_type)
9079 decl = current_this;
9081 /* If we need to generate something to get a proper
9082 handle on what this field is accessed from, do it
9083 now. */
9084 if (!is_static)
9086 decl = maybe_access_field (decl, *where_found, *type_found);
9087 if (decl == error_mark_node)
9088 return 1;
9091 /* We want to keep the location were found it, and the type
9092 we found. */
9093 *where_found = decl;
9094 *type_found = type;
9096 /* Generate the correct expression for field access from
9097 qualified this */
9098 if (from_qualified_this)
9100 field_decl = build_outer_field_access (qual_wfl, field_decl);
9101 from_qualified_this = 0;
9104 /* This is the decl found and eventually the next one to
9105 search from */
9106 decl = field_decl;
9108 from_type = 0;
9109 type = QUAL_DECL_TYPE (decl);
9111 /* Sneak preview. If decl is qualified by a `new', report
9112 the error here to be accurate on the peculiar construct */
9113 if (TREE_CHAIN (q)
9114 && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9115 && !JREFERENCE_TYPE_P (type))
9117 parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'",
9118 lang_printable_name (type, 0));
9119 return 1;
9122 /* `q' might have changed due to a after package resolution
9123 re-qualification */
9124 if (!q)
9125 break;
9127 *found_decl = decl;
9128 return 0;
9131 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9132 can't be accessed from REFERENCE (a record type). */
9134 static int
9135 not_accessible_p (reference, member, from_super)
9136 tree reference, member;
9137 int from_super;
9139 int access_flag = get_access_flags_from_decl (member);
9141 /* Access always granted for members declared public */
9142 if (access_flag & ACC_PUBLIC)
9143 return 0;
9145 /* Check access on protected members */
9146 if (access_flag & ACC_PROTECTED)
9148 /* Access granted if it occurs from within the package
9149 containing the class in which the protected member is
9150 declared */
9151 if (class_in_current_package (DECL_CONTEXT (member)))
9152 return 0;
9154 /* If accessed with the form `super.member', then access is granted */
9155 if (from_super)
9156 return 0;
9158 /* Otherwise, access is granted if occuring from the class where
9159 member is declared or a subclass of it */
9160 if (inherits_from_p (reference, DECL_CONTEXT (member)))
9161 return 0;
9162 return 1;
9165 /* Check access on private members. Access is granted only if it
9166 occurs from within the class in which it is declared. Exceptions
9167 are accesses from inner-classes. This section is probably not
9168 complete. FIXME */
9169 if (access_flag & ACC_PRIVATE)
9170 return (current_class == DECL_CONTEXT (member) ? 0 :
9171 (INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
9173 /* Default access are permitted only when occuring within the
9174 package in which the type (REFERENCE) is declared. In other words,
9175 REFERENCE is defined in the current package */
9176 if (ctxp->package)
9177 return !class_in_current_package (reference);
9179 /* Otherwise, access is granted */
9180 return 0;
9183 /* Test deprecated decl access. */
9184 static void
9185 check_deprecation (wfl, decl)
9186 tree wfl, decl;
9188 const char *file = DECL_SOURCE_FILE (decl);
9189 /* Complain if the field is deprecated and the file it was defined
9190 in isn't compiled at the same time the file which contains its
9191 use is */
9192 if (DECL_DEPRECATED (decl)
9193 && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9195 char the [20];
9196 switch (TREE_CODE (decl))
9198 case FUNCTION_DECL:
9199 strcpy (the, "method");
9200 break;
9201 case FIELD_DECL:
9202 strcpy (the, "field");
9203 break;
9204 case TYPE_DECL:
9205 strcpy (the, "class");
9206 break;
9207 default:
9208 fatal ("unexpected DECL code - check_deprecation");
9210 parse_warning_context
9211 (wfl, "The %s `%s' in class `%s' has been deprecated",
9212 the, lang_printable_name (decl, 0),
9213 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9217 /* Returns 1 if class was declared in the current package, 0 otherwise */
9219 static int
9220 class_in_current_package (class)
9221 tree class;
9223 static tree cache = NULL_TREE;
9224 int qualified_flag;
9225 tree left;
9227 if (cache == class)
9228 return 1;
9230 qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9232 /* If the current package is empty and the name of CLASS is
9233 qualified, class isn't in the current package. If there is a
9234 current package and the name of the CLASS is not qualified, class
9235 isn't in the current package */
9236 if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9237 return 0;
9239 /* If there is not package and the name of CLASS isn't qualified,
9240 they belong to the same unnamed package */
9241 if (!ctxp->package && !qualified_flag)
9242 return 1;
9244 /* Compare the left part of the name of CLASS with the package name */
9245 breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9246 if (ctxp->package == left)
9248 cache = class;
9249 return 1;
9251 return 0;
9254 /* This function may generate code to access DECL from WHERE. This is
9255 done only if certain conditions meet. */
9257 static tree
9258 maybe_access_field (decl, where, type)
9259 tree decl, where, type;
9261 if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9262 && !FIELD_STATIC (decl))
9263 decl = build_field_ref (where ? where : current_this,
9264 (type ? type : DECL_CONTEXT (decl)),
9265 DECL_NAME (decl));
9266 return decl;
9269 /* Build a method invocation, by patching PATCH. If non NULL
9270 and according to the situation, PRIMARY and WHERE may be
9271 used. IS_STATIC is set to 1 if the invoked function is static. */
9273 static tree
9274 patch_method_invocation (patch, primary, where, is_static, ret_decl)
9275 tree patch, primary, where;
9276 int *is_static;
9277 tree *ret_decl;
9279 tree wfl = TREE_OPERAND (patch, 0);
9280 tree args = TREE_OPERAND (patch, 1);
9281 tree name = EXPR_WFL_NODE (wfl);
9282 tree list;
9283 int is_static_flag = 0;
9284 int is_super_init = 0;
9285 tree this_arg = NULL_TREE;
9287 /* Should be overriden if everything goes well. Otherwise, if
9288 something fails, it should keep this value. It stop the
9289 evaluation of a bogus assignment. See java_complete_tree,
9290 MODIFY_EXPR: for the reasons why we sometimes want to keep on
9291 evaluating an assignment */
9292 TREE_TYPE (patch) = error_mark_node;
9294 /* Since lookup functions are messing with line numbers, save the
9295 context now. */
9296 java_parser_context_save_global ();
9298 /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9300 /* Resolution of qualified name, excluding constructors */
9301 if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9303 tree identifier, identifier_wfl, type, resolved;
9304 /* Extract the last IDENTIFIER of the qualified
9305 expression. This is a wfl and we will use it's location
9306 data during error report. */
9307 identifier_wfl = cut_identifier_in_qualified (wfl);
9308 identifier = EXPR_WFL_NODE (identifier_wfl);
9310 /* Given the context, IDENTIFIER is syntactically qualified
9311 as a MethodName. We need to qualify what's before */
9312 qualify_ambiguous_name (wfl);
9313 resolved = resolve_field_access (wfl, NULL, NULL);
9315 if (resolved == error_mark_node)
9316 PATCH_METHOD_RETURN_ERROR ();
9318 type = GET_SKIP_TYPE (resolved);
9319 resolve_and_layout (type, NULL_TREE);
9320 list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9321 args = nreverse (args);
9323 /* We're resolving a call from a type */
9324 if (TREE_CODE (resolved) == TYPE_DECL)
9326 if (CLASS_INTERFACE (resolved))
9328 parse_error_context
9329 (identifier_wfl,
9330 "Can't make static reference to method `%s' in interface `%s'",
9331 IDENTIFIER_POINTER (identifier),
9332 IDENTIFIER_POINTER (name));
9333 PATCH_METHOD_RETURN_ERROR ();
9335 if (list && !METHOD_STATIC (list))
9337 char *fct_name = xstrdup (lang_printable_name (list, 0));
9338 parse_error_context
9339 (identifier_wfl,
9340 "Can't make static reference to method `%s %s' in class `%s'",
9341 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
9342 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9343 free (fct_name);
9344 PATCH_METHOD_RETURN_ERROR ();
9347 else
9348 this_arg = primary = resolved;
9350 /* IDENTIFIER_WFL will be used to report any problem further */
9351 wfl = identifier_wfl;
9353 /* Resolution of simple names, names generated after a primary: or
9354 constructors */
9355 else
9357 tree class_to_search = NULL_TREE;
9358 int lc; /* Looking for Constructor */
9360 /* We search constructor in their target class */
9361 if (CALL_CONSTRUCTOR_P (patch))
9363 if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9364 class_to_search = EXPR_WFL_NODE (wfl);
9365 else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9366 this_identifier_node)
9367 class_to_search = NULL_TREE;
9368 else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9369 super_identifier_node)
9371 is_super_init = 1;
9372 if (CLASSTYPE_SUPER (current_class))
9373 class_to_search =
9374 DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9375 else
9377 parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9378 PATCH_METHOD_RETURN_ERROR ();
9382 /* Class to search is NULL if we're searching the current one */
9383 if (class_to_search)
9385 class_to_search = resolve_and_layout (class_to_search, wfl);
9387 if (!class_to_search)
9389 parse_error_context
9390 (wfl, "Class `%s' not found in type declaration",
9391 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9392 PATCH_METHOD_RETURN_ERROR ();
9395 /* Can't instantiate an abstract class, but we can
9396 invoke it's constructor. It's use within the `new'
9397 context is denied here. */
9398 if (CLASS_ABSTRACT (class_to_search)
9399 && TREE_CODE (patch) == NEW_CLASS_EXPR)
9401 parse_error_context
9402 (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9403 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9404 PATCH_METHOD_RETURN_ERROR ();
9407 class_to_search = TREE_TYPE (class_to_search);
9409 else
9410 class_to_search = current_class;
9411 lc = 1;
9413 /* This is a regular search in the local class, unless an
9414 alternate class is specified. */
9415 else
9417 class_to_search = (where ? where : current_class);
9418 lc = 0;
9421 /* NAME is a simple identifier or comes from a primary. Search
9422 in the class whose declaration contain the method being
9423 invoked. */
9424 resolve_and_layout (class_to_search, NULL_TREE);
9426 list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9427 /* Don't continue if no method were found, as the next statement
9428 can't be executed then. */
9429 if (!list)
9430 PATCH_METHOD_RETURN_ERROR ();
9432 /* Check for static reference if non static methods */
9433 if (check_for_static_method_reference (wfl, patch, list,
9434 class_to_search, primary))
9435 PATCH_METHOD_RETURN_ERROR ();
9437 /* Check for inner classes creation from illegal contexts */
9438 if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9439 && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9440 && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9442 parse_error_context
9443 (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9444 lang_printable_name (class_to_search, 0),
9445 (!current_this ? "" :
9446 "; an explicit one must be provided when creating this inner class"));
9447 PATCH_METHOD_RETURN_ERROR ();
9450 /* Non static methods are called with the current object extra
9451 argument. If patch a `new TYPE()', the argument is the value
9452 returned by the object allocator. If method is resolved as a
9453 primary, use the primary otherwise use the current THIS. */
9454 args = nreverse (args);
9455 if (TREE_CODE (patch) != NEW_CLASS_EXPR)
9457 this_arg = primary ? primary : current_this;
9459 /* If we're using an access method, things are different.
9460 There are two familly of cases:
9462 1) We're not generating bytecodes:
9464 - LIST is non static. It's invocation is transformed from
9465 x(a1,...,an) into this$<n>.x(a1,....an).
9466 - LIST is static. It's invocation is transformed from
9467 x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
9469 2) We're generating bytecodes:
9471 - LIST is non static. It's invocation is transformed from
9472 x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
9473 - LIST is static. It's invocation is transformed from
9474 x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
9476 Of course, this$<n> can be abitrary complex, ranging from
9477 this$0 (the immediate outer context) to
9478 access$0(access$0(...(this$0))).
9480 maybe_use_access_method returns a non zero value if the
9481 this_arg has to be moved into the (then generated) stub
9482 argument list. In the mean time, the selected function
9483 might have be replaced by a generated stub. */
9484 if (maybe_use_access_method (is_super_init, &list, &this_arg))
9485 args = tree_cons (NULL_TREE, this_arg, args);
9489 /* Merge point of all resolution schemes. If we have nothing, this
9490 is an error, already signaled */
9491 if (!list)
9492 PATCH_METHOD_RETURN_ERROR ();
9494 /* Check accessibility, position the is_static flag, build and
9495 return the call */
9496 if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
9498 char *fct_name = xstrdup (lang_printable_name (list, 0));
9499 parse_error_context
9500 (wfl, "Can't access %s method `%s %s.%s' from `%s'",
9501 java_accstring_lookup (get_access_flags_from_decl (list)),
9502 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
9503 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))),
9504 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9505 free (fct_name);
9506 PATCH_METHOD_RETURN_ERROR ();
9508 check_deprecation (wfl, list);
9510 /* If invoking a innerclass constructor, there are hidden parameters
9511 to pass */
9512 if (TREE_CODE (patch) == NEW_CLASS_EXPR
9513 && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9515 /* And make sure we add the accessed local variables to be saved
9516 in field aliases. */
9517 args = build_alias_initializer_parameter_list
9518 (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
9520 /* We have to reverse things. Find out why. FIXME */
9521 if (ANONYMOUS_CLASS_P (DECL_CONTEXT (list)))
9522 args = nreverse (args);
9524 /* Secretely pass the current_this/primary as a second argument */
9525 if (primary || current_this)
9526 args = tree_cons (NULL_TREE, (primary ? primary : current_this), args);
9527 else
9528 args = tree_cons (NULL_TREE, integer_zero_node, args);
9531 is_static_flag = METHOD_STATIC (list);
9532 if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
9533 args = tree_cons (NULL_TREE, this_arg, args);
9535 /* In the context of an explicit constructor invocation, we can't
9536 invoke any method relying on `this'. Exceptions are: we're
9537 invoking a static function, primary exists and is not the current
9538 this, we're creating a new object. */
9539 if (ctxp->explicit_constructor_p
9540 && !is_static_flag
9541 && (!primary || primary == current_this)
9542 && (TREE_CODE (patch) != NEW_CLASS_EXPR))
9544 parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9545 PATCH_METHOD_RETURN_ERROR ();
9547 java_parser_context_restore_global ();
9548 if (is_static)
9549 *is_static = is_static_flag;
9550 /* Sometimes, we want the decl of the selected method. Such as for
9551 EH checking */
9552 if (ret_decl)
9553 *ret_decl = list;
9554 patch = patch_invoke (patch, list, args);
9555 if (is_super_init && CLASS_HAS_FINIT_P (current_class))
9557 tree finit_parms, finit_call;
9559 /* Prepare to pass hidden parameters to $finit$, if any. */
9560 finit_parms = build_alias_initializer_parameter_list
9561 (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
9563 finit_call =
9564 build_method_invocation (build_wfl_node (finit_identifier_node),
9565 finit_parms);
9567 /* Generate the code used to initialize fields declared with an
9568 initialization statement and build a compound statement along
9569 with the super constructor invocation. */
9570 patch = build (COMPOUND_EXPR, void_type_node, patch,
9571 java_complete_tree (finit_call));
9572 CAN_COMPLETE_NORMALLY (patch) = 1;
9574 return patch;
9577 /* Check that we're not trying to do a static reference to a method in
9578 non static method. Return 1 if it's the case, 0 otherwise. */
9580 static int
9581 check_for_static_method_reference (wfl, node, method, where, primary)
9582 tree wfl, node, method, where, primary;
9584 if (METHOD_STATIC (current_function_decl)
9585 && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
9587 char *fct_name = xstrdup (lang_printable_name (method, 0));
9588 parse_error_context
9589 (wfl, "Can't make static reference to method `%s %s' in class `%s'",
9590 lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
9591 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
9592 free (fct_name);
9593 return 1;
9595 return 0;
9598 /* Fix the invocation of *MDECL if necessary in the case of a
9599 invocation from an inner class. *THIS_ARG might be modified
9600 appropriately and an alternative access to *MDECL might be
9601 returned. */
9603 static int
9604 maybe_use_access_method (is_super_init, mdecl, this_arg)
9605 int is_super_init;
9606 tree *mdecl, *this_arg;
9608 tree ctx;
9609 tree md = *mdecl, ta = *this_arg;
9610 int to_return = 0;
9611 int non_static_context = !METHOD_STATIC (md);
9613 if (is_super_init
9614 || DECL_CONTEXT (md) == current_class
9615 || !PURE_INNER_CLASS_TYPE_P (current_class)
9616 || DECL_FINIT_P (md))
9617 return 0;
9619 /* If we're calling a method found in an enclosing class, generate
9620 what it takes to retrieve the right this. Don't do that if we're
9621 invoking a static method. */
9623 if (non_static_context)
9625 ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
9626 if (ctx == DECL_CONTEXT (md))
9628 ta = build_current_thisn (current_class);
9629 ta = build_wfl_node (ta);
9631 else
9633 tree type = ctx;
9634 while (type)
9636 maybe_build_thisn_access_method (type);
9637 if (type == DECL_CONTEXT (md))
9639 ta = build_access_to_thisn (ctx, type, 0);
9640 break;
9642 type = (DECL_CONTEXT (TYPE_NAME (type)) ?
9643 TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
9646 ta = java_complete_tree (ta);
9649 /* We might have to use an access method to get to MD. We can
9650 break the method access rule as far as we're not generating
9651 bytecode */
9652 if (METHOD_PRIVATE (md) && flag_emit_class_files)
9654 md = build_outer_method_access_method (md);
9655 to_return = 1;
9658 *mdecl = md;
9659 *this_arg = ta;
9661 /* Returnin a non zero value indicates we were doing a non static
9662 method invokation that is now a static invocation. It will have
9663 callee displace `this' to insert it in the regular argument
9664 list. */
9665 return (non_static_context && to_return);
9668 /* Patch an invoke expression METHOD and ARGS, based on its invocation
9669 mode. */
9671 static tree
9672 patch_invoke (patch, method, args)
9673 tree patch, method, args;
9675 tree dtable, func;
9676 tree original_call, t, ta;
9677 tree cond = NULL_TREE;
9679 /* Last step for args: convert build-in types. If we're dealing with
9680 a new TYPE() type call, the first argument to the constructor
9681 isn't found in the incoming argument list, but delivered by
9682 `new' */
9683 t = TYPE_ARG_TYPES (TREE_TYPE (method));
9684 if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9685 t = TREE_CHAIN (t);
9686 for (ta = args; t != end_params_node && ta;
9687 t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
9688 if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
9689 TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
9690 TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
9692 /* Resolve unresolved returned type isses */
9693 t = TREE_TYPE (TREE_TYPE (method));
9694 if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
9695 resolve_and_layout (TREE_TYPE (t), NULL);
9697 if (flag_emit_class_files || flag_emit_xref)
9698 func = method;
9699 else
9701 tree signature = build_java_signature (TREE_TYPE (method));
9702 switch (invocation_mode (method, CALL_USING_SUPER (patch)))
9704 case INVOKE_VIRTUAL:
9705 dtable = invoke_build_dtable (0, args);
9706 func = build_invokevirtual (dtable, method);
9707 break;
9709 case INVOKE_NONVIRTUAL:
9710 /* If the object for the method call is null, we throw an
9711 exception. We don't do this if the object is the current
9712 method's `this'. In other cases we just rely on an
9713 optimization pass to eliminate redundant checks. */
9714 if (TREE_VALUE (args) != current_this)
9716 /* We use a SAVE_EXPR here to make sure we only evaluate
9717 the new `self' expression once. */
9718 tree save_arg = save_expr (TREE_VALUE (args));
9719 TREE_VALUE (args) = save_arg;
9720 cond = build (EQ_EXPR, boolean_type_node, save_arg,
9721 null_pointer_node);
9723 /* Fall through. */
9725 case INVOKE_SUPER:
9726 case INVOKE_STATIC:
9727 func = build_known_method_ref (method, TREE_TYPE (method),
9728 DECL_CONTEXT (method),
9729 signature, args);
9730 break;
9732 case INVOKE_INTERFACE:
9733 dtable = invoke_build_dtable (1, args);
9734 func = build_invokeinterface (dtable, method);
9735 break;
9737 default:
9738 fatal ("internal error - unknown invocation_mode result");
9741 /* Ensure self_type is initialized, (invokestatic). FIXME */
9742 func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
9745 TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
9746 TREE_OPERAND (patch, 0) = func;
9747 TREE_OPERAND (patch, 1) = args;
9748 original_call = patch;
9750 /* We're processing a `new TYPE ()' form. New is called and its
9751 returned value is the first argument to the constructor. We build
9752 a COMPOUND_EXPR and use saved expression so that the overall NEW
9753 expression value is a pointer to a newly created and initialized
9754 class. */
9755 if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
9757 tree class = DECL_CONTEXT (method);
9758 tree c1, saved_new, size, new;
9759 if (flag_emit_class_files || flag_emit_xref)
9761 TREE_TYPE (patch) = build_pointer_type (class);
9762 return patch;
9764 if (!TYPE_SIZE (class))
9765 safe_layout_class (class);
9766 size = size_in_bytes (class);
9767 new = build (CALL_EXPR, promote_type (class),
9768 build_address_of (alloc_object_node),
9769 tree_cons (NULL_TREE, build_class_ref (class),
9770 build_tree_list (NULL_TREE,
9771 size_in_bytes (class))),
9772 NULL_TREE);
9773 saved_new = save_expr (new);
9774 c1 = build_tree_list (NULL_TREE, saved_new);
9775 TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
9776 TREE_OPERAND (original_call, 1) = c1;
9777 TREE_SET_CODE (original_call, CALL_EXPR);
9778 patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
9781 /* If COND is set, then we are building a check to see if the object
9782 is NULL. */
9783 if (cond != NULL_TREE)
9785 /* We have to make the `then' branch a compound expression to
9786 make the types turn out right. This seems bizarre. */
9787 patch = build (COND_EXPR, TREE_TYPE (patch), cond,
9788 build (COMPOUND_EXPR, TREE_TYPE (patch),
9789 build (CALL_EXPR, void_type_node,
9790 build_address_of (soft_nullpointer_node),
9791 NULL_TREE, NULL_TREE),
9792 (FLOAT_TYPE_P (TREE_TYPE (patch))
9793 ? build_real (TREE_TYPE (patch), dconst0)
9794 : build1 (CONVERT_EXPR, TREE_TYPE (patch),
9795 integer_zero_node))),
9796 patch);
9797 TREE_SIDE_EFFECTS (patch) = 1;
9800 return patch;
9803 static int
9804 invocation_mode (method, super)
9805 tree method;
9806 int super;
9808 int access = get_access_flags_from_decl (method);
9810 if (super)
9811 return INVOKE_SUPER;
9813 if (access & ACC_STATIC)
9814 return INVOKE_STATIC;
9816 /* We have to look for a constructor before we handle nonvirtual
9817 calls; otherwise the constructor will look nonvirtual. */
9818 if (DECL_CONSTRUCTOR_P (method))
9819 return INVOKE_STATIC;
9821 if (access & ACC_FINAL || access & ACC_PRIVATE)
9822 return INVOKE_NONVIRTUAL;
9824 if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
9825 return INVOKE_NONVIRTUAL;
9827 if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
9828 return INVOKE_INTERFACE;
9830 return INVOKE_VIRTUAL;
9833 /* Retrieve a refined list of matching methods. It covers the step
9834 15.11.2 (Compile-Time Step 2) */
9836 static tree
9837 lookup_method_invoke (lc, cl, class, name, arg_list)
9838 int lc;
9839 tree cl;
9840 tree class, name, arg_list;
9842 tree atl = end_params_node; /* Arg Type List */
9843 tree method, signature, list, node;
9844 const char *candidates; /* Used for error report */
9845 char *dup;
9847 /* Fix the arguments */
9848 for (node = arg_list; node; node = TREE_CHAIN (node))
9850 tree current_arg = TREE_TYPE (TREE_VALUE (node));
9851 /* Non primitive type may have to be resolved */
9852 if (!JPRIMITIVE_TYPE_P (current_arg))
9853 resolve_and_layout (current_arg, NULL_TREE);
9854 /* And promoted */
9855 if (TREE_CODE (current_arg) == RECORD_TYPE)
9856 current_arg = promote_type (current_arg);
9857 atl = tree_cons (NULL_TREE, current_arg, atl);
9860 /* Presto. If we're dealing with an anonymous class and a
9861 constructor call, generate the right constructor now, since we
9862 know the arguments' types. */
9864 if (lc && ANONYMOUS_CLASS_P (class))
9865 craft_constructor (TYPE_NAME (class), atl);
9867 /* Find all candidates and then refine the list, searching for the
9868 most specific method. */
9869 list = find_applicable_accessible_methods_list (lc, class, name, atl);
9870 list = find_most_specific_methods_list (list);
9871 if (list && !TREE_CHAIN (list))
9872 return TREE_VALUE (list);
9874 /* Issue an error. List candidates if any. Candidates are listed
9875 only if accessible (non accessible methods may end-up here for
9876 the sake of a better error report). */
9877 candidates = NULL;
9878 if (list)
9880 tree current;
9881 obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
9882 for (current = list; current; current = TREE_CHAIN (current))
9884 tree cm = TREE_VALUE (current);
9885 char string [4096];
9886 if (!cm || not_accessible_p (class, cm, 0))
9887 continue;
9888 sprintf
9889 (string, " `%s' in `%s'%s",
9890 get_printable_method_name (cm),
9891 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
9892 (TREE_CHAIN (current) ? "\n" : ""));
9893 obstack_grow (&temporary_obstack, string, strlen (string));
9895 obstack_1grow (&temporary_obstack, '\0');
9896 candidates = obstack_finish (&temporary_obstack);
9898 /* Issue the error message */
9899 method = make_node (FUNCTION_TYPE);
9900 TYPE_ARG_TYPES (method) = atl;
9901 signature = build_java_argument_signature (method);
9902 dup = xstrdup (lang_printable_name (class, 0));
9903 parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
9904 (lc ? "constructor" : "method"),
9905 (lc ? dup : IDENTIFIER_POINTER (name)),
9906 IDENTIFIER_POINTER (signature), dup,
9907 (candidates ? candidates : ""));
9908 free (dup);
9909 return NULL_TREE;
9912 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
9913 when we're looking for a constructor. */
9915 static tree
9916 find_applicable_accessible_methods_list (lc, class, name, arglist)
9917 int lc;
9918 tree class, name, arglist;
9920 static int object_done = 0;
9921 tree list = NULL_TREE, all_list = NULL_TREE;
9923 if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
9925 load_class (class, 1);
9926 safe_layout_class (class);
9929 /* Search interfaces */
9930 if (CLASS_INTERFACE (TYPE_NAME (class)))
9932 static struct hash_table t, *searched_interfaces = NULL;
9933 static int search_not_done = 0;
9934 int i, n;
9935 tree basetype_vec = TYPE_BINFO_BASETYPES (class);
9937 /* Search in the hash table, otherwise create a new one if
9938 necessary and insert the new entry. */
9940 if (searched_interfaces)
9942 if (hash_lookup (searched_interfaces,
9943 (const hash_table_key) class, FALSE, NULL))
9944 return NULL;
9946 else
9948 hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
9949 java_hash_compare_tree_node);
9950 searched_interfaces = &t;
9953 hash_lookup (searched_interfaces,
9954 (const hash_table_key) class, TRUE, NULL);
9956 search_applicable_methods_list (lc, TYPE_METHODS (class),
9957 name, arglist, &list, &all_list);
9958 n = TREE_VEC_LENGTH (basetype_vec);
9959 for (i = 1; i < n; i++)
9961 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
9962 tree rlist;
9964 search_not_done++;
9965 rlist = find_applicable_accessible_methods_list (lc, t, name,
9966 arglist);
9967 list = chainon (rlist, list);
9968 search_not_done--;
9971 /* We're done. Reset the searched interfaces list and finally search
9972 java.lang.Object */
9973 if (!search_not_done)
9975 if (!object_done)
9976 search_applicable_methods_list (lc,
9977 TYPE_METHODS (object_type_node),
9978 name, arglist, &list, &all_list);
9979 hash_table_free (searched_interfaces);
9980 searched_interfaces = NULL;
9983 /* Search classes */
9984 else
9986 tree sc = class;
9987 int seen_inner_class = 0;
9988 search_applicable_methods_list (lc, TYPE_METHODS (class),
9989 name, arglist, &list, &all_list);
9991 /* We must search all interfaces of this class */
9992 if (!lc)
9994 tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
9995 int n = TREE_VEC_LENGTH (basetype_vec), i;
9996 object_done = 1;
9997 for (i = 1; i < n; i++)
9999 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10000 tree rlist;
10001 if (t != object_type_node)
10002 rlist = find_applicable_accessible_methods_list (lc, t,
10003 name, arglist);
10004 list = chainon (rlist, list);
10006 object_done = 0;
10009 /* Search enclosing context of inner classes before looking
10010 ancestors up. */
10011 while (!lc && INNER_CLASS_TYPE_P (class))
10013 tree rlist;
10014 seen_inner_class = 1;
10015 class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
10016 rlist = find_applicable_accessible_methods_list (lc, class,
10017 name, arglist);
10018 list = chainon (rlist, list);
10021 if (!lc && seen_inner_class
10022 && TREE_TYPE (DECL_CONTEXT (TYPE_NAME (sc))) == CLASSTYPE_SUPER (sc))
10023 class = CLASSTYPE_SUPER (sc);
10024 else
10025 class = sc;
10027 for (class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
10028 class; class = CLASSTYPE_SUPER (class))
10029 search_applicable_methods_list (lc, TYPE_METHODS (class),
10030 name, arglist, &list, &all_list);
10033 /* Either return the list obtained or all selected (but
10034 inaccessible) methods for better error report. */
10035 return (!list ? all_list : list);
10038 /* Effectively search for the approriate method in method */
10040 static void
10041 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10042 int lc;
10043 tree method, name, arglist;
10044 tree *list, *all_list;
10046 for (; method; method = TREE_CHAIN (method))
10048 /* When dealing with constructor, stop here, otherwise search
10049 other classes */
10050 if (lc && !DECL_CONSTRUCTOR_P (method))
10051 continue;
10052 else if (!lc && (DECL_CONSTRUCTOR_P (method)
10053 || (GET_METHOD_NAME (method) != name)))
10054 continue;
10056 if (argument_types_convertible (method, arglist))
10058 /* Retain accessible methods only */
10059 if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
10060 method, 0))
10061 *list = tree_cons (NULL_TREE, method, *list);
10062 else
10063 /* Also retain all selected method here */
10064 *all_list = tree_cons (NULL_TREE, method, *list);
10069 /* 15.11.2.2 Choose the Most Specific Method */
10071 static tree
10072 find_most_specific_methods_list (list)
10073 tree list;
10075 int max = 0;
10076 tree current, new_list = NULL_TREE;
10077 for (current = list; current; current = TREE_CHAIN (current))
10079 tree method;
10080 DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10082 for (method = list; method; method = TREE_CHAIN (method))
10084 /* Don't test a method against itself */
10085 if (method == current)
10086 continue;
10088 /* Compare arguments and location where method where declared */
10089 if (argument_types_convertible (TREE_VALUE (method),
10090 TREE_VALUE (current))
10091 && valid_method_invocation_conversion_p
10092 (DECL_CONTEXT (TREE_VALUE (method)),
10093 DECL_CONTEXT (TREE_VALUE (current))))
10095 int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
10096 max = (v > max ? v : max);
10101 /* Review the list and select the maximally specific methods */
10102 for (current = list; current; current = TREE_CHAIN (current))
10103 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10104 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10106 /* If we have several and they're all abstract, just pick the
10107 closest one. */
10109 if (new_list && TREE_CHAIN (new_list))
10111 tree c;
10112 for (c = new_list; c && METHOD_ABSTRACT (TREE_VALUE (c));
10113 c = TREE_CHAIN (c))
10115 if (!c)
10117 new_list = nreverse (new_list);
10118 TREE_CHAIN (new_list) = NULL_TREE;
10122 /* If we can't find one, lower expectations and try to gather multiple
10123 maximally specific methods */
10124 while (!new_list && max)
10126 while (--max > 0)
10128 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10129 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10133 return new_list;
10136 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10137 converted by method invocation conversion (5.3) to the type of the
10138 corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10139 to change less often than M1. */
10141 static int
10142 argument_types_convertible (m1, m2_or_arglist)
10143 tree m1, m2_or_arglist;
10145 static tree m2_arg_value = NULL_TREE;
10146 static tree m2_arg_cache = NULL_TREE;
10148 register tree m1_arg, m2_arg;
10150 SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10152 if (m2_arg_value == m2_or_arglist)
10153 m2_arg = m2_arg_cache;
10154 else
10156 /* M2_OR_ARGLIST can be a function DECL or a raw list of
10157 argument types */
10158 if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10160 m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10161 if (!METHOD_STATIC (m2_or_arglist))
10162 m2_arg = TREE_CHAIN (m2_arg);
10164 else
10165 m2_arg = m2_or_arglist;
10167 m2_arg_value = m2_or_arglist;
10168 m2_arg_cache = m2_arg;
10171 while (m1_arg != end_params_node && m2_arg != end_params_node)
10173 resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10174 if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10175 TREE_VALUE (m2_arg)))
10176 break;
10177 m1_arg = TREE_CHAIN (m1_arg);
10178 m2_arg = TREE_CHAIN (m2_arg);
10180 return m1_arg == end_params_node && m2_arg == end_params_node;
10183 /* Qualification routines */
10185 static void
10186 qualify_ambiguous_name (id)
10187 tree id;
10189 tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10190 saved_current_class;
10191 int again, super_found = 0, this_found = 0, new_array_found = 0;
10192 int code;
10194 /* We first qualify the first element, then derive qualification of
10195 others based on the first one. If the first element is qualified
10196 by a resolution (field or type), this resolution is stored in the
10197 QUAL_RESOLUTION of the qual element being examined. We need to
10198 save the current_class since the use of SUPER might change the
10199 its value. */
10200 saved_current_class = current_class;
10201 qual = EXPR_WFL_QUALIFICATION (id);
10202 do {
10204 /* Simple qualified expression feature a qual_wfl that is a
10205 WFL. Expression derived from a primary feature more complicated
10206 things like a CALL_EXPR. Expression from primary need to be
10207 worked out to extract the part on which the qualification will
10208 take place. */
10209 qual_wfl = QUAL_WFL (qual);
10210 switch (TREE_CODE (qual_wfl))
10212 case CALL_EXPR:
10213 qual_wfl = TREE_OPERAND (qual_wfl, 0);
10214 if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10216 qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10217 qual_wfl = QUAL_WFL (qual);
10219 break;
10220 case NEW_ARRAY_EXPR:
10221 case NEW_ANONYMOUS_ARRAY_EXPR:
10222 qual = TREE_CHAIN (qual);
10223 again = new_array_found = 1;
10224 continue;
10225 case CONVERT_EXPR:
10226 break;
10227 case NEW_CLASS_EXPR:
10228 qual_wfl = TREE_OPERAND (qual_wfl, 0);
10229 break;
10230 case ARRAY_REF:
10231 while (TREE_CODE (qual_wfl) == ARRAY_REF)
10232 qual_wfl = TREE_OPERAND (qual_wfl, 0);
10233 break;
10234 case STRING_CST:
10235 qual = TREE_CHAIN (qual);
10236 qual_wfl = QUAL_WFL (qual);
10237 break;
10238 case CLASS_LITERAL:
10239 qual = TREE_CHAIN (qual);
10240 qual_wfl = QUAL_WFL (qual);
10241 break;
10242 default:
10243 /* Fix for -Wall. Just break doing nothing */
10244 break;
10247 ptr_type = current_class;
10248 again = 0;
10249 code = TREE_CODE (qual_wfl);
10251 /* Pos evaluation: non WFL leading expression nodes */
10252 if (code == CONVERT_EXPR
10253 && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10254 name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10256 else if (code == INTEGER_CST)
10257 name = qual_wfl;
10259 else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10260 TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10261 name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10263 else if (code == TREE_LIST)
10264 name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10266 else if (code == STRING_CST || code == CONDITIONAL_EXPR
10267 || code == PLUS_EXPR)
10269 qual = TREE_CHAIN (qual);
10270 qual_wfl = QUAL_WFL (qual);
10271 again = 1;
10273 else
10275 name = EXPR_WFL_NODE (qual_wfl);
10276 if (!name)
10278 qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10279 again = 1;
10283 /* If we have a THIS (from a primary), we set the context accordingly */
10284 if (name == this_identifier_node)
10286 qual = TREE_CHAIN (qual);
10287 qual_wfl = QUAL_WFL (qual);
10288 if (TREE_CODE (qual_wfl) == CALL_EXPR)
10289 again = 1;
10290 else
10291 name = EXPR_WFL_NODE (qual_wfl);
10292 this_found = 1;
10294 /* If we have a SUPER, we set the context accordingly */
10295 if (name == super_identifier_node)
10297 current_class = CLASSTYPE_SUPER (ptr_type);
10298 /* Check that there is such a thing as a super class. If not,
10299 return. The error will be caught later on, during the
10300 resolution */
10301 if (!current_class)
10303 current_class = saved_current_class;
10304 return;
10306 qual = TREE_CHAIN (qual);
10307 /* Do one more interation to set things up */
10308 super_found = again = 1;
10310 } while (again);
10312 /* If name appears within the scope of a local variable declaration
10313 or parameter declaration, then it is an expression name. We don't
10314 carry this test out if we're in the context of the use of SUPER
10315 or THIS */
10316 if (!this_found && !super_found
10317 && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10318 && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10320 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10321 QUAL_RESOLUTION (qual) = decl;
10324 /* If within the class/interface NAME was found to be used there
10325 exists a (possibly inherited) field named NAME, then this is an
10326 expression name. If we saw a NEW_ARRAY_EXPR before and want to
10327 address length, it is OK. */
10328 else if ((decl = lookup_field_wrapper (ptr_type, name))
10329 || (new_array_found && name == length_identifier_node))
10331 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10332 QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10335 /* We reclassify NAME as yielding to a type name resolution if:
10336 - NAME is a class/interface declared within the compilation
10337 unit containing NAME,
10338 - NAME is imported via a single-type-import declaration,
10339 - NAME is declared in an another compilation unit of the package
10340 of the compilation unit containing NAME,
10341 - NAME is declared by exactly on type-import-on-demand declaration
10342 of the compilation unit containing NAME.
10343 - NAME is actually a STRING_CST. */
10344 else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10345 || (decl = resolve_and_layout (name, NULL_TREE)))
10347 RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10348 QUAL_RESOLUTION (qual) = decl;
10351 /* Method call, array references and cast are expression name */
10352 else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10353 || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
10354 || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR)
10355 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10357 /* Check here that NAME isn't declared by more than one
10358 type-import-on-demand declaration of the compilation unit
10359 containing NAME. FIXME */
10361 /* Otherwise, NAME is reclassified as a package name */
10362 else
10363 RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
10365 /* Propagate the qualification accross other components of the
10366 qualified name */
10367 for (qual = TREE_CHAIN (qual); qual;
10368 qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
10370 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10371 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
10372 else
10373 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
10376 /* Store the global qualification for the ambiguous part of ID back
10377 into ID fields */
10378 if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
10379 RESOLVE_EXPRESSION_NAME_P (id) = 1;
10380 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
10381 RESOLVE_TYPE_NAME_P (id) = 1;
10382 else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10383 RESOLVE_PACKAGE_NAME_P (id) = 1;
10385 /* Restore the current class */
10386 current_class = saved_current_class;
10389 static int
10390 breakdown_qualified (left, right, source)
10391 tree *left, *right, source;
10393 char *p = IDENTIFIER_POINTER (source), *base;
10394 int l = IDENTIFIER_LENGTH (source);
10396 /* Breakdown NAME into REMAINDER . IDENTIFIER */
10397 base = p;
10398 p += (l-1);
10399 while (*p != '.' && p != base)
10400 p--;
10402 /* We didn't find a '.'. Return an error */
10403 if (p == base)
10404 return 1;
10406 *p = '\0';
10407 if (right)
10408 *right = get_identifier (p+1);
10409 *left = get_identifier (IDENTIFIER_POINTER (source));
10410 *p = '.';
10412 return 0;
10415 /* Patch tree nodes in a function body. When a BLOCK is found, push
10416 local variable decls if present.
10417 Same as java_complete_lhs, but does resolve static finals to values. */
10419 static tree
10420 java_complete_tree (node)
10421 tree node;
10423 node = java_complete_lhs (node);
10424 if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
10425 && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
10426 && !flag_emit_xref)
10428 tree value = DECL_INITIAL (node);
10429 DECL_INITIAL (node) = NULL_TREE;
10430 push_obstacks (&permanent_obstack, &permanent_obstack);
10431 value = fold_constant_for_init (value, node);
10432 pop_obstacks ();
10433 DECL_INITIAL (node) = value;
10434 if (value != NULL_TREE)
10436 /* fold_constant_for_init sometimes widen the original type
10437 of the constant (i.e. byte to int.) It's not desirable,
10438 especially if NODE is a function argument. */
10439 if (TREE_CODE (value) == INTEGER_CST
10440 && TREE_TYPE (node) != TREE_TYPE (value))
10441 return convert (TREE_TYPE (node), value);
10442 else
10443 return value;
10446 return node;
10449 static tree
10450 java_stabilize_reference (node)
10451 tree node;
10453 if (TREE_CODE (node) == COMPOUND_EXPR)
10455 tree op0 = TREE_OPERAND (node, 0);
10456 tree op1 = TREE_OPERAND (node, 1);
10457 TREE_OPERAND (node, 0) = save_expr (op0);
10458 TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
10459 return node;
10461 return stabilize_reference (node);
10464 /* Patch tree nodes in a function body. When a BLOCK is found, push
10465 local variable decls if present.
10466 Same as java_complete_tree, but does not resolve static finals to values. */
10468 static tree
10469 java_complete_lhs (node)
10470 tree node;
10472 tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
10473 int flag;
10475 /* CONVERT_EXPR always has its type set, even though it needs to be
10476 worked out. */
10477 if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
10478 return node;
10480 /* The switch block implements cases processing container nodes
10481 first. Contained nodes are always written back. Leaves come
10482 next and return a value. */
10483 switch (TREE_CODE (node))
10485 case BLOCK:
10487 /* 1- Block section.
10488 Set the local values on decl names so we can identify them
10489 faster when they're referenced. At that stage, identifiers
10490 are legal so we don't check for declaration errors. */
10491 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10493 DECL_CONTEXT (cn) = current_function_decl;
10494 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
10496 if (BLOCK_EXPR_BODY (node) == NULL_TREE)
10497 CAN_COMPLETE_NORMALLY (node) = 1;
10498 else
10500 tree stmt = BLOCK_EXPR_BODY (node);
10501 tree *ptr;
10502 int error_seen = 0;
10503 if (TREE_CODE (stmt) == COMPOUND_EXPR)
10505 /* Re-order from (((A; B); C); ...; Z) to
10506 (A; (B; (C ; (...; Z)))).
10507 This makes it easier to scan the statements left-to-right
10508 without using recursion (which might overflow the stack
10509 if the block has many statements. */
10510 for (;;)
10512 tree left = TREE_OPERAND (stmt, 0);
10513 if (TREE_CODE (left) != COMPOUND_EXPR)
10514 break;
10515 TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
10516 TREE_OPERAND (left, 1) = stmt;
10517 stmt = left;
10519 BLOCK_EXPR_BODY (node) = stmt;
10522 /* Now do the actual complete, without deep recursion for
10523 long blocks. */
10524 ptr = &BLOCK_EXPR_BODY (node);
10525 while (TREE_CODE (*ptr) == COMPOUND_EXPR
10526 && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
10528 tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
10529 tree *next = &TREE_OPERAND (*ptr, 1);
10530 TREE_OPERAND (*ptr, 0) = cur;
10531 if (cur == empty_stmt_node)
10533 /* Optimization; makes it easier to detect empty bodies.
10534 Most useful for <clinit> with all-constant initializer. */
10535 *ptr = *next;
10536 continue;
10538 if (TREE_CODE (cur) == ERROR_MARK)
10539 error_seen++;
10540 else if (! CAN_COMPLETE_NORMALLY (cur))
10542 wfl_op2 = *next;
10543 for (;;)
10545 if (TREE_CODE (wfl_op2) == BLOCK)
10546 wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
10547 else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
10548 wfl_op2 = TREE_OPERAND (wfl_op2, 0);
10549 else
10550 break;
10552 if (TREE_CODE (wfl_op2) != CASE_EXPR
10553 && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
10554 unreachable_stmt_error (*ptr);
10556 ptr = next;
10558 *ptr = java_complete_tree (*ptr);
10560 if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
10561 return error_mark_node;
10562 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
10564 /* Turn local bindings to null */
10565 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10566 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
10568 TREE_TYPE (node) = void_type_node;
10569 break;
10571 /* 2- They are expressions but ultimately deal with statements */
10573 case THROW_EXPR:
10574 wfl_op1 = TREE_OPERAND (node, 0);
10575 COMPLETE_CHECK_OP_0 (node);
10576 /* 14.19 A throw statement cannot complete normally. */
10577 CAN_COMPLETE_NORMALLY (node) = 0;
10578 return patch_throw_statement (node, wfl_op1);
10580 case SYNCHRONIZED_EXPR:
10581 wfl_op1 = TREE_OPERAND (node, 0);
10582 return patch_synchronized_statement (node, wfl_op1);
10584 case TRY_EXPR:
10585 return patch_try_statement (node);
10587 case TRY_FINALLY_EXPR:
10588 COMPLETE_CHECK_OP_0 (node);
10589 COMPLETE_CHECK_OP_1 (node);
10590 CAN_COMPLETE_NORMALLY (node)
10591 = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
10592 && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
10593 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
10594 return node;
10596 case CLEANUP_POINT_EXPR:
10597 COMPLETE_CHECK_OP_0 (node);
10598 TREE_TYPE (node) = void_type_node;
10599 CAN_COMPLETE_NORMALLY (node) =
10600 CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10601 return node;
10603 case WITH_CLEANUP_EXPR:
10604 COMPLETE_CHECK_OP_0 (node);
10605 COMPLETE_CHECK_OP_2 (node);
10606 CAN_COMPLETE_NORMALLY (node) =
10607 CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10608 TREE_TYPE (node) = void_type_node;
10609 return node;
10611 case LABELED_BLOCK_EXPR:
10612 PUSH_LABELED_BLOCK (node);
10613 if (LABELED_BLOCK_BODY (node))
10614 COMPLETE_CHECK_OP_1 (node);
10615 TREE_TYPE (node) = void_type_node;
10616 POP_LABELED_BLOCK ();
10618 if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
10620 LABELED_BLOCK_BODY (node) = NULL_TREE;
10621 CAN_COMPLETE_NORMALLY (node) = 1;
10623 else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
10624 CAN_COMPLETE_NORMALLY (node) = 1;
10625 return node;
10627 case EXIT_BLOCK_EXPR:
10628 /* We don't complete operand 1, because it's the return value of
10629 the EXIT_BLOCK_EXPR which doesn't exist it Java */
10630 return patch_bc_statement (node);
10632 case CASE_EXPR:
10633 cn = java_complete_tree (TREE_OPERAND (node, 0));
10634 if (cn == error_mark_node)
10635 return cn;
10637 /* First, the case expression must be constant. Values of final
10638 fields are accepted. */
10639 cn = fold (cn);
10640 if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
10641 && JDECL_P (TREE_OPERAND (cn, 1))
10642 && FIELD_FINAL (TREE_OPERAND (cn, 1))
10643 && DECL_INITIAL (TREE_OPERAND (cn, 1)))
10645 push_obstacks (&permanent_obstack, &permanent_obstack);
10646 cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
10647 TREE_OPERAND (cn, 1));
10648 pop_obstacks ();
10651 if (!TREE_CONSTANT (cn) && !flag_emit_xref)
10653 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10654 parse_error_context (node, "Constant expression required");
10655 return error_mark_node;
10658 nn = ctxp->current_loop;
10660 /* It must be assignable to the type of the switch expression. */
10661 if (!try_builtin_assignconv (NULL_TREE,
10662 TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
10664 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10665 parse_error_context
10666 (wfl_operator,
10667 "Incompatible type for case. Can't convert `%s' to `int'",
10668 lang_printable_name (TREE_TYPE (cn), 0));
10669 return error_mark_node;
10672 cn = fold (convert (int_type_node, cn));
10674 /* Multiple instance of a case label bearing the same
10675 value is checked during code generation. The case
10676 expression is allright so far. */
10677 TREE_OPERAND (node, 0) = cn;
10678 TREE_TYPE (node) = void_type_node;
10679 CAN_COMPLETE_NORMALLY (node) = 1;
10680 TREE_SIDE_EFFECTS (node) = 1;
10681 break;
10683 case DEFAULT_EXPR:
10684 nn = ctxp->current_loop;
10685 /* Only one default label is allowed per switch statement */
10686 if (SWITCH_HAS_DEFAULT (nn))
10688 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10689 parse_error_context (wfl_operator,
10690 "Duplicate case label: `default'");
10691 return error_mark_node;
10693 else
10694 SWITCH_HAS_DEFAULT (nn) = 1;
10695 TREE_TYPE (node) = void_type_node;
10696 TREE_SIDE_EFFECTS (node) = 1;
10697 CAN_COMPLETE_NORMALLY (node) = 1;
10698 break;
10700 case SWITCH_EXPR:
10701 case LOOP_EXPR:
10702 PUSH_LOOP (node);
10703 /* Check whether the loop was enclosed in a labeled
10704 statement. If not, create one, insert the loop in it and
10705 return the node */
10706 nn = patch_loop_statement (node);
10708 /* Anyways, walk the body of the loop */
10709 if (TREE_CODE (node) == LOOP_EXPR)
10710 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10711 /* Switch statement: walk the switch expression and the cases */
10712 else
10713 node = patch_switch_statement (node);
10715 if (TREE_OPERAND (node, 0) == error_mark_node)
10716 nn = error_mark_node;
10717 else
10719 TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
10720 /* If we returned something different, that's because we
10721 inserted a label. Pop the label too. */
10722 if (nn != node)
10724 if (CAN_COMPLETE_NORMALLY (node))
10725 CAN_COMPLETE_NORMALLY (nn) = 1;
10726 POP_LABELED_BLOCK ();
10729 POP_LOOP ();
10730 return nn;
10732 case EXIT_EXPR:
10733 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10734 return patch_exit_expr (node);
10736 case COND_EXPR:
10737 /* Condition */
10738 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10739 if (TREE_OPERAND (node, 0) == error_mark_node)
10740 return error_mark_node;
10741 /* then-else branches */
10742 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10743 if (TREE_OPERAND (node, 1) == error_mark_node)
10744 return error_mark_node;
10745 TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
10746 if (TREE_OPERAND (node, 2) == error_mark_node)
10747 return error_mark_node;
10748 return patch_if_else_statement (node);
10749 break;
10751 case CONDITIONAL_EXPR:
10752 /* Condition */
10753 wfl_op1 = TREE_OPERAND (node, 0);
10754 COMPLETE_CHECK_OP_0 (node);
10755 wfl_op2 = TREE_OPERAND (node, 1);
10756 COMPLETE_CHECK_OP_1 (node);
10757 wfl_op3 = TREE_OPERAND (node, 2);
10758 COMPLETE_CHECK_OP_2 (node);
10759 return patch_conditional_expr (node, wfl_op1, wfl_op2);
10761 /* 3- Expression section */
10762 case COMPOUND_EXPR:
10763 wfl_op2 = TREE_OPERAND (node, 1);
10764 TREE_OPERAND (node, 0) = nn =
10765 java_complete_tree (TREE_OPERAND (node, 0));
10766 if (wfl_op2 == empty_stmt_node)
10767 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
10768 else
10770 if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
10772 /* An unreachable condition in a do-while statement
10773 is *not* (technically) an unreachable statement. */
10774 nn = wfl_op2;
10775 if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
10776 nn = EXPR_WFL_NODE (nn);
10777 if (TREE_CODE (nn) != EXIT_EXPR)
10779 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
10780 parse_error_context (wfl_operator, "Unreachable statement");
10783 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10784 if (TREE_OPERAND (node, 1) == error_mark_node)
10785 return error_mark_node;
10786 CAN_COMPLETE_NORMALLY (node)
10787 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
10789 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
10790 break;
10792 case RETURN_EXPR:
10793 /* CAN_COMPLETE_NORMALLY (node) = 0; */
10794 return patch_return (node);
10796 case EXPR_WITH_FILE_LOCATION:
10797 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
10798 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
10800 tree wfl = node;
10801 node = resolve_expression_name (node, NULL);
10802 if (node == error_mark_node)
10803 return node;
10804 /* Keep line number information somewhere were it doesn't
10805 disrupt the completion process. */
10806 if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
10808 EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
10809 TREE_OPERAND (node, 1) = wfl;
10811 CAN_COMPLETE_NORMALLY (node) = 1;
10813 else
10815 tree body;
10816 int save_lineno = lineno;
10817 lineno = EXPR_WFL_LINENO (node);
10818 body = java_complete_tree (EXPR_WFL_NODE (node));
10819 lineno = save_lineno;
10820 EXPR_WFL_NODE (node) = body;
10821 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
10822 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
10823 if (body == empty_stmt_node)
10825 /* Optimization; makes it easier to detect empty bodies. */
10826 return body;
10828 if (body == error_mark_node)
10830 /* Its important for the evaluation of assignment that
10831 this mark on the TREE_TYPE is propagated. */
10832 TREE_TYPE (node) = error_mark_node;
10833 return error_mark_node;
10835 else
10836 TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
10839 break;
10841 case NEW_ARRAY_EXPR:
10842 /* Patch all the dimensions */
10843 flag = 0;
10844 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
10846 int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
10847 tree dim = convert (int_type_node,
10848 java_complete_tree (TREE_VALUE (cn)));
10849 if (dim == error_mark_node)
10851 flag = 1;
10852 continue;
10854 else
10856 TREE_VALUE (cn) = dim;
10857 /* Setup the location of the current dimension, for
10858 later error report. */
10859 TREE_PURPOSE (cn) =
10860 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
10861 EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
10864 /* They complete the array creation expression, if no errors
10865 were found. */
10866 CAN_COMPLETE_NORMALLY (node) = 1;
10867 return (flag ? error_mark_node
10868 : force_evaluation_order (patch_newarray (node)));
10870 case NEW_ANONYMOUS_ARRAY_EXPR:
10871 /* Create the array type if necessary. */
10872 if (ANONYMOUS_ARRAY_DIMS_SIG (node))
10874 tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
10875 if (!(type = resolve_type_during_patch (type)))
10876 return error_mark_node;
10877 type = build_array_from_name (type, NULL_TREE,
10878 ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
10879 ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
10881 node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
10882 ANONYMOUS_ARRAY_INITIALIZER (node));
10883 if (node == error_mark_node)
10884 return error_mark_node;
10885 CAN_COMPLETE_NORMALLY (node) = 1;
10886 return node;
10888 case NEW_CLASS_EXPR:
10889 case CALL_EXPR:
10890 /* Complete function's argument(s) first */
10891 if (complete_function_arguments (node))
10892 return error_mark_node;
10893 else
10895 tree decl, wfl = TREE_OPERAND (node, 0);
10896 int in_this = CALL_THIS_CONSTRUCTOR_P (node);
10898 node = patch_method_invocation (node, NULL_TREE,
10899 NULL_TREE, 0, &decl);
10900 if (node == error_mark_node)
10901 return error_mark_node;
10903 check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
10904 /* If we call this(...), register signature and positions */
10905 if (in_this)
10906 DECL_CONSTRUCTOR_CALLS (current_function_decl) =
10907 tree_cons (wfl, decl,
10908 DECL_CONSTRUCTOR_CALLS (current_function_decl));
10909 CAN_COMPLETE_NORMALLY (node) = 1;
10910 return force_evaluation_order (node);
10913 case MODIFY_EXPR:
10914 /* Save potential wfls */
10915 wfl_op1 = TREE_OPERAND (node, 0);
10916 TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
10918 if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
10919 && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
10920 && DECL_INITIAL (nn) != NULL_TREE)
10922 tree value;
10924 push_obstacks (&permanent_obstack, &permanent_obstack);
10925 value = fold_constant_for_init (nn, nn);
10926 pop_obstacks ();
10928 if (value != NULL_TREE)
10930 tree type = TREE_TYPE (value);
10931 if (JPRIMITIVE_TYPE_P (type) ||
10932 (type == string_ptr_type_node && ! flag_emit_class_files))
10933 return empty_stmt_node;
10935 DECL_INITIAL (nn) = NULL_TREE;
10937 wfl_op2 = TREE_OPERAND (node, 1);
10939 if (TREE_OPERAND (node, 0) == error_mark_node)
10940 return error_mark_node;
10942 flag = COMPOUND_ASSIGN_P (wfl_op2);
10943 if (flag)
10945 /* This might break when accessing outer field from inner
10946 class. TESTME, FIXME */
10947 tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0));
10949 /* Hand stablize the lhs on both places */
10950 TREE_OPERAND (node, 0) = lvalue;
10951 TREE_OPERAND (TREE_OPERAND (node, 1), 0) =
10952 (flag_emit_class_files ? lvalue : save_expr (lvalue));
10954 /* 15.25.2.a: Left hand is not an array access. FIXME */
10955 /* Now complete the RHS. We write it back later on. */
10956 nn = java_complete_tree (TREE_OPERAND (node, 1));
10958 if ((cn = patch_string (nn)))
10959 nn = cn;
10961 /* The last part of the rewrite for E1 op= E2 is to have
10962 E1 = (T)(E1 op E2), with T being the type of E1. */
10963 nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2),
10964 TREE_TYPE (lvalue), nn));
10966 /* 15.25.2.b: Left hand is an array access. FIXME */
10969 /* If we're about to patch a NEW_ARRAY_INIT, we call a special
10970 function to complete this RHS. Note that a NEW_ARRAY_INIT
10971 might have been already fully expanded if created as a result
10972 of processing an anonymous array initializer. We avoid doing
10973 the operation twice by testing whether the node already bears
10974 a type. */
10975 else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
10976 nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
10977 TREE_OPERAND (node, 1));
10978 /* Otherwise we simply complete the RHS */
10979 else
10980 nn = java_complete_tree (TREE_OPERAND (node, 1));
10982 if (nn == error_mark_node)
10983 return error_mark_node;
10985 /* Write back the RHS as we evaluated it. */
10986 TREE_OPERAND (node, 1) = nn;
10988 /* In case we're handling = with a String as a RHS, we need to
10989 produce a String out of the RHS (it might still be a
10990 STRING_CST or a StringBuffer at this stage */
10991 if ((nn = patch_string (TREE_OPERAND (node, 1))))
10992 TREE_OPERAND (node, 1) = nn;
10994 if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
10995 TREE_OPERAND (node, 1))))
10997 /* We return error_mark_node if outer_field_access_fix
10998 detects we write into a final. */
10999 if (nn == error_mark_node)
11000 return error_mark_node;
11001 node = nn;
11003 else
11005 node = patch_assignment (node, wfl_op1, wfl_op2);
11006 /* Reorganize the tree if necessary. */
11007 if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node))
11008 || JSTRING_P (TREE_TYPE (node))))
11009 node = java_refold (node);
11012 CAN_COMPLETE_NORMALLY (node) = 1;
11013 return node;
11015 case MULT_EXPR:
11016 case PLUS_EXPR:
11017 case MINUS_EXPR:
11018 case LSHIFT_EXPR:
11019 case RSHIFT_EXPR:
11020 case URSHIFT_EXPR:
11021 case BIT_AND_EXPR:
11022 case BIT_XOR_EXPR:
11023 case BIT_IOR_EXPR:
11024 case TRUNC_MOD_EXPR:
11025 case TRUNC_DIV_EXPR:
11026 case RDIV_EXPR:
11027 case TRUTH_ANDIF_EXPR:
11028 case TRUTH_ORIF_EXPR:
11029 case EQ_EXPR:
11030 case NE_EXPR:
11031 case GT_EXPR:
11032 case GE_EXPR:
11033 case LT_EXPR:
11034 case LE_EXPR:
11035 /* Operands 0 and 1 are WFL in certain cases only. patch_binop
11036 knows how to handle those cases. */
11037 wfl_op1 = TREE_OPERAND (node, 0);
11038 wfl_op2 = TREE_OPERAND (node, 1);
11040 CAN_COMPLETE_NORMALLY (node) = 1;
11041 /* Don't complete string nodes if dealing with the PLUS operand. */
11042 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11044 nn = java_complete_tree (wfl_op1);
11045 if (nn == error_mark_node)
11046 return error_mark_node;
11048 TREE_OPERAND (node, 0) = nn;
11050 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11052 nn = java_complete_tree (wfl_op2);
11053 if (nn == error_mark_node)
11054 return error_mark_node;
11056 TREE_OPERAND (node, 1) = nn;
11058 return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11060 case INSTANCEOF_EXPR:
11061 wfl_op1 = TREE_OPERAND (node, 0);
11062 COMPLETE_CHECK_OP_0 (node);
11063 if (flag_emit_xref)
11065 TREE_TYPE (node) = boolean_type_node;
11066 return node;
11068 return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11070 case UNARY_PLUS_EXPR:
11071 case NEGATE_EXPR:
11072 case TRUTH_NOT_EXPR:
11073 case BIT_NOT_EXPR:
11074 case PREDECREMENT_EXPR:
11075 case PREINCREMENT_EXPR:
11076 case POSTDECREMENT_EXPR:
11077 case POSTINCREMENT_EXPR:
11078 case CONVERT_EXPR:
11079 /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11080 how to handle those cases. */
11081 wfl_op1 = TREE_OPERAND (node, 0);
11082 CAN_COMPLETE_NORMALLY (node) = 1;
11083 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11084 if (TREE_OPERAND (node, 0) == error_mark_node)
11085 return error_mark_node;
11086 node = patch_unaryop (node, wfl_op1);
11087 CAN_COMPLETE_NORMALLY (node) = 1;
11088 break;
11090 case ARRAY_REF:
11091 /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11092 how to handle those cases. */
11093 wfl_op1 = TREE_OPERAND (node, 0);
11094 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11095 if (TREE_OPERAND (node, 0) == error_mark_node)
11096 return error_mark_node;
11097 if (!flag_emit_class_files && !flag_emit_xref)
11098 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11099 /* The same applies to wfl_op2 */
11100 wfl_op2 = TREE_OPERAND (node, 1);
11101 TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11102 if (TREE_OPERAND (node, 1) == error_mark_node)
11103 return error_mark_node;
11104 if (!flag_emit_class_files && !flag_emit_xref)
11105 TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11106 return patch_array_ref (node);
11108 case RECORD_TYPE:
11109 return node;;
11111 case COMPONENT_REF:
11112 /* The first step in the re-write of qualified name handling. FIXME.
11113 So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11114 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11115 if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11117 tree name = TREE_OPERAND (node, 1);
11118 tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11119 if (field == NULL_TREE)
11121 error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11122 return error_mark_node;
11124 if (! FIELD_STATIC (field))
11126 error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11127 return error_mark_node;
11129 return field;
11131 else
11132 fatal ("unimplemented java_complete_tree for COMPONENT_REF");
11133 break;
11135 case THIS_EXPR:
11136 /* Can't use THIS in a static environment */
11137 if (!current_this)
11139 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11140 parse_error_context (wfl_operator,
11141 "Keyword `this' used outside allowed context");
11142 TREE_TYPE (node) = error_mark_node;
11143 return error_mark_node;
11145 if (ctxp->explicit_constructor_p)
11147 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11148 parse_error_context
11149 (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11150 TREE_TYPE (node) = error_mark_node;
11151 return error_mark_node;
11153 return current_this;
11155 case CLASS_LITERAL:
11156 CAN_COMPLETE_NORMALLY (node) = 1;
11157 node = patch_incomplete_class_ref (node);
11158 if (node == error_mark_node)
11159 return error_mark_node;
11160 break;
11162 case INSTANCE_INITIALIZERS_EXPR:
11163 in_instance_initializer++;
11164 node = java_complete_tree (TREE_OPERAND (node, 0));
11165 in_instance_initializer--;
11166 if (node != error_mark_node)
11167 TREE_TYPE (node) = void_type_node;
11168 else
11169 return error_mark_node;
11170 break;
11172 default:
11173 CAN_COMPLETE_NORMALLY (node) = 1;
11174 /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11175 and it's time to turn it into the appropriate String object */
11176 if ((nn = patch_string (node)))
11177 node = nn;
11178 else
11179 fatal ("No case for tree code `%s' - java_complete_tree\n",
11180 tree_code_name [TREE_CODE (node)]);
11182 return node;
11185 /* Complete function call's argument. Return a non zero value is an
11186 error was found. */
11188 static int
11189 complete_function_arguments (node)
11190 tree node;
11192 int flag = 0;
11193 tree cn;
11195 ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11196 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11198 tree wfl = TREE_VALUE (cn), parm, temp;
11199 parm = java_complete_tree (wfl);
11201 if (parm == error_mark_node)
11203 flag = 1;
11204 continue;
11206 /* If have a string literal that we haven't transformed yet or a
11207 crafted string buffer, as a result of use of the the String
11208 `+' operator. Build `parm.toString()' and expand it. */
11209 if ((temp = patch_string (parm)))
11210 parm = temp;
11211 /* Inline PRIMTYPE.TYPE read access */
11212 parm = maybe_build_primttype_type_ref (parm, wfl);
11214 TREE_VALUE (cn) = parm;
11216 ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11217 return flag;
11220 /* Sometimes (for loops and variable initialized during their
11221 declaration), we want to wrap a statement around a WFL and turn it
11222 debugable. */
11224 static tree
11225 build_debugable_stmt (location, stmt)
11226 int location;
11227 tree stmt;
11229 if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11231 stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11232 EXPR_WFL_LINECOL (stmt) = location;
11234 JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11235 return stmt;
11238 static tree
11239 build_expr_block (body, decls)
11240 tree body, decls;
11242 tree node = make_node (BLOCK);
11243 BLOCK_EXPR_DECLS (node) = decls;
11244 BLOCK_EXPR_BODY (node) = body;
11245 if (body)
11246 TREE_TYPE (node) = TREE_TYPE (body);
11247 TREE_SIDE_EFFECTS (node) = 1;
11248 return node;
11251 /* Create a new function block and link it approriately to current
11252 function block chain */
11254 static tree
11255 enter_block ()
11257 return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
11260 /* Link block B supercontext to the previous block. The current
11261 function DECL is used as supercontext when enter_a_block is called
11262 for the first time for a given function. The current function body
11263 (DECL_FUNCTION_BODY) is set to be block B. */
11265 static tree
11266 enter_a_block (b)
11267 tree b;
11269 tree fndecl = current_function_decl;
11271 if (!fndecl) {
11272 BLOCK_SUPERCONTEXT (b) = current_static_block;
11273 current_static_block = b;
11276 else if (!DECL_FUNCTION_BODY (fndecl))
11278 BLOCK_SUPERCONTEXT (b) = fndecl;
11279 DECL_FUNCTION_BODY (fndecl) = b;
11281 else
11283 BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11284 DECL_FUNCTION_BODY (fndecl) = b;
11286 return b;
11289 /* Exit a block by changing the current function body
11290 (DECL_FUNCTION_BODY) to the current block super context, only if
11291 the block being exited isn't the method's top level one. */
11293 static tree
11294 exit_block ()
11296 tree b;
11297 if (current_function_decl)
11299 b = DECL_FUNCTION_BODY (current_function_decl);
11300 if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11301 DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11303 else
11305 b = current_static_block;
11307 if (BLOCK_SUPERCONTEXT (b))
11308 current_static_block = BLOCK_SUPERCONTEXT (b);
11310 return b;
11313 /* Lookup for NAME in the nested function's blocks, all the way up to
11314 the current toplevel one. It complies with Java's local variable
11315 scoping rules. */
11317 static tree
11318 lookup_name_in_blocks (name)
11319 tree name;
11321 tree b = GET_CURRENT_BLOCK (current_function_decl);
11323 while (b != current_function_decl)
11325 tree current;
11327 /* Paranoid sanity check. To be removed */
11328 if (TREE_CODE (b) != BLOCK)
11329 fatal ("non block expr function body - lookup_name_in_blocks");
11331 for (current = BLOCK_EXPR_DECLS (b); current;
11332 current = TREE_CHAIN (current))
11333 if (DECL_NAME (current) == name)
11334 return current;
11335 b = BLOCK_SUPERCONTEXT (b);
11337 return NULL_TREE;
11340 static void
11341 maybe_absorb_scoping_blocks ()
11343 while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
11345 tree b = exit_block ();
11346 java_method_add_stmt (current_function_decl, b);
11347 SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
11352 /* This section of the source is reserved to build_* functions that
11353 are building incomplete tree nodes and the patch_* functions that
11354 are completing them. */
11356 /* Wrap a non WFL node around a WFL. */
11357 static tree
11358 build_wfl_wrap (node)
11359 tree node;
11361 tree wfl, node_to_insert = node;
11363 /* We want to process THIS . xxx symbolicaly, to keep it consistent
11364 with the way we're processing SUPER. A THIS from a primary as a
11365 different form than a SUPER. Turn THIS into something symbolic */
11366 if (TREE_CODE (node) == THIS_EXPR)
11367 node_to_insert = wfl = build_wfl_node (this_identifier_node);
11368 else
11369 wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
11371 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (node);
11372 EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
11373 return wfl;
11377 /* Build a super() constructor invocation. Returns empty_stmt_node if
11378 we're currently dealing with the class java.lang.Object. */
11380 static tree
11381 build_super_invocation (mdecl)
11382 tree mdecl;
11384 if (DECL_CONTEXT (mdecl) == object_type_node)
11385 return empty_stmt_node;
11386 else
11388 tree super_wfl = build_wfl_node (super_identifier_node);
11389 tree a = NULL_TREE, t;
11390 /* If we're dealing with an anonymous class, pass the arguments
11391 of the crafted constructor along. */
11392 if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
11394 SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
11395 for (; t != end_params_node; t = TREE_CHAIN (t))
11396 a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
11398 return build_method_invocation (super_wfl, a);
11402 /* Build a SUPER/THIS qualified method invocation. */
11404 static tree
11405 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
11406 int use_this;
11407 tree name, args;
11408 int lloc, rloc;
11410 tree invok;
11411 tree wfl =
11412 build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
11413 EXPR_WFL_LINECOL (wfl) = lloc;
11414 invok = build_method_invocation (name, args);
11415 return make_qualified_primary (wfl, invok, rloc);
11418 /* Build an incomplete CALL_EXPR node. */
11420 static tree
11421 build_method_invocation (name, args)
11422 tree name;
11423 tree args;
11425 tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
11426 TREE_SIDE_EFFECTS (call) = 1;
11427 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11428 return call;
11431 /* Build an incomplete new xxx(...) node. */
11433 static tree
11434 build_new_invocation (name, args)
11435 tree name, args;
11437 tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
11438 TREE_SIDE_EFFECTS (call) = 1;
11439 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11440 return call;
11443 /* Build an incomplete assignment expression. */
11445 static tree
11446 build_assignment (op, op_location, lhs, rhs)
11447 int op, op_location;
11448 tree lhs, rhs;
11450 tree assignment;
11451 /* Build the corresponding binop if we deal with a Compound
11452 Assignment operator. Mark the binop sub-tree as part of a
11453 Compound Assignment expression */
11454 if (op != ASSIGN_TK)
11456 rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
11457 COMPOUND_ASSIGN_P (rhs) = 1;
11459 assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
11460 TREE_SIDE_EFFECTS (assignment) = 1;
11461 EXPR_WFL_LINECOL (assignment) = op_location;
11462 return assignment;
11465 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
11467 char *
11468 print_int_node (node)
11469 tree node;
11471 static char buffer [80];
11472 if (TREE_CONSTANT_OVERFLOW (node))
11473 sprintf (buffer, "<overflow>");
11475 if (TREE_INT_CST_HIGH (node) == 0)
11476 sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
11477 TREE_INT_CST_LOW (node));
11478 else if (TREE_INT_CST_HIGH (node) == -1
11479 && TREE_INT_CST_LOW (node) != 0)
11481 buffer [0] = '-';
11482 sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
11483 -TREE_INT_CST_LOW (node));
11485 else
11486 sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
11487 TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
11489 return buffer;
11492 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
11493 context. */
11495 static int
11496 check_final_assignment (lvalue, wfl)
11497 tree lvalue, wfl;
11499 if (TREE_CODE (lvalue) == COMPOUND_EXPR
11500 && JDECL_P (TREE_OPERAND (lvalue, 1)))
11501 lvalue = TREE_OPERAND (lvalue, 1);
11503 /* When generating class files, references to the `length' field
11504 look a bit different. */
11505 if ((flag_emit_class_files
11506 && TREE_CODE (lvalue) == COMPONENT_REF
11507 && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
11508 && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
11509 || (TREE_CODE (lvalue) == FIELD_DECL
11510 && FIELD_FINAL (lvalue)
11511 && !DECL_CLINIT_P (current_function_decl)
11512 && !DECL_FINIT_P (current_function_decl)))
11514 parse_error_context
11515 (wfl, "Can't assign a value to the final variable `%s'",
11516 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
11517 return 1;
11519 return 0;
11522 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
11523 read. This is needed to avoid circularities in the implementation
11524 of these fields in libjava. */
11526 static tree
11527 maybe_build_primttype_type_ref (rhs, wfl)
11528 tree rhs, wfl;
11530 tree to_return = NULL_TREE;
11531 tree rhs_type = TREE_TYPE (rhs);
11532 if (TREE_CODE (rhs) == COMPOUND_EXPR)
11534 tree n = TREE_OPERAND (rhs, 1);
11535 if (TREE_CODE (n) == VAR_DECL
11536 && DECL_NAME (n) == TYPE_identifier_node
11537 && rhs_type == class_ptr_type)
11539 const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
11540 if (!strncmp (self_name, "java.lang.", 10))
11541 to_return = build_primtype_type_ref (self_name);
11544 return (to_return ? to_return : rhs );
11547 /* 15.25 Assignment operators. */
11549 static tree
11550 patch_assignment (node, wfl_op1, wfl_op2)
11551 tree node;
11552 tree wfl_op1;
11553 tree wfl_op2;
11555 tree rhs = TREE_OPERAND (node, 1);
11556 tree lvalue = TREE_OPERAND (node, 0), llvalue;
11557 tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
11558 int error_found = 0;
11559 int lvalue_from_array = 0;
11561 /* Can't assign to a (blank) final. */
11562 if (check_final_assignment (lvalue, wfl_op1))
11563 error_found = 1;
11565 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11567 /* Lhs can be a named variable */
11568 if (JDECL_P (lvalue))
11570 lhs_type = TREE_TYPE (lvalue);
11572 /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
11573 comment on reason why */
11574 else if (TREE_CODE (wfl_op1) == ARRAY_REF)
11576 lhs_type = TREE_TYPE (lvalue);
11577 lvalue_from_array = 1;
11579 /* Or a field access */
11580 else if (TREE_CODE (lvalue) == COMPONENT_REF)
11581 lhs_type = TREE_TYPE (lvalue);
11582 /* Or a function return slot */
11583 else if (TREE_CODE (lvalue) == RESULT_DECL)
11584 lhs_type = TREE_TYPE (lvalue);
11585 /* Otherwise, we might want to try to write into an optimized static
11586 final, this is an of a different nature, reported further on. */
11587 else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
11588 && resolve_expression_name (wfl_op1, &llvalue))
11590 if (!error_found && check_final_assignment (llvalue, wfl_op1))
11592 /* What we should do instead is resetting the all the flags
11593 previously set, exchange lvalue for llvalue and continue. */
11594 error_found = 1;
11595 return error_mark_node;
11597 else
11598 lhs_type = TREE_TYPE (lvalue);
11600 else
11602 parse_error_context (wfl_op1, "Invalid left hand side of assignment");
11603 error_found = 1;
11606 rhs_type = TREE_TYPE (rhs);
11607 /* 5.1 Try the assignment conversion for builtin type. */
11608 new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
11610 /* 5.2 If it failed, try a reference conversion */
11611 if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
11612 lhs_type = promote_type (rhs_type);
11614 /* 15.25.2 If we have a compound assignment, convert RHS into the
11615 type of the LHS */
11616 else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11617 new_rhs = convert (lhs_type, rhs);
11619 /* Explicit cast required. This is an error */
11620 if (!new_rhs)
11622 char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
11623 char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
11624 tree wfl;
11625 char operation [32]; /* Max size known */
11627 /* If the assignment is part of a declaration, we use the WFL of
11628 the declared variable to point out the error and call it a
11629 declaration problem. If the assignment is a genuine =
11630 operator, we call is a operator `=' problem, otherwise we
11631 call it an assignment problem. In both of these last cases,
11632 we use the WFL of the operator to indicate the error. */
11634 if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
11636 wfl = wfl_op1;
11637 strcpy (operation, "declaration");
11639 else
11641 wfl = wfl_operator;
11642 if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11643 strcpy (operation, "assignment");
11644 else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
11645 strcpy (operation, "`return'");
11646 else
11647 strcpy (operation, "`='");
11650 if (!valid_cast_to_p (rhs_type, lhs_type))
11651 parse_error_context
11652 (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
11653 operation, t1, t2);
11654 else
11655 parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
11656 operation, t1, t2);
11657 free (t1); free (t2);
11658 error_found = 1;
11661 /* Inline read access to java.lang.PRIMTYPE.TYPE */
11662 if (new_rhs)
11663 new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
11665 if (error_found)
11666 return error_mark_node;
11668 /* 10.10: Array Store Exception runtime check */
11669 if (!flag_emit_class_files
11670 && !flag_emit_xref
11671 && lvalue_from_array
11672 && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
11674 tree check;
11675 tree base = lvalue;
11677 /* We need to retrieve the right argument for _Jv_CheckArrayStore */
11678 if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11679 base = TREE_OPERAND (lvalue, 0);
11680 else
11682 if (flag_bounds_check)
11683 base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
11684 else
11685 base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
11688 /* Build the invocation of _Jv_CheckArrayStore */
11689 new_rhs = save_expr (new_rhs);
11690 check = build (CALL_EXPR, void_type_node,
11691 build_address_of (soft_checkarraystore_node),
11692 tree_cons (NULL_TREE, base,
11693 build_tree_list (NULL_TREE, new_rhs)),
11694 NULL_TREE);
11695 TREE_SIDE_EFFECTS (check) = 1;
11697 /* We have to decide on an insertion point */
11698 if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11700 tree t;
11701 if (flag_bounds_check)
11703 t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
11704 TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
11705 build (COMPOUND_EXPR, void_type_node, t, check);
11707 else
11708 TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
11709 check, TREE_OPERAND (lvalue, 1));
11711 else
11713 /* Make sure the bound check will happen before the store check */
11714 if (flag_bounds_check)
11715 TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
11716 build (COMPOUND_EXPR, void_type_node,
11717 TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
11718 else
11719 lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
11723 TREE_OPERAND (node, 0) = lvalue;
11724 TREE_OPERAND (node, 1) = new_rhs;
11725 TREE_TYPE (node) = lhs_type;
11726 return node;
11729 /* Check that type SOURCE can be cast into type DEST. If the cast
11730 can't occur at all, return 0 otherwise 1. This function is used to
11731 produce accurate error messages on the reasons why an assignment
11732 failed. */
11734 static tree
11735 try_reference_assignconv (lhs_type, rhs)
11736 tree lhs_type, rhs;
11738 tree new_rhs = NULL_TREE;
11739 tree rhs_type = TREE_TYPE (rhs);
11741 if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
11743 /* `null' may be assigned to any reference type */
11744 if (rhs == null_pointer_node)
11745 new_rhs = null_pointer_node;
11746 /* Try the reference assignment conversion */
11747 else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
11748 new_rhs = rhs;
11749 /* This is a magic assignment that we process differently */
11750 else if (rhs == soft_exceptioninfo_call_node)
11751 new_rhs = rhs;
11753 return new_rhs;
11756 /* Check that RHS can be converted into LHS_TYPE by the assignment
11757 conversion (5.2), for the cases of RHS being a builtin type. Return
11758 NULL_TREE if the conversion fails or if because RHS isn't of a
11759 builtin type. Return a converted RHS if the conversion is possible. */
11761 static tree
11762 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
11763 tree wfl_op1, lhs_type, rhs;
11765 tree new_rhs = NULL_TREE;
11766 tree rhs_type = TREE_TYPE (rhs);
11768 /* Zero accepted everywhere */
11769 if (TREE_CODE (rhs) == INTEGER_CST
11770 && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
11771 && JPRIMITIVE_TYPE_P (rhs_type))
11772 new_rhs = convert (lhs_type, rhs);
11774 /* 5.1.1 Try Identity Conversion,
11775 5.1.2 Try Widening Primitive Conversion */
11776 else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
11777 new_rhs = convert (lhs_type, rhs);
11779 /* Try a narrowing primitive conversion (5.1.3):
11780 - expression is a constant expression of type int AND
11781 - variable is byte, short or char AND
11782 - The value of the expression is representable in the type of the
11783 variable */
11784 else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
11785 && (lhs_type == byte_type_node || lhs_type == char_type_node
11786 || lhs_type == short_type_node))
11788 if (int_fits_type_p (rhs, lhs_type))
11789 new_rhs = convert (lhs_type, rhs);
11790 else if (wfl_op1) /* Might be called with a NULL */
11791 parse_warning_context
11792 (wfl_op1, "Constant expression `%s' to wide for narrowing primitive conversion to `%s'",
11793 print_int_node (rhs), lang_printable_name (lhs_type, 0));
11794 /* Reported a warning that will turn into an error further
11795 down, so we don't return */
11798 return new_rhs;
11801 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
11802 conversion (5.1.1) or widening primitve conversion (5.1.2). Return
11803 0 is the conversion test fails. This implements parts the method
11804 invocation convertion (5.3). */
11806 static int
11807 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
11808 tree lhs_type, rhs_type;
11810 /* 5.1.1: This is the identity conversion part. */
11811 if (lhs_type == rhs_type)
11812 return 1;
11814 /* Reject non primitive types */
11815 if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
11816 return 0;
11818 /* 5.1.2: widening primitive conversion. byte, even if it's smaller
11819 than a char can't be converted into a char. Short can't too, but
11820 the < test below takes care of that */
11821 if (lhs_type == char_type_node && rhs_type == byte_type_node)
11822 return 0;
11824 /* Accept all promoted type here. Note, we can't use <= in the test
11825 below, because we still need to bounce out assignments of short
11826 to char and the likes */
11827 if (lhs_type == int_type_node
11828 && (rhs_type == promoted_byte_type_node
11829 || rhs_type == promoted_short_type_node
11830 || rhs_type == promoted_char_type_node
11831 || rhs_type == promoted_boolean_type_node))
11832 return 1;
11834 /* From here, an integral is widened if its precision is smaller
11835 than the precision of the LHS or if the LHS is a floating point
11836 type, or the RHS is a float and the RHS a double. */
11837 if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type)
11838 && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
11839 || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
11840 || (rhs_type == float_type_node && lhs_type == double_type_node))
11841 return 1;
11843 return 0;
11846 /* Check that something of SOURCE type can be assigned or cast to
11847 something of DEST type at runtime. Return 1 if the operation is
11848 valid, 0 otherwise. If CAST is set to 1, we're treating the case
11849 were SOURCE is cast into DEST, which borrows a lot of the
11850 assignment check. */
11852 static int
11853 valid_ref_assignconv_cast_p (source, dest, cast)
11854 tree source;
11855 tree dest;
11856 int cast;
11858 /* SOURCE or DEST might be null if not from a declared entity. */
11859 if (!source || !dest)
11860 return 0;
11861 if (JNULLP_TYPE_P (source))
11862 return 1;
11863 if (TREE_CODE (source) == POINTER_TYPE)
11864 source = TREE_TYPE (source);
11865 if (TREE_CODE (dest) == POINTER_TYPE)
11866 dest = TREE_TYPE (dest);
11867 /* Case where SOURCE is a class type */
11868 if (TYPE_CLASS_P (source))
11870 if (TYPE_CLASS_P (dest))
11871 return (source == dest
11872 || inherits_from_p (source, dest)
11873 || enclosing_context_p (dest, source /*source, dest*/)
11874 || (cast && inherits_from_p (dest, source)));
11875 if (TYPE_INTERFACE_P (dest))
11877 /* If doing a cast and SOURCE is final, the operation is
11878 always correct a compile time (because even if SOURCE
11879 does not implement DEST, a subclass of SOURCE might). */
11880 if (cast && !CLASS_FINAL (TYPE_NAME (source)))
11881 return 1;
11882 /* Otherwise, SOURCE must implement DEST */
11883 return interface_of_p (dest, source);
11885 /* DEST is an array, cast permited if SOURCE is of Object type */
11886 return (cast && source == object_type_node ? 1 : 0);
11888 if (TYPE_INTERFACE_P (source))
11890 if (TYPE_CLASS_P (dest))
11892 /* If not casting, DEST must be the Object type */
11893 if (!cast)
11894 return dest == object_type_node;
11895 /* We're doing a cast. The cast is always valid is class
11896 DEST is not final, otherwise, DEST must implement SOURCE */
11897 else if (!CLASS_FINAL (TYPE_NAME (dest)))
11898 return 1;
11899 else
11900 return interface_of_p (source, dest);
11902 if (TYPE_INTERFACE_P (dest))
11904 /* If doing a cast, then if SOURCE and DEST contain method
11905 with the same signature but different return type, then
11906 this is a (compile time) error */
11907 if (cast)
11909 tree method_source, method_dest;
11910 tree source_type;
11911 tree source_sig;
11912 tree source_name;
11913 for (method_source = TYPE_METHODS (source); method_source;
11914 method_source = TREE_CHAIN (method_source))
11916 source_sig =
11917 build_java_argument_signature (TREE_TYPE (method_source));
11918 source_type = TREE_TYPE (TREE_TYPE (method_source));
11919 source_name = DECL_NAME (method_source);
11920 for (method_dest = TYPE_METHODS (dest);
11921 method_dest; method_dest = TREE_CHAIN (method_dest))
11922 if (source_sig ==
11923 build_java_argument_signature (TREE_TYPE (method_dest))
11924 && source_name == DECL_NAME (method_dest)
11925 && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
11926 return 0;
11928 return 1;
11930 else
11931 return source == dest || interface_of_p (dest, source);
11933 else /* Array */
11934 return (cast ?
11935 (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable) : 0);
11937 if (TYPE_ARRAY_P (source))
11939 if (TYPE_CLASS_P (dest))
11940 return dest == object_type_node;
11941 /* Can't cast an array to an interface unless the interface is
11942 java.lang.Cloneable */
11943 if (TYPE_INTERFACE_P (dest))
11944 return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
11945 else /* Arrays */
11947 tree source_element_type = TYPE_ARRAY_ELEMENT (source);
11948 tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
11950 /* In case of severe errors, they turn out null */
11951 if (!dest_element_type || !source_element_type)
11952 return 0;
11953 if (source_element_type == dest_element_type)
11954 return 1;
11955 return valid_ref_assignconv_cast_p (source_element_type,
11956 dest_element_type, cast);
11958 return 0;
11960 return 0;
11963 static int
11964 valid_cast_to_p (source, dest)
11965 tree source;
11966 tree dest;
11968 if (TREE_CODE (source) == POINTER_TYPE)
11969 source = TREE_TYPE (source);
11970 if (TREE_CODE (dest) == POINTER_TYPE)
11971 dest = TREE_TYPE (dest);
11973 if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
11974 return valid_ref_assignconv_cast_p (source, dest, 1);
11976 else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
11977 return 1;
11979 return 0;
11982 /* Method invocation conversion test. Return 1 if type SOURCE can be
11983 converted to type DEST through the methond invocation conversion
11984 process (5.3) */
11986 static tree
11987 do_unary_numeric_promotion (arg)
11988 tree arg;
11990 tree type = TREE_TYPE (arg);
11991 if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
11992 : TREE_CODE (type) == CHAR_TYPE)
11993 arg = convert (int_type_node, arg);
11994 return arg;
11997 /* Return a non zero value if SOURCE can be converted into DEST using
11998 the method invocation conversion rule (5.3). */
11999 static int
12000 valid_method_invocation_conversion_p (dest, source)
12001 tree dest, source;
12003 return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
12004 && valid_builtin_assignconv_identity_widening_p (dest, source))
12005 || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
12006 && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
12007 && valid_ref_assignconv_cast_p (source, dest, 0)));
12010 /* Build an incomplete binop expression. */
12012 static tree
12013 build_binop (op, op_location, op1, op2)
12014 enum tree_code op;
12015 int op_location;
12016 tree op1, op2;
12018 tree binop = build (op, NULL_TREE, op1, op2);
12019 TREE_SIDE_EFFECTS (binop) = 1;
12020 /* Store the location of the operator, for better error report. The
12021 string of the operator will be rebuild based on the OP value. */
12022 EXPR_WFL_LINECOL (binop) = op_location;
12023 return binop;
12026 /* Build the string of the operator retained by NODE. If NODE is part
12027 of a compound expression, add an '=' at the end of the string. This
12028 function is called when an error needs to be reported on an
12029 operator. The string is returned as a pointer to a static character
12030 buffer. */
12032 static char *
12033 operator_string (node)
12034 tree node;
12036 #define BUILD_OPERATOR_STRING(S) \
12038 sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
12039 return buffer; \
12042 static char buffer [10];
12043 switch (TREE_CODE (node))
12045 case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
12046 case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
12047 case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
12048 case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12049 case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
12050 case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
12051 case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
12052 case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
12053 case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
12054 case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
12055 case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
12056 case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
12057 case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
12058 case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
12059 case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
12060 case GT_EXPR: BUILD_OPERATOR_STRING (">");
12061 case GE_EXPR: BUILD_OPERATOR_STRING (">=");
12062 case LT_EXPR: BUILD_OPERATOR_STRING ("<");
12063 case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
12064 case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12065 case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
12066 case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
12067 case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
12068 case PREINCREMENT_EXPR: /* Fall through */
12069 case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
12070 case PREDECREMENT_EXPR: /* Fall through */
12071 case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
12072 default:
12073 fatal ("unregistered operator %s - operator_string",
12074 tree_code_name [TREE_CODE (node)]);
12076 return NULL;
12077 #undef BUILD_OPERATOR_STRING
12080 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2. */
12082 static int
12083 java_decl_equiv (var_acc1, var_acc2)
12084 tree var_acc1, var_acc2;
12086 if (JDECL_P (var_acc1))
12087 return (var_acc1 == var_acc2);
12089 return (TREE_CODE (var_acc1) == COMPONENT_REF
12090 && TREE_CODE (var_acc2) == COMPONENT_REF
12091 && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
12092 == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
12093 && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
12096 /* Return a non zero value if CODE is one of the operators that can be
12097 used in conjunction with the `=' operator in a compound assignment. */
12099 static int
12100 binop_compound_p (code)
12101 enum tree_code code;
12103 int i;
12104 for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
12105 if (binop_lookup [i] == code)
12106 break;
12108 return i < BINOP_COMPOUND_CANDIDATES;
12111 /* Reorganize after a fold to get SAVE_EXPR to generate what we want. */
12113 static tree
12114 java_refold (t)
12115 tree t;
12117 tree c, b, ns, decl;
12119 if (TREE_CODE (t) != MODIFY_EXPR)
12120 return t;
12122 c = TREE_OPERAND (t, 1);
12123 if (! (c && TREE_CODE (c) == COMPOUND_EXPR
12124 && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
12125 && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
12126 return t;
12128 /* Now the left branch of the binary operator. */
12129 b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
12130 if (! (b && TREE_CODE (b) == NOP_EXPR
12131 && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
12132 return t;
12134 ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
12135 if (! (ns && TREE_CODE (ns) == NOP_EXPR
12136 && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
12137 return t;
12139 decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
12140 if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
12141 /* It's got to be the an equivalent decl */
12142 && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
12144 /* Shorten the NOP_EXPR/SAVE_EXPR path. */
12145 TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
12146 /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
12147 TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
12148 /* Change the right part of the BINOP_EXPR */
12149 TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
12152 return t;
12155 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
12156 errors but we modify NODE so that it contains the type computed
12157 according to the expression, when it's fixed. Otherwise, we write
12158 error_mark_node as the type. It allows us to further the analysis
12159 of remaining nodes and detects more errors in certain cases. */
12161 static tree
12162 patch_binop (node, wfl_op1, wfl_op2)
12163 tree node;
12164 tree wfl_op1;
12165 tree wfl_op2;
12167 tree op1 = TREE_OPERAND (node, 0);
12168 tree op2 = TREE_OPERAND (node, 1);
12169 tree op1_type = TREE_TYPE (op1);
12170 tree op2_type = TREE_TYPE (op2);
12171 tree prom_type = NULL_TREE, cn;
12172 int code = TREE_CODE (node);
12174 /* If 1, tell the routine that we have to return error_mark_node
12175 after checking for the initialization of the RHS */
12176 int error_found = 0;
12178 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12180 switch (code)
12182 /* 15.16 Multiplicative operators */
12183 case MULT_EXPR: /* 15.16.1 Multiplication Operator * */
12184 case RDIV_EXPR: /* 15.16.2 Division Operator / */
12185 case TRUNC_DIV_EXPR: /* 15.16.2 Integral type Division Operator / */
12186 case TRUNC_MOD_EXPR: /* 15.16.3 Remainder operator % */
12187 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12189 if (!JPRIMITIVE_TYPE_P (op1_type))
12190 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12191 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12192 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12193 TREE_TYPE (node) = error_mark_node;
12194 error_found = 1;
12195 break;
12197 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12198 /* Change the division operator if necessary */
12199 if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
12200 TREE_SET_CODE (node, TRUNC_DIV_EXPR);
12202 if (TREE_CODE (prom_type) == INTEGER_TYPE
12203 && flag_use_divide_subroutine
12204 && ! flag_emit_class_files
12205 && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
12206 return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
12208 /* This one is more complicated. FLOATs are processed by a
12209 function call to soft_fmod. Duplicate the value of the
12210 COMPOUND_ASSIGN_P flag. */
12211 if (code == TRUNC_MOD_EXPR)
12213 tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
12214 COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
12215 TREE_SIDE_EFFECTS (mod)
12216 = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12217 return mod;
12219 break;
12221 /* 15.17 Additive Operators */
12222 case PLUS_EXPR: /* 15.17.1 String Concatenation Operator + */
12224 /* Operation is valid if either one argument is a string
12225 constant, a String object or a StringBuffer crafted for the
12226 purpose of the a previous usage of the String concatenation
12227 operator */
12229 if (TREE_CODE (op1) == STRING_CST
12230 || TREE_CODE (op2) == STRING_CST
12231 || JSTRING_TYPE_P (op1_type)
12232 || JSTRING_TYPE_P (op2_type)
12233 || IS_CRAFTED_STRING_BUFFER_P (op1)
12234 || IS_CRAFTED_STRING_BUFFER_P (op2))
12235 return build_string_concatenation (op1, op2);
12237 case MINUS_EXPR: /* 15.17.2 Additive Operators (+ and -) for
12238 Numeric Types */
12239 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12241 if (!JPRIMITIVE_TYPE_P (op1_type))
12242 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12243 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12244 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12245 TREE_TYPE (node) = error_mark_node;
12246 error_found = 1;
12247 break;
12249 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12250 break;
12252 /* 15.18 Shift Operators */
12253 case LSHIFT_EXPR:
12254 case RSHIFT_EXPR:
12255 case URSHIFT_EXPR:
12256 if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
12258 if (!JINTEGRAL_TYPE_P (op1_type))
12259 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12260 else
12262 if (JPRIMITIVE_TYPE_P (op2_type))
12263 parse_error_context (wfl_operator,
12264 "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
12265 operator_string (node),
12266 lang_printable_name (op2_type, 0));
12267 else
12268 parse_error_context (wfl_operator,
12269 "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral",
12270 operator_string (node),
12271 lang_printable_name (op2_type, 0));
12273 TREE_TYPE (node) = error_mark_node;
12274 error_found = 1;
12275 break;
12278 /* Unary numeric promotion (5.6.1) is performed on each operand
12279 separatly */
12280 op1 = do_unary_numeric_promotion (op1);
12281 op2 = do_unary_numeric_promotion (op2);
12283 /* The type of the shift expression is the type of the promoted
12284 type of the left-hand operand */
12285 prom_type = TREE_TYPE (op1);
12287 /* Shift int only up to 0x1f and long up to 0x3f */
12288 if (prom_type == int_type_node)
12289 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
12290 build_int_2 (0x1f, 0)));
12291 else
12292 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
12293 build_int_2 (0x3f, 0)));
12295 /* The >>> operator is a >> operating on unsigned quantities */
12296 if (code == URSHIFT_EXPR && ! flag_emit_class_files)
12298 tree to_return;
12299 tree utype = unsigned_type (prom_type);
12300 op1 = convert (utype, op1);
12301 TREE_SET_CODE (node, RSHIFT_EXPR);
12302 TREE_OPERAND (node, 0) = op1;
12303 TREE_OPERAND (node, 1) = op2;
12304 TREE_TYPE (node) = utype;
12305 to_return = convert (prom_type, node);
12306 /* Copy the original value of the COMPOUND_ASSIGN_P flag */
12307 COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
12308 TREE_SIDE_EFFECTS (to_return)
12309 = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12310 return to_return;
12312 break;
12314 /* 15.19.1 Type Comparison Operator instaceof */
12315 case INSTANCEOF_EXPR:
12317 TREE_TYPE (node) = boolean_type_node;
12319 if (!(op2_type = resolve_type_during_patch (op2)))
12320 return error_mark_node;
12322 /* The first operand must be a reference type or the null type */
12323 if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
12324 error_found = 1; /* Error reported further below */
12326 /* The second operand must be a reference type */
12327 if (!JREFERENCE_TYPE_P (op2_type))
12329 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
12330 parse_error_context
12331 (wfl_operator, "Invalid argument `%s' for `instanceof'",
12332 lang_printable_name (op2_type, 0));
12333 error_found = 1;
12336 if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
12338 /* If the first operand is null, the result is always false */
12339 if (op1 == null_pointer_node)
12340 return boolean_false_node;
12341 else if (flag_emit_class_files)
12343 TREE_OPERAND (node, 1) = op2_type;
12344 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
12345 return node;
12347 /* Otherwise we have to invoke instance of to figure it out */
12348 else
12350 tree call =
12351 build (CALL_EXPR, boolean_type_node,
12352 build_address_of (soft_instanceof_node),
12353 tree_cons
12354 (NULL_TREE, op1,
12355 build_tree_list (NULL_TREE,
12356 build_class_ref (op2_type))),
12357 NULL_TREE);
12358 TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
12359 return call;
12362 /* There is no way the expression operand can be an instance of
12363 the type operand. This is a compile time error. */
12364 else
12366 char *t1 = xstrdup (lang_printable_name (op1_type, 0));
12367 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
12368 parse_error_context
12369 (wfl_operator, "Impossible for `%s' to be instance of `%s'",
12370 t1, lang_printable_name (op2_type, 0));
12371 free (t1);
12372 error_found = 1;
12375 break;
12377 /* 15.21 Bitwise and Logical Operators */
12378 case BIT_AND_EXPR:
12379 case BIT_XOR_EXPR:
12380 case BIT_IOR_EXPR:
12381 if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
12382 /* Binary numeric promotion is performed on both operand and the
12383 expression retain that type */
12384 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12386 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE
12387 && TREE_CODE (op1_type) == BOOLEAN_TYPE)
12388 /* The type of the bitwise operator expression is BOOLEAN */
12389 prom_type = boolean_type_node;
12390 else
12392 if (!JINTEGRAL_TYPE_P (op1_type))
12393 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12394 if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
12395 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
12396 TREE_TYPE (node) = error_mark_node;
12397 error_found = 1;
12398 /* Insert a break here if adding thing before the switch's
12399 break for this case */
12401 break;
12403 /* 15.22 Conditional-And Operator */
12404 case TRUTH_ANDIF_EXPR:
12405 /* 15.23 Conditional-Or Operator */
12406 case TRUTH_ORIF_EXPR:
12407 /* Operands must be of BOOLEAN type */
12408 if (TREE_CODE (op1_type) != BOOLEAN_TYPE ||
12409 TREE_CODE (op2_type) != BOOLEAN_TYPE)
12411 if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
12412 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
12413 if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
12414 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
12415 TREE_TYPE (node) = boolean_type_node;
12416 error_found = 1;
12417 break;
12419 /* The type of the conditional operators is BOOLEAN */
12420 prom_type = boolean_type_node;
12421 break;
12423 /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
12424 case LT_EXPR:
12425 case GT_EXPR:
12426 case LE_EXPR:
12427 case GE_EXPR:
12428 /* The type of each of the operands must be a primitive numeric
12429 type */
12430 if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
12432 if (!JNUMERIC_TYPE_P (op1_type))
12433 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12434 if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
12435 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12436 TREE_TYPE (node) = boolean_type_node;
12437 error_found = 1;
12438 break;
12440 /* Binary numeric promotion is performed on the operands */
12441 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12442 /* The type of the relation expression is always BOOLEAN */
12443 prom_type = boolean_type_node;
12444 break;
12446 /* 15.20 Equality Operator */
12447 case EQ_EXPR:
12448 case NE_EXPR:
12449 /* It's time for us to patch the strings. */
12450 if ((cn = patch_string (op1)))
12452 op1 = cn;
12453 op1_type = TREE_TYPE (op1);
12455 if ((cn = patch_string (op2)))
12457 op2 = cn;
12458 op2_type = TREE_TYPE (op2);
12461 /* 15.20.1 Numerical Equality Operators == and != */
12462 /* Binary numeric promotion is performed on the operands */
12463 if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
12464 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12466 /* 15.20.2 Boolean Equality Operators == and != */
12467 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
12468 TREE_CODE (op2_type) == BOOLEAN_TYPE)
12469 ; /* Nothing to do here */
12471 /* 15.20.3 Reference Equality Operators == and != */
12472 /* Types have to be either references or the null type. If
12473 they're references, it must be possible to convert either
12474 type to the other by casting conversion. */
12475 else if (op1 == null_pointer_node || op2 == null_pointer_node
12476 || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
12477 && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
12478 || valid_ref_assignconv_cast_p (op2_type,
12479 op1_type, 1))))
12480 ; /* Nothing to do here */
12482 /* Else we have an error figure what can't be converted into
12483 what and report the error */
12484 else
12486 char *t1;
12487 t1 = xstrdup (lang_printable_name (op1_type, 0));
12488 parse_error_context
12489 (wfl_operator,
12490 "Incompatible type for `%s'. Can't convert `%s' to `%s'",
12491 operator_string (node), t1,
12492 lang_printable_name (op2_type, 0));
12493 free (t1);
12494 TREE_TYPE (node) = boolean_type_node;
12495 error_found = 1;
12496 break;
12498 prom_type = boolean_type_node;
12499 break;
12502 if (error_found)
12503 return error_mark_node;
12505 TREE_OPERAND (node, 0) = op1;
12506 TREE_OPERAND (node, 1) = op2;
12507 TREE_TYPE (node) = prom_type;
12508 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12510 if (flag_emit_xref)
12511 return node;
12513 /* fold does not respect side-effect order as required for Java but not C.
12514 * Also, it sometimes create SAVE_EXPRs which are bad when emitting
12515 * bytecode.
12517 if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
12518 : ! TREE_SIDE_EFFECTS (node))
12519 node = fold (node);
12520 return node;
12523 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
12524 zero value, the value of CSTE comes after the valude of STRING */
12526 static tree
12527 do_merge_string_cste (cste, string, string_len, after)
12528 tree cste;
12529 const char *string;
12530 int string_len, after;
12532 int len = TREE_STRING_LENGTH (cste) + string_len;
12533 const char *old = TREE_STRING_POINTER (cste);
12534 TREE_STRING_LENGTH (cste) = len;
12535 TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
12536 if (after)
12538 strcpy (TREE_STRING_POINTER (cste), string);
12539 strcat (TREE_STRING_POINTER (cste), old);
12541 else
12543 strcpy (TREE_STRING_POINTER (cste), old);
12544 strcat (TREE_STRING_POINTER (cste), string);
12546 return cste;
12549 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
12550 new STRING_CST on success, NULL_TREE on failure */
12552 static tree
12553 merge_string_cste (op1, op2, after)
12554 tree op1, op2;
12555 int after;
12557 /* Handle two string constants right away */
12558 if (TREE_CODE (op2) == STRING_CST)
12559 return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
12560 TREE_STRING_LENGTH (op2), after);
12562 /* Reasonable integer constant can be treated right away */
12563 if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
12565 static const char *boolean_true = "true";
12566 static const char *boolean_false = "false";
12567 static const char *null_pointer = "null";
12568 char ch[3];
12569 const char *string;
12571 if (op2 == boolean_true_node)
12572 string = boolean_true;
12573 else if (op2 == boolean_false_node)
12574 string = boolean_false;
12575 else if (op2 == null_pointer_node)
12576 string = null_pointer;
12577 else if (TREE_TYPE (op2) == char_type_node)
12579 ch[0] = (char )TREE_INT_CST_LOW (op2);
12580 ch[1] = '\0';
12581 string = ch;
12583 else
12584 string = print_int_node (op2);
12586 return do_merge_string_cste (op1, string, strlen (string), after);
12588 return NULL_TREE;
12591 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
12592 has to be a STRING_CST and the other part must be a STRING_CST or a
12593 INTEGRAL constant. Return a new STRING_CST if the operation
12594 succeed, NULL_TREE otherwise.
12596 If the case we want to optimize for space, we might want to return
12597 NULL_TREE for each invocation of this routine. FIXME */
12599 static tree
12600 string_constant_concatenation (op1, op2)
12601 tree op1, op2;
12603 if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
12605 tree string, rest;
12606 int invert;
12608 string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
12609 rest = (string == op1 ? op2 : op1);
12610 invert = (string == op1 ? 0 : 1 );
12612 /* Walk REST, only if it looks reasonable */
12613 if (TREE_CODE (rest) != STRING_CST
12614 && !IS_CRAFTED_STRING_BUFFER_P (rest)
12615 && !JSTRING_TYPE_P (TREE_TYPE (rest))
12616 && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
12618 rest = java_complete_tree (rest);
12619 if (rest == error_mark_node)
12620 return error_mark_node;
12621 rest = fold (rest);
12623 return merge_string_cste (string, rest, invert);
12625 return NULL_TREE;
12628 /* Implement the `+' operator. Does static optimization if possible,
12629 otherwise create (if necessary) and append elements to a
12630 StringBuffer. The StringBuffer will be carried around until it is
12631 used for a function call or an assignment. Then toString() will be
12632 called on it to turn it into a String object. */
12634 static tree
12635 build_string_concatenation (op1, op2)
12636 tree op1, op2;
12638 tree result;
12639 int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12641 if (flag_emit_xref)
12642 return build (PLUS_EXPR, string_type_node, op1, op2);
12644 /* Try to do some static optimization */
12645 if ((result = string_constant_concatenation (op1, op2)))
12646 return result;
12648 /* Discard empty strings on either side of the expression */
12649 if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
12651 op1 = op2;
12652 op2 = NULL_TREE;
12654 else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
12655 op2 = NULL_TREE;
12657 /* If operands are string constant, turn then into object references */
12658 if (TREE_CODE (op1) == STRING_CST)
12659 op1 = patch_string_cst (op1);
12660 if (op2 && TREE_CODE (op2) == STRING_CST)
12661 op2 = patch_string_cst (op2);
12663 /* If either one of the constant is null and the other non null
12664 operand is a String object, return it. */
12665 if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
12666 return op1;
12668 /* If OP1 isn't already a StringBuffer, create and
12669 initialize a new one */
12670 if (!IS_CRAFTED_STRING_BUFFER_P (op1))
12672 /* Two solutions here:
12673 1) OP1 is a constant string reference, we call new StringBuffer(OP1)
12674 2) OP1 is something else, we call new StringBuffer().append(OP1). */
12675 if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
12676 op1 = BUILD_STRING_BUFFER (op1);
12677 else
12679 tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
12680 op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
12684 if (op2)
12686 /* OP1 is no longer the last node holding a crafted StringBuffer */
12687 IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
12688 /* Create a node for `{new...,xxx}.append (op2)' */
12689 if (op2)
12690 op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
12693 /* Mark the last node holding a crafted StringBuffer */
12694 IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
12696 TREE_SIDE_EFFECTS (op1) = side_effects;
12697 return op1;
12700 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
12701 StringBuffer. If no string were found to be patched, return
12702 NULL. */
12704 static tree
12705 patch_string (node)
12706 tree node;
12708 if (node == error_mark_node)
12709 return error_mark_node;
12710 if (TREE_CODE (node) == STRING_CST)
12711 return patch_string_cst (node);
12712 else if (IS_CRAFTED_STRING_BUFFER_P (node))
12714 int saved = ctxp->explicit_constructor_p;
12715 tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
12716 tree ret;
12717 /* Temporary disable forbid the use of `this'. */
12718 ctxp->explicit_constructor_p = 0;
12719 ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
12720 /* String concatenation arguments must be evaluated in order too. */
12721 ret = force_evaluation_order (ret);
12722 /* Restore it at its previous value */
12723 ctxp->explicit_constructor_p = saved;
12724 return ret;
12726 return NULL_TREE;
12729 /* Build the internal representation of a string constant. */
12731 static tree
12732 patch_string_cst (node)
12733 tree node;
12735 int location;
12736 if (! flag_emit_class_files)
12738 push_obstacks (&permanent_obstack, &permanent_obstack);
12739 node = get_identifier (TREE_STRING_POINTER (node));
12740 location = alloc_name_constant (CONSTANT_String, node);
12741 node = build_ref_from_constant_pool (location);
12742 pop_obstacks ();
12744 TREE_TYPE (node) = string_ptr_type_node;
12745 TREE_CONSTANT (node) = 1;
12746 return node;
12749 /* Build an incomplete unary operator expression. */
12751 static tree
12752 build_unaryop (op_token, op_location, op1)
12753 int op_token, op_location;
12754 tree op1;
12756 enum tree_code op;
12757 tree unaryop;
12758 switch (op_token)
12760 case PLUS_TK: op = UNARY_PLUS_EXPR; break;
12761 case MINUS_TK: op = NEGATE_EXPR; break;
12762 case NEG_TK: op = TRUTH_NOT_EXPR; break;
12763 case NOT_TK: op = BIT_NOT_EXPR; break;
12764 default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
12765 op_token);
12768 unaryop = build1 (op, NULL_TREE, op1);
12769 TREE_SIDE_EFFECTS (unaryop) = 1;
12770 /* Store the location of the operator, for better error report. The
12771 string of the operator will be rebuild based on the OP value. */
12772 EXPR_WFL_LINECOL (unaryop) = op_location;
12773 return unaryop;
12776 /* Special case for the ++/-- operators, since they require an extra
12777 argument to build, which is set to NULL and patched
12778 later. IS_POST_P is 1 if the operator, 0 otherwise. */
12780 static tree
12781 build_incdec (op_token, op_location, op1, is_post_p)
12782 int op_token, op_location;
12783 tree op1;
12784 int is_post_p;
12786 static enum tree_code lookup [2][2] =
12788 { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
12789 { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
12791 tree node = build (lookup [is_post_p][(op_token - DECR_TK)],
12792 NULL_TREE, op1, NULL_TREE);
12793 TREE_SIDE_EFFECTS (node) = 1;
12794 /* Store the location of the operator, for better error report. The
12795 string of the operator will be rebuild based on the OP value. */
12796 EXPR_WFL_LINECOL (node) = op_location;
12797 return node;
12800 /* Build an incomplete cast operator, based on the use of the
12801 CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
12802 set. java_complete_tree is trained to walk a CONVERT_EXPR even
12803 though its type is already set. */
12805 static tree
12806 build_cast (location, type, exp)
12807 int location;
12808 tree type, exp;
12810 tree node = build1 (CONVERT_EXPR, type, exp);
12811 EXPR_WFL_LINECOL (node) = location;
12812 return node;
12815 /* Build an incomplete class reference operator. */
12816 static tree
12817 build_incomplete_class_ref (location, class_name)
12818 int location;
12819 tree class_name;
12821 tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
12822 EXPR_WFL_LINECOL (node) = location;
12823 return node;
12826 /* Complete an incomplete class reference operator. */
12827 static tree
12828 patch_incomplete_class_ref (node)
12829 tree node;
12831 tree type = TREE_OPERAND (node, 0);
12832 tree ref_type;
12834 if (!(ref_type = resolve_type_during_patch (type)))
12835 return error_mark_node;
12837 if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
12838 return build_class_ref (ref_type);
12840 /* If we're emitting class files and we have to deal with non
12841 primitive types, we invoke (and consider generating) the
12842 synthetic static method `class$'. */
12843 if (!TYPE_DOT_CLASS (current_class))
12844 build_dot_class_method (current_class);
12845 ref_type =
12846 build_dot_class_method_invocation (DECL_NAME (TYPE_NAME (ref_type)));
12847 return java_complete_tree (ref_type);
12850 /* 15.14 Unary operators. We return error_mark_node in case of error,
12851 but preserve the type of NODE if the type is fixed. */
12853 static tree
12854 patch_unaryop (node, wfl_op)
12855 tree node;
12856 tree wfl_op;
12858 tree op = TREE_OPERAND (node, 0);
12859 tree op_type = TREE_TYPE (op);
12860 tree prom_type = NULL_TREE, value, decl;
12861 int outer_field_flag = 0;
12862 int code = TREE_CODE (node);
12863 int error_found = 0;
12865 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12867 switch (code)
12869 /* 15.13.2 Postfix Increment Operator ++ */
12870 case POSTINCREMENT_EXPR:
12871 /* 15.13.3 Postfix Increment Operator -- */
12872 case POSTDECREMENT_EXPR:
12873 /* 15.14.1 Prefix Increment Operator ++ */
12874 case PREINCREMENT_EXPR:
12875 /* 15.14.2 Prefix Decrement Operator -- */
12876 case PREDECREMENT_EXPR:
12877 op = decl = strip_out_static_field_access_decl (op);
12878 outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
12879 /* We might be trying to change an outer field accessed using
12880 access method. */
12881 if (outer_field_flag)
12883 /* Retrieve the decl of the field we're trying to access. We
12884 do that by first retrieving the function we would call to
12885 access the field. It has been already verified that this
12886 field isn't final */
12887 if (flag_emit_class_files)
12888 decl = TREE_OPERAND (op, 0);
12889 else
12890 decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
12891 decl = DECL_FUNCTION_ACCESS_DECL (decl);
12893 /* We really should have a JAVA_ARRAY_EXPR to avoid this */
12894 else if (!JDECL_P (decl)
12895 && TREE_CODE (decl) != COMPONENT_REF
12896 && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
12897 && TREE_CODE (decl) != INDIRECT_REF
12898 && !(TREE_CODE (decl) == COMPOUND_EXPR
12899 && TREE_OPERAND (decl, 1)
12900 && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
12902 tree lvalue;
12903 /* Before screaming, check that we're not in fact trying to
12904 increment a optimized static final access, in which case
12905 we issue an different error message. */
12906 if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
12907 && resolve_expression_name (wfl_op, &lvalue)
12908 && check_final_assignment (lvalue, wfl_op)))
12909 parse_error_context (wfl_operator, "Invalid argument to `%s'",
12910 operator_string (node));
12911 TREE_TYPE (node) = error_mark_node;
12912 error_found = 1;
12915 if (check_final_assignment (op, wfl_op))
12916 error_found = 1;
12918 /* From now on, we know that op if a variable and that it has a
12919 valid wfl. We use wfl_op to locate errors related to the
12920 ++/-- operand. */
12921 else if (!JNUMERIC_TYPE_P (op_type))
12923 parse_error_context
12924 (wfl_op, "Invalid argument type `%s' to `%s'",
12925 lang_printable_name (op_type, 0), operator_string (node));
12926 TREE_TYPE (node) = error_mark_node;
12927 error_found = 1;
12929 else
12931 /* Before the addition, binary numeric promotion is performed on
12932 both operands, if really necessary */
12933 if (JINTEGRAL_TYPE_P (op_type))
12935 value = build_int_2 (1, 0);
12936 TREE_TYPE (value) = TREE_TYPE (node) = op_type;
12938 else
12940 value = build_int_2 (1, 0);
12941 TREE_TYPE (node) =
12942 binary_numeric_promotion (op_type,
12943 TREE_TYPE (value), &op, &value);
12946 /* We remember we might be accessing an outer field */
12947 if (outer_field_flag)
12949 /* We re-generate an access to the field */
12950 value = build (PLUS_EXPR, TREE_TYPE (op),
12951 build_outer_field_access (wfl_op, decl), value);
12953 /* And we patch the original access$() into a write
12954 with plus_op as a rhs */
12955 return outer_field_access_fix (node, op, value);
12958 /* And write back into the node. */
12959 TREE_OPERAND (node, 0) = op;
12960 TREE_OPERAND (node, 1) = value;
12961 /* Convert the overall back into its original type, if
12962 necessary, and return */
12963 if (JINTEGRAL_TYPE_P (op_type))
12964 return fold (node);
12965 else
12966 return fold (convert (op_type, node));
12968 break;
12970 /* 15.14.3 Unary Plus Operator + */
12971 case UNARY_PLUS_EXPR:
12972 /* 15.14.4 Unary Minus Operator - */
12973 case NEGATE_EXPR:
12974 if (!JNUMERIC_TYPE_P (op_type))
12976 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
12977 TREE_TYPE (node) = error_mark_node;
12978 error_found = 1;
12980 /* Unary numeric promotion is performed on operand */
12981 else
12983 op = do_unary_numeric_promotion (op);
12984 prom_type = TREE_TYPE (op);
12985 if (code == UNARY_PLUS_EXPR)
12986 return fold (op);
12988 break;
12990 /* 15.14.5 Bitwise Complement Operator ~ */
12991 case BIT_NOT_EXPR:
12992 if (!JINTEGRAL_TYPE_P (op_type))
12994 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
12995 TREE_TYPE (node) = error_mark_node;
12996 error_found = 1;
12998 else
13000 op = do_unary_numeric_promotion (op);
13001 prom_type = TREE_TYPE (op);
13003 break;
13005 /* 15.14.6 Logical Complement Operator ! */
13006 case TRUTH_NOT_EXPR:
13007 if (TREE_CODE (op_type) != BOOLEAN_TYPE)
13009 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
13010 /* But the type is known. We will report an error if further
13011 attempt of a assignment is made with this rhs */
13012 TREE_TYPE (node) = boolean_type_node;
13013 error_found = 1;
13015 else
13016 prom_type = boolean_type_node;
13017 break;
13019 /* 15.15 Cast Expression */
13020 case CONVERT_EXPR:
13021 value = patch_cast (node, wfl_operator);
13022 if (value == error_mark_node)
13024 /* If this cast is part of an assignment, we tell the code
13025 that deals with it not to complain about a mismatch,
13026 because things have been cast, anyways */
13027 TREE_TYPE (node) = error_mark_node;
13028 error_found = 1;
13030 else
13032 value = fold (value);
13033 TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
13034 return value;
13036 break;
13039 if (error_found)
13040 return error_mark_node;
13042 /* There are cases where node has been replaced by something else
13043 and we don't end up returning here: UNARY_PLUS_EXPR,
13044 CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
13045 TREE_OPERAND (node, 0) = fold (op);
13046 TREE_TYPE (node) = prom_type;
13047 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
13048 return fold (node);
13051 /* Generic type resolution that sometimes takes place during node
13052 patching. Returned the resolved type or generate an error
13053 message. Return the resolved type or NULL_TREE. */
13055 static tree
13056 resolve_type_during_patch (type)
13057 tree type;
13059 if (unresolved_type_p (type, NULL))
13061 tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
13062 if (!type_decl)
13064 parse_error_context (type,
13065 "Class `%s' not found in type declaration",
13066 IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
13067 return NULL_TREE;
13069 else
13071 CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
13072 return TREE_TYPE (type_decl);
13075 return type;
13077 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
13078 found. Otherwise NODE or something meant to replace it is returned. */
13080 static tree
13081 patch_cast (node, wfl_operator)
13082 tree node;
13083 tree wfl_operator;
13085 tree op = TREE_OPERAND (node, 0);
13086 tree op_type = TREE_TYPE (op);
13087 tree cast_type = TREE_TYPE (node);
13088 char *t1;
13090 /* First resolve OP_TYPE if unresolved */
13091 if (!(cast_type = resolve_type_during_patch (cast_type)))
13092 return error_mark_node;
13094 /* Check on cast that are proven correct at compile time */
13095 if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
13097 /* Same type */
13098 if (cast_type == op_type)
13099 return node;
13101 /* float and double type are converted to the original type main
13102 variant and then to the target type. */
13103 if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
13104 op = convert (integer_type_node, op);
13106 /* Try widening/narowwing convertion. Potentially, things need
13107 to be worked out in gcc so we implement the extreme cases
13108 correctly. fold_convert() needs to be fixed. */
13109 return convert (cast_type, op);
13112 /* It's also valid to cast a boolean into a boolean */
13113 if (op_type == boolean_type_node && cast_type == boolean_type_node)
13114 return node;
13116 /* null can be casted to references */
13117 if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
13118 return build_null_of_type (cast_type);
13120 /* The remaining legal casts involve conversion between reference
13121 types. Check for their compile time correctness. */
13122 if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type)
13123 && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
13125 TREE_TYPE (node) = promote_type (cast_type);
13126 /* Now, the case can be determined correct at compile time if
13127 OP_TYPE can be converted into CAST_TYPE by assignment
13128 conversion (5.2) */
13130 if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
13132 TREE_SET_CODE (node, NOP_EXPR);
13133 return node;
13136 if (flag_emit_class_files)
13138 TREE_SET_CODE (node, CONVERT_EXPR);
13139 return node;
13142 /* The cast requires a run-time check */
13143 return build (CALL_EXPR, promote_type (cast_type),
13144 build_address_of (soft_checkcast_node),
13145 tree_cons (NULL_TREE, build_class_ref (cast_type),
13146 build_tree_list (NULL_TREE, op)),
13147 NULL_TREE);
13150 /* Any other casts are proven incorrect at compile time */
13151 t1 = xstrdup (lang_printable_name (op_type, 0));
13152 parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
13153 t1, lang_printable_name (cast_type, 0));
13154 free (t1);
13155 return error_mark_node;
13158 /* Build a null constant and give it the type TYPE. */
13160 static tree
13161 build_null_of_type (type)
13162 tree type;
13164 tree node = build_int_2 (0, 0);
13165 TREE_TYPE (node) = promote_type (type);
13166 return node;
13169 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
13170 a list of indices. */
13171 static tree
13172 build_array_ref (location, array, index)
13173 int location;
13174 tree array, index;
13176 tree node = build (ARRAY_REF, NULL_TREE, array, index);
13177 EXPR_WFL_LINECOL (node) = location;
13178 return node;
13181 /* 15.12 Array Access Expression */
13183 static tree
13184 patch_array_ref (node)
13185 tree node;
13187 tree array = TREE_OPERAND (node, 0);
13188 tree array_type = TREE_TYPE (array);
13189 tree index = TREE_OPERAND (node, 1);
13190 tree index_type = TREE_TYPE (index);
13191 int error_found = 0;
13193 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13195 if (TREE_CODE (array_type) == POINTER_TYPE)
13196 array_type = TREE_TYPE (array_type);
13198 /* The array reference must be an array */
13199 if (!TYPE_ARRAY_P (array_type))
13201 parse_error_context
13202 (wfl_operator,
13203 "`[]' can only be applied to arrays. It can't be applied to `%s'",
13204 lang_printable_name (array_type, 0));
13205 TREE_TYPE (node) = error_mark_node;
13206 error_found = 1;
13209 /* The array index undergoes unary numeric promotion. The promoted
13210 type must be int */
13211 index = do_unary_numeric_promotion (index);
13212 if (TREE_TYPE (index) != int_type_node)
13214 if (valid_cast_to_p (index_type, int_type_node))
13215 parse_error_context (wfl_operator,
13216 "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
13217 lang_printable_name (index_type, 0));
13218 else
13219 parse_error_context (wfl_operator,
13220 "Incompatible type for `[]'. Can't convert `%s' to `int'",
13221 lang_printable_name (index_type, 0));
13222 TREE_TYPE (node) = error_mark_node;
13223 error_found = 1;
13226 if (error_found)
13227 return error_mark_node;
13229 array_type = TYPE_ARRAY_ELEMENT (array_type);
13231 if (flag_emit_class_files || flag_emit_xref)
13233 TREE_OPERAND (node, 0) = array;
13234 TREE_OPERAND (node, 1) = index;
13236 else
13238 /* The save_expr is for correct evaluation order. It would be cleaner
13239 to use force_evaluation_order (see comment there), but that is
13240 difficult when we also have to deal with bounds checking. */
13241 if (TREE_SIDE_EFFECTS (index))
13242 array = save_expr (array);
13243 node = build_java_arrayaccess (array, array_type, index);
13244 if (TREE_SIDE_EFFECTS (index))
13245 node = build (COMPOUND_EXPR, array_type, array, node);
13247 TREE_TYPE (node) = array_type;
13248 return node;
13251 /* 15.9 Array Creation Expressions */
13253 static tree
13254 build_newarray_node (type, dims, extra_dims)
13255 tree type;
13256 tree dims;
13257 int extra_dims;
13259 tree node =
13260 build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims),
13261 build_int_2 (extra_dims, 0));
13262 return node;
13265 static tree
13266 patch_newarray (node)
13267 tree node;
13269 tree type = TREE_OPERAND (node, 0);
13270 tree dims = TREE_OPERAND (node, 1);
13271 tree cdim, array_type;
13272 int error_found = 0;
13273 int ndims = 0;
13274 int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
13276 /* Dimension types are verified. It's better for the types to be
13277 verified in order. */
13278 for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
13280 int dim_error = 0;
13281 tree dim = TREE_VALUE (cdim);
13283 /* Dim might have been saved during its evaluation */
13284 dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
13286 /* The type of each specified dimension must be an integral type. */
13287 if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
13288 dim_error = 1;
13290 /* Each expression undergoes an unary numeric promotion (5.6.1) and the
13291 promoted type must be int. */
13292 else
13294 dim = do_unary_numeric_promotion (dim);
13295 if (TREE_TYPE (dim) != int_type_node)
13296 dim_error = 1;
13299 /* Report errors on types here */
13300 if (dim_error)
13302 parse_error_context
13303 (TREE_PURPOSE (cdim),
13304 "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'",
13305 (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
13306 "Explicit cast needed to" : "Can't"),
13307 lang_printable_name (TREE_TYPE (dim), 0));
13308 error_found = 1;
13311 TREE_PURPOSE (cdim) = NULL_TREE;
13314 /* Resolve array base type if unresolved */
13315 if (!(type = resolve_type_during_patch (type)))
13316 error_found = 1;
13318 if (error_found)
13320 /* We don't want further evaluation of this bogus array creation
13321 operation */
13322 TREE_TYPE (node) = error_mark_node;
13323 return error_mark_node;
13326 /* Set array_type to the actual (promoted) array type of the result. */
13327 if (TREE_CODE (type) == RECORD_TYPE)
13328 type = build_pointer_type (type);
13329 while (--xdims >= 0)
13331 type = promote_type (build_java_array_type (type, -1));
13333 dims = nreverse (dims);
13334 array_type = type;
13335 for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
13337 type = array_type;
13338 array_type
13339 = build_java_array_type (type,
13340 TREE_CODE (cdim) == INTEGER_CST
13341 ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
13342 : -1);
13343 array_type = promote_type (array_type);
13345 dims = nreverse (dims);
13347 /* The node is transformed into a function call. Things are done
13348 differently according to the number of dimensions. If the number
13349 of dimension is equal to 1, then the nature of the base type
13350 (primitive or not) matters. */
13351 if (ndims == 1)
13352 return build_new_array (type, TREE_VALUE (dims));
13354 /* Can't reuse what's already written in expr.c because it uses the
13355 JVM stack representation. Provide a build_multianewarray. FIXME */
13356 return build (CALL_EXPR, array_type,
13357 build_address_of (soft_multianewarray_node),
13358 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
13359 tree_cons (NULL_TREE,
13360 build_int_2 (ndims, 0), dims )),
13361 NULL_TREE);
13364 /* 10.6 Array initializer. */
13366 /* Build a wfl for array element that don't have one, so we can
13367 pin-point errors. */
13369 static tree
13370 maybe_build_array_element_wfl (node)
13371 tree node;
13373 if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
13374 return build_expr_wfl (NULL_TREE, ctxp->filename,
13375 ctxp->elc.line, ctxp->elc.prev_col);
13376 else
13377 return NULL_TREE;
13380 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
13381 identification of initialized arrays easier to detect during walk
13382 and expansion. */
13384 static tree
13385 build_new_array_init (location, values)
13386 int location;
13387 tree values;
13389 tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
13390 tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
13391 EXPR_WFL_LINECOL (to_return) = location;
13392 return to_return;
13395 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
13396 occurred. Otherwise return NODE after having set its type
13397 appropriately. */
13399 static tree
13400 patch_new_array_init (type, node)
13401 tree type, node;
13403 int error_seen = 0;
13404 tree current, element_type;
13405 HOST_WIDE_INT length;
13406 int all_constant = 1;
13407 tree init = TREE_OPERAND (node, 0);
13409 if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
13411 parse_error_context (node,
13412 "Invalid array initializer for non-array type `%s'",
13413 lang_printable_name (type, 1));
13414 return error_mark_node;
13416 type = TREE_TYPE (type);
13417 element_type = TYPE_ARRAY_ELEMENT (type);
13419 CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
13421 for (length = 0, current = CONSTRUCTOR_ELTS (init);
13422 current; length++, current = TREE_CHAIN (current))
13424 tree elt = TREE_VALUE (current);
13425 if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
13427 error_seen |= array_constructor_check_entry (element_type, current);
13428 elt = TREE_VALUE (current);
13429 /* When compiling to native code, STRING_CST is converted to
13430 INDIRECT_REF, but still with a TREE_CONSTANT flag. */
13431 if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
13432 all_constant = 0;
13434 else
13436 TREE_VALUE (current) = patch_new_array_init (element_type, elt);
13437 TREE_PURPOSE (current) = NULL_TREE;
13438 all_constant = 0;
13440 if (elt && TREE_VALUE (elt) == error_mark_node)
13441 error_seen = 1;
13444 if (error_seen)
13445 return error_mark_node;
13447 /* Create a new type. We can't reuse the one we have here by
13448 patching its dimension because it originally is of dimension -1
13449 hence reused by gcc. This would prevent triangular arrays. */
13450 type = build_java_array_type (element_type, length);
13451 TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
13452 TREE_TYPE (node) = promote_type (type);
13453 TREE_CONSTANT (init) = all_constant;
13454 TREE_CONSTANT (node) = all_constant;
13455 return node;
13458 /* Verify that one entry of the initializer element list can be
13459 assigned to the array base type. Report 1 if an error occurred, 0
13460 otherwise. */
13462 static int
13463 array_constructor_check_entry (type, entry)
13464 tree type, entry;
13466 char *array_type_string = NULL; /* For error reports */
13467 tree value, type_value, new_value, wfl_value, patched;
13468 int error_seen = 0;
13470 new_value = NULL_TREE;
13471 wfl_value = TREE_VALUE (entry);
13473 push_obstacks (&permanent_obstack, &permanent_obstack);
13474 value = java_complete_tree (TREE_VALUE (entry));
13475 /* patch_string return error_mark_node if arg is error_mark_node */
13476 if ((patched = patch_string (value)))
13477 value = patched;
13478 if (value == error_mark_node)
13479 return 1;
13481 type_value = TREE_TYPE (value);
13483 /* At anytime, try_builtin_assignconv can report a warning on
13484 constant overflow during narrowing. */
13485 SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
13486 new_value = try_builtin_assignconv (wfl_operator, type, value);
13487 if (!new_value && (new_value = try_reference_assignconv (type, value)))
13488 type_value = promote_type (type);
13490 pop_obstacks ();
13491 /* Check and report errors */
13492 if (!new_value)
13494 const char *msg = (!valid_cast_to_p (type_value, type) ?
13495 "Can't" : "Explicit cast needed to");
13496 if (!array_type_string)
13497 array_type_string = xstrdup (lang_printable_name (type, 1));
13498 parse_error_context
13499 (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
13500 msg, lang_printable_name (type_value, 1), array_type_string);
13501 error_seen = 1;
13504 if (new_value)
13506 new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
13507 TREE_VALUE (entry) = new_value;
13510 if (array_type_string)
13511 free (array_type_string);
13513 TREE_PURPOSE (entry) = NULL_TREE;
13514 return error_seen;
13517 static tree
13518 build_this (location)
13519 int location;
13521 tree node = build_wfl_node (this_identifier_node);
13522 TREE_SET_CODE (node, THIS_EXPR);
13523 EXPR_WFL_LINECOL (node) = location;
13524 return node;
13527 /* 14.15 The return statement. It builds a modify expression that
13528 assigns the returned value to the RESULT_DECL that hold the value
13529 to be returned. */
13531 static tree
13532 build_return (location, op)
13533 int location;
13534 tree op;
13536 tree node = build1 (RETURN_EXPR, NULL_TREE, op);
13537 EXPR_WFL_LINECOL (node) = location;
13538 node = build_debugable_stmt (location, node);
13539 return node;
13542 static tree
13543 patch_return (node)
13544 tree node;
13546 tree return_exp = TREE_OPERAND (node, 0);
13547 tree meth = current_function_decl;
13548 tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
13549 int error_found = 0;
13551 TREE_TYPE (node) = error_mark_node;
13552 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13554 /* It's invalid to have a return value within a function that is
13555 declared with the keyword void or that is a constructor */
13556 if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
13557 error_found = 1;
13559 /* It's invalid to use a return statement in a static block */
13560 if (DECL_CLINIT_P (current_function_decl))
13561 error_found = 1;
13563 /* It's invalid to have a no return value within a function that
13564 isn't declared with the keyword `void' */
13565 if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
13566 error_found = 2;
13568 if (in_instance_initializer)
13569 error_found = 1;
13571 if (error_found)
13573 if (in_instance_initializer)
13574 parse_error_context (wfl_operator,
13575 "`return' inside instance initializer");
13577 else if (DECL_CLINIT_P (current_function_decl))
13578 parse_error_context (wfl_operator,
13579 "`return' inside static initializer");
13581 else if (!DECL_CONSTRUCTOR_P (meth))
13583 char *t = xstrdup (lang_printable_name (mtype, 0));
13584 parse_error_context (wfl_operator,
13585 "`return' with%s value from `%s %s'",
13586 (error_found == 1 ? "" : "out"),
13587 t, lang_printable_name (meth, 0));
13588 free (t);
13590 else
13591 parse_error_context (wfl_operator,
13592 "`return' with value from constructor `%s'",
13593 lang_printable_name (meth, 0));
13594 return error_mark_node;
13597 /* If we have a return_exp, build a modify expression and expand
13598 it. Note: at that point, the assignment is declared valid, but we
13599 may want to carry some more hacks */
13600 if (return_exp)
13602 tree exp = java_complete_tree (return_exp);
13603 tree modify, patched;
13605 /* If the function returned value and EXP are booleans, EXP has
13606 to be converted into the type of DECL_RESULT, which is integer
13607 (see complete_start_java_method) */
13608 if (TREE_TYPE (exp) == boolean_type_node &&
13609 TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
13610 exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
13612 /* `null' can be assigned to a function returning a reference */
13613 if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
13614 exp == null_pointer_node)
13615 exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
13617 if ((patched = patch_string (exp)))
13618 exp = patched;
13620 modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
13621 EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
13622 modify = java_complete_tree (modify);
13624 if (modify != error_mark_node)
13626 TREE_SIDE_EFFECTS (modify) = 1;
13627 TREE_OPERAND (node, 0) = modify;
13629 else
13630 return error_mark_node;
13632 TREE_TYPE (node) = void_type_node;
13633 TREE_SIDE_EFFECTS (node) = 1;
13634 return node;
13637 /* 14.8 The if Statement */
13639 static tree
13640 build_if_else_statement (location, expression, if_body, else_body)
13641 int location;
13642 tree expression, if_body, else_body;
13644 tree node;
13645 if (!else_body)
13646 else_body = empty_stmt_node;
13647 node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
13648 EXPR_WFL_LINECOL (node) = location;
13649 node = build_debugable_stmt (location, node);
13650 return node;
13653 static tree
13654 patch_if_else_statement (node)
13655 tree node;
13657 tree expression = TREE_OPERAND (node, 0);
13659 TREE_TYPE (node) = error_mark_node;
13660 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13662 /* The type of expression must be boolean */
13663 if (TREE_TYPE (expression) != boolean_type_node
13664 && TREE_TYPE (expression) != promoted_boolean_type_node)
13666 parse_error_context
13667 (wfl_operator,
13668 "Incompatible type for `if'. Can't convert `%s' to `boolean'",
13669 lang_printable_name (TREE_TYPE (expression), 0));
13670 return error_mark_node;
13673 TREE_TYPE (node) = void_type_node;
13674 TREE_SIDE_EFFECTS (node) = 1;
13675 CAN_COMPLETE_NORMALLY (node)
13676 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
13677 | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
13678 return node;
13681 /* 14.6 Labeled Statements */
13683 /* Action taken when a lableled statement is parsed. a new
13684 LABELED_BLOCK_EXPR is created. No statement is attached to the
13685 label, yet. LABEL can be NULL_TREE for artificially-generated blocks. */
13687 static tree
13688 build_labeled_block (location, label)
13689 int location;
13690 tree label;
13692 tree label_name ;
13693 tree label_decl, node;
13694 if (label == NULL_TREE || label == continue_identifier_node)
13695 label_name = label;
13696 else
13698 label_name = merge_qualified_name (label_id, label);
13699 /* Issue an error if we try to reuse a label that was previously
13700 declared */
13701 if (IDENTIFIER_LOCAL_VALUE (label_name))
13703 EXPR_WFL_LINECOL (wfl_operator) = location;
13704 parse_error_context (wfl_operator,
13705 "Declaration of `%s' shadows a previous label declaration",
13706 IDENTIFIER_POINTER (label));
13707 EXPR_WFL_LINECOL (wfl_operator) =
13708 EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
13709 parse_error_context (wfl_operator,
13710 "This is the location of the previous declaration of label `%s'",
13711 IDENTIFIER_POINTER (label));
13712 java_error_count--;
13716 label_decl = create_label_decl (label_name);
13717 node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
13718 EXPR_WFL_LINECOL (node) = location;
13719 TREE_SIDE_EFFECTS (node) = 1;
13720 return node;
13723 /* A labeled statement LBE is attached a statement. */
13725 static tree
13726 finish_labeled_statement (lbe, statement)
13727 tree lbe; /* Labeled block expr */
13728 tree statement;
13730 /* In anyways, tie the loop to its statement */
13731 LABELED_BLOCK_BODY (lbe) = statement;
13732 pop_labeled_block ();
13733 POP_LABELED_BLOCK ();
13734 return lbe;
13737 /* 14.10, 14.11, 14.12 Loop Statements */
13739 /* Create an empty LOOP_EXPR and make it the last in the nested loop
13740 list. */
13742 static tree
13743 build_new_loop (loop_body)
13744 tree loop_body;
13746 tree loop = build (LOOP_EXPR, NULL_TREE, loop_body);
13747 TREE_SIDE_EFFECTS (loop) = 1;
13748 PUSH_LOOP (loop);
13749 return loop;
13752 /* Create a loop body according to the following structure:
13753 COMPOUND_EXPR
13754 COMPOUND_EXPR (loop main body)
13755 EXIT_EXPR (this order is for while/for loops.
13756 LABELED_BLOCK_EXPR the order is reversed for do loops)
13757 LABEL_DECL (a continue occuring here branches at the
13758 BODY end of this labeled block)
13759 INCREMENT (if any)
13761 REVERSED, if non zero, tells that the loop condition expr comes
13762 after the body, like in the do-while loop.
13764 To obtain a loop, the loop body structure described above is
13765 encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
13767 LABELED_BLOCK_EXPR
13768 LABEL_DECL (use this label to exit the loop)
13769 LOOP_EXPR
13770 <structure described above> */
13772 static tree
13773 build_loop_body (location, condition, reversed)
13774 int location;
13775 tree condition;
13776 int reversed;
13778 tree first, second, body;
13780 condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
13781 EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
13782 condition = build_debugable_stmt (location, condition);
13783 TREE_SIDE_EFFECTS (condition) = 1;
13785 body = build_labeled_block (0, continue_identifier_node);
13786 first = (reversed ? body : condition);
13787 second = (reversed ? condition : body);
13788 return
13789 build (COMPOUND_EXPR, NULL_TREE,
13790 build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
13793 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
13794 their order) on the current loop. Unlink the current loop from the
13795 loop list. */
13797 static tree
13798 finish_loop_body (location, condition, body, reversed)
13799 int location;
13800 tree condition, body;
13801 int reversed;
13803 tree to_return = ctxp->current_loop;
13804 tree loop_body = LOOP_EXPR_BODY (to_return);
13805 if (condition)
13807 tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
13808 /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
13809 The real EXIT_EXPR is one operand further. */
13810 EXPR_WFL_LINECOL (cnode) = location;
13811 /* This one is for accurate error reports */
13812 EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
13813 TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
13815 LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
13816 POP_LOOP ();
13817 return to_return;
13820 /* Tailored version of finish_loop_body for FOR loops, when FOR
13821 loops feature the condition part */
13823 static tree
13824 finish_for_loop (location, condition, update, body)
13825 int location;
13826 tree condition, update, body;
13828 /* Put the condition and the loop body in place */
13829 tree loop = finish_loop_body (location, condition, body, 0);
13830 /* LOOP is the current loop which has been now popped of the loop
13831 stack. Install the update block */
13832 LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
13833 return loop;
13836 /* Try to find the loop a block might be related to. This comprises
13837 the case where the LOOP_EXPR is found as the second operand of a
13838 COMPOUND_EXPR, because the loop happens to have an initialization
13839 part, then expressed as the first operand of the COMPOUND_EXPR. If
13840 the search finds something, 1 is returned. Otherwise, 0 is
13841 returned. The search is assumed to start from a
13842 LABELED_BLOCK_EXPR's block. */
13844 static tree
13845 search_loop (statement)
13846 tree statement;
13848 if (TREE_CODE (statement) == LOOP_EXPR)
13849 return statement;
13851 if (TREE_CODE (statement) == BLOCK)
13852 statement = BLOCK_SUBBLOCKS (statement);
13853 else
13854 return NULL_TREE;
13856 if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
13857 while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
13858 statement = TREE_OPERAND (statement, 1);
13860 return (TREE_CODE (statement) == LOOP_EXPR
13861 && FOR_LOOP_P (statement) ? statement : NULL_TREE);
13864 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
13865 returned otherwise. */
13867 static int
13868 labeled_block_contains_loop_p (block, loop)
13869 tree block, loop;
13871 if (!block)
13872 return 0;
13874 if (LABELED_BLOCK_BODY (block) == loop)
13875 return 1;
13877 if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
13878 return 1;
13880 return 0;
13883 /* If the loop isn't surrounded by a labeled statement, create one and
13884 insert LOOP as its body. */
13886 static tree
13887 patch_loop_statement (loop)
13888 tree loop;
13890 tree loop_label;
13892 TREE_TYPE (loop) = void_type_node;
13893 if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
13894 return loop;
13896 loop_label = build_labeled_block (0, NULL_TREE);
13897 /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
13898 that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
13899 LABELED_BLOCK_BODY (loop_label) = loop;
13900 PUSH_LABELED_BLOCK (loop_label);
13901 return loop_label;
13904 /* 14.13, 14.14: break and continue Statements */
13906 /* Build a break or a continue statement. a null NAME indicates an
13907 unlabeled break/continue statement. */
13909 static tree
13910 build_bc_statement (location, is_break, name)
13911 int location, is_break;
13912 tree name;
13914 tree break_continue, label_block_expr = NULL_TREE;
13916 if (name)
13918 if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE
13919 (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
13920 /* Null means that we don't have a target for this named
13921 break/continue. In this case, we make the target to be the
13922 label name, so that the error can be reported accuratly in
13923 patch_bc_statement. */
13924 label_block_expr = EXPR_WFL_NODE (name);
13926 /* Unlabeled break/continue will be handled during the
13927 break/continue patch operation */
13928 break_continue
13929 = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
13931 IS_BREAK_STMT_P (break_continue) = is_break;
13932 TREE_SIDE_EFFECTS (break_continue) = 1;
13933 EXPR_WFL_LINECOL (break_continue) = location;
13934 break_continue = build_debugable_stmt (location, break_continue);
13935 return break_continue;
13938 /* Verification of a break/continue statement. */
13940 static tree
13941 patch_bc_statement (node)
13942 tree node;
13944 tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
13945 tree labeled_block = ctxp->current_labeled_block;
13946 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13948 /* Having an identifier here means that the target is unknown. */
13949 if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
13951 parse_error_context (wfl_operator, "No label definition found for `%s'",
13952 IDENTIFIER_POINTER (bc_label));
13953 return error_mark_node;
13955 if (! IS_BREAK_STMT_P (node))
13957 /* It's a continue statement. */
13958 for (;; labeled_block = TREE_CHAIN (labeled_block))
13960 if (labeled_block == NULL_TREE)
13962 if (bc_label == NULL_TREE)
13963 parse_error_context (wfl_operator,
13964 "`continue' must be in loop");
13965 else
13966 parse_error_context
13967 (wfl_operator, "continue label `%s' does not name a loop",
13968 IDENTIFIER_POINTER (bc_label));
13969 return error_mark_node;
13971 if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
13972 == continue_identifier_node)
13973 && (bc_label == NULL_TREE
13974 || TREE_CHAIN (labeled_block) == bc_label))
13976 bc_label = labeled_block;
13977 break;
13981 else if (!bc_label)
13983 for (;; labeled_block = TREE_CHAIN (labeled_block))
13985 if (labeled_block == NULL_TREE)
13987 parse_error_context (wfl_operator,
13988 "`break' must be in loop or switch");
13989 return error_mark_node;
13991 target_stmt = LABELED_BLOCK_BODY (labeled_block);
13992 if (TREE_CODE (target_stmt) == SWITCH_EXPR
13993 || search_loop (target_stmt))
13995 bc_label = labeled_block;
13996 break;
14001 EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
14002 CAN_COMPLETE_NORMALLY (bc_label) = 1;
14004 /* Our break/continue don't return values. */
14005 TREE_TYPE (node) = void_type_node;
14006 /* Encapsulate the break within a compound statement so that it's
14007 expanded all the times by expand_expr (and not clobbered
14008 sometimes, like after a if statement) */
14009 node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
14010 TREE_SIDE_EFFECTS (node) = 1;
14011 return node;
14014 /* Process the exit expression belonging to a loop. Its type must be
14015 boolean. */
14017 static tree
14018 patch_exit_expr (node)
14019 tree node;
14021 tree expression = TREE_OPERAND (node, 0);
14022 TREE_TYPE (node) = error_mark_node;
14023 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14025 /* The type of expression must be boolean */
14026 if (TREE_TYPE (expression) != boolean_type_node)
14028 parse_error_context
14029 (wfl_operator,
14030 "Incompatible type for loop conditional. Can't convert `%s' to `boolean'",
14031 lang_printable_name (TREE_TYPE (expression), 0));
14032 return error_mark_node;
14034 /* Now we know things are allright, invert the condition, fold and
14035 return */
14036 TREE_OPERAND (node, 0) =
14037 fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
14039 if (! integer_zerop (TREE_OPERAND (node, 0))
14040 && ctxp->current_loop != NULL_TREE
14041 && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
14042 CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
14043 if (! integer_onep (TREE_OPERAND (node, 0)))
14044 CAN_COMPLETE_NORMALLY (node) = 1;
14047 TREE_TYPE (node) = void_type_node;
14048 return node;
14051 /* 14.9 Switch statement */
14053 static tree
14054 patch_switch_statement (node)
14055 tree node;
14057 tree se = TREE_OPERAND (node, 0), se_type;
14059 /* Complete the switch expression */
14060 se = TREE_OPERAND (node, 0) = java_complete_tree (se);
14061 se_type = TREE_TYPE (se);
14062 /* The type of the switch expression must be char, byte, short or
14063 int */
14064 if (!JINTEGRAL_TYPE_P (se_type))
14066 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14067 parse_error_context (wfl_operator,
14068 "Incompatible type for `switch'. Can't convert `%s' to `int'",
14069 lang_printable_name (se_type, 0));
14070 /* This is what java_complete_tree will check */
14071 TREE_OPERAND (node, 0) = error_mark_node;
14072 return error_mark_node;
14075 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
14077 /* Ready to return */
14078 if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
14080 TREE_TYPE (node) = error_mark_node;
14081 return error_mark_node;
14083 TREE_TYPE (node) = void_type_node;
14084 TREE_SIDE_EFFECTS (node) = 1;
14085 CAN_COMPLETE_NORMALLY (node)
14086 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
14087 || ! SWITCH_HAS_DEFAULT (node);
14088 return node;
14091 /* 14.18 The try/catch statements */
14093 static tree
14094 build_try_statement (location, try_block, catches)
14095 int location;
14096 tree try_block, catches;
14098 tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
14099 EXPR_WFL_LINECOL (node) = location;
14100 return node;
14103 static tree
14104 build_try_finally_statement (location, try_block, finally)
14105 int location;
14106 tree try_block, finally;
14108 tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
14109 EXPR_WFL_LINECOL (node) = location;
14110 return node;
14113 static tree
14114 patch_try_statement (node)
14115 tree node;
14117 int error_found = 0;
14118 tree try = TREE_OPERAND (node, 0);
14119 /* Exception handlers are considered in left to right order */
14120 tree catch = nreverse (TREE_OPERAND (node, 1));
14121 tree current, caught_type_list = NULL_TREE;
14123 /* Check catch clauses, if any. Every time we find an error, we try
14124 to process the next catch clause. We process the catch clause before
14125 the try block so that when processing the try block we can check thrown
14126 exceptions againts the caught type list. */
14127 for (current = catch; current; current = TREE_CHAIN (current))
14129 tree carg_decl, carg_type;
14130 tree sub_current, catch_block, catch_clause;
14131 int unreachable;
14133 /* At this point, the structure of the catch clause is
14134 CATCH_EXPR (catch node)
14135 BLOCK (with the decl of the parameter)
14136 COMPOUND_EXPR
14137 MODIFY_EXPR (assignment of the catch parameter)
14138 BLOCK (catch clause block)
14140 catch_clause = TREE_OPERAND (current, 0);
14141 carg_decl = BLOCK_EXPR_DECLS (catch_clause);
14142 carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
14144 /* Catch clauses can't have more than one parameter declared,
14145 but it's already enforced by the grammar. Make sure that the
14146 only parameter of the clause statement in of class Throwable
14147 or a subclass of Throwable, but that was done earlier. The
14148 catch clause parameter type has also been resolved. */
14150 /* Just make sure that the catch clause parameter type inherits
14151 from java.lang.Throwable */
14152 if (!inherits_from_p (carg_type, throwable_type_node))
14154 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14155 parse_error_context (wfl_operator,
14156 "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
14157 lang_printable_name (carg_type, 0));
14158 error_found = 1;
14159 continue;
14162 /* Partial check for unreachable catch statement: The catch
14163 clause is reachable iff is no earlier catch block A in
14164 the try statement such that the type of the catch
14165 clause's parameter is the same as or a subclass of the
14166 type of A's parameter */
14167 unreachable = 0;
14168 for (sub_current = catch;
14169 sub_current != current; sub_current = TREE_CHAIN (sub_current))
14171 tree sub_catch_clause, decl;
14172 sub_catch_clause = TREE_OPERAND (sub_current, 0);
14173 decl = BLOCK_EXPR_DECLS (sub_catch_clause);
14175 if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
14177 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14178 parse_error_context
14179 (wfl_operator,
14180 "`catch' not reached because of the catch clause at line %d",
14181 EXPR_WFL_LINENO (sub_current));
14182 unreachable = error_found = 1;
14183 break;
14186 /* Complete the catch clause block */
14187 catch_block = java_complete_tree (TREE_OPERAND (current, 0));
14188 if (catch_block == error_mark_node)
14190 error_found = 1;
14191 continue;
14193 if (CAN_COMPLETE_NORMALLY (catch_block))
14194 CAN_COMPLETE_NORMALLY (node) = 1;
14195 TREE_OPERAND (current, 0) = catch_block;
14197 if (unreachable)
14198 continue;
14200 /* Things to do here: the exception must be thrown */
14202 /* Link this type to the caught type list */
14203 caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
14206 PUSH_EXCEPTIONS (caught_type_list);
14207 if ((try = java_complete_tree (try)) == error_mark_node)
14208 error_found = 1;
14209 if (CAN_COMPLETE_NORMALLY (try))
14210 CAN_COMPLETE_NORMALLY (node) = 1;
14211 POP_EXCEPTIONS ();
14213 /* Verification ends here */
14214 if (error_found)
14215 return error_mark_node;
14217 TREE_OPERAND (node, 0) = try;
14218 TREE_OPERAND (node, 1) = catch;
14219 TREE_TYPE (node) = void_type_node;
14220 return node;
14223 /* 14.17 The synchronized Statement */
14225 static tree
14226 patch_synchronized_statement (node, wfl_op1)
14227 tree node, wfl_op1;
14229 tree expr = java_complete_tree (TREE_OPERAND (node, 0));
14230 tree block = TREE_OPERAND (node, 1);
14232 tree enter, exit, expr_decl, assignment;
14234 if (expr == error_mark_node)
14236 block = java_complete_tree (block);
14237 return expr;
14240 /* The TYPE of expr must be a reference type */
14241 if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
14243 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14244 parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
14245 lang_printable_name (TREE_TYPE (expr), 0));
14246 return error_mark_node;
14249 if (flag_emit_xref)
14251 TREE_OPERAND (node, 0) = expr;
14252 TREE_OPERAND (node, 1) = java_complete_tree (block);
14253 CAN_COMPLETE_NORMALLY (node) = 1;
14254 return node;
14257 /* Generate a try-finally for the synchronized statement, except
14258 that the handler that catches all throw exception calls
14259 _Jv_MonitorExit and then rethrow the exception.
14260 The synchronized statement is then implemented as:
14261 TRY
14263 _Jv_MonitorEnter (expression)
14264 synchronized_block
14265 _Jv_MonitorExit (expression)
14267 CATCH_ALL
14269 e = _Jv_exception_info ();
14270 _Jv_MonitorExit (expression)
14271 Throw (e);
14272 } */
14274 expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
14275 BUILD_MONITOR_ENTER (enter, expr_decl);
14276 BUILD_MONITOR_EXIT (exit, expr_decl);
14277 CAN_COMPLETE_NORMALLY (enter) = 1;
14278 CAN_COMPLETE_NORMALLY (exit) = 1;
14279 assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
14280 TREE_SIDE_EFFECTS (assignment) = 1;
14281 node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
14282 build (COMPOUND_EXPR, NULL_TREE,
14283 build (WITH_CLEANUP_EXPR, NULL_TREE,
14284 build (COMPOUND_EXPR, NULL_TREE,
14285 assignment, enter),
14286 NULL_TREE, exit),
14287 block));
14288 node = build_expr_block (node, expr_decl);
14290 return java_complete_tree (node);
14293 /* 14.16 The throw Statement */
14295 static tree
14296 patch_throw_statement (node, wfl_op1)
14297 tree node, wfl_op1;
14299 tree expr = TREE_OPERAND (node, 0);
14300 tree type = TREE_TYPE (expr);
14301 int unchecked_ok = 0, tryblock_throws_ok = 0;
14303 /* Thrown expression must be assignable to java.lang.Throwable */
14304 if (!try_reference_assignconv (throwable_type_node, expr))
14306 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14307 parse_error_context (wfl_operator,
14308 "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
14309 lang_printable_name (type, 0));
14310 /* If the thrown expression was a reference, we further the
14311 compile-time check. */
14312 if (!JREFERENCE_TYPE_P (type))
14313 return error_mark_node;
14316 /* At least one of the following must be true */
14318 /* The type of the throw expression is a not checked exception,
14319 i.e. is a unchecked expression. */
14320 unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
14322 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14323 /* An instance can't throw a checked excetion unless that exception
14324 is explicitely declared in the `throws' clause of each
14325 constructor. This doesn't apply to anonymous classes, since they
14326 don't have declared constructors. */
14327 if (!unchecked_ok
14328 && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
14330 tree current;
14331 for (current = TYPE_METHODS (current_class); current;
14332 current = TREE_CHAIN (current))
14333 if (DECL_CONSTRUCTOR_P (current)
14334 && !check_thrown_exceptions_do (TREE_TYPE (expr)))
14336 parse_error_context (wfl_operator, "Checked exception `%s' can't be thrown in instance initializer (not all declared constructor are declaring it in their `throws' clause)",
14337 lang_printable_name (TREE_TYPE (expr), 0));
14338 return error_mark_node;
14342 /* Throw is contained in a try statement and at least one catch
14343 clause can receive the thrown expression or the current method is
14344 declared to throw such an exception. Or, the throw statement is
14345 contained in a method or constructor declaration and the type of
14346 the Expression is assignable to at least one type listed in the
14347 throws clause the declaration. */
14348 if (!unchecked_ok)
14349 tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
14350 if (!(unchecked_ok || tryblock_throws_ok))
14352 /* If there is a surrounding try block that has no matching
14353 clatch clause, report it first. A surrounding try block exits
14354 only if there is something after the list of checked
14355 exception thrown by the current function (if any). */
14356 if (IN_TRY_BLOCK_P ())
14357 parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
14358 lang_printable_name (type, 0));
14359 /* If we have no surrounding try statement and the method doesn't have
14360 any throws, report it now. FIXME */
14362 /* We report that the exception can't be throw from a try block
14363 in all circumstances but when the `throw' is inside a static
14364 block. */
14365 else if (!EXCEPTIONS_P (currently_caught_type_list)
14366 && !tryblock_throws_ok)
14368 if (DECL_CLINIT_P (current_function_decl))
14369 parse_error_context (wfl_operator,
14370 "Checked exception `%s' can't be thrown in initializer",
14371 lang_printable_name (type, 0));
14372 else
14373 parse_error_context (wfl_operator,
14374 "Checked exception `%s' isn't thrown from a `try' block",
14375 lang_printable_name (type, 0));
14377 /* Otherwise, the current method doesn't have the appropriate
14378 throws declaration */
14379 else
14380 parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)",
14381 lang_printable_name (type, 0));
14382 return error_mark_node;
14385 if (! flag_emit_class_files && ! flag_emit_xref)
14386 BUILD_THROW (node, expr);
14388 /* If doing xrefs, keep the location where the `throw' was seen. */
14389 if (flag_emit_xref)
14390 EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
14391 return node;
14394 /* Check that exception said to be thrown by method DECL can be
14395 effectively caught from where DECL is invoked. */
14397 static void
14398 check_thrown_exceptions (location, decl)
14399 int location;
14400 tree decl;
14402 tree throws;
14403 /* For all the unchecked exceptions thrown by DECL */
14404 for (throws = DECL_FUNCTION_THROWS (decl); throws;
14405 throws = TREE_CHAIN (throws))
14406 if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
14408 #if 1
14409 /* Temporary hack to suppresses errors about cloning arrays. FIXME */
14410 if (DECL_NAME (decl) == get_identifier ("clone"))
14411 continue;
14412 #endif
14413 EXPR_WFL_LINECOL (wfl_operator) = location;
14414 if (DECL_FINIT_P (current_function_decl))
14415 parse_error_context
14416 (wfl_operator, "Exception `%s' can't be thrown in initializer",
14417 lang_printable_name (TREE_VALUE (throws), 0));
14418 else
14420 parse_error_context
14421 (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'",
14422 lang_printable_name (TREE_VALUE (throws), 0),
14423 (DECL_INIT_P (current_function_decl) ?
14424 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
14425 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
14430 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
14431 try-catch blocks, OR is listed in the `throws' clause of the
14432 current method. */
14434 static int
14435 check_thrown_exceptions_do (exception)
14436 tree exception;
14438 tree list = currently_caught_type_list;
14439 resolve_and_layout (exception, NULL_TREE);
14440 /* First, all the nested try-catch-finally at that stage. The
14441 last element contains `throws' clause exceptions, if any. */
14442 if (IS_UNCHECKED_EXCEPTION_P (exception))
14443 return 1;
14444 while (list)
14446 tree caught;
14447 for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
14448 if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
14449 return 1;
14450 list = TREE_CHAIN (list);
14452 return 0;
14455 static void
14456 purge_unchecked_exceptions (mdecl)
14457 tree mdecl;
14459 tree throws = DECL_FUNCTION_THROWS (mdecl);
14460 tree new = NULL_TREE;
14462 while (throws)
14464 tree next = TREE_CHAIN (throws);
14465 if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
14467 TREE_CHAIN (throws) = new;
14468 new = throws;
14470 throws = next;
14472 /* List is inverted here, but it doesn't matter */
14473 DECL_FUNCTION_THROWS (mdecl) = new;
14476 /* 15.24 Conditional Operator ?: */
14478 static tree
14479 patch_conditional_expr (node, wfl_cond, wfl_op1)
14480 tree node, wfl_cond, wfl_op1;
14482 tree cond = TREE_OPERAND (node, 0);
14483 tree op1 = TREE_OPERAND (node, 1);
14484 tree op2 = TREE_OPERAND (node, 2);
14485 tree resulting_type = NULL_TREE;
14486 tree t1, t2, patched;
14487 int error_found = 0;
14489 /* Operands of ?: might be StringBuffers crafted as a result of a
14490 string concatenation. Obtain a descent operand here. */
14491 if ((patched = patch_string (op1)))
14492 TREE_OPERAND (node, 1) = op1 = patched;
14493 if ((patched = patch_string (op2)))
14494 TREE_OPERAND (node, 2) = op2 = patched;
14496 t1 = TREE_TYPE (op1);
14497 t2 = TREE_TYPE (op2);
14499 /* The first expression must be a boolean */
14500 if (TREE_TYPE (cond) != boolean_type_node)
14502 SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
14503 parse_error_context (wfl_operator,
14504 "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
14505 lang_printable_name (TREE_TYPE (cond), 0));
14506 error_found = 1;
14509 /* Second and third can be numeric, boolean (i.e. primitive),
14510 references or null. Anything else results in an error */
14511 if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
14512 || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node)
14513 && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
14514 || (t1 == boolean_type_node && t2 == boolean_type_node)))
14515 error_found = 1;
14517 /* Determine the type of the conditional expression. Same types are
14518 easy to deal with */
14519 else if (t1 == t2)
14520 resulting_type = t1;
14522 /* There are different rules for numeric types */
14523 else if (JNUMERIC_TYPE_P (t1))
14525 /* if byte/short found, the resulting type is short */
14526 if ((t1 == byte_type_node && t2 == short_type_node)
14527 || (t1 == short_type_node && t2 == byte_type_node))
14528 resulting_type = short_type_node;
14530 /* If t1 is a constant int and t2 is of type byte, short or char
14531 and t1's value fits in t2, then the resulting type is t2 */
14532 else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
14533 && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
14534 resulting_type = t2;
14536 /* If t2 is a constant int and t1 is of type byte, short or char
14537 and t2's value fits in t1, then the resulting type is t1 */
14538 else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
14539 && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
14540 resulting_type = t1;
14542 /* Otherwise, binary numeric promotion is applied and the
14543 resulting type is the promoted type of operand 1 and 2 */
14544 else
14545 resulting_type = binary_numeric_promotion (t1, t2,
14546 &TREE_OPERAND (node, 1),
14547 &TREE_OPERAND (node, 2));
14550 /* Cases of a reference and a null type */
14551 else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
14552 resulting_type = t1;
14554 else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
14555 resulting_type = t2;
14557 /* Last case: different reference types. If a type can be converted
14558 into the other one by assignment conversion, the latter
14559 determines the type of the expression */
14560 else if ((resulting_type = try_reference_assignconv (t1, op2)))
14561 resulting_type = promote_type (t1);
14563 else if ((resulting_type = try_reference_assignconv (t2, op1)))
14564 resulting_type = promote_type (t2);
14566 /* If we don't have any resulting type, we're in trouble */
14567 if (!resulting_type)
14569 char *t = xstrdup (lang_printable_name (t1, 0));
14570 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14571 parse_error_context (wfl_operator,
14572 "Incompatible type for `?:'. Can't convert `%s' to `%s'",
14573 t, lang_printable_name (t2, 0));
14574 free (t);
14575 error_found = 1;
14578 if (error_found)
14580 TREE_TYPE (node) = error_mark_node;
14581 return error_mark_node;
14584 TREE_TYPE (node) = resulting_type;
14585 TREE_SET_CODE (node, COND_EXPR);
14586 CAN_COMPLETE_NORMALLY (node) = 1;
14587 return node;
14590 /* Try to constant fold NODE.
14591 If NODE is not a constant expression, return NULL_EXPR.
14592 CONTEXT is a static final VAR_DECL whose initializer we are folding. */
14594 static tree
14595 fold_constant_for_init (node, context)
14596 tree node;
14597 tree context;
14599 tree op0, op1, val;
14600 enum tree_code code = TREE_CODE (node);
14602 if (code == STRING_CST)
14603 return node;
14605 if (code == INTEGER_CST || code == REAL_CST)
14606 return convert (TREE_TYPE (context), node);
14607 if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL && code != FIELD_DECL)
14608 return NULL_TREE;
14610 switch (code)
14612 case PLUS_EXPR:
14613 case MINUS_EXPR:
14614 case MULT_EXPR:
14615 case TRUNC_MOD_EXPR:
14616 case RDIV_EXPR:
14617 case LSHIFT_EXPR:
14618 case RSHIFT_EXPR:
14619 case URSHIFT_EXPR:
14620 case BIT_AND_EXPR:
14621 case BIT_XOR_EXPR:
14622 case BIT_IOR_EXPR:
14623 case TRUTH_ANDIF_EXPR:
14624 case TRUTH_ORIF_EXPR:
14625 case EQ_EXPR:
14626 case NE_EXPR:
14627 case GT_EXPR:
14628 case GE_EXPR:
14629 case LT_EXPR:
14630 case LE_EXPR:
14631 op0 = TREE_OPERAND (node, 0);
14632 op1 = TREE_OPERAND (node, 1);
14633 val = fold_constant_for_init (op0, context);
14634 if (val == NULL_TREE || ! TREE_CONSTANT (val))
14635 return NULL_TREE;
14636 TREE_OPERAND (node, 0) = val;
14637 val = fold_constant_for_init (op1, context);
14638 if (val == NULL_TREE || ! TREE_CONSTANT (val))
14639 return NULL_TREE;
14640 TREE_OPERAND (node, 1) = val;
14641 return patch_binop (node, op0, op1);
14643 case UNARY_PLUS_EXPR:
14644 case NEGATE_EXPR:
14645 case TRUTH_NOT_EXPR:
14646 case BIT_NOT_EXPR:
14647 case CONVERT_EXPR:
14648 op0 = TREE_OPERAND (node, 0);
14649 val = fold_constant_for_init (op0, context);
14650 if (val == NULL_TREE || ! TREE_CONSTANT (val))
14651 return NULL_TREE;
14652 TREE_OPERAND (node, 0) = val;
14653 return patch_unaryop (node, op0);
14654 break;
14656 case COND_EXPR:
14657 val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
14658 if (val == NULL_TREE || ! TREE_CONSTANT (val))
14659 return NULL_TREE;
14660 TREE_OPERAND (node, 0) = val;
14661 val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
14662 if (val == NULL_TREE || ! TREE_CONSTANT (val))
14663 return NULL_TREE;
14664 TREE_OPERAND (node, 1) = val;
14665 val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
14666 if (val == NULL_TREE || ! TREE_CONSTANT (val))
14667 return NULL_TREE;
14668 TREE_OPERAND (node, 2) = val;
14669 return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
14670 : TREE_OPERAND (node, 2);
14672 case VAR_DECL:
14673 case FIELD_DECL:
14674 if (! FIELD_FINAL (node)
14675 || DECL_INITIAL (node) == NULL_TREE)
14676 return NULL_TREE;
14677 val = DECL_INITIAL (node);
14678 /* Guard against infinite recursion. */
14679 DECL_INITIAL (node) = NULL_TREE;
14680 val = fold_constant_for_init (val, node);
14681 DECL_INITIAL (node) = val;
14682 return val;
14684 case EXPR_WITH_FILE_LOCATION:
14685 /* Compare java_complete_tree and resolve_expression_name. */
14686 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
14687 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
14689 tree name = EXPR_WFL_NODE (node);
14690 tree decl;
14691 if (PRIMARY_P (node))
14692 return NULL_TREE;
14693 else if (! QUALIFIED_P (name))
14695 decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
14696 if (decl == NULL_TREE
14697 || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
14698 return NULL_TREE;
14699 return fold_constant_for_init (decl, decl);
14701 else
14703 /* Wait until the USE_COMPONENT_REF re-write. FIXME. */
14704 qualify_ambiguous_name (node);
14705 if (resolve_field_access (node, &decl, NULL)
14706 && decl != NULL_TREE)
14707 return fold_constant_for_init (decl, decl);
14708 return NULL_TREE;
14711 else
14713 op0 = TREE_OPERAND (node, 0);
14714 val = fold_constant_for_init (op0, context);
14715 if (val == NULL_TREE || ! TREE_CONSTANT (val))
14716 return NULL_TREE;
14717 TREE_OPERAND (node, 0) = val;
14718 return val;
14721 #ifdef USE_COMPONENT_REF
14722 case IDENTIFIER:
14723 case COMPONENT_REF:
14725 #endif
14727 default:
14728 return NULL_TREE;
14732 #ifdef USE_COMPONENT_REF
14733 /* Context is 'T' for TypeName, 'P' for PackageName,
14734 'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
14736 tree
14737 resolve_simple_name (name, context)
14738 tree name;
14739 int context;
14743 tree
14744 resolve_qualified_name (name, context)
14745 tree name;
14746 int context;
14749 #endif