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