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