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