]> gcc.gnu.org Git - gcc.git/blob - gcc/java/parse.y
[multiple changes]
[gcc.git] / gcc / java / parse.y
1 /* Source code parsing and tree node generation for the GNU compiler
2 for the Java(TM) language.
3 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
4 Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
5
6 This file is part of GNU CC.
7
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.
12
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.
17
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.
22
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. */
26
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).
30
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"
34
35 The following modifications were brought to the original grammar:
36
37 method_body: added the rule '| block SC_TK'
38 static_initializer: added the rule 'static block SC_TK'.
39
40 Note: All the extra rules described above should go away when the
41 empty_statement rule will work.
42
43 statement_nsi: 'nsi' should be read no_short_if.
44
45 Some rules have been modified to support JDK1.1 inner classes
46 definitions and other extensions. */
47
48 %{
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 "except.h"
66
67 #ifndef DIR_SEPARATOR
68 #define DIR_SEPARATOR '/'
69 #endif
70
71 /* Local function prototypes */
72 static char *java_accstring_lookup PROTO ((int));
73 static void classitf_redefinition_error PROTO ((char *,tree, tree, tree));
74 static void variable_redefinition_error PROTO ((tree, tree, tree, int));
75 static void check_modifiers PROTO ((char *, int, int));
76 static tree create_class PROTO ((int, tree, tree, tree));
77 static tree create_interface PROTO ((int, tree, tree));
78 static tree find_field PROTO ((tree, tree));
79 static tree lookup_field_wrapper PROTO ((tree, tree));
80 static int duplicate_declaration_error_p PROTO ((tree, tree, tree));
81 static void register_fields PROTO ((int, tree, tree));
82 static tree parser_qualified_classname PROTO ((tree));
83 static int parser_check_super PROTO ((tree, tree, tree));
84 static int parser_check_super_interface PROTO ((tree, tree, tree));
85 static void check_modifiers_consistency PROTO ((int));
86 static tree lookup_cl PROTO ((tree));
87 static tree lookup_java_method2 PROTO ((tree, tree, int));
88 static tree method_header PROTO ((int, tree, tree, tree));
89 static void fix_method_argument_names PROTO ((tree ,tree));
90 static tree method_declarator PROTO ((tree, tree));
91 static void parse_warning_context PVPROTO ((tree cl, const char *msg, ...))
92 ATTRIBUTE_PRINTF_2;
93 static void issue_warning_error_from_context PROTO ((tree, const char *msg, va_list));
94 static tree parse_jdk1_1_error PROTO ((char *));
95 static void complete_class_report_errors PROTO ((jdep *));
96 static int process_imports PROTO ((void));
97 static void read_import_dir PROTO ((tree));
98 static int find_in_imports_on_demand PROTO ((tree));
99 static int find_in_imports PROTO ((tree));
100 static int check_pkg_class_access PROTO ((tree, tree));
101 static tree resolve_package PROTO ((tree, tree *));
102 static tree lookup_package_type PROTO ((char *, int));
103 static tree resolve_class PROTO ((tree, tree, tree));
104 static void declare_local_variables PROTO ((int, tree, tree));
105 static void source_start_java_method PROTO ((tree));
106 static void source_end_java_method PROTO ((void));
107 static void expand_start_java_method PROTO ((tree));
108 static tree find_name_in_single_imports PROTO ((tree));
109 static void check_abstract_method_header PROTO ((tree));
110 static tree lookup_java_interface_method2 PROTO ((tree, tree));
111 static tree resolve_expression_name PROTO ((tree, tree *));
112 static tree maybe_create_class_interface_decl PROTO ((tree, tree, tree));
113 static int check_class_interface_creation PROTO ((int, int, tree,
114 tree, tree, tree));
115 static tree patch_method_invocation PROTO ((tree, tree, tree,
116 int *, tree *));
117 static int breakdown_qualified PROTO ((tree *, tree *, tree));
118 static tree resolve_and_layout PROTO ((tree, tree));
119 static tree resolve_no_layout PROTO ((tree, tree));
120 static int invocation_mode PROTO ((tree, int));
121 static tree find_applicable_accessible_methods_list PROTO ((int, tree,
122 tree, tree));
123 static void search_applicable_methods_list PROTO ((int, tree, tree, tree,
124 tree *, tree *));
125 static tree find_most_specific_methods_list PROTO ((tree));
126 static int argument_types_convertible PROTO ((tree, tree));
127 static tree patch_invoke PROTO ((tree, tree, tree));
128 static tree lookup_method_invoke PROTO ((int, tree, tree, tree, tree));
129 static tree register_incomplete_type PROTO ((int, tree, tree, tree));
130 static tree obtain_incomplete_type PROTO ((tree));
131 static tree java_complete_lhs PROTO ((tree));
132 static tree java_complete_tree PROTO ((tree));
133 static void java_complete_expand_method PROTO ((tree));
134 static int unresolved_type_p PROTO ((tree, tree *));
135 static void create_jdep_list PROTO ((struct parser_ctxt *));
136 static tree build_expr_block PROTO ((tree, tree));
137 static tree enter_block PROTO ((void));
138 static tree enter_a_block PROTO ((tree));
139 static tree exit_block PROTO ((void));
140 static tree lookup_name_in_blocks PROTO ((tree));
141 static void maybe_absorb_scoping_blocks PROTO ((void));
142 static tree build_method_invocation PROTO ((tree, tree));
143 static tree build_new_invocation PROTO ((tree, tree));
144 static tree build_assignment PROTO ((int, int, tree, tree));
145 static tree build_binop PROTO ((enum tree_code, int, tree, tree));
146 static int check_final_assignment PROTO ((tree ,tree));
147 static tree patch_assignment PROTO ((tree, tree, tree ));
148 static tree patch_binop PROTO ((tree, tree, tree));
149 static tree build_unaryop PROTO ((int, int, tree));
150 static tree build_incdec PROTO ((int, int, tree, int));
151 static tree patch_unaryop PROTO ((tree, tree));
152 static tree build_cast PROTO ((int, tree, tree));
153 static tree build_null_of_type PROTO ((tree));
154 static tree patch_cast PROTO ((tree, tree));
155 static int valid_ref_assignconv_cast_p PROTO ((tree, tree, int));
156 static int valid_builtin_assignconv_identity_widening_p PROTO ((tree, tree));
157 static int valid_cast_to_p PROTO ((tree, tree));
158 static int valid_method_invocation_conversion_p PROTO ((tree, tree));
159 static tree try_builtin_assignconv PROTO ((tree, tree, tree));
160 static tree try_reference_assignconv PROTO ((tree, tree));
161 static tree build_unresolved_array_type PROTO ((tree));
162 static tree build_array_from_name PROTO ((tree, tree, tree, tree *));
163 static tree build_array_ref PROTO ((int, tree, tree));
164 static tree patch_array_ref PROTO ((tree));
165 static tree make_qualified_name PROTO ((tree, tree, int));
166 static tree merge_qualified_name PROTO ((tree, tree));
167 static tree make_qualified_primary PROTO ((tree, tree, int));
168 static int resolve_qualified_expression_name PROTO ((tree, tree *,
169 tree *, tree *));
170 static void qualify_ambiguous_name PROTO ((tree));
171 static void maybe_generate_clinit PROTO ((void));
172 static tree resolve_field_access PROTO ((tree, tree *, tree *));
173 static tree build_newarray_node PROTO ((tree, tree, int));
174 static tree patch_newarray PROTO ((tree));
175 static tree resolve_type_during_patch PROTO ((tree));
176 static tree build_this PROTO ((int));
177 static tree build_return PROTO ((int, tree));
178 static tree patch_return PROTO ((tree));
179 static tree maybe_access_field PROTO ((tree, tree, tree));
180 static int complete_function_arguments PROTO ((tree));
181 static int check_for_static_method_reference PROTO ((tree, tree, tree, tree, tree));
182 static int not_accessible_p PROTO ((tree, tree, int));
183 static void check_deprecation PROTO ((tree, tree));
184 static int class_in_current_package PROTO ((tree));
185 static tree build_if_else_statement PROTO ((int, tree, tree, tree));
186 static tree patch_if_else_statement PROTO ((tree));
187 static tree add_stmt_to_compound PROTO ((tree, tree, tree));
188 static tree add_stmt_to_block PROTO ((tree, tree, tree));
189 static tree patch_exit_expr PROTO ((tree));
190 static tree build_labeled_block PROTO ((int, tree));
191 static tree finish_labeled_statement PROTO ((tree, tree));
192 static tree build_bc_statement PROTO ((int, int, tree));
193 static tree patch_bc_statement PROTO ((tree));
194 static tree patch_loop_statement PROTO ((tree));
195 static tree build_new_loop PROTO ((tree));
196 static tree build_loop_body PROTO ((int, tree, int));
197 static tree finish_loop_body PROTO ((int, tree, tree, int));
198 static tree build_debugable_stmt PROTO ((int, tree));
199 static tree finish_for_loop PROTO ((int, tree, tree, tree));
200 static tree patch_switch_statement PROTO ((tree));
201 static tree string_constant_concatenation PROTO ((tree, tree));
202 static tree build_string_concatenation PROTO ((tree, tree));
203 static tree patch_string_cst PROTO ((tree));
204 static tree patch_string PROTO ((tree));
205 static tree build_try_statement PROTO ((int, tree, tree));
206 static tree build_try_finally_statement PROTO ((int, tree, tree));
207 static tree patch_try_statement PROTO ((tree));
208 static tree patch_synchronized_statement PROTO ((tree, tree));
209 static tree patch_throw_statement PROTO ((tree, tree));
210 static void check_thrown_exceptions PROTO ((int, tree));
211 static int check_thrown_exceptions_do PROTO ((tree));
212 static void purge_unchecked_exceptions PROTO ((tree));
213 static void check_throws_clauses PROTO ((tree, tree, tree));
214 static void finish_method_declaration PROTO ((tree));
215 static tree build_super_invocation PROTO (());
216 static int verify_constructor_circularity PROTO ((tree, tree));
217 static char *constructor_circularity_msg PROTO ((tree, tree));
218 static tree build_this_super_qualified_invocation PROTO ((int, tree, tree,
219 int, int));
220 static char *get_printable_method_name PROTO ((tree));
221 static tree patch_conditional_expr PROTO ((tree, tree, tree));
222 static void maybe_generate_finit PROTO (());
223 static void fix_constructors PROTO ((tree));
224 static int verify_constructor_super PROTO (());
225 static tree create_artificial_method PROTO ((tree, int, tree, tree, tree));
226 static void start_artificial_method_body PROTO ((tree));
227 static void end_artificial_method_body PROTO ((tree));
228 static int check_method_redefinition PROTO ((tree, tree));
229 static int reset_method_name PROTO ((tree));
230 static void java_check_regular_methods PROTO ((tree));
231 static void java_check_abstract_methods PROTO ((tree));
232 static tree maybe_build_primttype_type_ref PROTO ((tree, tree));
233 static void unreachable_stmt_error PROTO ((tree));
234 static tree find_expr_with_wfl PROTO ((tree));
235 static void missing_return_error PROTO ((tree));
236 static tree build_new_array_init PROTO ((int, tree));
237 static tree patch_new_array_init PROTO ((tree, tree));
238 static tree maybe_build_array_element_wfl PROTO ((tree));
239 static int array_constructor_check_entry PROTO ((tree, tree));
240 static char *purify_type_name PROTO ((char *));
241 static tree fold_constant_for_init PROTO ((tree, tree));
242 static tree strip_out_static_field_access_decl PROTO ((tree));
243 static jdeplist *reverse_jdep_list PROTO ((struct parser_ctxt *));
244 static void static_ref_err PROTO ((tree, tree, tree));
245
246 /* Number of error found so far. */
247 int java_error_count;
248 /* Number of warning found so far. */
249 int java_warning_count;
250 /* Tell when not to fold, when doing xrefs */
251 int do_not_fold;
252
253 /* The current parser context */
254 struct parser_ctxt *ctxp;
255
256 /* List of things that were analyzed for which code will be generated */
257 static struct parser_ctxt *ctxp_for_generation = NULL;
258
259 /* binop_lookup maps token to tree_code. It is used where binary
260 operations are involved and required by the parser. RDIV_EXPR
261 covers both integral/floating point division. The code is changed
262 once the type of both operator is worked out. */
263
264 static enum tree_code binop_lookup[19] =
265 {
266 PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
267 LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR,
268 BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
269 TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
270 EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
271 };
272 #define BINOP_LOOKUP(VALUE) \
273 binop_lookup [((VALUE) - PLUS_TK)% \
274 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
275
276 /* Fake WFL used to report error message. It is initialized once if
277 needed and reused with it's location information is overriden. */
278 tree wfl_operator = NULL_TREE;
279
280 /* The "$L" identifier we use to create labels. */
281 static tree label_id = NULL_TREE;
282
283 /* The "StringBuffer" identifier used for the String `+' operator. */
284 static tree wfl_string_buffer = NULL_TREE;
285
286 /* The "append" identifier used for String `+' operator. */
287 static tree wfl_append = NULL_TREE;
288
289 /* The "toString" identifier used for String `+' operator. */
290 static tree wfl_to_string = NULL_TREE;
291
292 /* The "java.lang" import qualified name. */
293 static tree java_lang_id = NULL_TREE;
294
295 /* The "java.lang.Cloneable" qualified name. */
296 static tree java_lang_cloneable = NULL_TREE;
297
298 /* Context and flag for static blocks */
299 static tree current_static_block = NULL_TREE;
300
301 %}
302
303 %union {
304 tree node;
305 int sub_token;
306 struct {
307 int token;
308 int location;
309 } operator;
310 int value;
311 }
312
313 %{
314 #include "lex.c"
315 %}
316
317 %pure_parser
318
319 /* Things defined here have to match the order of what's in the
320 binop_lookup table. */
321
322 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
323 %token LS_TK SRS_TK ZRS_TK
324 %token AND_TK XOR_TK OR_TK
325 %token BOOL_AND_TK BOOL_OR_TK
326 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
327
328 /* This maps to the same binop_lookup entry than the token above */
329
330 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
331 %token REM_ASSIGN_TK
332 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
333 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
334
335
336 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
337
338 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
339 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
340 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
341 %token PAD_TK ABSTRACT_TK MODIFIER_TK
342
343 /* Keep those two in order, too */
344 %token DECR_TK INCR_TK
345
346 /* From now one, things can be in any order */
347
348 %token DEFAULT_TK IF_TK THROW_TK
349 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
350 %token THROWS_TK BREAK_TK IMPORT_TK
351 %token ELSE_TK INSTANCEOF_TK RETURN_TK
352 %token VOID_TK CATCH_TK INTERFACE_TK
353 %token CASE_TK EXTENDS_TK FINALLY_TK
354 %token SUPER_TK WHILE_TK CLASS_TK
355 %token SWITCH_TK CONST_TK TRY_TK
356 %token FOR_TK NEW_TK CONTINUE_TK
357 %token GOTO_TK PACKAGE_TK THIS_TK
358
359 %token BYTE_TK SHORT_TK INT_TK LONG_TK
360 %token CHAR_TK INTEGRAL_TK
361
362 %token FLOAT_TK DOUBLE_TK FP_TK
363
364 %token ID_TK
365
366 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
367
368 %token ASSIGN_ANY_TK ASSIGN_TK
369 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
370
371 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
372 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
373
374 %type <value> modifiers MODIFIER_TK
375
376 %type <node> super ID_TK identifier
377 %type <node> name simple_name qualified_name
378 %type <node> class_declaration type_declaration compilation_unit
379 field_declaration method_declaration extends_interfaces
380 interfaces interface_type_list
381 interface_declaration class_member_declaration
382 import_declarations package_declaration
383 type_declarations interface_body
384 interface_member_declaration constant_declaration
385 interface_member_declarations interface_type
386 abstract_method_declaration interface_type_list
387 %type <node> class_body_declaration class_member_declaration
388 static_initializer constructor_declaration block
389 %type <node> class_body_declarations constructor_header
390 %type <node> class_or_interface_type class_type class_type_list
391 constructor_declarator explicit_constructor_invocation
392 %type <node> dim_expr dim_exprs this_or_super throws
393
394 %type <node> variable_declarator_id variable_declarator
395 variable_declarators variable_initializer
396 variable_initializers constructor_body
397 array_initializer
398
399 %type <node> class_body block_end constructor_block_end
400 %type <node> statement statement_without_trailing_substatement
401 labeled_statement if_then_statement label_decl
402 if_then_else_statement while_statement for_statement
403 statement_nsi labeled_statement_nsi do_statement
404 if_then_else_statement_nsi while_statement_nsi
405 for_statement_nsi statement_expression_list for_init
406 for_update statement_expression expression_statement
407 primary_no_new_array expression primary
408 array_creation_expression array_type
409 class_instance_creation_expression field_access
410 method_invocation array_access something_dot_new
411 argument_list postfix_expression while_expression
412 post_increment_expression post_decrement_expression
413 unary_expression_not_plus_minus unary_expression
414 pre_increment_expression pre_decrement_expression
415 unary_expression_not_plus_minus cast_expression
416 multiplicative_expression additive_expression
417 shift_expression relational_expression
418 equality_expression and_expression
419 exclusive_or_expression inclusive_or_expression
420 conditional_and_expression conditional_or_expression
421 conditional_expression assignment_expression
422 left_hand_side assignment for_header for_begin
423 constant_expression do_statement_begin empty_statement
424 switch_statement synchronized_statement throw_statement
425 try_statement switch_expression switch_block
426 catches catch_clause catch_clause_parameter finally
427 %type <node> return_statement break_statement continue_statement
428
429 %type <operator> ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
430 %type <operator> REM_ASSIGN_TK PLUS_ASSIGN_TK MINUS_ASSIGN_TK
431 %type <operator> LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
432 %type <operator> AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
433 %type <operator> ASSIGN_ANY_TK assignment_operator
434 %token <operator> EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK
435 %token <operator> BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
436 %token <operator> DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
437 %token <operator> NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
438 %token <operator> OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
439 %type <operator> THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK
440 %type <operator> CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
441
442 %type <node> method_body
443
444 %type <node> literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
445 STRING_LIT_TK NULL_TK VOID_TK
446
447 %type <node> IF_TK WHILE_TK FOR_TK
448
449 %type <node> formal_parameter_list formal_parameter
450 method_declarator method_header
451
452 %type <node> primitive_type reference_type type
453 BOOLEAN_TK INTEGRAL_TK FP_TK
454
455 %%
456 /* 19.2 Production from 2.3: The Syntactic Grammar */
457 goal:
458 compilation_unit
459 {}
460 ;
461
462 /* 19.3 Productions from 3: Lexical structure */
463 literal:
464 INT_LIT_TK
465 | FP_LIT_TK
466 | BOOL_LIT_TK
467 | CHAR_LIT_TK
468 | STRING_LIT_TK
469 | NULL_TK
470 ;
471
472 /* 19.4 Productions from 4: Types, Values and Variables */
473 type:
474 primitive_type
475 | reference_type
476 ;
477
478 primitive_type:
479 INTEGRAL_TK
480 | FP_TK
481 | BOOLEAN_TK
482 ;
483
484 reference_type:
485 class_or_interface_type
486 | array_type
487 ;
488
489 class_or_interface_type:
490 name
491 ;
492
493 class_type:
494 class_or_interface_type /* Default rule */
495 ;
496
497 interface_type:
498 class_or_interface_type
499 ;
500
501 array_type:
502 primitive_type OSB_TK CSB_TK
503 {
504 $$ = build_java_array_type ($1, -1);
505 CLASS_LOADED_P ($$) = 1;
506 }
507 | name OSB_TK CSB_TK
508 { $$ = build_unresolved_array_type ($1); }
509 | array_type OSB_TK CSB_TK
510 { $$ = build_unresolved_array_type ($1); }
511 | primitive_type OSB_TK error
512 {RULE ("']' expected"); RECOVER;}
513 | array_type OSB_TK error
514 {RULE ("']' expected"); RECOVER;}
515 ;
516
517 /* 19.5 Productions from 6: Names */
518 name:
519 simple_name /* Default rule */
520 | qualified_name /* Default rule */
521 ;
522
523 simple_name:
524 identifier /* Default rule */
525 ;
526
527 qualified_name:
528 name DOT_TK identifier
529 { $$ = make_qualified_name ($1, $3, $2.location); }
530 ;
531
532 identifier:
533 ID_TK
534 ;
535
536 /* 19.6: Production from 7: Packages */
537 compilation_unit:
538 {$$ = NULL;}
539 | package_declaration
540 | import_declarations
541 | type_declarations
542 | package_declaration import_declarations
543 | package_declaration type_declarations
544 | import_declarations type_declarations
545 | package_declaration import_declarations type_declarations
546 ;
547
548 import_declarations:
549 import_declaration
550 {
551 $$ = NULL;
552 }
553 | import_declarations import_declaration
554 {
555 $$ = NULL;
556 }
557 ;
558
559 type_declarations:
560 type_declaration
561 | type_declarations type_declaration
562 ;
563
564 package_declaration:
565 PACKAGE_TK name SC_TK
566 { ctxp->package = EXPR_WFL_NODE ($2); }
567 | PACKAGE_TK error
568 {yyerror ("Missing name"); RECOVER;}
569 | PACKAGE_TK name error
570 {yyerror ("';' expected"); RECOVER;}
571 ;
572
573 import_declaration:
574 single_type_import_declaration
575 | type_import_on_demand_declaration
576 ;
577
578 single_type_import_declaration:
579 IMPORT_TK name SC_TK
580 {
581 tree name = EXPR_WFL_NODE ($2), node, last_name;
582 int i = IDENTIFIER_LENGTH (name)-1;
583 char *last = &IDENTIFIER_POINTER (name)[i];
584 while (last != IDENTIFIER_POINTER (name))
585 {
586 if (last [0] == '.')
587 break;
588 last--;
589 }
590 last_name = get_identifier (++last);
591 if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
592 {
593 tree err = find_name_in_single_imports (last_name);
594 if (err && err != name)
595 parse_error_context
596 ($2, "Ambiguous class: `%s' and `%s'",
597 IDENTIFIER_POINTER (name),
598 IDENTIFIER_POINTER (err));
599 else
600 REGISTER_IMPORT ($2, last_name)
601 }
602 else
603 REGISTER_IMPORT ($2, last_name);
604 }
605 | IMPORT_TK error
606 {yyerror ("Missing name"); RECOVER;}
607 | IMPORT_TK name error
608 {yyerror ("';' expected"); RECOVER;}
609 ;
610
611 type_import_on_demand_declaration:
612 IMPORT_TK name DOT_TK MULT_TK SC_TK
613 {
614 tree name = EXPR_WFL_NODE ($2);
615 /* Don't import java.lang.* twice. */
616 if (name != java_lang_id)
617 {
618 tree node = build_tree_list ($2, NULL_TREE);
619 read_import_dir ($2);
620 TREE_CHAIN (node) = ctxp->import_demand_list;
621 ctxp->import_demand_list = node;
622 }
623 }
624 | IMPORT_TK name DOT_TK error
625 {yyerror ("'*' expected"); RECOVER;}
626 | IMPORT_TK name DOT_TK MULT_TK error
627 {yyerror ("';' expected"); RECOVER;}
628 ;
629
630 type_declaration:
631 class_declaration
632 {
633 maybe_generate_finit ();
634 maybe_generate_clinit ();
635 $$ = $1;
636 }
637 | interface_declaration
638 {
639 maybe_generate_clinit ();
640 $$ = $1;
641 }
642 | SC_TK
643 { $$ = NULL; }
644 | error
645 {
646 YYERROR_NOW;
647 yyerror ("Class or interface declaration expected");
648 }
649 ;
650
651 /* 19.7 Shortened from the original:
652 modifiers: modifier | modifiers modifier
653 modifier: any of public... */
654 modifiers:
655 MODIFIER_TK
656 {
657 $$ = (1 << $1);
658 }
659 | modifiers MODIFIER_TK
660 {
661 int acc = (1 << $2);
662 if ($$ & acc)
663 parse_error_context
664 (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
665 java_accstring_lookup (acc));
666 else
667 {
668 $$ |= acc;
669 }
670 }
671 ;
672
673 /* 19.8.1 Production from $8.1: Class Declaration */
674 class_declaration:
675 modifiers CLASS_TK identifier super interfaces
676 { create_class ($1, $3, $4, $5); }
677 class_body
678 {
679 $$ = $7;
680 }
681 | CLASS_TK identifier super interfaces
682 { create_class (0, $2, $3, $4); }
683 class_body
684 {
685 $$ = $6;
686 }
687 | modifiers CLASS_TK error
688 {yyerror ("Missing class name"); RECOVER;}
689 | CLASS_TK error
690 {yyerror ("Missing class name"); RECOVER;}
691 | CLASS_TK identifier error
692 {
693 if (!ctxp->class_err) yyerror ("'{' expected");
694 DRECOVER(class1);
695 }
696 | modifiers CLASS_TK identifier error
697 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
698 ;
699
700 super:
701 { $$ = NULL; }
702 | EXTENDS_TK class_type
703 { $$ = $2; }
704 | EXTENDS_TK class_type error
705 {yyerror ("'{' expected"); ctxp->class_err=1;}
706 | EXTENDS_TK error
707 {yyerror ("Missing super class name"); ctxp->class_err=1;}
708 ;
709
710 interfaces:
711 { $$ = NULL_TREE; }
712 | IMPLEMENTS_TK interface_type_list
713 { $$ = $2; }
714 | IMPLEMENTS_TK error
715 {
716 ctxp->class_err=1;
717 yyerror ("Missing interface name");
718 }
719 ;
720
721 interface_type_list:
722 interface_type
723 {
724 ctxp->interface_number = 1;
725 $$ = build_tree_list ($1, NULL_TREE);
726 }
727 | interface_type_list C_TK interface_type
728 {
729 ctxp->interface_number++;
730 $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
731 }
732 | interface_type_list C_TK error
733 {yyerror ("Missing interface name"); RECOVER;}
734 ;
735
736 class_body:
737 OCB_TK CCB_TK
738 {
739 /* Store the location of the `}' when doing xrefs */
740 if (flag_emit_xref)
741 DECL_END_SOURCE_LINE (ctxp->current_parsed_class) =
742 EXPR_WFL_ADD_COL ($2.location, 1);
743 $$ = ctxp->current_parsed_class;
744 }
745 | OCB_TK class_body_declarations CCB_TK
746 {
747 /* Store the location of the `}' when doing xrefs */
748 if (flag_emit_xref)
749 DECL_END_SOURCE_LINE (ctxp->current_parsed_class) =
750 EXPR_WFL_ADD_COL ($3.location, 1);
751 $$ = ctxp->current_parsed_class;
752 }
753 ;
754
755 class_body_declarations:
756 class_body_declaration
757 | class_body_declarations class_body_declaration
758 ;
759
760 class_body_declaration:
761 class_member_declaration
762 | static_initializer
763 | constructor_declaration
764 | block /* Added, JDK1.1, instance initializer */
765 { $$ = parse_jdk1_1_error ("instance initializer"); }
766 ;
767
768 class_member_declaration:
769 field_declaration
770 | field_declaration SC_TK
771 { $$ = $1; }
772 | method_declaration
773 | class_declaration /* Added, JDK1.1 inner classes */
774 { $$ = parse_jdk1_1_error ("inner classe declaration"); }
775 | interface_declaration /* Added, JDK1.1 inner classes */
776 { $$ = parse_jdk1_1_error ("inner interface declaration"); }
777 ;
778
779 /* 19.8.2 Productions from 8.3: Field Declarations */
780 field_declaration:
781 type variable_declarators SC_TK
782 { register_fields (0, $1, $2); }
783 | modifiers type variable_declarators SC_TK
784 {
785 check_modifiers
786 ("Illegal modifier `%s' for field declaration",
787 $1, FIELD_MODIFIERS);
788 check_modifiers_consistency ($1);
789 register_fields ($1, $2, $3);
790 }
791 ;
792
793 variable_declarators:
794 /* Should we use build_decl_list () instead ? FIXME */
795 variable_declarator /* Default rule */
796 | variable_declarators C_TK variable_declarator
797 { $$ = chainon ($1, $3); }
798 | variable_declarators C_TK error
799 {yyerror ("Missing term"); RECOVER;}
800 ;
801
802 variable_declarator:
803 variable_declarator_id
804 { $$ = build_tree_list ($1, NULL_TREE); }
805 | variable_declarator_id ASSIGN_TK variable_initializer
806 {
807 if (java_error_count)
808 $3 = NULL_TREE;
809 $$ = build_tree_list
810 ($1, build_assignment ($2.token, $2.location, $1, $3));
811 }
812 | variable_declarator_id ASSIGN_TK error
813 {
814 yyerror ("Missing variable initializer");
815 $$ = build_tree_list ($1, NULL_TREE);
816 RECOVER;
817 }
818 | variable_declarator_id ASSIGN_TK variable_initializer error
819 {
820 yyerror ("';' expected");
821 $$ = build_tree_list ($1, NULL_TREE);
822 RECOVER;
823 }
824 ;
825
826 variable_declarator_id:
827 identifier
828 | variable_declarator_id OSB_TK CSB_TK
829 { $$ = build_unresolved_array_type ($1); }
830 | identifier error
831 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
832 | variable_declarator_id OSB_TK error
833 {yyerror ("']' expected"); DRECOVER(vdi);}
834 | variable_declarator_id CSB_TK error
835 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
836 ;
837
838 variable_initializer:
839 expression
840 | array_initializer
841 ;
842
843 /* 19.8.3 Productions from 8.4: Method Declarations */
844 method_declaration:
845 method_header
846 {
847 current_function_decl = $1;
848 source_start_java_method (current_function_decl);
849 }
850 method_body
851 { finish_method_declaration ($3); }
852 | method_header error
853 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
854 ;
855
856 method_header:
857 type method_declarator throws
858 { $$ = method_header (0, $1, $2, $3); }
859 | VOID_TK method_declarator throws
860 { $$ = method_header (0, void_type_node, $2, $3); }
861 | modifiers type method_declarator throws
862 { $$ = method_header ($1, $2, $3, $4); }
863 | modifiers VOID_TK method_declarator throws
864 { $$ = method_header ($1, void_type_node, $3, $4); }
865 | type error
866 {RECOVER;}
867 | modifiers type error
868 {RECOVER;}
869 | VOID_TK error
870 {yyerror ("Identifier expected"); RECOVER;}
871 | modifiers VOID_TK error
872 {yyerror ("Identifier expected"); RECOVER;}
873 | modifiers error
874 {
875 yyerror ("Invalid method declaration, return type required");
876 RECOVER;
877 }
878 ;
879
880 method_declarator:
881 identifier OP_TK CP_TK
882 { $$ = method_declarator ($1, NULL_TREE); }
883 | identifier OP_TK formal_parameter_list CP_TK
884 { $$ = method_declarator ($1, $3); }
885 | method_declarator OSB_TK CSB_TK
886 {
887 EXPR_WFL_LINECOL (wfl_operator) = $2.location;
888 TREE_PURPOSE ($1) =
889 build_unresolved_array_type (TREE_PURPOSE ($1));
890 parse_warning_context
891 (wfl_operator,
892 "Discouraged form of returned type specification");
893 }
894 | identifier OP_TK error
895 {yyerror ("')' expected"); DRECOVER(method_declarator);}
896 | method_declarator OSB_TK error
897 {yyerror ("']' expected"); RECOVER;}
898 ;
899
900 formal_parameter_list:
901 formal_parameter
902 {
903 ctxp->formal_parameter_number = 1;
904 }
905 | formal_parameter_list C_TK formal_parameter
906 {
907 ctxp->formal_parameter_number += 1;
908 $$ = chainon ($1, $3);
909 }
910 | formal_parameter_list C_TK error
911 {yyerror ("Missing formal parameter term"); RECOVER;}
912 ;
913
914 formal_parameter:
915 type variable_declarator_id
916 {
917 $$ = build_tree_list ($2, $1);
918 }
919 | modifiers type variable_declarator_id /* Added, JDK1.1 final parms */
920 {
921 parse_jdk1_1_error ("final parameters");
922 $$ = build_tree_list ($3, $2);
923 }
924 | type error
925 {yyerror ("Missing identifier"); RECOVER;}
926 | modifiers type error
927 {
928 SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
929 yyerror ("Missing identifier"); RECOVER;
930 }
931 ;
932
933 throws:
934 { $$ = NULL_TREE; }
935 | THROWS_TK class_type_list
936 { $$ = $2; }
937 | THROWS_TK error
938 {yyerror ("Missing class type term"); RECOVER;}
939 ;
940
941 class_type_list:
942 class_type
943 { $$ = build_tree_list ($1, $1); }
944 | class_type_list C_TK class_type
945 { $$ = tree_cons ($3, $3, $1); }
946 | class_type_list C_TK error
947 {yyerror ("Missing class type term"); RECOVER;}
948 ;
949
950 method_body:
951 block
952 | block SC_TK
953 | SC_TK
954 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
955 ;
956
957 /* 19.8.4 Productions from 8.5: Static Initializers */
958 static_initializer:
959 static block
960 {
961 TREE_CHAIN ($2) = ctxp->static_initialized;
962 ctxp->static_initialized = $2;
963 }
964 | static block SC_TK /* Shouldn't be here. FIXME */
965 {
966 TREE_CHAIN ($2) = ctxp->static_initialized;
967 ctxp->static_initialized = $2;
968 }
969 ;
970
971 static: /* Test lval.sub_token here */
972 MODIFIER_TK
973 {
974 SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
975 }
976 ;
977
978 /* 19.8.5 Productions from 8.6: Constructor Declarations */
979 constructor_declaration:
980 constructor_header
981 {
982 current_function_decl = $1;
983 source_start_java_method (current_function_decl);
984 }
985 constructor_body
986 { finish_method_declaration ($3); }
987 ;
988
989 constructor_header:
990 constructor_declarator throws
991 { $$ = method_header (0, NULL_TREE, $1, $2); }
992 | modifiers constructor_declarator throws
993 { $$ = method_header ($1, NULL_TREE, $2, $3); }
994 ;
995
996 constructor_declarator:
997 simple_name OP_TK CP_TK
998 { $$ = method_declarator ($1, NULL_TREE); }
999 | simple_name OP_TK formal_parameter_list CP_TK
1000 { $$ = method_declarator ($1, $3); }
1001 ;
1002
1003 constructor_body:
1004 /* Unlike regular method, we always need a complete (empty)
1005 body so we can safely perform all the required code
1006 addition (super invocation and field initialization) */
1007 block_begin constructor_block_end
1008 {
1009 BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1010 $$ = $2;
1011 }
1012 | block_begin explicit_constructor_invocation constructor_block_end
1013 { $$ = $3; }
1014 | block_begin block_statements constructor_block_end
1015 { $$ = $3; }
1016 | block_begin explicit_constructor_invocation block_statements constructor_block_end
1017 { $$ = $4; }
1018 ;
1019
1020 constructor_block_end:
1021 block_end
1022 | block_end SC_TK
1023
1024 /* Error recovery for that rule moved down expression_statement: rule. */
1025 explicit_constructor_invocation:
1026 this_or_super OP_TK CP_TK SC_TK
1027 {
1028 $$ = build_method_invocation ($1, NULL_TREE);
1029 $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1030 $$ = java_method_add_stmt (current_function_decl, $$);
1031 }
1032 | this_or_super OP_TK argument_list CP_TK SC_TK
1033 {
1034 $$ = build_method_invocation ($1, $3);
1035 $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1036 $$ = java_method_add_stmt (current_function_decl, $$);
1037 }
1038 /* Added, JDK1.1 inner classes. Modified because the rule
1039 'primary' couldn't work. */
1040 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1041 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1042 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1043 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1044 ;
1045
1046 this_or_super: /* Added, simplifies error diagnostics */
1047 THIS_TK
1048 {
1049 tree wfl = build_wfl_node (this_identifier_node);
1050 EXPR_WFL_LINECOL (wfl) = $1.location;
1051 $$ = wfl;
1052 }
1053 | SUPER_TK
1054 {
1055 tree wfl = build_wfl_node (super_identifier_node);
1056 EXPR_WFL_LINECOL (wfl) = $1.location;
1057 $$ = wfl;
1058 }
1059 ;
1060
1061 /* 19.9 Productions from 9: Interfaces */
1062 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
1063 interface_declaration:
1064 INTERFACE_TK identifier
1065 { create_interface (0, $2, NULL_TREE); }
1066 interface_body
1067 {
1068 $$ = $4;
1069 }
1070 | modifiers INTERFACE_TK identifier
1071 { create_interface ($1, $3, NULL_TREE); }
1072 interface_body
1073 {
1074 $$ = $5;
1075 }
1076 | INTERFACE_TK identifier extends_interfaces
1077 { create_interface (0, $2, $3); }
1078 interface_body
1079 {
1080 $$ = $5;
1081 }
1082 | modifiers INTERFACE_TK identifier extends_interfaces
1083 { create_interface ($1, $3, $4); }
1084 interface_body
1085 {
1086 $$ = $6;
1087 }
1088 | INTERFACE_TK identifier error
1089 {yyerror ("'{' expected"); RECOVER;}
1090 | modifiers INTERFACE_TK identifier error
1091 {yyerror ("'{' expected"); RECOVER;}
1092 ;
1093
1094 extends_interfaces:
1095 EXTENDS_TK interface_type
1096 {
1097 ctxp->interface_number = 1;
1098 $$ = build_tree_list ($2, NULL_TREE);
1099 }
1100 | extends_interfaces C_TK interface_type
1101 {
1102 ctxp->interface_number++;
1103 $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1104 }
1105 | EXTENDS_TK error
1106 {yyerror ("Invalid interface type"); RECOVER;}
1107 | extends_interfaces C_TK error
1108 {yyerror ("Missing term"); RECOVER;}
1109 ;
1110
1111 interface_body:
1112 OCB_TK CCB_TK
1113 { $$ = NULL_TREE; }
1114 | OCB_TK interface_member_declarations CCB_TK
1115 { $$ = NULL_TREE; }
1116 ;
1117
1118 interface_member_declarations:
1119 interface_member_declaration
1120 | interface_member_declarations interface_member_declaration
1121 ;
1122
1123 interface_member_declaration:
1124 constant_declaration
1125 | abstract_method_declaration
1126 | class_declaration /* Added, JDK1.1 inner classes */
1127 { $$ = parse_jdk1_1_error ("inner class declaration"); }
1128 | interface_declaration /* Added, JDK1.1 inner classes */
1129 { $$ = parse_jdk1_1_error ("inner interface declaration"); }
1130 ;
1131
1132 constant_declaration:
1133 field_declaration
1134 ;
1135
1136 abstract_method_declaration:
1137 method_header SC_TK
1138 {
1139 check_abstract_method_header ($1);
1140 current_function_decl = NULL_TREE; /* FIXME ? */
1141 }
1142 | method_header error
1143 {yyerror ("';' expected"); RECOVER;}
1144 ;
1145
1146 /* 19.10 Productions from 10: Arrays */
1147 array_initializer:
1148 OCB_TK CCB_TK
1149 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1150 | OCB_TK variable_initializers CCB_TK
1151 { $$ = build_new_array_init ($1.location, $2); }
1152 | OCB_TK variable_initializers C_TK CCB_TK
1153 { $$ = build_new_array_init ($1.location, $2); }
1154 ;
1155
1156 variable_initializers:
1157 variable_initializer
1158 {
1159 $$ = tree_cons (maybe_build_array_element_wfl ($1),
1160 $1, NULL_TREE);
1161 }
1162 | variable_initializers C_TK variable_initializer
1163 {
1164 $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1165 }
1166 | variable_initializers C_TK error
1167 {yyerror ("Missing term"); RECOVER;}
1168 ;
1169
1170 /* 19.11 Production from 14: Blocks and Statements */
1171 block:
1172 OCB_TK CCB_TK
1173 {
1174 /* Store the location of the `}' when doing xrefs */
1175 if (current_function_decl && flag_emit_xref)
1176 DECL_END_SOURCE_LINE (current_function_decl) =
1177 EXPR_WFL_ADD_COL ($2.location, 1);
1178 $$ = empty_stmt_node;
1179 }
1180 | block_begin block_statements block_end
1181 { $$ = $3; }
1182 ;
1183
1184 block_begin:
1185 OCB_TK
1186 { enter_block (); }
1187 ;
1188
1189 block_end:
1190 CCB_TK
1191 {
1192 maybe_absorb_scoping_blocks ();
1193 /* Store the location of the `}' when doing xrefs */
1194 if (current_function_decl && flag_emit_xref)
1195 DECL_END_SOURCE_LINE (current_function_decl) =
1196 EXPR_WFL_ADD_COL ($1.location, 1);
1197 $$ = exit_block ();
1198 }
1199 ;
1200
1201 block_statements:
1202 block_statement
1203 | block_statements block_statement
1204 ;
1205
1206 block_statement:
1207 local_variable_declaration_statement
1208 | statement
1209 { java_method_add_stmt (current_function_decl, $1); }
1210 | class_declaration /* Added, JDK1.1 inner classes */
1211 { parse_jdk1_1_error ("inner class declaration"); }
1212 ;
1213
1214 local_variable_declaration_statement:
1215 local_variable_declaration SC_TK /* Can't catch missing ';' here */
1216 ;
1217
1218 local_variable_declaration:
1219 type variable_declarators
1220 { declare_local_variables (0, $1, $2); }
1221 | modifiers type variable_declarators /* Added, JDK1.1 final locals */
1222 { declare_local_variables ($1, $2, $3); }
1223 ;
1224
1225 statement:
1226 statement_without_trailing_substatement
1227 | labeled_statement
1228 | if_then_statement
1229 | if_then_else_statement
1230 | while_statement
1231 | for_statement
1232 { $$ = exit_block (); }
1233 ;
1234
1235 statement_nsi:
1236 statement_without_trailing_substatement
1237 | labeled_statement_nsi
1238 | if_then_else_statement_nsi
1239 | while_statement_nsi
1240 | for_statement_nsi
1241 { $$ = exit_block (); }
1242 ;
1243
1244 statement_without_trailing_substatement:
1245 block
1246 | empty_statement
1247 | expression_statement
1248 | switch_statement
1249 | do_statement
1250 | break_statement
1251 | continue_statement
1252 | return_statement
1253 | synchronized_statement
1254 | throw_statement
1255 | try_statement
1256 ;
1257
1258 empty_statement:
1259 SC_TK
1260 { $$ = empty_stmt_node; }
1261 ;
1262
1263 label_decl:
1264 identifier REL_CL_TK
1265 {
1266 $$ = build_labeled_block (EXPR_WFL_LINECOL ($1),
1267 EXPR_WFL_NODE ($1));
1268 pushlevel (2);
1269 push_labeled_block ($$);
1270 PUSH_LABELED_BLOCK ($$);
1271 }
1272 ;
1273
1274 labeled_statement:
1275 label_decl statement
1276 { $$ = finish_labeled_statement ($1, $2); }
1277 | identifier error
1278 {yyerror ("':' expected"); RECOVER;}
1279 ;
1280
1281 labeled_statement_nsi:
1282 label_decl statement_nsi
1283 { $$ = finish_labeled_statement ($1, $2); }
1284 ;
1285
1286 /* We concentrate here a bunch of error handling rules that we couldn't write
1287 earlier, because expression_statement catches a missing ';'. */
1288 expression_statement:
1289 statement_expression SC_TK
1290 {
1291 /* We have a statement. Generate a WFL around it so
1292 we can debug it */
1293 $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1294 /* We know we have a statement, so set the debug
1295 info to be eventually generate here. */
1296 $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1297 }
1298 | error SC_TK
1299 {
1300 if (ctxp->prevent_ese != lineno)
1301 yyerror ("Invalid expression statement");
1302 DRECOVER (expr_stmt);
1303 }
1304 | error OCB_TK
1305 {
1306 if (ctxp->prevent_ese != lineno)
1307 yyerror ("Invalid expression statement");
1308 DRECOVER (expr_stmt);
1309 }
1310 | error CCB_TK
1311 {
1312 if (ctxp->prevent_ese != lineno)
1313 yyerror ("Invalid expression statement");
1314 DRECOVER (expr_stmt);
1315 }
1316 | this_or_super OP_TK error
1317 {yyerror ("')' expected"); RECOVER;}
1318 | this_or_super OP_TK CP_TK error
1319 {
1320 yyerror ("Constructor invocation must be first "
1321 "thing in a constructor");
1322 RECOVER;
1323 }
1324 | this_or_super OP_TK argument_list error
1325 {yyerror ("')' expected"); RECOVER;}
1326 | this_or_super OP_TK argument_list CP_TK error
1327 {
1328 yyerror ("Constructor invocation must be first "
1329 "thing in a constructor");
1330 RECOVER;
1331 }
1332 | name DOT_TK SUPER_TK error
1333 {yyerror ("'(' expected"); RECOVER;}
1334 | name DOT_TK SUPER_TK OP_TK error
1335 {yyerror ("')' expected"); RECOVER;}
1336 | name DOT_TK SUPER_TK OP_TK argument_list error
1337 {yyerror ("')' expected"); RECOVER;}
1338 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1339 {yyerror ("';' expected"); RECOVER;}
1340 | name DOT_TK SUPER_TK OP_TK CP_TK error
1341 {yyerror ("';' expected"); RECOVER;}
1342 ;
1343
1344 statement_expression:
1345 assignment
1346 | pre_increment_expression
1347 | pre_decrement_expression
1348 | post_increment_expression
1349 | post_decrement_expression
1350 | method_invocation
1351 | class_instance_creation_expression
1352 ;
1353
1354 if_then_statement:
1355 IF_TK OP_TK expression CP_TK statement
1356 {
1357 $$ = build_if_else_statement ($2.location, $3,
1358 $5, NULL_TREE);
1359 }
1360 | IF_TK error
1361 {yyerror ("'(' expected"); RECOVER;}
1362 | IF_TK OP_TK error
1363 {yyerror ("Missing term"); RECOVER;}
1364 | IF_TK OP_TK expression error
1365 {yyerror ("')' expected"); RECOVER;}
1366 ;
1367
1368 if_then_else_statement:
1369 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1370 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1371 ;
1372
1373 if_then_else_statement_nsi:
1374 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1375 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1376 ;
1377
1378 switch_statement:
1379 switch_expression
1380 {
1381 enter_block ();
1382 }
1383 switch_block
1384 {
1385 /* Make into "proper list" of COMPOUND_EXPRs.
1386 I.e. make the last statment also have its own
1387 COMPOUND_EXPR. */
1388 maybe_absorb_scoping_blocks ();
1389 TREE_OPERAND ($1, 1) = exit_block ();
1390 $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1391 }
1392 ;
1393
1394 switch_expression:
1395 SWITCH_TK OP_TK expression CP_TK
1396 {
1397 $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1398 EXPR_WFL_LINECOL ($$) = $2.location;
1399 }
1400 | SWITCH_TK error
1401 {yyerror ("'(' expected"); RECOVER;}
1402 | SWITCH_TK OP_TK error
1403 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1404 | SWITCH_TK OP_TK expression CP_TK error
1405 {yyerror ("'{' expected"); RECOVER;}
1406 ;
1407
1408 /* Default assignment is there to avoid type node on switch_block
1409 node. */
1410
1411 switch_block:
1412 OCB_TK CCB_TK
1413 { $$ = NULL_TREE; }
1414 | OCB_TK switch_labels CCB_TK
1415 { $$ = NULL_TREE; }
1416 | OCB_TK switch_block_statement_groups CCB_TK
1417 { $$ = NULL_TREE; }
1418 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
1419 { $$ = NULL_TREE; }
1420 ;
1421
1422 switch_block_statement_groups:
1423 switch_block_statement_group
1424 | switch_block_statement_groups switch_block_statement_group
1425 ;
1426
1427 switch_block_statement_group:
1428 switch_labels block_statements
1429 ;
1430
1431 switch_labels:
1432 switch_label
1433 | switch_labels switch_label
1434 ;
1435
1436 switch_label:
1437 CASE_TK constant_expression REL_CL_TK
1438 {
1439 tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1440 EXPR_WFL_LINECOL (lab) = $1.location;
1441 java_method_add_stmt (current_function_decl, lab);
1442 }
1443 | DEFAULT_TK REL_CL_TK
1444 {
1445 tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1446 EXPR_WFL_LINECOL (lab) = $1.location;
1447 java_method_add_stmt (current_function_decl, lab);
1448 }
1449 | CASE_TK error
1450 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1451 | CASE_TK constant_expression error
1452 {yyerror ("':' expected"); RECOVER;}
1453 | DEFAULT_TK error
1454 {yyerror ("':' expected"); RECOVER;}
1455 ;
1456
1457 while_expression:
1458 WHILE_TK OP_TK expression CP_TK
1459 {
1460 tree body = build_loop_body ($2.location, $3, 0);
1461 $$ = build_new_loop (body);
1462 }
1463 ;
1464
1465 while_statement:
1466 while_expression statement
1467 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1468 | WHILE_TK error
1469 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1470 | WHILE_TK OP_TK error
1471 {yyerror ("Missing term and ')' expected"); RECOVER;}
1472 | WHILE_TK OP_TK expression error
1473 {yyerror ("')' expected"); RECOVER;}
1474 ;
1475
1476 while_statement_nsi:
1477 while_expression statement_nsi
1478 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1479 ;
1480
1481 do_statement_begin:
1482 DO_TK
1483 {
1484 tree body = build_loop_body (0, NULL_TREE, 1);
1485 $$ = build_new_loop (body);
1486 }
1487 /* Need error handing here. FIXME */
1488 ;
1489
1490 do_statement:
1491 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1492 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1493 ;
1494
1495 for_statement:
1496 for_begin SC_TK expression SC_TK for_update CP_TK statement
1497 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7); }
1498 | for_begin SC_TK SC_TK for_update CP_TK statement
1499 {
1500 $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1501 /* We have not condition, so we get rid of the EXIT_EXPR */
1502 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
1503 empty_stmt_node;
1504 }
1505 | for_begin SC_TK error
1506 {yyerror ("Invalid control expression"); RECOVER;}
1507 | for_begin SC_TK expression SC_TK error
1508 {yyerror ("Invalid update expression"); RECOVER;}
1509 | for_begin SC_TK SC_TK error
1510 {yyerror ("Invalid update expression"); RECOVER;}
1511 ;
1512
1513 for_statement_nsi:
1514 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1515 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1516 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1517 {
1518 $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1519 /* We have not condition, so we get rid of the EXIT_EXPR */
1520 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
1521 empty_stmt_node;
1522 }
1523 ;
1524
1525 for_header:
1526 FOR_TK OP_TK
1527 {
1528 /* This scope defined for local variable that may be
1529 defined within the scope of the for loop */
1530 enter_block ();
1531 }
1532 | FOR_TK error
1533 {yyerror ("'(' expected"); DRECOVER(for_1);}
1534 | FOR_TK OP_TK error
1535 {yyerror ("Invalid init statement"); RECOVER;}
1536 ;
1537
1538 for_begin:
1539 for_header for_init
1540 {
1541 /* We now declare the loop body. The loop is
1542 declared as a for loop. */
1543 tree body = build_loop_body (0, NULL_TREE, 0);
1544 $$ = build_new_loop (body);
1545 IS_FOR_LOOP_P ($$) = 1;
1546 /* The loop is added to the current block the for
1547 statement is defined within */
1548 java_method_add_stmt (current_function_decl, $$);
1549 }
1550 ;
1551 for_init: /* Can be empty */
1552 { $$ = empty_stmt_node; }
1553 | statement_expression_list
1554 {
1555 /* Init statement recorded within the previously
1556 defined block scope */
1557 $$ = java_method_add_stmt (current_function_decl, $1);
1558 }
1559 | local_variable_declaration
1560 {
1561 /* Local variable are recorded within the previously
1562 defined block scope */
1563 $$ = NULL_TREE;
1564 }
1565 | statement_expression_list error
1566 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1567 ;
1568
1569 for_update: /* Can be empty */
1570 {$$ = empty_stmt_node;}
1571 | statement_expression_list
1572 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1573 ;
1574
1575 statement_expression_list:
1576 statement_expression
1577 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1578 | statement_expression_list C_TK statement_expression
1579 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1580 | statement_expression_list C_TK error
1581 {yyerror ("Missing term"); RECOVER;}
1582 ;
1583
1584 break_statement:
1585 BREAK_TK SC_TK
1586 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1587 | BREAK_TK identifier SC_TK
1588 { $$ = build_bc_statement ($1.location, 1, $2); }
1589 | BREAK_TK error
1590 {yyerror ("Missing term"); RECOVER;}
1591 | BREAK_TK identifier error
1592 {yyerror ("';' expected"); RECOVER;}
1593 ;
1594
1595 continue_statement:
1596 CONTINUE_TK SC_TK
1597 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1598 | CONTINUE_TK identifier SC_TK
1599 { $$ = build_bc_statement ($1.location, 0, $2); }
1600 | CONTINUE_TK error
1601 {yyerror ("Missing term"); RECOVER;}
1602 | CONTINUE_TK identifier error
1603 {yyerror ("';' expected"); RECOVER;}
1604 ;
1605
1606 return_statement:
1607 RETURN_TK SC_TK
1608 { $$ = build_return ($1.location, NULL_TREE); }
1609 | RETURN_TK expression SC_TK
1610 { $$ = build_return ($1.location, $2); }
1611 | RETURN_TK error
1612 {yyerror ("Missing term"); RECOVER;}
1613 | RETURN_TK expression error
1614 {yyerror ("';' expected"); RECOVER;}
1615 ;
1616
1617 throw_statement:
1618 THROW_TK expression SC_TK
1619 {
1620 $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1621 EXPR_WFL_LINECOL ($$) = $1.location;
1622 }
1623 | THROW_TK error
1624 {yyerror ("Missing term"); RECOVER;}
1625 | THROW_TK expression error
1626 {yyerror ("';' expected"); RECOVER;}
1627 ;
1628
1629 synchronized_statement:
1630 synchronized OP_TK expression CP_TK block
1631 {
1632 $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1633 EXPR_WFL_LINECOL ($$) =
1634 EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1635 }
1636 | synchronized OP_TK expression CP_TK error
1637 {yyerror ("'{' expected"); RECOVER;}
1638 | synchronized error
1639 {yyerror ("'(' expected"); RECOVER;}
1640 | synchronized OP_TK error CP_TK
1641 {yyerror ("Missing term"); RECOVER;}
1642 | synchronized OP_TK error
1643 {yyerror ("Missing term"); RECOVER;}
1644 ;
1645
1646 synchronized:
1647 MODIFIER_TK
1648 {
1649 if ((1 << $1) != ACC_SYNCHRONIZED)
1650 fatal ("synchronized was '%d' - yyparse", (1 << $1));
1651 }
1652 ;
1653
1654 try_statement:
1655 TRY_TK block catches
1656 { $$ = build_try_statement ($1.location, $2, $3); }
1657 | TRY_TK block finally
1658 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1659 | TRY_TK block catches finally
1660 { $$ = build_try_finally_statement
1661 ($1.location, build_try_statement ($1.location,
1662 $2, $3), $4);
1663 }
1664 | TRY_TK error
1665 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1666 ;
1667
1668 catches:
1669 catch_clause
1670 | catches catch_clause
1671 {
1672 TREE_CHAIN ($2) = $1;
1673 $$ = $2;
1674 }
1675 ;
1676
1677 catch_clause:
1678 catch_clause_parameter block
1679 {
1680 java_method_add_stmt (current_function_decl, $2);
1681 exit_block ();
1682 $$ = $1;
1683 }
1684
1685 catch_clause_parameter:
1686 CATCH_TK OP_TK formal_parameter CP_TK
1687 {
1688 /* We add a block to define a scope for
1689 formal_parameter (CCBP). The formal parameter is
1690 declared initialized by the appropriate function
1691 call */
1692 tree ccpb = enter_block ();
1693 tree init = build_assignment (ASSIGN_TK, $2.location,
1694 TREE_PURPOSE ($3),
1695 soft_exceptioninfo_call_node);
1696 declare_local_variables (0, TREE_VALUE ($3),
1697 build_tree_list (TREE_PURPOSE ($3),
1698 init));
1699 $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1700 EXPR_WFL_LINECOL ($$) = $1.location;
1701 }
1702 | CATCH_TK error
1703 {yyerror ("'(' expected"); RECOVER;}
1704 | CATCH_TK OP_TK error
1705 {yyerror ("Missing term or ')' expected"); DRECOVER (2);}
1706 | CATCH_TK OP_TK error CP_TK /* That's for () */
1707 {yyerror ("')' expected"); DRECOVER (1);}
1708 ;
1709
1710 finally:
1711 FINALLY_TK block
1712 { $$ = $2; }
1713 | FINALLY_TK error
1714 {yyerror ("'{' expected"); RECOVER; }
1715 ;
1716
1717 /* 19.12 Production from 15: Expressions */
1718 primary:
1719 primary_no_new_array
1720 | array_creation_expression
1721 ;
1722
1723 primary_no_new_array:
1724 literal
1725 | THIS_TK
1726 { $$ = build_this ($1.location); }
1727 | OP_TK expression CP_TK
1728 {$$ = $2;}
1729 | class_instance_creation_expression
1730 | field_access
1731 | method_invocation
1732 | array_access
1733 /* type DOT_TK CLASS_TK doens't work. So we split the rule
1734 'type' into its components. Missing is something for array,
1735 which will complete the reference_type part. FIXME */
1736 | name DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
1737 { $$ = parse_jdk1_1_error ("named class literals"); }
1738 | primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
1739 { $$ = build_class_ref ($1); }
1740 | VOID_TK DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
1741 { $$ = build_class_ref (void_type_node); }
1742 /* Added, JDK1.1 inner classes. Documentation is wrong
1743 refering to a 'ClassName' (class_name) rule that doesn't
1744 exist. Used name instead. */
1745 | name DOT_TK THIS_TK
1746 { $$ = parse_jdk1_1_error ("class literals"); }
1747 | OP_TK expression error
1748 {yyerror ("')' expected"); RECOVER;}
1749 | name DOT_TK error
1750 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1751 | primitive_type DOT_TK error
1752 {yyerror ("'class' expected" ); RECOVER;}
1753 | VOID_TK DOT_TK error
1754 {yyerror ("'class' expected" ); RECOVER;}
1755 ;
1756
1757 class_instance_creation_expression:
1758 NEW_TK class_type OP_TK argument_list CP_TK
1759 { $$ = build_new_invocation ($2, $4); }
1760 | NEW_TK class_type OP_TK CP_TK
1761 { $$ = build_new_invocation ($2, NULL_TREE); }
1762 /* Added, JDK1.1 inner classes but modified to use
1763 'class_type' instead of 'TypeName' (type_name) mentionned
1764 in the documentation but doesn't exist. */
1765 | NEW_TK class_type OP_TK argument_list CP_TK class_body
1766 { $$ = parse_jdk1_1_error ("inner class instance creation"); }
1767 | NEW_TK class_type OP_TK CP_TK class_body
1768 { $$ = parse_jdk1_1_error ("inner class instance creation"); }
1769 /* Added, JDK1.1 inner classes, modified to use name or
1770 primary instead of primary solely which couldn't work in
1771 all situations. */
1772 | something_dot_new identifier OP_TK CP_TK
1773 | something_dot_new identifier OP_TK CP_TK class_body
1774 | something_dot_new identifier OP_TK argument_list CP_TK
1775 | something_dot_new identifier OP_TK argument_list CP_TK class_body
1776 | NEW_TK error SC_TK
1777 {yyerror ("'(' expected"); DRECOVER(new_1);}
1778 | NEW_TK class_type error
1779 {yyerror ("'(' expected"); RECOVER;}
1780 | NEW_TK class_type OP_TK error
1781 {yyerror ("')' or term expected"); RECOVER;}
1782 | NEW_TK class_type OP_TK argument_list error
1783 {yyerror ("')' expected"); RECOVER;}
1784 | something_dot_new error
1785 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1786 | something_dot_new identifier error
1787 {yyerror ("'(' expected"); RECOVER;}
1788 ;
1789
1790 something_dot_new: /* Added, not part of the specs. */
1791 name DOT_TK NEW_TK
1792 | primary DOT_TK NEW_TK
1793 ;
1794
1795 argument_list:
1796 expression
1797 {
1798 $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
1799 ctxp->formal_parameter_number = 1;
1800 }
1801 | argument_list C_TK expression
1802 {
1803 ctxp->formal_parameter_number += 1;
1804 $$ = tree_cons (NULL_TREE, $3, $1);
1805 }
1806 | argument_list C_TK error
1807 {yyerror ("Missing term"); RECOVER;}
1808 ;
1809
1810 array_creation_expression:
1811 NEW_TK primitive_type dim_exprs
1812 { $$ = build_newarray_node ($2, $3, 0); }
1813 | NEW_TK class_or_interface_type dim_exprs
1814 { $$ = build_newarray_node ($2, $3, 0); }
1815 | NEW_TK primitive_type dim_exprs dims
1816 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
1817 | NEW_TK class_or_interface_type dim_exprs dims
1818 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
1819 /* Added, JDK1.1 anonymous array. Initial documentation rule
1820 modified */
1821 | NEW_TK class_or_interface_type dims array_initializer
1822 { $$ = parse_jdk1_1_error ("anonymous array"); }
1823 | NEW_TK primitive_type dims array_initializer
1824 { $$ = parse_jdk1_1_error ("anonymous array"); }
1825 | NEW_TK error CSB_TK
1826 {yyerror ("'[' expected"); DRECOVER ("]");}
1827 | NEW_TK error OSB_TK
1828 {yyerror ("']' expected"); RECOVER;}
1829 ;
1830
1831 dim_exprs:
1832 dim_expr
1833 { $$ = build_tree_list (NULL_TREE, $1); }
1834 | dim_exprs dim_expr
1835 { $$ = tree_cons (NULL_TREE, $2, $$); }
1836 ;
1837
1838 dim_expr:
1839 OSB_TK expression CSB_TK
1840 {
1841 EXPR_WFL_LINECOL ($2) = $1.location;
1842 $$ = $2;
1843 }
1844 | OSB_TK expression error
1845 {yyerror ("']' expected"); RECOVER;}
1846 | OSB_TK error
1847 {
1848 yyerror ("Missing term");
1849 yyerror ("']' expected");
1850 RECOVER;
1851 }
1852 ;
1853
1854 dims:
1855 OSB_TK CSB_TK
1856 {
1857 int allocate = 0;
1858 /* If not initialized, allocate memory for the osb
1859 numbers stack */
1860 if (!ctxp->osb_limit)
1861 {
1862 allocate = ctxp->osb_limit = 32;
1863 ctxp->osb_depth = -1;
1864 }
1865 /* If capacity overflown, reallocate a bigger chuck */
1866 else if (ctxp->osb_depth+1 == ctxp->osb_limit)
1867 allocate = ctxp->osb_limit << 1;
1868
1869 if (allocate)
1870 {
1871 allocate *= sizeof (int);
1872 if (ctxp->osb_number)
1873 ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
1874 allocate);
1875 else
1876 ctxp->osb_number = (int *)xmalloc (allocate);
1877 }
1878 ctxp->osb_depth++;
1879 CURRENT_OSB (ctxp) = 1;
1880 }
1881 | dims OSB_TK CSB_TK
1882 { CURRENT_OSB (ctxp)++; }
1883 | dims OSB_TK error
1884 { yyerror ("']' expected"); RECOVER;}
1885 ;
1886
1887 field_access:
1888 primary DOT_TK identifier
1889 { $$ = make_qualified_primary ($1, $3, $2.location); }
1890 /* FIXME - REWRITE TO:
1891 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
1892 | SUPER_TK DOT_TK identifier
1893 {
1894 tree super_wfl =
1895 build_wfl_node (super_identifier_node);
1896 EXPR_WFL_LINECOL (super_wfl) = $1.location;
1897 $$ = make_qualified_name (super_wfl, $3, $2.location);
1898 }
1899 | SUPER_TK error
1900 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
1901 ;
1902
1903 method_invocation:
1904 name OP_TK CP_TK
1905 { $$ = build_method_invocation ($1, NULL_TREE); }
1906 | name OP_TK argument_list CP_TK
1907 { $$ = build_method_invocation ($1, $3); }
1908 | primary DOT_TK identifier OP_TK CP_TK
1909 {
1910 if (TREE_CODE ($1) == THIS_EXPR)
1911 $$ = build_this_super_qualified_invocation
1912 (1, $3, NULL_TREE, 0, $2.location);
1913 else
1914 {
1915 tree invok = build_method_invocation ($3, NULL_TREE);
1916 $$ = make_qualified_primary ($1, invok, $2.location);
1917 }
1918 }
1919 | primary DOT_TK identifier OP_TK argument_list CP_TK
1920 {
1921 if (TREE_CODE ($1) == THIS_EXPR)
1922 $$ = build_this_super_qualified_invocation
1923 (1, $3, $5, 0, $2.location);
1924 else
1925 {
1926 tree invok = build_method_invocation ($3, $5);
1927 $$ = make_qualified_primary ($1, invok, $2.location);
1928 }
1929 }
1930 | SUPER_TK DOT_TK identifier OP_TK CP_TK
1931 {
1932 $$ = build_this_super_qualified_invocation
1933 (0, $3, NULL_TREE, $1.location, $2.location);
1934 }
1935 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
1936 {
1937 $$ = build_this_super_qualified_invocation
1938 (0, $3, $5, $1.location, $2.location);
1939 }
1940 /* Screws up thing. I let it here until I'm convinced it can
1941 be removed. FIXME
1942 | primary DOT_TK error
1943 {yyerror ("'(' expected"); DRECOVER(bad);} */
1944 | SUPER_TK DOT_TK error CP_TK
1945 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
1946 | SUPER_TK DOT_TK error DOT_TK
1947 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
1948 ;
1949
1950 array_access:
1951 name OSB_TK expression CSB_TK
1952 { $$ = build_array_ref ($2.location, $1, $3); }
1953 | primary_no_new_array OSB_TK expression CSB_TK
1954 { $$ = build_array_ref ($2.location, $1, $3); }
1955 | name OSB_TK error
1956 {
1957 yyerror ("Missing term and ']' expected");
1958 DRECOVER(array_access);
1959 }
1960 | name OSB_TK expression error
1961 {
1962 yyerror ("']' expected");
1963 DRECOVER(array_access);
1964 }
1965 | primary_no_new_array OSB_TK error
1966 {
1967 yyerror ("Missing term and ']' expected");
1968 DRECOVER(array_access);
1969 }
1970 | primary_no_new_array OSB_TK expression error
1971 {
1972 yyerror ("']' expected");
1973 DRECOVER(array_access);
1974 }
1975 ;
1976
1977 postfix_expression:
1978 primary
1979 | name
1980 | post_increment_expression
1981 | post_decrement_expression
1982 ;
1983
1984 post_increment_expression:
1985 postfix_expression INCR_TK
1986 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
1987 ;
1988
1989 post_decrement_expression:
1990 postfix_expression DECR_TK
1991 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
1992 ;
1993
1994 unary_expression:
1995 pre_increment_expression
1996 | pre_decrement_expression
1997 | PLUS_TK unary_expression
1998 {$$ = build_unaryop ($1.token, $1.location, $2); }
1999 | MINUS_TK unary_expression
2000 {$$ = build_unaryop ($1.token, $1.location, $2); }
2001 | unary_expression_not_plus_minus
2002 | PLUS_TK error
2003 {yyerror ("Missing term"); RECOVER}
2004 | MINUS_TK error
2005 {yyerror ("Missing term"); RECOVER}
2006 ;
2007
2008 pre_increment_expression:
2009 INCR_TK unary_expression
2010 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2011 | INCR_TK error
2012 {yyerror ("Missing term"); RECOVER}
2013 ;
2014
2015 pre_decrement_expression:
2016 DECR_TK unary_expression
2017 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2018 | DECR_TK error
2019 {yyerror ("Missing term"); RECOVER}
2020 ;
2021
2022 unary_expression_not_plus_minus:
2023 postfix_expression
2024 | NOT_TK unary_expression
2025 {$$ = build_unaryop ($1.token, $1.location, $2); }
2026 | NEG_TK unary_expression
2027 {$$ = build_unaryop ($1.token, $1.location, $2); }
2028 | cast_expression
2029 | NOT_TK error
2030 {yyerror ("Missing term"); RECOVER}
2031 | NEG_TK error
2032 {yyerror ("Missing term"); RECOVER}
2033 ;
2034
2035 cast_expression: /* Error handling here is potentially weak */
2036 OP_TK primitive_type dims CP_TK unary_expression
2037 {
2038 tree type = $2;
2039 while (CURRENT_OSB (ctxp)--)
2040 type = build_java_array_type (type, -1);
2041 ctxp->osb_depth--;
2042 $$ = build_cast ($1.location, type, $5);
2043 }
2044 | OP_TK primitive_type CP_TK unary_expression
2045 { $$ = build_cast ($1.location, $2, $4); }
2046 | OP_TK expression CP_TK unary_expression_not_plus_minus
2047 { $$ = build_cast ($1.location, $2, $4); }
2048 | OP_TK name dims CP_TK unary_expression_not_plus_minus
2049 {
2050 char *ptr;
2051 while (CURRENT_OSB (ctxp)--)
2052 obstack_1grow (&temporary_obstack, '[');
2053 ctxp->osb_depth--;
2054 obstack_grow0 (&temporary_obstack,
2055 IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2056 IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2057 ptr = obstack_finish (&temporary_obstack);
2058 EXPR_WFL_NODE ($2) = get_identifier (ptr);
2059 $$ = build_cast ($1.location, $2, $5);
2060 }
2061 | OP_TK primitive_type OSB_TK error
2062 {yyerror ("']' expected, invalid type expression");}
2063 | OP_TK error
2064 {
2065 if (ctxp->prevent_ese != lineno)
2066 yyerror ("Invalid type expression"); RECOVER;
2067 RECOVER;
2068 }
2069 | OP_TK primitive_type dims CP_TK error
2070 {yyerror ("Missing term"); RECOVER;}
2071 | OP_TK primitive_type CP_TK error
2072 {yyerror ("Missing term"); RECOVER;}
2073 | OP_TK name dims CP_TK error
2074 {yyerror ("Missing term"); RECOVER;}
2075 ;
2076
2077 multiplicative_expression:
2078 unary_expression
2079 | multiplicative_expression MULT_TK unary_expression
2080 {
2081 $$ = build_binop (BINOP_LOOKUP ($2.token),
2082 $2.location, $1, $3);
2083 }
2084 | multiplicative_expression DIV_TK unary_expression
2085 {
2086 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2087 $1, $3);
2088 }
2089 | multiplicative_expression REM_TK unary_expression
2090 {
2091 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2092 $1, $3);
2093 }
2094 | multiplicative_expression MULT_TK error
2095 {yyerror ("Missing term"); RECOVER;}
2096 | multiplicative_expression DIV_TK error
2097 {yyerror ("Missing term"); RECOVER;}
2098 | multiplicative_expression REM_TK error
2099 {yyerror ("Missing term"); RECOVER;}
2100 ;
2101
2102 additive_expression:
2103 multiplicative_expression
2104 | additive_expression PLUS_TK multiplicative_expression
2105 {
2106 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2107 $1, $3);
2108 }
2109 | additive_expression MINUS_TK multiplicative_expression
2110 {
2111 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2112 $1, $3);
2113 }
2114 | additive_expression PLUS_TK error
2115 {yyerror ("Missing term"); RECOVER;}
2116 | additive_expression MINUS_TK error
2117 {yyerror ("Missing term"); RECOVER;}
2118 ;
2119
2120 shift_expression:
2121 additive_expression
2122 | shift_expression LS_TK additive_expression
2123 {
2124 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2125 $1, $3);
2126 }
2127 | shift_expression SRS_TK additive_expression
2128 {
2129 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2130 $1, $3);
2131 }
2132 | shift_expression ZRS_TK additive_expression
2133 {
2134 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2135 $1, $3);
2136 }
2137 | shift_expression LS_TK error
2138 {yyerror ("Missing term"); RECOVER;}
2139 | shift_expression SRS_TK error
2140 {yyerror ("Missing term"); RECOVER;}
2141 | shift_expression ZRS_TK error
2142 {yyerror ("Missing term"); RECOVER;}
2143 ;
2144
2145 relational_expression:
2146 shift_expression
2147 | relational_expression LT_TK shift_expression
2148 {
2149 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2150 $1, $3);
2151 }
2152 | relational_expression GT_TK shift_expression
2153 {
2154 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2155 $1, $3);
2156 }
2157 | relational_expression LTE_TK shift_expression
2158 {
2159 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2160 $1, $3);
2161 }
2162 | relational_expression GTE_TK shift_expression
2163 {
2164 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2165 $1, $3);
2166 }
2167 | relational_expression INSTANCEOF_TK reference_type
2168 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2169 | relational_expression LT_TK error
2170 {yyerror ("Missing term"); RECOVER;}
2171 | relational_expression GT_TK error
2172 {yyerror ("Missing term"); RECOVER;}
2173 | relational_expression LTE_TK error
2174 {yyerror ("Missing term"); RECOVER;}
2175 | relational_expression GTE_TK error
2176 {yyerror ("Missing term"); RECOVER;}
2177 | relational_expression INSTANCEOF_TK error
2178 {yyerror ("Invalid reference type"); RECOVER;}
2179 ;
2180
2181 equality_expression:
2182 relational_expression
2183 | equality_expression EQ_TK relational_expression
2184 {
2185 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2186 $1, $3);
2187 }
2188 | equality_expression NEQ_TK relational_expression
2189 {
2190 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2191 $1, $3);
2192 }
2193 | equality_expression EQ_TK error
2194 {yyerror ("Missing term"); RECOVER;}
2195 | equality_expression NEQ_TK error
2196 {yyerror ("Missing term"); RECOVER;}
2197 ;
2198
2199 and_expression:
2200 equality_expression
2201 | and_expression AND_TK equality_expression
2202 {
2203 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2204 $1, $3);
2205 }
2206 | and_expression AND_TK error
2207 {yyerror ("Missing term"); RECOVER;}
2208 ;
2209
2210 exclusive_or_expression:
2211 and_expression
2212 | exclusive_or_expression XOR_TK and_expression
2213 {
2214 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2215 $1, $3);
2216 }
2217 | exclusive_or_expression XOR_TK error
2218 {yyerror ("Missing term"); RECOVER;}
2219 ;
2220
2221 inclusive_or_expression:
2222 exclusive_or_expression
2223 | inclusive_or_expression OR_TK exclusive_or_expression
2224 {
2225 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2226 $1, $3);
2227 }
2228 | inclusive_or_expression OR_TK error
2229 {yyerror ("Missing term"); RECOVER;}
2230 ;
2231
2232 conditional_and_expression:
2233 inclusive_or_expression
2234 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
2235 {
2236 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2237 $1, $3);
2238 }
2239 | conditional_and_expression BOOL_AND_TK error
2240 {yyerror ("Missing term"); RECOVER;}
2241 ;
2242
2243 conditional_or_expression:
2244 conditional_and_expression
2245 | conditional_or_expression BOOL_OR_TK conditional_and_expression
2246 {
2247 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2248 $1, $3);
2249 }
2250 | conditional_or_expression BOOL_OR_TK error
2251 {yyerror ("Missing term"); RECOVER;}
2252 ;
2253
2254 conditional_expression: /* Error handling here is weak */
2255 conditional_or_expression
2256 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2257 {
2258 $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2259 EXPR_WFL_LINECOL ($$) = $2.location;
2260 }
2261 | conditional_or_expression REL_QM_TK REL_CL_TK error
2262 {
2263 YYERROR_NOW;
2264 yyerror ("Missing term");
2265 DRECOVER (1);
2266 }
2267 | conditional_or_expression REL_QM_TK error
2268 {yyerror ("Missing term"); DRECOVER (2);}
2269 | conditional_or_expression REL_QM_TK expression REL_CL_TK error
2270 {yyerror ("Missing term"); DRECOVER (3);}
2271 ;
2272
2273 assignment_expression:
2274 conditional_expression
2275 | assignment
2276 ;
2277
2278 assignment:
2279 left_hand_side assignment_operator assignment_expression
2280 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2281 | left_hand_side assignment_operator error
2282 {
2283 if (ctxp->prevent_ese != lineno)
2284 yyerror ("Missing term");
2285 DRECOVER (assign);
2286 }
2287 ;
2288
2289 left_hand_side:
2290 name
2291 | field_access
2292 | array_access
2293 ;
2294
2295 assignment_operator:
2296 ASSIGN_ANY_TK
2297 | ASSIGN_TK
2298 ;
2299
2300 expression:
2301 assignment_expression
2302 ;
2303
2304 constant_expression:
2305 expression
2306 ;
2307
2308 %%
2309 \f
2310
2311 /* Flag for the error report routine to issue the error the first time
2312 it's called (overriding the default behavior which is to drop the
2313 first invocation and honor the second one, taking advantage of a
2314 richer context. */
2315 static int force_error = 0;
2316
2317 /* Create a new parser context and make it the current one. */
2318
2319 void
2320 java_push_parser_context ()
2321 {
2322 struct parser_ctxt *new =
2323 (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2324
2325 bzero ((PTR) new, sizeof (struct parser_ctxt));
2326 new->next = ctxp;
2327 ctxp = new;
2328 if (ctxp->next)
2329 {
2330 ctxp->incomplete_class = ctxp->next->incomplete_class;
2331 ctxp->gclass_list = ctxp->next->gclass_list;
2332 }
2333 }
2334
2335 /* If the first file of a file list was a class file, no context
2336 exists for a source file to be parsed. This boolean remembers that
2337 java_parser_context_save_global might have created a dummy one, so
2338 that java_parser_context_restore_global can pop it. */
2339 static int extra_ctxp_pushed_p = 0;
2340
2341 void
2342 java_parser_context_save_global ()
2343 {
2344 if (!ctxp)
2345 {
2346 java_push_parser_context ();
2347 extra_ctxp_pushed_p = 1;
2348 }
2349 ctxp->finput = finput;
2350 ctxp->lineno = lineno;
2351 ctxp->current_class = current_class;
2352 ctxp->filename = input_filename;
2353 ctxp->current_function_decl = current_function_decl;
2354 }
2355
2356 void
2357 java_parser_context_restore_global ()
2358 {
2359 finput = ctxp->finput;
2360 lineno = ctxp->lineno;
2361 current_class = ctxp->current_class;
2362 input_filename = ctxp->filename;
2363 current_function_decl = ctxp->current_function_decl;
2364 if (!ctxp->next && extra_ctxp_pushed_p)
2365 {
2366 java_pop_parser_context (0);
2367 extra_ctxp_pushed_p = 0;
2368 }
2369 }
2370
2371 void
2372 java_pop_parser_context (generate)
2373 int generate;
2374 {
2375 tree current;
2376 struct parser_ctxt *toFree, *next;
2377
2378 if (!ctxp)
2379 return;
2380
2381 toFree = ctxp;
2382 next = ctxp->next;
2383 if (next)
2384 {
2385 next->incomplete_class = ctxp->incomplete_class;
2386 next->gclass_list = ctxp->gclass_list;
2387 lineno = ctxp->lineno;
2388 finput = ctxp->finput;
2389 current_class = ctxp->current_class;
2390 }
2391
2392 /* Set the single import class file flag to 0 for the current list
2393 of imported things */
2394 for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2395 IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2396
2397 /* And restore those of the previous context */
2398 if ((ctxp = next)) /* Assignment is really meant here */
2399 for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2400 IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2401
2402 if (generate)
2403 {
2404 toFree->next = ctxp_for_generation;
2405 ctxp_for_generation = toFree;
2406 }
2407 else
2408 free (toFree);
2409 }
2410
2411 /* Reporting JDK1.1 features not implemented */
2412
2413 static tree
2414 parse_jdk1_1_error (msg)
2415 char *msg;
2416 {
2417 sorry (": `%s' JDK1.1(TM) feature", msg);
2418 java_error_count++;
2419 return empty_stmt_node;
2420 }
2421
2422 static int do_warning = 0;
2423
2424 void
2425 yyerror (msg)
2426 char *msg;
2427 {
2428 static java_lc elc;
2429 static int prev_lineno;
2430 static char *prev_msg;
2431
2432 int save_lineno;
2433 char *remainder, *code_from_source;
2434 extern struct obstack temporary_obstack;
2435
2436 if (!force_error && prev_lineno == lineno)
2437 return;
2438
2439 /* Save current error location but report latter, when the context is
2440 richer. */
2441 if (ctxp->java_error_flag == 0)
2442 {
2443 ctxp->java_error_flag = 1;
2444 elc = ctxp->elc;
2445 /* Do something to use the previous line if we're reaching the
2446 end of the file... */
2447 #ifdef VERBOSE_SKELETON
2448 printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2449 #endif
2450 return;
2451 }
2452
2453 /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2454 if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2455 return;
2456
2457 ctxp->java_error_flag = 0;
2458 if (do_warning)
2459 java_warning_count++;
2460 else
2461 java_error_count++;
2462
2463 if (elc.col == 0 && msg[1] == ';')
2464 {
2465 elc.col = ctxp->p_line->char_col-1;
2466 elc.line = ctxp->p_line->lineno;
2467 }
2468
2469 save_lineno = lineno;
2470 prev_lineno = lineno = elc.line;
2471 prev_msg = msg;
2472
2473 code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2474 obstack_grow0 (&temporary_obstack,
2475 code_from_source, strlen (code_from_source));
2476 remainder = obstack_finish (&temporary_obstack);
2477 if (do_warning)
2478 warning ("%s.\n%s", msg, remainder);
2479 else
2480 error ("%s.\n%s", msg, remainder);
2481
2482 /* This allow us to cheaply avoid an extra 'Invalid expression
2483 statement' error report when errors have been already reported on
2484 the same line. This occurs when we report an error but don't have
2485 a synchronization point other than ';', which
2486 expression_statement is the only one to take care of. */
2487 ctxp->prevent_ese = lineno = save_lineno;
2488 }
2489
2490 static void
2491 issue_warning_error_from_context (cl, msg, ap)
2492 tree cl;
2493 const char *msg;
2494 va_list ap;
2495 {
2496 char *saved, *saved_input_filename;
2497 char buffer [4096];
2498 vsprintf (buffer, msg, ap);
2499 force_error = 1;
2500
2501 ctxp->elc.line = EXPR_WFL_LINENO (cl);
2502 ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 :
2503 (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
2504
2505 /* We have a CL, that's a good reason for using it if it contains data */
2506 saved = ctxp->filename;
2507 if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
2508 ctxp->filename = EXPR_WFL_FILENAME (cl);
2509 saved_input_filename = input_filename;
2510 input_filename = ctxp->filename;
2511 java_error (NULL);
2512 java_error (buffer);
2513 ctxp->filename = saved;
2514 input_filename = saved_input_filename;
2515 force_error = 0;
2516 }
2517
2518 /* Issue an error message at a current source line CL */
2519
2520 void
2521 parse_error_context VPROTO ((tree cl, const char *msg, ...))
2522 {
2523 #ifndef ANSI_PROTOTYPES
2524 tree cl;
2525 const char *msg;
2526 #endif
2527 va_list ap;
2528
2529 VA_START (ap, msg);
2530 #ifndef ANSI_PROTOTYPES
2531 cl = va_arg (ap, tree);
2532 msg = va_arg (ap, const char *);
2533 #endif
2534 issue_warning_error_from_context (cl, msg, ap);
2535 va_end (ap);
2536 }
2537
2538 /* Issue a warning at a current source line CL */
2539
2540 static void
2541 parse_warning_context VPROTO ((tree cl, const char *msg, ...))
2542 {
2543 #ifndef ANSI_PROTOTYPES
2544 tree cl;
2545 const char *msg;
2546 #endif
2547 va_list ap;
2548
2549 VA_START (ap, msg);
2550 #ifndef ANSI_PROTOTYPES
2551 cl = va_arg (ap, tree);
2552 msg = va_arg (ap, const char *);
2553 #endif
2554
2555 force_error = do_warning = 1;
2556 issue_warning_error_from_context (cl, msg, ap);
2557 do_warning = force_error = 0;
2558 va_end (ap);
2559 }
2560
2561 static tree
2562 find_expr_with_wfl (node)
2563 tree node;
2564 {
2565 while (node)
2566 {
2567 char code;
2568 tree to_return;
2569
2570 switch (TREE_CODE (node))
2571 {
2572 case BLOCK:
2573 node = BLOCK_EXPR_BODY (node);
2574 continue;
2575
2576 case COMPOUND_EXPR:
2577 to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
2578 if (to_return)
2579 return to_return;
2580 node = TREE_OPERAND (node, 1);
2581 continue;
2582
2583 case LOOP_EXPR:
2584 node = TREE_OPERAND (node, 0);
2585 continue;
2586
2587 case LABELED_BLOCK_EXPR:
2588 node = TREE_OPERAND (node, 1);
2589 continue;
2590
2591 default:
2592 code = TREE_CODE_CLASS (TREE_CODE (node));
2593 if (((code == '1') || (code == '2') || (code == 'e'))
2594 && EXPR_WFL_LINECOL (node))
2595 return node;
2596 return NULL_TREE;
2597 }
2598 }
2599 return NULL_TREE;
2600 }
2601
2602 /* Issue a missing return statement error. Uses METHOD to figure the
2603 last line of the method the error occurs in. */
2604
2605 static void
2606 missing_return_error (method)
2607 tree method;
2608 {
2609 EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
2610 parse_error_context (wfl_operator, "Missing return statement");
2611 }
2612
2613 /* Issue an unreachable statement error. From NODE, find the next
2614 statement to report appropriately. */
2615 static void
2616 unreachable_stmt_error (node)
2617 tree node;
2618 {
2619 /* Browse node to find the next expression node that has a WFL. Use
2620 the location to report the error */
2621 if (TREE_CODE (node) == COMPOUND_EXPR)
2622 node = find_expr_with_wfl (TREE_OPERAND (node, 1));
2623 else
2624 node = find_expr_with_wfl (node);
2625
2626 if (node)
2627 {
2628 EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
2629 parse_error_context (wfl_operator, "Unreachable statement");
2630 }
2631 else
2632 fatal ("Can't get valid statement - unreachable_stmt_error");
2633 }
2634
2635 int
2636 java_report_errors ()
2637 {
2638 if (java_error_count)
2639 fprintf (stderr, "%d error%s",
2640 java_error_count, (java_error_count == 1 ? "" : "s"));
2641 if (java_warning_count)
2642 fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
2643 java_warning_count, (java_warning_count == 1 ? "" : "s"));
2644 if (java_error_count || java_warning_count)
2645 putc ('\n', stderr);
2646 return java_error_count;
2647 }
2648
2649 static char *
2650 java_accstring_lookup (flags)
2651 int flags;
2652 {
2653 static char buffer [80];
2654 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
2655
2656 /* Access modifier looked-up first for easier report on forbidden
2657 access. */
2658 if (flags & ACC_PUBLIC) COPY_RETURN ("public");
2659 if (flags & ACC_PRIVATE) COPY_RETURN ("private");
2660 if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
2661 if (flags & ACC_STATIC) COPY_RETURN ("static");
2662 if (flags & ACC_FINAL) COPY_RETURN ("final");
2663 if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
2664 if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
2665 if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
2666 if (flags & ACC_NATIVE) COPY_RETURN ("native");
2667 if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
2668 if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
2669
2670 buffer [0] = '\0';
2671 return buffer;
2672 #undef COPY_RETURN
2673 }
2674
2675 /* Issuing error messages upon redefinition of classes, interfaces or
2676 variables. */
2677
2678 static void
2679 classitf_redefinition_error (context, id, decl, cl)
2680 char *context;
2681 tree id, decl, cl;
2682 {
2683 parse_error_context (cl, "%s `%s' already defined in %s:%d",
2684 context, IDENTIFIER_POINTER (id),
2685 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
2686 /* Here we should point out where its redefined. It's a unicode. FIXME */
2687 }
2688
2689 static void
2690 variable_redefinition_error (context, name, type, line)
2691 tree context, name, type;
2692 int line;
2693 {
2694 char *type_name;
2695
2696 /* Figure a proper name for type. We might haven't resolved it */
2697 if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
2698 type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
2699 else
2700 type_name = lang_printable_name (type, 0);
2701
2702 parse_error_context (context,
2703 "Variable `%s' is already defined in this method and "
2704 "was declared `%s %s' at line %d",
2705 IDENTIFIER_POINTER (name),
2706 type_name, IDENTIFIER_POINTER (name), line);
2707 }
2708
2709 static tree
2710 build_array_from_name (type, type_wfl, name, ret_name)
2711 tree type, type_wfl, name, *ret_name;
2712 {
2713 int more_dims = 0;
2714 char *string;
2715
2716 /* Eventually get more dims */
2717 string = IDENTIFIER_POINTER (name);
2718 while (string [more_dims] == '[')
2719 more_dims++;
2720
2721 /* If we have, then craft a new type for this variable */
2722 if (more_dims)
2723 {
2724 name = get_identifier (&string [more_dims]);
2725
2726 /* If we have a pointer, use its type */
2727 if (TREE_CODE (type) == POINTER_TYPE)
2728 type = TREE_TYPE (type);
2729
2730 /* Building the first dimension of a primitive type uses this
2731 function */
2732 if (JPRIMITIVE_TYPE_P (type))
2733 {
2734 type = build_java_array_type (type, -1);
2735 CLASS_LOADED_P (type) = 1;
2736 more_dims--;
2737 }
2738 /* Otherwise, if we have a WFL for this type, use it (the type
2739 is already an array on an unresolved type, and we just keep
2740 on adding dimensions) */
2741 else if (type_wfl)
2742 type = type_wfl;
2743
2744 /* Add all the dimensions */
2745 while (more_dims--)
2746 type = build_unresolved_array_type (type);
2747
2748 /* The type may have been incomplete in the first place */
2749 if (type_wfl)
2750 type = obtain_incomplete_type (type);
2751 }
2752
2753 *ret_name = name;
2754 return type;
2755 }
2756
2757 /* Build something that the type identifier resolver will identify as
2758 being an array to an unresolved type. TYPE_WFL is a WFL on a
2759 identifier. */
2760
2761 static tree
2762 build_unresolved_array_type (type_or_wfl)
2763 tree type_or_wfl;
2764 {
2765 char *ptr;
2766
2767 /* TYPE_OR_WFL might be an array on a resolved type. In this case,
2768 just create a array type */
2769 if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
2770 {
2771 tree type = build_java_array_type (type_or_wfl, -1);
2772 CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
2773 return type;
2774 }
2775
2776 obstack_1grow (&temporary_obstack, '[');
2777 obstack_grow0 (&temporary_obstack,
2778 IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
2779 IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
2780 ptr = obstack_finish (&temporary_obstack);
2781 return build_expr_wfl (get_identifier (ptr),
2782 EXPR_WFL_FILENAME (type_or_wfl),
2783 EXPR_WFL_LINENO (type_or_wfl),
2784 EXPR_WFL_COLNO (type_or_wfl));
2785 }
2786
2787 /* Check modifiers. If one doesn't fit, retrieve it in its declaration line
2788 and point it out. */
2789
2790 static void
2791 check_modifiers (message, value, mask)
2792 char *message;
2793 int value;
2794 int mask;
2795 {
2796 /* Should point out the one that don't fit. ASCII/unicode,
2797 going backward. FIXME */
2798 if (value & ~mask)
2799 {
2800 int i, remainder = value & ~mask;
2801 for (i = 0; i <= 10; i++)
2802 if ((1 << i) & remainder)
2803 parse_error_context (ctxp->modifier_ctx [i], message,
2804 java_accstring_lookup (1 << i));
2805 }
2806 }
2807
2808 static void
2809 parser_add_interface (class_decl, interface_decl, wfl)
2810 tree class_decl, interface_decl, wfl;
2811 {
2812 if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
2813 parse_error_context (wfl, "Interface `%s' repeated",
2814 IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
2815 }
2816
2817 /* Bulk of common class/interface checks. Return 1 if an error was
2818 encountered. TAG is 0 for a class, 1 for an interface. */
2819
2820 static int
2821 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
2822 int is_interface, flags;
2823 tree raw_name, qualified_name, decl, cl;
2824 {
2825 tree node;
2826
2827 if (!quiet_flag)
2828 fprintf (stderr, " %s %s", (is_interface ? "interface" : "class"),
2829 IDENTIFIER_POINTER (qualified_name));
2830
2831 /* Scope of an interface/class type name:
2832 - Can't be imported by a single type import
2833 - Can't already exists in the package */
2834 if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
2835 && (node = find_name_in_single_imports (raw_name)))
2836 {
2837 parse_error_context
2838 (cl, "%s name `%s' clashes with imported type `%s'",
2839 (is_interface ? "Interface" : "Class"),
2840 IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
2841 return 1;
2842 }
2843 if (decl && CLASS_COMPLETE_P (decl))
2844 {
2845 classitf_redefinition_error ((is_interface ? "Interface" : "Class"),
2846 qualified_name, decl, cl);
2847 return 1;
2848 }
2849
2850 /* If public, file name should match class/interface name */
2851 if (flags & ACC_PUBLIC)
2852 {
2853 char *f;
2854
2855 /* Contains OS dependent assumption on path separator. FIXME */
2856 for (f = &input_filename [strlen (input_filename)];
2857 f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
2858 f--)
2859 ;
2860 if (f[0] == '/' || f[0] == DIR_SEPARATOR)
2861 f++;
2862 if (strncmp (IDENTIFIER_POINTER (raw_name),
2863 f , IDENTIFIER_LENGTH (raw_name)) ||
2864 f [IDENTIFIER_LENGTH (raw_name)] != '.')
2865 parse_error_context (cl, "Public %s `%s' must be defined in a file "
2866 "called `%s.java'",
2867 (is_interface ? "interface" : "class"),
2868 IDENTIFIER_POINTER (qualified_name),
2869 IDENTIFIER_POINTER (raw_name));
2870 }
2871
2872 check_modifiers ((is_interface ?
2873 "Illegal modifier `%s' for interface declaration" :
2874 "Illegal modifier `%s' for class declaration"), flags,
2875 (is_interface ? INTERFACE_MODIFIERS : CLASS_MODIFIERS));
2876 return 0;
2877 }
2878
2879 /* If DECL is NULL, create and push a new DECL, record the current
2880 line CL and do other maintenance things. */
2881
2882 static tree
2883 maybe_create_class_interface_decl (decl, qualified_name, cl)
2884 tree decl, qualified_name, cl;
2885 {
2886 if (!decl)
2887 decl = push_class (make_class (), qualified_name);
2888
2889 /* Take care of the file and line business */
2890 DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
2891 /* If we're emiting xrefs, store the line/col number information */
2892 if (flag_emit_xref)
2893 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
2894 else
2895 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
2896 CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
2897 CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
2898 IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
2899
2900 ctxp->current_parsed_class = decl;
2901
2902 /* Link the declaration to the already seen ones */
2903 TREE_CHAIN (decl) = ctxp->class_list;
2904 ctxp->class_list = decl;
2905
2906 /* Create a new nodes in the global lists */
2907 ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
2908 all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
2909
2910 /* Install a new dependency list element */
2911 create_jdep_list (ctxp);
2912
2913 SOURCE_FRONTEND_DEBUG (("Defining class/interface %s",
2914 IDENTIFIER_POINTER (qualified_name)));
2915 return decl;
2916 }
2917
2918 static void
2919 add_superinterfaces (decl, interface_list)
2920 tree decl, interface_list;
2921 {
2922 tree node;
2923 /* Superinterface(s): if present and defined, parser_check_super_interface ()
2924 takes care of ensuring that:
2925 - This is an accessible interface type,
2926 - Circularity detection.
2927 parser_add_interface is then called. If present but not defined,
2928 the check operation is delayed until the super interface gets
2929 defined. */
2930 for (node = interface_list; node; node = TREE_CHAIN (node))
2931 {
2932 tree current = TREE_PURPOSE (node);
2933 tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
2934 if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
2935 {
2936 if (!parser_check_super_interface (idecl, decl, current))
2937 parser_add_interface (decl, idecl, current);
2938 }
2939 else
2940 register_incomplete_type (JDEP_INTERFACE,
2941 current, decl, NULL_TREE);
2942 }
2943 }
2944
2945 /* Create an interface in pass1 and return its decl. Return the
2946 interface's decl in pass 2. */
2947
2948 static tree
2949 create_interface (flags, id, super)
2950 int flags;
2951 tree id, super;
2952 {
2953 tree raw_name = EXPR_WFL_NODE (id);
2954 tree q_name = parser_qualified_classname (id);
2955 tree decl = IDENTIFIER_CLASS_VALUE (q_name);
2956
2957 EXPR_WFL_NODE (id) = q_name; /* Keep source location, even if refined. */
2958
2959 /* Basic checks: scope, redefinition, modifiers */
2960 if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
2961 return NULL_TREE;
2962
2963 /* Interface modifiers check
2964 - public/abstract allowed (already done at that point)
2965 - abstract is obsolete (comes first, it's a warning, or should be)
2966 - Can't use twice the same (checked in the modifier rule) */
2967 if ((flags & ACC_ABSTRACT) && flag_redundant)
2968 parse_warning_context
2969 (MODIFIER_WFL (ABSTRACT_TK),
2970 "Redundant use of `abstract' modifier. Interface `%s' is implicitely "
2971 "abstract", IDENTIFIER_POINTER (raw_name));
2972
2973 /* Create a new decl if DECL is NULL, otherwise fix it */
2974 decl = maybe_create_class_interface_decl (decl, q_name, id);
2975
2976 /* Set super info and mark the class a complete */
2977 set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl),
2978 object_type_node, ctxp->interface_number);
2979 ctxp->interface_number = 0;
2980 CLASS_COMPLETE_P (decl) = 1;
2981 add_superinterfaces (decl, super);
2982
2983 return decl;
2984 }
2985
2986 /* Create an class in pass1 and return its decl. Return class
2987 interface's decl in pass 2. */
2988
2989 static tree
2990 create_class (flags, id, super, interfaces)
2991 int flags;
2992 tree id, super, interfaces;
2993 {
2994 tree raw_name = EXPR_WFL_NODE (id);
2995 tree class_id, decl;
2996 tree super_decl_type;
2997
2998 class_id = parser_qualified_classname (id);
2999 decl = IDENTIFIER_CLASS_VALUE (class_id);
3000 ctxp->current_parsed_class_un = EXPR_WFL_NODE (id);
3001 EXPR_WFL_NODE (id) = class_id;
3002
3003 /* Basic check: scope, redefinition, modifiers */
3004 if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3005 return NULL_TREE;
3006
3007 /* Class modifier check:
3008 - Allowed modifier (already done at that point)
3009 - abstract AND final forbidden
3010 - Public classes defined in the correct file */
3011 if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3012 parse_error_context (id, "Class `%s' can't be declared both abstract "
3013 "and final", IDENTIFIER_POINTER (raw_name));
3014
3015 /* Create a new decl if DECL is NULL, otherwise fix it */
3016 decl = maybe_create_class_interface_decl (decl, class_id, id);
3017
3018 /* If SUPER exists, use it, otherwise use Object */
3019 if (super)
3020 {
3021 /* Can't extend java.lang.Object */
3022 if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3023 {
3024 parse_error_context (id, "Can't extend `java.lang.Object'");
3025 return NULL_TREE;
3026 }
3027
3028 super_decl_type =
3029 register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3030 }
3031 else if (TREE_TYPE (decl) != object_type_node)
3032 super_decl_type = object_type_node;
3033 /* We're defining java.lang.Object */
3034 else
3035 super_decl_type = NULL_TREE;
3036
3037 /* Set super info and mark the class a complete */
3038 set_super_info (flags, TREE_TYPE (decl), super_decl_type,
3039 ctxp->interface_number);
3040 ctxp->interface_number = 0;
3041 CLASS_COMPLETE_P (decl) = 1;
3042 add_superinterfaces (decl, interfaces);
3043
3044 /* If doing xref, store the location at which the inherited class
3045 (if any) was seen. */
3046 if (flag_emit_xref && super)
3047 DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3048
3049 /* Eventually sets the @deprecated tag flag */
3050 CHECK_DEPRECATED (decl);
3051
3052 return decl;
3053 }
3054
3055 /* Can't use lookup_field () since we don't want to load the class and
3056 can't set the CLASS_LOADED_P flag */
3057
3058 static tree
3059 find_field (class, name)
3060 tree class;
3061 tree name;
3062 {
3063 tree decl;
3064 for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
3065 {
3066 if (DECL_NAME (decl) == name)
3067 return decl;
3068 }
3069 return NULL_TREE;
3070 }
3071
3072 /* Wrap around lookup_field that doesn't potentially upset the value
3073 of CLASS */
3074
3075 static tree
3076 lookup_field_wrapper (class, name)
3077 tree class, name;
3078 {
3079 tree type = class;
3080 tree decl;
3081 java_parser_context_save_global ();
3082 decl = lookup_field (&type, name);
3083 java_parser_context_restore_global ();
3084 return decl;
3085 }
3086
3087 /* Find duplicate field within the same class declarations and report
3088 the error. Returns 1 if a duplicated field was found, 0
3089 otherwise. */
3090
3091 static int
3092 duplicate_declaration_error_p (new_field_name, new_type, cl)
3093 tree new_field_name, new_type, cl;
3094 {
3095 /* This might be modified to work with method decl as well */
3096 tree decl = find_field (TREE_TYPE (ctxp->current_parsed_class),
3097 new_field_name);
3098 if (decl)
3099 {
3100 char *t1 = strdup (purify_type_name
3101 ((TREE_CODE (new_type) == POINTER_TYPE
3102 && TREE_TYPE (new_type) == NULL_TREE) ?
3103 IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
3104 lang_printable_name (new_type, 1)));
3105 /* The type may not have been completed by the time we report
3106 the error */
3107 char *t2 = strdup (purify_type_name
3108 ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
3109 && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
3110 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
3111 lang_printable_name (TREE_TYPE (decl), 1)));
3112 parse_error_context
3113 (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)",
3114 t1, IDENTIFIER_POINTER (new_field_name),
3115 t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
3116 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3117 free (t1);
3118 free (t2);
3119 return 1;
3120 }
3121 return 0;
3122 }
3123
3124 /* Field registration routine. If TYPE doesn't exist, field
3125 declarations are linked to the undefined TYPE dependency list, to
3126 be later resolved in java_complete_class () */
3127
3128 static void
3129 register_fields (flags, type, variable_list)
3130 int flags;
3131 tree type, variable_list;
3132 {
3133 tree current, saved_type;
3134 tree class_type = TREE_TYPE (ctxp->current_parsed_class);
3135 int saved_lineno = lineno;
3136 int must_chain = 0;
3137 tree wfl = NULL_TREE;
3138
3139 /* If we're adding fields to interfaces, those fields are public,
3140 static, final */
3141 if (CLASS_INTERFACE (TYPE_NAME (class_type)))
3142 {
3143 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
3144 flags, ACC_PUBLIC,
3145 "%s", "interface field(s)");
3146 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
3147 flags, ACC_STATIC,
3148 "%s", "interface field(s)");
3149 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
3150 flags, ACC_FINAL, "%s", "interface field(s)");
3151 check_modifiers ("Illegal interface member modifier `%s'", flags,
3152 INTERFACE_FIELD_MODIFIERS);
3153 flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
3154 }
3155
3156 /* Obtain a suitable type for resolution, if necessary */
3157 SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
3158
3159 /* If TYPE is fully resolved and we don't have a reference, make one */
3160 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
3161
3162 for (current = variable_list, saved_type = type; current;
3163 current = TREE_CHAIN (current), type = saved_type)
3164 {
3165 tree real_type;
3166 tree field_decl;
3167 tree cl = TREE_PURPOSE (current);
3168 tree init = TREE_VALUE (current);
3169 tree current_name = EXPR_WFL_NODE (cl);
3170
3171 /* Process NAME, as it may specify extra dimension(s) for it */
3172 type = build_array_from_name (type, wfl, current_name, &current_name);
3173
3174 /* Type adjustment. We may have just readjusted TYPE because
3175 the variable specified more dimensions. Make sure we have
3176 a reference if we can and don't have one already. Also
3177 change the name if we have an init. */
3178 if (type != saved_type)
3179 {
3180 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
3181 if (init)
3182 EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
3183 }
3184
3185 real_type = GET_REAL_TYPE (type);
3186 /* Check for redeclarations */
3187 if (duplicate_declaration_error_p (current_name, real_type, cl))
3188 continue;
3189
3190 /* Set lineno to the line the field was found and create a
3191 declaration for it. Eventually sets the @deprecated tag flag. */
3192 if (flag_emit_xref)
3193 lineno = EXPR_WFL_LINECOL (cl);
3194 else
3195 lineno = EXPR_WFL_LINENO (cl);
3196 field_decl = add_field (class_type, current_name, real_type, flags);
3197 CHECK_DEPRECATED (field_decl);
3198
3199 /* Check if we must chain. */
3200 if (must_chain)
3201 register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
3202
3203 /* If we have an initialization value tied to the field */
3204 if (init)
3205 {
3206 /* The field is declared static */
3207 if (flags & ACC_STATIC)
3208 {
3209 /* We include the field and its initialization part into
3210 a list used to generate <clinit>. After <clinit> is
3211 walked, field initializations will be processed and
3212 fields initialized with known constants will be taken
3213 out of <clinit> and have their DECL_INITIAL set
3214 appropriately. */
3215 TREE_CHAIN (init) = ctxp->static_initialized;
3216 ctxp->static_initialized = init;
3217 DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
3218 if (TREE_OPERAND (init, 1)
3219 && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
3220 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
3221 }
3222 /* A non-static field declared with an immediate initialization is
3223 to be initialized in <init>, if any. This field is remembered
3224 to be processed at the time of the generation of <init>. */
3225 else
3226 {
3227 TREE_CHAIN (init) = ctxp->non_static_initialized;
3228 ctxp->non_static_initialized = init;
3229 }
3230 MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
3231 }
3232 }
3233 lineno = saved_lineno;
3234 }
3235
3236 /* Generate the method $finit$ that initializes fields initialized
3237 upon declaration. */
3238
3239 static void
3240 maybe_generate_finit ()
3241 {
3242 tree mdecl, current;
3243
3244 if (!ctxp->non_static_initialized || java_error_count)
3245 return;
3246
3247 mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
3248 ACC_PRIVATE, void_type_node,
3249 finit_identifier_node, end_params_node);
3250 start_artificial_method_body (mdecl);
3251
3252 ctxp->non_static_initialized = nreverse (ctxp->non_static_initialized);
3253 for (current = ctxp->non_static_initialized; current;
3254 current = TREE_CHAIN (current))
3255 java_method_add_stmt (mdecl,
3256 build_debugable_stmt (EXPR_WFL_LINECOL (current),
3257 current));
3258
3259 end_artificial_method_body (mdecl);
3260 CLASS_HAS_FINIT_P (TREE_TYPE (ctxp->current_parsed_class)) = 1;
3261 ctxp->non_static_initialized = NULL_TREE;
3262 }
3263
3264 /* Check whether it is necessary to generate a <clinit> for the class
3265 we just parsed. */
3266
3267 static void
3268 maybe_generate_clinit ()
3269 {
3270 tree mdecl, c;
3271
3272 if (!ctxp->static_initialized || java_error_count)
3273 return;
3274
3275 mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
3276 ACC_STATIC, void_type_node,
3277 clinit_identifier_node, end_params_node);
3278 start_artificial_method_body (mdecl);
3279
3280 /* Keep initialization in order to enforce 8.5 */
3281 ctxp->static_initialized = nreverse (ctxp->static_initialized);
3282
3283 /* We process the list of assignment we produced as the result of
3284 the declaration of initialized static field and add them as
3285 statement to the <clinit> method. */
3286 for (c = ctxp->static_initialized; c; c = TREE_CHAIN (c))
3287 {
3288 /* We build the assignment expression that will initialize the
3289 field to its value. There are strict rules on static
3290 initializers (8.5). FIXME */
3291 java_method_add_stmt (mdecl,
3292 build_debugable_stmt (EXPR_WFL_LINECOL (c), c));
3293 }
3294
3295 end_artificial_method_body (mdecl);
3296 ctxp->static_initialized = NULL_TREE;
3297 }
3298
3299 /* Shared accros method_declarator and method_header to remember the
3300 patch stage that was reached during the declaration of the method.
3301 A method DECL is built differently is there is no patch
3302 (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
3303 pending on the currently defined method. */
3304
3305 static int patch_stage;
3306
3307 /* Check the method declaration and add the method to its current
3308 class. If the argument list is known to contain incomplete types,
3309 the method is partially added and the registration will be resume
3310 once the method arguments resolved. If TYPE is NULL, we're dealing
3311 with a constructor. */
3312
3313 static tree
3314 method_header (flags, type, mdecl, throws)
3315 int flags;
3316 tree type, mdecl, throws;
3317 {
3318 tree meth = TREE_VALUE (mdecl);
3319 tree id = TREE_PURPOSE (mdecl);
3320 tree this_class = TREE_TYPE (ctxp->current_parsed_class);
3321 tree type_wfl = NULL_TREE;
3322 tree meth_name = NULL_TREE, current, orig_arg;
3323 int saved_lineno;
3324 int constructor_ok = 0, must_chain;
3325
3326 check_modifiers_consistency (flags);
3327
3328 /* There are some forbidden modifiers for an abstract method and its
3329 class must be abstract as well. */
3330 if (type && (flags & ACC_ABSTRACT))
3331 {
3332 ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
3333 ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
3334 ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
3335 ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
3336 ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
3337 if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
3338 && !CLASS_INTERFACE (TYPE_NAME (this_class)))
3339 parse_error_context
3340 (id, "Class `%s' must be declared abstract to define abstract "
3341 "method `%s'",
3342 IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
3343 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
3344 }
3345 /* Things to be checked when declaring a constructor */
3346 if (!type)
3347 {
3348 int ec = java_error_count;
3349 /* 8.6: Constructor declarations: we might be trying to define a
3350 method without specifying a return type. */
3351 if (EXPR_WFL_NODE (id) != ctxp->current_parsed_class_un)
3352 parse_error_context
3353 (id, "Invalid method declaration, return type required");
3354 /* 8.6.3: Constructor modifiers */
3355 else
3356 {
3357 JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
3358 JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
3359 JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
3360 JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
3361 JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
3362 }
3363 /* If we found error here, we don't consider it's OK to tread
3364 the method definition as a constructor, for the rest of this
3365 function */
3366 if (ec == java_error_count)
3367 constructor_ok = 1;
3368 }
3369
3370 /* Method declared within the scope of an interface are implicitly
3371 abstract and public. Conflicts with other erroneously provided
3372 modifiers are checked right after. */
3373
3374 if (CLASS_INTERFACE (TYPE_NAME (this_class)))
3375 {
3376 /* If FLAGS isn't set because of a modifier, turn the
3377 corresponding modifier WFL to NULL so we issue a warning on
3378 the obsolete use of the modifier */
3379 if (!(flags & ACC_PUBLIC))
3380 MODIFIER_WFL (PUBLIC_TK) = NULL;
3381 if (!(flags & ACC_ABSTRACT))
3382 MODIFIER_WFL (ABSTRACT_TK) = NULL;
3383 flags |= ACC_PUBLIC;
3384 flags |= ACC_ABSTRACT;
3385 }
3386
3387 /* Modifiers context reset moved up, so abstract method declaration
3388 modifiers can be later checked. */
3389
3390 /* Set constructor returned type to void and method name to <init>,
3391 unless we found an error identifier the constructor (in which
3392 case we retain the original name) */
3393 if (!type)
3394 {
3395 type = void_type_node;
3396 if (constructor_ok)
3397 meth_name = init_identifier_node;
3398 }
3399 else
3400 meth_name = EXPR_WFL_NODE (id);
3401
3402 /* Do the returned type resolution and registration if necessary */
3403 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
3404
3405 if (meth_name)
3406 type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
3407 EXPR_WFL_NODE (id) = meth_name;
3408 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
3409
3410 if (must_chain)
3411 {
3412 patch_stage = JDEP_METHOD_RETURN;
3413 register_incomplete_type (patch_stage, type_wfl, id, type);
3414 TREE_TYPE (meth) = GET_REAL_TYPE (type);
3415 }
3416 else
3417 TREE_TYPE (meth) = type;
3418
3419 saved_lineno = lineno;
3420 /* When defining an abstract or interface method, the curly
3421 bracket at level 1 doesn't exist because there is no function
3422 body */
3423 lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 :
3424 EXPR_WFL_LINENO (id));
3425
3426 /* Remember the original argument list */
3427 orig_arg = TYPE_ARG_TYPES (meth);
3428
3429 if (patch_stage) /* includes ret type and/or all args */
3430 {
3431 jdep *jdep;
3432 meth = add_method_1 (this_class, flags, meth_name, meth);
3433 /* Patch for the return type */
3434 if (patch_stage == JDEP_METHOD_RETURN)
3435 {
3436 jdep = CLASSD_LAST (ctxp->classd_list);
3437 JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
3438 }
3439 /* This is the stop JDEP. METH allows the function's signature
3440 to be computed. */
3441 register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
3442 }
3443 else
3444 meth = add_method (this_class, flags, meth_name,
3445 build_java_signature (meth));
3446
3447 /* Fix the method argument list so we have the argument name
3448 information */
3449 fix_method_argument_names (orig_arg, meth);
3450
3451 /* Register the parameter number and re-install the current line
3452 number */
3453 DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
3454 lineno = saved_lineno;
3455
3456 /* Register exception specified by the `throws' keyword for
3457 resolution and set the method decl appropriate field to the list.
3458 Note: the grammar ensures that what we get here are class
3459 types. */
3460 if (throws)
3461 {
3462 throws = nreverse (throws);
3463 for (current = throws; current; current = TREE_CHAIN (current))
3464 {
3465 register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
3466 NULL_TREE, NULL_TREE);
3467 JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) =
3468 &TREE_VALUE (current);
3469 }
3470 DECL_FUNCTION_THROWS (meth) = throws;
3471 }
3472
3473 /* We set the DECL_NAME to ID so we can track the location where
3474 the function was declared. This allow us to report
3475 redefinition error accurately. When method are verified,
3476 DECL_NAME is reinstalled properly (using the content of the
3477 WFL node ID) (see check_method_redefinition). We don't do that
3478 when Object is being defined. Constructor <init> names will be
3479 reinstalled the same way. */
3480 if (TREE_TYPE (ctxp->current_parsed_class) != object_type_node)
3481 DECL_NAME (meth) = id;
3482
3483 /* Set the flag if we correctly processed a constructor */
3484 if (constructor_ok)
3485 DECL_CONSTRUCTOR_P (meth) = 1;
3486
3487 /* Eventually set the @deprecated tag flag */
3488 CHECK_DEPRECATED (meth);
3489
3490 /* If doing xref, store column and line number information instead
3491 of the line number only. */
3492 if (flag_emit_xref)
3493 DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
3494
3495 return meth;
3496 }
3497
3498 static void
3499 fix_method_argument_names (orig_arg, meth)
3500 tree orig_arg, meth;
3501 {
3502 tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
3503 if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
3504 {
3505 TREE_PURPOSE (arg) = this_identifier_node;
3506 arg = TREE_CHAIN (arg);
3507 }
3508 while (orig_arg != end_params_node)
3509 {
3510 TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
3511 orig_arg = TREE_CHAIN (orig_arg);
3512 arg = TREE_CHAIN (arg);
3513 }
3514 }
3515
3516 /* Complete the method declaration with METHOD_BODY. */
3517
3518 static void
3519 finish_method_declaration (method_body)
3520 tree method_body;
3521 {
3522 int flags = get_access_flags_from_decl (current_function_decl);
3523
3524 /* 8.4.5 Method Body */
3525 if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
3526 {
3527 tree wfl = DECL_NAME (current_function_decl);
3528 parse_error_context (wfl,
3529 "%s method `%s' can't have a body defined",
3530 (METHOD_NATIVE (current_function_decl) ?
3531 "Native" : "Abstract"),
3532 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
3533 method_body = NULL_TREE;
3534 }
3535 else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
3536 {
3537 tree wfl = DECL_NAME (current_function_decl);
3538 parse_error_context (wfl,
3539 "Non native and non abstract method `%s' must "
3540 "have a body defined",
3541 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
3542 method_body = NULL_TREE;
3543 }
3544
3545 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
3546 maybe_absorb_scoping_blocks ();
3547 /* Exit function's body */
3548 exit_block ();
3549 /* Merge last line of the function with first line, directly in the
3550 function decl. It will be used to emit correct debug info. */
3551 if (!flag_emit_xref)
3552 DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
3553 /* So we don't have an irrelevant function declaration context for
3554 the next static block we'll see. */
3555 current_function_decl = NULL_TREE;
3556 }
3557
3558 /* Build a an error message for constructor circularity errors. */
3559
3560 static char *
3561 constructor_circularity_msg (from, to)
3562 tree from, to;
3563 {
3564 static char string [4096];
3565 char *t = strdup (lang_printable_name (from, 0));
3566 sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
3567 free (t);
3568 return string;
3569 }
3570
3571 /* Verify a circular call to METH. Return 1 if an error is found, 0
3572 otherwise. */
3573
3574 static int
3575 verify_constructor_circularity (meth, current)
3576 tree meth, current;
3577 {
3578 static tree list = NULL_TREE;
3579 tree c;
3580 for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
3581 {
3582 if (TREE_VALUE (c) == meth)
3583 {
3584 char *t;
3585 if (list)
3586 {
3587 tree liste;
3588 list = nreverse (list);
3589 for (liste = list; liste; liste = TREE_CHAIN (liste))
3590 {
3591 parse_error_context
3592 (TREE_PURPOSE (TREE_PURPOSE (liste)),
3593 constructor_circularity_msg
3594 (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste))));
3595 java_error_count--;
3596 }
3597 }
3598 t = strdup (lang_printable_name (meth, 0));
3599 parse_error_context (TREE_PURPOSE (c),
3600 "%s: recursive invocation of constructor `%s'",
3601 constructor_circularity_msg (current, meth), t);
3602 free (t);
3603 list = NULL_TREE;
3604 return 1;
3605 }
3606 }
3607 for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
3608 {
3609 list = tree_cons (c, current, list);
3610 if (verify_constructor_circularity (meth, TREE_VALUE (c)))
3611 return 1;
3612 list = TREE_CHAIN (list);
3613 }
3614 return 0;
3615 }
3616
3617 /* Check modifiers that can be declared but exclusively */
3618
3619 static void
3620 check_modifiers_consistency (flags)
3621 int flags;
3622 {
3623 int acc_count = 0;
3624 tree cl = NULL_TREE;
3625
3626 THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, 0, acc_count, cl);
3627 THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, 1, acc_count, cl);
3628 THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, 2, acc_count, cl);
3629 if (acc_count > 1)
3630 parse_error_context
3631 (cl, "Inconsistent member declaration. At most one of `public', "
3632 "`private', or `protected' may be specified");
3633 }
3634
3635 /* Check the methode header METH for abstract specifics features */
3636
3637 static void
3638 check_abstract_method_header (meth)
3639 tree meth;
3640 {
3641 int flags = get_access_flags_from_decl (meth);
3642 /* DECL_NAME might still be a WFL node */
3643 tree name = GET_METHOD_NAME (meth);
3644
3645 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags,
3646 ACC_ABSTRACT, "abstract method `%s'",
3647 IDENTIFIER_POINTER (name));
3648 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK), flags,
3649 ACC_PUBLIC, "abstract method `%s'",
3650 IDENTIFIER_POINTER (name));
3651
3652 check_modifiers ("Illegal modifier `%s' for interface method",
3653 flags, INTERFACE_METHOD_MODIFIERS);
3654 }
3655
3656 /* Create a FUNCTION_TYPE node and start augmenting it with the
3657 declared function arguments. Arguments type that can't be resolved
3658 are left as they are, but the returned node is marked as containing
3659 incomplete types. */
3660
3661 static tree
3662 method_declarator (id, list)
3663 tree id, list;
3664 {
3665 tree arg_types = NULL_TREE, current, node;
3666 tree meth = make_node (FUNCTION_TYPE);
3667 jdep *jdep;
3668
3669 patch_stage = JDEP_NO_PATCH;
3670
3671 for (current = list; current; current = TREE_CHAIN (current))
3672 {
3673 int must_chain = 0;
3674 tree wfl_name = TREE_PURPOSE (current);
3675 tree type = TREE_VALUE (current);
3676 tree name = EXPR_WFL_NODE (wfl_name);
3677 tree already, arg_node;
3678 tree type_wfl = NULL_TREE;
3679 tree real_type;
3680
3681 /* Obtain a suitable type for resolution, if necessary */
3682 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
3683
3684 /* Process NAME, as it may specify extra dimension(s) for it */
3685 type = build_array_from_name (type, type_wfl, name, &name);
3686 EXPR_WFL_NODE (wfl_name) = name;
3687
3688 real_type = GET_REAL_TYPE (type);
3689 if (TREE_CODE (real_type) == RECORD_TYPE)
3690 {
3691 real_type = promote_type (real_type);
3692 if (TREE_CODE (type) == TREE_LIST)
3693 TREE_PURPOSE (type) = real_type;
3694 }
3695
3696 /* Check redefinition */
3697 for (already = arg_types; already; already = TREE_CHAIN (already))
3698 if (TREE_PURPOSE (already) == name)
3699 {
3700 parse_error_context
3701 (wfl_name, "Variable `%s' is used more than once in the "
3702 "argument list of method `%s'", IDENTIFIER_POINTER (name),
3703 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
3704 break;
3705 }
3706
3707 /* If we've an incomplete argument type, we know there is a location
3708 to patch when the type get resolved, later. */
3709 jdep = NULL;
3710 if (must_chain)
3711 {
3712 patch_stage = JDEP_METHOD;
3713 type = register_incomplete_type (patch_stage,
3714 type_wfl, wfl_name, type);
3715 jdep = CLASSD_LAST (ctxp->classd_list);
3716 JDEP_MISC (jdep) = id;
3717 }
3718
3719 /* The argument node: a name and a (possibly) incomplete type */
3720 arg_node = build_tree_list (name, real_type);
3721 if (jdep)
3722 JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
3723 TREE_CHAIN (arg_node) = arg_types;
3724 arg_types = arg_node;
3725 }
3726 TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
3727 node = build_tree_list (id, meth);
3728 return node;
3729 }
3730
3731 static int
3732 unresolved_type_p (wfl, returned)
3733 tree wfl;
3734 tree *returned;
3735
3736 {
3737 if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
3738 {
3739 tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
3740 if (returned)
3741 *returned = (decl ? TREE_TYPE (decl) : NULL_TREE);
3742 return 1;
3743 }
3744 if (returned)
3745 *returned = wfl;
3746 return 0;
3747 }
3748
3749 /* From NAME, build a qualified identifier node using the
3750 qualification from the current package definition. */
3751
3752 static tree
3753 parser_qualified_classname (name)
3754 tree name;
3755 {
3756 if (ctxp->package)
3757 return merge_qualified_name (ctxp->package, EXPR_WFL_NODE (name));
3758 else
3759 return EXPR_WFL_NODE (name);
3760 }
3761
3762 /* Called once the type a interface extends is resolved. Returns 0 if
3763 everything is OK. */
3764
3765 static int
3766 parser_check_super_interface (super_decl, this_decl, this_wfl)
3767 tree super_decl, this_decl, this_wfl;
3768 {
3769 tree super_type = TREE_TYPE (super_decl);
3770
3771 /* Has to be an interface */
3772 if (!CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (super_decl))))
3773 {
3774 parse_error_context
3775 (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
3776 (TYPE_ARRAY_P (super_type) ? "array" : "class"),
3777 IDENTIFIER_POINTER (DECL_NAME (super_decl)),
3778 (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ?
3779 "interface" : "class"),
3780 IDENTIFIER_POINTER (DECL_NAME (this_decl)));
3781 return 1;
3782 }
3783
3784 /* Check scope: same package OK, other package: OK if public */
3785 if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
3786 return 1;
3787
3788 SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
3789 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3790 IDENTIFIER_POINTER (DECL_NAME (super_decl))));
3791 return 0;
3792 }
3793
3794 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
3795 0 if everthing is OK. */
3796
3797 static int
3798 parser_check_super (super_decl, this_decl, wfl)
3799 tree super_decl, this_decl, wfl;
3800 {
3801 tree super_type = TREE_TYPE (super_decl);
3802
3803 /* SUPER should be a CLASS (neither an array nor an interface) */
3804 if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
3805 {
3806 parse_error_context
3807 (wfl, "Class `%s' can't subclass %s `%s'",
3808 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3809 (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
3810 IDENTIFIER_POINTER (DECL_NAME (super_decl)));
3811 return 1;
3812 }
3813
3814 if (CLASS_FINAL (TYPE_NAME (super_type)))
3815 {
3816 parse_error_context (wfl, "Can't subclass final classes: %s",
3817 IDENTIFIER_POINTER (DECL_NAME (super_decl)));
3818 return 1;
3819 }
3820
3821 /* Check scope: same package OK, other package: OK if public */
3822 if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
3823 return 1;
3824
3825 SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
3826 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3827 IDENTIFIER_POINTER (DECL_NAME (super_decl))));
3828 return 0;
3829 }
3830
3831 /* Create a new dependency list and link it (in a LIFO manner) to the
3832 CTXP list of type dependency list. */
3833
3834 static void
3835 create_jdep_list (ctxp)
3836 struct parser_ctxt *ctxp;
3837 {
3838 jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));
3839 new->first = new->last = NULL;
3840 new->next = ctxp->classd_list;
3841 ctxp->classd_list = new;
3842 }
3843
3844 static jdeplist *
3845 reverse_jdep_list (ctxp)
3846 struct parser_ctxt *ctxp;
3847 {
3848 register jdeplist *prev = NULL, *current, *next;
3849 for (current = ctxp->classd_list; current; current = next)
3850 {
3851 next = current->next;
3852 current->next = prev;
3853 prev = current;
3854 }
3855 return prev;
3856 }
3857
3858 /* Create a fake pointer based on the ID stored in
3859 TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
3860 registered again. */
3861
3862 static tree
3863 obtain_incomplete_type (type_name)
3864 tree type_name;
3865 {
3866 tree ptr, name;
3867
3868 if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
3869 name = EXPR_WFL_NODE (type_name);
3870 else if (INCOMPLETE_TYPE_P (type_name))
3871 name = TYPE_NAME (type_name);
3872 else
3873 fatal ("invalid type name - obtain_incomplete_type");
3874
3875 for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
3876 if (TYPE_NAME (ptr) == name)
3877 break;
3878
3879 if (!ptr)
3880 {
3881 push_obstacks (&permanent_obstack, &permanent_obstack);
3882 BUILD_PTR_FROM_NAME (ptr, name);
3883 layout_type (ptr);
3884 pop_obstacks ();
3885 TREE_CHAIN (ptr) = ctxp->incomplete_class;
3886 ctxp->incomplete_class = ptr;
3887 }
3888
3889 return ptr;
3890 }
3891
3892 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
3893 non NULL instead of computing a new fake type based on WFL. The new
3894 dependency is inserted in the current type dependency list, in FIFO
3895 manner. */
3896
3897 static tree
3898 register_incomplete_type (kind, wfl, decl, ptr)
3899 int kind;
3900 tree wfl, decl, ptr;
3901 {
3902 jdep *new = (jdep *)xmalloc (sizeof (jdep));
3903
3904 if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
3905 ptr = obtain_incomplete_type (wfl);
3906
3907 JDEP_KIND (new) = kind;
3908 JDEP_DECL (new) = decl;
3909 JDEP_SOLV (new) = ptr;
3910 JDEP_WFL (new) = wfl;
3911 JDEP_CHAIN (new) = NULL;
3912 JDEP_MISC (new) = NULL_TREE;
3913 JDEP_GET_PATCH (new) = (tree *)NULL;
3914
3915 JDEP_INSERT (ctxp->classd_list, new);
3916
3917 return ptr;
3918 }
3919
3920 void
3921 java_check_circular_reference ()
3922 {
3923 tree current;
3924 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
3925 {
3926 tree type = TREE_TYPE (current);
3927 if (CLASS_INTERFACE (TYPE_NAME (type)))
3928 {
3929 /* Check all interfaces this class extends */
3930 tree basetype_vec = TYPE_BINFO_BASETYPES (type);
3931 int n, i;
3932
3933 if (!basetype_vec)
3934 return;
3935 n = TREE_VEC_LENGTH (basetype_vec);
3936 for (i = 0; i < n; i++)
3937 {
3938 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
3939 if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node
3940 && interface_of_p (type, BINFO_TYPE (vec_elt)))
3941 parse_error_context (lookup_cl (current),
3942 "Cyclic interface inheritance");
3943 }
3944 }
3945 else
3946 if (inherits_from_p (CLASSTYPE_SUPER (type), type))
3947 parse_error_context (lookup_cl (current),
3948 "Cyclic class inheritance");
3949 }
3950 }
3951
3952 /* safe_layout_class just makes sure that we can load a class without
3953 disrupting the current_class, input_file, lineno, etc, information
3954 about the class processed currently. */
3955
3956 void
3957 safe_layout_class (class)
3958 tree class;
3959 {
3960 tree save_current_class = current_class;
3961 char *save_input_filename = input_filename;
3962 int save_lineno = lineno;
3963
3964 push_obstacks (&permanent_obstack, &permanent_obstack);
3965
3966 layout_class (class);
3967 pop_obstacks ();
3968
3969 current_class = save_current_class;
3970 input_filename = save_input_filename;
3971 lineno = save_lineno;
3972 CLASS_LOADED_P (class) = 1;
3973 }
3974
3975 static tree
3976 jdep_resolve_class (dep)
3977 jdep *dep;
3978 {
3979 tree decl;
3980
3981 if (JDEP_RESOLVED_P (dep))
3982 decl = JDEP_RESOLVED_DECL (dep);
3983 else
3984 {
3985 decl = resolve_class (JDEP_TO_RESOLVE (dep),
3986 JDEP_DECL (dep), JDEP_WFL (dep));
3987 JDEP_RESOLVED (dep, decl);
3988 }
3989
3990 if (!decl)
3991 complete_class_report_errors (dep);
3992
3993 return decl;
3994 }
3995
3996 /* Complete unsatisfied class declaration and their dependencies */
3997
3998 void
3999 java_complete_class ()
4000 {
4001 tree cclass;
4002 jdeplist *cclassd;
4003 int error_found;
4004 tree type;
4005
4006 push_obstacks (&permanent_obstack, &permanent_obstack);
4007
4008 /* Process imports and reverse the import on demand list */
4009 process_imports ();
4010 if (ctxp->import_demand_list)
4011 ctxp->import_demand_list = nreverse (ctxp->import_demand_list);
4012
4013 /* Rever things so we have the right order */
4014 ctxp->class_list = nreverse (ctxp->class_list);
4015 ctxp->classd_list = reverse_jdep_list (ctxp);
4016
4017 for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
4018 cclass && cclassd;
4019 cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
4020 {
4021 jdep *dep;
4022 for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
4023 {
4024 tree decl;
4025 if (!(decl = jdep_resolve_class (dep)))
4026 continue;
4027
4028 /* Now it's time to patch */
4029 switch (JDEP_KIND (dep))
4030 {
4031 case JDEP_SUPER:
4032 /* Simply patch super */
4033 if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
4034 continue;
4035 BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO
4036 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
4037 break;
4038
4039 case JDEP_FIELD:
4040 {
4041 /* We do part of the job done in add_field */
4042 tree field_decl = JDEP_DECL (dep);
4043 tree field_type = TREE_TYPE (decl);
4044 push_obstacks (&permanent_obstack, &permanent_obstack);
4045 if (TREE_CODE (field_type) == RECORD_TYPE)
4046 field_type = promote_type (field_type);
4047 pop_obstacks ();
4048 TREE_TYPE (field_decl) = field_type;
4049 DECL_ALIGN (field_decl) = 0;
4050 layout_decl (field_decl, 0);
4051 SOURCE_FRONTEND_DEBUG
4052 (("Completed field/var decl `%s' with `%s'",
4053 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
4054 IDENTIFIER_POINTER (DECL_NAME (decl))));
4055 break;
4056 }
4057 case JDEP_METHOD: /* We start patching a method */
4058 case JDEP_METHOD_RETURN:
4059 error_found = 0;
4060 while (1)
4061 {
4062 if (decl)
4063 {
4064 type = TREE_TYPE(decl);
4065 if (TREE_CODE (type) == RECORD_TYPE)
4066 type = promote_type (type);
4067 JDEP_APPLY_PATCH (dep, type);
4068 SOURCE_FRONTEND_DEBUG
4069 (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
4070 "Completing fct `%s' with ret type `%s'":
4071 "Completing arg `%s' with type `%s'"),
4072 IDENTIFIER_POINTER (EXPR_WFL_NODE
4073 (JDEP_DECL_WFL (dep))),
4074 IDENTIFIER_POINTER (DECL_NAME (decl))));
4075 }
4076 else
4077 error_found = 1;
4078 dep = JDEP_CHAIN (dep);
4079 if (JDEP_KIND (dep) == JDEP_METHOD_END)
4080 break;
4081 else
4082 decl = jdep_resolve_class (dep);
4083 }
4084 if (!error_found)
4085 {
4086 tree mdecl = JDEP_DECL (dep), signature;
4087 push_obstacks (&permanent_obstack, &permanent_obstack);
4088 /* Recompute and reset the signature */
4089 signature = build_java_signature (TREE_TYPE (mdecl));
4090 set_java_signature (TREE_TYPE (mdecl), signature);
4091 pop_obstacks ();
4092 }
4093 else
4094 continue;
4095 break;
4096
4097 case JDEP_INTERFACE:
4098 if (parser_check_super_interface (decl, JDEP_DECL (dep),
4099 JDEP_WFL (dep)))
4100 continue;
4101 parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
4102 break;
4103
4104 case JDEP_PARM:
4105 case JDEP_VARIABLE:
4106 type = TREE_TYPE(decl);
4107 if (TREE_CODE (type) == RECORD_TYPE)
4108 type = promote_type (type);
4109 JDEP_APPLY_PATCH (dep, type);
4110 break;
4111
4112 case JDEP_TYPE:
4113 JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
4114 SOURCE_FRONTEND_DEBUG
4115 (("Completing a random type dependency on a '%s' node",
4116 tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
4117 break;
4118
4119 case JDEP_EXCEPTION:
4120 JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
4121 SOURCE_FRONTEND_DEBUG
4122 (("Completing `%s' `throws' argument node",
4123 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
4124 break;
4125
4126 default:
4127 fatal ("Can't handle patch code %d - java_complete_class",
4128 JDEP_KIND (dep));
4129 }
4130 }
4131 }
4132 pop_obstacks ();
4133 return;
4134 }
4135
4136 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
4137 array. */
4138
4139 static tree
4140 resolve_class (class_type, decl, cl)
4141 tree class_type, decl, cl;
4142 {
4143 char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
4144 char *base = name;
4145 tree resolved_type = TREE_TYPE (class_type);
4146 tree resolved_type_decl;
4147
4148 if (resolved_type != NULL_TREE)
4149 {
4150 tree resolved_type_decl = TYPE_NAME (resolved_type);
4151 if (resolved_type_decl == NULL_TREE
4152 || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
4153 {
4154 resolved_type_decl = build_decl (TYPE_DECL,
4155 TYPE_NAME (class_type),
4156 resolved_type);
4157 }
4158 return resolved_type_decl;
4159 }
4160
4161 /* 1- Check to see if we have an array. If true, find what we really
4162 want to resolve */
4163 while (name[0] == '[')
4164 name++;
4165 if (base != name)
4166 TYPE_NAME (class_type) = get_identifier (name);
4167
4168 /* 2- Resolve the bare type */
4169 if (!(resolved_type_decl = do_resolve_class (class_type, decl, cl)))
4170 return NULL_TREE;
4171 resolved_type = TREE_TYPE (resolved_type_decl);
4172
4173 /* 3- If we have and array, reconstruct the array down to its nesting */
4174 if (base != name)
4175 {
4176 while (base != name)
4177 {
4178 if (TREE_CODE (resolved_type) == RECORD_TYPE)
4179 resolved_type = promote_type (resolved_type);
4180 resolved_type = build_java_array_type (resolved_type, -1);
4181 CLASS_LOADED_P (resolved_type) = 1;
4182 name--;
4183 }
4184 /* Build a fake decl for this, since this is what is expected to
4185 be returned. */
4186 resolved_type_decl =
4187 build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
4188 /* Figure how those two things are important for error report. FIXME */
4189 DECL_SOURCE_LINE (resolved_type_decl) = 0;
4190 DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
4191 TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
4192 }
4193 TREE_TYPE (class_type) = resolved_type;
4194 return resolved_type_decl;
4195 }
4196
4197 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
4198 are used to report error messages. */
4199
4200 tree
4201 do_resolve_class (class_type, decl, cl)
4202 tree class_type;
4203 tree decl;
4204 tree cl;
4205 {
4206 tree new_class_decl;
4207 tree original_name = NULL_TREE;
4208
4209 /* Do not try to replace TYPE_NAME (class_type) by a variable, since
4210 its is changed by find_in_imports{_on_demand} */
4211
4212 /* 1- Check for the type in single imports */
4213 if (find_in_imports (class_type))
4214 return NULL_TREE;
4215
4216 /* 2- And check for the type in the current compilation unit. If it fails,
4217 try with a name qualified with the package name if appropriate. */
4218 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4219 {
4220 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4221 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4222 load_class (TYPE_NAME (class_type), 0);
4223 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4224 }
4225
4226 original_name = TYPE_NAME (class_type);
4227 if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
4228 TYPE_NAME (class_type) = merge_qualified_name (ctxp->package,
4229 TYPE_NAME (class_type));
4230 #if 1
4231 if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4232 load_class (TYPE_NAME (class_type), 0);
4233 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4234 {
4235 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4236 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4237 load_class (TYPE_NAME (class_type), 0);
4238 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4239 }
4240 #else
4241 new_name = TYPE_NAME (class_type);
4242 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_name)) != NULL_TREE)
4243 {
4244 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4245 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4246 load_class (new_name, 0);
4247 return IDENTIFIER_CLASS_VALUE (new_name);
4248 }
4249 else
4250 {
4251 tree class = read_class (new_name);
4252 if (class != NULL_TREE)
4253 {
4254 tree decl = IDENTIFIER_CLASS_VALUE (new_name);
4255 if (decl == NULL_TREE)
4256 decl = push_class (class, new_name);
4257 return decl;
4258 }
4259 }
4260 #endif
4261 TYPE_NAME (class_type) = original_name;
4262
4263 /* 3- Check an other compilation unit that bears the name of type */
4264 load_class (TYPE_NAME (class_type), 0);
4265 if (check_pkg_class_access (TYPE_NAME (class_type),
4266 (cl ? cl : lookup_cl (decl))))
4267 return NULL_TREE;
4268
4269 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4270 return new_class_decl;
4271
4272 /* 4- Check the import on demands. Don't allow bar.baz to be
4273 imported from foo.* */
4274 if (!QUALIFIED_P (TYPE_NAME (class_type)))
4275 if (find_in_imports_on_demand (class_type))
4276 return NULL_TREE;
4277
4278 /* 5- Last call for a resolution */
4279 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4280 }
4281
4282 /* Resolve NAME and lay it out (if not done and if not the current
4283 parsed class). Return a decl node. This function is meant to be
4284 called when type resolution is necessary during the walk pass. */
4285
4286 static tree
4287 resolve_and_layout (something, cl)
4288 tree something;
4289 tree cl;
4290 {
4291 tree decl;
4292
4293 /* Don't do that on the current class */
4294 if (something == current_class)
4295 return TYPE_NAME (current_class);
4296
4297 /* Don't do anything for void and other primitive types */
4298 if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
4299 return NULL_TREE;
4300
4301 /* Pointer types can be reall pointer types or fake pointers. When
4302 finding a real pointer, recheck for primitive types */
4303 if (TREE_CODE (something) == POINTER_TYPE)
4304 {
4305 if (TREE_TYPE (something))
4306 {
4307 something = TREE_TYPE (something);
4308 if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
4309 return NULL_TREE;
4310 }
4311 else
4312 something = TYPE_NAME (something);
4313 }
4314
4315 /* Don't do anything for arrays of primitive types */
4316 if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
4317 && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
4318 return NULL_TREE;
4319
4320 /* If something is not and IDENTIFIER_NODE, it can be a a TYPE_DECL
4321 or a real TYPE */
4322 if (TREE_CODE (something) != IDENTIFIER_NODE)
4323 something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
4324 DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
4325
4326 if (!(decl = resolve_no_layout (something, cl)))
4327 return NULL_TREE;
4328
4329 /* Resolve and layout if necessary */
4330 layout_class_methods (TREE_TYPE (decl));
4331 if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)))
4332 CHECK_METHODS (decl);
4333 if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
4334 safe_layout_class (TREE_TYPE (decl));
4335
4336 return decl;
4337 }
4338
4339 /* Resolve a class, returns its decl but doesn't perform any
4340 layout. The current parsing context is saved and restored */
4341
4342 static tree
4343 resolve_no_layout (name, cl)
4344 tree name, cl;
4345 {
4346 tree ptr, decl;
4347 BUILD_PTR_FROM_NAME (ptr, name);
4348 java_parser_context_save_global ();
4349 decl = resolve_class (ptr, NULL_TREE, cl);
4350 java_parser_context_restore_global ();
4351
4352 return decl;
4353 }
4354
4355 /* Called when reporting errors. Skip leader '[' in a complex array
4356 type description that failed to be resolved. */
4357
4358 static char *
4359 purify_type_name (name)
4360 char *name;
4361 {
4362 while (*name && *name == '[')
4363 name++;
4364 return name;
4365 }
4366
4367 /* The type CURRENT refers to can't be found. We print error messages. */
4368
4369 static void
4370 complete_class_report_errors (dep)
4371 jdep *dep;
4372 {
4373 char *name;
4374
4375 if (!JDEP_WFL (dep))
4376 return;
4377
4378 name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
4379 switch (JDEP_KIND (dep))
4380 {
4381 case JDEP_SUPER:
4382 parse_error_context
4383 (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
4384 purify_type_name (name),
4385 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4386 break;
4387 case JDEP_FIELD:
4388 parse_error_context
4389 (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
4390 purify_type_name (name),
4391 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4392 break;
4393 case JDEP_METHOD: /* Covers arguments */
4394 parse_error_context
4395 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4396 "argument `%s' of method `%s'",
4397 purify_type_name (name),
4398 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
4399 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
4400 break;
4401 case JDEP_METHOD_RETURN: /* Covers return type */
4402 parse_error_context
4403 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4404 "return type of method `%s'",
4405 purify_type_name (name),
4406 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
4407 break;
4408 case JDEP_INTERFACE:
4409 parse_error_context
4410 (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
4411 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
4412 (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
4413 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4414 break;
4415 case JDEP_VARIABLE:
4416 parse_error_context
4417 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4418 "local variable `%s'",
4419 purify_type_name (IDENTIFIER_POINTER
4420 (EXPR_WFL_NODE (JDEP_WFL (dep)))),
4421 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4422 break;
4423 case JDEP_EXCEPTION: /* As specified by `throws' */
4424 parse_error_context
4425 (JDEP_WFL (dep), "Class `%s' not found in `throws'",
4426 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
4427 break;
4428 default:
4429 /* Fix for -Wall. Just break doing nothing. The error will be
4430 caught later */
4431 break;
4432 }
4433 }
4434
4435 /* Check uninitialized final. */
4436
4437 void
4438 java_check_final ()
4439 {
4440 }
4441
4442 /* Return a static string containing the DECL prototype string. If
4443 DECL is a constructor, use the class name instead of the form
4444 <init> */
4445
4446 static char *
4447 get_printable_method_name (decl)
4448 tree decl;
4449 {
4450 char *to_return;
4451 tree name = NULL_TREE;
4452
4453 if (DECL_CONSTRUCTOR_P (decl))
4454 {
4455 name = DECL_NAME (decl);
4456 DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
4457 }
4458
4459 to_return = lang_printable_name (decl, 0);
4460 if (DECL_CONSTRUCTOR_P (decl))
4461 DECL_NAME (decl) = name;
4462
4463 return to_return;
4464 }
4465
4466 /* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
4467 nevertheless needs to be verfied, 1 otherwise. */
4468
4469 static int
4470 reset_method_name (method)
4471 tree method;
4472 {
4473 if (!IS_CLINIT (method) && DECL_NAME (method) != finit_identifier_node)
4474 {
4475 /* NAME is just the plain name when Object is being defined */
4476 if (DECL_CONTEXT (method) != object_type_node)
4477 DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ?
4478 init_identifier_node : GET_METHOD_NAME (method));
4479 return 0;
4480 }
4481 else
4482 return 1;
4483 }
4484
4485 /* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
4486
4487 tree
4488 java_get_real_method_name (method_decl)
4489 tree method_decl;
4490 {
4491 tree method_name = DECL_NAME (method_decl);
4492 if (DECL_CONSTRUCTOR_P (method_decl))
4493 return init_identifier_node;
4494
4495 /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
4496 and still can be a constructor. FIXME */
4497
4498 /* Don't confuse method only bearing the name of their class as
4499 constructors */
4500 else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
4501 && ctxp
4502 && ctxp->current_parsed_class_un == EXPR_WFL_NODE (method_name)
4503 && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
4504 && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
4505 return init_identifier_node;
4506 else
4507 return EXPR_WFL_NODE (method_name);
4508 }
4509
4510 /* Track method being redefined inside the same class. As a side
4511 effect, set DECL_NAME to an IDENTIFIER (prior entering this
4512 function it's a FWL, so we can track errors more accurately */
4513
4514 static int
4515 check_method_redefinition (class, method)
4516 tree class, method;
4517 {
4518 tree redef, name;
4519 tree cl = DECL_NAME (method);
4520 tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
4521 /* decl name of artificial <clinit> and $finit$ doesn't need to be
4522 fixed and checked */
4523
4524 /* Reset the method name before running the check. If it returns 1,
4525 the method doesn't need to be verified with respect to method
4526 redeclaration and we return 0 */
4527 if (reset_method_name (method))
4528 return 0;
4529
4530 name = DECL_NAME (method);
4531 for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
4532 {
4533 if (redef == method)
4534 break;
4535 if (DECL_NAME (redef) == name
4536 && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
4537 {
4538 parse_error_context
4539 (cl, "Duplicate %s declaration `%s'",
4540 (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
4541 get_printable_method_name (redef));
4542 return 1;
4543 }
4544 }
4545 return 0;
4546 }
4547
4548 /* Check all the methods of CLASS. Methods are first completed then
4549 checked according to regular method existance rules.
4550 If no constructor were encountered, then build its declaration. */
4551
4552 static void
4553 java_check_regular_methods (class_decl)
4554 tree class_decl;
4555 {
4556 int saw_constructor = 0;
4557 tree method;
4558 tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
4559 tree super_class = CLASSTYPE_SUPER (class);
4560 tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
4561 tree mthrows;
4562
4563 /* It is not necessary to check methods defined in java.lang.Object */
4564 if (class == object_type_node)
4565 return;
4566
4567 if (!TYPE_NVIRTUALS (class))
4568 TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
4569
4570 /* Should take interfaces into account. FIXME */
4571 for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
4572 {
4573 tree sig;
4574 tree method_wfl = DECL_NAME (method);
4575 int aflags;
4576
4577 /* If we previously found something and its name was saved,
4578 reinstall it now */
4579 if (found && saved_found_wfl)
4580 {
4581 DECL_NAME (found) = saved_found_wfl;
4582 saved_found_wfl = NULL_TREE;
4583 }
4584
4585 /* Check for redefinitions */
4586 if (check_method_redefinition (class, method))
4587 continue;
4588
4589 /* If we see one constructor a mark so we don't generate the
4590 default one. Also skip other verifications: constructors
4591 can't be inherited hence hiden or overriden */
4592 if (DECL_CONSTRUCTOR_P (method))
4593 {
4594 saw_constructor = 1;
4595 continue;
4596 }
4597
4598 /* We verify things thrown by the method. They must inherits from
4599 java.lang.Throwable */
4600 for (mthrows = DECL_FUNCTION_THROWS (method);
4601 mthrows; mthrows = TREE_CHAIN (mthrows))
4602 {
4603 if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
4604 parse_error_context
4605 (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be "
4606 "a subclass of class `java.lang.Throwable'",
4607 IDENTIFIER_POINTER
4608 (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
4609 }
4610
4611 sig = build_java_argument_signature (TREE_TYPE (method));
4612 found = lookup_argument_method (super_class, DECL_NAME (method), sig);
4613
4614 /* Nothing overrides or it's a private method. */
4615 if (!found)
4616 continue;
4617 if (METHOD_PRIVATE (found))
4618 {
4619 found = NULL_TREE;
4620 continue;
4621 }
4622
4623 /* If found wasn't verified, it's DECL_NAME won't be set properly.
4624 We set it temporarily for the sake of the error report. */
4625 saved_found_wfl = DECL_NAME (found);
4626 reset_method_name (found);
4627
4628 /* Can't override a method with the same name and different return
4629 types. */
4630 if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
4631 {
4632 char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
4633 0));
4634 parse_error_context
4635 (method_wfl,
4636 "Method `%s' was defined with return type `%s' in class `%s'",
4637 lang_printable_name (found, 0), t,
4638 IDENTIFIER_POINTER
4639 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4640 free (t);
4641 }
4642
4643 aflags = get_access_flags_from_decl (found);
4644 /* If the method has default, access in an other package, then
4645 issue a warning that the current method doesn't override the
4646 one that was found elsewhere. Do not issue this warning when
4647 the match was found in java.lang.Object. */
4648 if (DECL_CONTEXT (found) != object_type_node
4649 && ((aflags & 0x7) == 0)
4650 && !class_in_current_package (DECL_CONTEXT (found))
4651 && DECL_NAME (found) != clinit_identifier_node
4652 && flag_not_overriding)
4653 {
4654 parse_warning_context
4655 (method_wfl, "Method `%s' in class `%s' does not "
4656 "override the corresponding method in class `%s', which is "
4657 "private to a different package",
4658 lang_printable_name (found, 0),
4659 IDENTIFIER_POINTER (DECL_NAME (class_decl)),
4660 IDENTIFIER_POINTER (DECL_NAME
4661 (TYPE_NAME (DECL_CONTEXT (found)))));
4662 continue;
4663 }
4664
4665 /* Can't override final. Can't override static. */
4666 if (METHOD_FINAL (found) || METHOD_STATIC (found))
4667 {
4668 /* Static *can* override static */
4669 if (METHOD_STATIC (found) && METHOD_STATIC (method))
4670 continue;
4671 parse_error_context
4672 (method_wfl,
4673 "%s methods can't be overriden. Method `%s' is %s in class `%s'",
4674 (METHOD_FINAL (found) ? "Final" : "Static"),
4675 lang_printable_name (found, 0),
4676 (METHOD_FINAL (found) ? "final" : "static"),
4677 IDENTIFIER_POINTER
4678 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4679 continue;
4680 }
4681
4682 /* Static method can't override instance method. */
4683 if (METHOD_STATIC (method))
4684 {
4685 parse_error_context
4686 (method_wfl,
4687 "Instance methods can't be overriden by a static method. Method "
4688 "`%s' is an instance method in class `%s'",
4689 lang_printable_name (found, 0),
4690 IDENTIFIER_POINTER
4691 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4692 continue;
4693 }
4694
4695 /* - Overriding/hiding public must be public
4696 - Overriding/hiding protected must be protected or public
4697 - If the overriden or hidden method has default (package)
4698 access, then the overriding or hiding method must not be
4699 private; otherwise, a compile-time error occurs */
4700 if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
4701 || (METHOD_PROTECTED (found)
4702 && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
4703 || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
4704 && METHOD_PRIVATE (method)))
4705 {
4706 parse_error_context
4707 (method_wfl,
4708 "Methods can't be overridden to be more private. Method `%s' is "
4709 "not %s in class `%s'", lang_printable_name (method, 0),
4710 (METHOD_PUBLIC (method) ? "public" :
4711 (METHOD_PRIVATE (method) ? "private" : "protected")),
4712 IDENTIFIER_POINTER (DECL_NAME
4713 (TYPE_NAME (DECL_CONTEXT (found)))));
4714 continue;
4715 }
4716
4717 /* Overriding methods must have compatible `throws' clauses on checked
4718 exceptions, if any */
4719 check_throws_clauses (method, method_wfl, found);
4720
4721 /* Inheriting multiple methods with the same signature. FIXME */
4722 }
4723
4724 /* Don't forget eventual pending found and saved_found_wfl. Take
4725 into account that we might have exited because we saw an
4726 aritifical method as the last entry. */
4727
4728 if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
4729 DECL_NAME (found) = saved_found_wfl;
4730
4731 if (!TYPE_NVIRTUALS (class))
4732 TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
4733
4734 if (!saw_constructor)
4735 {
4736 /* No constructor seen, we craft one, at line 0. Since this
4737 operation takes place after we laid methods out
4738 (layout_class_methods), we prepare the its DECL
4739 appropriately. */
4740 int flags;
4741 tree decl;
4742
4743 /* If the class is declared PUBLIC, the default constructor is
4744 PUBLIC otherwise it has default access implied by no access
4745 modifiers. */
4746 flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
4747 ACC_PUBLIC : 0);
4748 decl = create_artificial_method (class, flags, void_type_node,
4749 init_identifier_node, end_params_node);
4750 DECL_CONSTRUCTOR_P (decl) = 1;
4751 layout_class_method (TREE_TYPE (class_decl), NULL_TREE, decl, NULL_TREE);
4752 }
4753 }
4754
4755 /* Return a non zero value if the `throws' clause of METHOD (if any)
4756 is incompatible with the `throws' clause of FOUND (if any). */
4757
4758 static void
4759 check_throws_clauses (method, method_wfl, found)
4760 tree method, method_wfl, found;
4761 {
4762 tree mthrows, fthrows;
4763
4764 /* Can't check these things with class loaded from bytecode. FIXME */
4765 if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
4766 return;
4767
4768 for (mthrows = DECL_FUNCTION_THROWS (method);
4769 mthrows; mthrows = TREE_CHAIN (mthrows))
4770 {
4771 /* We don't verify unchecked expressions */
4772 if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
4773 continue;
4774 /* Checked expression must be compatible */
4775 for (fthrows = DECL_FUNCTION_THROWS (found);
4776 fthrows; fthrows = TREE_CHAIN (fthrows))
4777 if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
4778 break;
4779 if (!fthrows)
4780 {
4781 parse_error_context
4782 (method_wfl, "Invalid checked exception class `%s' in "
4783 "`throws' clause. The exception must be a subclass of an "
4784 "exception thrown by `%s' from class `%s'",
4785 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
4786 lang_printable_name (found, 0),
4787 IDENTIFIER_POINTER
4788 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4789 }
4790 }
4791 }
4792
4793 /* Check abstract method of interface INTERFACE */
4794
4795 static void
4796 java_check_abstract_methods (interface_decl)
4797 tree interface_decl;
4798 {
4799 int i, n;
4800 tree method, basetype_vec, found;
4801 tree interface = TREE_TYPE (interface_decl);
4802
4803 for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
4804 {
4805 tree method_wfl = DECL_NAME (method);
4806
4807 /* 2- Check for double definition inside the defining interface */
4808 if (check_method_redefinition (interface, method))
4809 continue;
4810
4811 /* 3- Overriding is OK as far as we preserve the return type and
4812 the thrown exceptions (FIXME) */
4813 found = lookup_java_interface_method2 (interface, method);
4814 if (found)
4815 {
4816 char *t;
4817 tree saved_found_wfl = DECL_NAME (found);
4818 reset_method_name (found);
4819 t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
4820 parse_error_context
4821 (method_wfl,
4822 "Method `%s' was defined with return type `%s' in class `%s'",
4823 lang_printable_name (found, 0), t,
4824 IDENTIFIER_POINTER
4825 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4826 free (t);
4827 continue;
4828
4829 DECL_NAME (found) = saved_found_wfl;
4830 }
4831 }
4832
4833 /* 4- Inherited methods can't differ by their returned types */
4834 if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
4835 return;
4836 n = TREE_VEC_LENGTH (basetype_vec);
4837 for (i = 0; i < n; i++)
4838 {
4839 tree sub_interface_method, sub_interface;
4840 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4841 if (!vec_elt)
4842 continue;
4843 sub_interface = BINFO_TYPE (vec_elt);
4844 for (sub_interface_method = TYPE_METHODS (sub_interface);
4845 sub_interface_method;
4846 sub_interface_method = TREE_CHAIN (sub_interface_method))
4847 {
4848 found = lookup_java_interface_method2 (interface,
4849 sub_interface_method);
4850 if (found && (found != sub_interface_method))
4851 {
4852 tree saved_found_wfl = DECL_NAME (found);
4853 reset_method_name (found);
4854 parse_error_context
4855 (lookup_cl (sub_interface_method),
4856 "Interface `%s' inherits method `%s' from interface `%s'. "
4857 "This method is redefined with a different return type in "
4858 "interface `%s'",
4859 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
4860 lang_printable_name (found, 0),
4861 IDENTIFIER_POINTER
4862 (DECL_NAME (TYPE_NAME
4863 (DECL_CONTEXT (sub_interface_method)))),
4864 IDENTIFIER_POINTER
4865 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4866 DECL_NAME (found) = saved_found_wfl;
4867 }
4868 }
4869 }
4870 }
4871
4872 /* Lookup methods in interfaces using their name and partial
4873 signature. Return a matching method only if their types differ. */
4874
4875 static tree
4876 lookup_java_interface_method2 (class, method_decl)
4877 tree class, method_decl;
4878 {
4879 int i, n;
4880 tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
4881
4882 if (!basetype_vec)
4883 return NULL_TREE;
4884
4885 n = TREE_VEC_LENGTH (basetype_vec);
4886 for (i = 0; i < n; i++)
4887 {
4888 tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
4889 if ((BINFO_TYPE (vec_elt) != object_type_node)
4890 && (to_return =
4891 lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
4892 return to_return;
4893 }
4894 for (i = 0; i < n; i++)
4895 {
4896 to_return = lookup_java_interface_method2
4897 (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
4898 if (to_return)
4899 return to_return;
4900 }
4901
4902 return NULL_TREE;
4903 }
4904
4905 /* Lookup method using their name and partial signature. Return a
4906 matching method only if their types differ. */
4907
4908 static tree
4909 lookup_java_method2 (clas, method_decl, do_interface)
4910 tree clas, method_decl;
4911 int do_interface;
4912 {
4913 tree method, method_signature, method_name, method_type, name;
4914
4915 method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
4916 name = DECL_NAME (method_decl);
4917 method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
4918 EXPR_WFL_NODE (name) : name);
4919 method_type = TREE_TYPE (TREE_TYPE (method_decl));
4920
4921 while (clas != NULL_TREE)
4922 {
4923 for (method = TYPE_METHODS (clas);
4924 method != NULL_TREE; method = TREE_CHAIN (method))
4925 {
4926 tree method_sig = build_java_argument_signature (TREE_TYPE (method));
4927 tree name = DECL_NAME (method);
4928 if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
4929 EXPR_WFL_NODE (name) : name) == method_name
4930 && method_sig == method_signature
4931 && TREE_TYPE (TREE_TYPE (method)) != method_type)
4932 return method;
4933 }
4934 clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
4935 }
4936 return NULL_TREE;
4937 }
4938
4939 /* Return the line that matches DECL line number. Used during error
4940 report */
4941
4942 static tree
4943 lookup_cl (decl)
4944 tree decl;
4945 {
4946 static tree cl = NULL_TREE;
4947
4948 if (!decl)
4949 return NULL_TREE;
4950
4951 if (cl == NULL_TREE)
4952 cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
4953
4954 EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
4955 EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
4956
4957 return cl;
4958 }
4959
4960 /* Look for a simple name in the single-type import list */
4961
4962 static tree
4963 find_name_in_single_imports (name)
4964 tree name;
4965 {
4966 tree node;
4967
4968 for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
4969 if (TREE_VALUE (node) == name)
4970 return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
4971
4972 return NULL_TREE;
4973 }
4974
4975 /* Process all single-type import. */
4976
4977 static int
4978 process_imports ()
4979 {
4980 tree import;
4981 int error_found;
4982
4983 for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
4984 {
4985 tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
4986
4987 /* Don't load twice something already defined. */
4988 if (IDENTIFIER_CLASS_VALUE (to_be_found))
4989 continue;
4990 QUALIFIED_P (to_be_found) = 1;
4991 load_class (to_be_found, 0);
4992 error_found =
4993 check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
4994 if (!IDENTIFIER_CLASS_VALUE (to_be_found))
4995 {
4996 parse_error_context (TREE_PURPOSE (import),
4997 "Class or interface `%s' not found in import",
4998 IDENTIFIER_POINTER (to_be_found));
4999 return 1;
5000 }
5001 if (error_found)
5002 return 1;
5003 }
5004 return 0;
5005 }
5006
5007 /* Possibly find a class imported by a single-type import statement. Return
5008 1 if an error occured, 0 otherwise. */
5009
5010 static int
5011 find_in_imports (class_type)
5012 tree class_type;
5013 {
5014 tree import;
5015
5016 for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
5017 if (TREE_VALUE (import) == TYPE_NAME (class_type))
5018 {
5019 TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
5020 QUALIFIED_P (TYPE_NAME (class_type)) = 1;
5021 }
5022 return 0;
5023 }
5024
5025 static int
5026 note_possible_classname (name, len)
5027 char *name;
5028 int len;
5029 {
5030 tree node;
5031 if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
5032 len = len - 5;
5033 else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
5034 len = len - 6;
5035 else
5036 return 0;
5037 node = ident_subst (name, len, "", '/', '.', "");
5038 IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
5039 QUALIFIED_P (node) = 1; /* As soon as we turn / into . */
5040 return 1;
5041 }
5042
5043 /* Read a import directory, gathering potential match for further type
5044 references. Indifferently reads a filesystem or a ZIP archive
5045 directory. */
5046
5047 static void
5048 read_import_dir (wfl)
5049 tree wfl;
5050 {
5051 tree package_id = EXPR_WFL_NODE (wfl);
5052 char *package_name = IDENTIFIER_POINTER (package_id);
5053 int package_length = IDENTIFIER_LENGTH (package_id);
5054 DIR *dirp = NULL;
5055 JCF *saved_jcf = current_jcf;
5056
5057 int found = 0;
5058 int k;
5059 void *entry;
5060 struct buffer filename[1];
5061
5062
5063 if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
5064 return;
5065 IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
5066
5067 BUFFER_INIT (filename);
5068 buffer_grow (filename, package_length + 100);
5069
5070 for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
5071 {
5072 char *entry_name = jcf_path_name (entry);
5073 int entry_length = strlen (entry_name);
5074 if (jcf_path_is_zipfile (entry))
5075 {
5076 ZipFile *zipf;
5077 buffer_grow (filename, entry_length);
5078 memcpy (filename->data, entry_name, entry_length - 1);
5079 filename->data[entry_length-1] = '\0';
5080 zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
5081 if (zipf == NULL)
5082 error ("malformed .zip archive in CLASSPATH: %s", entry_name);
5083 else
5084 {
5085 ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
5086 BUFFER_RESET (filename);
5087 for (k = 0; k < package_length; k++)
5088 {
5089 char ch = package_name[k];
5090 *filename->ptr++ = ch == '.' ? '/' : ch;
5091 }
5092 *filename->ptr++ = '/';
5093
5094 for (k = 0; k < zipf->count; k++, zipd = ZIPDIR_NEXT (zipd))
5095 {
5096 char *current_entry = ZIPDIR_FILENAME (zipd);
5097 int current_entry_len = zipd->filename_length;
5098
5099 if (current_entry_len >= BUFFER_LENGTH (filename)
5100 && strncmp (filename->data, current_entry,
5101 BUFFER_LENGTH (filename)) != 0)
5102 continue;
5103 found |= note_possible_classname (current_entry,
5104 current_entry_len);
5105 }
5106 }
5107 }
5108 else
5109 {
5110 BUFFER_RESET (filename);
5111 buffer_grow (filename, entry_length + package_length + 4);
5112 strcpy (filename->data, entry_name);
5113 filename->ptr = filename->data + entry_length;
5114 for (k = 0; k < package_length; k++)
5115 {
5116 char ch = package_name[k];
5117 *filename->ptr++ = ch == '.' ? '/' : ch;
5118 }
5119 *filename->ptr = '\0';
5120
5121 dirp = opendir (filename->data);
5122 if (dirp == NULL)
5123 continue;
5124 *filename->ptr++ = '/';
5125 for (;;)
5126 {
5127 int len;
5128 char *d_name;
5129 struct dirent *direntp = readdir (dirp);
5130 if (!direntp)
5131 break;
5132 d_name = direntp->d_name;
5133 len = strlen (direntp->d_name);
5134 buffer_grow (filename, len+1);
5135 strcpy (filename->ptr, d_name);
5136 found |= note_possible_classname (filename->data + entry_length,
5137 package_length+len+1);
5138 }
5139 if (dirp)
5140 closedir (dirp);
5141 }
5142 }
5143
5144 free (filename->data);
5145
5146 /* Here we should have a unified way of retrieving an entry, to be
5147 indexed. */
5148 if (!found)
5149 {
5150 static int first = 1;
5151 if (first)
5152 {
5153 char buffer [256];
5154 sprintf (buffer, "Can't find default package `%s'. Check "
5155 "the CLASSPATH environment variable and the access to the "
5156 "archives.", package_name);
5157 error (buffer);
5158 java_error_count++;
5159 first = 0;
5160 }
5161 else
5162 parse_error_context (wfl, "Package `%s' not found in import",
5163 package_name);
5164 current_jcf = saved_jcf;
5165 return;
5166 }
5167 current_jcf = saved_jcf;
5168 }
5169
5170 /* Possibly find a type in the import on demands specified
5171 types. Returns 1 if an error occured, 0 otherwise. Run throught the
5172 entire list, to detected potential double definitions. */
5173
5174 static int
5175 find_in_imports_on_demand (class_type)
5176 tree class_type;
5177 {
5178 tree node, import, node_to_use = NULL_TREE;
5179 int seen_once = -1;
5180 tree cl = NULL_TREE;
5181
5182 for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
5183 {
5184 char *id_name;
5185 obstack_grow (&temporary_obstack,
5186 IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
5187 IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
5188 obstack_1grow (&temporary_obstack, '.');
5189 obstack_grow0 (&temporary_obstack,
5190 IDENTIFIER_POINTER (TYPE_NAME (class_type)),
5191 IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
5192 id_name = obstack_finish (&temporary_obstack);
5193
5194 node = maybe_get_identifier (id_name);
5195 if (node && IS_A_CLASSFILE_NAME (node))
5196 {
5197 if (seen_once < 0)
5198 {
5199 cl = TREE_PURPOSE (import);
5200 seen_once = 1;
5201 node_to_use = node;
5202 }
5203 else
5204 {
5205 seen_once++;
5206 parse_error_context
5207 (import, "Type `%s' also potentially defined in package `%s'",
5208 IDENTIFIER_POINTER (TYPE_NAME (class_type)),
5209 IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
5210 }
5211 }
5212 }
5213
5214 if (seen_once == 1)
5215 {
5216 /* Setup lineno so that it refers to the line of the import (in
5217 case we parse a class file and encounter errors */
5218 tree decl;
5219 int saved_lineno = lineno;
5220 lineno = EXPR_WFL_LINENO (cl);
5221 TYPE_NAME (class_type) = node_to_use;
5222 QUALIFIED_P (TYPE_NAME (class_type)) = 1;
5223 decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5224 /* If there is no DECL set for the class or if the class isn't
5225 loaded and not seen in source yet, the load */
5226 if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
5227 && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
5228 load_class (node_to_use, 0);
5229 lineno = saved_lineno;
5230 return check_pkg_class_access (TYPE_NAME (class_type), cl);
5231 }
5232 else
5233 return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
5234 }
5235
5236 static tree
5237 resolve_package (pkg, next)
5238 tree pkg, *next;
5239 {
5240 tree type_name = NULL_TREE;
5241 char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
5242
5243 /* The trick is to determine when the package name stops and were
5244 the name of something contained in the package starts. Then we
5245 return a fully qualified name of what we want to get. */
5246
5247 /* Do a quick search on well known package names */
5248 if (!strncmp (name, "java.lang.reflect", 17))
5249 {
5250 *next =
5251 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
5252 type_name = lookup_package_type (name, 17);
5253 }
5254 else if (!strncmp (name, "java.lang", 9))
5255 {
5256 *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
5257 type_name = lookup_package_type (name, 9);
5258 }
5259 else
5260 return NULL_TREE; /* FIXME, search all imported packages. */
5261
5262 return type_name;
5263 }
5264
5265 static tree
5266 lookup_package_type (name, from)
5267 char *name;
5268 int from;
5269 {
5270 char subname [128];
5271 char *sub = &name[from+1];
5272 while (*sub != '.' && *sub)
5273 sub++;
5274 strncpy (subname, name, sub-name);
5275 subname [sub-name] = '\0';
5276 return get_identifier (subname);
5277 }
5278
5279 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
5280 access violations were found, 1 otherwise. */
5281
5282 static int
5283 check_pkg_class_access (class_name, cl)
5284 tree class_name;
5285 tree cl;
5286 {
5287 tree type;
5288
5289 if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
5290 return 0;
5291
5292 if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
5293 return 0;
5294
5295 if (!CLASS_PUBLIC (TYPE_NAME (type)))
5296 {
5297 /* Access to a private class within the same package is
5298 allowed. */
5299 tree l, r;
5300 breakdown_qualified (&l, &r, class_name);
5301 if (l == ctxp->package)
5302 return 0;
5303
5304 parse_error_context
5305 (cl, "Can't access %s `%s'. Only public classes and interfaces in "
5306 "other packages can be accessed",
5307 (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
5308 IDENTIFIER_POINTER (class_name));
5309 return 1;
5310 }
5311 return 0;
5312 }
5313
5314 /* Local variable declaration. */
5315
5316 static void
5317 declare_local_variables (modifier, type, vlist)
5318 int modifier;
5319 tree type;
5320 tree vlist;
5321 {
5322 tree decl, current, saved_type;
5323 tree type_wfl = NULL_TREE;
5324 int must_chain = 0;
5325
5326 /* Push a new block if statements were seen between the last time we
5327 pushed a block and now. Keep a cound of block to close */
5328 if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
5329 {
5330 tree body = GET_CURRENT_BLOCK (current_function_decl);
5331 tree b = enter_block ();
5332 BLOCK_EXPR_ORIGIN (b) = body;
5333 }
5334
5335 if (modifier)
5336 {
5337 int i;
5338 for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
5339 if (modifier == ACC_FINAL)
5340 {
5341 if (flag_static_local_jdk1_1)
5342 parse_warning_context (ctxp->modifier_ctx [i],
5343 "Unsupported JDK1.1 `final' local variable "
5344 "(treated as non final)");
5345 }
5346 else
5347 {
5348 parse_error_context
5349 (ctxp->modifier_ctx [i],
5350 "Only `final' is allowed as a local variables modifier");
5351 return;
5352 }
5353 }
5354
5355 /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
5356 hold the TYPE value if a new incomplete has to be created (as
5357 opposed to being found already existing and reused). */
5358 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
5359
5360 /* If TYPE is fully resolved and we don't have a reference, make one */
5361 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
5362
5363 /* Go through all the declared variables */
5364 for (current = vlist, saved_type = type; current;
5365 current = TREE_CHAIN (current), type = saved_type)
5366 {
5367 tree other, real_type;
5368 tree wfl = TREE_PURPOSE (current);
5369 tree name = EXPR_WFL_NODE (wfl);
5370 tree init = TREE_VALUE (current);
5371
5372 /* Process NAME, as it may specify extra dimension(s) for it */
5373 type = build_array_from_name (type, type_wfl, name, &name);
5374
5375 /* Variable redefinition check */
5376 if ((other = lookup_name_in_blocks (name)))
5377 {
5378 variable_redefinition_error (wfl, name, TREE_TYPE (other),
5379 DECL_SOURCE_LINE (other));
5380 continue;
5381 }
5382
5383 /* Type adjustment. We may have just readjusted TYPE because
5384 the variable specified more dimensions. Make sure we have
5385 a reference if we can and don't have one already. */
5386 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
5387
5388 real_type = GET_REAL_TYPE (type);
5389 /* Never layout this decl. This will be done when its scope
5390 will be entered */
5391 decl = build_decl (VAR_DECL, name, real_type);
5392 BLOCK_CHAIN_DECL (decl);
5393
5394 /* If doing xreferencing, replace the line number with the WFL
5395 compound value */
5396 if (flag_emit_xref)
5397 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
5398
5399 /* Don't try to use an INIT statement when an error was found */
5400 if (init && java_error_count)
5401 init = NULL_TREE;
5402
5403 /* Add the initialization function to the current function's code */
5404 if (init)
5405 {
5406 /* Name might have been readjusted */
5407 EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
5408 MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
5409 java_method_add_stmt (current_function_decl,
5410 build_debugable_stmt (EXPR_WFL_LINECOL (init),
5411 init));
5412 }
5413
5414 /* Setup dependency the type of the decl */
5415 if (must_chain)
5416 {
5417 jdep *dep;
5418 register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
5419 dep = CLASSD_LAST (ctxp->classd_list);
5420 JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
5421 }
5422 }
5423 SOURCE_FRONTEND_DEBUG (("Defined locals"));
5424 }
5425
5426 /* Called during parsing. Build decls from argument list. */
5427
5428 static void
5429 source_start_java_method (fndecl)
5430 tree fndecl;
5431 {
5432 tree tem;
5433 tree parm_decl;
5434 int i;
5435
5436 current_function_decl = fndecl;
5437
5438 /* New scope for the function */
5439 enter_block ();
5440 for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
5441 tem != end_params_node; tem = TREE_CHAIN (tem), i++)
5442 {
5443 tree type = TREE_VALUE (tem);
5444 tree name = TREE_PURPOSE (tem);
5445
5446 /* If type is incomplete. Create an incomplete decl and ask for
5447 the decl to be patched later */
5448 if (INCOMPLETE_TYPE_P (type))
5449 {
5450 jdep *jdep;
5451 tree real_type = GET_REAL_TYPE (type);
5452 parm_decl = build_decl (PARM_DECL, name, real_type);
5453 type = obtain_incomplete_type (type);
5454 register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
5455 jdep = CLASSD_LAST (ctxp->classd_list);
5456 JDEP_MISC (jdep) = name;
5457 JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
5458 }
5459 else
5460 parm_decl = build_decl (PARM_DECL, name, type);
5461
5462 BLOCK_CHAIN_DECL (parm_decl);
5463 }
5464 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
5465 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
5466 nreverse (tem);
5467 DECL_ARG_SLOT_COUNT (current_function_decl) = i;
5468 }
5469
5470 /* Called during parsing. Creates an artificial method declaration. */
5471
5472 static tree
5473 create_artificial_method (class, flags, type, name, args)
5474 tree class;
5475 int flags;
5476 tree type, name, args;
5477 {
5478 int saved_lineno = lineno;
5479 tree mdecl;
5480
5481 lineno = 0;
5482 mdecl = make_node (FUNCTION_TYPE);
5483 TREE_TYPE (mdecl) = type;
5484 TYPE_ARG_TYPES (mdecl) = args;
5485 mdecl = add_method (class, flags, name, build_java_signature (mdecl));
5486 lineno = saved_lineno;
5487 DECL_ARTIFICIAL (mdecl) = 1;
5488 return mdecl;
5489 }
5490
5491 /* Starts the body if an artifical method. */
5492
5493 static void
5494 start_artificial_method_body (mdecl)
5495 tree mdecl;
5496 {
5497 DECL_SOURCE_LINE (mdecl) = 1;
5498 DECL_SOURCE_LINE_MERGE (mdecl, 1);
5499 source_start_java_method (mdecl);
5500 enter_block ();
5501 }
5502
5503 static void
5504 end_artificial_method_body (mdecl)
5505 tree mdecl;
5506 {
5507 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
5508 exit_block ();
5509 }
5510
5511 /* Called during expansion. Push decls formerly built from argument
5512 list so they're usable during expansion. */
5513
5514 static void
5515 expand_start_java_method (fndecl)
5516 tree fndecl;
5517 {
5518 tree tem, *ptr;
5519
5520 current_function_decl = fndecl;
5521
5522 announce_function (fndecl);
5523 pushlevel (1); /* Push parameters */
5524 ptr = &DECL_ARGUMENTS (fndecl);
5525 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
5526 while (tem)
5527 {
5528 tree next = TREE_CHAIN (tem);
5529 tree type = TREE_TYPE (tem);
5530 #ifdef PROMOTE_PROTOTYPES
5531 if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
5532 && INTEGRAL_TYPE_P (type))
5533 type = integer_type_node;
5534 #endif
5535 DECL_ARG_TYPE (tem) = type;
5536 layout_decl (tem, 0);
5537 pushdecl (tem);
5538 *ptr = tem;
5539 ptr = &TREE_CHAIN (tem);
5540 tem = next;
5541 }
5542 *ptr = NULL_TREE;
5543 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
5544 lineno = DECL_SOURCE_LINE_FIRST (fndecl);
5545 }
5546
5547 /* Terminate a function and expand its body. */
5548
5549 static void
5550 source_end_java_method ()
5551 {
5552 tree fndecl = current_function_decl;
5553 int flag_asynchronous_exceptions = asynchronous_exceptions;
5554
5555 java_parser_context_save_global ();
5556 lineno = ctxp->last_ccb_indent1;
5557
5558 /* Set EH language codes */
5559 java_set_exception_lang_code ();
5560
5561 /* Turn function bodies with only a NOP expr null, so they don't get
5562 generated at all and we won't get warnings when using the -W
5563 -Wall flags. */
5564 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
5565 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
5566
5567 /* Generate function's code */
5568 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
5569 && ! flag_emit_class_files
5570 && ! flag_emit_xref)
5571 expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
5572
5573 /* pop out of its parameters */
5574 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
5575 poplevel (1, 0, 1);
5576 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5577
5578 /* Generate rtl for function exit. */
5579 if (! flag_emit_class_files && ! flag_emit_xref)
5580 {
5581 lineno = DECL_SOURCE_LINE_LAST (fndecl);
5582 /* Emit catch-finally clauses */
5583 emit_handlers ();
5584 expand_function_end (input_filename, lineno, 0);
5585
5586 /* FIXME: If the current method contains any exception handlers,
5587 force asynchronous_exceptions: this is necessary because signal
5588 handlers in libjava may throw exceptions. This is far from being
5589 a perfect solution, but it's better than doing nothing at all.*/
5590 if (catch_clauses)
5591 asynchronous_exceptions = 1;
5592
5593 /* Run the optimizers and output assembler code for this function. */
5594 rest_of_compilation (fndecl);
5595 }
5596
5597 current_function_decl = NULL_TREE;
5598 /* permanent_allocation (1); */
5599 java_parser_context_restore_global ();
5600 asynchronous_exceptions = flag_asynchronous_exceptions;
5601 }
5602
5603 /* Record EXPR in the current function block. Complements compound
5604 expression second operand if necessary. */
5605
5606 tree
5607 java_method_add_stmt (fndecl, expr)
5608 tree fndecl, expr;
5609 {
5610 return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
5611 }
5612
5613 static tree
5614 add_stmt_to_block (b, type, stmt)
5615 tree b, type, stmt;
5616 {
5617 tree body = BLOCK_EXPR_BODY (b), c;
5618
5619 if (java_error_count)
5620 return body;
5621
5622 if ((c = add_stmt_to_compound (body, type, stmt)) == body)
5623 return body;
5624
5625 BLOCK_EXPR_BODY (b) = c;
5626 TREE_SIDE_EFFECTS (c) = 1;
5627 return c;
5628 }
5629
5630 /* Add STMT to EXISTING if possible, otherwise create a new
5631 COMPOUND_EXPR and add STMT to it. */
5632
5633 static tree
5634 add_stmt_to_compound (existing, type, stmt)
5635 tree existing, type, stmt;
5636 {
5637 if (existing)
5638 return build (COMPOUND_EXPR, type, existing, stmt);
5639 else
5640 return stmt;
5641 }
5642
5643 /* Hold THIS for the scope of the current public method decl. */
5644 static tree current_this;
5645
5646 void java_layout_seen_class_methods ()
5647 {
5648 tree previous_list = all_class_list;
5649 tree end = NULL_TREE;
5650 tree current;
5651
5652 while (1)
5653 {
5654 for (current = previous_list;
5655 current != end; current = TREE_CHAIN (current))
5656 layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
5657
5658 if (previous_list != all_class_list)
5659 {
5660 end = previous_list;
5661 previous_list = all_class_list;
5662 }
5663 else
5664 break;
5665 }
5666 }
5667
5668 /* Layout the methods of all classes loaded in one way on an
5669 other. Check methods of source parsed classes. Then reorder the
5670 fields and layout the classes or the type of all source parsed
5671 classes */
5672
5673 void
5674 java_layout_classes ()
5675 {
5676 tree current;
5677 int save_error_count = java_error_count;
5678
5679 /* Layout the methods of all classes seen so far */
5680 java_layout_seen_class_methods ();
5681 java_parse_abort_on_error ();
5682 all_class_list = NULL_TREE;
5683
5684 /* Then check the methods of all parsed classes */
5685 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
5686 if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
5687 CHECK_METHODS (TREE_VALUE (current));
5688 java_parse_abort_on_error ();
5689
5690 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
5691 {
5692 current_class = TREE_TYPE (TREE_VALUE (current));
5693
5694 /* Reverse the fields, but leave the dummy field in front.
5695 Fields are already ordered for Object and Class */
5696 if (TYPE_FIELDS (current_class) && current_class != object_type_node
5697 && current_class != class_type_node)
5698 {
5699 /* If the dummy field is there, reverse the right fields and
5700 just layout the type for proper fields offset */
5701 if (!DECL_NAME (TYPE_FIELDS (current_class)))
5702 {
5703 tree fields = TYPE_FIELDS (current_class);
5704 TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
5705 TYPE_SIZE (current_class) = NULL_TREE;
5706 layout_type (current_class);
5707 }
5708 /* We don't have a dummy field, we need to layout the class,
5709 after having reversed the fields */
5710 else
5711 {
5712 TYPE_FIELDS (current_class) =
5713 nreverse (TYPE_FIELDS (current_class));
5714 TYPE_SIZE (current_class) = NULL_TREE;
5715 layout_class (current_class);
5716 }
5717 }
5718 else
5719 layout_class (current_class);
5720
5721 /* From now on, the class is considered completely loaded */
5722 CLASS_LOADED_P (current_class) = 1;
5723
5724 /* Error reported by the caller */
5725 if (java_error_count)
5726 return;
5727 }
5728
5729 /* We might have reloaded classes durign the process of laying out
5730 classes for code generation. We must layout the methods of those
5731 late additions, as constructor checks might use them */
5732 java_layout_seen_class_methods ();
5733 java_parse_abort_on_error ();
5734 }
5735
5736 /* Expand all methods in all registered classes. */
5737
5738 void
5739 java_complete_expand_methods ()
5740 {
5741 tree current;
5742
5743 do_not_fold = flag_emit_xref;
5744
5745 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5746 {
5747 int is_interface;
5748 tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
5749 tree decl;
5750
5751 current_class = TREE_TYPE (current);
5752 is_interface = CLASS_INTERFACE (TYPE_NAME (current_class));
5753
5754 /* Initialize a new constant pool */
5755 init_outgoing_cpool ();
5756
5757 /* We want <clinit> (if any) to be processed first. */
5758 decl = tree_last (TYPE_METHODS (class_type));
5759 if (IS_CLINIT (decl))
5760 {
5761 tree fbody = DECL_FUNCTION_BODY (decl);
5762 tree list;
5763 if (fbody != NULL_TREE)
5764 {
5765 /* First check if we can ignore empty <clinit> */
5766 tree block_body = BLOCK_EXPR_BODY (fbody);
5767
5768 current_this = NULL_TREE;
5769 current_function_decl = decl;
5770 if (block_body != NULL_TREE)
5771 {
5772 /* Prevent the use of `this' inside <clinit> */
5773 ctxp->explicit_constructor_p = 1;
5774
5775 block_body = java_complete_tree (block_body);
5776 ctxp->explicit_constructor_p = 0;
5777 BLOCK_EXPR_BODY (fbody) = block_body;
5778 if (block_body != NULL_TREE
5779 && TREE_CODE (block_body) == BLOCK
5780 && BLOCK_EXPR_BODY (block_body) == empty_stmt_node)
5781 decl = NULL_TREE;
5782 }
5783 }
5784 list = nreverse (TREE_CHAIN (nreverse (TYPE_METHODS (class_type))));
5785 if (decl != NULL_TREE)
5786 {
5787 TREE_CHAIN (decl) = list;
5788 TYPE_METHODS (class_type) = decl;
5789 }
5790 else
5791 TYPE_METHODS (class_type) = list;
5792 }
5793
5794 for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5795 {
5796 current_function_decl = decl;
5797 /* Don't generate debug info on line zero when expanding a
5798 generated constructor. */
5799 if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl))
5800 {
5801 /* If we found errors, it's too dangerous to try to
5802 generate and expand a constructor */
5803 if (!java_error_count)
5804 {
5805 restore_line_number_status (1);
5806 java_complete_expand_method (decl);
5807 restore_line_number_status (0);
5808 }
5809 }
5810 else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
5811 continue;
5812 else
5813 java_complete_expand_method (decl);
5814 }
5815
5816 /* Now verify constructor circularity (stop after the first one
5817 we find) */
5818 if (!is_interface)
5819 for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5820 if (DECL_CONSTRUCTOR_P (decl) &&
5821 verify_constructor_circularity (decl, decl))
5822 break;
5823
5824 /* Make the class data, register it and run the rest of decl
5825 compilation on it */
5826 if (!java_error_count)
5827 {
5828 if (flag_emit_class_files)
5829 write_classfile (current_class);
5830 if (flag_emit_xref)
5831 expand_xref (current_class);
5832 else if (! flag_syntax_only)
5833 finish_class (current_class);
5834 }
5835 }
5836 }
5837
5838 /* Hold a list of catch clauses list. The first element of this list is
5839 the list of the catch clauses of the currently analysed try block. */
5840 static tree currently_caught_type_list;
5841
5842 /* Complete and expand a method. */
5843
5844 static void
5845 java_complete_expand_method (mdecl)
5846 tree mdecl;
5847 {
5848 /* Fix constructors before expanding them */
5849 if (DECL_CONSTRUCTOR_P (mdecl))
5850 fix_constructors (mdecl);
5851
5852 /* Expand functions that have a body */
5853 if (DECL_FUNCTION_BODY (mdecl))
5854 {
5855 tree fbody = DECL_FUNCTION_BODY (mdecl);
5856 tree block_body = BLOCK_EXPR_BODY (fbody);
5857 tree exception_copy;
5858 expand_start_java_method (mdecl);
5859 build_result_decl (mdecl);
5860
5861 current_this
5862 = (!METHOD_STATIC (mdecl) ?
5863 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
5864
5865 /* Purge the `throws' list of unchecked exceptions. If we're
5866 doing xref, save a copy of the list and re-install it
5867 later. */
5868 if (flag_emit_xref)
5869 exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
5870
5871 purge_unchecked_exceptions (mdecl);
5872
5873 /* Install exceptions thrown with `throws' */
5874 PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
5875
5876 if (block_body != NULL_TREE)
5877 {
5878 block_body = java_complete_tree (block_body);
5879 if (!flag_emit_xref)
5880 check_for_initialization (block_body);
5881 ctxp->explicit_constructor_p = 0;
5882 }
5883 BLOCK_EXPR_BODY (fbody) = block_body;
5884
5885 if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
5886 && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
5887 && !flag_emit_xref)
5888 missing_return_error (current_function_decl);
5889
5890 complete_start_java_method (mdecl);
5891
5892 /* Don't go any further if we've found error(s) during the
5893 expansion */
5894 if (!java_error_count)
5895 source_end_java_method ();
5896 else
5897 {
5898 pushdecl_force_head (DECL_ARGUMENTS (mdecl));
5899 poplevel (1, 0, 1);
5900 }
5901
5902 /* Pop the exceptions and sanity check */
5903 POP_EXCEPTIONS();
5904 if (currently_caught_type_list)
5905 fatal ("Exception list non empty - java_complete_expand_method");
5906
5907 if (flag_emit_xref)
5908 DECL_FUNCTION_THROWS (mdecl) = exception_copy;
5909 }
5910 }
5911
5912 /* Craft a body for default constructor. Patch existing constructor
5913 bodies with call to super() and field initialization statements if
5914 necessary. */
5915
5916 static void
5917 fix_constructors (mdecl)
5918 tree mdecl;
5919 {
5920 tree body = DECL_FUNCTION_BODY (mdecl);
5921
5922 if (!body)
5923 {
5924 /* The constructor body must be crafted by hand. It's the
5925 constructor we defined when we realize we didn't have the
5926 CLASSNAME() constructor */
5927
5928 tree compound;
5929
5930 /* It is an error for the compiler to generate a default
5931 constructor if the superclass doesn't have a constructor that
5932 takes no argument */
5933 if (verify_constructor_super ())
5934 {
5935 tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (current_class));
5936 char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
5937 parse_error_context (lookup_cl (TYPE_NAME (current_class)),
5938 "No constructor matching `%s()' found in "
5939 "class `%s'", n, n);
5940 }
5941
5942 start_artificial_method_body (mdecl);
5943
5944 /* We don't generate a super constructor invocation if we're
5945 compiling java.lang.Object. build_super_invocation takes care
5946 of that. */
5947 compound = java_method_add_stmt (mdecl, build_super_invocation ());
5948
5949 end_artificial_method_body (mdecl);
5950 }
5951 /* Search for an explicit constructor invocation */
5952 else
5953 {
5954 int found = 0;
5955 tree main_block = BLOCK_EXPR_BODY (body);
5956 tree compound = NULL_TREE;
5957
5958 while (body)
5959 switch (TREE_CODE (body))
5960 {
5961 case CALL_EXPR:
5962 found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
5963 body = NULL_TREE;
5964 break;
5965 case COMPOUND_EXPR:
5966 case EXPR_WITH_FILE_LOCATION:
5967 body = TREE_OPERAND (body, 0);
5968 break;
5969 case BLOCK:
5970 body = BLOCK_EXPR_BODY (body);
5971 break;
5972 default:
5973 found = 0;
5974 body = NULL_TREE;
5975 }
5976 /* The constructor is missing an invocation of super() */
5977 if (!found)
5978 compound = add_stmt_to_compound (compound, NULL_TREE,
5979 build_super_invocation ());
5980
5981 /* Fix the constructor main block if we're adding extra stmts */
5982 if (compound)
5983 {
5984 compound = add_stmt_to_compound (compound, NULL_TREE,
5985 BLOCK_EXPR_BODY (main_block));
5986 BLOCK_EXPR_BODY (main_block) = compound;
5987 }
5988 }
5989 }
5990
5991 /* Browse constructors in the super class, searching for a constructor
5992 that doesn't take any argument. Return 0 if one is found, 1
5993 otherwise. */
5994
5995 static int
5996 verify_constructor_super ()
5997 {
5998 tree class = CLASSTYPE_SUPER (current_class);
5999 if (!class)
6000 return 0;
6001
6002 if (class)
6003 {
6004 tree mdecl;
6005 for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
6006 {
6007 if (DECL_CONSTRUCTOR_P (mdecl)
6008 && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) == end_params_node)
6009 return 0;
6010 }
6011 }
6012 return 1;
6013 }
6014
6015 /* Expand finals. */
6016
6017 void
6018 java_expand_finals ()
6019 {
6020 }
6021
6022 /* Generate code for all context remembered for code generation. */
6023
6024 void
6025 java_expand_classes ()
6026 {
6027 int save_error_count = 0;
6028 java_parse_abort_on_error ();
6029 if (!(ctxp = ctxp_for_generation))
6030 return;
6031 java_layout_classes ();
6032 java_parse_abort_on_error ();
6033
6034 for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
6035 {
6036 ctxp = ctxp_for_generation;
6037 lang_init_source (2); /* Error msgs have method prototypes */
6038 java_complete_expand_methods (); /* Complete and expand method bodies */
6039 java_parse_abort_on_error ();
6040 java_expand_finals (); /* Expand and check the finals */
6041 java_parse_abort_on_error ();
6042 java_check_final (); /* Check unitialized final */
6043 java_parse_abort_on_error ();
6044 }
6045 }
6046
6047 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
6048 a tree list node containing RIGHT. Fore coming RIGHTs will be
6049 chained to this hook. LOCATION contains the location of the
6050 separating `.' operator. */
6051
6052 static tree
6053 make_qualified_primary (primary, right, location)
6054 tree primary, right;
6055 int location;
6056 {
6057 tree wfl;
6058
6059 /* We want to process THIS . xxx symbolicaly, to keep it consistent
6060 with the way we're processing SUPER. A THIS from a primary as a
6061 different form than a SUPER. Turn THIS into something symbolic */
6062 if (TREE_CODE (primary) == THIS_EXPR)
6063 {
6064 wfl = build_wfl_node (this_identifier_node);
6065 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
6066 wfl = make_qualified_name (wfl, right, location);
6067 PRIMARY_P (wfl) = 1;
6068 return wfl;
6069 }
6070 /* Other non WFL node are wrapped around a WFL */
6071 else if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
6072 {
6073 wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
6074 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
6075 EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (primary, NULL_TREE);
6076 }
6077 else
6078 {
6079 wfl = primary;
6080 if (!EXPR_WFL_QUALIFICATION (primary))
6081 EXPR_WFL_QUALIFICATION (primary) =
6082 build_tree_list (primary, NULL_TREE);
6083 }
6084
6085 EXPR_WFL_LINECOL (right) = location;
6086 chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
6087 PRIMARY_P (wfl) = 1;
6088 return wfl;
6089 }
6090
6091 /* Simple merge of two name separated by a `.' */
6092
6093 static tree
6094 merge_qualified_name (left, right)
6095 tree left, right;
6096 {
6097 tree node;
6098 obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
6099 IDENTIFIER_LENGTH (left));
6100 obstack_1grow (&temporary_obstack, '.');
6101 obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
6102 IDENTIFIER_LENGTH (right));
6103 node = get_identifier (obstack_base (&temporary_obstack));
6104 obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
6105 QUALIFIED_P (node) = 1;
6106 return node;
6107 }
6108
6109 /* Merge the two parts of a qualified name into LEFT. Set the
6110 location information of the resulting node to LOCATION, usually
6111 inherited from the location information of the `.' operator. */
6112
6113 static tree
6114 make_qualified_name (left, right, location)
6115 tree left, right;
6116 int location;
6117 {
6118 #ifdef USE_COMPONENT_REF
6119 tree node = build (COMPONENT_REF, NULL_TREE, left, right);
6120 EXPR_WFL_LINECOL (node) = location;
6121 return node;
6122 #else
6123 tree left_id = EXPR_WFL_NODE (left);
6124 tree right_id = EXPR_WFL_NODE (right);
6125 tree wfl, merge;
6126
6127 merge = merge_qualified_name (left_id, right_id);
6128
6129 /* Left wasn't qualified and is now qualified */
6130 if (!QUALIFIED_P (left_id))
6131 {
6132 tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
6133 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
6134 EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
6135 }
6136
6137 wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
6138 EXPR_WFL_LINECOL (wfl) = location;
6139 chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
6140
6141 EXPR_WFL_NODE (left) = merge;
6142 return left;
6143 #endif
6144 }
6145
6146 /* Extract the last identifier component of the qualified in WFL. The
6147 last identifier is removed from the linked list */
6148
6149 static tree
6150 cut_identifier_in_qualified (wfl)
6151 tree wfl;
6152 {
6153 tree q;
6154 tree previous = NULL_TREE;
6155 for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
6156 if (!TREE_CHAIN (q))
6157 {
6158 if (!previous)
6159 fatal ("Operating on a non qualified qualified WFL - "
6160 "cut_identifier_in_qualified");
6161 TREE_CHAIN (previous) = NULL_TREE;
6162 return TREE_PURPOSE (q);
6163 }
6164 }
6165
6166 /* Resolve the expression name NAME. Return its decl. */
6167
6168 static tree
6169 resolve_expression_name (id, orig)
6170 tree id;
6171 tree *orig;
6172 {
6173 tree name = EXPR_WFL_NODE (id);
6174 tree decl;
6175
6176 /* 6.5.5.1: Simple expression names */
6177 if (!PRIMARY_P (id) && !QUALIFIED_P (name))
6178 {
6179 /* 15.13.1: NAME can appear within the scope of a local variable
6180 declaration */
6181 if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
6182 return decl;
6183
6184 /* 15.13.1: NAME can appear within a class declaration */
6185 else
6186 {
6187 decl = lookup_field_wrapper (current_class, name);
6188 if (decl)
6189 {
6190 int fs = FIELD_STATIC (decl);
6191 /* Instance variable (8.3.1.1) can't appear within
6192 static method, static initializer or initializer for
6193 a static variable. */
6194 if (!fs && METHOD_STATIC (current_function_decl))
6195 {
6196 static_ref_err (id, name, current_class);
6197 return error_mark_node;
6198 }
6199 /* Instance variables can't appear as an argument of
6200 an explicit constructor invocation */
6201 if (!fs && ctxp->explicit_constructor_p)
6202 {
6203 parse_error_context
6204 (id, "Can't reference `%s' before the superclass "
6205 "constructor has been called", IDENTIFIER_POINTER (name));
6206 return error_mark_node;
6207 }
6208
6209 /* Otherwise build what it takes to access the field */
6210 decl = build_field_ref ((fs ? NULL_TREE : current_this),
6211 DECL_CONTEXT (decl), name);
6212 if (fs && !flag_emit_class_files && !flag_emit_xref)
6213 decl = build_class_init (DECL_CONTEXT (decl), decl);
6214 /* We may be asked to save the real field access node */
6215 if (orig)
6216 *orig = decl;
6217 /* And we return what we got */
6218 return decl;
6219 }
6220 /* Fall down to error report on undefined variable */
6221 }
6222 }
6223 /* 6.5.5.2 Qualified Expression Names */
6224 else
6225 {
6226 if (orig)
6227 *orig = NULL_TREE;
6228 qualify_ambiguous_name (id);
6229 /* 15.10.1 Field Access Using a Primary and/or Expression Name */
6230 /* 15.10.2: Accessing Superclass Members using super */
6231 return resolve_field_access (id, NULL, NULL);
6232 }
6233
6234 /* We've got an error here */
6235 parse_error_context (id, "Undefined variable `%s'",
6236 IDENTIFIER_POINTER (name));
6237
6238 return error_mark_node;
6239 }
6240
6241 static void
6242 static_ref_err (wfl, field_id, class_type)
6243 tree wfl, field_id, class_type;
6244 {
6245 parse_error_context
6246 (wfl,
6247 "Can't make a static reference to nonstatic variable `%s' in class `%s'",
6248 IDENTIFIER_POINTER (field_id),
6249 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
6250 }
6251
6252 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
6253 We return something suitable to generate the field access. We also
6254 return the field decl in FIELD_DECL and its type in FIELD_TYPE. If
6255 recipient's address can be null. */
6256
6257 static tree
6258 resolve_field_access (qual_wfl, field_decl, field_type)
6259 tree qual_wfl;
6260 tree *field_decl, *field_type;
6261 {
6262 int is_static = 0;
6263 tree field_ref;
6264 tree decl, where_found, type_found;
6265
6266 if (resolve_qualified_expression_name (qual_wfl, &decl,
6267 &where_found, &type_found))
6268 return error_mark_node;
6269
6270 /* Resolve the LENGTH field of an array here */
6271 if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
6272 && ! flag_emit_class_files && ! flag_emit_xref)
6273 {
6274 tree length = build_java_array_length_access (where_found);
6275 field_ref =
6276 build_java_arraynull_check (type_found, length, int_type_node);
6277 }
6278 /* We might have been trying to resolve field.method(). In which
6279 case, the resolution is over and decl is the answer */
6280 else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
6281 field_ref = decl;
6282 else if (JDECL_P (decl))
6283 {
6284 int static_final_found = 0;
6285 if (!type_found)
6286 type_found = DECL_CONTEXT (decl);
6287 is_static = JDECL_P (decl) && FIELD_STATIC (decl);
6288 if (FIELD_FINAL (decl)
6289 && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
6290 && DECL_LANG_SPECIFIC (decl)
6291 && DECL_INITIAL (decl))
6292 {
6293 field_ref = DECL_INITIAL (decl);
6294 static_final_found = 1;
6295 }
6296 else
6297 field_ref = build_field_ref ((is_static && !flag_emit_xref?
6298 NULL_TREE : where_found),
6299 type_found, DECL_NAME (decl));
6300 if (field_ref == error_mark_node)
6301 return error_mark_node;
6302 if (is_static && !static_final_found
6303 && !flag_emit_class_files && !flag_emit_xref)
6304 {
6305 field_ref = build_class_init (type_found, field_ref);
6306 /* If the static field was identified by an expression that
6307 needs to be generated, make the field access a compound
6308 expression whose first part is the evaluation of the
6309 field selector part. */
6310 if (where_found && TREE_CODE (where_found) != TYPE_DECL
6311 && TREE_CODE (where_found) != RECORD_TYPE)
6312 {
6313 tree type = QUAL_DECL_TYPE (field_ref);
6314 field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
6315 }
6316 }
6317 }
6318 else
6319 field_ref = decl;
6320
6321 if (field_decl)
6322 *field_decl = decl;
6323 if (field_type)
6324 *field_type = (QUAL_DECL_TYPE (decl) ?
6325 QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
6326 return field_ref;
6327 }
6328
6329 /* If NODE is an access to f static field, strip out the class
6330 initialization part and return the field decl, otherwise, return
6331 NODE. */
6332
6333 static tree
6334 strip_out_static_field_access_decl (node)
6335 tree node;
6336 {
6337 if (TREE_CODE (node) == COMPOUND_EXPR)
6338 {
6339 tree op1 = TREE_OPERAND (node, 1);
6340 if (TREE_CODE (op1) == COMPOUND_EXPR)
6341 {
6342 tree call = TREE_OPERAND (op1, 0);
6343 if (TREE_CODE (call) == CALL_EXPR
6344 && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
6345 && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
6346 == soft_initclass_node)
6347 return TREE_OPERAND (op1, 1);
6348 }
6349 }
6350 return node;
6351 }
6352
6353 /* 6.5.5.2: Qualified Expression Names */
6354
6355 static int
6356 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
6357 tree wfl;
6358 tree *found_decl, *type_found, *where_found;
6359 {
6360 int from_type = 0; /* Field search initiated from a type */
6361 int from_super = 0, from_cast = 0;
6362 int previous_call_static = 0;
6363 int is_static;
6364 tree decl = NULL_TREE, type = NULL_TREE, q;
6365 *type_found = *where_found = NULL_TREE;
6366
6367 for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
6368 {
6369 tree qual_wfl = QUAL_WFL (q);
6370
6371 /* 15.10.1 Field Access Using a Primary */
6372 switch (TREE_CODE (qual_wfl))
6373 {
6374 case CALL_EXPR:
6375 case NEW_CLASS_EXPR:
6376 /* If the access to the function call is a non static field,
6377 build the code to access it. */
6378 if (JDECL_P (decl) && !FIELD_STATIC (decl))
6379 {
6380 decl = maybe_access_field (decl, *where_found,
6381 DECL_CONTEXT (decl));
6382 if (decl == error_mark_node)
6383 return 1;
6384 }
6385 /* And code for the function call */
6386 if (complete_function_arguments (qual_wfl))
6387 return 1;
6388 if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
6389 CALL_USING_SUPER (qual_wfl) = 1;
6390 *where_found =
6391 patch_method_invocation (qual_wfl, decl, type, &is_static, NULL);
6392 if (*where_found == error_mark_node)
6393 return 1;
6394 *type_found = type = QUAL_DECL_TYPE (*where_found);
6395
6396 /* If the previous call was static and this one is too,
6397 build a compound expression to hold the two (because in
6398 that case, previous function calls aren't transported as
6399 forcoming function's argument. */
6400 if (previous_call_static && is_static)
6401 {
6402 decl = build (COMPOUND_EXPR, type, decl, *where_found);
6403 TREE_SIDE_EFFECTS (decl) = 1;
6404 }
6405 else
6406 {
6407 previous_call_static = is_static;
6408 decl = *where_found;
6409 }
6410 continue;
6411
6412 case NEW_ARRAY_EXPR:
6413 *where_found = decl = java_complete_tree (qual_wfl);
6414 if (decl == error_mark_node)
6415 return 1;
6416 *type_found = type = QUAL_DECL_TYPE (decl);
6417 CLASS_LOADED_P (type) = 1;
6418 continue;
6419
6420 case CONVERT_EXPR:
6421 *where_found = decl = java_complete_tree (qual_wfl);
6422 if (decl == error_mark_node)
6423 return 1;
6424 *type_found = type = QUAL_DECL_TYPE (decl);
6425 from_cast = 1;
6426 continue;
6427
6428 case CONDITIONAL_EXPR:
6429 case STRING_CST:
6430 *where_found = decl = java_complete_tree (qual_wfl);
6431 if (decl == error_mark_node)
6432 return 1;
6433 *type_found = type = QUAL_DECL_TYPE (decl);
6434 continue;
6435
6436 case ARRAY_REF:
6437 /* If the access to the function call is a non static field,
6438 build the code to access it. */
6439 if (JDECL_P (decl) && !FIELD_STATIC (decl))
6440 {
6441 decl = maybe_access_field (decl, *where_found, type);
6442 if (decl == error_mark_node)
6443 return 1;
6444 }
6445 /* And code for the array reference expression */
6446 decl = java_complete_tree (qual_wfl);
6447 if (decl == error_mark_node)
6448 return 1;
6449 type = QUAL_DECL_TYPE (decl);
6450 continue;
6451
6452 default:
6453 /* Fix for -Wall Just go to the next statement. Don't
6454 continue */
6455 break;
6456 }
6457
6458 /* If we fall here, we weren't processing a (static) function call. */
6459 previous_call_static = 0;
6460
6461 /* It can be the keyword THIS */
6462 if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
6463 {
6464 if (!current_this)
6465 {
6466 parse_error_context
6467 (wfl, "Keyword `this' used outside allowed context");
6468 return 1;
6469 }
6470 /* We have to generate code for intermediate acess */
6471 *where_found = decl = current_this;
6472 *type_found = type = QUAL_DECL_TYPE (decl);
6473 continue;
6474 }
6475
6476 /* 15.10.2 Accessing Superclass Members using SUPER */
6477 if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
6478 {
6479 tree node;
6480 /* Check on the restricted use of SUPER */
6481 if (METHOD_STATIC (current_function_decl)
6482 || current_class == object_type_node)
6483 {
6484 parse_error_context
6485 (wfl, "Keyword `super' used outside allowed context");
6486 return 1;
6487 }
6488 /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
6489 node = build_cast (EXPR_WFL_LINECOL (qual_wfl),
6490 CLASSTYPE_SUPER (current_class),
6491 build_this (EXPR_WFL_LINECOL (qual_wfl)));
6492 *where_found = decl = java_complete_tree (node);
6493 if (decl == error_mark_node)
6494 return 1;
6495 *type_found = type = QUAL_DECL_TYPE (decl);
6496 from_super = from_type = 1;
6497 continue;
6498 }
6499
6500 /* 15.13.1: Can't search for field name in packages, so we
6501 assume a variable/class name was meant. */
6502 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
6503 {
6504 tree name = resolve_package (wfl, &q);
6505 if (name)
6506 {
6507 *where_found = decl = resolve_no_layout (name, qual_wfl);
6508 /* We wan't to be absolutely that the class is laid
6509 out. We're going to search something inside it. */
6510 *type_found = type = TREE_TYPE (decl);
6511 layout_class (type);
6512 from_type = 1;
6513 /* Should be a list, really. FIXME */
6514 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 1;
6515 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 0;
6516 }
6517 else
6518 {
6519 if (from_super || from_cast)
6520 parse_error_context
6521 ((from_cast ? qual_wfl : wfl),
6522 "No variable `%s' defined in class `%s'",
6523 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
6524 lang_printable_name (type, 0));
6525 else
6526 parse_error_context
6527 (qual_wfl, "Undefined variable or class name: `%s'",
6528 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
6529 return 1;
6530 }
6531 }
6532
6533 /* We have a type name. It's been already resolved when the
6534 expression was qualified. */
6535 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
6536 {
6537 if (!(decl = QUAL_RESOLUTION (q)))
6538 return 1; /* Error reported already */
6539
6540 if (not_accessible_p (TREE_TYPE (decl), decl, 0))
6541 {
6542 parse_error_context
6543 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
6544 java_accstring_lookup (get_access_flags_from_decl (decl)),
6545 GET_TYPE_NAME (type),
6546 IDENTIFIER_POINTER (DECL_NAME (decl)),
6547 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
6548 return 1;
6549 }
6550 check_deprecation (qual_wfl, decl);
6551
6552 type = TREE_TYPE (decl);
6553 from_type = 1;
6554 }
6555 /* We resolve and expression name */
6556 else
6557 {
6558 tree field_decl;
6559
6560 /* If there exists an early resolution, use it. That occurs
6561 only once and we know that there are more things to
6562 come. Don't do that when processing something after SUPER
6563 (we need more thing to be put in place below */
6564 if (!from_super && QUAL_RESOLUTION (q))
6565 {
6566 decl = QUAL_RESOLUTION (q);
6567 if (!type)
6568 {
6569 if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
6570 {
6571 if (current_this)
6572 *where_found = current_this;
6573 else
6574 {
6575 static_ref_err (qual_wfl, DECL_NAME (decl),
6576 current_class);
6577 return 1;
6578 }
6579 }
6580 else
6581 {
6582 *where_found = TREE_TYPE (decl);
6583 if (TREE_CODE (*where_found) == POINTER_TYPE)
6584 *where_found = TREE_TYPE (*where_found);
6585 }
6586 }
6587 }
6588
6589 /* We have to search for a field, knowing the type of its
6590 container. The flag FROM_TYPE indicates that we resolved
6591 the last member of the expression as a type name, which
6592 means that for the resolution of this field, we'll look
6593 for other errors than if it was resolved as a member of
6594 an other field. */
6595 else
6596 {
6597 int is_static;
6598 tree field_decl_type; /* For layout */
6599
6600 if (!from_type && !JREFERENCE_TYPE_P (type))
6601 {
6602 parse_error_context
6603 (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
6604 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
6605 lang_printable_name (type, 0),
6606 IDENTIFIER_POINTER (DECL_NAME (field_decl)));
6607 return 1;
6608 }
6609
6610 field_decl = lookup_field_wrapper (type,
6611 EXPR_WFL_NODE (qual_wfl));
6612 if (field_decl == NULL_TREE)
6613 {
6614 parse_error_context
6615 (qual_wfl, "No variable `%s' defined in type `%s'",
6616 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
6617 GET_TYPE_NAME (type));
6618 return 1;
6619 }
6620 if (field_decl == error_mark_node)
6621 return 1;
6622
6623 /* Layout the type of field_decl, since we may need
6624 it. Don't do primitive types or loaded classes. The
6625 situation of non primitive arrays may not handled
6626 properly here. FIXME */
6627 if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
6628 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
6629 else
6630 field_decl_type = TREE_TYPE (field_decl);
6631 if (!JPRIMITIVE_TYPE_P (field_decl_type)
6632 && !CLASS_LOADED_P (field_decl_type)
6633 && !TYPE_ARRAY_P (field_decl_type))
6634 resolve_and_layout (field_decl_type, NULL_TREE);
6635 if (TYPE_ARRAY_P (field_decl_type))
6636 CLASS_LOADED_P (field_decl_type) = 1;
6637
6638 /* Check on accessibility here */
6639 if (not_accessible_p (type, field_decl, from_super))
6640 {
6641 parse_error_context
6642 (qual_wfl,
6643 "Can't access %s field `%s.%s' from `%s'",
6644 java_accstring_lookup
6645 (get_access_flags_from_decl (field_decl)),
6646 GET_TYPE_NAME (type),
6647 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
6648 IDENTIFIER_POINTER
6649 (DECL_NAME (TYPE_NAME (current_class))));
6650 return 1;
6651 }
6652 check_deprecation (qual_wfl, field_decl);
6653
6654 /* There are things to check when fields are accessed
6655 from type. There are no restrictions on a static
6656 declaration of the field when it is accessed from an
6657 interface */
6658 is_static = FIELD_STATIC (field_decl);
6659 if (!from_super && from_type
6660 && !TYPE_INTERFACE_P (type) && !is_static)
6661 {
6662 static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
6663 return 1;
6664 }
6665 from_cast = from_super = 0;
6666
6667 /* If we need to generate something to get a proper
6668 handle on what this field is accessed from, do it
6669 now. */
6670 if (!is_static)
6671 {
6672 decl = maybe_access_field (decl, *where_found, *type_found);
6673 if (decl == error_mark_node)
6674 return 1;
6675 }
6676
6677 /* We want to keep the location were found it, and the type
6678 we found. */
6679 *where_found = decl;
6680 *type_found = type;
6681
6682 /* This is the decl found and eventually the next one to
6683 search from */
6684 decl = field_decl;
6685 }
6686 from_type = 0;
6687 type = QUAL_DECL_TYPE (decl);
6688 }
6689 }
6690 *found_decl = decl;
6691 return 0;
6692 }
6693
6694 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
6695 can't be accessed from REFERENCE (a record type). */
6696
6697 int not_accessible_p (reference, member, from_super)
6698 tree reference, member;
6699 int from_super;
6700 {
6701 int access_flag = get_access_flags_from_decl (member);
6702
6703 /* Access always granted for members declared public */
6704 if (access_flag & ACC_PUBLIC)
6705 return 0;
6706
6707 /* Check access on protected members */
6708 if (access_flag & ACC_PROTECTED)
6709 {
6710 /* Access granted if it occurs from within the package
6711 containing the class in which the protected member is
6712 declared */
6713 if (class_in_current_package (DECL_CONTEXT (member)))
6714 return 0;
6715
6716 /* If accessed with the form `super.member', then access is granted */
6717 if (from_super)
6718 return 0;
6719
6720 /* Otherwise, access is granted if occuring from the class where
6721 member is declared or a subclass of it */
6722 if (inherits_from_p (reference, current_class))
6723 return 0;
6724 return 1;
6725 }
6726
6727 /* Check access on private members. Access is granted only if it
6728 occurs from within the class in witch it is declared */
6729 if (access_flag & ACC_PRIVATE)
6730 return (current_class == DECL_CONTEXT (member) ? 0 : 1);
6731
6732 /* Default access are permitted only when occuring within the
6733 package in which the type (REFERENCE) is declared. In other words,
6734 REFERENCE is defined in the current package */
6735 if (ctxp->package)
6736 return !class_in_current_package (reference);
6737
6738 /* Otherwise, access is granted */
6739 return 0;
6740 }
6741
6742 /* Test deprecated decl access. */
6743 static void
6744 check_deprecation (wfl, decl)
6745 tree wfl, decl;
6746 {
6747 char *file = DECL_SOURCE_FILE (decl);
6748 /* Complain if the field is deprecated and the file it was defined
6749 in isn't compiled at the same time the file which contains its
6750 use is */
6751 if (DECL_DEPRECATED (decl)
6752 && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
6753 {
6754 char the [20];
6755 switch (TREE_CODE (decl))
6756 {
6757 case FUNCTION_DECL:
6758 strcpy (the, "method");
6759 break;
6760 case FIELD_DECL:
6761 strcpy (the, "field");
6762 break;
6763 case TYPE_DECL:
6764 strcpy (the, "class");
6765 break;
6766 default:
6767 fatal ("unexpected DECL code - check_deprecation");
6768 }
6769 parse_warning_context
6770 (wfl, "The %s `%s' in class `%s' has been deprecated",
6771 the, lang_printable_name (decl, 0),
6772 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
6773 }
6774 }
6775
6776 /* Returns 1 if class was declared in the current package, 0 otherwise */
6777
6778 static int
6779 class_in_current_package (class)
6780 tree class;
6781 {
6782 static tree cache = NULL_TREE;
6783 int qualified_flag;
6784 tree left;
6785
6786 if (cache == class)
6787 return 1;
6788
6789 qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
6790
6791 /* If the current package is empty and the name of CLASS is
6792 qualified, class isn't in the current package. If there is a
6793 current package and the name of the CLASS is not qualified, class
6794 isn't in the current package */
6795 if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
6796 return 0;
6797
6798 /* If there is not package and the name of CLASS isn't qualified,
6799 they belong to the same unnamed package */
6800 if (!ctxp->package && !qualified_flag)
6801 return 1;
6802
6803 /* Compare the left part of the name of CLASS with the package name */
6804 breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
6805 if (ctxp->package == left)
6806 {
6807 cache = class;
6808 return 1;
6809 }
6810 return 0;
6811 }
6812
6813 /* This function may generate code to access DECL from WHERE. This is
6814 done only if certain conditions meet. */
6815
6816 static tree
6817 maybe_access_field (decl, where, type)
6818 tree decl, where, type;
6819 {
6820 if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
6821 && !FIELD_STATIC (decl))
6822 decl = build_field_ref (where ? where : current_this,
6823 (type ? type : DECL_CONTEXT (decl)),
6824 DECL_NAME (decl));
6825 return decl;
6826 }
6827
6828 /* Build a method invocation, by patching PATCH. If non NULL
6829 and according to the situation, PRIMARY and WHERE may be
6830 used. IS_STATIC is set to 1 if the invoked function is static. */
6831
6832 static tree
6833 patch_method_invocation (patch, primary, where, is_static, ret_decl)
6834 tree patch, primary, where;
6835 int *is_static;
6836 tree *ret_decl;
6837 {
6838 tree wfl = TREE_OPERAND (patch, 0);
6839 tree args = TREE_OPERAND (patch, 1);
6840 tree name = EXPR_WFL_NODE (wfl);
6841 tree list;
6842 int is_static_flag = 0;
6843 int is_super_init = 0;
6844 tree this_arg = NULL_TREE;
6845
6846 /* Should be overriden if everything goes well. Otherwise, if
6847 something fails, it should keep this value. It stop the
6848 evaluation of a bogus assignment. See java_complete_tree,
6849 MODIFY_EXPR: for the reasons why we sometimes want to keep on
6850 evaluating an assignment */
6851 TREE_TYPE (patch) = error_mark_node;
6852
6853 /* Since lookup functions are messing with line numbers, save the
6854 context now. */
6855 java_parser_context_save_global ();
6856
6857 /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
6858
6859 /* Resolution of qualified name, excluding constructors */
6860 if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
6861 {
6862 tree class_decl, identifier, identifier_wfl;
6863 /* Extract the last IDENTIFIER of the qualified
6864 expression. This is a wfl and we will use it's location
6865 data during error report. */
6866 identifier_wfl = cut_identifier_in_qualified (wfl);
6867 identifier = EXPR_WFL_NODE (identifier_wfl);
6868
6869 /* Given the context, IDENTIFIER is syntactically qualified
6870 as a MethodName. We need to qualify what's before */
6871 qualify_ambiguous_name (wfl);
6872
6873 /* Package resolution are erroneous */
6874 if (RESOLVE_PACKAGE_NAME_P (wfl))
6875 {
6876 tree remainder;
6877 breakdown_qualified (&remainder, NULL, EXPR_WFL_NODE (wfl));
6878 parse_error_context (wfl, "Can't search method `%s' in package "
6879 "`%s'",IDENTIFIER_POINTER (identifier),
6880 IDENTIFIER_POINTER (remainder));
6881 PATCH_METHOD_RETURN_ERROR ();
6882 }
6883 /* We're resolving a call from a type */
6884 else if (RESOLVE_TYPE_NAME_P (wfl))
6885 {
6886 tree decl = QUAL_RESOLUTION (EXPR_WFL_QUALIFICATION (wfl));
6887 tree name = DECL_NAME (decl);
6888 tree type;
6889
6890 class_decl = resolve_and_layout (name, wfl);
6891 if (CLASS_INTERFACE (decl))
6892 {
6893 parse_error_context
6894 (identifier_wfl, "Can't make static reference to method "
6895 "`%s' in interface `%s'", IDENTIFIER_POINTER (identifier),
6896 IDENTIFIER_POINTER (name));
6897 PATCH_METHOD_RETURN_ERROR ();
6898 }
6899 /* Look the method up in the type selector. The method ought
6900 to be static. */
6901 type = TREE_TYPE (class_decl);
6902 list = lookup_method_invoke (0, wfl, type, identifier, args);
6903 if (list && !METHOD_STATIC (list))
6904 {
6905 char *fct_name = strdup (lang_printable_name (list, 0));
6906 parse_error_context
6907 (identifier_wfl,
6908 "Can't make static reference to method `%s %s' in class `%s'",
6909 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
6910 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
6911 free (fct_name);
6912 PATCH_METHOD_RETURN_ERROR ();
6913 }
6914 args = nreverse (args);
6915 }
6916 /* We're resolving an expression name */
6917 else
6918 {
6919 tree field, type;
6920
6921 /* 1- Find the field to which the call applies */
6922 field = resolve_field_access (wfl, NULL, &type);
6923 if (field == error_mark_node)
6924 PATCH_METHOD_RETURN_ERROR ();
6925 /* field is used in lieu of a primary. It alows us not to
6926 report errors on erroneous use of `this' in
6927 constructors. */
6928 primary = field;
6929
6930 /* 2- Do the layout of the class where the last field
6931 was found, so we can search it. */
6932 class_decl = resolve_and_layout (type, NULL_TREE);
6933 if (class_decl != NULL_TREE)
6934 type = TREE_TYPE (class_decl);
6935
6936 /* 3- Retrieve a filtered list of method matches, Refine
6937 if necessary. In any cases, point out errors. */
6938 list = lookup_method_invoke (0, identifier_wfl, type,
6939 identifier, args);
6940
6941 /* 4- Add the field as an argument */
6942 args = nreverse (args);
6943 this_arg = field;
6944 }
6945
6946 /* IDENTIFIER_WFL will be used to report any problem further */
6947 wfl = identifier_wfl;
6948 }
6949 /* Resolution of simple names, names generated after a primary: or
6950 constructors */
6951 else
6952 {
6953 tree class_to_search;
6954 int lc; /* Looking for Constructor */
6955
6956 /* We search constructor in their target class */
6957 if (CALL_CONSTRUCTOR_P (patch))
6958 {
6959 if (TREE_CODE (patch) == NEW_CLASS_EXPR)
6960 class_to_search = EXPR_WFL_NODE (wfl);
6961 else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
6962 this_identifier_node)
6963 class_to_search = NULL_TREE;
6964 else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
6965 super_identifier_node)
6966 {
6967 is_super_init = 1;
6968 if (CLASSTYPE_SUPER (current_class))
6969 class_to_search =
6970 DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
6971 else
6972 {
6973 parse_error_context (wfl, "Can't invoke super constructor "
6974 "on java.lang.Object");
6975 PATCH_METHOD_RETURN_ERROR ();
6976 }
6977 }
6978
6979 /* Class to search is NULL if we're searching the current one */
6980 if (class_to_search)
6981 {
6982 class_to_search = resolve_and_layout (class_to_search,
6983 NULL_TREE);
6984 if (!class_to_search)
6985 {
6986 parse_error_context
6987 (wfl, "Class `%s' not found in type declaration",
6988 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
6989 PATCH_METHOD_RETURN_ERROR ();
6990 }
6991
6992 /* Can't instantiate an abstract class, but we can
6993 invoke it's constructor. It's use within the `new'
6994 context is denied here. */
6995 if (CLASS_ABSTRACT (class_to_search)
6996 && TREE_CODE (patch) == NEW_CLASS_EXPR)
6997 {
6998 parse_error_context
6999 (wfl, "Class `%s' is an abstract class. It can't be "
7000 "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
7001 PATCH_METHOD_RETURN_ERROR ();
7002 }
7003 class_to_search = TREE_TYPE (class_to_search);
7004 }
7005 else
7006 class_to_search = current_class;
7007 lc = 1;
7008 }
7009 /* This is a regular search in the local class, unless an
7010 alternate class is specified. */
7011 else
7012 {
7013 class_to_search = (where ? where : current_class);
7014 lc = 0;
7015 }
7016
7017 /* NAME is a simple identifier or comes from a primary. Search
7018 in the class whose declaration contain the method being
7019 invoked. */
7020 resolve_and_layout (class_to_search, NULL_TREE);
7021 list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
7022
7023 /* Don't continue if no method were found, as the next statement
7024 can't be executed then. */
7025 if (!list)
7026 PATCH_METHOD_RETURN_ERROR ();
7027
7028 /* Check for static reference if non static methods */
7029 if (check_for_static_method_reference (wfl, patch, list,
7030 class_to_search, primary))
7031 PATCH_METHOD_RETURN_ERROR ();
7032
7033 /* Non static methods are called with the current object extra
7034 argument. If patch a `new TYPE()', the argument is the value
7035 returned by the object allocator. If method is resolved as a
7036 primary, use the primary otherwise use the current THIS. */
7037 args = nreverse (args);
7038 if (TREE_CODE (patch) != NEW_CLASS_EXPR)
7039 this_arg = primary ? primary : current_this;
7040 }
7041
7042 /* Merge point of all resolution schemes. If we have nothing, this
7043 is an error, already signaled */
7044 if (!list)
7045 PATCH_METHOD_RETURN_ERROR ();
7046
7047 /* Check accessibility, position the is_static flag, build and
7048 return the call */
7049 if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
7050 {
7051 char *fct_name = strdup (lang_printable_name (list, 0));
7052 parse_error_context
7053 (wfl, "Can't access %s method `%s %s.%s' from `%s'",
7054 java_accstring_lookup (get_access_flags_from_decl (list)),
7055 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
7056 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))),
7057 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
7058 free (fct_name);
7059 PATCH_METHOD_RETURN_ERROR ();
7060 }
7061 check_deprecation (wfl, list);
7062
7063 is_static_flag = METHOD_STATIC (list);
7064 if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
7065 args = tree_cons (NULL_TREE, this_arg, args);
7066
7067 /* In the context of an explicit constructor invocation, we can't
7068 invoke any method relying on `this'. Exceptions are: we're
7069 invoking a static function, primary exists and is not the current
7070 this, we're creating a new object. */
7071 if (ctxp->explicit_constructor_p
7072 && !is_static_flag
7073 && (!primary || primary == current_this)
7074 && (TREE_CODE (patch) != NEW_CLASS_EXPR))
7075 {
7076 parse_error_context
7077 (wfl, "Can't reference `this' before the superclass constructor has "
7078 "been called");
7079 PATCH_METHOD_RETURN_ERROR ();
7080 }
7081 java_parser_context_restore_global ();
7082 if (is_static)
7083 *is_static = is_static_flag;
7084 /* Sometimes, we want the decl of the selected method. Such as for
7085 EH checking */
7086 if (ret_decl)
7087 *ret_decl = list;
7088 patch = patch_invoke (patch, list, args);
7089 if (is_super_init && CLASS_HAS_FINIT_P (current_class))
7090 {
7091 /* Generate the code used to initialize fields declared with an
7092 initialization statement. For now, it returns a call the the
7093 artificial function $finit$, if required. */
7094
7095 tree finit_call =
7096 build_method_invocation (build_expr_wfl (finit_identifier_node,
7097 input_filename, 0, 0),
7098 NULL_TREE);
7099 patch = build (COMPOUND_EXPR, void_type_node, patch,
7100 java_complete_tree (finit_call));
7101 CAN_COMPLETE_NORMALLY (patch) = 1;
7102 }
7103 return patch;
7104 }
7105
7106 /* Check that we're not trying to do a static reference to a method in
7107 non static method. Return 1 if it's the case, 0 otherwise. */
7108
7109 static int
7110 check_for_static_method_reference (wfl, node, method, where, primary)
7111 tree wfl, node, method, where, primary;
7112 {
7113 if (METHOD_STATIC (current_function_decl)
7114 && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
7115 {
7116 char *fct_name = strdup (lang_printable_name (method, 0));
7117 parse_error_context
7118 (wfl, "Can't make static reference to method `%s %s' in class `%s'",
7119 lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
7120 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
7121 free (fct_name);
7122 return 1;
7123 }
7124 return 0;
7125 }
7126
7127 /* Patch an invoke expression METHOD and ARGS, based on its invocation
7128 mode. */
7129
7130 static tree
7131 patch_invoke (patch, method, args)
7132 tree patch, method, args;
7133 {
7134 tree dtable, func;
7135 tree original_call, t, ta;
7136
7137 /* Last step for args: convert build-in types. If we're dealing with
7138 a new TYPE() type call, the first argument to the constructor
7139 isn't found in the incomming argument list, but delivered by
7140 `new' */
7141 t = TYPE_ARG_TYPES (TREE_TYPE (method));
7142 if (TREE_CODE (patch) == NEW_CLASS_EXPR)
7143 t = TREE_CHAIN (t);
7144 for (ta = args; t != end_params_node && ta;
7145 t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
7146 if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
7147 TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
7148 TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
7149
7150 if (flag_emit_class_files || flag_emit_xref)
7151 func = method;
7152 else
7153 {
7154 tree signature = build_java_signature (TREE_TYPE (method));
7155 switch (invocation_mode (method, CALL_USING_SUPER (patch)))
7156 {
7157 case INVOKE_VIRTUAL:
7158 dtable = invoke_build_dtable (0, args);
7159 func = build_invokevirtual (dtable, method);
7160 break;
7161
7162 case INVOKE_SUPER:
7163 case INVOKE_STATIC:
7164 func = build_known_method_ref (method, TREE_TYPE (method),
7165 DECL_CONTEXT (method),
7166 signature, args);
7167 break;
7168
7169 case INVOKE_INTERFACE:
7170 dtable = invoke_build_dtable (1, args);
7171 func = build_invokeinterface (dtable, DECL_NAME (method), signature);
7172 break;
7173
7174 default:
7175 fatal ("internal error - unknown invocation_mode result");
7176 }
7177
7178 /* Ensure self_type is initialized, (invokestatic). FIXME */
7179 func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
7180 }
7181
7182 TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
7183 TREE_OPERAND (patch, 0) = func;
7184 TREE_OPERAND (patch, 1) = args;
7185 original_call = patch;
7186
7187 /* We're processing a `new TYPE ()' form. New is called an its
7188 returned value is the first argument to the constructor. We build
7189 a COMPOUND_EXPR and use saved expression so that the overall NEW
7190 expression value is a pointer to a newly created and initialized
7191 class. */
7192 if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
7193 {
7194 tree class = DECL_CONTEXT (method);
7195 tree c1, saved_new, size, new;
7196 if (flag_emit_class_files || flag_emit_xref)
7197 {
7198 TREE_TYPE (patch) = build_pointer_type (class);
7199 return patch;
7200 }
7201 if (!TYPE_SIZE (class))
7202 safe_layout_class (class);
7203 size = size_in_bytes (class);
7204 new = build (CALL_EXPR, promote_type (class),
7205 build_address_of (alloc_object_node),
7206 tree_cons (NULL_TREE, build_class_ref (class),
7207 build_tree_list (NULL_TREE,
7208 size_in_bytes (class))),
7209 NULL_TREE);
7210 saved_new = save_expr (new);
7211 c1 = build_tree_list (NULL_TREE, saved_new);
7212 TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
7213 TREE_OPERAND (original_call, 1) = c1;
7214 TREE_SET_CODE (original_call, CALL_EXPR);
7215 patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
7216 }
7217 return patch;
7218 }
7219
7220 static int
7221 invocation_mode (method, super)
7222 tree method;
7223 int super;
7224 {
7225 int access = get_access_flags_from_decl (method);
7226
7227 if (super)
7228 return INVOKE_SUPER;
7229
7230 if (access & ACC_STATIC || access & ACC_FINAL || access & ACC_PRIVATE)
7231 return INVOKE_STATIC;
7232
7233 if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
7234 return INVOKE_STATIC;
7235
7236 if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
7237 return INVOKE_INTERFACE;
7238
7239 if (DECL_CONSTRUCTOR_P (method))
7240 return INVOKE_STATIC;
7241
7242 return INVOKE_VIRTUAL;
7243 }
7244
7245 /* Retrieve a refined list of matching methods. It covers the step
7246 15.11.2 (Compile-Time Step 2) */
7247
7248 static tree
7249 lookup_method_invoke (lc, cl, class, name, arg_list)
7250 int lc;
7251 tree cl;
7252 tree class, name, arg_list;
7253 {
7254 tree atl = end_params_node; /* Arg Type List */
7255 tree method, signature, list, node;
7256 char *candidates; /* Used for error report */
7257
7258 /* Fix the arguments */
7259 for (node = arg_list; node; node = TREE_CHAIN (node))
7260 {
7261 tree current_arg = TREE_TYPE (TREE_VALUE (node));
7262 /* Non primitive type may have to be resolved */
7263 if (!JPRIMITIVE_TYPE_P (current_arg))
7264 resolve_and_layout (current_arg, NULL_TREE);
7265 /* And promoted */
7266 if (TREE_CODE (current_arg) == RECORD_TYPE)
7267 current_arg = promote_type (current_arg);
7268 atl = tree_cons (NULL_TREE, current_arg, atl);
7269 }
7270
7271 /* Find all candidates and then refine the list, searching for the
7272 most specific method. */
7273 list = find_applicable_accessible_methods_list (lc, class, name, atl);
7274 list = find_most_specific_methods_list (list);
7275 if (list && !TREE_CHAIN (list))
7276 return TREE_VALUE (list);
7277
7278 /* Issue an error. List candidates if any. Candidates are listed
7279 only if accessible (non accessible methods may end-up here for
7280 the sake of a better error report). */
7281 candidates = NULL;
7282 if (list)
7283 {
7284 tree current;
7285 obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
7286 for (current = list; current; current = TREE_CHAIN (current))
7287 {
7288 tree cm = TREE_VALUE (current);
7289 char string [4096];
7290 if (!cm || not_accessible_p (class, cm, 0))
7291 continue;
7292 sprintf
7293 (string, " `%s' in `%s'%s",
7294 get_printable_method_name (cm),
7295 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
7296 (TREE_CHAIN (current) ? "\n" : ""));
7297 obstack_grow (&temporary_obstack, string, strlen (string));
7298 }
7299 obstack_1grow (&temporary_obstack, '\0');
7300 candidates = obstack_finish (&temporary_obstack);
7301 }
7302 /* Issue the error message */
7303 method = make_node (FUNCTION_TYPE);
7304 TYPE_ARG_TYPES (method) = atl;
7305 signature = build_java_argument_signature (method);
7306 parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
7307 (lc ? "constructor" : "method"),
7308 (lc ?
7309 IDENTIFIER_POINTER(DECL_NAME (TYPE_NAME (class))) :
7310 IDENTIFIER_POINTER (name)),
7311 IDENTIFIER_POINTER (signature),
7312 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))),
7313 (candidates ? candidates : ""));
7314 return NULL_TREE;
7315 }
7316
7317 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
7318 when we're looking for a constructor. */
7319
7320 static tree
7321 find_applicable_accessible_methods_list (lc, class, name, arglist)
7322 int lc;
7323 tree class, name, arglist;
7324 {
7325 tree list = NULL_TREE, all_list = NULL_TREE;
7326
7327 /* Search interfaces */
7328 if (CLASS_INTERFACE (TYPE_NAME (class)))
7329 {
7330 static tree searched_interfaces = NULL_TREE;
7331 static int search_not_done = 0;
7332 int i, n;
7333 tree basetype_vec = TYPE_BINFO_BASETYPES (class);
7334
7335 /* Have we searched this interface already? */
7336 if (searched_interfaces)
7337 {
7338 tree current;
7339 for (current = searched_interfaces;
7340 current; current = TREE_CHAIN (current))
7341 if (TREE_VALUE (current) == class)
7342 return NULL;
7343 }
7344 searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
7345
7346 search_applicable_methods_list
7347 (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
7348
7349 n = TREE_VEC_LENGTH (basetype_vec);
7350 for (i = 0; i < n; i++)
7351 {
7352 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
7353 tree rlist;
7354
7355 /* Skip java.lang.Object (we'll search it once later.) */
7356 if (t == object_type_node)
7357 continue;
7358
7359 search_not_done++;
7360 rlist = find_applicable_accessible_methods_list (lc, t, name,
7361 arglist);
7362 all_list = chainon (rlist, (list ? list : all_list));
7363 search_not_done--;
7364 }
7365
7366 /* We're done. Reset the searched interfaces list and finally search
7367 java.lang.Object */
7368 if (!search_not_done)
7369 {
7370 searched_interfaces = NULL_TREE;
7371 search_applicable_methods_list (lc, TYPE_METHODS (object_type_node),
7372 name, arglist, &list, &all_list);
7373 }
7374 }
7375 /* Search classes */
7376 else
7377 while (class != NULL_TREE)
7378 {
7379 search_applicable_methods_list
7380 (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
7381 class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
7382 }
7383
7384 /* Either return the list obtained or all selected (but
7385 inaccessible) methods for better error report. */
7386 return (!list ? all_list : list);
7387 }
7388
7389 /* Effectively search for the approriate method in method */
7390
7391 static void
7392 search_applicable_methods_list(lc, method, name, arglist, list, all_list)
7393 int lc;
7394 tree method, name, arglist;
7395 tree *list, *all_list;
7396 {
7397 for (; method; method = TREE_CHAIN (method))
7398 {
7399 /* When dealing with constructor, stop here, otherwise search
7400 other classes */
7401 if (lc && !DECL_CONSTRUCTOR_P (method))
7402 continue;
7403 else if (!lc && (DECL_CONSTRUCTOR_P (method)
7404 || (GET_METHOD_NAME (method) != name)))
7405 continue;
7406
7407 if (argument_types_convertible (method, arglist))
7408 {
7409 /* Retain accessible methods only */
7410 if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
7411 method, 0))
7412 *list = tree_cons (NULL_TREE, method, *list);
7413 else
7414 /* Also retain all selected method here */
7415 *all_list = tree_cons (NULL_TREE, method, *list);
7416 }
7417 }
7418 }
7419
7420 /* 15.11.2.2 Choose the Most Specific Method */
7421
7422 static tree
7423 find_most_specific_methods_list (list)
7424 tree list;
7425 {
7426 int max = 0;
7427 tree current, new_list = NULL_TREE;
7428 for (current = list; current; current = TREE_CHAIN (current))
7429 {
7430 tree method;
7431 DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
7432
7433 for (method = list; method; method = TREE_CHAIN (method))
7434 {
7435 /* Don't test a method against itself */
7436 if (method == current)
7437 continue;
7438
7439 /* Compare arguments and location where method where declared */
7440 if (argument_types_convertible (TREE_VALUE (method),
7441 TREE_VALUE (current))
7442 && valid_method_invocation_conversion_p
7443 (DECL_CONTEXT (TREE_VALUE (method)),
7444 DECL_CONTEXT (TREE_VALUE (current))))
7445 {
7446 int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
7447 max = (v > max ? v : max);
7448 }
7449 }
7450 }
7451
7452 /* Review the list and select the maximally specific methods */
7453 for (current = list; current; current = TREE_CHAIN (current))
7454 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
7455 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
7456
7457 /* If we can't find one, lower expectations and try to gather multiple
7458 maximally specific methods */
7459 while (!new_list)
7460 {
7461 while (--max > 0)
7462 {
7463 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
7464 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
7465 }
7466 return new_list;
7467 }
7468
7469 return new_list;
7470 }
7471
7472 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
7473 converted by method invocation conversion (5.3) to the type of the
7474 corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
7475 to change less often than M1. */
7476
7477 static int
7478 argument_types_convertible (m1, m2_or_arglist)
7479 tree m1, m2_or_arglist;
7480 {
7481 static tree m2_arg_value = NULL_TREE;
7482 static tree m2_arg_cache = NULL_TREE;
7483
7484 register tree m1_arg, m2_arg;
7485
7486 m1_arg = TYPE_ARG_TYPES (TREE_TYPE (m1));
7487 if (!METHOD_STATIC (m1))
7488 m1_arg = TREE_CHAIN (m1_arg);
7489
7490 if (m2_arg_value == m2_or_arglist)
7491 m2_arg = m2_arg_cache;
7492 else
7493 {
7494 /* M2_OR_ARGLIST can be a function DECL or a raw list of
7495 argument types */
7496 if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
7497 {
7498 m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
7499 if (!METHOD_STATIC (m2_or_arglist))
7500 m2_arg = TREE_CHAIN (m2_arg);
7501 }
7502 else
7503 m2_arg = m2_or_arglist;
7504
7505 m2_arg_value = m2_or_arglist;
7506 m2_arg_cache = m2_arg;
7507 }
7508
7509 while (m1_arg != end_params_node && m2_arg != end_params_node)
7510 {
7511 resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
7512 if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
7513 TREE_VALUE (m2_arg)))
7514 break;
7515 m1_arg = TREE_CHAIN (m1_arg);
7516 m2_arg = TREE_CHAIN (m2_arg);
7517 }
7518 return m1_arg == end_params_node && m2_arg == end_params_node;
7519 }
7520
7521 /* Qualification routines */
7522
7523 static void
7524 qualify_ambiguous_name (id)
7525 tree id;
7526 {
7527 tree qual, qual_wfl, name, decl, ptr_type, saved_current_class;
7528 int again, super_found = 0, this_found = 0, new_array_found = 0;
7529
7530 /* We first qualify the first element, then derive qualification of
7531 others based on the first one. If the first element is qualified
7532 by a resolution (field or type), this resolution is stored in the
7533 QUAL_RESOLUTION of the qual element being examined. We need to
7534 save the current_class since the use of SUPER might change the
7535 its value. */
7536 saved_current_class = current_class;
7537 qual = EXPR_WFL_QUALIFICATION (id);
7538 do {
7539
7540 /* Simple qualified expression feature a qual_wfl that is a
7541 WFL. Expression derived from a primary feature more complicated
7542 things like a CALL_EXPR. Expression from primary need to be
7543 worked out to extract the part on which the qualification will
7544 take place. */
7545 qual_wfl = QUAL_WFL (qual);
7546 switch (TREE_CODE (qual_wfl))
7547 {
7548 case CALL_EXPR:
7549 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7550 if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
7551 {
7552 qual = EXPR_WFL_QUALIFICATION (qual_wfl);
7553 qual_wfl = QUAL_WFL (qual);
7554 }
7555 break;
7556 case NEW_ARRAY_EXPR:
7557 qual = TREE_CHAIN (qual);
7558 new_array_found = again = 1;
7559 continue;
7560 case NEW_CLASS_EXPR:
7561 case CONVERT_EXPR:
7562 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7563 break;
7564 case ARRAY_REF:
7565 while (TREE_CODE (qual_wfl) == ARRAY_REF)
7566 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7567 break;
7568 default:
7569 /* Fix for -Wall. Just break doing nothing */
7570 break;
7571 }
7572 name = EXPR_WFL_NODE (qual_wfl);
7573 ptr_type = current_class;
7574 again = 0;
7575 /* If we have a THIS (from a primary), we set the context accordingly */
7576 if (name == this_identifier_node)
7577 {
7578 qual = TREE_CHAIN (qual);
7579 qual_wfl = QUAL_WFL (qual);
7580 if (TREE_CODE (qual_wfl) == CALL_EXPR)
7581 again = 1;
7582 else
7583 name = EXPR_WFL_NODE (qual_wfl);
7584 this_found = 1;
7585 }
7586 /* If we have a SUPER, we set the context accordingly */
7587 if (name == super_identifier_node)
7588 {
7589 current_class = CLASSTYPE_SUPER (ptr_type);
7590 /* Check that there is such a thing as a super class. If not,
7591 return. The error will be caught later on, during the
7592 resolution */
7593 if (!current_class)
7594 {
7595 current_class = saved_current_class;
7596 return;
7597 }
7598 qual = TREE_CHAIN (qual);
7599 /* Do one more interation to set things up */
7600 super_found = again = 1;
7601 }
7602 /* Loop one more time if we're dealing with ?: or a string
7603 constant, or a convert expression */
7604 if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR
7605 || TREE_CODE (qual_wfl) == STRING_CST
7606 || TREE_CODE (qual_wfl) == CONVERT_EXPR)
7607 {
7608 qual = TREE_CHAIN (qual);
7609 qual_wfl = QUAL_WFL (qual);
7610 again = 1;
7611 }
7612 } while (again);
7613
7614 /* If name appears within the scope of a location variable
7615 declaration or parameter declaration, then it is an expression
7616 name. We don't carry this test out if we're in the context of the
7617 use of SUPER or THIS */
7618 if (!this_found && !super_found && (decl = IDENTIFIER_LOCAL_VALUE (name)))
7619 {
7620 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
7621 QUAL_RESOLUTION (qual) = decl;
7622 }
7623
7624 /* If within the class/interface NAME was found to be used there
7625 exists a (possibly inherited) field named NAME, then this is an
7626 expression name. If we saw a NEW_ARRAY_EXPR before and want to
7627 address length, it is OK. */
7628 else if ((decl = lookup_field_wrapper (ptr_type, name))
7629 || (new_array_found && name == length_identifier_node))
7630 {
7631 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
7632 QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
7633 }
7634
7635 /* We reclassify NAME as a type name if:
7636 - NAME is a class/interface declared within the compilation
7637 unit containing NAME,
7638 - NAME is imported via a single-type-import declaration,
7639 - NAME is declared in an another compilation unit of the package
7640 of the compilation unit containing NAME,
7641 - NAME is declared by exactly on type-import-on-demand declaration
7642 of the compilation unit containing NAME. */
7643 else if ((decl = resolve_and_layout (name, NULL_TREE)))
7644 {
7645 RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
7646 QUAL_RESOLUTION (qual) = decl;
7647 }
7648
7649 /* Method call are expression name */
7650 else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
7651 || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF)
7652 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
7653
7654 /* Check here that NAME isn't declared by more than one
7655 type-import-on-demand declaration of the compilation unit
7656 containing NAME. FIXME */
7657
7658 /* Otherwise, NAME is reclassified as a package name */
7659 else
7660 RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
7661
7662 /* Propagate the qualification accross other components of the
7663 qualified name */
7664 for (qual = TREE_CHAIN (qual); qual;
7665 qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
7666 {
7667 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
7668 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
7669 else
7670 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
7671 }
7672
7673 /* Store the global qualification for the ambiguous part of ID back
7674 into ID fields */
7675 if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
7676 RESOLVE_EXPRESSION_NAME_P (id) = 1;
7677 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
7678 RESOLVE_TYPE_NAME_P (id) = 1;
7679 else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
7680 RESOLVE_PACKAGE_NAME_P (id) = 1;
7681
7682 /* Restore the current class */
7683 current_class = saved_current_class;
7684 }
7685
7686 static int
7687 breakdown_qualified (left, right, source)
7688 tree *left, *right, source;
7689 {
7690 char *p = IDENTIFIER_POINTER (source), *base;
7691 int l = IDENTIFIER_LENGTH (source);
7692
7693 /* Breakdown NAME into REMAINDER . IDENTIFIER */
7694 base = p;
7695 p += (l-1);
7696 while (*p != '.' && p != base)
7697 p--;
7698
7699 /* We didn't find a '.'. Return an error */
7700 if (p == base)
7701 return 1;
7702
7703 *p = '\0';
7704 if (right)
7705 *right = get_identifier (p+1);
7706 *left = get_identifier (IDENTIFIER_POINTER (source));
7707 *p = '.';
7708
7709 return 0;
7710 }
7711
7712 /* Patch tree nodes in a function body. When a BLOCK is found, push
7713 local variable decls if present.
7714 Same as java_complete_lhs, but does resolve static finals to values. */
7715
7716 static tree
7717 java_complete_tree (node)
7718 tree node;
7719 {
7720 node = java_complete_lhs (node);
7721 if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
7722 && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
7723 && !flag_emit_xref)
7724 {
7725 tree value = DECL_INITIAL (node);
7726 DECL_INITIAL (node) = NULL_TREE;
7727 value = fold_constant_for_init (value, node);
7728 DECL_INITIAL (node) = value;
7729 if (value != NULL_TREE)
7730 return value;
7731 }
7732 return node;
7733 }
7734
7735 static tree
7736 java_stabilize_reference (node)
7737 tree node;
7738 {
7739 if (TREE_CODE (node) == COMPOUND_EXPR)
7740 {
7741 tree op0 = TREE_OPERAND (node, 0);
7742 tree op1 = TREE_OPERAND (node, 1);
7743 TREE_OPERAND (node, 0) = save_expr (op0);
7744 TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
7745 return node;
7746 }
7747 else
7748 return stabilize_reference (node);
7749 }
7750
7751 /* Patch tree nodes in a function body. When a BLOCK is found, push
7752 local variable decls if present.
7753 Same as java_complete_tree, but does not resolve static finals to values. */
7754
7755 static tree
7756 java_complete_lhs (node)
7757 tree node;
7758 {
7759 tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
7760 int flag;
7761
7762 /* CONVERT_EXPR always has its type set, even though it needs to be
7763 worked out. */
7764 if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
7765 return node;
7766
7767 /* The switch block implements cases processing container nodes
7768 first. Contained nodes are always written back. Leaves come
7769 next and return a value. */
7770 switch (TREE_CODE (node))
7771 {
7772 case BLOCK:
7773
7774 /* 1- Block section.
7775 Set the local values on decl names so we can identify them
7776 faster when they're referenced. At that stage, identifiers
7777 are legal so we don't check for declaration errors. */
7778 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
7779 {
7780 DECL_CONTEXT (cn) = current_function_decl;
7781 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
7782 }
7783 if (BLOCK_EXPR_BODY (node) == NULL_TREE)
7784 CAN_COMPLETE_NORMALLY (node) = 1;
7785 else
7786 {
7787 tree stmt = BLOCK_EXPR_BODY (node);
7788 tree *ptr;
7789 int error_seen = 0;
7790 if (TREE_CODE (stmt) == COMPOUND_EXPR)
7791 {
7792 /* Re-order from (((A; B); C); ...; Z) to
7793 (A; (B; (C ; (...; Z)))).
7794 This makes it easier to scan the statements left-to-right
7795 without using recursion (which might overflow the stack
7796 if the block has many statements. */
7797 for (;;)
7798 {
7799 tree left = TREE_OPERAND (stmt, 0);
7800 if (TREE_CODE (left) != COMPOUND_EXPR)
7801 break;
7802 TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
7803 TREE_OPERAND (left, 1) = stmt;
7804 stmt = left;
7805 }
7806 BLOCK_EXPR_BODY (node) = stmt;
7807 }
7808
7809 /* Now do the actual complete, without deep recursion for
7810 long blocks. */
7811 ptr = &BLOCK_EXPR_BODY (node);
7812 while (TREE_CODE (*ptr) == COMPOUND_EXPR
7813 && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
7814 {
7815 tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
7816 tree *next = &TREE_OPERAND (*ptr, 1);
7817 TREE_OPERAND (*ptr, 0) = cur;
7818 if (cur == empty_stmt_node)
7819 {
7820 /* Optimization; makes it easier to detect empty bodies.
7821 Most useful for <clinit> with all-constant initializer. */
7822 *ptr = *next;
7823 continue;
7824 }
7825 if (TREE_CODE (cur) == ERROR_MARK)
7826 error_seen++;
7827 else if (! CAN_COMPLETE_NORMALLY (cur))
7828 {
7829 wfl_op2 = *next;
7830 for (;;)
7831 {
7832 if (TREE_CODE (wfl_op2) == BLOCK)
7833 wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
7834 else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
7835 wfl_op2 = TREE_OPERAND (wfl_op2, 0);
7836 else
7837 break;
7838 }
7839 if (TREE_CODE (wfl_op2) != CASE_EXPR
7840 && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
7841 unreachable_stmt_error (*ptr);
7842 }
7843 ptr = next;
7844 }
7845 *ptr = java_complete_tree (*ptr);
7846
7847 if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
7848 return error_mark_node;
7849 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
7850 }
7851 /* Turn local bindings to null */
7852 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
7853 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
7854
7855 TREE_TYPE (node) = void_type_node;
7856 break;
7857
7858 /* 2- They are expressions but ultimately deal with statements */
7859
7860 case THROW_EXPR:
7861 wfl_op1 = TREE_OPERAND (node, 0);
7862 COMPLETE_CHECK_OP_0 (node);
7863 /* CAN_COMPLETE_NORMALLY (node) = 0; */
7864 return patch_throw_statement (node, wfl_op1);
7865
7866 case SYNCHRONIZED_EXPR:
7867 wfl_op1 = TREE_OPERAND (node, 0);
7868 return patch_synchronized_statement (node, wfl_op1);
7869
7870 case TRY_EXPR:
7871 return patch_try_statement (node);
7872
7873 case TRY_FINALLY_EXPR:
7874 COMPLETE_CHECK_OP_0 (node);
7875 COMPLETE_CHECK_OP_1 (node);
7876 CAN_COMPLETE_NORMALLY (node)
7877 = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
7878 && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
7879 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
7880 return node;
7881
7882 case CLEANUP_POINT_EXPR:
7883 COMPLETE_CHECK_OP_0 (node);
7884 TREE_TYPE (node) = void_type_node;
7885 CAN_COMPLETE_NORMALLY (node) =
7886 CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
7887 return node;
7888
7889 case WITH_CLEANUP_EXPR:
7890 COMPLETE_CHECK_OP_0 (node);
7891 COMPLETE_CHECK_OP_2 (node);
7892 CAN_COMPLETE_NORMALLY (node) =
7893 CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
7894 TREE_TYPE (node) = void_type_node;
7895 return node;
7896
7897 case LABELED_BLOCK_EXPR:
7898 PUSH_LABELED_BLOCK (node);
7899 if (LABELED_BLOCK_BODY (node))
7900 COMPLETE_CHECK_OP_1 (node);
7901 TREE_TYPE (node) = void_type_node;
7902 POP_LABELED_BLOCK ();
7903
7904 if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
7905 {
7906 LABELED_BLOCK_BODY (node) = NULL_TREE;
7907 CAN_COMPLETE_NORMALLY (node) = 1;
7908 }
7909 else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
7910 CAN_COMPLETE_NORMALLY (node) = 1;
7911 return node;
7912
7913 case EXIT_BLOCK_EXPR:
7914 /* We don't complete operand 1, because it's the return value of
7915 the EXIT_BLOCK_EXPR which doesn't exist it Java */
7916 return patch_bc_statement (node);
7917
7918 case CASE_EXPR:
7919 cn = java_complete_tree (TREE_OPERAND (node, 0));
7920 if (cn == error_mark_node)
7921 return cn;
7922
7923 /* First, the case expression must be constant */
7924 cn = fold (cn);
7925
7926 if (!TREE_CONSTANT (cn) && !flag_emit_xref)
7927 {
7928 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7929 parse_error_context (node, "Constant expression required");
7930 return error_mark_node;
7931 }
7932
7933 nn = ctxp->current_loop;
7934
7935 /* It must be assignable to the type of the switch expression. */
7936 if (!try_builtin_assignconv (NULL_TREE,
7937 TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
7938 {
7939 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7940 parse_error_context
7941 (wfl_operator,
7942 "Incompatible type for case. Can't convert `%s' to `int'",
7943 lang_printable_name (TREE_TYPE (cn), 0));
7944 return error_mark_node;
7945 }
7946
7947 cn = fold (convert (int_type_node, cn));
7948
7949 /* Multiple instance of a case label bearing the same
7950 value is checked during code generation. The case
7951 expression is allright so far. */
7952 TREE_OPERAND (node, 0) = cn;
7953 TREE_TYPE (node) = void_type_node;
7954 CAN_COMPLETE_NORMALLY (node) = 1;
7955 TREE_SIDE_EFFECTS (node) = 1;
7956 break;
7957
7958 case DEFAULT_EXPR:
7959 nn = ctxp->current_loop;
7960 /* Only one default label is allowed per switch statement */
7961 if (SWITCH_HAS_DEFAULT (nn))
7962 {
7963 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7964 parse_error_context (wfl_operator,
7965 "Duplicate case label: `default'");
7966 return error_mark_node;
7967 }
7968 else
7969 SWITCH_HAS_DEFAULT (nn) = 1;
7970 TREE_TYPE (node) = void_type_node;
7971 TREE_SIDE_EFFECTS (node) = 1;
7972 CAN_COMPLETE_NORMALLY (node) = 1;
7973 break;
7974
7975 case SWITCH_EXPR:
7976 case LOOP_EXPR:
7977 PUSH_LOOP (node);
7978 /* Check whether the loop was enclosed in a labeled
7979 statement. If not, create one, insert the loop in it and
7980 return the node */
7981 nn = patch_loop_statement (node);
7982
7983 /* Anyways, walk the body of the loop */
7984 if (TREE_CODE (node) == LOOP_EXPR)
7985 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
7986 /* Switch statement: walk the switch expression and the cases */
7987 else
7988 node = patch_switch_statement (node);
7989
7990 if (TREE_OPERAND (node, 0) == error_mark_node)
7991 nn = error_mark_node;
7992 else
7993 {
7994 TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
7995 /* If we returned something different, that's because we
7996 inserted a label. Pop the label too. */
7997 if (nn != node)
7998 {
7999 if (CAN_COMPLETE_NORMALLY (node))
8000 CAN_COMPLETE_NORMALLY (nn) = 1;
8001 POP_LABELED_BLOCK ();
8002 }
8003 }
8004 POP_LOOP ();
8005 return nn;
8006
8007 case EXIT_EXPR:
8008 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
8009 return patch_exit_expr (node);
8010
8011 case COND_EXPR:
8012 /* Condition */
8013 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
8014 if (TREE_OPERAND (node, 0) == error_mark_node)
8015 return error_mark_node;
8016 /* then-else branches */
8017 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
8018 if (TREE_OPERAND (node, 1) == error_mark_node)
8019 return error_mark_node;
8020 TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
8021 if (TREE_OPERAND (node, 2) == error_mark_node)
8022 return error_mark_node;
8023 return patch_if_else_statement (node);
8024 break;
8025
8026 case CONDITIONAL_EXPR:
8027 /* Condition */
8028 wfl_op1 = TREE_OPERAND (node, 0);
8029 COMPLETE_CHECK_OP_0 (node);
8030 wfl_op2 = TREE_OPERAND (node, 1);
8031 COMPLETE_CHECK_OP_1 (node);
8032 wfl_op3 = TREE_OPERAND (node, 2);
8033 COMPLETE_CHECK_OP_2 (node);
8034 return patch_conditional_expr (node, wfl_op1, wfl_op2);
8035
8036 /* 3- Expression section */
8037 case COMPOUND_EXPR:
8038 wfl_op2 = TREE_OPERAND (node, 1);
8039 TREE_OPERAND (node, 0) = nn =
8040 java_complete_tree (TREE_OPERAND (node, 0));
8041 if (wfl_op2 == empty_stmt_node)
8042 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
8043 else
8044 {
8045 if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
8046 {
8047 /* An unreachable condition in a do-while statement
8048 is *not* (technically) an unreachable statement. */
8049 nn = wfl_op2;
8050 if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
8051 nn = EXPR_WFL_NODE (nn);
8052 if (TREE_CODE (nn) != EXIT_EXPR)
8053 {
8054 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
8055 parse_error_context (wfl_operator, "Unreachable statement");
8056 }
8057 }
8058 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
8059 if (TREE_OPERAND (node, 1) == error_mark_node)
8060 return error_mark_node;
8061 CAN_COMPLETE_NORMALLY (node)
8062 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
8063 }
8064 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
8065 break;
8066
8067 case RETURN_EXPR:
8068 /* CAN_COMPLETE_NORMALLY (node) = 0; */
8069 return patch_return (node);
8070
8071 case EXPR_WITH_FILE_LOCATION:
8072 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
8073 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
8074 {
8075 tree wfl = node;
8076 node = resolve_expression_name (node, NULL);
8077 if (node == error_mark_node)
8078 return node;
8079 /* Keep line number information somewhere were it doesn't
8080 disrupt the completion process. */
8081 if (flag_emit_xref)
8082 {
8083 EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
8084 TREE_OPERAND (node, 1) = wfl;
8085 }
8086 CAN_COMPLETE_NORMALLY (node) = 1;
8087 }
8088 else
8089 {
8090 tree body;
8091 int save_lineno = lineno;
8092 lineno = EXPR_WFL_LINENO (node);
8093 body = java_complete_tree (EXPR_WFL_NODE (node));
8094 lineno = save_lineno;
8095 EXPR_WFL_NODE (node) = body;
8096 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
8097 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
8098 if (body == empty_stmt_node)
8099 {
8100 /* Optimization; makes it easier to detect empty bodies. */
8101 return body;
8102 }
8103 if (body == error_mark_node)
8104 {
8105 /* Its important for the evaluation of assignment that
8106 this mark on the TREE_TYPE is propagated. */
8107 TREE_TYPE (node) = error_mark_node;
8108 return error_mark_node;
8109 }
8110 else
8111 TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
8112
8113 }
8114 break;
8115
8116 case NEW_ARRAY_EXPR:
8117 /* Patch all the dimensions */
8118 flag = 0;
8119 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
8120 {
8121 int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
8122 tree dim = java_complete_tree (TREE_VALUE (cn));
8123 if (dim == error_mark_node)
8124 {
8125 flag = 1;
8126 continue;
8127 }
8128 else
8129 {
8130 TREE_VALUE (cn) = dim;
8131 /* Setup the location of the current dimension, for
8132 later error report. */
8133 TREE_PURPOSE (cn) =
8134 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
8135 EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
8136 }
8137 }
8138 /* They complete the array creation expression, if no errors
8139 were found. */
8140 CAN_COMPLETE_NORMALLY (node) = 1;
8141 return (flag ? error_mark_node
8142 : force_evaluation_order (patch_newarray (node)));
8143
8144 case NEW_CLASS_EXPR:
8145 case CALL_EXPR:
8146 /* Complete function's argument(s) first */
8147 if (complete_function_arguments (node))
8148 return error_mark_node;
8149 else
8150 {
8151 tree decl, wfl = TREE_OPERAND (node, 0);
8152 int in_this = CALL_THIS_CONSTRUCTOR_P (node);
8153
8154 node = patch_method_invocation (node, NULL_TREE,
8155 NULL_TREE, 0, &decl);
8156 if (node == error_mark_node)
8157 return error_mark_node;
8158
8159 check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
8160 /* If we call this(...), register signature and positions */
8161 if (in_this)
8162 DECL_CONSTRUCTOR_CALLS (current_function_decl) =
8163 tree_cons (wfl, decl,
8164 DECL_CONSTRUCTOR_CALLS (current_function_decl));
8165 CAN_COMPLETE_NORMALLY (node) = 1;
8166 return force_evaluation_order (node);
8167 }
8168
8169 case MODIFY_EXPR:
8170 /* Save potential wfls */
8171 wfl_op1 = TREE_OPERAND (node, 0);
8172 TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
8173 if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
8174 && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
8175 && DECL_INITIAL (nn) != NULL_TREE)
8176 {
8177 tree value = fold_constant_for_init (nn, nn);
8178 if (value != NULL_TREE)
8179 {
8180 tree type = TREE_TYPE (value);
8181 if (JPRIMITIVE_TYPE_P (type) || type == string_ptr_type_node)
8182 return empty_stmt_node;
8183 }
8184 DECL_INITIAL (nn) = NULL_TREE;
8185 }
8186 wfl_op2 = TREE_OPERAND (node, 1);
8187
8188 if (TREE_OPERAND (node, 0) == error_mark_node)
8189 return error_mark_node;
8190
8191 if (COMPOUND_ASSIGN_P (wfl_op2))
8192 {
8193 tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0));
8194
8195 /* Hand stablize the lhs on both places */
8196 TREE_OPERAND (node, 0) = lvalue;
8197 TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue;
8198
8199 /* Now complete the RHS. We write it back later on. */
8200 nn = java_complete_tree (TREE_OPERAND (node, 1));
8201
8202 if ((cn = patch_string (nn)))
8203 nn = cn;
8204
8205 /* The last part of the rewrite for E1 op= E2 is to have
8206 E1 = (T)(E1 op E2), with T being the type of E1. */
8207 nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2),
8208 TREE_TYPE (lvalue), nn));
8209 }
8210
8211 /* If we're about to patch a NEW_ARRAY_INIT, we call a special
8212 function to complete this RHS */
8213 else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)
8214 nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
8215 TREE_OPERAND (node, 1));
8216 /* Otherwise we simply complete the RHS */
8217 else
8218 nn = java_complete_tree (TREE_OPERAND (node, 1));
8219
8220 if (nn == error_mark_node)
8221 return error_mark_node;
8222
8223 /* Write back the RHS as we evaluated it. */
8224 TREE_OPERAND (node, 1) = nn;
8225
8226 /* In case we're handling = with a String as a RHS, we need to
8227 produce a String out of the RHS (it might still be a
8228 STRING_CST or a StringBuffer at this stage */
8229 if ((nn = patch_string (TREE_OPERAND (node, 1))))
8230 TREE_OPERAND (node, 1) = nn;
8231 node = patch_assignment (node, wfl_op1, wfl_op2);
8232 CAN_COMPLETE_NORMALLY (node) = 1;
8233 return node;
8234
8235 case MULT_EXPR:
8236 case PLUS_EXPR:
8237 case MINUS_EXPR:
8238 case LSHIFT_EXPR:
8239 case RSHIFT_EXPR:
8240 case URSHIFT_EXPR:
8241 case BIT_AND_EXPR:
8242 case BIT_XOR_EXPR:
8243 case BIT_IOR_EXPR:
8244 case TRUNC_MOD_EXPR:
8245 case RDIV_EXPR:
8246 case TRUTH_ANDIF_EXPR:
8247 case TRUTH_ORIF_EXPR:
8248 case EQ_EXPR:
8249 case NE_EXPR:
8250 case GT_EXPR:
8251 case GE_EXPR:
8252 case LT_EXPR:
8253 case LE_EXPR:
8254 /* Operands 0 and 1 are WFL in certain cases only. patch_binop
8255 knows how to handle those cases. */
8256 wfl_op1 = TREE_OPERAND (node, 0);
8257 wfl_op2 = TREE_OPERAND (node, 1);
8258
8259 CAN_COMPLETE_NORMALLY (node) = 1;
8260 /* Don't complete string nodes if dealing with the PLUS operand. */
8261 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
8262 {
8263 nn = java_complete_tree (wfl_op1);
8264 if (nn == error_mark_node)
8265 return error_mark_node;
8266 if ((cn = patch_string (nn)))
8267 nn = cn;
8268 TREE_OPERAND (node, 0) = nn;
8269 }
8270 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
8271 {
8272 nn = java_complete_tree (wfl_op2);
8273 if (nn == error_mark_node)
8274 return error_mark_node;
8275 if ((cn = patch_string (nn)))
8276 nn = cn;
8277 TREE_OPERAND (node, 1) = nn;
8278 }
8279 return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
8280
8281 case INSTANCEOF_EXPR:
8282 wfl_op1 = TREE_OPERAND (node, 0);
8283 COMPLETE_CHECK_OP_0 (node);
8284 if (flag_emit_xref)
8285 {
8286 TREE_TYPE (node) = boolean_type_node;
8287 return node;
8288 }
8289 return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
8290
8291 case UNARY_PLUS_EXPR:
8292 case NEGATE_EXPR:
8293 case TRUTH_NOT_EXPR:
8294 case BIT_NOT_EXPR:
8295 case PREDECREMENT_EXPR:
8296 case PREINCREMENT_EXPR:
8297 case POSTDECREMENT_EXPR:
8298 case POSTINCREMENT_EXPR:
8299 case CONVERT_EXPR:
8300 /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
8301 how to handle those cases. */
8302 wfl_op1 = TREE_OPERAND (node, 0);
8303 CAN_COMPLETE_NORMALLY (node) = 1;
8304 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
8305 if (TREE_OPERAND (node, 0) == error_mark_node)
8306 return error_mark_node;
8307 node = patch_unaryop (node, wfl_op1);
8308 CAN_COMPLETE_NORMALLY (node) = 1;
8309 break;
8310
8311 case ARRAY_REF:
8312 /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
8313 how to handle those cases. */
8314 wfl_op1 = TREE_OPERAND (node, 0);
8315 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
8316 if (TREE_OPERAND (node, 0) == error_mark_node)
8317 return error_mark_node;
8318 if (!flag_emit_class_files && !flag_emit_xref)
8319 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
8320 /* The same applies to wfl_op2 */
8321 wfl_op2 = TREE_OPERAND (node, 1);
8322 TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
8323 if (TREE_OPERAND (node, 1) == error_mark_node)
8324 return error_mark_node;
8325 if (!flag_emit_class_files && !flag_emit_xref)
8326 TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
8327 return patch_array_ref (node);
8328
8329 case RECORD_TYPE:
8330 return node;;
8331
8332 case COMPONENT_REF:
8333 /* The first step in the re-write of qualified name handling. FIXME.
8334 So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
8335 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
8336 if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
8337 {
8338 tree name = TREE_OPERAND (node, 1);
8339 tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
8340 if (field == NULL_TREE)
8341 {
8342 error ("missing static field `%s'", IDENTIFIER_POINTER (name));
8343 return error_mark_node;
8344 }
8345 if (! FIELD_STATIC (field))
8346 {
8347 error ("not a static field `%s'", IDENTIFIER_POINTER (name));
8348 return error_mark_node;
8349 }
8350 return field;
8351 }
8352 else
8353 fatal ("unimplemented java_complete_tree for COMPONENT_REF");
8354 break;
8355
8356 case THIS_EXPR:
8357 /* Can't use THIS in a static environment */
8358 if (!current_this)
8359 {
8360 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8361 parse_error_context (wfl_operator, "Keyword `this' used outside "
8362 "allowed context");
8363 TREE_TYPE (node) = error_mark_node;
8364 return error_mark_node;
8365 }
8366 if (ctxp->explicit_constructor_p)
8367 {
8368 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8369 parse_error_context
8370 (wfl_operator, "Can't reference `this' or `super' before the "
8371 "superclass constructor has been called");
8372 TREE_TYPE (node) = error_mark_node;
8373 return error_mark_node;
8374 }
8375 return current_this;
8376
8377 default:
8378 CAN_COMPLETE_NORMALLY (node) = 1;
8379 /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
8380 and it's time to turn it into the appropriate String object
8381 */
8382 if ((node = patch_string (node)))
8383 return node;
8384 fatal ("No case for tree code `%s' - java_complete_tree\n",
8385 tree_code_name [TREE_CODE (node)]);
8386 }
8387 return node;
8388 }
8389
8390 /* Complete function call's argument. Return a non zero value is an
8391 error was found. */
8392
8393 static int
8394 complete_function_arguments (node)
8395 tree node;
8396 {
8397 int flag = 0;
8398 tree cn;
8399
8400 ctxp->explicit_constructor_p += (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
8401 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
8402 {
8403 tree wfl = TREE_VALUE (cn), parm, temp;
8404 parm = java_complete_tree (wfl);
8405 if (parm == error_mark_node)
8406 {
8407 flag = 1;
8408 continue;
8409 }
8410 /* If have a string literal that we haven't transformed yet or a
8411 crafted string buffer, as a result of use of the the String
8412 `+' operator. Build `parm.toString()' and expand it. */
8413 if ((temp = patch_string (parm)))
8414 parm = temp;
8415 /* Inline PRIMTYPE.TYPE read access */
8416 parm = maybe_build_primttype_type_ref (parm, wfl);
8417
8418 TREE_VALUE (cn) = parm;
8419 }
8420 ctxp->explicit_constructor_p -= (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
8421 return flag;
8422 }
8423
8424 /* Sometimes (for loops and variable initialized during their
8425 declaration), we want to wrap a statement around a WFL and turn it
8426 debugable. */
8427
8428 static tree
8429 build_debugable_stmt (location, stmt)
8430 int location;
8431 tree stmt;
8432 {
8433 if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
8434 {
8435 stmt = build_expr_wfl (stmt, input_filename, 0, 0);
8436 EXPR_WFL_LINECOL (stmt) = location;
8437 }
8438 JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
8439 return stmt;
8440 }
8441
8442 static tree
8443 build_expr_block (body, decls)
8444 tree body, decls;
8445 {
8446 tree node = make_node (BLOCK);
8447 BLOCK_EXPR_DECLS (node) = decls;
8448 BLOCK_EXPR_BODY (node) = body;
8449 if (body)
8450 TREE_TYPE (node) = TREE_TYPE (body);
8451 TREE_SIDE_EFFECTS (node) = 1;
8452 return node;
8453 }
8454
8455 /* Create a new function block and link it approriately to current
8456 function block chain */
8457
8458 static tree
8459 enter_block ()
8460 {
8461 return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
8462 }
8463
8464 /* Link block B supercontext to the previous block. The current
8465 function DECL is used as supercontext when enter_a_block is called
8466 for the first time for a given function. The current function body
8467 (DECL_FUNCTION_BODY) is set to be block B. */
8468
8469 static tree
8470 enter_a_block (b)
8471 tree b;
8472 {
8473 tree fndecl = current_function_decl;
8474
8475 if (!fndecl) {
8476 BLOCK_SUPERCONTEXT (b) = current_static_block;
8477 current_static_block = b;
8478 }
8479
8480 else if (!DECL_FUNCTION_BODY (fndecl))
8481 {
8482 BLOCK_SUPERCONTEXT (b) = fndecl;
8483 DECL_FUNCTION_BODY (fndecl) = b;
8484 }
8485 else
8486 {
8487 BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
8488 DECL_FUNCTION_BODY (fndecl) = b;
8489 }
8490 return b;
8491 }
8492
8493 /* Exit a block by changing the current function body
8494 (DECL_FUNCTION_BODY) to the current block super context, only if
8495 the block being exited isn't the method's top level one. */
8496
8497 static tree
8498 exit_block ()
8499 {
8500 tree b;
8501 if (current_function_decl)
8502 {
8503 b = DECL_FUNCTION_BODY (current_function_decl);
8504 if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
8505 DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
8506 }
8507 else
8508 {
8509 b = current_static_block;
8510
8511 if (BLOCK_SUPERCONTEXT (b))
8512 current_static_block = BLOCK_SUPERCONTEXT (b);
8513 }
8514 return b;
8515 }
8516
8517 /* Lookup for NAME in the nested function's blocks, all the way up to
8518 the current toplevel one. It complies with Java's local variable
8519 scoping rules. */
8520
8521 static tree
8522 lookup_name_in_blocks (name)
8523 tree name;
8524 {
8525 tree b = GET_CURRENT_BLOCK (current_function_decl);
8526
8527 while (b != current_function_decl)
8528 {
8529 tree current;
8530
8531 /* Paranoid sanity check. To be removed */
8532 if (TREE_CODE (b) != BLOCK)
8533 fatal ("non block expr function body - lookup_name_in_blocks");
8534
8535 for (current = BLOCK_EXPR_DECLS (b); current;
8536 current = TREE_CHAIN (current))
8537 if (DECL_NAME (current) == name)
8538 return current;
8539 b = BLOCK_SUPERCONTEXT (b);
8540 }
8541 return NULL_TREE;
8542 }
8543
8544 static void
8545 maybe_absorb_scoping_blocks ()
8546 {
8547 while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
8548 {
8549 tree b = exit_block ();
8550 java_method_add_stmt (current_function_decl, b);
8551 SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
8552 }
8553 }
8554
8555 \f
8556 /* This section of the source is reserved to build_* functions that
8557 are building incomplete tree nodes and the patch_* functions that
8558 are completing them. */
8559
8560 /* Build a super() constructor invocation. Returns empty_stmt_node if
8561 we're currently dealing with the class java.lang.Object. */
8562
8563 static tree
8564 build_super_invocation ()
8565 {
8566 if (current_class == object_type_node)
8567 return empty_stmt_node;
8568 else
8569 {
8570 tree super_wfl = build_wfl_node (super_identifier_node);
8571 return build_method_invocation (super_wfl, NULL_TREE);
8572 }
8573 }
8574
8575 /* Build a SUPER/THIS qualified method invocation. */
8576
8577 static tree
8578 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
8579 int use_this;
8580 tree name, args;
8581 int lloc, rloc;
8582
8583 {
8584 tree invok;
8585 tree wfl =
8586 build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
8587 EXPR_WFL_LINECOL (wfl) = lloc;
8588 invok = build_method_invocation (name, args);
8589 return make_qualified_primary (wfl, invok, rloc);
8590 }
8591
8592 /* Build an incomplete CALL_EXPR node. */
8593
8594 static tree
8595 build_method_invocation (name, args)
8596 tree name;
8597 tree args;
8598 {
8599 tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
8600 TREE_SIDE_EFFECTS (call) = 1;
8601 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
8602 return call;
8603 }
8604
8605 /* Build an incomplete new xxx(...) node. */
8606
8607 static tree
8608 build_new_invocation (name, args)
8609 tree name, args;
8610 {
8611 tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
8612 TREE_SIDE_EFFECTS (call) = 1;
8613 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
8614 return call;
8615 }
8616
8617 /* Build an incomplete assignment expression. */
8618
8619 static tree
8620 build_assignment (op, op_location, lhs, rhs)
8621 int op, op_location;
8622 tree lhs, rhs;
8623 {
8624 tree assignment;
8625 /* Build the corresponding binop if we deal with a Compound
8626 Assignment operator. Mark the binop sub-tree as part of a
8627 Compound Assignment expression */
8628 if (op != ASSIGN_TK)
8629 {
8630 rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
8631 COMPOUND_ASSIGN_P (rhs) = 1;
8632 }
8633 assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
8634 TREE_SIDE_EFFECTS (assignment) = 1;
8635 EXPR_WFL_LINECOL (assignment) = op_location;
8636 return assignment;
8637 }
8638
8639 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
8640
8641 char *
8642 print_int_node (node)
8643 tree node;
8644 {
8645 static char buffer [80];
8646 if (TREE_CONSTANT_OVERFLOW (node))
8647 sprintf (buffer, "<overflow>");
8648
8649 if (TREE_INT_CST_HIGH (node) == 0)
8650 sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
8651 TREE_INT_CST_LOW (node));
8652 else if (TREE_INT_CST_HIGH (node) == -1
8653 && TREE_INT_CST_LOW (node) != 0)
8654 {
8655 buffer [0] = '-';
8656 sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
8657 -TREE_INT_CST_LOW (node));
8658 }
8659 else
8660 sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
8661 TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
8662
8663 return buffer;
8664 }
8665
8666 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
8667 context. */
8668
8669 static int
8670 check_final_assignment (lvalue, wfl)
8671 tree lvalue, wfl;
8672 {
8673 if (JDECL_P (lvalue)
8674 && FIELD_FINAL (lvalue) && !IS_CLINIT (current_function_decl))
8675 {
8676 parse_error_context
8677 (wfl, "Can't assign a value to the final variable `%s'",
8678 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
8679 return 1;
8680 }
8681 return 0;
8682 }
8683
8684 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
8685 read. This is needed to avoid circularities in the implementation
8686 of these fields in libjava. */
8687
8688 static tree
8689 maybe_build_primttype_type_ref (rhs, wfl)
8690 tree rhs, wfl;
8691 {
8692 tree to_return = NULL_TREE;
8693 tree rhs_type = TREE_TYPE (rhs);
8694 if (TREE_CODE (rhs) == COMPOUND_EXPR)
8695 {
8696 tree n = TREE_OPERAND (rhs, 1);
8697 if (TREE_CODE (n) == VAR_DECL
8698 && DECL_NAME (n) == TYPE_identifier_node
8699 && rhs_type == class_ptr_type)
8700 {
8701 char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
8702 if (!strncmp (self_name, "java.lang.", 10))
8703 to_return = build_primtype_type_ref (self_name);
8704 }
8705 }
8706 return (to_return ? to_return : rhs );
8707 }
8708
8709 /* 15.25 Assignment operators. */
8710
8711 static tree
8712 patch_assignment (node, wfl_op1, wfl_op2)
8713 tree node;
8714 tree wfl_op1;
8715 tree wfl_op2;
8716 {
8717 tree rhs = TREE_OPERAND (node, 1);
8718 tree lvalue = TREE_OPERAND (node, 0), llvalue;
8719 tree lhs_type, rhs_type, new_rhs = NULL_TREE;
8720 int error_found = 0;
8721 int lvalue_from_array = 0;
8722
8723 /* Can't assign to a final. */
8724 if (check_final_assignment (lvalue, wfl_op1))
8725 error_found = 1;
8726
8727 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8728
8729 /* Lhs can be a named variable */
8730 if (JDECL_P (lvalue))
8731 {
8732 lhs_type = TREE_TYPE (lvalue);
8733 }
8734 /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
8735 comment on reason why */
8736 else if (TREE_CODE (wfl_op1) == ARRAY_REF)
8737 {
8738 lhs_type = TREE_TYPE (lvalue);
8739 lvalue_from_array = 1;
8740 }
8741 /* Or a field access */
8742 else if (TREE_CODE (lvalue) == COMPONENT_REF)
8743 lhs_type = TREE_TYPE (lvalue);
8744 /* Or a function return slot */
8745 else if (TREE_CODE (lvalue) == RESULT_DECL)
8746 lhs_type = TREE_TYPE (lvalue);
8747 /* Otherwise, we might want to try to write into an optimized static
8748 final, this is an of a different nature, reported further on. */
8749 else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
8750 && resolve_expression_name (wfl_op1, &llvalue))
8751 {
8752 if (check_final_assignment (llvalue, wfl_op1))
8753 {
8754 /* What we should do instead is resetting the all the flags
8755 previously set, exchange lvalue for llvalue and continue. */
8756 error_found = 1;
8757 return error_mark_node;
8758 }
8759 else
8760 lhs_type = TREE_TYPE (lvalue);
8761 }
8762 else
8763 {
8764 parse_error_context (wfl_op1, "Invalid left hand side of assignment");
8765 error_found = 1;
8766 }
8767
8768 rhs_type = TREE_TYPE (rhs);
8769 /* 5.1 Try the assignment conversion for builtin type. */
8770 new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
8771
8772 /* 5.2 If it failed, try a reference conversion */
8773 if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
8774 lhs_type = promote_type (rhs_type);
8775
8776 /* 15.25.2 If we have a compound assignment, convert RHS into the
8777 type of the LHS */
8778 else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
8779 new_rhs = convert (lhs_type, rhs);
8780
8781 /* Explicit cast required. This is an error */
8782 if (!new_rhs)
8783 {
8784 char *t1 = strdup (lang_printable_name (TREE_TYPE (rhs), 0));
8785 char *t2 = strdup (lang_printable_name (lhs_type, 0));
8786 tree wfl;
8787 char operation [32]; /* Max size known */
8788
8789 /* If the assignment is part of a declaration, we use the WFL of
8790 the declared variable to point out the error and call it a
8791 declaration problem. If the assignment is a genuine =
8792 operator, we call is a operator `=' problem, otherwise we
8793 call it an assignment problem. In both of these last cases,
8794 we use the WFL of the operator to indicate the error. */
8795
8796 if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
8797 {
8798 wfl = wfl_op1;
8799 strcpy (operation, "declaration");
8800 }
8801 else
8802 {
8803 wfl = wfl_operator;
8804 if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
8805 strcpy (operation, "assignment");
8806 else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
8807 strcpy (operation, "`return'");
8808 else
8809 strcpy (operation, "`='");
8810 }
8811
8812 parse_error_context
8813 (wfl, (!valid_cast_to_p (rhs_type, lhs_type) ?
8814 "Incompatible type for %s. Can't convert `%s' to `%s'" :
8815 "Incompatible type for %s. Explicit cast "
8816 "needed to convert `%s' to `%s'"), operation, t1, t2);
8817 free (t1); free (t2);
8818 error_found = 1;
8819 }
8820
8821 /* Inline read access to java.lang.PRIMTYPE.TYPE */
8822 if (new_rhs)
8823 new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
8824
8825 if (error_found)
8826 return error_mark_node;
8827
8828 /* 10.10: Array Store Exception runtime check */
8829 if (!flag_emit_class_files
8830 && !flag_emit_xref
8831 && lvalue_from_array
8832 && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type))
8833 && !CLASS_FINAL (TYPE_NAME (GET_SKIP_TYPE (rhs_type))))
8834 {
8835 tree check;
8836 tree base = lvalue;
8837
8838 /* We need to retrieve the right argument for _Jv_CheckArrayStore */
8839 if (TREE_CODE (lvalue) == COMPOUND_EXPR)
8840 base = TREE_OPERAND (lvalue, 0);
8841 else
8842 {
8843 if (flag_bounds_check)
8844 base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
8845 else
8846 base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
8847 }
8848
8849 /* Build the invocation of _Jv_CheckArrayStore */
8850 check = build (CALL_EXPR, void_type_node,
8851 build_address_of (soft_checkarraystore_node),
8852 tree_cons (NULL_TREE, base,
8853 build_tree_list (NULL_TREE, new_rhs)),
8854 NULL_TREE);
8855 TREE_SIDE_EFFECTS (check) = 1;
8856
8857 /* We have to decide on an insertion point */
8858 if (TREE_CODE (lvalue) == COMPOUND_EXPR)
8859 {
8860 tree t;
8861 if (flag_bounds_check)
8862 {
8863 t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
8864 TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
8865 build (COMPOUND_EXPR, void_type_node, t, check);
8866 }
8867 else
8868 TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
8869 check, TREE_OPERAND (lvalue, 1));
8870 }
8871 else
8872 {
8873 /* Make sure the bound check will happen before the store check */
8874 if (flag_bounds_check)
8875 TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
8876 build (COMPOUND_EXPR, void_type_node,
8877 TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
8878 else
8879 lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
8880 }
8881 }
8882
8883 TREE_OPERAND (node, 0) = lvalue;
8884 TREE_OPERAND (node, 1) = new_rhs;
8885 TREE_TYPE (node) = lhs_type;
8886 return node;
8887 }
8888
8889 /* Check that type SOURCE can be cast into type DEST. If the cast
8890 can't occur at all, return 0 otherwise 1. This function is used to
8891 produce accurate error messages on the reasons why an assignment
8892 failed. */
8893
8894 static tree
8895 try_reference_assignconv (lhs_type, rhs)
8896 tree lhs_type, rhs;
8897 {
8898 tree new_rhs = NULL_TREE;
8899 tree rhs_type = TREE_TYPE (rhs);
8900
8901 if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
8902 {
8903 /* `null' may be assigned to any reference type */
8904 if (rhs == null_pointer_node)
8905 new_rhs = null_pointer_node;
8906 /* Try the reference assignment conversion */
8907 else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
8908 new_rhs = rhs;
8909 /* This is a magic assignment that we process differently */
8910 else if (rhs == soft_exceptioninfo_call_node)
8911 new_rhs = rhs;
8912 }
8913 return new_rhs;
8914 }
8915
8916 /* Check that RHS can be converted into LHS_TYPE by the assignment
8917 conversion (5.2), for the cases of RHS being a builtin type. Return
8918 NULL_TREE if the conversion fails or if because RHS isn't of a
8919 builtin type. Return a converted RHS if the conversion is possible. */
8920
8921 static tree
8922 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
8923 tree wfl_op1, lhs_type, rhs;
8924 {
8925 tree new_rhs = NULL_TREE;
8926 tree rhs_type = TREE_TYPE (rhs);
8927
8928 /* Zero accepted everywhere */
8929 if (TREE_CODE (rhs) == INTEGER_CST
8930 && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
8931 && JPRIMITIVE_TYPE_P (rhs_type))
8932 new_rhs = convert (lhs_type, rhs);
8933
8934 /* 5.1.1 Try Identity Conversion,
8935 5.1.2 Try Widening Primitive Conversion */
8936 else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
8937 new_rhs = convert (lhs_type, rhs);
8938
8939 /* Try a narrowing primitive conversion (5.1.3):
8940 - expression is a constant expression of type int AND
8941 - variable is byte, short or char AND
8942 - The value of the expression is representable in the type of the
8943 variable */
8944 else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
8945 && (lhs_type == byte_type_node || lhs_type == char_type_node
8946 || lhs_type == short_type_node))
8947 {
8948 if (int_fits_type_p (rhs, lhs_type))
8949 new_rhs = convert (lhs_type, rhs);
8950 else if (wfl_op1) /* Might be called with a NULL */
8951 parse_warning_context
8952 (wfl_op1, "Constant expression `%s' to wide for narrowing "
8953 "primitive conversion to `%s'",
8954 print_int_node (rhs), lang_printable_name (lhs_type, 0));
8955 /* Reported a warning that will turn into an error further
8956 down, so we don't return */
8957 }
8958
8959 return new_rhs;
8960 }
8961
8962 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
8963 conversion (5.1.1) or widening primitve conversion (5.1.2). Return
8964 0 is the conversion test fails. This implements parts the method
8965 invocation convertion (5.3). */
8966
8967 static int
8968 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
8969 tree lhs_type, rhs_type;
8970 {
8971 /* 5.1.1: This is the identity conversion part. */
8972 if (lhs_type == rhs_type)
8973 return 1;
8974
8975 /* Reject non primitive types */
8976 if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
8977 return 0;
8978
8979 /* 5.1.2: widening primitive conversion. byte, even if it's smaller
8980 than a char can't be converted into a char. Short can't too, but
8981 the < test below takes care of that */
8982 if (lhs_type == char_type_node && rhs_type == byte_type_node)
8983 return 0;
8984
8985 /* Accept all promoted type here. Note, we can't use <= in the test
8986 below, because we still need to bounce out assignments of short
8987 to char and the likes */
8988 if (lhs_type == int_type_node
8989 && (rhs_type == promoted_byte_type_node
8990 || rhs_type == promoted_short_type_node
8991 || rhs_type == promoted_char_type_node
8992 || rhs_type == promoted_boolean_type_node))
8993 return 1;
8994
8995 /* From here, an integral is widened if its precision is smaller
8996 than the precision of the LHS or if the LHS is a floating point
8997 type, or the RHS is a float and the RHS a double. */
8998 if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type)
8999 && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
9000 || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
9001 || (rhs_type == float_type_node && lhs_type == double_type_node))
9002 return 1;
9003
9004 return 0;
9005 }
9006
9007 /* Check that something of SOURCE type can be assigned or cast to
9008 something of DEST type at runtime. Return 1 if the operation is
9009 valid, 0 otherwise. If CAST is set to 1, we're treating the case
9010 were SOURCE is cast into DEST, which borrows a lot of the
9011 assignment check. */
9012
9013 static int
9014 valid_ref_assignconv_cast_p (source, dest, cast)
9015 tree source;
9016 tree dest;
9017 int cast;
9018 {
9019 /* SOURCE or DEST might be null if not from a declared entity. */
9020 if (!source || !dest)
9021 return 0;
9022 if (JNULLP_TYPE_P (source))
9023 return 1;
9024 if (TREE_CODE (source) == POINTER_TYPE)
9025 source = TREE_TYPE (source);
9026 if (TREE_CODE (dest) == POINTER_TYPE)
9027 dest = TREE_TYPE (dest);
9028 /* Case where SOURCE is a class type */
9029 if (TYPE_CLASS_P (source))
9030 {
9031 if (TYPE_CLASS_P (dest))
9032 return source == dest || inherits_from_p (source, dest)
9033 || (cast && inherits_from_p (dest, source));
9034 if (TYPE_INTERFACE_P (dest))
9035 {
9036 /* If doing a cast and SOURCE is final, the operation is
9037 always correct a compile time (because even if SOURCE
9038 does not implement DEST, a subclass of SOURCE might). */
9039 if (cast && !CLASS_FINAL (TYPE_NAME (source)))
9040 return 1;
9041 /* Otherwise, SOURCE must implement DEST */
9042 return interface_of_p (dest, source);
9043 }
9044 /* DEST is an array, cast permited if SOURCE is of Object type */
9045 return (cast && source == object_type_node ? 1 : 0);
9046 }
9047 if (TYPE_INTERFACE_P (source))
9048 {
9049 if (TYPE_CLASS_P (dest))
9050 {
9051 /* If not casting, DEST must be the Object type */
9052 if (!cast)
9053 return dest == object_type_node;
9054 /* We're doing a cast. The cast is always valid is class
9055 DEST is not final, otherwise, DEST must implement SOURCE */
9056 else if (!CLASS_FINAL (TYPE_NAME (dest)))
9057 return 1;
9058 else
9059 return interface_of_p (source, dest);
9060 }
9061 if (TYPE_INTERFACE_P (dest))
9062 {
9063 /* If doing a cast, then if SOURCE and DEST contain method
9064 with the same signature but different return type, then
9065 this is a (compile time) error */
9066 if (cast)
9067 {
9068 tree method_source, method_dest;
9069 tree source_type;
9070 tree source_sig;
9071 tree source_name;
9072 for (method_source = TYPE_METHODS (source); method_source;
9073 method_source = TREE_CHAIN (method_source))
9074 {
9075 source_sig =
9076 build_java_argument_signature (TREE_TYPE (method_source));
9077 source_type = TREE_TYPE (TREE_TYPE (method_source));
9078 source_name = DECL_NAME (method_source);
9079 for (method_dest = TYPE_METHODS (dest);
9080 method_dest; method_dest = TREE_CHAIN (method_dest))
9081 if (source_sig ==
9082 build_java_argument_signature (TREE_TYPE (method_dest))
9083 && source_name == DECL_NAME (method_dest)
9084 && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
9085 return 0;
9086 }
9087 return 1;
9088 }
9089 else
9090 return source == dest || interface_of_p (dest, source);
9091 }
9092 else /* Array */
9093 return 0;
9094 }
9095 if (TYPE_ARRAY_P (source))
9096 {
9097 if (TYPE_CLASS_P (dest))
9098 return dest == object_type_node;
9099 /* Can't cast an array to an interface unless the interface is
9100 java.lang.Cloneable */
9101 if (TYPE_INTERFACE_P (dest))
9102 return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
9103 else /* Arrays */
9104 {
9105 tree source_element_type = TYPE_ARRAY_ELEMENT (source);
9106 tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
9107
9108 /* In case of severe errors, they turn out null */
9109 if (!dest_element_type || !source_element_type)
9110 return 0;
9111 if (source_element_type == dest_element_type)
9112 return 1;
9113 return valid_ref_assignconv_cast_p (source_element_type,
9114 dest_element_type, cast);
9115 }
9116 return 0;
9117 }
9118 return 0;
9119 }
9120
9121 static int
9122 valid_cast_to_p (source, dest)
9123 tree source;
9124 tree dest;
9125 {
9126 if (TREE_CODE (source) == POINTER_TYPE)
9127 source = TREE_TYPE (source);
9128 if (TREE_CODE (dest) == POINTER_TYPE)
9129 dest = TREE_TYPE (dest);
9130
9131 if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
9132 return valid_ref_assignconv_cast_p (source, dest, 1);
9133
9134 else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
9135 return 1;
9136
9137 return 0;
9138 }
9139
9140 /* Method invocation conversion test. Return 1 if type SOURCE can be
9141 converted to type DEST through the methond invocation conversion
9142 process (5.3) */
9143
9144 static tree
9145 do_unary_numeric_promotion (arg)
9146 tree arg;
9147 {
9148 tree type = TREE_TYPE (arg);
9149 if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
9150 : TREE_CODE (type) == CHAR_TYPE)
9151 arg = convert (int_type_node, arg);
9152 return arg;
9153 }
9154
9155 /* Return a non zero value if SOURCE can be converted into DEST using
9156 the method invocation conversion rule (5.3). */
9157 static int
9158 valid_method_invocation_conversion_p (dest, source)
9159 tree dest, source;
9160 {
9161 return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
9162 && valid_builtin_assignconv_identity_widening_p (dest, source))
9163 || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
9164 && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
9165 && valid_ref_assignconv_cast_p (source, dest, 0)));
9166 }
9167
9168 /* Build an incomplete binop expression. */
9169
9170 static tree
9171 build_binop (op, op_location, op1, op2)
9172 enum tree_code op;
9173 int op_location;
9174 tree op1, op2;
9175 {
9176 tree binop = build (op, NULL_TREE, op1, op2);
9177 TREE_SIDE_EFFECTS (binop) = 1;
9178 /* Store the location of the operator, for better error report. The
9179 string of the operator will be rebuild based on the OP value. */
9180 EXPR_WFL_LINECOL (binop) = op_location;
9181 return binop;
9182 }
9183
9184 /* Build the string of the operator retained by NODE. If NODE is part
9185 of a compound expression, add an '=' at the end of the string. This
9186 function is called when an error needs to be reported on an
9187 operator. The string is returned as a pointer to a static character
9188 buffer. */
9189
9190 static char *
9191 operator_string (node)
9192 tree node;
9193 {
9194 #define BUILD_OPERATOR_STRING(S) \
9195 { \
9196 sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
9197 return buffer; \
9198 }
9199
9200 static char buffer [10];
9201 switch (TREE_CODE (node))
9202 {
9203 case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
9204 case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
9205 case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
9206 case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
9207 case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
9208 case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
9209 case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
9210 case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
9211 case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
9212 case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
9213 case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
9214 case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
9215 case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
9216 case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
9217 case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
9218 case GT_EXPR: BUILD_OPERATOR_STRING (">");
9219 case GE_EXPR: BUILD_OPERATOR_STRING (">=");
9220 case LT_EXPR: BUILD_OPERATOR_STRING ("<");
9221 case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
9222 case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
9223 case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
9224 case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
9225 case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
9226 case PREINCREMENT_EXPR: /* Fall through */
9227 case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
9228 case PREDECREMENT_EXPR: /* Fall through */
9229 case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
9230 default:
9231 fatal ("unregistered operator %s - operator_string",
9232 tree_code_name [TREE_CODE (node)]);
9233 }
9234 return NULL;
9235 #undef BUILD_OPERATOR_STRING
9236 }
9237
9238 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
9239 errors but we modify NODE so that it contains the type computed
9240 according to the expression, when it's fixed. Otherwise, we write
9241 error_mark_node as the type. It allows us to further the analysis
9242 of remaining nodes and detects more errors in certain cases. */
9243
9244 static tree
9245 patch_binop (node, wfl_op1, wfl_op2)
9246 tree node;
9247 tree wfl_op1;
9248 tree wfl_op2;
9249 {
9250 tree op1 = TREE_OPERAND (node, 0);
9251 tree op2 = TREE_OPERAND (node, 1);
9252 tree op1_type = TREE_TYPE (op1);
9253 tree op2_type = TREE_TYPE (op2);
9254 tree prom_type = NULL_TREE;
9255 int code = TREE_CODE (node);
9256
9257 /* If 1, tell the routine that we have to return error_mark_node
9258 after checking for the initialization of the RHS */
9259 int error_found = 0;
9260
9261 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9262
9263 switch (code)
9264 {
9265 /* 15.16 Multiplicative operators */
9266 case MULT_EXPR: /* 15.16.1 Multiplication Operator * */
9267 case RDIV_EXPR: /* 15.16.2 Division Operator / */
9268 case TRUNC_MOD_EXPR: /* 15.16.3 Remainder operator % */
9269 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
9270 {
9271 if (!JPRIMITIVE_TYPE_P (op1_type))
9272 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9273 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
9274 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9275 TREE_TYPE (node) = error_mark_node;
9276 error_found = 1;
9277 break;
9278 }
9279 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9280 /* Change the division operator if necessary */
9281 if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
9282 TREE_SET_CODE (node, TRUNC_DIV_EXPR);
9283
9284 /* This one is more complicated. FLOATs are processed by a
9285 function call to soft_fmod. Duplicate the value of the
9286 COMPOUND_ASSIGN_P flag. */
9287 if (code == TRUNC_MOD_EXPR)
9288 {
9289 tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
9290 COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
9291 TREE_SIDE_EFFECTS (mod)
9292 = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
9293 return mod;
9294 }
9295 break;
9296
9297 /* 15.17 Additive Operators */
9298 case PLUS_EXPR: /* 15.17.1 String Concatenation Operator + */
9299
9300 /* Operation is valid if either one argument is a string
9301 constant, a String object or a StringBuffer crafted for the
9302 purpose of the a previous usage of the String concatenation
9303 operator */
9304
9305 if (TREE_CODE (op1) == STRING_CST
9306 || TREE_CODE (op2) == STRING_CST
9307 || JSTRING_TYPE_P (op1_type)
9308 || JSTRING_TYPE_P (op2_type)
9309 || IS_CRAFTED_STRING_BUFFER_P (op1)
9310 || IS_CRAFTED_STRING_BUFFER_P (op2))
9311 return build_string_concatenation (op1, op2);
9312
9313 case MINUS_EXPR: /* 15.17.2 Additive Operators (+ and -) for
9314 Numeric Types */
9315 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
9316 {
9317 if (!JPRIMITIVE_TYPE_P (op1_type))
9318 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9319 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
9320 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9321 TREE_TYPE (node) = error_mark_node;
9322 error_found = 1;
9323 break;
9324 }
9325 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9326 break;
9327
9328 /* 15.18 Shift Operators */
9329 case LSHIFT_EXPR:
9330 case RSHIFT_EXPR:
9331 case URSHIFT_EXPR:
9332 if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
9333 {
9334 if (!JINTEGRAL_TYPE_P (op1_type))
9335 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
9336 else
9337 parse_error_context
9338 (wfl_operator, (JPRIMITIVE_TYPE_P (op2_type) ?
9339 "Incompatible type for `%s'. Explicit cast needed to convert "
9340 "shift distance from `%s' to integral" :
9341 "Incompatible type for `%s'. Can't convert shift distance from "
9342 "`%s' to integral"),
9343 operator_string (node), lang_printable_name (op2_type, 0));
9344 TREE_TYPE (node) = error_mark_node;
9345 error_found = 1;
9346 break;
9347 }
9348
9349 /* Unary numeric promotion (5.6.1) is performed on each operand
9350 separatly */
9351 op1 = do_unary_numeric_promotion (op1);
9352 op2 = do_unary_numeric_promotion (op2);
9353
9354 /* The type of the shift expression is the type of the promoted
9355 type of the left-hand operand */
9356 prom_type = TREE_TYPE (op1);
9357
9358 /* Shift int only up to 0x1f and long up to 0x3f */
9359 if (prom_type == int_type_node)
9360 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
9361 build_int_2 (0x1f, 0)));
9362 else
9363 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
9364 build_int_2 (0x3f, 0)));
9365
9366 /* The >>> operator is a >> operating on unsigned quantities */
9367 if (code == URSHIFT_EXPR && ! flag_emit_class_files)
9368 {
9369 tree to_return;
9370 tree utype = unsigned_type (prom_type);
9371 op1 = convert (utype, op1);
9372 TREE_SET_CODE (node, RSHIFT_EXPR);
9373 TREE_OPERAND (node, 0) = op1;
9374 TREE_OPERAND (node, 1) = op2;
9375 TREE_TYPE (node) = utype;
9376 to_return = convert (prom_type, node);
9377 /* Copy the original value of the COMPOUND_ASSIGN_P flag */
9378 COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
9379 TREE_SIDE_EFFECTS (to_return)
9380 = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
9381 return to_return;
9382 }
9383 break;
9384
9385 /* 15.19.1 Type Comparison Operator instaceof */
9386 case INSTANCEOF_EXPR:
9387
9388 TREE_TYPE (node) = boolean_type_node;
9389
9390 if (!(op2_type = resolve_type_during_patch (op2)))
9391 return error_mark_node;
9392
9393 /* The first operand must be a reference type or the null type */
9394 if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
9395 error_found = 1; /* Error reported further below */
9396
9397 /* The second operand must be a reference type */
9398 if (!JREFERENCE_TYPE_P (op2_type))
9399 {
9400 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
9401 parse_error_context
9402 (wfl_operator, "Invalid argument `%s' for `instanceof'",
9403 lang_printable_name (op2_type, 0));
9404 error_found = 1;
9405 }
9406
9407 if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
9408 {
9409 /* If the first operand is null, the result is always false */
9410 if (op1 == null_pointer_node)
9411 return boolean_false_node;
9412 else if (flag_emit_class_files)
9413 {
9414 TREE_OPERAND (node, 1) = op2_type;
9415 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
9416 return node;
9417 }
9418 /* Otherwise we have to invoke instance of to figure it out */
9419 else
9420 {
9421 tree call =
9422 build (CALL_EXPR, boolean_type_node,
9423 build_address_of (soft_instanceof_node),
9424 tree_cons
9425 (NULL_TREE, op1,
9426 build_tree_list (NULL_TREE,
9427 build_class_ref (op2_type))),
9428 NULL_TREE);
9429 TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
9430 return call;
9431 }
9432 }
9433 /* There is no way the expression operand can be an instance of
9434 the type operand. This is a compile time error. */
9435 else
9436 {
9437 char *t1 = strdup (lang_printable_name (op1_type, 0));
9438 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
9439 parse_error_context
9440 (wfl_operator, "Impossible for `%s' to be instance of `%s'",
9441 t1, lang_printable_name (op2_type, 0));
9442 free (t1);
9443 error_found = 1;
9444 }
9445
9446 break;
9447
9448 /* 15.21 Bitwise and Logical Operators */
9449 case BIT_AND_EXPR:
9450 case BIT_XOR_EXPR:
9451 case BIT_IOR_EXPR:
9452 if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
9453 /* Binary numeric promotion is performed on both operand and the
9454 expression retain that type */
9455 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9456
9457 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE
9458 && TREE_CODE (op1_type) == BOOLEAN_TYPE)
9459 /* The type of the bitwise operator expression is BOOLEAN */
9460 prom_type = boolean_type_node;
9461 else
9462 {
9463 if (!JINTEGRAL_TYPE_P (op1_type))
9464 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
9465 if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
9466 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
9467 TREE_TYPE (node) = error_mark_node;
9468 error_found = 1;
9469 /* Insert a break here if adding thing before the switch's
9470 break for this case */
9471 }
9472 break;
9473
9474 /* 15.22 Conditional-And Operator */
9475 case TRUTH_ANDIF_EXPR:
9476 /* 15.23 Conditional-Or Operator */
9477 case TRUTH_ORIF_EXPR:
9478 /* Operands must be of BOOLEAN type */
9479 if (TREE_CODE (op1_type) != BOOLEAN_TYPE ||
9480 TREE_CODE (op2_type) != BOOLEAN_TYPE)
9481 {
9482 if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
9483 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
9484 if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
9485 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
9486 TREE_TYPE (node) = boolean_type_node;
9487 error_found = 1;
9488 break;
9489 }
9490 /* The type of the conditional operators is BOOLEAN */
9491 prom_type = boolean_type_node;
9492 break;
9493
9494 /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
9495 case LT_EXPR:
9496 case GT_EXPR:
9497 case LE_EXPR:
9498 case GE_EXPR:
9499 /* The type of each of the operands must be a primitive numeric
9500 type */
9501 if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
9502 {
9503 if (!JNUMERIC_TYPE_P (op1_type))
9504 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9505 if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
9506 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9507 TREE_TYPE (node) = boolean_type_node;
9508 error_found = 1;
9509 break;
9510 }
9511 /* Binary numeric promotion is performed on the operands */
9512 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9513 /* The type of the relation expression is always BOOLEAN */
9514 prom_type = boolean_type_node;
9515 break;
9516
9517 /* 15.20 Equality Operator */
9518 case EQ_EXPR:
9519 case NE_EXPR:
9520 /* 15.20.1 Numerical Equality Operators == and != */
9521 /* Binary numeric promotion is performed on the operands */
9522 if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
9523 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9524
9525 /* 15.20.2 Boolean Equality Operators == and != */
9526 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
9527 TREE_CODE (op2_type) == BOOLEAN_TYPE)
9528 ; /* Nothing to do here */
9529
9530 /* 15.20.3 Reference Equality Operators == and != */
9531 /* Types have to be either references or the null type. If
9532 they're references, it must be possible to convert either
9533 type to the other by casting conversion. */
9534 else if (op1 == null_pointer_node || op2 == null_pointer_node
9535 || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
9536 && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
9537 || valid_ref_assignconv_cast_p (op2_type,
9538 op1_type, 1))))
9539 ; /* Nothing to do here */
9540
9541 /* Else we have an error figure what can't be converted into
9542 what and report the error */
9543 else
9544 {
9545 char *t1;
9546 t1 = strdup (lang_printable_name (op1_type, 0));
9547 parse_error_context
9548 (wfl_operator, "Incompatible type for `%s'. Can't convert `%s' "
9549 "to `%s'", operator_string (node), t1,
9550 lang_printable_name (op2_type, 0));
9551 free (t1);
9552 TREE_TYPE (node) = boolean_type_node;
9553 error_found = 1;
9554 break;
9555 }
9556 prom_type = boolean_type_node;
9557 break;
9558 }
9559
9560 if (error_found)
9561 return error_mark_node;
9562
9563 TREE_OPERAND (node, 0) = op1;
9564 TREE_OPERAND (node, 1) = op2;
9565 TREE_TYPE (node) = prom_type;
9566 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
9567
9568 if (flag_emit_xref)
9569 return node;
9570
9571 /* fold does not respect side-effect order as required for Java but not C.
9572 * Also, it sometimes create SAVE_EXPRs which are bad when emitting
9573 * bytecode.
9574 */
9575 if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
9576 : ! TREE_SIDE_EFFECTS (node))
9577 node = fold (node);
9578 return node;
9579 }
9580
9581 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
9582 zero value, the value of CSTE comes after the valude of STRING */
9583
9584 static tree
9585 do_merge_string_cste (cste, string, string_len, after)
9586 tree cste;
9587 char *string;
9588 int string_len, after;
9589 {
9590 int len = TREE_STRING_LENGTH (cste) + string_len;
9591 char *old = TREE_STRING_POINTER (cste);
9592 TREE_STRING_LENGTH (cste) = len;
9593 TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
9594 if (after)
9595 {
9596 strcpy (TREE_STRING_POINTER (cste), string);
9597 strcat (TREE_STRING_POINTER (cste), old);
9598 }
9599 else
9600 {
9601 strcpy (TREE_STRING_POINTER (cste), old);
9602 strcat (TREE_STRING_POINTER (cste), string);
9603 }
9604 return cste;
9605 }
9606
9607 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
9608 new STRING_CST on success, NULL_TREE on failure */
9609
9610 static tree
9611 merge_string_cste (op1, op2, after)
9612 tree op1, op2;
9613 int after;
9614 {
9615 /* Handle two string constants right away */
9616 if (TREE_CODE (op2) == STRING_CST)
9617 return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
9618 TREE_STRING_LENGTH (op2), after);
9619
9620 /* Reasonable integer constant can be treated right away */
9621 if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
9622 {
9623 static char *boolean_true = "true";
9624 static char *boolean_false = "false";
9625 static char *null_pointer = "null";
9626 char ch[3];
9627 char *string;
9628
9629 if (op2 == boolean_true_node)
9630 string = boolean_true;
9631 else if (op2 == boolean_false_node)
9632 string = boolean_false;
9633 else if (op2 == null_pointer_node)
9634 string = null_pointer;
9635 else if (TREE_TYPE (op2) == char_type_node)
9636 {
9637 ch[0] = (char )TREE_INT_CST_LOW (op2);
9638 ch[1] = '\0';
9639 string = ch;
9640 }
9641 else
9642 string = print_int_node (op2);
9643
9644 return do_merge_string_cste (op1, string, strlen (string), after);
9645 }
9646 return NULL_TREE;
9647 }
9648
9649 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
9650 has to be a STRING_CST and the other part must be a STRING_CST or a
9651 INTEGRAL constant. Return a new STRING_CST if the operation
9652 succeed, NULL_TREE otherwise.
9653
9654 If the case we want to optimize for space, we might want to return
9655 NULL_TREE for each invocation of this routine. FIXME */
9656
9657 static tree
9658 string_constant_concatenation (op1, op2)
9659 tree op1, op2;
9660 {
9661 if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
9662 {
9663 tree string, rest;
9664 int invert;
9665
9666 string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
9667 rest = (string == op1 ? op2 : op1);
9668 invert = (string == op1 ? 0 : 1 );
9669
9670 /* Walk REST, only if it looks reasonable */
9671 if (TREE_CODE (rest) != STRING_CST
9672 && !IS_CRAFTED_STRING_BUFFER_P (rest)
9673 && !JSTRING_TYPE_P (TREE_TYPE (rest))
9674 && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
9675 {
9676 rest = java_complete_tree (rest);
9677 if (rest == error_mark_node)
9678 return error_mark_node;
9679 rest = fold (rest);
9680 }
9681 return merge_string_cste (string, rest, invert);
9682 }
9683 return NULL_TREE;
9684 }
9685
9686 /* Implement the `+' operator. Does static optimization if possible,
9687 otherwise create (if necessary) and append elements to a
9688 StringBuffer. The StringBuffer will be carried around until it is
9689 used for a function call or an assignment. Then toString() will be
9690 called on it to turn it into a String object. */
9691
9692 static tree
9693 build_string_concatenation (op1, op2)
9694 tree op1, op2;
9695 {
9696 tree result;
9697 int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
9698
9699 if (flag_emit_xref)
9700 return build (PLUS_EXPR, string_type_node, op1, op2);
9701
9702 /* Try to do some static optimization */
9703 if ((result = string_constant_concatenation (op1, op2)))
9704 return result;
9705
9706 /* Discard empty strings on either side of the expression */
9707 if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
9708 {
9709 op1 = op2;
9710 op2 = NULL_TREE;
9711 }
9712 else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
9713 op2 = NULL_TREE;
9714
9715 /* If operands are string constant, turn then into object references */
9716 if (TREE_CODE (op1) == STRING_CST)
9717 op1 = patch_string_cst (op1);
9718 if (op2 && TREE_CODE (op2) == STRING_CST)
9719 op2 = patch_string_cst (op2);
9720
9721 /* If either one of the constant is null and the other non null
9722 operand is a String object, return it. */
9723 if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
9724 return op1;
9725
9726 /* If OP1 isn't already a StringBuffer, create and
9727 initialize a new one */
9728 if (!IS_CRAFTED_STRING_BUFFER_P (op1))
9729 {
9730 /* Two solutions here:
9731 1) OP1 is a string reference, we call new StringBuffer(OP1)
9732 2) OP1 is something else, we call new StringBuffer().append(OP1). */
9733 if (JSTRING_TYPE_P (TREE_TYPE (op1)))
9734 op1 = BUILD_STRING_BUFFER (op1);
9735 else
9736 {
9737 tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
9738 op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
9739 }
9740 }
9741
9742 if (op2)
9743 {
9744 /* OP1 is no longer the last node holding a crafted StringBuffer */
9745 IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
9746 /* Create a node for `{new...,xxx}.append (op2)' */
9747 if (op2)
9748 op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
9749 }
9750
9751 /* Mark the last node holding a crafted StringBuffer */
9752 IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
9753
9754 TREE_SIDE_EFFECTS (op1) = side_effects;
9755 return op1;
9756 }
9757
9758 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
9759 StringBuffer. If no string were found to be patched, return
9760 NULL. */
9761
9762 static tree
9763 patch_string (node)
9764 tree node;
9765 {
9766 if (node == error_mark_node)
9767 return error_mark_node;
9768 if (TREE_CODE (node) == STRING_CST)
9769 return patch_string_cst (node);
9770 else if (IS_CRAFTED_STRING_BUFFER_P (node))
9771 {
9772 int saved = ctxp->explicit_constructor_p;
9773 tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
9774 tree ret;
9775 /* Temporary disable forbid the use of `this'. */
9776 ctxp->explicit_constructor_p = 0;
9777 ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
9778 /* Restore it at its previous value */
9779 ctxp->explicit_constructor_p = saved;
9780 return ret;
9781 }
9782 return NULL_TREE;
9783 }
9784
9785 /* Build the internal representation of a string constant. */
9786
9787 static tree
9788 patch_string_cst (node)
9789 tree node;
9790 {
9791 int location;
9792 if (! flag_emit_class_files)
9793 {
9794 push_obstacks (&permanent_obstack, &permanent_obstack);
9795 node = get_identifier (TREE_STRING_POINTER (node));
9796 location = alloc_name_constant (CONSTANT_String, node);
9797 node = build_ref_from_constant_pool (location);
9798 }
9799 TREE_TYPE (node) = string_ptr_type_node;
9800 TREE_CONSTANT (node) = 1;
9801 return node;
9802 }
9803
9804 /* Build an incomplete unary operator expression. */
9805
9806 static tree
9807 build_unaryop (op_token, op_location, op1)
9808 int op_token, op_location;
9809 tree op1;
9810 {
9811 enum tree_code op;
9812 tree unaryop;
9813 switch (op_token)
9814 {
9815 case PLUS_TK: op = UNARY_PLUS_EXPR; break;
9816 case MINUS_TK: op = NEGATE_EXPR; break;
9817 case NEG_TK: op = TRUTH_NOT_EXPR; break;
9818 case NOT_TK: op = BIT_NOT_EXPR; break;
9819 default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
9820 op_token);
9821 }
9822
9823 unaryop = build1 (op, NULL_TREE, op1);
9824 TREE_SIDE_EFFECTS (unaryop) = 1;
9825 /* Store the location of the operator, for better error report. The
9826 string of the operator will be rebuild based on the OP value. */
9827 EXPR_WFL_LINECOL (unaryop) = op_location;
9828 return unaryop;
9829 }
9830
9831 /* Special case for the ++/-- operators, since they require an extra
9832 argument to build, which is set to NULL and patched
9833 later. IS_POST_P is 1 if the operator, 0 otherwise. */
9834
9835 static tree
9836 build_incdec (op_token, op_location, op1, is_post_p)
9837 int op_token, op_location;
9838 tree op1;
9839 int is_post_p;
9840 {
9841 static enum tree_code lookup [2][2] =
9842 {
9843 { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
9844 { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
9845 };
9846 tree node = build (lookup [is_post_p][(op_token - DECR_TK)],
9847 NULL_TREE, op1, NULL_TREE);
9848 TREE_SIDE_EFFECTS (node) = 1;
9849 /* Store the location of the operator, for better error report. The
9850 string of the operator will be rebuild based on the OP value. */
9851 EXPR_WFL_LINECOL (node) = op_location;
9852 return node;
9853 }
9854
9855 /* Build an incomplete cast operator, based on the use of the
9856 CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
9857 set. java_complete_tree is trained to walk a CONVERT_EXPR even
9858 though its type is already set. */
9859
9860 static tree
9861 build_cast (location, type, exp)
9862 int location;
9863 tree type, exp;
9864 {
9865 tree node = build1 (CONVERT_EXPR, type, exp);
9866 EXPR_WFL_LINECOL (node) = location;
9867 return node;
9868 }
9869
9870 /* 15.14 Unary operators. We return error_mark_node in case of error,
9871 but preserve the type of NODE if the type is fixed. */
9872
9873 static tree
9874 patch_unaryop (node, wfl_op)
9875 tree node;
9876 tree wfl_op;
9877 {
9878 tree op = TREE_OPERAND (node, 0);
9879 tree op_type = TREE_TYPE (op);
9880 tree prom_type = NULL_TREE, value, decl;
9881 int code = TREE_CODE (node);
9882 int error_found = 0;
9883
9884 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9885
9886 switch (code)
9887 {
9888 /* 15.13.2 Postfix Increment Operator ++ */
9889 case POSTINCREMENT_EXPR:
9890 /* 15.13.3 Postfix Increment Operator -- */
9891 case POSTDECREMENT_EXPR:
9892 /* 15.14.1 Prefix Increment Operator ++ */
9893 case PREINCREMENT_EXPR:
9894 /* 15.14.2 Prefix Decrement Operator -- */
9895 case PREDECREMENT_EXPR:
9896 decl = strip_out_static_field_access_decl (op);
9897 /* We really should have a JAVA_ARRAY_EXPR to avoid this */
9898 if (!JDECL_P (decl)
9899 && TREE_CODE (decl) != COMPONENT_REF
9900 && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
9901 && TREE_CODE (decl) != INDIRECT_REF
9902 && !(TREE_CODE (decl) == COMPOUND_EXPR
9903 && TREE_OPERAND (decl, 1)
9904 && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
9905 {
9906 tree lvalue;
9907 /* Before screaming, check that we're not in fact trying to
9908 increment a optimized static final access, in which case
9909 we issue an different error message. */
9910 if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
9911 && resolve_expression_name (wfl_op, &lvalue)
9912 && check_final_assignment (lvalue, wfl_op)))
9913 parse_error_context (wfl_operator, "Invalid argument to `%s'",
9914 operator_string (node));
9915 TREE_TYPE (node) = error_mark_node;
9916 error_found = 1;
9917 }
9918 else if (check_final_assignment (op, wfl_op))
9919 error_found = 1;
9920
9921 /* From now on, we know that op if a variable and that it has a
9922 valid wfl. We use wfl_op to locate errors related to the
9923 ++/-- operand. */
9924 else if (!JNUMERIC_TYPE_P (op_type))
9925 {
9926 parse_error_context
9927 (wfl_op, "Invalid argument type `%s' to `%s'",
9928 lang_printable_name (op_type, 0), operator_string (node));
9929 TREE_TYPE (node) = error_mark_node;
9930 error_found = 1;
9931 }
9932 else
9933 {
9934 /* Before the addition, binary numeric promotion is performed on
9935 both operands */
9936 value = build_int_2 (1, 0);
9937 TREE_TYPE (node) =
9938 binary_numeric_promotion (op_type, TREE_TYPE (value), &op, &value);
9939 /* And write the promoted incremented and increment */
9940 TREE_OPERAND (node, 0) = op;
9941 TREE_OPERAND (node, 1) = value;
9942 /* Convert the overall back into its original type. */
9943 return fold (convert (op_type, node));
9944 }
9945 break;
9946
9947 /* 15.14.3 Unary Plus Operator + */
9948 case UNARY_PLUS_EXPR:
9949 /* 15.14.4 Unary Minus Operator - */
9950 case NEGATE_EXPR:
9951 if (!JNUMERIC_TYPE_P (op_type))
9952 {
9953 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
9954 TREE_TYPE (node) = error_mark_node;
9955 error_found = 1;
9956 }
9957 /* Unary numeric promotion is performed on operand */
9958 else
9959 {
9960 op = do_unary_numeric_promotion (op);
9961 prom_type = TREE_TYPE (op);
9962 if (code == UNARY_PLUS_EXPR)
9963 return fold (op);
9964 }
9965 break;
9966
9967 /* 15.14.5 Bitwise Complement Operator ~ */
9968 case BIT_NOT_EXPR:
9969 if (!JINTEGRAL_TYPE_P (op_type))
9970 {
9971 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
9972 TREE_TYPE (node) = error_mark_node;
9973 error_found = 1;
9974 }
9975 else
9976 {
9977 op = do_unary_numeric_promotion (op);
9978 prom_type = TREE_TYPE (op);
9979 }
9980 break;
9981
9982 /* 15.14.6 Logical Complement Operator ! */
9983 case TRUTH_NOT_EXPR:
9984 if (TREE_CODE (op_type) != BOOLEAN_TYPE)
9985 {
9986 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
9987 /* But the type is known. We will report an error if further
9988 attempt of a assignment is made with this rhs */
9989 TREE_TYPE (node) = boolean_type_node;
9990 error_found = 1;
9991 }
9992 else
9993 prom_type = boolean_type_node;
9994 break;
9995
9996 /* 15.15 Cast Expression */
9997 case CONVERT_EXPR:
9998 value = patch_cast (node, wfl_operator);
9999 if (value == error_mark_node)
10000 {
10001 /* If this cast is part of an assignment, we tell the code
10002 that deals with it not to complain about a mismatch,
10003 because things have been cast, anyways */
10004 TREE_TYPE (node) = error_mark_node;
10005 error_found = 1;
10006 }
10007 else
10008 {
10009 value = fold (value);
10010 TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
10011 return value;
10012 }
10013 break;
10014 }
10015
10016 if (error_found)
10017 return error_mark_node;
10018
10019 /* There are cases where node has been replaced by something else
10020 and we don't end up returning here: UNARY_PLUS_EXPR,
10021 CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
10022 TREE_OPERAND (node, 0) = fold (op);
10023 TREE_TYPE (node) = prom_type;
10024 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
10025 return fold (node);
10026 }
10027
10028 /* Generic type resolution that sometimes takes place during node
10029 patching. Returned the resolved type or generate an error
10030 message. Return the resolved type or NULL_TREE. */
10031
10032 static tree
10033 resolve_type_during_patch (type)
10034 tree type;
10035 {
10036 if (unresolved_type_p (type, NULL))
10037 {
10038 tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
10039 if (!type_decl)
10040 {
10041 parse_error_context (type,
10042 "Class `%s' not found in type declaration",
10043 IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
10044 return NULL_TREE;
10045 }
10046 else
10047 {
10048 CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
10049 return TREE_TYPE (type_decl);
10050 }
10051 }
10052 return type;
10053 }
10054 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
10055 found. Otherwise NODE or something meant to replace it is returned. */
10056
10057 static tree
10058 patch_cast (node, wfl_operator)
10059 tree node;
10060 tree wfl_operator;
10061 {
10062 tree op = TREE_OPERAND (node, 0);
10063 tree op_type = TREE_TYPE (op);
10064 tree cast_type = TREE_TYPE (node);
10065 char *t1;
10066
10067 /* First resolve OP_TYPE if unresolved */
10068 if (!(cast_type = resolve_type_during_patch (cast_type)))
10069 return error_mark_node;
10070
10071 /* Check on cast that are proven correct at compile time */
10072 if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
10073 {
10074 static tree convert_narrow ();
10075 /* Same type */
10076 if (cast_type == op_type)
10077 return node;
10078
10079 /* float and double type are converted to the original type main
10080 variant and then to the target type. */
10081 if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
10082 op = convert (integer_type_node, op);
10083
10084 /* Try widening/narowwing convertion. Potentially, things need
10085 to be worked out in gcc so we implement the extreme cases
10086 correctly. fold_convert() needs to be fixed. */
10087 return convert (cast_type, op);
10088 }
10089
10090 /* It's also valid to cast a boolean into a boolean */
10091 if (op_type == boolean_type_node && cast_type == boolean_type_node)
10092 return node;
10093
10094 /* null can be casted to references */
10095 if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
10096 return build_null_of_type (cast_type);
10097
10098 /* The remaining legal casts involve conversion between reference
10099 types. Check for their compile time correctness. */
10100 if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type)
10101 && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
10102 {
10103 TREE_TYPE (node) = promote_type (cast_type);
10104 /* Now, the case can be determined correct at compile time if
10105 OP_TYPE can be converted into CAST_TYPE by assignment
10106 conversion (5.2) */
10107
10108 if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
10109 {
10110 TREE_SET_CODE (node, NOP_EXPR);
10111 return node;
10112 }
10113
10114 if (flag_emit_class_files)
10115 {
10116 TREE_SET_CODE (node, CONVERT_EXPR);
10117 return node;
10118 }
10119
10120 /* The cast requires a run-time check */
10121 return build (CALL_EXPR, promote_type (cast_type),
10122 build_address_of (soft_checkcast_node),
10123 tree_cons (NULL_TREE, build_class_ref (cast_type),
10124 build_tree_list (NULL_TREE, op)),
10125 NULL_TREE);
10126 }
10127
10128 /* Any other casts are proven incorrect at compile time */
10129 t1 = strdup (lang_printable_name (op_type, 0));
10130 parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
10131 t1, lang_printable_name (cast_type, 0));
10132 free (t1);
10133 return error_mark_node;
10134 }
10135
10136 /* Build a null constant and give it the type TYPE. */
10137
10138 static tree
10139 build_null_of_type (type)
10140 tree type;
10141 {
10142 tree node = build_int_2 (0, 0);
10143 TREE_TYPE (node) = promote_type (type);
10144 return node;
10145 }
10146
10147 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
10148 a list of indices. */
10149 static tree
10150 build_array_ref (location, array, index)
10151 int location;
10152 tree array, index;
10153 {
10154 tree node = build (ARRAY_REF, NULL_TREE, array, index);
10155 EXPR_WFL_LINECOL (node) = location;
10156 return node;
10157 }
10158
10159 /* 15.12 Array Access Expression */
10160
10161 static tree
10162 patch_array_ref (node)
10163 tree node;
10164 {
10165 tree array = TREE_OPERAND (node, 0);
10166 tree array_type = TREE_TYPE (array);
10167 tree index = TREE_OPERAND (node, 1);
10168 tree index_type = TREE_TYPE (index);
10169 int error_found = 0;
10170
10171 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10172
10173 if (TREE_CODE (array_type) == POINTER_TYPE)
10174 array_type = TREE_TYPE (array_type);
10175
10176 /* The array reference must be an array */
10177 if (!TYPE_ARRAY_P (array_type))
10178 {
10179 parse_error_context
10180 (wfl_operator, "`[]' can only be applied to arrays. It can't be "
10181 "applied to `%s'", lang_printable_name (array_type, 0));
10182 TREE_TYPE (node) = error_mark_node;
10183 error_found = 1;
10184 }
10185
10186 /* The array index underdoes unary numeric promotion. The promoted
10187 type must be int */
10188 index = do_unary_numeric_promotion (index);
10189 if (TREE_TYPE (index) != int_type_node)
10190 {
10191 int could_cast = valid_cast_to_p (index_type, int_type_node);
10192 parse_error_context
10193 (wfl_operator,
10194 (could_cast ? "Incompatible type for `[]'. Explicit cast needed to "
10195 "convert `%s' to `int'" : "Incompatible type for `[]'. "
10196 "Can't convert `%s' to `int'"),
10197 lang_printable_name (index_type, 0));
10198 TREE_TYPE (node) = error_mark_node;
10199 error_found = 1;
10200 }
10201
10202 if (error_found)
10203 return error_mark_node;
10204
10205 array_type = TYPE_ARRAY_ELEMENT (array_type);
10206
10207 if (flag_emit_class_files || flag_emit_xref)
10208 {
10209 TREE_OPERAND (node, 0) = array;
10210 TREE_OPERAND (node, 1) = index;
10211 }
10212 else
10213 {
10214 /* The save_expr is for correct evaluation order. It would be cleaner
10215 to use force_evaluation_order (see comment there), but that is
10216 difficult when we also have to deal with bounds checking. */
10217 if (TREE_SIDE_EFFECTS (index))
10218 array = save_expr (array);
10219 node = build_java_arrayaccess (array, array_type, index);
10220 if (TREE_SIDE_EFFECTS (index))
10221 node = build (COMPOUND_EXPR, array_type, array, node);
10222 }
10223 TREE_TYPE (node) = array_type;
10224 return node;
10225 }
10226
10227 /* 15.9 Array Creation Expressions */
10228
10229 static tree
10230 build_newarray_node (type, dims, extra_dims)
10231 tree type;
10232 tree dims;
10233 int extra_dims;
10234 {
10235 tree node =
10236 build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims),
10237 build_int_2 (extra_dims, 0));
10238 return node;
10239 }
10240
10241 static tree
10242 patch_newarray (node)
10243 tree node;
10244 {
10245 tree type = TREE_OPERAND (node, 0);
10246 tree dims = TREE_OPERAND (node, 1);
10247 tree cdim, array_type;
10248 int error_found = 0;
10249 int ndims = 0;
10250 int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
10251
10252 /* Dimension types are verified. It's better for the types to be
10253 verified in order. */
10254 for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
10255 {
10256 int dim_error = 0;
10257 tree dim = TREE_VALUE (cdim);
10258
10259 /* Dim might have been saved during its evaluation */
10260 dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
10261
10262 /* The type of each specified dimension must be an integral type. */
10263 if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
10264 dim_error = 1;
10265
10266 /* Each expression undergoes an unary numeric promotion (5.6.1) and the
10267 promoted type must be int. */
10268 else
10269 {
10270 dim = do_unary_numeric_promotion (dim);
10271 if (TREE_TYPE (dim) != int_type_node)
10272 dim_error = 1;
10273 }
10274
10275 /* Report errors on types here */
10276 if (dim_error)
10277 {
10278 parse_error_context
10279 (TREE_PURPOSE (cdim),
10280 "Incompatible type for dimension in array creation expression. "
10281 "%s convert `%s' to `int'",
10282 (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
10283 "Explicit cast needed to" : "Can't"),
10284 lang_printable_name (TREE_TYPE (dim), 0));
10285 error_found = 1;
10286 }
10287
10288 TREE_PURPOSE (cdim) = NULL_TREE;
10289 }
10290
10291 /* Resolve array base type if unresolved */
10292 if (!(type = resolve_type_during_patch (type)))
10293 error_found = 1;
10294
10295 if (error_found)
10296 {
10297 /* We don't want further evaluation of this bogus array creation
10298 operation */
10299 TREE_TYPE (node) = error_mark_node;
10300 return error_mark_node;
10301 }
10302
10303 /* Set array_type to the actual (promoted) array type of the result. */
10304 if (TREE_CODE (type) == RECORD_TYPE)
10305 type = build_pointer_type (type);
10306 while (--xdims >= 0)
10307 {
10308 type = promote_type (build_java_array_type (type, -1));
10309 }
10310 dims = nreverse (dims);
10311 array_type = type;
10312 for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
10313 {
10314 type = array_type;
10315 array_type = build_java_array_type (type,
10316 TREE_CODE (cdim) == INTEGER_CST ?
10317 TREE_INT_CST_LOW (cdim) : -1);
10318 array_type = promote_type (array_type);
10319 }
10320 dims = nreverse (dims);
10321
10322 /* The node is transformed into a function call. Things are done
10323 differently according to the number of dimensions. If the number
10324 of dimension is equal to 1, then the nature of the base type
10325 (primitive or not) matters. */
10326 if (ndims == 1)
10327 return build_new_array (type, TREE_VALUE (dims));
10328
10329 /* Can't reuse what's already written in expr.c because it uses the
10330 JVM stack representation. Provide a build_multianewarray. FIXME */
10331 return build (CALL_EXPR, array_type,
10332 build_address_of (soft_multianewarray_node),
10333 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
10334 tree_cons (NULL_TREE,
10335 build_int_2 (ndims, 0), dims )),
10336 NULL_TREE);
10337 }
10338
10339 /* 10.6 Array initializer. */
10340
10341 /* Build a wfl for array element that don't have one, so we can
10342 pin-point errors. */
10343
10344 static tree
10345 maybe_build_array_element_wfl (node)
10346 tree node;
10347 {
10348 if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
10349 return build_expr_wfl (NULL_TREE, ctxp->filename,
10350 ctxp->elc.line, ctxp->elc.prev_col);
10351 else
10352 return NULL_TREE;
10353 }
10354
10355 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
10356 identification of initialized arrays easier to detect during walk
10357 and expansion. */
10358
10359 static tree
10360 build_new_array_init (location, values)
10361 int location;
10362 tree values;
10363 {
10364 tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
10365 tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
10366 EXPR_WFL_LINECOL (to_return) = location;
10367 return to_return;
10368 }
10369
10370 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
10371 occurred. Otherwise return NODE after having set its type
10372 appropriately. */
10373
10374 static tree
10375 patch_new_array_init (type, node)
10376 tree type, node;
10377 {
10378 int error_seen = 0;
10379 tree current, element_type;
10380 HOST_WIDE_INT length;
10381 int all_constant = 1;
10382 tree init = TREE_OPERAND (node, 0);
10383
10384 if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
10385 {
10386 parse_error_context (node,
10387 "Invalid array initializer for non-array type `%s'",
10388 lang_printable_name (type, 1));
10389 return error_mark_node;
10390 }
10391 type = TREE_TYPE (type);
10392 element_type = TYPE_ARRAY_ELEMENT (type);
10393
10394 CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
10395
10396 for (length = 0, current = CONSTRUCTOR_ELTS (init);
10397 current; length++, current = TREE_CHAIN (current))
10398 {
10399 tree elt = TREE_VALUE (current);
10400 if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
10401 {
10402 error_seen |= array_constructor_check_entry (element_type, current);
10403 elt = TREE_VALUE (current);
10404 /* When compiling to native code, STRING_CST is converted to
10405 INDIRECT_REF, but still with a TREE_CONSTANT flag. */
10406 if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
10407 all_constant = 0;
10408 }
10409 else
10410 {
10411 TREE_VALUE (current) = patch_new_array_init (element_type, elt);
10412 TREE_PURPOSE (current) = NULL_TREE;
10413 all_constant = 0;
10414 }
10415 if (elt && TREE_VALUE (elt) == error_mark_node)
10416 error_seen = 1;
10417 }
10418
10419 if (error_seen)
10420 return error_mark_node;
10421
10422 /* Create a new type. We can't reuse the one we have here by
10423 patching its dimension because it originally is of dimension -1
10424 hence reused by gcc. This would prevent triangular arrays. */
10425 type = build_java_array_type (element_type, length);
10426 TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
10427 TREE_TYPE (node) = promote_type (type);
10428 TREE_CONSTANT (init) = all_constant;
10429 TREE_CONSTANT (node) = all_constant;
10430 return node;
10431 }
10432
10433 /* Verify that one entry of the initializer element list can be
10434 assigned to the array base type. Report 1 if an error occurred, 0
10435 otherwise. */
10436
10437 static int
10438 array_constructor_check_entry (type, entry)
10439 tree type, entry;
10440 {
10441 char *array_type_string = NULL; /* For error reports */
10442 tree value, type_value, new_value, wfl_value, patched;
10443 int error_seen = 0;
10444
10445 new_value = NULL_TREE;
10446 wfl_value = TREE_VALUE (entry);
10447
10448 value = java_complete_tree (TREE_VALUE (entry));
10449 /* patch_string return error_mark_node if arg is error_mark_node */
10450 if ((patched = patch_string (value)))
10451 value = patched;
10452 if (value == error_mark_node)
10453 return 1;
10454
10455 type_value = TREE_TYPE (value);
10456
10457 /* At anytime, try_builtin_assignconv can report a warning on
10458 constant overflow during narrowing. */
10459 SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
10460 new_value = try_builtin_assignconv (wfl_operator, type, value);
10461 if (!new_value && (new_value = try_reference_assignconv (type, value)))
10462 type_value = promote_type (type);
10463
10464 /* Check and report errors */
10465 if (!new_value)
10466 {
10467 char *msg = (!valid_cast_to_p (type_value, type) ?
10468 "Can't" : "Explicit cast needed to");
10469 if (!array_type_string)
10470 array_type_string = strdup (lang_printable_name (type, 1));
10471 parse_error_context
10472 (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
10473 msg, lang_printable_name (type_value, 1), array_type_string);
10474 error_seen = 1;
10475 }
10476
10477 if (new_value)
10478 {
10479 new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
10480 TREE_VALUE (entry) = new_value;
10481 }
10482
10483 if (array_type_string)
10484 free (array_type_string);
10485
10486 TREE_PURPOSE (entry) = NULL_TREE;
10487 return error_seen;
10488 }
10489
10490 static tree
10491 build_this (location)
10492 int location;
10493 {
10494 tree node = build_wfl_node (this_identifier_node);
10495 TREE_SET_CODE (node, THIS_EXPR);
10496 EXPR_WFL_LINECOL (node) = location;
10497 return node;
10498 }
10499
10500 /* 14.15 The return statement. It builds a modify expression that
10501 assigns the returned value to the RESULT_DECL that hold the value
10502 to be returned. */
10503
10504 static tree
10505 build_return (location, op)
10506 int location;
10507 tree op;
10508 {
10509 tree node = build1 (RETURN_EXPR, NULL_TREE, op);
10510 EXPR_WFL_LINECOL (node) = location;
10511 node = build_debugable_stmt (location, node);
10512 return node;
10513 }
10514
10515 static tree
10516 patch_return (node)
10517 tree node;
10518 {
10519 tree return_exp = TREE_OPERAND (node, 0);
10520 tree meth = current_function_decl;
10521 tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
10522 int error_found = 0;
10523
10524 TREE_TYPE (node) = error_mark_node;
10525 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10526
10527 /* It's invalid to have a return value within a function that is
10528 declared with the keyword void or that is a constructor */
10529 if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
10530 error_found = 1;
10531
10532 /* It's invalid to use a return statement in a static block */
10533 if (IS_CLINIT (current_function_decl))
10534 error_found = 1;
10535
10536 /* It's invalid to have a no return value within a function that
10537 isn't declared with the keyword `void' */
10538 if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
10539 error_found = 2;
10540
10541 if (error_found)
10542 {
10543 if (IS_CLINIT (current_function_decl))
10544 parse_error_context (wfl_operator,
10545 "`return' inside static initializer.");
10546
10547 else if (!DECL_CONSTRUCTOR_P (meth))
10548 {
10549 char *t = strdup (lang_printable_name (mtype, 0));
10550 parse_error_context (wfl_operator,
10551 "`return' with%s value from `%s %s'",
10552 (error_found == 1 ? "" : "out"),
10553 t, lang_printable_name (meth, 0));
10554 free (t);
10555 }
10556 else
10557 parse_error_context (wfl_operator,
10558 "`return' with value from constructor `%s'",
10559 lang_printable_name (meth, 0));
10560 return error_mark_node;
10561 }
10562
10563 /* If we have a return_exp, build a modify expression and expand
10564 it. Note: at that point, the assignment is declared valid, but we
10565 may want to carry some more hacks */
10566 if (return_exp)
10567 {
10568 tree exp = java_complete_tree (return_exp);
10569 tree modify, patched;
10570
10571 /* If the function returned value and EXP are booleans, EXP has
10572 to be converted into the type of DECL_RESULT, which is integer
10573 (see complete_start_java_method) */
10574 if (TREE_TYPE (exp) == boolean_type_node &&
10575 TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
10576 exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
10577
10578 /* `null' can be assigned to a function returning a reference */
10579 if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
10580 exp == null_pointer_node)
10581 exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
10582
10583 if ((patched = patch_string (exp)))
10584 exp = patched;
10585
10586 modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
10587 EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
10588 modify = java_complete_tree (modify);
10589
10590 if (modify != error_mark_node)
10591 {
10592 TREE_SIDE_EFFECTS (modify) = 1;
10593 TREE_OPERAND (node, 0) = modify;
10594 }
10595 else
10596 return error_mark_node;
10597 }
10598 TREE_TYPE (node) = void_type_node;
10599 TREE_SIDE_EFFECTS (node) = 1;
10600 return node;
10601 }
10602
10603 /* 14.8 The if Statement */
10604
10605 static tree
10606 build_if_else_statement (location, expression, if_body, else_body)
10607 int location;
10608 tree expression, if_body, else_body;
10609 {
10610 tree node;
10611 if (!else_body)
10612 else_body = empty_stmt_node;
10613 node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
10614 EXPR_WFL_LINECOL (node) = location;
10615 node = build_debugable_stmt (location, node);
10616 return node;
10617 }
10618
10619 static tree
10620 patch_if_else_statement (node)
10621 tree node;
10622 {
10623 tree expression = TREE_OPERAND (node, 0);
10624
10625 TREE_TYPE (node) = error_mark_node;
10626 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10627
10628 /* The type of expression must be boolean */
10629 if (TREE_TYPE (expression) != boolean_type_node
10630 && TREE_TYPE (expression) != promoted_boolean_type_node)
10631 {
10632 parse_error_context
10633 (wfl_operator,
10634 "Incompatible type for `if'. Can't convert `%s' to `boolean'",
10635 lang_printable_name (TREE_TYPE (expression), 0));
10636 return error_mark_node;
10637 }
10638
10639 TREE_TYPE (node) = void_type_node;
10640 TREE_SIDE_EFFECTS (node) = 1;
10641 CAN_COMPLETE_NORMALLY (node)
10642 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
10643 | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
10644 return node;
10645 }
10646
10647 /* 14.6 Labeled Statements */
10648
10649 /* Action taken when a lableled statement is parsed. a new
10650 LABELED_BLOCK_EXPR is created. No statement is attached to the
10651 label, yet. LABEL can be NULL_TREE for artificially-generated blocks. */
10652
10653 static tree
10654 build_labeled_block (location, label)
10655 int location;
10656 tree label;
10657 {
10658 tree label_name ;
10659 tree label_decl, node;
10660 if (label == NULL_TREE || label == continue_identifier_node)
10661 label_name = label;
10662 else
10663 {
10664 label_name = merge_qualified_name (label_id, label);
10665 /* Issue an error if we try to reuse a label that was previously
10666 declared */
10667 if (IDENTIFIER_LOCAL_VALUE (label_name))
10668 {
10669 EXPR_WFL_LINECOL (wfl_operator) = location;
10670 parse_error_context (wfl_operator, "Declaration of `%s' shadows "
10671 "a previous label declaration",
10672 IDENTIFIER_POINTER (label));
10673 EXPR_WFL_LINECOL (wfl_operator) =
10674 EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
10675 parse_error_context (wfl_operator, "This is the location of the "
10676 "previous declaration of label `%s'",
10677 IDENTIFIER_POINTER (label));
10678 java_error_count--;
10679 }
10680 }
10681
10682 label_decl = create_label_decl (label_name);
10683 node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
10684 EXPR_WFL_LINECOL (node) = location;
10685 TREE_SIDE_EFFECTS (node) = 1;
10686 return node;
10687 }
10688
10689 /* A labeled statement LBE is attached a statement. */
10690
10691 static tree
10692 finish_labeled_statement (lbe, statement)
10693 tree lbe; /* Labeled block expr */
10694 tree statement;
10695 {
10696 /* In anyways, tie the loop to its statement */
10697 LABELED_BLOCK_BODY (lbe) = statement;
10698 pop_labeled_block ();
10699 POP_LABELED_BLOCK ();
10700 return lbe;
10701 }
10702
10703 /* 14.10, 14.11, 14.12 Loop Statements */
10704
10705 /* Create an empty LOOP_EXPR and make it the last in the nested loop
10706 list. */
10707
10708 static tree
10709 build_new_loop (loop_body)
10710 tree loop_body;
10711 {
10712 tree loop = build (LOOP_EXPR, NULL_TREE, loop_body);
10713 TREE_SIDE_EFFECTS (loop) = 1;
10714 PUSH_LOOP (loop);
10715 return loop;
10716 }
10717
10718 /* Create a loop body according to the following structure:
10719 COMPOUND_EXPR
10720 COMPOUND_EXPR (loop main body)
10721 EXIT_EXPR (this order is for while/for loops.
10722 LABELED_BLOCK_EXPR the order is reversed for do loops)
10723 LABEL_DECL (a continue occuring here branches at the
10724 BODY end of this labeled block)
10725 INCREMENT (if any)
10726
10727 REVERSED, if non zero, tells that the loop condition expr comes
10728 after the body, like in the do-while loop.
10729
10730 To obtain a loop, the loop body structure described above is
10731 encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
10732
10733 LABELED_BLOCK_EXPR
10734 LABEL_DECL (use this label to exit the loop)
10735 LOOP_EXPR
10736 <structure described above> */
10737
10738 static tree
10739 build_loop_body (location, condition, reversed)
10740 int location;
10741 tree condition;
10742 int reversed;
10743 {
10744 tree first, second, body;
10745
10746 condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
10747 EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
10748 condition = build_debugable_stmt (location, condition);
10749 TREE_SIDE_EFFECTS (condition) = 1;
10750
10751 body = build_labeled_block (0, continue_identifier_node);
10752 first = (reversed ? body : condition);
10753 second = (reversed ? condition : body);
10754 return
10755 build (COMPOUND_EXPR, NULL_TREE,
10756 build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
10757 }
10758
10759 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
10760 their order) on the current loop. Unlink the current loop from the
10761 loop list. */
10762
10763 static tree
10764 finish_loop_body (location, condition, body, reversed)
10765 int location;
10766 tree condition, body;
10767 int reversed;
10768 {
10769 tree to_return = ctxp->current_loop;
10770 tree loop_body = LOOP_EXPR_BODY (to_return);
10771 if (condition)
10772 {
10773 tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
10774 /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
10775 The real EXIT_EXPR is one operand further. */
10776 EXPR_WFL_LINECOL (cnode) = location;
10777 /* This one is for accurate error reports */
10778 EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
10779 TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
10780 }
10781 LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
10782 POP_LOOP ();
10783 return to_return;
10784 }
10785
10786 /* Tailored version of finish_loop_body for FOR loops, when FOR
10787 loops feature the condition part */
10788
10789 static tree
10790 finish_for_loop (location, condition, update, body)
10791 int location;
10792 tree condition, update, body;
10793 {
10794 /* Put the condition and the loop body in place */
10795 tree loop = finish_loop_body (location, condition, body, 0);
10796 /* LOOP is the current loop which has been now popped of the loop
10797 stack. Install the update block */
10798 LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
10799 return loop;
10800 }
10801
10802 /* If the loop isn't surrounded by a labeled statement, create one and
10803 insert LOOP as its body. */
10804
10805 static tree
10806 patch_loop_statement (loop)
10807 tree loop;
10808 {
10809 tree loop_label;
10810 tree block = ctxp->current_labeled_block;
10811 TREE_TYPE (loop) = void_type_node;
10812 if (block != NULL_TREE)
10813 {
10814 tree block_body = LABELED_BLOCK_BODY (block);
10815 if (IS_FOR_LOOP_P (loop))
10816 {
10817 if (TREE_CODE (block_body) == BLOCK)
10818 {
10819 block_body = BLOCK_EXPR_BODY (block_body);
10820 if (block_body == loop
10821 || (TREE_CODE (block_body) == COMPOUND_EXPR
10822 && TREE_OPERAND (block_body, 1) == loop))
10823 return loop;
10824 }
10825 }
10826 else
10827 {
10828 if (block_body == loop)
10829 return loop;
10830 }
10831 }
10832 loop_label = build_labeled_block (0, NULL_TREE);
10833 LABELED_BLOCK_BODY (loop_label) = loop;
10834 PUSH_LABELED_BLOCK (loop_label);
10835 loop = loop_label;
10836 return loop;
10837 }
10838
10839 /* 14.13, 14.14: break and continue Statements */
10840
10841 /* Build a break or a continue statement. a null NAME indicates an
10842 unlabeled break/continue statement. */
10843
10844 static tree
10845 build_bc_statement (location, is_break, name)
10846 int location, is_break;
10847 tree name;
10848 {
10849 tree break_continue, label_block_expr = NULL_TREE;
10850
10851 if (name)
10852 {
10853 if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE
10854 (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
10855 /* Null means that we don't have a target for this named
10856 break/continue. In this case, we make the target to be the
10857 label name, so that the error can be reported accuratly in
10858 patch_bc_statement. */
10859 label_block_expr = EXPR_WFL_NODE (name);
10860 }
10861 /* Unlabeled break/continue will be handled during the
10862 break/continue patch operation */
10863 break_continue
10864 = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
10865
10866 IS_BREAK_STMT_P (break_continue) = is_break;
10867 TREE_SIDE_EFFECTS (break_continue) = 1;
10868 EXPR_WFL_LINECOL (break_continue) = location;
10869 break_continue = build_debugable_stmt (location, break_continue);
10870 return break_continue;
10871 }
10872
10873 /* Verification of a break/continue statement. */
10874
10875 static tree
10876 patch_bc_statement (node)
10877 tree node;
10878 {
10879 tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
10880 tree labeled_block = ctxp->current_labeled_block;
10881 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10882
10883 /* Having an identifier here means that the target is unknown. */
10884 if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
10885 {
10886 parse_error_context (wfl_operator, "No label definition found for `%s'",
10887 IDENTIFIER_POINTER (bc_label));
10888 return error_mark_node;
10889 }
10890 if (! IS_BREAK_STMT_P (node))
10891 {
10892 /* It's a continue statement. */
10893 for (;; labeled_block = TREE_CHAIN (labeled_block))
10894 {
10895 if (labeled_block == NULL_TREE)
10896 {
10897 if (bc_label == NULL_TREE)
10898 parse_error_context (wfl_operator,
10899 "`continue' must be in loop");
10900 else
10901 parse_error_context
10902 (wfl_operator, "continue label `%s' does not name a loop",
10903 IDENTIFIER_POINTER (bc_label));
10904 return error_mark_node;
10905 }
10906 if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
10907 == continue_identifier_node)
10908 && (bc_label == NULL_TREE
10909 || TREE_CHAIN (labeled_block) == bc_label))
10910 {
10911 bc_label = labeled_block;
10912 break;
10913 }
10914 }
10915 }
10916 else if (!bc_label)
10917 {
10918 for (;; labeled_block = TREE_CHAIN (labeled_block))
10919 {
10920 if (labeled_block == NULL_TREE)
10921 {
10922 parse_error_context (wfl_operator,
10923 "`break' must be in loop or switch");
10924 return error_mark_node;
10925 }
10926 target_stmt = LABELED_BLOCK_BODY (labeled_block);
10927 if (TREE_CODE (target_stmt) == SWITCH_EXPR
10928 || TREE_CODE (target_stmt) == LOOP_EXPR)
10929 {
10930 bc_label = labeled_block;
10931 break;
10932 }
10933 }
10934 }
10935
10936 EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
10937 CAN_COMPLETE_NORMALLY (bc_label) = 1;
10938
10939 /* Our break/continue don't return values. */
10940 TREE_TYPE (node) = void_type_node;
10941 /* Encapsulate the break within a compound statement so that it's
10942 expanded all the times by expand_expr (and not clobered
10943 sometimes, like after a if statement) */
10944 node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
10945 TREE_SIDE_EFFECTS (node) = 1;
10946 return node;
10947 }
10948
10949 /* Process the exit expression belonging to a loop. Its type must be
10950 boolean. */
10951
10952 static tree
10953 patch_exit_expr (node)
10954 tree node;
10955 {
10956 tree expression = TREE_OPERAND (node, 0);
10957 TREE_TYPE (node) = error_mark_node;
10958 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10959
10960 /* The type of expression must be boolean */
10961 if (TREE_TYPE (expression) != boolean_type_node)
10962 {
10963 parse_error_context
10964 (wfl_operator,
10965 "Incompatible type for loop conditional. Can't convert `%s' to "
10966 "`boolean'",
10967 lang_printable_name (TREE_TYPE (expression), 0));
10968 return error_mark_node;
10969 }
10970 /* Now we know things are allright, invert the condition, fold and
10971 return */
10972 TREE_OPERAND (node, 0) =
10973 fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
10974
10975 if (! integer_zerop (TREE_OPERAND (node, 0))
10976 && ctxp->current_loop != NULL_TREE
10977 && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
10978 CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
10979 if (! integer_onep (TREE_OPERAND (node, 0)))
10980 CAN_COMPLETE_NORMALLY (node) = 1;
10981
10982
10983 TREE_TYPE (node) = void_type_node;
10984 return node;
10985 }
10986
10987 /* 14.9 Switch statement */
10988
10989 static tree
10990 patch_switch_statement (node)
10991 tree node;
10992 {
10993 tree se = TREE_OPERAND (node, 0), se_type;
10994
10995 /* Complete the switch expression */
10996 se = TREE_OPERAND (node, 0) = java_complete_tree (se);
10997 se_type = TREE_TYPE (se);
10998 /* The type of the switch expression must be char, byte, short or
10999 int */
11000 if (!JINTEGRAL_TYPE_P (se_type))
11001 {
11002 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11003 parse_error_context (wfl_operator, "Incompatible type for `switch'. "
11004 "Can't convert `%s' to `int'",
11005 lang_printable_name (se_type, 0));
11006 /* This is what java_complete_tree will check */
11007 TREE_OPERAND (node, 0) = error_mark_node;
11008 return error_mark_node;
11009 }
11010
11011 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11012
11013 /* Ready to return */
11014 if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
11015 {
11016 TREE_TYPE (node) = error_mark_node;
11017 return error_mark_node;
11018 }
11019 TREE_TYPE (node) = void_type_node;
11020 TREE_SIDE_EFFECTS (node) = 1;
11021 CAN_COMPLETE_NORMALLY (node)
11022 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
11023 || ! SWITCH_HAS_DEFAULT (node);
11024 return node;
11025 }
11026
11027 /* 14.18 The try statement */
11028
11029 static tree
11030 build_try_statement (location, try_block, catches)
11031 int location;
11032 tree try_block, catches;
11033 {
11034 tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
11035 EXPR_WFL_LINECOL (node) = location;
11036 return node;
11037 }
11038
11039 static tree
11040 build_try_finally_statement (location, try_block, finally)
11041 int location;
11042 tree try_block, finally;
11043 {
11044 tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
11045 EXPR_WFL_LINECOL (node) = location;
11046 return node;
11047 }
11048
11049 static tree
11050 patch_try_statement (node)
11051 tree node;
11052 {
11053 int error_found = 0;
11054 tree try = TREE_OPERAND (node, 0);
11055 /* Exception handlers are considered in left to right order */
11056 tree catch = nreverse (TREE_OPERAND (node, 1));
11057 tree current, caught_type_list = NULL_TREE;
11058
11059 /* Check catch clauses, if any. Every time we find an error, we try
11060 to process the next catch clause. We process the catch clause before
11061 the try block so that when processing the try block we can check thrown
11062 exceptions againts the caught type list. */
11063 for (current = catch; current; current = TREE_CHAIN (current))
11064 {
11065 tree carg_decl, carg_type;
11066 tree sub_current, catch_block, catch_clause;
11067 int unreachable;
11068
11069 /* At this point, the structure of the catch clause is
11070 CATCH_EXPR (catch node)
11071 BLOCK (with the decl of the parameter)
11072 COMPOUND_EXPR
11073 MODIFY_EXPR (assignment of the catch parameter)
11074 BLOCK (catch clause block)
11075 */
11076 catch_clause = TREE_OPERAND (current, 0);
11077 carg_decl = BLOCK_EXPR_DECLS (catch_clause);
11078 carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
11079
11080 /* Catch clauses can't have more than one parameter declared,
11081 but it's already enforced by the grammar. Make sure that the
11082 only parameter of the clause statement in of class Throwable
11083 or a subclass of Throwable, but that was done earlier. The
11084 catch clause parameter type has also been resolved. */
11085
11086 /* Just make sure that the catch clause parameter type inherits
11087 from java.lang.Throwable */
11088 if (!inherits_from_p (carg_type, throwable_type_node))
11089 {
11090 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
11091 parse_error_context (wfl_operator,
11092 "Can't catch class `%s'. Catch clause "
11093 "parameter type must be a subclass of "
11094 "class `java.lang.Throwable'",
11095 lang_printable_name (carg_type, 0));
11096 error_found = 1;
11097 continue;
11098 }
11099
11100 /* Partial check for unreachable catch statement: The catch
11101 clause is reachable iff is no earlier catch block A in
11102 the try statement such that the type of the catch
11103 clause's parameter is the same as or a subclass of the
11104 type of A's parameter */
11105 unreachable = 0;
11106 for (sub_current = catch;
11107 sub_current != current; sub_current = TREE_CHAIN (sub_current))
11108 {
11109 tree sub_catch_clause, decl;
11110 sub_catch_clause = TREE_OPERAND (sub_current, 0);
11111 decl = BLOCK_EXPR_DECLS (sub_catch_clause);
11112
11113 if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
11114 {
11115 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
11116 parse_error_context
11117 (wfl_operator, "`catch' not reached because of the catch "
11118 "clause at line %d", EXPR_WFL_LINENO (sub_current));
11119 unreachable = error_found = 1;
11120 break;
11121 }
11122 }
11123 /* Complete the catch clause block */
11124 catch_block = java_complete_tree (TREE_OPERAND (current, 0));
11125 if (catch_block == error_mark_node)
11126 {
11127 error_found = 1;
11128 continue;
11129 }
11130 if (CAN_COMPLETE_NORMALLY (catch_block))
11131 CAN_COMPLETE_NORMALLY (node) = 1;
11132 TREE_OPERAND (current, 0) = catch_block;
11133
11134 if (unreachable)
11135 continue;
11136
11137 /* Things to do here: the exception must be thrown */
11138
11139 /* Link this type to the caught type list */
11140 caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
11141 }
11142
11143 PUSH_EXCEPTIONS (caught_type_list);
11144 if ((try = java_complete_tree (try)) == error_mark_node)
11145 error_found = 1;
11146 if (CAN_COMPLETE_NORMALLY (try))
11147 CAN_COMPLETE_NORMALLY (node) = 1;
11148 POP_EXCEPTIONS ();
11149
11150 /* Verification ends here */
11151 if (error_found)
11152 return error_mark_node;
11153
11154 TREE_OPERAND (node, 0) = try;
11155 TREE_OPERAND (node, 1) = catch;
11156 TREE_TYPE (node) = void_type_node;
11157 return node;
11158 }
11159
11160 /* 14.17 The synchronized Statement */
11161
11162 static tree
11163 patch_synchronized_statement (node, wfl_op1)
11164 tree node, wfl_op1;
11165 {
11166 tree expr = java_complete_tree (TREE_OPERAND (node, 0));
11167 tree block = TREE_OPERAND (node, 1);
11168
11169 tree enter, exit, expr_decl, assignment;
11170
11171 if (expr == error_mark_node)
11172 {
11173 block = java_complete_tree (block);
11174 return expr;
11175 }
11176
11177 /* The TYPE of expr must be a reference type */
11178 if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
11179 {
11180 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11181 parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
11182 ". Can't convert `%s' to `java.lang.Object'",
11183 lang_printable_name (TREE_TYPE (expr), 0));
11184 return error_mark_node;
11185 }
11186
11187 if (flag_emit_xref)
11188 {
11189 TREE_OPERAND (node, 0) = expr;
11190 TREE_OPERAND (node, 1) = java_complete_tree (block);
11191 CAN_COMPLETE_NORMALLY (node) = 1;
11192 return node;
11193 }
11194
11195 /* Generate a try-finally for the synchronized statement, except
11196 that the handler that catches all throw exception calls
11197 _Jv_MonitorExit and then rethrow the exception.
11198 The synchronized statement is then implemented as:
11199 TRY
11200 {
11201 _Jv_MonitorEnter (expression)
11202 synchronized_block
11203 _Jv_MonitorExit (expression)
11204 }
11205 CATCH_ALL
11206 {
11207 e = _Jv_exception_info ();
11208 _Jv_MonitorExit (expression)
11209 Throw (e);
11210 } */
11211
11212 expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
11213 BUILD_MONITOR_ENTER (enter, expr_decl);
11214 BUILD_MONITOR_EXIT (exit, expr_decl);
11215 CAN_COMPLETE_NORMALLY (enter) = 1;
11216 CAN_COMPLETE_NORMALLY (exit) = 1;
11217 assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
11218 TREE_SIDE_EFFECTS (assignment) = 1;
11219 node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
11220 build (COMPOUND_EXPR, NULL_TREE,
11221 build (WITH_CLEANUP_EXPR, NULL_TREE,
11222 build (COMPOUND_EXPR, NULL_TREE,
11223 assignment, enter),
11224 NULL_TREE, exit),
11225 block));
11226 node = build_expr_block (node, expr_decl);
11227
11228 return java_complete_tree (node);
11229 }
11230
11231 /* 14.16 The throw Statement */
11232
11233 static tree
11234 patch_throw_statement (node, wfl_op1)
11235 tree node, wfl_op1;
11236 {
11237 tree expr = TREE_OPERAND (node, 0);
11238 tree type = TREE_TYPE (expr);
11239 int unchecked_ok = 0, tryblock_throws_ok = 0;
11240
11241 /* Thrown expression must be assignable to java.lang.Throwable */
11242 if (!try_reference_assignconv (throwable_type_node, expr))
11243 {
11244 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11245 parse_error_context (wfl_operator, "Can't throw `%s'; it must be a "
11246 "subclass of class `java.lang.Throwable'",
11247 lang_printable_name (type, 0));
11248 /* If the thrown expression was a reference, we further the
11249 compile-time check. */
11250 if (!JREFERENCE_TYPE_P (type))
11251 return error_mark_node;
11252 }
11253
11254 /* At least one of the following must be true */
11255
11256 /* The type of the throw expression is a not checked exception,
11257 i.e. is a unchecked expression. */
11258 unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
11259
11260 /* Throw is contained in a try statement and at least one catch
11261 clause can receive the thrown expression or the current method is
11262 declared to throw such an exception. Or, the throw statement is
11263 contained in a method or constructor declaration and the type of
11264 the Expression is assignable to at least one type listed in the
11265 throws clause the declaration. */
11266 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11267 if (!unchecked_ok)
11268 tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
11269 if (!(unchecked_ok || tryblock_throws_ok))
11270 {
11271 /* If there is a surrounding try block that has no matching
11272 clatch clause, report it first. A surrounding try block exits
11273 only if there is something after the list of checked
11274 exception thrown by the current function (if any). */
11275 if (IN_TRY_BLOCK_P ())
11276 parse_error_context (wfl_operator, "Checked exception `%s' can't be "
11277 "caught by any of the catch clause(s) "
11278 "of the surrounding `try' block",
11279 lang_printable_name (type, 0));
11280 /* If we have no surrounding try statement and the method doesn't have
11281 any throws, report it now. FIXME */
11282
11283 /* We report that the exception can't be throw from a try block
11284 in all circumstances but when the `throw' is inside a static
11285 block. */
11286 else if (!EXCEPTIONS_P (currently_caught_type_list)
11287 && !tryblock_throws_ok)
11288 {
11289 if (IS_CLINIT (current_function_decl))
11290 parse_error_context (wfl_operator, "Checked exception `%s' can't "
11291 "be thrown in initializer",
11292 lang_printable_name (type, 0));
11293 else
11294 parse_error_context (wfl_operator, "Checked exception `%s' isn't "
11295 "thrown from a `try' block",
11296 lang_printable_name (type, 0));
11297 }
11298 /* Otherwise, the current method doesn't have the appropriate
11299 throws declaration */
11300 else
11301 parse_error_context (wfl_operator, "Checked exception `%s' doesn't "
11302 "match any of current method's `throws' "
11303 "declaration(s)",
11304 lang_printable_name (type, 0));
11305 return error_mark_node;
11306 }
11307
11308 if (! flag_emit_class_files && ! flag_emit_xref)
11309 BUILD_THROW (node, expr);
11310
11311 /* If doing xrefs, keep the location where the `throw' was seen. */
11312 if (flag_emit_xref)
11313 EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
11314 return node;
11315 }
11316
11317 /* Check that exception said to be thrown by method DECL can be
11318 effectively caught from where DECL is invoked. */
11319
11320 static void
11321 check_thrown_exceptions (location, decl)
11322 int location;
11323 tree decl;
11324 {
11325 tree throws;
11326 /* For all the unchecked exceptions thrown by DECL */
11327 for (throws = DECL_FUNCTION_THROWS (decl); throws;
11328 throws = TREE_CHAIN (throws))
11329 if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
11330 {
11331 #if 1
11332 /* Temporary hack to suppresses errors about cloning arrays. FIXME */
11333 if (DECL_NAME (decl) == get_identifier ("clone"))
11334 continue;
11335 #endif
11336 EXPR_WFL_LINECOL (wfl_operator) = location;
11337 parse_error_context
11338 (wfl_operator, "Exception `%s' must be caught, or it must be "
11339 "declared in the `throws' clause of `%s'",
11340 lang_printable_name (TREE_VALUE (throws), 0),
11341 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
11342 }
11343 }
11344
11345 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
11346 try-catch blocks, OR is listed in the `throws' clause of the
11347 current method. */
11348
11349 static int
11350 check_thrown_exceptions_do (exception)
11351 tree exception;
11352 {
11353 tree list = currently_caught_type_list;
11354 resolve_and_layout (exception, NULL_TREE);
11355 /* First, all the nested try-catch-finally at that stage. The
11356 last element contains `throws' clause exceptions, if any. */
11357 if (IS_UNCHECKED_EXCEPTION_P (exception))
11358 return 1;
11359 while (list)
11360 {
11361 tree caught;
11362 for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
11363 if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
11364 return 1;
11365 list = TREE_CHAIN (list);
11366 }
11367 return 0;
11368 }
11369
11370 static void
11371 purge_unchecked_exceptions (mdecl)
11372 tree mdecl;
11373 {
11374 tree throws = DECL_FUNCTION_THROWS (mdecl);
11375 tree new = NULL_TREE;
11376
11377 while (throws)
11378 {
11379 tree next = TREE_CHAIN (throws);
11380 if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
11381 {
11382 TREE_CHAIN (throws) = new;
11383 new = throws;
11384 }
11385 throws = next;
11386 }
11387 /* List is inverted here, but it doesn't matter */
11388 DECL_FUNCTION_THROWS (mdecl) = new;
11389 }
11390
11391 /* 15.24 Conditional Operator ?: */
11392
11393 static tree
11394 patch_conditional_expr (node, wfl_cond, wfl_op1)
11395 tree node, wfl_cond, wfl_op1;
11396 {
11397 tree cond = TREE_OPERAND (node, 0);
11398 tree op1 = TREE_OPERAND (node, 1);
11399 tree op2 = TREE_OPERAND (node, 2);
11400 tree resulting_type = NULL_TREE;
11401 tree t1, t2, patched;
11402 int error_found = 0;
11403
11404 /* Operands of ?: might be StringBuffers crafted as a result of a
11405 string concatenation. Obtain a descent operand here. */
11406 if ((patched = patch_string (op1)))
11407 TREE_OPERAND (node, 1) = op1 = patched;
11408 if ((patched = patch_string (op2)))
11409 TREE_OPERAND (node, 2) = op2 = patched;
11410
11411 t1 = TREE_TYPE (op1);
11412 t2 = TREE_TYPE (op2);
11413
11414 /* The first expression must be a boolean */
11415 if (TREE_TYPE (cond) != boolean_type_node)
11416 {
11417 SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
11418 parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
11419 "convert `%s' to `boolean'",
11420 lang_printable_name (TREE_TYPE (cond), 0));
11421 error_found = 1;
11422 }
11423
11424 /* Second and third can be numeric, boolean (i.e. primitive),
11425 references or null. Anything else results in an error */
11426 if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
11427 || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node)
11428 && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
11429 || (t1 == boolean_type_node && t2 == boolean_type_node)))
11430 error_found = 1;
11431
11432 /* Determine the type of the conditional expression. Same types are
11433 easy to deal with */
11434 else if (t1 == t2)
11435 resulting_type = t1;
11436
11437 /* There are different rules for numeric types */
11438 else if (JNUMERIC_TYPE_P (t1))
11439 {
11440 /* if byte/short found, the resulting type is short */
11441 if ((t1 == byte_type_node && t2 == short_type_node)
11442 || (t1 == short_type_node && t2 == byte_type_node))
11443 resulting_type = short_type_node;
11444
11445 /* If t1 is a constant int and t2 is of type byte, short or char
11446 and t1's value fits in t2, then the resulting type is t2 */
11447 else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
11448 && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
11449 resulting_type = t2;
11450
11451 /* If t2 is a constant int and t1 is of type byte, short or char
11452 and t2's value fits in t1, then the resulting type is t1 */
11453 else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
11454 && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
11455 resulting_type = t1;
11456
11457 /* Otherwise, binary numeric promotion is applied and the
11458 resulting type is the promoted type of operand 1 and 2 */
11459 else
11460 resulting_type = binary_numeric_promotion (t2, t2,
11461 &TREE_OPERAND (node, 1),
11462 &TREE_OPERAND (node, 2));
11463 }
11464
11465 /* Cases of a reference and a null type */
11466 else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
11467 resulting_type = t1;
11468
11469 else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
11470 resulting_type = t2;
11471
11472 /* Last case: different reference types. If a type can be converted
11473 into the other one by assignment conversion, the latter
11474 determines the type of the expression */
11475 else if ((resulting_type = try_reference_assignconv (t1, op2)))
11476 resulting_type = promote_type (t1);
11477
11478 else if ((resulting_type = try_reference_assignconv (t2, op1)))
11479 resulting_type = promote_type (t2);
11480
11481 /* If we don't have any resulting type, we're in trouble */
11482 if (!resulting_type)
11483 {
11484 char *t = strdup (lang_printable_name (t1, 0));
11485 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11486 parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
11487 "convert `%s' to `%s'", t,
11488 lang_printable_name (t2, 0));
11489 free (t);
11490 error_found = 1;
11491 }
11492
11493 if (error_found)
11494 {
11495 TREE_TYPE (node) = error_mark_node;
11496 return error_mark_node;
11497 }
11498
11499 TREE_TYPE (node) = resulting_type;
11500 TREE_SET_CODE (node, COND_EXPR);
11501 CAN_COMPLETE_NORMALLY (node) = 1;
11502 return node;
11503 }
11504
11505 /* Try to constant fold NODE.
11506 If NODE is not a constant expression, return NULL_EXPR.
11507 CONTEXT is a static final VAR_DECL whose initializer we are folding. */
11508
11509 static tree
11510 fold_constant_for_init (node, context)
11511 tree node;
11512 tree context;
11513 {
11514 tree op0, op1, val;
11515 enum tree_code code = TREE_CODE (node);
11516
11517 if (code == INTEGER_CST || code == REAL_CST || code == STRING_CST)
11518 return node;
11519 if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL)
11520 return NULL_TREE;
11521
11522 switch (code)
11523 {
11524 case PLUS_EXPR:
11525 case MINUS_EXPR:
11526 case MULT_EXPR:
11527 case TRUNC_MOD_EXPR:
11528 case RDIV_EXPR:
11529 case LSHIFT_EXPR:
11530 case RSHIFT_EXPR:
11531 case URSHIFT_EXPR:
11532 case BIT_AND_EXPR:
11533 case BIT_XOR_EXPR:
11534 case BIT_IOR_EXPR:
11535 case TRUTH_ANDIF_EXPR:
11536 case TRUTH_ORIF_EXPR:
11537 case EQ_EXPR:
11538 case NE_EXPR:
11539 case GT_EXPR:
11540 case GE_EXPR:
11541 case LT_EXPR:
11542 case LE_EXPR:
11543 op0 = TREE_OPERAND (node, 0);
11544 op1 = TREE_OPERAND (node, 1);
11545 val = fold_constant_for_init (op0, context);
11546 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11547 return NULL_TREE;
11548 TREE_OPERAND (node, 0) = val;
11549 val = fold_constant_for_init (op1, context);
11550 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11551 return NULL_TREE;
11552 TREE_OPERAND (node, 1) = val;
11553 return patch_binop (node, op0, op1);
11554
11555 case UNARY_PLUS_EXPR:
11556 case NEGATE_EXPR:
11557 case TRUTH_NOT_EXPR:
11558 case BIT_NOT_EXPR:
11559 case CONVERT_EXPR:
11560 op0 = TREE_OPERAND (node, 0);
11561 val = fold_constant_for_init (op0, context);
11562 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11563 return NULL_TREE;
11564 TREE_OPERAND (node, 0) = val;
11565 return patch_unaryop (node, op0);
11566 break;
11567
11568 case COND_EXPR:
11569 val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
11570 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11571 return NULL_TREE;
11572 TREE_OPERAND (node, 0) = val;
11573 val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
11574 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11575 return NULL_TREE;
11576 TREE_OPERAND (node, 1) = val;
11577 val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
11578 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11579 return NULL_TREE;
11580 TREE_OPERAND (node, 2) = val;
11581 return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
11582 : TREE_OPERAND (node, 2);
11583
11584 case VAR_DECL:
11585 if (! FIELD_STATIC (node) || ! FIELD_FINAL (node)
11586 || DECL_INITIAL (node) == NULL_TREE)
11587 return NULL_TREE;
11588 val = DECL_INITIAL (node);
11589 /* Guard against infinite recursion. */
11590 DECL_INITIAL (node) = NULL_TREE;
11591 val = fold_constant_for_init (val, node);
11592 DECL_INITIAL (node) = val;
11593 return val;
11594
11595 case EXPR_WITH_FILE_LOCATION:
11596 /* Compare java_complete_tree and resolve_expression_name. */
11597 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11598 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11599 {
11600 tree name = EXPR_WFL_NODE (node);
11601 tree decl;
11602 if (PRIMARY_P (node))
11603 return NULL_TREE;
11604 else if (! QUALIFIED_P (name))
11605 {
11606 decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
11607 if (decl == NULL_TREE || ! FIELD_STATIC (decl))
11608 return NULL_TREE;
11609 return fold_constant_for_init (decl, decl);
11610 }
11611 else
11612 {
11613 #if 0
11614 /* Wait until the USE_COMPONENT_REF re-write. FIXME. */
11615 qualify_ambiguous_name (node);
11616 if (resolve_field_access (node, &decl, NULL)
11617 && decl != NULL_TREE)
11618 return fold_constant_for_init (decl, decl);
11619 #endif
11620 return NULL_TREE;
11621 }
11622 }
11623 else
11624 {
11625 op0 = TREE_OPERAND (node, 0);
11626 val = fold_constant_for_init (op0, context);
11627 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11628 return NULL_TREE;
11629 TREE_OPERAND (node, 0) = val;
11630 return val;
11631 }
11632
11633 #ifdef USE_COMPONENT_REF
11634 case IDENTIFIER:
11635 case COMPONENT_REF:
11636 ?;
11637 #endif
11638
11639 default:
11640 return NULL_TREE;
11641 }
11642 }
11643
11644 #ifdef USE_COMPONENT_REF
11645 /* Context is 'T' for TypeName, 'P' for PackageName,
11646 'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
11647
11648 tree
11649 resolve_simple_name (name, context)
11650 tree name;
11651 int context;
11652 {
11653 }
11654
11655 tree
11656 resolve_qualified_name (name, context)
11657 tree name;
11658 int context;
11659 {
11660 }
11661 #endif
This page took 0.529261 seconds and 5 git commands to generate.