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