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