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