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