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