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