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