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