]> gcc.gnu.org Git - gcc.git/blame - gcc/java/parse.y
cp-tree.h (push_nested_namespace): Declare.
[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;
e04a16fb
AG
3268
3269 if (!ctxp->static_initialized || java_error_count)
3270 return;
3271
22eed1e6
APB
3272 mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
3273 ACC_STATIC, void_type_node,
de4c7b02 3274 clinit_identifier_node, end_params_node);
22eed1e6 3275 start_artificial_method_body (mdecl);
e04a16fb
AG
3276
3277 /* Keep initialization in order to enforce 8.5 */
3278 ctxp->static_initialized = nreverse (ctxp->static_initialized);
3279
3280 /* We process the list of assignment we produced as the result of
3281 the declaration of initialized static field and add them as
3282 statement to the <clinit> method. */
3283 for (c = ctxp->static_initialized; c; c = TREE_CHAIN (c))
3284 {
3285 /* We build the assignment expression that will initialize the
3286 field to its value. There are strict rules on static
3287 initializers (8.5). FIXME */
22eed1e6
APB
3288 java_method_add_stmt (mdecl,
3289 build_debugable_stmt (EXPR_WFL_LINECOL (c), c));
e04a16fb
AG
3290 }
3291
22eed1e6 3292 end_artificial_method_body (mdecl);
e04a16fb
AG
3293 ctxp->static_initialized = NULL_TREE;
3294}
3295
3296/* Shared accros method_declarator and method_header to remember the
3297 patch stage that was reached during the declaration of the method.
3298 A method DECL is built differently is there is no patch
3299 (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
3300 pending on the currently defined method. */
3301
3302static int patch_stage;
3303
3304/* Check the method declaration and add the method to its current
3305 class. If the argument list is known to contain incomplete types,
3306 the method is partially added and the registration will be resume
22eed1e6
APB
3307 once the method arguments resolved. If TYPE is NULL, we're dealing
3308 with a constructor. */
e04a16fb
AG
3309
3310static tree
3311method_header (flags, type, mdecl, throws)
3312 int flags;
3313 tree type, mdecl, throws;
3314{
3315 tree meth = TREE_VALUE (mdecl);
3316 tree id = TREE_PURPOSE (mdecl);
3317 tree this_class = TREE_TYPE (ctxp->current_parsed_class);
1886c9d8 3318 tree type_wfl = NULL_TREE;
4a5f66c3 3319 tree meth_name = NULL_TREE, current, orig_arg;
e04a16fb 3320 int saved_lineno;
1886c9d8 3321 int constructor_ok = 0, must_chain;
e04a16fb
AG
3322
3323 check_modifiers_consistency (flags);
3324
3325 /* There are some forbidden modifiers for an abstract method and its
3326 class must be abstract as well. */
22eed1e6 3327 if (type && (flags & ACC_ABSTRACT))
e04a16fb
AG
3328 {
3329 ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
3330 ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
3331 ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
3332 ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
3333 ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
2aa11e97
APB
3334 if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
3335 && !CLASS_INTERFACE (TYPE_NAME (this_class)))
e04a16fb
AG
3336 parse_error_context
3337 (id, "Class `%s' must be declared abstract to define abstract "
3338 "method `%s'",
3339 IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
3340 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
3341 }
22eed1e6
APB
3342 /* Things to be checked when declaring a constructor */
3343 if (!type)
3344 {
3345 int ec = java_error_count;
3346 /* 8.6: Constructor declarations: we might be trying to define a
3347 method without specifying a return type. */
5e942c50 3348 if (EXPR_WFL_NODE (id) != ctxp->current_parsed_class_un)
22eed1e6
APB
3349 parse_error_context
3350 (id, "Invalid method declaration, return type required");
3351 /* 8.6.3: Constructor modifiers */
3352 else
3353 {
3354 JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
3355 JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
3356 JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
3357 JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
3358 JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
3359 }
3360 /* If we found error here, we don't consider it's OK to tread
3361 the method definition as a constructor, for the rest of this
3362 function */
3363 if (ec == java_error_count)
3364 constructor_ok = 1;
3365 }
e04a16fb
AG
3366
3367 /* Method declared within the scope of an interface are implicitly
3368 abstract and public. Conflicts with other erroneously provided
c0d87ff6 3369 modifiers are checked right after. */
e04a16fb
AG
3370
3371 if (CLASS_INTERFACE (TYPE_NAME (this_class)))
3372 {
3373 /* If FLAGS isn't set because of a modifier, turn the
3374 corresponding modifier WFL to NULL so we issue a warning on
3375 the obsolete use of the modifier */
3376 if (!(flags & ACC_PUBLIC))
3377 MODIFIER_WFL (PUBLIC_TK) = NULL;
3378 if (!(flags & ACC_ABSTRACT))
3379 MODIFIER_WFL (ABSTRACT_TK) = NULL;
3380 flags |= ACC_PUBLIC;
3381 flags |= ACC_ABSTRACT;
3382 }
3383
3384 /* Modifiers context reset moved up, so abstract method declaration
3385 modifiers can be later checked. */
3386
22eed1e6
APB
3387 /* Set constructor returned type to void and method name to <init>,
3388 unless we found an error identifier the constructor (in which
3389 case we retain the original name) */
3390 if (!type)
3391 {
3392 type = void_type_node;
3393 if (constructor_ok)
3394 meth_name = init_identifier_node;
3395 }
3396 else
3397 meth_name = EXPR_WFL_NODE (id);
e04a16fb 3398
1886c9d8
APB
3399 /* Do the returned type resolution and registration if necessary */
3400 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
3401
4a5f66c3
APB
3402 if (meth_name)
3403 type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
1886c9d8
APB
3404 EXPR_WFL_NODE (id) = meth_name;
3405 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
3406
3407 if (must_chain)
e04a16fb 3408 {
1886c9d8
APB
3409 patch_stage = JDEP_METHOD_RETURN;
3410 register_incomplete_type (patch_stage, type_wfl, id, type);
3411 TREE_TYPE (meth) = GET_REAL_TYPE (type);
e04a16fb
AG
3412 }
3413 else
1886c9d8 3414 TREE_TYPE (meth) = type;
e04a16fb
AG
3415
3416 saved_lineno = lineno;
3417 /* When defining an abstract or interface method, the curly
3418 bracket at level 1 doesn't exist because there is no function
3419 body */
3420 lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 :
3421 EXPR_WFL_LINENO (id));
3422
5e942c50
APB
3423 /* Remember the original argument list */
3424 orig_arg = TYPE_ARG_TYPES (meth);
3425
e04a16fb
AG
3426 if (patch_stage) /* includes ret type and/or all args */
3427 {
3428 jdep *jdep;
3429 meth = add_method_1 (this_class, flags, meth_name, meth);
3430 /* Patch for the return type */
3431 if (patch_stage == JDEP_METHOD_RETURN)
3432 {
3433 jdep = CLASSD_LAST (ctxp->classd_list);
3434 JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
3435 }
3436 /* This is the stop JDEP. METH allows the function's signature
3437 to be computed. */
3438 register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
3439 }
3440 else
5e942c50
APB
3441 meth = add_method (this_class, flags, meth_name,
3442 build_java_signature (meth));
3443
3444 /* Fix the method argument list so we have the argument name
3445 information */
3446 fix_method_argument_names (orig_arg, meth);
3447
3448 /* Register the parameter number and re-install the current line
3449 number */
e04a16fb
AG
3450 DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
3451 lineno = saved_lineno;
b9f7e36c
APB
3452
3453 /* Register exception specified by the `throws' keyword for
3454 resolution and set the method decl appropriate field to the list.
3455 Note: the grammar ensures that what we get here are class
3456 types. */
3457 if (throws)
3458 {
3459 throws = nreverse (throws);
3460 for (current = throws; current; current = TREE_CHAIN (current))
3461 {
3462 register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
3463 NULL_TREE, NULL_TREE);
3464 JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) =
3465 &TREE_VALUE (current);
3466 }
3467 DECL_FUNCTION_THROWS (meth) = throws;
3468 }
3469
e04a16fb
AG
3470 /* We set the DECL_NAME to ID so we can track the location where
3471 the function was declared. This allow us to report
3472 redefinition error accurately. When method are verified,
3473 DECL_NAME is reinstalled properly (using the content of the
3474 WFL node ID) (see check_method_redefinition). We don't do that
22eed1e6
APB
3475 when Object is being defined. Constructor <init> names will be
3476 reinstalled the same way. */
e04a16fb
AG
3477 if (TREE_TYPE (ctxp->current_parsed_class) != object_type_node)
3478 DECL_NAME (meth) = id;
22eed1e6
APB
3479
3480 /* Set the flag if we correctly processed a constructor */
3481 if (constructor_ok)
3482 DECL_CONSTRUCTOR_P (meth) = 1;
3483
5e942c50
APB
3484 /* Eventually set the @deprecated tag flag */
3485 CHECK_DEPRECATED (meth);
3486
7f10c2e2
APB
3487 /* If doing xref, store column and line number information instead
3488 of the line number only. */
3489 if (flag_emit_xref)
3490 DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
3491
e04a16fb
AG
3492 return meth;
3493}
3494
5e942c50
APB
3495static void
3496fix_method_argument_names (orig_arg, meth)
3497 tree orig_arg, meth;
3498{
3499 tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
3500 if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
3501 {
3502 TREE_PURPOSE (arg) = this_identifier_node;
3503 arg = TREE_CHAIN (arg);
3504 }
de4c7b02 3505 while (orig_arg != end_params_node)
5e942c50
APB
3506 {
3507 TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
3508 orig_arg = TREE_CHAIN (orig_arg);
3509 arg = TREE_CHAIN (arg);
3510 }
3511}
3512
22eed1e6
APB
3513/* Complete the method declaration with METHOD_BODY. */
3514
3515static void
b635eb2f 3516finish_method_declaration (method_body)
22eed1e6
APB
3517 tree method_body;
3518{
3519 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
3520 maybe_absorb_scoping_blocks ();
3521 /* Exit function's body */
3522 exit_block ();
3523 /* Merge last line of the function with first line, directly in the
3524 function decl. It will be used to emit correct debug info. */
7f10c2e2
APB
3525 if (!flag_emit_xref)
3526 DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
f099f336
APB
3527 /* So we don't have an irrelevant function declaration context for
3528 the next static block we'll see. */
3529 current_function_decl = NULL_TREE;
22eed1e6
APB
3530}
3531
3532/* Build a an error message for constructor circularity errors. */
3533
3534static char *
3535constructor_circularity_msg (from, to)
3536 tree from, to;
3537{
3538 static char string [4096];
3539 char *t = strdup (lang_printable_name (from, 0));
3540 sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
3541 free (t);
3542 return string;
3543}
3544
3545/* Verify a circular call to METH. Return 1 if an error is found, 0
3546 otherwise. */
3547
3548static int
3549verify_constructor_circularity (meth, current)
3550 tree meth, current;
3551{
3552 static tree list = NULL_TREE;
3553 tree c;
3554 for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
3555 {
3556 if (TREE_VALUE (c) == meth)
3557 {
3558 char *t;
3559 if (list)
3560 {
3561 tree liste;
3562 list = nreverse (list);
3563 for (liste = list; liste; liste = TREE_CHAIN (liste))
3564 {
3565 parse_error_context
3566 (TREE_PURPOSE (TREE_PURPOSE (liste)),
3567 constructor_circularity_msg
3568 (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste))));
3569 java_error_count--;
3570 }
3571 }
3572 t = strdup (lang_printable_name (meth, 0));
3573 parse_error_context (TREE_PURPOSE (c),
3574 "%s: recursive invocation of constructor `%s'",
3575 constructor_circularity_msg (current, meth), t);
3576 free (t);
3577 list = NULL_TREE;
3578 return 1;
3579 }
3580 }
3581 for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
3582 {
3583 list = tree_cons (c, current, list);
3584 if (verify_constructor_circularity (meth, TREE_VALUE (c)))
3585 return 1;
3586 list = TREE_CHAIN (list);
3587 }
3588 return 0;
3589}
3590
e04a16fb
AG
3591/* Check modifiers that can be declared but exclusively */
3592
3593static void
3594check_modifiers_consistency (flags)
3595 int flags;
3596{
3597 int acc_count = 0;
3598 tree cl = NULL_TREE;
3599
3600 THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, 0, acc_count, cl);
3601 THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, 1, acc_count, cl);
3602 THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, 2, acc_count, cl);
3603 if (acc_count > 1)
3604 parse_error_context
3605 (cl, "Inconsistent member declaration. At most one of `public', "
3606 "`private', or `protected' may be specified");
3607}
3608
3609/* Check the methode header METH for abstract specifics features */
3610
3611static void
3612check_abstract_method_header (meth)
3613 tree meth;
3614{
3615 int flags = get_access_flags_from_decl (meth);
3616 /* DECL_NAME might still be a WFL node */
c877974e 3617 tree name = GET_METHOD_NAME (meth);
e04a16fb
AG
3618
3619 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags,
3620 ACC_ABSTRACT, "abstract method `%s'",
3621 IDENTIFIER_POINTER (name));
3622 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK), flags,
3623 ACC_PUBLIC, "abstract method `%s'",
3624 IDENTIFIER_POINTER (name));
3625
3626 check_modifiers ("Illegal modifier `%s' for interface method",
3627 flags, INTERFACE_METHOD_MODIFIERS);
3628}
3629
3630/* Create a FUNCTION_TYPE node and start augmenting it with the
3631 declared function arguments. Arguments type that can't be resolved
3632 are left as they are, but the returned node is marked as containing
3633 incomplete types. */
3634
3635static tree
3636method_declarator (id, list)
3637 tree id, list;
3638{
3639 tree arg_types = NULL_TREE, current, node;
3640 tree meth = make_node (FUNCTION_TYPE);
3641 jdep *jdep;
e04a16fb
AG
3642
3643 patch_stage = JDEP_NO_PATCH;
3644
3645 for (current = list; current; current = TREE_CHAIN (current))
3646 {
c583dd46 3647 int must_chain = 0;
e04a16fb
AG
3648 tree wfl_name = TREE_PURPOSE (current);
3649 tree type = TREE_VALUE (current);
3650 tree name = EXPR_WFL_NODE (wfl_name);
c583dd46
APB
3651 tree already, arg_node;
3652 tree type_wfl = NULL_TREE;
23a79c61 3653 tree real_type;
c583dd46
APB
3654
3655 /* Obtain a suitable type for resolution, if necessary */
3656 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
3657
3658 /* Process NAME, as it may specify extra dimension(s) for it */
3659 type = build_array_from_name (type, type_wfl, name, &name);
3660 EXPR_WFL_NODE (wfl_name) = name;
e04a16fb 3661
23a79c61
APB
3662 real_type = GET_REAL_TYPE (type);
3663 if (TREE_CODE (real_type) == RECORD_TYPE)
3664 {
3665 real_type = promote_type (real_type);
3666 if (TREE_CODE (type) == TREE_LIST)
3667 TREE_PURPOSE (type) = real_type;
3668 }
5e942c50 3669
e04a16fb
AG
3670 /* Check redefinition */
3671 for (already = arg_types; already; already = TREE_CHAIN (already))
3672 if (TREE_PURPOSE (already) == name)
3673 {
3674 parse_error_context
3675 (wfl_name, "Variable `%s' is used more than once in the "
3676 "argument list of method `%s'", IDENTIFIER_POINTER (name),
3677 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
3678 break;
3679 }
3680
3681 /* If we've an incomplete argument type, we know there is a location
3682 to patch when the type get resolved, later. */
3683 jdep = NULL;
c583dd46 3684 if (must_chain)
e04a16fb 3685 {
c583dd46
APB
3686 patch_stage = JDEP_METHOD;
3687 type = register_incomplete_type (patch_stage,
3688 type_wfl, wfl_name, type);
3689 jdep = CLASSD_LAST (ctxp->classd_list);
3690 JDEP_MISC (jdep) = id;
e04a16fb 3691 }
c583dd46 3692
e04a16fb 3693 /* The argument node: a name and a (possibly) incomplete type */
23a79c61 3694 arg_node = build_tree_list (name, real_type);
e04a16fb
AG
3695 if (jdep)
3696 JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
3697 TREE_CHAIN (arg_node) = arg_types;
3698 arg_types = arg_node;
3699 }
de4c7b02 3700 TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
e04a16fb
AG
3701 node = build_tree_list (id, meth);
3702 return node;
3703}
3704
3705static int
3706unresolved_type_p (wfl, returned)
3707 tree wfl;
3708 tree *returned;
3709
3710{
3711 if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
3712 {
3713 tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
3714 if (returned)
3715 *returned = (decl ? TREE_TYPE (decl) : NULL_TREE);
3716 return 1;
3717 }
3718 if (returned)
3719 *returned = wfl;
3720 return 0;
3721}
3722
3723/* From NAME, build a qualified identifier node using the
3724 qualification from the current package definition. */
3725
3726static tree
3727parser_qualified_classname (name)
3728 tree name;
3729{
3730 if (ctxp->package)
3731 return merge_qualified_name (ctxp->package, EXPR_WFL_NODE (name));
3732 else
3733 return EXPR_WFL_NODE (name);
3734}
3735
3736/* Called once the type a interface extends is resolved. Returns 0 if
3737 everything is OK. */
3738
3739static int
3740parser_check_super_interface (super_decl, this_decl, this_wfl)
3741 tree super_decl, this_decl, this_wfl;
3742{
3743 tree super_type = TREE_TYPE (super_decl);
3744
3745 /* Has to be an interface */
3746 if (!CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (super_decl))))
3747 {
3748 parse_error_context
3749 (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
3750 (TYPE_ARRAY_P (super_type) ? "array" : "class"),
3751 IDENTIFIER_POINTER (DECL_NAME (super_decl)),
3752 (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ?
3753 "interface" : "class"),
3754 IDENTIFIER_POINTER (DECL_NAME (this_decl)));
3755 return 1;
3756 }
3757
3758 /* Check scope: same package OK, other package: OK if public */
3759 if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
3760 return 1;
3761
3762 SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
3763 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3764 IDENTIFIER_POINTER (DECL_NAME (super_decl))));
3765 return 0;
3766}
3767
3768/* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
3769 0 if everthing is OK. */
3770
3771static int
3772parser_check_super (super_decl, this_decl, wfl)
3773 tree super_decl, this_decl, wfl;
3774{
e04a16fb
AG
3775 tree super_type = TREE_TYPE (super_decl);
3776
3777 /* SUPER should be a CLASS (neither an array nor an interface) */
3778 if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
3779 {
3780 parse_error_context
3781 (wfl, "Class `%s' can't subclass %s `%s'",
3782 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3783 (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
3784 IDENTIFIER_POINTER (DECL_NAME (super_decl)));
3785 return 1;
3786 }
3787
3788 if (CLASS_FINAL (TYPE_NAME (super_type)))
3789 {
3790 parse_error_context (wfl, "Can't subclass final classes: %s",
3791 IDENTIFIER_POINTER (DECL_NAME (super_decl)));
3792 return 1;
3793 }
3794
3795 /* Check scope: same package OK, other package: OK if public */
3796 if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
3797 return 1;
3798
3799 SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
3800 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3801 IDENTIFIER_POINTER (DECL_NAME (super_decl))));
3802 return 0;
3803}
3804
3805/* Create a new dependency list and link it (in a LIFO manner) to the
3806 CTXP list of type dependency list. */
3807
3808static void
3809create_jdep_list (ctxp)
3810 struct parser_ctxt *ctxp;
3811{
23a79c61 3812 jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));
e04a16fb
AG
3813 new->first = new->last = NULL;
3814 new->next = ctxp->classd_list;
3815 ctxp->classd_list = new;
3816}
3817
3818static jdeplist *
3819reverse_jdep_list (ctxp)
3820 struct parser_ctxt *ctxp;
3821{
3822 register jdeplist *prev = NULL, *current, *next;
3823 for (current = ctxp->classd_list; current; current = next)
3824 {
3825 next = current->next;
3826 current->next = prev;
3827 prev = current;
3828 }
3829 return prev;
3830}
3831
23a79c61
APB
3832/* Create a fake pointer based on the ID stored in
3833 TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
3834 registered again. */
e04a16fb
AG
3835
3836static tree
23a79c61
APB
3837obtain_incomplete_type (type_name)
3838 tree type_name;
e04a16fb 3839{
23a79c61
APB
3840 tree ptr, name;
3841
3842 if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
3843 name = EXPR_WFL_NODE (type_name);
3844 else if (INCOMPLETE_TYPE_P (type_name))
3845 name = TYPE_NAME (type_name);
3846 else
3847 fatal ("invalid type name - obtain_incomplete_type");
e04a16fb
AG
3848
3849 for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
78d21f92 3850 if (TYPE_NAME (ptr) == name)
e04a16fb
AG
3851 break;
3852
3853 if (!ptr)
3854 {
e04a16fb 3855 push_obstacks (&permanent_obstack, &permanent_obstack);
78d21f92
PB
3856 BUILD_PTR_FROM_NAME (ptr, name);
3857 layout_type (ptr);
e04a16fb
AG
3858 pop_obstacks ();
3859 TREE_CHAIN (ptr) = ctxp->incomplete_class;
3860 ctxp->incomplete_class = ptr;
3861 }
3862
3863 return ptr;
3864}
3865
3866/* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
3867 non NULL instead of computing a new fake type based on WFL. The new
3868 dependency is inserted in the current type dependency list, in FIFO
3869 manner. */
3870
3871static tree
3872register_incomplete_type (kind, wfl, decl, ptr)
3873 int kind;
3874 tree wfl, decl, ptr;
3875{
23a79c61 3876 jdep *new = (jdep *)xmalloc (sizeof (jdep));
e04a16fb 3877
e04a16fb
AG
3878 if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
3879 ptr = obtain_incomplete_type (wfl);
3880
3881 JDEP_KIND (new) = kind;
3882 JDEP_DECL (new) = decl;
3883 JDEP_SOLV (new) = ptr;
3884 JDEP_WFL (new) = wfl;
3885 JDEP_CHAIN (new) = NULL;
3886 JDEP_MISC (new) = NULL_TREE;
3887 JDEP_GET_PATCH (new) = (tree *)NULL;
3888
3889 JDEP_INSERT (ctxp->classd_list, new);
3890
3891 return ptr;
3892}
3893
3894void
3895java_check_circular_reference ()
3896{
3897 tree current;
3898 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
3899 {
3900 tree type = TREE_TYPE (current);
3901 if (CLASS_INTERFACE (TYPE_NAME (type)))
3902 {
3903 /* Check all interfaces this class extends */
3904 tree basetype_vec = TYPE_BINFO_BASETYPES (type);
3905 int n, i;
3906
3907 if (!basetype_vec)
3908 return;
3909 n = TREE_VEC_LENGTH (basetype_vec);
3910 for (i = 0; i < n; i++)
3911 {
3912 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
3913 if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node
3914 && interface_of_p (type, BINFO_TYPE (vec_elt)))
3915 parse_error_context (lookup_cl (current),
3916 "Cyclic interface inheritance");
3917 }
3918 }
3919 else
3920 if (inherits_from_p (CLASSTYPE_SUPER (type), type))
3921 parse_error_context (lookup_cl (current),
3922 "Cyclic class inheritance");
3923 }
3924}
3925
23a79c61
APB
3926/* safe_layout_class just makes sure that we can load a class without
3927 disrupting the current_class, input_file, lineno, etc, information
3928 about the class processed currently. */
3929
e04a16fb
AG
3930void
3931safe_layout_class (class)
3932 tree class;
3933{
3934 tree save_current_class = current_class;
3935 char *save_input_filename = input_filename;
3936 int save_lineno = lineno;
5e942c50 3937
e04a16fb 3938 push_obstacks (&permanent_obstack, &permanent_obstack);
5e942c50 3939
e04a16fb
AG
3940 layout_class (class);
3941 pop_obstacks ();
5e942c50 3942
e04a16fb
AG
3943 current_class = save_current_class;
3944 input_filename = save_input_filename;
3945 lineno = save_lineno;
3946 CLASS_LOADED_P (class) = 1;
3947}
3948
3949static tree
3950jdep_resolve_class (dep)
3951 jdep *dep;
3952{
3953 tree decl;
3954
23a79c61
APB
3955 if (JDEP_RESOLVED_P (dep))
3956 decl = JDEP_RESOLVED_DECL (dep);
3957 else
e04a16fb 3958 {
23a79c61
APB
3959 decl = resolve_class (JDEP_TO_RESOLVE (dep),
3960 JDEP_DECL (dep), JDEP_WFL (dep));
e04a16fb
AG
3961 JDEP_RESOLVED (dep, decl);
3962 }
23a79c61 3963
e04a16fb 3964 if (!decl)
23a79c61
APB
3965 complete_class_report_errors (dep);
3966
e04a16fb
AG
3967 return decl;
3968}
3969
3970/* Complete unsatisfied class declaration and their dependencies */
3971
3972void
3973java_complete_class ()
3974{
e04a16fb
AG
3975 tree cclass;
3976 jdeplist *cclassd;
3977 int error_found;
b67d701b 3978 tree type;
e04a16fb
AG
3979
3980 push_obstacks (&permanent_obstack, &permanent_obstack);
3981
3982 /* Process imports and reverse the import on demand list */
3983 process_imports ();
3984 if (ctxp->import_demand_list)
3985 ctxp->import_demand_list = nreverse (ctxp->import_demand_list);
3986
3987 /* Rever things so we have the right order */
3988 ctxp->class_list = nreverse (ctxp->class_list);
3989 ctxp->classd_list = reverse_jdep_list (ctxp);
c877974e 3990
e04a16fb
AG
3991 for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
3992 cclass && cclassd;
3993 cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
3994 {
3995 jdep *dep;
3996 for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
3997 {
3998 tree decl;
e04a16fb
AG
3999 if (!(decl = jdep_resolve_class (dep)))
4000 continue;
4001
4002 /* Now it's time to patch */
4003 switch (JDEP_KIND (dep))
4004 {
4005 case JDEP_SUPER:
4006 /* Simply patch super */
4007 if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
4008 continue;
4009 BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO
4010 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
4011 break;
4012
4013 case JDEP_FIELD:
4014 {
4015 /* We do part of the job done in add_field */
4016 tree field_decl = JDEP_DECL (dep);
4017 tree field_type = TREE_TYPE (decl);
4018 push_obstacks (&permanent_obstack, &permanent_obstack);
e04a16fb 4019 if (TREE_CODE (field_type) == RECORD_TYPE)
e04a16fb
AG
4020 field_type = promote_type (field_type);
4021 pop_obstacks ();
4022 TREE_TYPE (field_decl) = field_type;
5e942c50
APB
4023 DECL_ALIGN (field_decl) = 0;
4024 layout_decl (field_decl, 0);
e04a16fb
AG
4025 SOURCE_FRONTEND_DEBUG
4026 (("Completed field/var decl `%s' with `%s'",
4027 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
4028 IDENTIFIER_POINTER (DECL_NAME (decl))));
4029 break;
4030 }
4031 case JDEP_METHOD: /* We start patching a method */
4032 case JDEP_METHOD_RETURN:
4033 error_found = 0;
4034 while (1)
4035 {
4036 if (decl)
4037 {
b67d701b
PB
4038 type = TREE_TYPE(decl);
4039 if (TREE_CODE (type) == RECORD_TYPE)
4040 type = promote_type (type);
e04a16fb
AG
4041 JDEP_APPLY_PATCH (dep, type);
4042 SOURCE_FRONTEND_DEBUG
4043 (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
4044 "Completing fct `%s' with ret type `%s'":
4045 "Completing arg `%s' with type `%s'"),
4046 IDENTIFIER_POINTER (EXPR_WFL_NODE
4047 (JDEP_DECL_WFL (dep))),
4048 IDENTIFIER_POINTER (DECL_NAME (decl))));
4049 }
4050 else
4051 error_found = 1;
4052 dep = JDEP_CHAIN (dep);
4053 if (JDEP_KIND (dep) == JDEP_METHOD_END)
4054 break;
4055 else
4056 decl = jdep_resolve_class (dep);
4057 }
4058 if (!error_found)
4059 {
4060 tree mdecl = JDEP_DECL (dep), signature;
4061 push_obstacks (&permanent_obstack, &permanent_obstack);
4062 /* Recompute and reset the signature */
4063 signature = build_java_signature (TREE_TYPE (mdecl));
4064 set_java_signature (TREE_TYPE (mdecl), signature);
4065 pop_obstacks ();
4066 }
4067 else
4068 continue;
4069 break;
4070
4071 case JDEP_INTERFACE:
4072 if (parser_check_super_interface (decl, JDEP_DECL (dep),
4073 JDEP_WFL (dep)))
4074 continue;
4075 parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
4076 break;
4077
b67d701b 4078 case JDEP_PARM:
e04a16fb 4079 case JDEP_VARIABLE:
b67d701b
PB
4080 type = TREE_TYPE(decl);
4081 if (TREE_CODE (type) == RECORD_TYPE)
4082 type = promote_type (type);
4083 JDEP_APPLY_PATCH (dep, type);
e04a16fb
AG
4084 break;
4085
4086 case JDEP_TYPE:
4087 JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
4088 SOURCE_FRONTEND_DEBUG
4089 (("Completing a random type dependency on a '%s' node",
4090 tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
4091 break;
4092
b9f7e36c 4093 case JDEP_EXCEPTION:
c877974e
APB
4094 JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
4095 SOURCE_FRONTEND_DEBUG
4096 (("Completing `%s' `throws' argument node",
4097 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
b9f7e36c
APB
4098 break;
4099
e04a16fb 4100 default:
0a2138e2
APB
4101 fatal ("Can't handle patch code %d - java_complete_class",
4102 JDEP_KIND (dep));
e04a16fb
AG
4103 }
4104 }
4105 }
4106 pop_obstacks ();
4107 return;
4108}
4109
4110/* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
4111 array. */
4112
4113static tree
4114resolve_class (class_type, decl, cl)
4115 tree class_type, decl, cl;
4116{
4117 char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
4118 char *base = name;
78d21f92
PB
4119 tree resolved_type = TREE_TYPE (class_type);
4120 tree resolved_type_decl;
e04a16fb 4121
78d21f92
PB
4122 if (resolved_type != NULL_TREE)
4123 {
4124 tree resolved_type_decl = TYPE_NAME (resolved_type);
4125 if (resolved_type_decl == NULL_TREE
4126 || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
4127 {
4128 resolved_type_decl = build_decl (TYPE_DECL,
4129 TYPE_NAME (class_type),
4130 resolved_type);
4131 }
4132 return resolved_type_decl;
4133 }
4134
e04a16fb
AG
4135 /* 1- Check to see if we have an array. If true, find what we really
4136 want to resolve */
4137 while (name[0] == '[')
4138 name++;
4139 if (base != name)
4140 TYPE_NAME (class_type) = get_identifier (name);
4141
4142 /* 2- Resolve the bare type */
4143 if (!(resolved_type_decl = do_resolve_class (class_type, decl, cl)))
4144 return NULL_TREE;
4145 resolved_type = TREE_TYPE (resolved_type_decl);
4146
4147 /* 3- If we have and array, reconstruct the array down to its nesting */
4148 if (base != name)
4149 {
4150 while (base != name)
4151 {
4152 if (TREE_CODE (resolved_type) == RECORD_TYPE)
4153 resolved_type = promote_type (resolved_type);
4154 resolved_type = build_java_array_type (resolved_type, -1);
c583dd46 4155 CLASS_LOADED_P (resolved_type) = 1;
e04a16fb
AG
4156 name--;
4157 }
4158 /* Build a fake decl for this, since this is what is expected to
4159 be returned. */
4160 resolved_type_decl =
4161 build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
4162 /* Figure how those two things are important for error report. FIXME */
4163 DECL_SOURCE_LINE (resolved_type_decl) = 0;
4164 DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
78d21f92 4165 TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
e04a16fb 4166 }
78d21f92 4167 TREE_TYPE (class_type) = resolved_type;
e04a16fb
AG
4168 return resolved_type_decl;
4169}
4170
4171/* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
4172 are used to report error messages. */
4173
78d21f92 4174tree
e04a16fb
AG
4175do_resolve_class (class_type, decl, cl)
4176 tree class_type;
4177 tree decl;
4178 tree cl;
4179{
4180 tree new_class_decl;
4181 tree original_name = NULL_TREE;
4182
4183 /* Do not try to replace TYPE_NAME (class_type) by a variable, since
4184 its is changed by find_in_imports{_on_demand} */
4185
4186 /* 1- Check for the type in single imports */
4187 if (find_in_imports (class_type))
4188 return NULL_TREE;
4189
4190 /* 2- And check for the type in the current compilation unit. If it fails,
4191 try with a name qualified with the package name if appropriate. */
e04a16fb
AG
4192 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4193 {
4194 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4195 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4196 load_class (TYPE_NAME (class_type), 0);
4197 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4198 }
4199
4200 original_name = TYPE_NAME (class_type);
4201 if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
4202 TYPE_NAME (class_type) = merge_qualified_name (ctxp->package,
4203 TYPE_NAME (class_type));
bc3ca41b 4204#if 1
5e942c50
APB
4205 if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4206 load_class (TYPE_NAME (class_type), 0);
e04a16fb
AG
4207 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4208 {
4209 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4210 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4211 load_class (TYPE_NAME (class_type), 0);
4212 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4213 }
bc3ca41b
PB
4214#else
4215 new_name = TYPE_NAME (class_type);
4216 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_name)) != NULL_TREE)
4217 {
4218 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4219 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4220 load_class (new_name, 0);
4221 return IDENTIFIER_CLASS_VALUE (new_name);
4222 }
4223 else
4224 {
4225 tree class = read_class (new_name);
4226 if (class != NULL_TREE)
4227 {
4228 tree decl = IDENTIFIER_CLASS_VALUE (new_name);
4229 if (decl == NULL_TREE)
4230 decl = push_class (class, new_name);
4231 return decl;
4232 }
4233 }
4234#endif
e04a16fb
AG
4235 TYPE_NAME (class_type) = original_name;
4236
4237 /* 3- Check an other compilation unit that bears the name of type */
4238 load_class (TYPE_NAME (class_type), 0);
4239 if (check_pkg_class_access (TYPE_NAME (class_type),
4240 (cl ? cl : lookup_cl (decl))))
4241 return NULL_TREE;
4242
4243 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4244 return new_class_decl;
4245
4246 /* 4- Check the import on demands. Don't allow bar.baz to be
4247 imported from foo.* */
4248 if (!QUALIFIED_P (TYPE_NAME (class_type)))
4249 if (find_in_imports_on_demand (class_type))
4250 return NULL_TREE;
4251
4252 /* 5- Last call for a resolution */
4253 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4254}
4255
4256/* Resolve NAME and lay it out (if not done and if not the current
23a79c61
APB
4257 parsed class). Return a decl node. This function is meant to be
4258 called when type resolution is necessary during the walk pass. */
e04a16fb
AG
4259
4260static tree
c877974e
APB
4261resolve_and_layout (something, cl)
4262 tree something;
e04a16fb
AG
4263 tree cl;
4264{
c877974e
APB
4265 tree decl;
4266
23a79c61
APB
4267 /* Don't do that on the current class */
4268 if (something == current_class)
4269 return TYPE_NAME (current_class);
c877974e 4270
23a79c61 4271 /* Don't do anything for void and other primitive types */
c877974e
APB
4272 if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
4273 return NULL_TREE;
4274
23a79c61
APB
4275 /* Pointer types can be reall pointer types or fake pointers. When
4276 finding a real pointer, recheck for primitive types */
4277 if (TREE_CODE (something) == POINTER_TYPE)
4278 {
4279 if (TREE_TYPE (something))
4280 {
4281 something = TREE_TYPE (something);
4282 if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
4283 return NULL_TREE;
4284 }
4285 else
4286 something = TYPE_NAME (something);
4287 }
4288
4289 /* Don't do anything for arrays of primitive types */
4290 if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
4291 && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
4292 return NULL_TREE;
4293
4294 /* If something is not and IDENTIFIER_NODE, it can be a a TYPE_DECL
4295 or a real TYPE */
c877974e
APB
4296 if (TREE_CODE (something) != IDENTIFIER_NODE)
4297 something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
4298 DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
4299
23a79c61
APB
4300 if (!(decl = resolve_no_layout (something, cl)))
4301 return NULL_TREE;
4302
4303 /* Resolve and layout if necessary */
4304 layout_class_methods (TREE_TYPE (decl));
4305 if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)))
4306 CHECK_METHODS (decl);
4307 if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
e04a16fb 4308 safe_layout_class (TREE_TYPE (decl));
23a79c61 4309
e04a16fb
AG
4310 return decl;
4311}
4312
4313/* Resolve a class, returns its decl but doesn't perform any
4314 layout. The current parsing context is saved and restored */
4315
4316static tree
4317resolve_no_layout (name, cl)
4318 tree name, cl;
4319{
4320 tree ptr, decl;
4321 BUILD_PTR_FROM_NAME (ptr, name);
4322 java_parser_context_save_global ();
4323 decl = resolve_class (ptr, NULL_TREE, cl);
4324 java_parser_context_restore_global ();
4325
4326 return decl;
4327}
4328
23a79c61
APB
4329/* Called when reporting errors. Skip leader '[' in a complex array
4330 type description that failed to be resolved. */
e04a16fb
AG
4331
4332static char *
4333purify_type_name (name)
4334 char *name;
4335{
4336 while (*name && *name == '[')
4337 name++;
4338 return name;
4339}
4340
4341/* The type CURRENT refers to can't be found. We print error messages. */
4342
4343static void
4344complete_class_report_errors (dep)
4345 jdep *dep;
4346{
23a79c61
APB
4347 char *name;
4348
4349 if (!JDEP_WFL (dep))
4350 return;
4351
4352 name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
e04a16fb
AG
4353 switch (JDEP_KIND (dep))
4354 {
4355 case JDEP_SUPER:
4356 parse_error_context
4357 (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
23a79c61 4358 purify_type_name (name),
e04a16fb
AG
4359 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4360 break;
4361 case JDEP_FIELD:
4362 parse_error_context
4363 (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
23a79c61 4364 purify_type_name (name),
e04a16fb
AG
4365 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4366 break;
4367 case JDEP_METHOD: /* Covers arguments */
4368 parse_error_context
4369 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4370 "argument `%s' of method `%s'",
23a79c61 4371 purify_type_name (name),
e04a16fb
AG
4372 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
4373 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
4374 break;
4375 case JDEP_METHOD_RETURN: /* Covers return type */
4376 parse_error_context
4377 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4378 "return type of method `%s'",
23a79c61 4379 purify_type_name (name),
e04a16fb
AG
4380 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
4381 break;
4382 case JDEP_INTERFACE:
4383 parse_error_context
4384 (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
4385 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
4386 (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
4387 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4388 break;
4389 case JDEP_VARIABLE:
4390 parse_error_context
4391 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4392 "local variable `%s'",
b67d701b
PB
4393 purify_type_name (IDENTIFIER_POINTER
4394 (EXPR_WFL_NODE (JDEP_WFL (dep)))),
e04a16fb
AG
4395 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4396 break;
b9f7e36c
APB
4397 case JDEP_EXCEPTION: /* As specified by `throws' */
4398 parse_error_context
4399 (JDEP_WFL (dep), "Class `%s' not found in `throws'",
4400 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
4401 break;
0a2138e2
APB
4402 default:
4403 /* Fix for -Wall. Just break doing nothing. The error will be
4404 caught later */
4405 break;
e04a16fb
AG
4406 }
4407}
4408
4409/* Check uninitialized final. */
4410
4411void
4412java_check_final ()
4413{
4414}
4415
22eed1e6
APB
4416/* Return a static string containing the DECL prototype string. If
4417 DECL is a constructor, use the class name instead of the form
4418 <init> */
4419
4420static char *
4421get_printable_method_name (decl)
4422 tree decl;
4423{
4424 char *to_return;
9ee9b555 4425 tree name = NULL_TREE;
22eed1e6
APB
4426
4427 if (DECL_CONSTRUCTOR_P (decl))
4428 {
4429 name = DECL_NAME (decl);
5e942c50 4430 DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
22eed1e6
APB
4431 }
4432
4433 to_return = lang_printable_name (decl, 0);
4434 if (DECL_CONSTRUCTOR_P (decl))
4435 DECL_NAME (decl) = name;
4436
4437 return to_return;
4438}
4439
5e942c50
APB
4440/* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
4441 nevertheless needs to be verfied, 1 otherwise. */
4442
4443static int
4444reset_method_name (method)
4445 tree method;
4446{
7f1d4866 4447 if (!IS_CLINIT (method) && DECL_NAME (method) != finit_identifier_node)
5e942c50
APB
4448 {
4449 /* NAME is just the plain name when Object is being defined */
4450 if (DECL_CONTEXT (method) != object_type_node)
c877974e
APB
4451 DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ?
4452 init_identifier_node : GET_METHOD_NAME (method));
5e942c50
APB
4453 return 0;
4454 }
4455 else
4456 return 1;
4457}
4458
c877974e
APB
4459/* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
4460
4461tree
4462java_get_real_method_name (method_decl)
4463 tree method_decl;
4464{
4465 tree method_name = DECL_NAME (method_decl);
4466 if (DECL_CONSTRUCTOR_P (method_decl))
4467 return init_identifier_node;
82371d41
APB
4468
4469 /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
4470 and still can be a constructor. FIXME */
4471
23a79c61
APB
4472 /* Don't confuse method only bearing the name of their class as
4473 constructors */
82371d41
APB
4474 else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
4475 && ctxp
4476 && ctxp->current_parsed_class_un == EXPR_WFL_NODE (method_name)
23a79c61
APB
4477 && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
4478 && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
c877974e
APB
4479 return init_identifier_node;
4480 else
4481 return EXPR_WFL_NODE (method_name);
4482}
4483
22eed1e6
APB
4484/* Track method being redefined inside the same class. As a side
4485 effect, set DECL_NAME to an IDENTIFIER (prior entering this
4486 function it's a FWL, so we can track errors more accurately */
4487
e04a16fb
AG
4488static int
4489check_method_redefinition (class, method)
4490 tree class, method;
4491{
4492 tree redef, name;
4493 tree cl = DECL_NAME (method);
c3f2a476 4494 tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
ba179f9f
APB
4495 /* decl name of artificial <clinit> and $finit$ doesn't need to be
4496 fixed and checked */
5e942c50
APB
4497
4498 /* Reset the method name before running the check. If it returns 1,
4499 the method doesn't need to be verified with respect to method
4500 redeclaration and we return 0 */
4501 if (reset_method_name (method))
e04a16fb 4502 return 0;
5e942c50
APB
4503
4504 name = DECL_NAME (method);
e04a16fb
AG
4505 for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
4506 {
c3f2a476 4507 if (redef == method)
e04a16fb 4508 break;
c3f2a476
APB
4509 if (DECL_NAME (redef) == name
4510 && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
e04a16fb 4511 {
22eed1e6
APB
4512 parse_error_context
4513 (cl, "Duplicate %s declaration `%s'",
4514 (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
4515 get_printable_method_name (redef));
e04a16fb
AG
4516 return 1;
4517 }
4518 }
4519 return 0;
4520}
4521
4522/* Check all the methods of CLASS. Methods are first completed then
4523 checked according to regular method existance rules.
4524 If no constructor were encountered, then build its declaration. */
4525
4526static void
4527java_check_regular_methods (class_decl)
4528 tree class_decl;
4529{
5e942c50 4530 int saw_constructor = 0;
e04a16fb
AG
4531 tree method;
4532 tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
4533 tree super_class = CLASSTYPE_SUPER (class);
5e942c50 4534 tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
c877974e
APB
4535 tree mthrows;
4536
4537 /* It is not necessary to check methods defined in java.lang.Object */
4538 if (class == object_type_node)
4539 return;
e04a16fb 4540
23a79c61
APB
4541 if (!TYPE_NVIRTUALS (class))
4542 TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
e04a16fb
AG
4543
4544 /* Should take interfaces into account. FIXME */
4545 for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
4546 {
5e942c50 4547 tree sig;
e04a16fb
AG
4548 tree method_wfl = DECL_NAME (method);
4549 int aflags;
4550
5e942c50
APB
4551 /* If we previously found something and its name was saved,
4552 reinstall it now */
4553 if (found && saved_found_wfl)
ba179f9f
APB
4554 {
4555 DECL_NAME (found) = saved_found_wfl;
4556 saved_found_wfl = NULL_TREE;
4557 }
5e942c50 4558
e04a16fb
AG
4559 /* Check for redefinitions */
4560 if (check_method_redefinition (class, method))
4561 continue;
4562
22eed1e6
APB
4563 /* If we see one constructor a mark so we don't generate the
4564 default one. Also skip other verifications: constructors
4565 can't be inherited hence hiden or overriden */
4566 if (DECL_CONSTRUCTOR_P (method))
4567 {
4568 saw_constructor = 1;
4569 continue;
4570 }
4571
c877974e
APB
4572 /* We verify things thrown by the method. They must inherits from
4573 java.lang.Throwable */
4574 for (mthrows = DECL_FUNCTION_THROWS (method);
4575 mthrows; mthrows = TREE_CHAIN (mthrows))
4576 {
4577 if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
4578 parse_error_context
4579 (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be "
4580 "a subclass of class `java.lang.Throwable'",
4581 IDENTIFIER_POINTER
4582 (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
4583 }
4584
e04a16fb 4585 sig = build_java_argument_signature (TREE_TYPE (method));
e04a16fb 4586 found = lookup_argument_method (super_class, DECL_NAME (method), sig);
b9f7e36c 4587
5e942c50 4588 /* Nothing overrides or it's a private method. */
aabd7048 4589 if (!found)
5e942c50 4590 continue;
aabd7048
PB
4591 if (METHOD_PRIVATE (found))
4592 {
4593 found = NULL_TREE;
4594 continue;
4595 }
5e942c50
APB
4596
4597 /* If found wasn't verified, it's DECL_NAME won't be set properly.
4598 We set it temporarily for the sake of the error report. */
4599 saved_found_wfl = DECL_NAME (found);
4600 reset_method_name (found);
4601
e04a16fb
AG
4602 /* Can't override a method with the same name and different return
4603 types. */
4604 if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
b9f7e36c 4605 {
0a2138e2
APB
4606 char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
4607 0));
b9f7e36c 4608 parse_error_context
7f10c2e2 4609 (method_wfl,
b9f7e36c 4610 "Method `%s' was defined with return type `%s' in class `%s'",
0a2138e2 4611 lang_printable_name (found, 0), t,
b9f7e36c
APB
4612 IDENTIFIER_POINTER
4613 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4614 free (t);
4615 }
e04a16fb 4616
7f10c2e2
APB
4617 aflags = get_access_flags_from_decl (found);
4618 /* If the method has default, access in an other package, then
4619 issue a warning that the current method doesn't override the
4620 one that was found elsewhere. Do not issue this warning when
4621 the match was found in java.lang.Object. */
4622 if (DECL_CONTEXT (found) != object_type_node
4623 && ((aflags & 0x7) == 0)
4624 && !class_in_current_package (DECL_CONTEXT (found))
1fb89a4d 4625 && DECL_NAME (found) != clinit_identifier_node
7f10c2e2
APB
4626 && flag_not_overriding)
4627 {
4628 parse_warning_context
4629 (method_wfl, "Method `%s' in class `%s' does not "
4630 "override the corresponding method in class `%s', which is "
4631 "private to a different package",
4632 lang_printable_name (found, 0),
4633 IDENTIFIER_POINTER (DECL_NAME (class_decl)),
4634 IDENTIFIER_POINTER (DECL_NAME
4635 (TYPE_NAME (DECL_CONTEXT (found)))));
4636 continue;
4637 }
4638
e04a16fb
AG
4639 /* Can't override final. Can't override static. */
4640 if (METHOD_FINAL (found) || METHOD_STATIC (found))
4641 {
4642 /* Static *can* override static */
4643 if (METHOD_STATIC (found) && METHOD_STATIC (method))
4644 continue;
4645 parse_error_context
4646 (method_wfl,
4647 "%s methods can't be overriden. Method `%s' is %s in class `%s'",
4648 (METHOD_FINAL (found) ? "Final" : "Static"),
0a2138e2 4649 lang_printable_name (found, 0),
e04a16fb
AG
4650 (METHOD_FINAL (found) ? "final" : "static"),
4651 IDENTIFIER_POINTER
4652 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4653 continue;
4654 }
7f10c2e2 4655
e04a16fb
AG
4656 /* Static method can't override instance method. */
4657 if (METHOD_STATIC (method))
4658 {
4659 parse_error_context
4660 (method_wfl,
4661 "Instance methods can't be overriden by a static method. Method "
4662 "`%s' is an instance method in class `%s'",
0a2138e2 4663 lang_printable_name (found, 0),
e04a16fb
AG
4664 IDENTIFIER_POINTER
4665 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4666 continue;
4667 }
5e942c50 4668
5e942c50
APB
4669 /* - Overriding/hiding public must be public
4670 - Overriding/hiding protected must be protected or public
4671 - If the overriden or hidden method has default (package)
4672 access, then the overriding or hiding method must not be
4673 private; otherwise, a compile-time error occurs */
4674 if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
4675 || (METHOD_PROTECTED (found)
4676 && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
4677 || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
4678 && METHOD_PRIVATE (method)))
e04a16fb
AG
4679 {
4680 parse_error_context
4681 (method_wfl,
4682 "Methods can't be overridden to be more private. Method `%s' is "
5e942c50
APB
4683 "not %s in class `%s'", lang_printable_name (method, 0),
4684 (METHOD_PUBLIC (method) ? "public" :
4685 (METHOD_PRIVATE (method) ? "private" : "protected")),
4686 IDENTIFIER_POINTER (DECL_NAME
4687 (TYPE_NAME (DECL_CONTEXT (found)))));
e04a16fb
AG
4688 continue;
4689 }
4690
b9f7e36c
APB
4691 /* Overriding methods must have compatible `throws' clauses on checked
4692 exceptions, if any */
4693 check_throws_clauses (method, method_wfl, found);
4694
e04a16fb
AG
4695 /* Inheriting multiple methods with the same signature. FIXME */
4696 }
4697
5e942c50
APB
4698 /* Don't forget eventual pending found and saved_found_wfl. Take
4699 into account that we might have exited because we saw an
4700 aritifical method as the last entry. */
4701
4702 if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
4703 DECL_NAME (found) = saved_found_wfl;
4704
23a79c61
APB
4705 if (!TYPE_NVIRTUALS (class))
4706 TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
e04a16fb 4707
22eed1e6 4708 if (!saw_constructor)
e04a16fb 4709 {
23a79c61
APB
4710 /* No constructor seen, we craft one, at line 0. Since this
4711 operation takes place after we laid methods out
4712 (layout_class_methods), we prepare the its DECL
4713 appropriately. */
22eed1e6
APB
4714 int flags;
4715 tree decl;
4716
4717 /* If the class is declared PUBLIC, the default constructor is
4718 PUBLIC otherwise it has default access implied by no access
4719 modifiers. */
4720 flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
4721 ACC_PUBLIC : 0);
4722 decl = create_artificial_method (class, flags, void_type_node,
de4c7b02 4723 init_identifier_node, end_params_node);
e04a16fb 4724 DECL_CONSTRUCTOR_P (decl) = 1;
23a79c61 4725 layout_class_method (TREE_TYPE (class_decl), NULL_TREE, decl, NULL_TREE);
e04a16fb
AG
4726 }
4727}
4728
b9f7e36c
APB
4729/* Return a non zero value if the `throws' clause of METHOD (if any)
4730 is incompatible with the `throws' clause of FOUND (if any). */
4731
4732static void
4733check_throws_clauses (method, method_wfl, found)
4734 tree method, method_wfl, found;
4735{
4736 tree mthrows, fthrows;
4737
c877974e
APB
4738 /* Can't check these things with class loaded from bytecode. FIXME */
4739 if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
4740 return;
4741
b9f7e36c
APB
4742 for (mthrows = DECL_FUNCTION_THROWS (method);
4743 mthrows; mthrows = TREE_CHAIN (mthrows))
4744 {
4745 /* We don't verify unchecked expressions */
c877974e 4746 if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
b9f7e36c
APB
4747 continue;
4748 /* Checked expression must be compatible */
4749 for (fthrows = DECL_FUNCTION_THROWS (found);
4750 fthrows; fthrows = TREE_CHAIN (fthrows))
4751 if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
4752 break;
4753 if (!fthrows)
4754 {
4755 parse_error_context
4756 (method_wfl, "Invalid checked exception class `%s' in "
4757 "`throws' clause. The exception must be a subclass of an "
4758 "exception thrown by `%s' from class `%s'",
4759 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
0a2138e2 4760 lang_printable_name (found, 0),
b9f7e36c
APB
4761 IDENTIFIER_POINTER
4762 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4763 }
4764 }
4765}
4766
e04a16fb
AG
4767/* Check abstract method of interface INTERFACE */
4768
4769static void
5e942c50
APB
4770java_check_abstract_methods (interface_decl)
4771 tree interface_decl;
e04a16fb
AG
4772{
4773 int i, n;
4774 tree method, basetype_vec, found;
5e942c50 4775 tree interface = TREE_TYPE (interface_decl);
e04a16fb
AG
4776
4777 for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
4778 {
b9f7e36c 4779 tree method_wfl = DECL_NAME (method);
e04a16fb
AG
4780
4781 /* 2- Check for double definition inside the defining interface */
4782 if (check_method_redefinition (interface, method))
4783 continue;
4784
4785 /* 3- Overriding is OK as far as we preserve the return type and
b9f7e36c 4786 the thrown exceptions (FIXME) */
e04a16fb
AG
4787 found = lookup_java_interface_method2 (interface, method);
4788 if (found)
4789 {
5e942c50
APB
4790 char *t;
4791 tree saved_found_wfl = DECL_NAME (found);
4792 reset_method_name (found);
4793 t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
e04a16fb 4794 parse_error_context
b9f7e36c 4795 (method_wfl,
5e942c50 4796 "Method `%s' was defined with return type `%s' in class `%s'",
0a2138e2 4797 lang_printable_name (found, 0), t,
b9f7e36c
APB
4798 IDENTIFIER_POINTER
4799 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4800 free (t);
e04a16fb 4801 continue;
5e942c50
APB
4802
4803 DECL_NAME (found) = saved_found_wfl;
e04a16fb
AG
4804 }
4805 }
4806
4807 /* 4- Inherited methods can't differ by their returned types */
4808 if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
4809 return;
4810 n = TREE_VEC_LENGTH (basetype_vec);
4811 for (i = 0; i < n; i++)
4812 {
4813 tree sub_interface_method, sub_interface;
4814 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4815 if (!vec_elt)
4816 continue;
4817 sub_interface = BINFO_TYPE (vec_elt);
4818 for (sub_interface_method = TYPE_METHODS (sub_interface);
4819 sub_interface_method;
4820 sub_interface_method = TREE_CHAIN (sub_interface_method))
4821 {
4822 found = lookup_java_interface_method2 (interface,
4823 sub_interface_method);
4824 if (found && (found != sub_interface_method))
5e942c50
APB
4825 {
4826 tree saved_found_wfl = DECL_NAME (found);
4827 reset_method_name (found);
4828 parse_error_context
4829 (lookup_cl (sub_interface_method),
4830 "Interface `%s' inherits method `%s' from interface `%s'. "
4831 "This method is redefined with a different return type in "
4832 "interface `%s'",
4833 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
4834 lang_printable_name (found, 0),
4835 IDENTIFIER_POINTER
4836 (DECL_NAME (TYPE_NAME
4837 (DECL_CONTEXT (sub_interface_method)))),
4838 IDENTIFIER_POINTER
4839 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4840 DECL_NAME (found) = saved_found_wfl;
4841 }
e04a16fb
AG
4842 }
4843 }
4844}
4845
e04a16fb
AG
4846/* Lookup methods in interfaces using their name and partial
4847 signature. Return a matching method only if their types differ. */
4848
4849static tree
4850lookup_java_interface_method2 (class, method_decl)
4851 tree class, method_decl;
4852{
4853 int i, n;
4854 tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
4855
4856 if (!basetype_vec)
4857 return NULL_TREE;
4858
4859 n = TREE_VEC_LENGTH (basetype_vec);
4860 for (i = 0; i < n; i++)
4861 {
4862 tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
4863 if ((BINFO_TYPE (vec_elt) != object_type_node)
4864 && (to_return =
4865 lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
4866 return to_return;
4867 }
4868 for (i = 0; i < n; i++)
4869 {
4870 to_return = lookup_java_interface_method2
4871 (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
4872 if (to_return)
4873 return to_return;
4874 }
4875
4876 return NULL_TREE;
4877}
4878
4879/* Lookup method using their name and partial signature. Return a
4880 matching method only if their types differ. */
4881
4882static tree
4883lookup_java_method2 (clas, method_decl, do_interface)
4884 tree clas, method_decl;
4885 int do_interface;
4886{
5e942c50
APB
4887 tree method, method_signature, method_name, method_type, name;
4888
e04a16fb 4889 method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
5e942c50
APB
4890 name = DECL_NAME (method_decl);
4891 method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
4892 EXPR_WFL_NODE (name) : name);
e04a16fb
AG
4893 method_type = TREE_TYPE (TREE_TYPE (method_decl));
4894
4895 while (clas != NULL_TREE)
4896 {
4897 for (method = TYPE_METHODS (clas);
4898 method != NULL_TREE; method = TREE_CHAIN (method))
4899 {
4900 tree method_sig = build_java_argument_signature (TREE_TYPE (method));
5e942c50
APB
4901 tree name = DECL_NAME (method);
4902 if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
4903 EXPR_WFL_NODE (name) : name) == method_name
e04a16fb
AG
4904 && method_sig == method_signature
4905 && TREE_TYPE (TREE_TYPE (method)) != method_type)
5e942c50 4906 return method;
e04a16fb
AG
4907 }
4908 clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
4909 }
4910 return NULL_TREE;
4911}
4912
4913/* Return the line that matches DECL line number. Used during error
4914 report */
4915
4916static tree
4917lookup_cl (decl)
4918 tree decl;
4919{
4920 static tree cl = NULL_TREE;
4921
4922 if (!decl)
4923 return NULL_TREE;
4924
4925 if (cl == NULL_TREE)
4926 cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
4927
4928 EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
4929 EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
4930
4931 return cl;
4932}
4933
4934/* Look for a simple name in the single-type import list */
4935
4936static tree
4937find_name_in_single_imports (name)
4938 tree name;
4939{
4940 tree node;
4941
4942 for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
4943 if (TREE_VALUE (node) == name)
4944 return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
4945
4946 return NULL_TREE;
4947}
4948
4949/* Process all single-type import. */
4950
4951static int
4952process_imports ()
4953{
4954 tree import;
4955 int error_found;
4956
4957 for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
4958 {
4959 tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
4960
4961 /* Don't load twice something already defined. */
4962 if (IDENTIFIER_CLASS_VALUE (to_be_found))
4963 continue;
4964 QUALIFIED_P (to_be_found) = 1;
4965 load_class (to_be_found, 0);
4966 error_found =
4967 check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
4968 if (!IDENTIFIER_CLASS_VALUE (to_be_found))
4969 {
4970 parse_error_context (TREE_PURPOSE (import),
4971 "Class or interface `%s' not found in import",
4972 IDENTIFIER_POINTER (to_be_found));
4973 return 1;
4974 }
4975 if (error_found)
4976 return 1;
4977 }
4978 return 0;
4979}
4980
4981/* Possibly find a class imported by a single-type import statement. Return
4982 1 if an error occured, 0 otherwise. */
4983
4984static int
4985find_in_imports (class_type)
4986 tree class_type;
4987{
4988 tree import;
4989
4990 for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
4991 if (TREE_VALUE (import) == TYPE_NAME (class_type))
4992 {
4993 TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
4994 QUALIFIED_P (TYPE_NAME (class_type)) = 1;
e04a16fb
AG
4995 }
4996 return 0;
4997}
4998
e04a16fb 4999static int
63a212ed
PB
5000note_possible_classname (name, len)
5001 char *name;
5002 int len;
e04a16fb 5003{
63a212ed
PB
5004 tree node;
5005 if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
5006 len = len - 5;
5007 else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
5008 len = len - 6;
e04a16fb 5009 else
63a212ed
PB
5010 return 0;
5011 node = ident_subst (name, len, "", '/', '.', "");
5012 IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
5013 QUALIFIED_P (node) = 1; /* As soon as we turn / into . */
5014 return 1;
e04a16fb
AG
5015}
5016
5017/* Read a import directory, gathering potential match for further type
5018 references. Indifferently reads a filesystem or a ZIP archive
5019 directory. */
5020
5021static void
5022read_import_dir (wfl)
5023 tree wfl;
5024{
63a212ed
PB
5025 tree package_id = EXPR_WFL_NODE (wfl);
5026 char *package_name = IDENTIFIER_POINTER (package_id);
5027 int package_length = IDENTIFIER_LENGTH (package_id);
e04a16fb 5028 DIR *dirp = NULL;
d8fccff5 5029 JCF *saved_jcf = current_jcf;
e04a16fb 5030
63a212ed
PB
5031 int found = 0;
5032 int k;
5033 void *entry;
5034 struct buffer filename[1];
5035
5036
5037 if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
5038 return;
5039 IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
5040
5041 BUFFER_INIT (filename);
5042 buffer_grow (filename, package_length + 100);
5043
5044 for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
5045 {
5046 char *entry_name = jcf_path_name (entry);
5047 int entry_length = strlen (entry_name);
5048 if (jcf_path_is_zipfile (entry))
5049 {
5050 ZipFile *zipf;
5051 buffer_grow (filename, entry_length);
5052 memcpy (filename->data, entry_name, entry_length - 1);
5053 filename->data[entry_length-1] = '\0';
5054 zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
5055 if (zipf == NULL)
5056 error ("malformed .zip archive in CLASSPATH: %s", entry_name);
5057 else
5058 {
5059 ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
5060 BUFFER_RESET (filename);
5061 for (k = 0; k < package_length; k++)
5062 {
5063 char ch = package_name[k];
5064 *filename->ptr++ = ch == '.' ? '/' : ch;
5065 }
5066 *filename->ptr++ = '/';
5067
345137c7 5068 for (k = 0; k < zipf->count; k++, zipd = ZIPDIR_NEXT (zipd))
63a212ed
PB
5069 {
5070 char *current_entry = ZIPDIR_FILENAME (zipd);
5071 int current_entry_len = zipd->filename_length;
5072
345137c7
TT
5073 if (current_entry_len >= BUFFER_LENGTH (filename)
5074 && strncmp (filename->data, current_entry,
5075 BUFFER_LENGTH (filename)) != 0)
63a212ed 5076 continue;
345137c7 5077 found |= note_possible_classname (current_entry,
63a212ed
PB
5078 current_entry_len);
5079 }
5080 }
5081 }
5082 else
5083 {
5084 BUFFER_RESET (filename);
5085 buffer_grow (filename, entry_length + package_length + 4);
5086 strcpy (filename->data, entry_name);
5087 filename->ptr = filename->data + entry_length;
5088 for (k = 0; k < package_length; k++)
5089 {
5090 char ch = package_name[k];
5091 *filename->ptr++ = ch == '.' ? '/' : ch;
5092 }
5093 *filename->ptr = '\0';
5094
5095 dirp = opendir (filename->data);
5096 if (dirp == NULL)
5097 continue;
5098 *filename->ptr++ = '/';
5099 for (;;)
5100 {
63a212ed
PB
5101 int len;
5102 char *d_name;
5103 struct dirent *direntp = readdir (dirp);
5104 if (!direntp)
5105 break;
5106 d_name = direntp->d_name;
5107 len = strlen (direntp->d_name);
5108 buffer_grow (filename, len+1);
5109 strcpy (filename->ptr, d_name);
345137c7 5110 found |= note_possible_classname (filename->data + entry_length,
63a212ed
PB
5111 package_length+len+1);
5112 }
5113 if (dirp)
5114 closedir (dirp);
5115 }
5116 }
e04a16fb 5117
63a212ed 5118 free (filename->data);
e04a16fb 5119
63a212ed
PB
5120 /* Here we should have a unified way of retrieving an entry, to be
5121 indexed. */
5122 if (!found)
e04a16fb
AG
5123 {
5124 static int first = 1;
5125 if (first)
5126 {
5127 char buffer [256];
5128 sprintf (buffer, "Can't find default package `%s'. Check "
5129 "the CLASSPATH environment variable and the access to the "
63a212ed 5130 "archives.", package_name);
e04a16fb
AG
5131 error (buffer);
5132 java_error_count++;
5133 first = 0;
5134 }
5135 else
63a212ed
PB
5136 parse_error_context (wfl, "Package `%s' not found in import",
5137 package_name);
e04a16fb
AG
5138 current_jcf = saved_jcf;
5139 return;
5140 }
e04a16fb
AG
5141 current_jcf = saved_jcf;
5142}
5143
5144/* Possibly find a type in the import on demands specified
5145 types. Returns 1 if an error occured, 0 otherwise. Run throught the
5146 entire list, to detected potential double definitions. */
5147
5148static int
5149find_in_imports_on_demand (class_type)
5150 tree class_type;
5151{
ab3a6dd6 5152 tree node, import, node_to_use = NULL_TREE;
e04a16fb 5153 int seen_once = -1;
ab3a6dd6 5154 tree cl = NULL_TREE;
e04a16fb
AG
5155
5156 for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
5157 {
5158 char *id_name;
e04a16fb
AG
5159 obstack_grow (&temporary_obstack,
5160 IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
5161 IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
63a212ed 5162 obstack_1grow (&temporary_obstack, '.');
e04a16fb
AG
5163 obstack_grow0 (&temporary_obstack,
5164 IDENTIFIER_POINTER (TYPE_NAME (class_type)),
5165 IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
5166 id_name = obstack_finish (&temporary_obstack);
5167
5168 node = maybe_get_identifier (id_name);
5169 if (node && IS_A_CLASSFILE_NAME (node))
5170 {
5171 if (seen_once < 0)
5172 {
5173 cl = TREE_PURPOSE (import);
5174 seen_once = 1;
5175 node_to_use = node;
5176 }
5177 else
5178 {
5179 seen_once++;
5180 parse_error_context
5181 (import, "Type `%s' also potentially defined in package `%s'",
5182 IDENTIFIER_POINTER (TYPE_NAME (class_type)),
5183 IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
5184 }
5185 }
5186 }
5187
5188 if (seen_once == 1)
5189 {
5190 /* Setup lineno so that it refers to the line of the import (in
5191 case we parse a class file and encounter errors */
5192 tree decl;
5193 int saved_lineno = lineno;
5194 lineno = EXPR_WFL_LINENO (cl);
63a212ed 5195 TYPE_NAME (class_type) = node_to_use;
e04a16fb
AG
5196 QUALIFIED_P (TYPE_NAME (class_type)) = 1;
5197 decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5198 /* If there is no DECL set for the class or if the class isn't
5199 loaded and not seen in source yet, the load */
5200 if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
5201 && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
5202 load_class (node_to_use, 0);
5203 lineno = saved_lineno;
5204 return check_pkg_class_access (TYPE_NAME (class_type), cl);
5205 }
5206 else
5207 return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
5208}
5209
5e942c50
APB
5210static tree
5211resolve_package (pkg, next)
5212 tree pkg, *next;
5213{
5214 tree type_name = NULL_TREE;
5215 char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
5e942c50
APB
5216
5217 /* The trick is to determine when the package name stops and were
5218 the name of something contained in the package starts. Then we
5219 return a fully qualified name of what we want to get. */
5220
5221 /* Do a quick search on well known package names */
5222 if (!strncmp (name, "java.lang.reflect", 17))
5223 {
5224 *next =
5225 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
5226 type_name = lookup_package_type (name, 17);
5227 }
5228 else if (!strncmp (name, "java.lang", 9))
5229 {
5230 *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
5231 type_name = lookup_package_type (name, 9);
5232 }
5233 else
5234 return NULL_TREE; /* FIXME, search all imported packages. */
5235
5236 return type_name;
5237}
5238
5239static tree
5240lookup_package_type (name, from)
5241 char *name;
5242 int from;
5243{
5244 char subname [128];
5245 char *sub = &name[from+1];
5246 while (*sub != '.' && *sub)
5247 sub++;
5248 strncpy (subname, name, sub-name);
5249 subname [sub-name] = '\0';
5250 return get_identifier (subname);
5251}
5252
e04a16fb
AG
5253/* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
5254 access violations were found, 1 otherwise. */
5255
5256static int
5257check_pkg_class_access (class_name, cl)
5258 tree class_name;
5259 tree cl;
5260{
5261 tree type;
e04a16fb
AG
5262
5263 if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
5264 return 0;
5265
5266 if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
5267 return 0;
5268
5269 if (!CLASS_PUBLIC (TYPE_NAME (type)))
5270 {
e28cd97b
APB
5271 /* Access to a private class within the same package is
5272 allowed. */
5273 tree l, r;
5274 breakdown_qualified (&l, &r, class_name);
5275 if (l == ctxp->package)
5276 return 0;
5277
e04a16fb
AG
5278 parse_error_context
5279 (cl, "Can't access %s `%s'. Only public classes and interfaces in "
5280 "other packages can be accessed",
5281 (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
5282 IDENTIFIER_POINTER (class_name));
5283 return 1;
5284 }
5285 return 0;
5286}
5287
5288/* Local variable declaration. */
5289
5290static void
5291declare_local_variables (modifier, type, vlist)
5292 int modifier;
5293 tree type;
5294 tree vlist;
5295{
c583dd46
APB
5296 tree decl, current, saved_type;
5297 tree type_wfl = NULL_TREE;
e04a16fb
AG
5298 int must_chain = 0;
5299
2aa11e97 5300 /* Push a new block if statements were seen between the last time we
e04a16fb 5301 pushed a block and now. Keep a cound of block to close */
f099f336 5302 if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
e04a16fb 5303 {
f099f336 5304 tree body = GET_CURRENT_BLOCK (current_function_decl);
e04a16fb 5305 tree b = enter_block ();
f099f336 5306 BLOCK_EXPR_ORIGIN (b) = body;
e04a16fb
AG
5307 }
5308
5309 if (modifier)
5310 {
5311 int i;
5312 for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
c877974e
APB
5313 if (modifier == ACC_FINAL)
5314 {
5315 if (flag_static_local_jdk1_1)
5316 parse_warning_context (ctxp->modifier_ctx [i],
5317 "Unsupported JDK1.1 `final' local variable "
5318 "(treated as non final)");
5319 }
5320 else
5321 {
5322 parse_error_context
5323 (ctxp->modifier_ctx [i],
5324 "Only `final' is allowed as a local variables modifier");
5325 return;
5326 }
e04a16fb
AG
5327 }
5328
c583dd46
APB
5329 /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
5330 hold the TYPE value if a new incomplete has to be created (as
5331 opposed to being found already existing and reused). */
5332 SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
5333
5334 /* If TYPE is fully resolved and we don't have a reference, make one */
1886c9d8 5335 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
c583dd46
APB
5336
5337 /* Go through all the declared variables */
5338 for (current = vlist, saved_type = type; current;
5339 current = TREE_CHAIN (current), type = saved_type)
e04a16fb 5340 {
c877974e 5341 tree other, real_type;
e04a16fb
AG
5342 tree wfl = TREE_PURPOSE (current);
5343 tree name = EXPR_WFL_NODE (wfl);
5344 tree init = TREE_VALUE (current);
e04a16fb 5345
c583dd46
APB
5346 /* Process NAME, as it may specify extra dimension(s) for it */
5347 type = build_array_from_name (type, type_wfl, name, &name);
5348
5349 /* Variable redefinition check */
5350 if ((other = lookup_name_in_blocks (name)))
5351 {
5352 variable_redefinition_error (wfl, name, TREE_TYPE (other),
5353 DECL_SOURCE_LINE (other));
5354 continue;
5355 }
5356
5357 /* Type adjustment. We may have just readjusted TYPE because
5358 the variable specified more dimensions. Make sure we have
5359 a reference if we can and don't have one already. */
1886c9d8 5360 PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
c877974e
APB
5361
5362 real_type = GET_REAL_TYPE (type);
c583dd46
APB
5363 /* Never layout this decl. This will be done when its scope
5364 will be entered */
c877974e 5365 decl = build_decl (VAR_DECL, name, real_type);
c583dd46
APB
5366 BLOCK_CHAIN_DECL (decl);
5367
d4370213
APB
5368 /* If doing xreferencing, replace the line number with the WFL
5369 compound value */
5370 if (flag_emit_xref)
5371 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
5372
e04a16fb
AG
5373 /* Don't try to use an INIT statement when an error was found */
5374 if (init && java_error_count)
5375 init = NULL_TREE;
c583dd46
APB
5376
5377 /* Add the initialization function to the current function's code */
5378 if (init)
e04a16fb 5379 {
c583dd46
APB
5380 /* Name might have been readjusted */
5381 EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
5382 MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
5383 java_method_add_stmt (current_function_decl,
5384 build_debugable_stmt (EXPR_WFL_LINECOL (init),
5385 init));
5386 }
5387
5388 /* Setup dependency the type of the decl */
5389 if (must_chain)
5390 {
5391 jdep *dep;
5392 register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
5393 dep = CLASSD_LAST (ctxp->classd_list);
5394 JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
e04a16fb
AG
5395 }
5396 }
5397 SOURCE_FRONTEND_DEBUG (("Defined locals"));
5398}
5399
5400/* Called during parsing. Build decls from argument list. */
5401
5402static void
5403source_start_java_method (fndecl)
5404 tree fndecl;
5405{
5406 tree tem;
5407 tree parm_decl;
5408 int i;
5409
e04a16fb
AG
5410 current_function_decl = fndecl;
5411
5412 /* New scope for the function */
5413 enter_block ();
5414 for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
de4c7b02 5415 tem != end_params_node; tem = TREE_CHAIN (tem), i++)
e04a16fb
AG
5416 {
5417 tree type = TREE_VALUE (tem);
5418 tree name = TREE_PURPOSE (tem);
5419
23a79c61
APB
5420 /* If type is incomplete. Create an incomplete decl and ask for
5421 the decl to be patched later */
e04a16fb
AG
5422 if (INCOMPLETE_TYPE_P (type))
5423 {
5424 jdep *jdep;
c877974e
APB
5425 tree real_type = GET_REAL_TYPE (type);
5426 parm_decl = build_decl (PARM_DECL, name, real_type);
23a79c61 5427 type = obtain_incomplete_type (type);
e04a16fb
AG
5428 register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
5429 jdep = CLASSD_LAST (ctxp->classd_list);
5430 JDEP_MISC (jdep) = name;
5431 JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
5432 }
5433 else
5434 parm_decl = build_decl (PARM_DECL, name, type);
5435
5436 BLOCK_CHAIN_DECL (parm_decl);
5437 }
5438 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
5439 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
5440 nreverse (tem);
5441 DECL_ARG_SLOT_COUNT (current_function_decl) = i;
5442}
5443
22eed1e6
APB
5444/* Called during parsing. Creates an artificial method declaration. */
5445
5446static tree
5447create_artificial_method (class, flags, type, name, args)
5448 tree class;
5449 int flags;
5450 tree type, name, args;
5451{
5452 int saved_lineno = lineno;
5453 tree mdecl;
5454
5455 lineno = 0;
5456 mdecl = make_node (FUNCTION_TYPE);
5457 TREE_TYPE (mdecl) = type;
5458 TYPE_ARG_TYPES (mdecl) = args;
5459 mdecl = add_method (class, flags, name, build_java_signature (mdecl));
5460 lineno = saved_lineno;
5461 DECL_ARTIFICIAL (mdecl) = 1;
5462 return mdecl;
5463}
5464
5465/* Starts the body if an artifical method. */
5466
5467static void
5468start_artificial_method_body (mdecl)
5469 tree mdecl;
5470{
5471 DECL_SOURCE_LINE (mdecl) = 1;
5472 DECL_SOURCE_LINE_MERGE (mdecl, 1);
5473 source_start_java_method (mdecl);
5474 enter_block ();
5475}
5476
5477static void
5478end_artificial_method_body (mdecl)
5479 tree mdecl;
5480{
5481 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
5482 exit_block ();
5483}
5484
e04a16fb
AG
5485/* Called during expansion. Push decls formerly built from argument
5486 list so they're usable during expansion. */
5487
5488static void
5489expand_start_java_method (fndecl)
5490 tree fndecl;
5491{
5492 tree tem, *ptr;
e04a16fb 5493
e04a16fb
AG
5494 current_function_decl = fndecl;
5495
5496 announce_function (fndecl);
5497 pushlevel (1); /* Push parameters */
5498 ptr = &DECL_ARGUMENTS (fndecl);
5499 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
5500 while (tem)
5501 {
5502 tree next = TREE_CHAIN (tem);
b67d701b
PB
5503 tree type = TREE_TYPE (tem);
5504#ifdef PROMOTE_PROTOTYPES
5505 if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
5506 && INTEGRAL_TYPE_P (type))
5507 type = integer_type_node;
5508#endif
5509 DECL_ARG_TYPE (tem) = type;
e04a16fb
AG
5510 layout_decl (tem, 0);
5511 pushdecl (tem);
e04a16fb
AG
5512 *ptr = tem;
5513 ptr = &TREE_CHAIN (tem);
5514 tem = next;
5515 }
5516 *ptr = NULL_TREE;
5517 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
5518 lineno = DECL_SOURCE_LINE_FIRST (fndecl);
e04a16fb
AG
5519}
5520
5521/* Terminate a function and expand its body. */
5522
5523static void
5524source_end_java_method ()
5525{
5526 tree fndecl = current_function_decl;
138657ec 5527 int flag_asynchronous_exceptions = asynchronous_exceptions;
e04a16fb
AG
5528
5529 java_parser_context_save_global ();
5530 lineno = ctxp->last_ccb_indent1;
5531
b67d701b
PB
5532 /* Set EH language codes */
5533 java_set_exception_lang_code ();
5534
5423609c
APB
5535 /* Turn function bodies with only a NOP expr null, so they don't get
5536 generated at all and we won't get warnings when using the -W
5537 -Wall flags. */
5538 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
5539 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
5540
e04a16fb
AG
5541 /* Generate function's code */
5542 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
e8fc7396
APB
5543 && ! flag_emit_class_files
5544 && ! flag_emit_xref)
e04a16fb
AG
5545 expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
5546
5547 /* pop out of its parameters */
5548 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
5549 poplevel (1, 0, 1);
5550 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5551
5552 /* Generate rtl for function exit. */
e8fc7396 5553 if (! flag_emit_class_files && ! flag_emit_xref)
e04a16fb
AG
5554 {
5555 lineno = DECL_SOURCE_LINE_LAST (fndecl);
b67d701b
PB
5556 /* Emit catch-finally clauses */
5557 emit_handlers ();
e04a16fb
AG
5558 expand_function_end (input_filename, lineno, 0);
5559
138657ec
AH
5560 /* FIXME: If the current method contains any exception handlers,
5561 force asynchronous_exceptions: this is necessary because signal
5562 handlers in libjava may throw exceptions. This is far from being
5563 a perfect solution, but it's better than doing nothing at all.*/
5564 if (catch_clauses)
5565 asynchronous_exceptions = 1;
5566
e04a16fb
AG
5567 /* Run the optimizers and output assembler code for this function. */
5568 rest_of_compilation (fndecl);
5569 }
5570
5571 current_function_decl = NULL_TREE;
5572 /* permanent_allocation (1); */
5573 java_parser_context_restore_global ();
138657ec 5574 asynchronous_exceptions = flag_asynchronous_exceptions;
e04a16fb
AG
5575}
5576
5577/* Record EXPR in the current function block. Complements compound
5578 expression second operand if necessary. */
5579
5580tree
5581java_method_add_stmt (fndecl, expr)
5582 tree fndecl, expr;
5583{
f099f336 5584 return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
b67d701b 5585}
e04a16fb 5586
b67d701b
PB
5587static tree
5588add_stmt_to_block (b, type, stmt)
5589 tree b, type, stmt;
5590{
5591 tree body = BLOCK_EXPR_BODY (b), c;
5592
e04a16fb
AG
5593 if (java_error_count)
5594 return body;
b67d701b
PB
5595
5596 if ((c = add_stmt_to_compound (body, type, stmt)) == body)
e04a16fb
AG
5597 return body;
5598
b67d701b
PB
5599 BLOCK_EXPR_BODY (b) = c;
5600 TREE_SIDE_EFFECTS (c) = 1;
5601 return c;
e04a16fb
AG
5602}
5603
5604/* Add STMT to EXISTING if possible, otherwise create a new
5605 COMPOUND_EXPR and add STMT to it. */
5606
5607static tree
5608add_stmt_to_compound (existing, type, stmt)
5609 tree existing, type, stmt;
5610{
15fdcfe9
PB
5611 if (existing)
5612 return build (COMPOUND_EXPR, type, existing, stmt);
e04a16fb 5613 else
15fdcfe9 5614 return stmt;
e04a16fb
AG
5615}
5616
5617/* Hold THIS for the scope of the current public method decl. */
5618static tree current_this;
5619
1886c9d8
APB
5620void java_layout_seen_class_methods ()
5621{
5622 tree previous_list = all_class_list;
5623 tree end = NULL_TREE;
5624 tree current;
5625
5626 while (1)
5627 {
5628 for (current = previous_list;
5629 current != end; current = TREE_CHAIN (current))
5630 layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
5631
5632 if (previous_list != all_class_list)
5633 {
5634 end = previous_list;
5635 previous_list = all_class_list;
5636 }
5637 else
5638 break;
5639 }
5640}
5641
23a79c61
APB
5642/* Layout the methods of all classes loaded in one way on an
5643 other. Check methods of source parsed classes. Then reorder the
5644 fields and layout the classes or the type of all source parsed
5645 classes */
e04a16fb
AG
5646
5647void
5648java_layout_classes ()
5649{
5650 tree current;
bc3ca41b 5651 int save_error_count = java_error_count;
5e942c50 5652
23a79c61 5653 /* Layout the methods of all classes seen so far */
1886c9d8 5654 java_layout_seen_class_methods ();
23a79c61
APB
5655 java_parse_abort_on_error ();
5656 all_class_list = NULL_TREE;
5657
5658 /* Then check the methods of all parsed classes */
5659 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
5660 if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
5661 CHECK_METHODS (TREE_VALUE (current));
5662 java_parse_abort_on_error ();
5663
5e942c50 5664 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
e04a16fb 5665 {
5e942c50 5666 current_class = TREE_TYPE (TREE_VALUE (current));
22eed1e6 5667
c877974e
APB
5668 /* Reverse the fields, but leave the dummy field in front.
5669 Fields are already ordered for Object and Class */
5670 if (TYPE_FIELDS (current_class) && current_class != object_type_node
5671 && current_class != class_type_node)
5672 {
23a79c61
APB
5673 /* If the dummy field is there, reverse the right fields and
5674 just layout the type for proper fields offset */
c877974e
APB
5675 if (!DECL_NAME (TYPE_FIELDS (current_class)))
5676 {
5677 tree fields = TYPE_FIELDS (current_class);
5678 TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
5679 TYPE_SIZE (current_class) = NULL_TREE;
5680 layout_type (current_class);
5681 }
23a79c61
APB
5682 /* We don't have a dummy field, we need to layout the class,
5683 after having reversed the fields */
c877974e
APB
5684 else
5685 {
5686 TYPE_FIELDS (current_class) =
5687 nreverse (TYPE_FIELDS (current_class));
5688 TYPE_SIZE (current_class) = NULL_TREE;
5689 layout_class (current_class);
5690 }
5691 }
23a79c61
APB
5692 else
5693 layout_class (current_class);
5e942c50 5694
c877974e
APB
5695 /* From now on, the class is considered completely loaded */
5696 CLASS_LOADED_P (current_class) = 1;
5697
5e942c50
APB
5698 /* Error reported by the caller */
5699 if (java_error_count)
5700 return;
e04a16fb 5701 }
23a79c61
APB
5702
5703 /* We might have reloaded classes durign the process of laying out
5704 classes for code generation. We must layout the methods of those
5705 late additions, as constructor checks might use them */
1886c9d8 5706 java_layout_seen_class_methods ();
23a79c61 5707 java_parse_abort_on_error ();
e04a16fb
AG
5708}
5709
5710/* Expand all methods in all registered classes. */
5711
5712void
5713java_complete_expand_methods ()
5714{
5715 tree current;
ce6e9147
APB
5716
5717 do_not_fold = flag_emit_xref;
e04a16fb
AG
5718
5719 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5720 {
7f1d4866 5721 int is_interface;
e04a16fb
AG
5722 tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
5723 tree decl;
e04a16fb
AG
5724
5725 current_class = TREE_TYPE (current);
7f1d4866 5726 is_interface = CLASS_INTERFACE (TYPE_NAME (current_class));
e04a16fb
AG
5727
5728 /* Initialize a new constant pool */
5729 init_outgoing_cpool ();
5730
7525cc04
APB
5731 /* We want <clinit> (if any) to be processed first. */
5732 decl = tree_last (TYPE_METHODS (class_type));
7f1d4866 5733 if (IS_CLINIT (decl))
7525cc04 5734 {
cd9643f7
PB
5735 tree fbody = DECL_FUNCTION_BODY (decl);
5736 tree list;
5737 if (fbody != NULL_TREE)
5738 {
5739 /* First check if we can ignore empty <clinit> */
5740 tree block_body = BLOCK_EXPR_BODY (fbody);
5741
5742 current_this = NULL_TREE;
5743 current_function_decl = decl;
5744 if (block_body != NULL_TREE)
5745 {
5746 /* Prevent the use of `this' inside <clinit> */
5747 ctxp->explicit_constructor_p = 1;
5748
5749 block_body = java_complete_tree (block_body);
5750 ctxp->explicit_constructor_p = 0;
5751 BLOCK_EXPR_BODY (fbody) = block_body;
5752 if (block_body != NULL_TREE
5753 && TREE_CODE (block_body) == BLOCK
5754 && BLOCK_EXPR_BODY (block_body) == empty_stmt_node)
5755 decl = NULL_TREE;
5756 }
5757 }
5758 list = nreverse (TREE_CHAIN (nreverse (TYPE_METHODS (class_type))));
5759 if (decl != NULL_TREE)
5760 {
5761 TREE_CHAIN (decl) = list;
5762 TYPE_METHODS (class_type) = decl;
5763 }
5764 else
5765 TYPE_METHODS (class_type) = list;
7525cc04 5766 }
7f1d4866
APB
5767
5768 for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5769 {
7f1d4866
APB
5770 current_function_decl = decl;
5771 /* Don't generate debug info on line zero when expanding a
5772 generated constructor. */
5773 if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl))
5774 {
5775 /* If we found errors, it's too dangerous to try to
5776 generate and expand a constructor */
5777 if (!java_error_count)
5778 {
5779 restore_line_number_status (1);
5780 java_complete_expand_method (decl);
5781 restore_line_number_status (0);
e04a16fb 5782 }
7f1d4866
APB
5783 }
5784 else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
5785 continue;
5786 else
5787 java_complete_expand_method (decl);
5788 }
e04a16fb 5789
22eed1e6
APB
5790 /* Now verify constructor circularity (stop after the first one
5791 we find) */
7f1d4866 5792 if (!is_interface)
22eed1e6
APB
5793 for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5794 if (DECL_CONSTRUCTOR_P (decl) &&
5795 verify_constructor_circularity (decl, decl))
5796 break;
5797
e04a16fb
AG
5798 /* Make the class data, register it and run the rest of decl
5799 compilation on it */
63a212ed
PB
5800 if (!java_error_count)
5801 {
5802 if (flag_emit_class_files)
5803 write_classfile (current_class);
f099f336
APB
5804 if (flag_emit_xref)
5805 expand_xref (current_class);
aabd7048 5806 else if (! flag_syntax_only)
63a212ed
PB
5807 finish_class (current_class);
5808 }
e04a16fb
AG
5809 }
5810}
5811
b9f7e36c
APB
5812/* Hold a list of catch clauses list. The first element of this list is
5813 the list of the catch clauses of the currently analysed try block. */
5814static tree currently_caught_type_list;
5815
e04a16fb
AG
5816/* Complete and expand a method. */
5817
5818static void
5819java_complete_expand_method (mdecl)
5820 tree mdecl;
5821{
22eed1e6
APB
5822 /* Fix constructors before expanding them */
5823 if (DECL_CONSTRUCTOR_P (mdecl))
5824 fix_constructors (mdecl);
e04a16fb 5825
22eed1e6 5826 /* Expand functions that have a body */
e04a16fb
AG
5827 if (DECL_FUNCTION_BODY (mdecl))
5828 {
9bbc7d9f
PB
5829 tree fbody = DECL_FUNCTION_BODY (mdecl);
5830 tree block_body = BLOCK_EXPR_BODY (fbody);
ce6e9147 5831 tree exception_copy;
e04a16fb 5832 expand_start_java_method (mdecl);
939d7216 5833 build_result_decl (mdecl);
e04a16fb
AG
5834
5835 current_this
5836 = (!METHOD_STATIC (mdecl) ?
5837 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
5838
ce6e9147
APB
5839 /* Purge the `throws' list of unchecked exceptions. If we're
5840 doing xref, save a copy of the list and re-install it
5841 later. */
5842 if (flag_emit_xref)
5843 exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
5844
b9f7e36c
APB
5845 purge_unchecked_exceptions (mdecl);
5846
5847 /* Install exceptions thrown with `throws' */
5848 PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
5849
9bbc7d9f 5850 if (block_body != NULL_TREE)
bc3ca41b
PB
5851 {
5852 block_body = java_complete_tree (block_body);
ce6e9147
APB
5853 if (!flag_emit_xref)
5854 check_for_initialization (block_body);
f099f336 5855 ctxp->explicit_constructor_p = 0;
bc3ca41b 5856 }
9bbc7d9f 5857 BLOCK_EXPR_BODY (fbody) = block_body;
5e942c50 5858
9bbc7d9f 5859 if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
ce6e9147
APB
5860 && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
5861 && !flag_emit_xref)
82371d41 5862 missing_return_error (current_function_decl);
7525cc04 5863
939d7216
PB
5864 complete_start_java_method (mdecl);
5865
e04a16fb
AG
5866 /* Don't go any further if we've found error(s) during the
5867 expansion */
5868 if (!java_error_count)
5869 source_end_java_method ();
22eed1e6
APB
5870 else
5871 {
5872 pushdecl_force_head (DECL_ARGUMENTS (mdecl));
5873 poplevel (1, 0, 1);
5874 }
b9f7e36c
APB
5875
5876 /* Pop the exceptions and sanity check */
5877 POP_EXCEPTIONS();
5878 if (currently_caught_type_list)
5879 fatal ("Exception list non empty - java_complete_expand_method");
ce6e9147
APB
5880
5881 if (flag_emit_xref)
5882 DECL_FUNCTION_THROWS (mdecl) = exception_copy;
e04a16fb
AG
5883 }
5884}
5885
22eed1e6
APB
5886/* Craft a body for default constructor. Patch existing constructor
5887 bodies with call to super() and field initialization statements if
5888 necessary. */
5889
5890static void
5891fix_constructors (mdecl)
5892 tree mdecl;
5893{
5894 tree body = DECL_FUNCTION_BODY (mdecl);
22eed1e6 5895
22eed1e6
APB
5896 if (!body)
5897 {
89e09b9a
PB
5898 /* The constructor body must be crafted by hand. It's the
5899 constructor we defined when we realize we didn't have the
5900 CLASSNAME() constructor */
5901
22eed1e6
APB
5902 tree compound;
5903
5904 /* It is an error for the compiler to generate a default
5905 constructor if the superclass doesn't have a constructor that
5906 takes no argument */
5907 if (verify_constructor_super ())
5908 {
5909 tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (current_class));
5910 char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
5911 parse_error_context (lookup_cl (TYPE_NAME (current_class)),
5912 "No constructor matching `%s()' found in "
5913 "class `%s'", n, n);
5914 }
5915
5916 start_artificial_method_body (mdecl);
5917
5918 /* We don't generate a super constructor invocation if we're
5919 compiling java.lang.Object. build_super_invocation takes care
5920 of that. */
5921 compound = java_method_add_stmt (mdecl, build_super_invocation ());
22eed1e6
APB
5922
5923 end_artificial_method_body (mdecl);
5924 }
5925 /* Search for an explicit constructor invocation */
5926 else
5927 {
5928 int found = 0;
5929 tree main_block = BLOCK_EXPR_BODY (body);
5930 tree compound = NULL_TREE;
5931
5932 while (body)
5933 switch (TREE_CODE (body))
5934 {
5935 case CALL_EXPR:
5936 found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
5937 body = NULL_TREE;
5938 break;
5939 case COMPOUND_EXPR:
5940 case EXPR_WITH_FILE_LOCATION:
5941 body = TREE_OPERAND (body, 0);
5942 break;
5943 case BLOCK:
5944 body = BLOCK_EXPR_BODY (body);
5945 break;
5946 default:
5947 found = 0;
5948 body = NULL_TREE;
5949 }
5950 /* The constructor is missing an invocation of super() */
5951 if (!found)
5952 compound = add_stmt_to_compound (compound, NULL_TREE,
5953 build_super_invocation ());
5954
22eed1e6
APB
5955 /* Fix the constructor main block if we're adding extra stmts */
5956 if (compound)
5957 {
5958 compound = add_stmt_to_compound (compound, NULL_TREE,
5959 BLOCK_EXPR_BODY (main_block));
5960 BLOCK_EXPR_BODY (main_block) = compound;
5961 }
5962 }
5963}
5964
5965/* Browse constructors in the super class, searching for a constructor
5966 that doesn't take any argument. Return 0 if one is found, 1
5967 otherwise. */
5968
5969static int
5970verify_constructor_super ()
5971{
5972 tree class = CLASSTYPE_SUPER (current_class);
5973 if (!class)
5974 return 0;
5975
5976 if (class)
5977 {
5978 tree mdecl;
5979 for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
5980 {
5981 if (DECL_CONSTRUCTOR_P (mdecl)
de4c7b02 5982 && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) == end_params_node)
22eed1e6
APB
5983 return 0;
5984 }
5985 }
5986 return 1;
5987}
5988
e04a16fb
AG
5989/* Expand finals. */
5990
5991void
5992java_expand_finals ()
5993{
5994}
5995
22eed1e6 5996/* Generate code for all context remembered for code generation. */
b351b287
APB
5997
5998void
5999java_expand_classes ()
6000{
5423609c 6001 int save_error_count = 0;
23a79c61
APB
6002 java_parse_abort_on_error ();
6003 if (!(ctxp = ctxp_for_generation))
5e942c50
APB
6004 return;
6005 java_layout_classes ();
6006 java_parse_abort_on_error ();
6007
b351b287
APB
6008 for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
6009 {
6010 ctxp = ctxp_for_generation;
6011 lang_init_source (2); /* Error msgs have method prototypes */
6012 java_complete_expand_methods (); /* Complete and expand method bodies */
6013 java_parse_abort_on_error ();
6014 java_expand_finals (); /* Expand and check the finals */
6015 java_parse_abort_on_error ();
6016 java_check_final (); /* Check unitialized final */
6017 java_parse_abort_on_error ();
6018 }
b351b287
APB
6019}
6020
e04a16fb
AG
6021/* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
6022 a tree list node containing RIGHT. Fore coming RIGHTs will be
6023 chained to this hook. LOCATION contains the location of the
6024 separating `.' operator. */
6025
6026static tree
6027make_qualified_primary (primary, right, location)
6028 tree primary, right;
6029 int location;
6030{
6031 tree wfl;
6032
6033 /* We want to process THIS . xxx symbolicaly, to keep it consistent
6034 with the way we're processing SUPER. A THIS from a primary as a
6035 different form than a SUPER. Turn THIS into something symbolic */
b67d701b 6036 if (TREE_CODE (primary) == THIS_EXPR)
e04a16fb 6037 {
9ee9b555 6038 wfl = build_wfl_node (this_identifier_node);
e04a16fb
AG
6039 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
6040 wfl = make_qualified_name (wfl, right, location);
6041 PRIMARY_P (wfl) = 1;
6042 return wfl;
6043 }
6044 /* Other non WFL node are wrapped around a WFL */
6045 else if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
6046 {
6047 wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
6048 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
6049 EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (primary, NULL_TREE);
6050 }
6051 else
6052 {
6053 wfl = primary;
6054 if (!EXPR_WFL_QUALIFICATION (primary))
6055 EXPR_WFL_QUALIFICATION (primary) =
6056 build_tree_list (primary, NULL_TREE);
6057 }
6058
6059 EXPR_WFL_LINECOL (right) = location;
6060 chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
6061 PRIMARY_P (wfl) = 1;
6062 return wfl;
6063}
6064
6065/* Simple merge of two name separated by a `.' */
6066
6067static tree
6068merge_qualified_name (left, right)
6069 tree left, right;
6070{
6071 tree node;
6072 obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
6073 IDENTIFIER_LENGTH (left));
6074 obstack_1grow (&temporary_obstack, '.');
6075 obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
6076 IDENTIFIER_LENGTH (right));
6077 node = get_identifier (obstack_base (&temporary_obstack));
6078 obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
6079 QUALIFIED_P (node) = 1;
6080 return node;
6081}
6082
6083/* Merge the two parts of a qualified name into LEFT. Set the
6084 location information of the resulting node to LOCATION, usually
6085 inherited from the location information of the `.' operator. */
6086
6087static tree
6088make_qualified_name (left, right, location)
6089 tree left, right;
6090 int location;
6091{
bc3ca41b
PB
6092#ifdef USE_COMPONENT_REF
6093 tree node = build (COMPONENT_REF, NULL_TREE, left, right);
6094 EXPR_WFL_LINECOL (node) = location;
6095 return node;
6096#else
e04a16fb
AG
6097 tree left_id = EXPR_WFL_NODE (left);
6098 tree right_id = EXPR_WFL_NODE (right);
6099 tree wfl, merge;
6100
6101 merge = merge_qualified_name (left_id, right_id);
6102
6103 /* Left wasn't qualified and is now qualified */
6104 if (!QUALIFIED_P (left_id))
6105 {
6106 tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
6107 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
6108 EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
6109 }
6110
6111 wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
6112 EXPR_WFL_LINECOL (wfl) = location;
6113 chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
6114
6115 EXPR_WFL_NODE (left) = merge;
6116 return left;
bc3ca41b 6117#endif
e04a16fb
AG
6118}
6119
6120/* Extract the last identifier component of the qualified in WFL. The
6121 last identifier is removed from the linked list */
6122
6123static tree
6124cut_identifier_in_qualified (wfl)
6125 tree wfl;
6126{
6127 tree q;
6128 tree previous = NULL_TREE;
6129 for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
6130 if (!TREE_CHAIN (q))
6131 {
6132 if (!previous)
6133 fatal ("Operating on a non qualified qualified WFL - "
6134 "cut_identifier_in_qualified");
6135 TREE_CHAIN (previous) = NULL_TREE;
6136 return TREE_PURPOSE (q);
6137 }
6138}
6139
6140/* Resolve the expression name NAME. Return its decl. */
6141
6142static tree
5e942c50 6143resolve_expression_name (id, orig)
e04a16fb 6144 tree id;
5e942c50 6145 tree *orig;
e04a16fb
AG
6146{
6147 tree name = EXPR_WFL_NODE (id);
6148 tree decl;
6149
6150 /* 6.5.5.1: Simple expression names */
6151 if (!PRIMARY_P (id) && !QUALIFIED_P (name))
6152 {
6153 /* 15.13.1: NAME can appear within the scope of a local variable
6154 declaration */
6155 if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
6156 return decl;
6157
6158 /* 15.13.1: NAME can appear within a class declaration */
6159 else
6160 {
6161 decl = lookup_field_wrapper (current_class, name);
6162 if (decl)
6163 {
6164 int fs = FIELD_STATIC (decl);
6165 /* Instance variable (8.3.1.1) can't appear within
6166 static method, static initializer or initializer for
6167 a static variable. */
6168 if (!fs && METHOD_STATIC (current_function_decl))
6169 {
7f10c2e2 6170 static_ref_err (id, name, current_class);
e04a16fb
AG
6171 return error_mark_node;
6172 }
22eed1e6
APB
6173 /* Instance variables can't appear as an argument of
6174 an explicit constructor invocation */
6175 if (!fs && ctxp->explicit_constructor_p)
6176 {
6177 parse_error_context
6178 (id, "Can't reference `%s' before the superclass "
6179 "constructor has been called", IDENTIFIER_POINTER (name));
6180 return error_mark_node;
6181 }
5e942c50
APB
6182
6183 /* Otherwise build what it takes to access the field */
e04a16fb 6184 decl = build_field_ref ((fs ? NULL_TREE : current_this),
7f1d4866 6185 DECL_CONTEXT (decl), name);
e8fc7396 6186 if (fs && !flag_emit_class_files && !flag_emit_xref)
7f1d4866 6187 decl = build_class_init (DECL_CONTEXT (decl), decl);
5e942c50
APB
6188 /* We may be asked to save the real field access node */
6189 if (orig)
6190 *orig = decl;
6191 /* And we return what we got */
5b09b33e 6192 return decl;
e04a16fb
AG
6193 }
6194 /* Fall down to error report on undefined variable */
6195 }
6196 }
6197 /* 6.5.5.2 Qualified Expression Names */
6198 else
6199 {
5e942c50
APB
6200 if (orig)
6201 *orig = NULL_TREE;
e04a16fb
AG
6202 qualify_ambiguous_name (id);
6203 /* 15.10.1 Field Access Using a Primary and/or Expression Name */
6204 /* 15.10.2: Accessing Superclass Members using super */
6205 return resolve_field_access (id, NULL, NULL);
6206 }
6207
6208 /* We've got an error here */
6209 parse_error_context (id, "Undefined variable `%s'",
6210 IDENTIFIER_POINTER (name));
6211
6212 return error_mark_node;
6213}
6214
7f10c2e2
APB
6215static void
6216static_ref_err (wfl, field_id, class_type)
6217 tree wfl, field_id, class_type;
6218{
6219 parse_error_context
6220 (wfl,
6221 "Can't make a static reference to nonstatic variable `%s' in class `%s'",
6222 IDENTIFIER_POINTER (field_id),
6223 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
6224}
6225
e04a16fb
AG
6226/* 15.10.1 Field Acess Using a Primary and/or Expression Name.
6227 We return something suitable to generate the field access. We also
6228 return the field decl in FIELD_DECL and its type in FIELD_TYPE. If
6229 recipient's address can be null. */
6230
6231static tree
6232resolve_field_access (qual_wfl, field_decl, field_type)
6233 tree qual_wfl;
6234 tree *field_decl, *field_type;
6235{
6236 int is_static = 0;
6237 tree field_ref;
6238 tree decl, where_found, type_found;
6239
6240 if (resolve_qualified_expression_name (qual_wfl, &decl,
6241 &where_found, &type_found))
6242 return error_mark_node;
6243
6244 /* Resolve the LENGTH field of an array here */
6245 if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
e8fc7396 6246 && ! flag_emit_class_files && ! flag_emit_xref)
e04a16fb
AG
6247 {
6248 tree length = build_java_array_length_access (where_found);
6249 field_ref =
6250 build_java_arraynull_check (type_found, length, int_type_node);
6251 }
6252 /* We might have been trying to resolve field.method(). In which
6253 case, the resolution is over and decl is the answer */
34f4db93 6254 else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
e04a16fb 6255 field_ref = decl;
34f4db93 6256 else if (JDECL_P (decl))
e04a16fb 6257 {
5e942c50
APB
6258 int static_final_found = 0;
6259 if (!type_found)
6260 type_found = DECL_CONTEXT (decl);
34f4db93 6261 is_static = JDECL_P (decl) && FIELD_STATIC (decl);
5e942c50
APB
6262 if (FIELD_FINAL (decl)
6263 && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
6264 && DECL_LANG_SPECIFIC (decl)
7525cc04 6265 && DECL_INITIAL (decl))
5e942c50 6266 {
7525cc04 6267 field_ref = DECL_INITIAL (decl);
5e942c50
APB
6268 static_final_found = 1;
6269 }
6270 else
7f10c2e2
APB
6271 field_ref = build_field_ref ((is_static && !flag_emit_xref?
6272 NULL_TREE : where_found),
5e942c50 6273 type_found, DECL_NAME (decl));
e04a16fb
AG
6274 if (field_ref == error_mark_node)
6275 return error_mark_node;
e8fc7396
APB
6276 if (is_static && !static_final_found
6277 && !flag_emit_class_files && !flag_emit_xref)
e04a16fb
AG
6278 {
6279 field_ref = build_class_init (type_found, field_ref);
6280 /* If the static field was identified by an expression that
6281 needs to be generated, make the field access a compound
7f10c2e2 6282 expression whose first part is the evaluation of the
e04a16fb 6283 field selector part. */
c877974e
APB
6284 if (where_found && TREE_CODE (where_found) != TYPE_DECL
6285 && TREE_CODE (where_found) != RECORD_TYPE)
e04a16fb
AG
6286 {
6287 tree type = QUAL_DECL_TYPE (field_ref);
6288 field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
6289 }
6290 }
6291 }
6292 else
6293 field_ref = decl;
6294
6295 if (field_decl)
6296 *field_decl = decl;
6297 if (field_type)
c877974e
APB
6298 *field_type = (QUAL_DECL_TYPE (decl) ?
6299 QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
e04a16fb
AG
6300 return field_ref;
6301}
6302
e28cd97b
APB
6303/* If NODE is an access to f static field, strip out the class
6304 initialization part and return the field decl, otherwise, return
6305 NODE. */
6306
6307static tree
6308strip_out_static_field_access_decl (node)
6309 tree node;
6310{
6311 if (TREE_CODE (node) == COMPOUND_EXPR)
6312 {
6313 tree op1 = TREE_OPERAND (node, 1);
6314 if (TREE_CODE (op1) == COMPOUND_EXPR)
6315 {
6316 tree call = TREE_OPERAND (op1, 0);
6317 if (TREE_CODE (call) == CALL_EXPR
6318 && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
6319 && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
6320 == soft_initclass_node)
6321 return TREE_OPERAND (op1, 1);
6322 }
6323 }
6324 return node;
6325}
6326
e04a16fb
AG
6327/* 6.5.5.2: Qualified Expression Names */
6328
6329static int
6330resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
6331 tree wfl;
6332 tree *found_decl, *type_found, *where_found;
6333{
6334 int from_type = 0; /* Field search initiated from a type */
6335 int from_super = 0, from_cast = 0;
6336 int previous_call_static = 0;
6337 int is_static;
6338 tree decl = NULL_TREE, type = NULL_TREE, q;
c877974e 6339 *type_found = *where_found = NULL_TREE;
e04a16fb
AG
6340
6341 for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
6342 {
6343 tree qual_wfl = QUAL_WFL (q);
6344
6345 /* 15.10.1 Field Access Using a Primary */
e04a16fb
AG
6346 switch (TREE_CODE (qual_wfl))
6347 {
6348 case CALL_EXPR:
b67d701b 6349 case NEW_CLASS_EXPR:
e04a16fb
AG
6350 /* If the access to the function call is a non static field,
6351 build the code to access it. */
34f4db93 6352 if (JDECL_P (decl) && !FIELD_STATIC (decl))
e04a16fb 6353 {
ac825856
APB
6354 decl = maybe_access_field (decl, *where_found,
6355 DECL_CONTEXT (decl));
e04a16fb
AG
6356 if (decl == error_mark_node)
6357 return 1;
6358 }
6359 /* And code for the function call */
6360 if (complete_function_arguments (qual_wfl))
6361 return 1;
89e09b9a
PB
6362 if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
6363 CALL_USING_SUPER (qual_wfl) = 1;
e04a16fb 6364 *where_found =
89e09b9a 6365 patch_method_invocation (qual_wfl, decl, type, &is_static, NULL);
e04a16fb
AG
6366 if (*where_found == error_mark_node)
6367 return 1;
6368 *type_found = type = QUAL_DECL_TYPE (*where_found);
6369
6370 /* If the previous call was static and this one is too,
6371 build a compound expression to hold the two (because in
6372 that case, previous function calls aren't transported as
6373 forcoming function's argument. */
6374 if (previous_call_static && is_static)
6375 {
6376 decl = build (COMPOUND_EXPR, type, decl, *where_found);
6377 TREE_SIDE_EFFECTS (decl) = 1;
6378 }
6379 else
6380 {
6381 previous_call_static = is_static;
6382 decl = *where_found;
6383 }
6384 continue;
6385
d8fccff5
APB
6386 case NEW_ARRAY_EXPR:
6387 *where_found = decl = java_complete_tree (qual_wfl);
6388 if (decl == error_mark_node)
6389 return 1;
6390 *type_found = type = QUAL_DECL_TYPE (decl);
6391 CLASS_LOADED_P (type) = 1;
6392 continue;
6393
e04a16fb
AG
6394 case CONVERT_EXPR:
6395 *where_found = decl = java_complete_tree (qual_wfl);
6396 if (decl == error_mark_node)
6397 return 1;
6398 *type_found = type = QUAL_DECL_TYPE (decl);
6399 from_cast = 1;
6400 continue;
6401
22eed1e6 6402 case CONDITIONAL_EXPR:
5e942c50 6403 case STRING_CST:
22eed1e6
APB
6404 *where_found = decl = java_complete_tree (qual_wfl);
6405 if (decl == error_mark_node)
6406 return 1;
6407 *type_found = type = QUAL_DECL_TYPE (decl);
6408 continue;
6409
e04a16fb
AG
6410 case ARRAY_REF:
6411 /* If the access to the function call is a non static field,
6412 build the code to access it. */
34f4db93 6413 if (JDECL_P (decl) && !FIELD_STATIC (decl))
e04a16fb
AG
6414 {
6415 decl = maybe_access_field (decl, *where_found, type);
6416 if (decl == error_mark_node)
6417 return 1;
6418 }
6419 /* And code for the array reference expression */
6420 decl = java_complete_tree (qual_wfl);
6421 if (decl == error_mark_node)
6422 return 1;
6423 type = QUAL_DECL_TYPE (decl);
6424 continue;
0a2138e2
APB
6425
6426 default:
6427 /* Fix for -Wall Just go to the next statement. Don't
6428 continue */
a3f406ce 6429 break;
e04a16fb
AG
6430 }
6431
6432 /* If we fall here, we weren't processing a (static) function call. */
6433 previous_call_static = 0;
6434
6435 /* It can be the keyword THIS */
6436 if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
6437 {
6438 if (!current_this)
6439 {
6440 parse_error_context
6441 (wfl, "Keyword `this' used outside allowed context");
6442 return 1;
6443 }
6444 /* We have to generate code for intermediate acess */
6445 *where_found = decl = current_this;
5e942c50 6446 *type_found = type = QUAL_DECL_TYPE (decl);
e04a16fb
AG
6447 continue;
6448 }
6449
6450 /* 15.10.2 Accessing Superclass Members using SUPER */
6451 if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
6452 {
6453 tree node;
6454 /* Check on the restricted use of SUPER */
6455 if (METHOD_STATIC (current_function_decl)
6456 || current_class == object_type_node)
6457 {
6458 parse_error_context
6459 (wfl, "Keyword `super' used outside allowed context");
6460 return 1;
6461 }
6462 /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
6463 node = build_cast (EXPR_WFL_LINECOL (qual_wfl),
6464 CLASSTYPE_SUPER (current_class),
6465 build_this (EXPR_WFL_LINECOL (qual_wfl)));
6466 *where_found = decl = java_complete_tree (node);
22eed1e6
APB
6467 if (decl == error_mark_node)
6468 return 1;
e04a16fb
AG
6469 *type_found = type = QUAL_DECL_TYPE (decl);
6470 from_super = from_type = 1;
6471 continue;
6472 }
6473
6474 /* 15.13.1: Can't search for field name in packages, so we
6475 assume a variable/class name was meant. */
6476 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
6477 {
5e942c50
APB
6478 tree name = resolve_package (wfl, &q);
6479 if (name)
6480 {
6481 *where_found = decl = resolve_no_layout (name, qual_wfl);
6482 /* We wan't to be absolutely that the class is laid
6483 out. We're going to search something inside it. */
6484 *type_found = type = TREE_TYPE (decl);
6485 layout_class (type);
6486 from_type = 1;
6487 /* Should be a list, really. FIXME */
6488 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 1;
6489 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 0;
6490 }
e04a16fb 6491 else
5e942c50
APB
6492 {
6493 if (from_super || from_cast)
6494 parse_error_context
6495 ((from_cast ? qual_wfl : wfl),
6496 "No variable `%s' defined in class `%s'",
6497 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
6498 lang_printable_name (type, 0));
6499 else
6500 parse_error_context
6501 (qual_wfl, "Undefined variable or class name: `%s'",
6502 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
6503 return 1;
6504 }
e04a16fb
AG
6505 }
6506
6507 /* We have a type name. It's been already resolved when the
6508 expression was qualified. */
6509 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
6510 {
6511 if (!(decl = QUAL_RESOLUTION (q)))
6512 return 1; /* Error reported already */
6513
6514 if (not_accessible_p (TREE_TYPE (decl), decl, 0))
6515 {
6516 parse_error_context
6517 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
6518 java_accstring_lookup (get_access_flags_from_decl (decl)),
2aa11e97 6519 GET_TYPE_NAME (type),
e04a16fb
AG
6520 IDENTIFIER_POINTER (DECL_NAME (decl)),
6521 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
6522 return 1;
6523 }
5e942c50 6524 check_deprecation (qual_wfl, decl);
e04a16fb
AG
6525
6526 type = TREE_TYPE (decl);
6527 from_type = 1;
6528 }
6529 /* We resolve and expression name */
6530 else
6531 {
6532 tree field_decl;
6533
6534 /* If there exists an early resolution, use it. That occurs
6535 only once and we know that there are more things to
6536 come. Don't do that when processing something after SUPER
6537 (we need more thing to be put in place below */
6538 if (!from_super && QUAL_RESOLUTION (q))
b67d701b
PB
6539 {
6540 decl = QUAL_RESOLUTION (q);
c877974e 6541 if (!type)
5e942c50 6542 {
7f10c2e2
APB
6543 if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
6544 {
6545 if (current_this)
6546 *where_found = current_this;
6547 else
6548 {
6549 static_ref_err (qual_wfl, DECL_NAME (decl),
6550 current_class);
6551 return 1;
6552 }
6553 }
c877974e
APB
6554 else
6555 {
6556 *where_found = TREE_TYPE (decl);
6557 if (TREE_CODE (*where_found) == POINTER_TYPE)
6558 *where_found = TREE_TYPE (*where_found);
6559 }
5e942c50 6560 }
b67d701b 6561 }
e04a16fb
AG
6562
6563 /* We have to search for a field, knowing the type of its
6564 container. The flag FROM_TYPE indicates that we resolved
6565 the last member of the expression as a type name, which
5e942c50
APB
6566 means that for the resolution of this field, we'll look
6567 for other errors than if it was resolved as a member of
6568 an other field. */
e04a16fb
AG
6569 else
6570 {
6571 int is_static;
5e942c50
APB
6572 tree field_decl_type; /* For layout */
6573
e04a16fb
AG
6574 if (!from_type && !JREFERENCE_TYPE_P (type))
6575 {
6576 parse_error_context
6577 (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
6578 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
0a2138e2 6579 lang_printable_name (type, 0),
e04a16fb
AG
6580 IDENTIFIER_POINTER (DECL_NAME (field_decl)));
6581 return 1;
6582 }
6583
dc0b3eff
PB
6584 field_decl = lookup_field_wrapper (type,
6585 EXPR_WFL_NODE (qual_wfl));
6586 if (field_decl == NULL_TREE)
e04a16fb
AG
6587 {
6588 parse_error_context
2aa11e97 6589 (qual_wfl, "No variable `%s' defined in type `%s'",
e04a16fb 6590 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
2aa11e97 6591 GET_TYPE_NAME (type));
e04a16fb
AG
6592 return 1;
6593 }
dc0b3eff
PB
6594 if (field_decl == error_mark_node)
6595 return 1;
5e942c50
APB
6596
6597 /* Layout the type of field_decl, since we may need
c877974e
APB
6598 it. Don't do primitive types or loaded classes. The
6599 situation of non primitive arrays may not handled
6600 properly here. FIXME */
5e942c50
APB
6601 if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
6602 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
6603 else
6604 field_decl_type = TREE_TYPE (field_decl);
6605 if (!JPRIMITIVE_TYPE_P (field_decl_type)
c877974e
APB
6606 && !CLASS_LOADED_P (field_decl_type)
6607 && !TYPE_ARRAY_P (field_decl_type))
6608 resolve_and_layout (field_decl_type, NULL_TREE);
6609 if (TYPE_ARRAY_P (field_decl_type))
6610 CLASS_LOADED_P (field_decl_type) = 1;
e04a16fb
AG
6611
6612 /* Check on accessibility here */
6613 if (not_accessible_p (type, field_decl, from_super))
6614 {
6615 parse_error_context
6616 (qual_wfl,
6617 "Can't access %s field `%s.%s' from `%s'",
6618 java_accstring_lookup
6619 (get_access_flags_from_decl (field_decl)),
2aa11e97 6620 GET_TYPE_NAME (type),
e04a16fb
AG
6621 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
6622 IDENTIFIER_POINTER
6623 (DECL_NAME (TYPE_NAME (current_class))));
6624 return 1;
6625 }
5e942c50 6626 check_deprecation (qual_wfl, field_decl);
e04a16fb
AG
6627
6628 /* There are things to check when fields are accessed
6629 from type. There are no restrictions on a static
6630 declaration of the field when it is accessed from an
6631 interface */
6632 is_static = FIELD_STATIC (field_decl);
6633 if (!from_super && from_type
6634 && !TYPE_INTERFACE_P (type) && !is_static)
6635 {
7f10c2e2 6636 static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
e04a16fb
AG
6637 return 1;
6638 }
6639 from_cast = from_super = 0;
6640
5e942c50
APB
6641 /* If we need to generate something to get a proper
6642 handle on what this field is accessed from, do it
6643 now. */
e04a16fb
AG
6644 if (!is_static)
6645 {
c583dd46 6646 decl = maybe_access_field (decl, *where_found, *type_found);
e04a16fb
AG
6647 if (decl == error_mark_node)
6648 return 1;
6649 }
6650
6651 /* We want to keep the location were found it, and the type
6652 we found. */
6653 *where_found = decl;
6654 *type_found = type;
6655
6656 /* This is the decl found and eventually the next one to
6657 search from */
6658 decl = field_decl;
6659 }
e04a16fb
AG
6660 from_type = 0;
6661 type = QUAL_DECL_TYPE (decl);
6662 }
6663 }
6664 *found_decl = decl;
6665 return 0;
6666}
6667
6668/* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
6669 can't be accessed from REFERENCE (a record type). */
6670
6671int not_accessible_p (reference, member, from_super)
6672 tree reference, member;
6673 int from_super;
6674{
6675 int access_flag = get_access_flags_from_decl (member);
6676
6677 /* Access always granted for members declared public */
6678 if (access_flag & ACC_PUBLIC)
6679 return 0;
6680
6681 /* Check access on protected members */
6682 if (access_flag & ACC_PROTECTED)
6683 {
6684 /* Access granted if it occurs from within the package
6685 containing the class in which the protected member is
6686 declared */
6687 if (class_in_current_package (DECL_CONTEXT (member)))
6688 return 0;
6689
9bbc7d9f
PB
6690 /* If accessed with the form `super.member', then access is granted */
6691 if (from_super)
6692 return 0;
e04a16fb 6693
9bbc7d9f
PB
6694 /* Otherwise, access is granted if occuring from the class where
6695 member is declared or a subclass of it */
6696 if (inherits_from_p (reference, current_class))
6697 return 0;
e04a16fb
AG
6698 return 1;
6699 }
6700
6701 /* Check access on private members. Access is granted only if it
c877974e 6702 occurs from within the class in witch it is declared */
e04a16fb
AG
6703 if (access_flag & ACC_PRIVATE)
6704 return (current_class == DECL_CONTEXT (member) ? 0 : 1);
6705
6706 /* Default access are permitted only when occuring within the
6707 package in which the type (REFERENCE) is declared. In other words,
6708 REFERENCE is defined in the current package */
6709 if (ctxp->package)
6710 return !class_in_current_package (reference);
6711
6712 /* Otherwise, access is granted */
6713 return 0;
6714}
6715
5e942c50
APB
6716/* Test deprecated decl access. */
6717static void
6718check_deprecation (wfl, decl)
6719 tree wfl, decl;
6720{
6721 char *file = DECL_SOURCE_FILE (decl);
6722 /* Complain if the field is deprecated and the file it was defined
6723 in isn't compiled at the same time the file which contains its
6724 use is */
6725 if (DECL_DEPRECATED (decl)
6726 && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
6727 {
6728 char the [20];
6729 switch (TREE_CODE (decl))
6730 {
6731 case FUNCTION_DECL:
6732 strcpy (the, "method");
6733 break;
6734 case FIELD_DECL:
6735 strcpy (the, "field");
6736 break;
6737 case TYPE_DECL:
6738 strcpy (the, "class");
6739 break;
15fdcfe9
PB
6740 default:
6741 fatal ("unexpected DECL code - check_deprecation");
5e942c50
APB
6742 }
6743 parse_warning_context
6744 (wfl, "The %s `%s' in class `%s' has been deprecated",
6745 the, lang_printable_name (decl, 0),
6746 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
6747 }
6748}
6749
e04a16fb
AG
6750/* Returns 1 if class was declared in the current package, 0 otherwise */
6751
6752static int
6753class_in_current_package (class)
6754 tree class;
6755{
6756 static tree cache = NULL_TREE;
6757 int qualified_flag;
6758 tree left;
6759
6760 if (cache == class)
6761 return 1;
6762
6763 qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
6764
6765 /* If the current package is empty and the name of CLASS is
6766 qualified, class isn't in the current package. If there is a
6767 current package and the name of the CLASS is not qualified, class
6768 isn't in the current package */
0a2138e2 6769 if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
e04a16fb
AG
6770 return 0;
6771
6772 /* If there is not package and the name of CLASS isn't qualified,
6773 they belong to the same unnamed package */
6774 if (!ctxp->package && !qualified_flag)
6775 return 1;
6776
6777 /* Compare the left part of the name of CLASS with the package name */
6778 breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
6779 if (ctxp->package == left)
6780 {
6781 cache = class;
6782 return 1;
6783 }
6784 return 0;
6785}
6786
6787/* This function may generate code to access DECL from WHERE. This is
6788 done only if certain conditions meet. */
6789
6790static tree
6791maybe_access_field (decl, where, type)
6792 tree decl, where, type;
6793{
5e942c50
APB
6794 if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
6795 && !FIELD_STATIC (decl))
e04a16fb 6796 decl = build_field_ref (where ? where : current_this,
c583dd46
APB
6797 (type ? type : DECL_CONTEXT (decl)),
6798 DECL_NAME (decl));
e04a16fb
AG
6799 return decl;
6800}
6801
15fdcfe9 6802/* Build a method invocation, by patching PATCH. If non NULL
e04a16fb
AG
6803 and according to the situation, PRIMARY and WHERE may be
6804 used. IS_STATIC is set to 1 if the invoked function is static. */
6805
6806static tree
89e09b9a 6807patch_method_invocation (patch, primary, where, is_static, ret_decl)
e04a16fb
AG
6808 tree patch, primary, where;
6809 int *is_static;
b9f7e36c 6810 tree *ret_decl;
e04a16fb
AG
6811{
6812 tree wfl = TREE_OPERAND (patch, 0);
6813 tree args = TREE_OPERAND (patch, 1);
6814 tree name = EXPR_WFL_NODE (wfl);
5e942c50 6815 tree list;
22eed1e6 6816 int is_static_flag = 0;
89e09b9a 6817 int is_super_init = 0;
bccaf73a 6818 tree this_arg = NULL_TREE;
e04a16fb
AG
6819
6820 /* Should be overriden if everything goes well. Otherwise, if
6821 something fails, it should keep this value. It stop the
6822 evaluation of a bogus assignment. See java_complete_tree,
6823 MODIFY_EXPR: for the reasons why we sometimes want to keep on
6824 evaluating an assignment */
6825 TREE_TYPE (patch) = error_mark_node;
6826
6827 /* Since lookup functions are messing with line numbers, save the
6828 context now. */
6829 java_parser_context_save_global ();
6830
6831 /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
6832
6833 /* Resolution of qualified name, excluding constructors */
6834 if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
6835 {
6836 tree class_decl, identifier, identifier_wfl;
6837 /* Extract the last IDENTIFIER of the qualified
6838 expression. This is a wfl and we will use it's location
6839 data during error report. */
6840 identifier_wfl = cut_identifier_in_qualified (wfl);
6841 identifier = EXPR_WFL_NODE (identifier_wfl);
6842
6843 /* Given the context, IDENTIFIER is syntactically qualified
6844 as a MethodName. We need to qualify what's before */
6845 qualify_ambiguous_name (wfl);
6846
6847 /* Package resolution are erroneous */
6848 if (RESOLVE_PACKAGE_NAME_P (wfl))
6849 {
6850 tree remainder;
6851 breakdown_qualified (&remainder, NULL, EXPR_WFL_NODE (wfl));
6852 parse_error_context (wfl, "Can't search method `%s' in package "
6853 "`%s'",IDENTIFIER_POINTER (identifier),
6854 IDENTIFIER_POINTER (remainder));
b9f7e36c 6855 PATCH_METHOD_RETURN_ERROR ();
e04a16fb
AG
6856 }
6857 /* We're resolving a call from a type */
6858 else if (RESOLVE_TYPE_NAME_P (wfl))
6859 {
6860 tree decl = QUAL_RESOLUTION (EXPR_WFL_QUALIFICATION (wfl));
6861 tree name = DECL_NAME (decl);
6862 tree type;
6863
6864 class_decl = resolve_and_layout (name, wfl);
6865 if (CLASS_INTERFACE (decl))
6866 {
6867 parse_error_context
6868 (identifier_wfl, "Can't make static reference to method "
6869 "`%s' in interface `%s'", IDENTIFIER_POINTER (identifier),
6870 IDENTIFIER_POINTER (name));
b9f7e36c 6871 PATCH_METHOD_RETURN_ERROR ();
e04a16fb
AG
6872 }
6873 /* Look the method up in the type selector. The method ought
6874 to be static. */
6875 type = TREE_TYPE (class_decl);
6876 list = lookup_method_invoke (0, wfl, type, identifier, args);
6877 if (list && !METHOD_STATIC (list))
6878 {
0a2138e2 6879 char *fct_name = strdup (lang_printable_name (list, 0));
e04a16fb
AG
6880 parse_error_context
6881 (identifier_wfl,
6882 "Can't make static reference to method `%s %s' in class `%s'",
0a2138e2
APB
6883 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
6884 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
e04a16fb 6885 free (fct_name);
b9f7e36c 6886 PATCH_METHOD_RETURN_ERROR ();
e04a16fb 6887 }
5e942c50 6888 args = nreverse (args);
e04a16fb
AG
6889 }
6890 /* We're resolving an expression name */
6891 else
6892 {
6893 tree field, type;
6894
6895 /* 1- Find the field to which the call applies */
6896 field = resolve_field_access (wfl, NULL, &type);
6897 if (field == error_mark_node)
b9f7e36c 6898 PATCH_METHOD_RETURN_ERROR ();
c3f2a476
APB
6899 /* field is used in lieu of a primary. It alows us not to
6900 report errors on erroneous use of `this' in
6901 constructors. */
6902 primary = field;
e04a16fb
AG
6903
6904 /* 2- Do the layout of the class where the last field
6905 was found, so we can search it. */
c877974e 6906 class_decl = resolve_and_layout (type, NULL_TREE);
3e78f871 6907 if (class_decl != NULL_TREE)
c877974e
APB
6908 type = TREE_TYPE (class_decl);
6909
e04a16fb
AG
6910 /* 3- Retrieve a filtered list of method matches, Refine
6911 if necessary. In any cases, point out errors. */
6912 list = lookup_method_invoke (0, identifier_wfl, type,
6913 identifier, args);
6914
6915 /* 4- Add the field as an argument */
bccaf73a
PB
6916 args = nreverse (args);
6917 this_arg = field;
e04a16fb
AG
6918 }
6919
5e942c50 6920 /* IDENTIFIER_WFL will be used to report any problem further */
e04a16fb
AG
6921 wfl = identifier_wfl;
6922 }
6923 /* Resolution of simple names, names generated after a primary: or
6924 constructors */
6925 else
6926 {
6927 tree class_to_search;
6928 int lc; /* Looking for Constructor */
6929
6930 /* We search constructor in their target class */
6931 if (CALL_CONSTRUCTOR_P (patch))
6932 {
22eed1e6
APB
6933 if (TREE_CODE (patch) == NEW_CLASS_EXPR)
6934 class_to_search = EXPR_WFL_NODE (wfl);
6935 else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
6936 this_identifier_node)
6937 class_to_search = NULL_TREE;
6938 else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
6939 super_identifier_node)
e04a16fb 6940 {
89e09b9a 6941 is_super_init = 1;
22eed1e6
APB
6942 if (CLASSTYPE_SUPER (current_class))
6943 class_to_search =
6944 DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
6945 else
6946 {
6947 parse_error_context (wfl, "Can't invoke super constructor "
6948 "on java.lang.Object");
6949 PATCH_METHOD_RETURN_ERROR ();
6950 }
e04a16fb 6951 }
22eed1e6
APB
6952
6953 /* Class to search is NULL if we're searching the current one */
6954 if (class_to_search)
e04a16fb 6955 {
23a79c61
APB
6956 class_to_search = resolve_and_layout (class_to_search,
6957 NULL_TREE);
22eed1e6
APB
6958 if (!class_to_search)
6959 {
6960 parse_error_context
6961 (wfl, "Class `%s' not found in type declaration",
6962 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
6963 PATCH_METHOD_RETURN_ERROR ();
6964 }
6965
5e942c50
APB
6966 /* Can't instantiate an abstract class, but we can
6967 invoke it's constructor. It's use within the `new'
6968 context is denied here. */
6969 if (CLASS_ABSTRACT (class_to_search)
6970 && TREE_CODE (patch) == NEW_CLASS_EXPR)
22eed1e6
APB
6971 {
6972 parse_error_context
6973 (wfl, "Class `%s' is an abstract class. It can't be "
6974 "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
6975 PATCH_METHOD_RETURN_ERROR ();
6976 }
6977 class_to_search = TREE_TYPE (class_to_search);
e04a16fb 6978 }
22eed1e6
APB
6979 else
6980 class_to_search = current_class;
e04a16fb
AG
6981 lc = 1;
6982 }
6983 /* This is a regular search in the local class, unless an
6984 alternate class is specified. */
6985 else
6986 {
6987 class_to_search = (where ? where : current_class);
6988 lc = 0;
6989 }
6990
6991 /* NAME is a simple identifier or comes from a primary. Search
6992 in the class whose declaration contain the method being
6993 invoked. */
c877974e 6994 resolve_and_layout (class_to_search, NULL_TREE);
e04a16fb
AG
6995 list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
6996
6997 /* Don't continue if no method were found, as the next statement
6998 can't be executed then. */
b9f7e36c
APB
6999 if (!list)
7000 PATCH_METHOD_RETURN_ERROR ();
e04a16fb
AG
7001
7002 /* Check for static reference if non static methods */
7003 if (check_for_static_method_reference (wfl, patch, list,
7004 class_to_search, primary))
b9f7e36c 7005 PATCH_METHOD_RETURN_ERROR ();
e04a16fb 7006
22eed1e6
APB
7007 /* Non static methods are called with the current object extra
7008 argument. If patch a `new TYPE()', the argument is the value
7009 returned by the object allocator. If method is resolved as a
7010 primary, use the primary otherwise use the current THIS. */
b9f7e36c 7011 args = nreverse (args);
bccaf73a
PB
7012 if (TREE_CODE (patch) != NEW_CLASS_EXPR)
7013 this_arg = primary ? primary : current_this;
e04a16fb 7014 }
b67d701b 7015
e04a16fb
AG
7016 /* Merge point of all resolution schemes. If we have nothing, this
7017 is an error, already signaled */
b9f7e36c
APB
7018 if (!list)
7019 PATCH_METHOD_RETURN_ERROR ();
b67d701b 7020
e04a16fb
AG
7021 /* Check accessibility, position the is_static flag, build and
7022 return the call */
9bbc7d9f 7023 if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
e04a16fb 7024 {
0a2138e2 7025 char *fct_name = strdup (lang_printable_name (list, 0));
e04a16fb
AG
7026 parse_error_context
7027 (wfl, "Can't access %s method `%s %s.%s' from `%s'",
7028 java_accstring_lookup (get_access_flags_from_decl (list)),
0a2138e2 7029 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
5e942c50
APB
7030 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))),
7031 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
e04a16fb 7032 free (fct_name);
b9f7e36c 7033 PATCH_METHOD_RETURN_ERROR ();
e04a16fb 7034 }
5e942c50 7035 check_deprecation (wfl, list);
22eed1e6
APB
7036
7037 is_static_flag = METHOD_STATIC (list);
bccaf73a
PB
7038 if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
7039 args = tree_cons (NULL_TREE, this_arg, args);
22eed1e6 7040
c3f2a476
APB
7041 /* In the context of an explicit constructor invocation, we can't
7042 invoke any method relying on `this'. Exceptions are: we're
7043 invoking a static function, primary exists and is not the current
7044 this, we're creating a new object. */
22eed1e6 7045 if (ctxp->explicit_constructor_p
c3f2a476
APB
7046 && !is_static_flag
7047 && (!primary || primary == current_this)
7048 && (TREE_CODE (patch) != NEW_CLASS_EXPR))
22eed1e6
APB
7049 {
7050 parse_error_context
7051 (wfl, "Can't reference `this' before the superclass constructor has "
7052 "been called");
7053 PATCH_METHOD_RETURN_ERROR ();
7054 }
e04a16fb 7055 java_parser_context_restore_global ();
22eed1e6
APB
7056 if (is_static)
7057 *is_static = is_static_flag;
b9f7e36c
APB
7058 /* Sometimes, we want the decl of the selected method. Such as for
7059 EH checking */
7060 if (ret_decl)
7061 *ret_decl = list;
89e09b9a
PB
7062 patch = patch_invoke (patch, list, args);
7063 if (is_super_init && CLASS_HAS_FINIT_P (current_class))
7064 {
7065 /* Generate the code used to initialize fields declared with an
7066 initialization statement. For now, it returns a call the the
7067 artificial function $finit$, if required. */
7068
7069 tree finit_call =
7070 build_method_invocation (build_expr_wfl (finit_identifier_node,
7071 input_filename, 0, 0),
7072 NULL_TREE);
7073 patch = build (COMPOUND_EXPR, void_type_node, patch,
7074 java_complete_tree (finit_call));
7075 CAN_COMPLETE_NORMALLY (patch) = 1;
7076 }
7077 return patch;
e04a16fb
AG
7078}
7079
7080/* Check that we're not trying to do a static reference to a method in
7081 non static method. Return 1 if it's the case, 0 otherwise. */
7082
7083static int
7084check_for_static_method_reference (wfl, node, method, where, primary)
7085 tree wfl, node, method, where, primary;
7086{
7087 if (METHOD_STATIC (current_function_decl)
7088 && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
7089 {
0a2138e2 7090 char *fct_name = strdup (lang_printable_name (method, 0));
e04a16fb
AG
7091 parse_error_context
7092 (wfl, "Can't make static reference to method `%s %s' in class `%s'",
0a2138e2 7093 lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
e04a16fb
AG
7094 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
7095 free (fct_name);
7096 return 1;
7097 }
7098 return 0;
7099}
7100
7101/* Patch an invoke expression METHOD and ARGS, based on its invocation
7102 mode. */
7103
7104static tree
89e09b9a 7105patch_invoke (patch, method, args)
e04a16fb 7106 tree patch, method, args;
e04a16fb
AG
7107{
7108 tree dtable, func;
0a2138e2 7109 tree original_call, t, ta;
e04a16fb 7110
5e942c50
APB
7111 /* Last step for args: convert build-in types. If we're dealing with
7112 a new TYPE() type call, the first argument to the constructor
7113 isn't found in the incomming argument list, but delivered by
7114 `new' */
7115 t = TYPE_ARG_TYPES (TREE_TYPE (method));
7116 if (TREE_CODE (patch) == NEW_CLASS_EXPR)
7117 t = TREE_CHAIN (t);
ac825856
APB
7118 for (ta = args; t != end_params_node && ta;
7119 t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
b9f7e36c
APB
7120 if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
7121 TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
7122 TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
22eed1e6 7123
e8fc7396 7124 if (flag_emit_class_files || flag_emit_xref)
15fdcfe9
PB
7125 func = method;
7126 else
e04a16fb 7127 {
15fdcfe9 7128 tree signature = build_java_signature (TREE_TYPE (method));
89e09b9a 7129 switch (invocation_mode (method, CALL_USING_SUPER (patch)))
15fdcfe9
PB
7130 {
7131 case INVOKE_VIRTUAL:
7132 dtable = invoke_build_dtable (0, args);
7133 func = build_invokevirtual (dtable, method);
7134 break;
b9f7e36c 7135
15fdcfe9
PB
7136 case INVOKE_SUPER:
7137 case INVOKE_STATIC:
7138 func = build_known_method_ref (method, TREE_TYPE (method),
7139 DECL_CONTEXT (method),
7140 signature, args);
7141 break;
e04a16fb 7142
15fdcfe9
PB
7143 case INVOKE_INTERFACE:
7144 dtable = invoke_build_dtable (1, args);
7145 func = build_invokeinterface (dtable, DECL_NAME (method), signature);
7146 break;
5e942c50 7147
15fdcfe9 7148 default:
89e09b9a 7149 fatal ("internal error - unknown invocation_mode result");
15fdcfe9
PB
7150 }
7151
7152 /* Ensure self_type is initialized, (invokestatic). FIXME */
7153 func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
e04a16fb
AG
7154 }
7155
e04a16fb
AG
7156 TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
7157 TREE_OPERAND (patch, 0) = func;
7158 TREE_OPERAND (patch, 1) = args;
7159 original_call = patch;
7160
22eed1e6
APB
7161 /* We're processing a `new TYPE ()' form. New is called an its
7162 returned value is the first argument to the constructor. We build
7163 a COMPOUND_EXPR and use saved expression so that the overall NEW
7164 expression value is a pointer to a newly created and initialized
7165 class. */
7166 if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
e04a16fb
AG
7167 {
7168 tree class = DECL_CONTEXT (method);
7169 tree c1, saved_new, size, new;
e8fc7396 7170 if (flag_emit_class_files || flag_emit_xref)
15fdcfe9
PB
7171 {
7172 TREE_TYPE (patch) = build_pointer_type (class);
7173 return patch;
7174 }
e04a16fb
AG
7175 if (!TYPE_SIZE (class))
7176 safe_layout_class (class);
7177 size = size_in_bytes (class);
7178 new = build (CALL_EXPR, promote_type (class),
7179 build_address_of (alloc_object_node),
7180 tree_cons (NULL_TREE, build_class_ref (class),
7181 build_tree_list (NULL_TREE,
7182 size_in_bytes (class))),
7183 NULL_TREE);
7184 saved_new = save_expr (new);
7185 c1 = build_tree_list (NULL_TREE, saved_new);
7186 TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
7187 TREE_OPERAND (original_call, 1) = c1;
7188 TREE_SET_CODE (original_call, CALL_EXPR);
7189 patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
7190 }
7191 return patch;
7192}
7193
7194static int
7195invocation_mode (method, super)
7196 tree method;
7197 int super;
7198{
7199 int access = get_access_flags_from_decl (method);
7200
22eed1e6
APB
7201 if (super)
7202 return INVOKE_SUPER;
7203
82371d41 7204 if (access & ACC_STATIC || access & ACC_FINAL || access & ACC_PRIVATE)
e04a16fb
AG
7205 return INVOKE_STATIC;
7206
7207 if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
7208 return INVOKE_STATIC;
7209
e04a16fb
AG
7210 if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
7211 return INVOKE_INTERFACE;
7212
7213 if (DECL_CONSTRUCTOR_P (method))
7214 return INVOKE_STATIC;
22eed1e6 7215
e04a16fb
AG
7216 return INVOKE_VIRTUAL;
7217}
7218
b67d701b
PB
7219/* Retrieve a refined list of matching methods. It covers the step
7220 15.11.2 (Compile-Time Step 2) */
e04a16fb
AG
7221
7222static tree
7223lookup_method_invoke (lc, cl, class, name, arg_list)
7224 int lc;
7225 tree cl;
7226 tree class, name, arg_list;
7227{
de4c7b02 7228 tree atl = end_params_node; /* Arg Type List */
c877974e 7229 tree method, signature, list, node;
b67d701b 7230 char *candidates; /* Used for error report */
e04a16fb 7231
5e942c50 7232 /* Fix the arguments */
e04a16fb
AG
7233 for (node = arg_list; node; node = TREE_CHAIN (node))
7234 {
e3884b71 7235 tree current_arg = TREE_TYPE (TREE_VALUE (node));
c877974e 7236 /* Non primitive type may have to be resolved */
e3884b71 7237 if (!JPRIMITIVE_TYPE_P (current_arg))
c877974e
APB
7238 resolve_and_layout (current_arg, NULL_TREE);
7239 /* And promoted */
b67d701b 7240 if (TREE_CODE (current_arg) == RECORD_TYPE)
c877974e 7241 current_arg = promote_type (current_arg);
5e942c50 7242 atl = tree_cons (NULL_TREE, current_arg, atl);
e04a16fb 7243 }
e04a16fb 7244
5e942c50
APB
7245 /* Find all candidates and then refine the list, searching for the
7246 most specific method. */
7247 list = find_applicable_accessible_methods_list (lc, class, name, atl);
7248 list = find_most_specific_methods_list (list);
b67d701b
PB
7249 if (list && !TREE_CHAIN (list))
7250 return TREE_VALUE (list);
e04a16fb 7251
b67d701b
PB
7252 /* Issue an error. List candidates if any. Candidates are listed
7253 only if accessible (non accessible methods may end-up here for
7254 the sake of a better error report). */
7255 candidates = NULL;
7256 if (list)
e04a16fb 7257 {
e04a16fb 7258 tree current;
b67d701b 7259 obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
e04a16fb
AG
7260 for (current = list; current; current = TREE_CHAIN (current))
7261 {
b67d701b
PB
7262 tree cm = TREE_VALUE (current);
7263 char string [4096];
7264 if (!cm || not_accessible_p (class, cm, 0))
7265 continue;
b67d701b 7266 sprintf
22eed1e6
APB
7267 (string, " `%s' in `%s'%s",
7268 get_printable_method_name (cm),
b67d701b
PB
7269 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
7270 (TREE_CHAIN (current) ? "\n" : ""));
7271 obstack_grow (&temporary_obstack, string, strlen (string));
7272 }
7273 obstack_1grow (&temporary_obstack, '\0');
7274 candidates = obstack_finish (&temporary_obstack);
7275 }
7276 /* Issue the error message */
c877974e
APB
7277 method = make_node (FUNCTION_TYPE);
7278 TYPE_ARG_TYPES (method) = atl;
b67d701b 7279 signature = build_java_argument_signature (method);
22eed1e6
APB
7280 parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
7281 (lc ? "constructor" : "method"),
7282 (lc ?
7283 IDENTIFIER_POINTER(DECL_NAME (TYPE_NAME (class))) :
7284 IDENTIFIER_POINTER (name)),
b67d701b
PB
7285 IDENTIFIER_POINTER (signature),
7286 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))),
7287 (candidates ? candidates : ""));
7288 return NULL_TREE;
7289}
7290
5e942c50
APB
7291/* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
7292 when we're looking for a constructor. */
b67d701b
PB
7293
7294static tree
5e942c50
APB
7295find_applicable_accessible_methods_list (lc, class, name, arglist)
7296 int lc;
b67d701b
PB
7297 tree class, name, arglist;
7298{
b67d701b
PB
7299 tree list = NULL_TREE, all_list = NULL_TREE;
7300
1982388a
APB
7301 /* Search interfaces */
7302 if (CLASS_INTERFACE (TYPE_NAME (class)))
b67d701b 7303 {
de0b553f
APB
7304 static tree searched_interfaces = NULL_TREE;
7305 static int search_not_done = 0;
1982388a
APB
7306 int i, n;
7307 tree basetype_vec = TYPE_BINFO_BASETYPES (class);
7308
de0b553f
APB
7309 /* Have we searched this interface already? */
7310 if (searched_interfaces)
7311 {
7312 tree current;
7313 for (current = searched_interfaces;
7314 current; current = TREE_CHAIN (current))
7315 if (TREE_VALUE (current) == class)
7316 return NULL;
7317 }
7318 searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
7319
1982388a
APB
7320 search_applicable_methods_list
7321 (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
7322
7323 n = TREE_VEC_LENGTH (basetype_vec);
7324 for (i = 0; i < n; i++)
b67d701b 7325 {
de0b553f
APB
7326 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
7327 tree rlist;
7328
7329 /* Skip java.lang.Object (we'll search it once later.) */
7330 if (t == object_type_node)
7331 continue;
7332
7333 search_not_done++;
7334 rlist = find_applicable_accessible_methods_list (lc, t, name,
7335 arglist);
1982388a 7336 all_list = chainon (rlist, (list ? list : all_list));
de0b553f
APB
7337 search_not_done--;
7338 }
7339
7340 /* We're done. Reset the searched interfaces list and finally search
7341 java.lang.Object */
7342 if (!search_not_done)
7343 {
7344 searched_interfaces = NULL_TREE;
7345 search_applicable_methods_list (lc, TYPE_METHODS (object_type_node),
7346 name, arglist, &list, &all_list);
e04a16fb 7347 }
e04a16fb 7348 }
1982388a
APB
7349 /* Search classes */
7350 else
7351 while (class != NULL_TREE)
7352 {
7353 search_applicable_methods_list
7354 (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
7355 class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
7356 }
7357
b67d701b
PB
7358 /* Either return the list obtained or all selected (but
7359 inaccessible) methods for better error report. */
7360 return (!list ? all_list : list);
7361}
e04a16fb 7362
1982388a
APB
7363/* Effectively search for the approriate method in method */
7364
7365static void
7366search_applicable_methods_list(lc, method, name, arglist, list, all_list)
7367 int lc;
7368 tree method, name, arglist;
7369 tree *list, *all_list;
7370{
7371 for (; method; method = TREE_CHAIN (method))
7372 {
7373 /* When dealing with constructor, stop here, otherwise search
7374 other classes */
7375 if (lc && !DECL_CONSTRUCTOR_P (method))
7376 continue;
7377 else if (!lc && (DECL_CONSTRUCTOR_P (method)
7378 || (GET_METHOD_NAME (method) != name)))
7379 continue;
7380
7381 if (argument_types_convertible (method, arglist))
7382 {
7383 /* Retain accessible methods only */
7384 if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
7385 method, 0))
7386 *list = tree_cons (NULL_TREE, method, *list);
7387 else
7388 /* Also retain all selected method here */
7389 *all_list = tree_cons (NULL_TREE, method, *list);
7390 }
7391 }
7392}
7393
b67d701b
PB
7394/* 15.11.2.2 Choose the Most Specific Method */
7395
7396static tree
7397find_most_specific_methods_list (list)
7398 tree list;
7399{
7400 int max = 0;
7401 tree current, new_list = NULL_TREE;
7402 for (current = list; current; current = TREE_CHAIN (current))
e04a16fb 7403 {
b67d701b
PB
7404 tree method;
7405 DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
7406
7407 for (method = list; method; method = TREE_CHAIN (method))
7408 {
7409 /* Don't test a method against itself */
7410 if (method == current)
7411 continue;
7412
7413 /* Compare arguments and location where method where declared */
7414 if (argument_types_convertible (TREE_VALUE (method),
7415 TREE_VALUE (current))
7416 && valid_method_invocation_conversion_p
7417 (DECL_CONTEXT (TREE_VALUE (method)),
7418 DECL_CONTEXT (TREE_VALUE (current))))
7419 {
7420 int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
7421 max = (v > max ? v : max);
7422 }
7423 }
e04a16fb
AG
7424 }
7425
b67d701b
PB
7426 /* Review the list and select the maximally specific methods */
7427 for (current = list; current; current = TREE_CHAIN (current))
7428 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
7429 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
7430
7431 /* If we can't find one, lower expectations and try to gather multiple
7432 maximally specific methods */
7433 while (!new_list)
7434 {
7435 while (--max > 0)
7436 {
7437 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
7438 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
7439 }
7440 return new_list;
7441 }
7442
7443 return new_list;
e04a16fb
AG
7444}
7445
b67d701b
PB
7446/* Make sure that the type of each M2_OR_ARGLIST arguments can be
7447 converted by method invocation conversion (5.3) to the type of the
7448 corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
7449 to change less often than M1. */
e04a16fb 7450
b67d701b
PB
7451static int
7452argument_types_convertible (m1, m2_or_arglist)
7453 tree m1, m2_or_arglist;
e04a16fb 7454{
b67d701b
PB
7455 static tree m2_arg_value = NULL_TREE;
7456 static tree m2_arg_cache = NULL_TREE;
e04a16fb 7457
b67d701b 7458 register tree m1_arg, m2_arg;
e04a16fb 7459
b67d701b
PB
7460 m1_arg = TYPE_ARG_TYPES (TREE_TYPE (m1));
7461 if (!METHOD_STATIC (m1))
7462 m1_arg = TREE_CHAIN (m1_arg);
e04a16fb 7463
b67d701b
PB
7464 if (m2_arg_value == m2_or_arglist)
7465 m2_arg = m2_arg_cache;
7466 else
7467 {
7468 /* M2_OR_ARGLIST can be a function DECL or a raw list of
7469 argument types */
7470 if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
7471 {
7472 m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
7473 if (!METHOD_STATIC (m2_or_arglist))
7474 m2_arg = TREE_CHAIN (m2_arg);
7475 }
7476 else
7477 m2_arg = m2_or_arglist;
e04a16fb 7478
b67d701b
PB
7479 m2_arg_value = m2_or_arglist;
7480 m2_arg_cache = m2_arg;
7481 }
e04a16fb 7482
de4c7b02 7483 while (m1_arg != end_params_node && m2_arg != end_params_node)
b67d701b 7484 {
c877974e 7485 resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
b67d701b
PB
7486 if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
7487 TREE_VALUE (m2_arg)))
7488 break;
7489 m1_arg = TREE_CHAIN (m1_arg);
7490 m2_arg = TREE_CHAIN (m2_arg);
e04a16fb 7491 }
de4c7b02 7492 return m1_arg == end_params_node && m2_arg == end_params_node;
e04a16fb
AG
7493}
7494
7495/* Qualification routines */
7496
7497static void
7498qualify_ambiguous_name (id)
7499 tree id;
7500{
7501 tree qual, qual_wfl, name, decl, ptr_type, saved_current_class;
d8fccff5 7502 int again, super_found = 0, this_found = 0, new_array_found = 0;
e04a16fb
AG
7503
7504 /* We first qualify the first element, then derive qualification of
7505 others based on the first one. If the first element is qualified
7506 by a resolution (field or type), this resolution is stored in the
7507 QUAL_RESOLUTION of the qual element being examined. We need to
7508 save the current_class since the use of SUPER might change the
7509 its value. */
7510 saved_current_class = current_class;
7511 qual = EXPR_WFL_QUALIFICATION (id);
7512 do {
7513
7514 /* Simple qualified expression feature a qual_wfl that is a
7515 WFL. Expression derived from a primary feature more complicated
7516 things like a CALL_EXPR. Expression from primary need to be
7517 worked out to extract the part on which the qualification will
7518 take place. */
7519 qual_wfl = QUAL_WFL (qual);
7520 switch (TREE_CODE (qual_wfl))
7521 {
7522 case CALL_EXPR:
7523 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7524 if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
7525 {
7526 qual = EXPR_WFL_QUALIFICATION (qual_wfl);
7527 qual_wfl = QUAL_WFL (qual);
7528 }
7529 break;
d8fccff5
APB
7530 case NEW_ARRAY_EXPR:
7531 qual = TREE_CHAIN (qual);
7532 new_array_found = again = 1;
7533 continue;
b67d701b 7534 case NEW_CLASS_EXPR:
e04a16fb 7535 case CONVERT_EXPR:
e04a16fb
AG
7536 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7537 break;
c583dd46
APB
7538 case ARRAY_REF:
7539 while (TREE_CODE (qual_wfl) == ARRAY_REF)
7540 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7541 break;
0a2138e2
APB
7542 default:
7543 /* Fix for -Wall. Just break doing nothing */
7544 break;
e04a16fb
AG
7545 }
7546 name = EXPR_WFL_NODE (qual_wfl);
7547 ptr_type = current_class;
7548 again = 0;
7549 /* If we have a THIS (from a primary), we set the context accordingly */
7550 if (name == this_identifier_node)
7551 {
7552 qual = TREE_CHAIN (qual);
7553 qual_wfl = QUAL_WFL (qual);
22eed1e6
APB
7554 if (TREE_CODE (qual_wfl) == CALL_EXPR)
7555 again = 1;
7556 else
7557 name = EXPR_WFL_NODE (qual_wfl);
e04a16fb
AG
7558 this_found = 1;
7559 }
7560 /* If we have a SUPER, we set the context accordingly */
7561 if (name == super_identifier_node)
7562 {
7563 current_class = CLASSTYPE_SUPER (ptr_type);
7564 /* Check that there is such a thing as a super class. If not,
7565 return. The error will be caught later on, during the
7566 resolution */
7567 if (!current_class)
7568 {
7569 current_class = saved_current_class;
7570 return;
7571 }
7572 qual = TREE_CHAIN (qual);
7573 /* Do one more interation to set things up */
7574 super_found = again = 1;
7575 }
09ed0f70
APB
7576 /* Loop one more time if we're dealing with ?: or a string
7577 constant, or a convert expression */
5e942c50 7578 if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR
09ed0f70
APB
7579 || TREE_CODE (qual_wfl) == STRING_CST
7580 || TREE_CODE (qual_wfl) == CONVERT_EXPR)
22eed1e6
APB
7581 {
7582 qual = TREE_CHAIN (qual);
7583 qual_wfl = QUAL_WFL (qual);
7584 again = 1;
7585 }
e04a16fb
AG
7586 } while (again);
7587
7588 /* If name appears within the scope of a location variable
7589 declaration or parameter declaration, then it is an expression
7590 name. We don't carry this test out if we're in the context of the
7591 use of SUPER or THIS */
e04a16fb
AG
7592 if (!this_found && !super_found && (decl = IDENTIFIER_LOCAL_VALUE (name)))
7593 {
7594 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
7595 QUAL_RESOLUTION (qual) = decl;
7596 }
7597
7598 /* If within the class/interface NAME was found to be used there
7599 exists a (possibly inherited) field named NAME, then this is an
d8fccff5
APB
7600 expression name. If we saw a NEW_ARRAY_EXPR before and want to
7601 address length, it is OK. */
7602 else if ((decl = lookup_field_wrapper (ptr_type, name))
7603 || (new_array_found && name == length_identifier_node))
e04a16fb
AG
7604 {
7605 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
d8fccff5 7606 QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
e04a16fb
AG
7607 }
7608
7609 /* We reclassify NAME as a type name if:
7610 - NAME is a class/interface declared within the compilation
7611 unit containing NAME,
7612 - NAME is imported via a single-type-import declaration,
7613 - NAME is declared in an another compilation unit of the package
7614 of the compilation unit containing NAME,
7615 - NAME is declared by exactly on type-import-on-demand declaration
7616 of the compilation unit containing NAME. */
7617 else if ((decl = resolve_and_layout (name, NULL_TREE)))
7618 {
7619 RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
7620 QUAL_RESOLUTION (qual) = decl;
7621 }
7622
7623 /* Method call are expression name */
9bbc7d9f
PB
7624 else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
7625 || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF)
e04a16fb
AG
7626 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
7627
7628 /* Check here that NAME isn't declared by more than one
7629 type-import-on-demand declaration of the compilation unit
7630 containing NAME. FIXME */
7631
7632 /* Otherwise, NAME is reclassified as a package name */
7633 else
7634 RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
7635
7636 /* Propagate the qualification accross other components of the
7637 qualified name */
7638 for (qual = TREE_CHAIN (qual); qual;
7639 qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
7640 {
7641 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
7642 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
7643 else
7644 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
7645 }
7646
7647 /* Store the global qualification for the ambiguous part of ID back
7648 into ID fields */
7649 if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
7650 RESOLVE_EXPRESSION_NAME_P (id) = 1;
7651 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
7652 RESOLVE_TYPE_NAME_P (id) = 1;
7653 else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
7654 RESOLVE_PACKAGE_NAME_P (id) = 1;
7655
7656 /* Restore the current class */
7657 current_class = saved_current_class;
7658}
7659
7660static int
7661breakdown_qualified (left, right, source)
7662 tree *left, *right, source;
7663{
7664 char *p = IDENTIFIER_POINTER (source), *base;
7665 int l = IDENTIFIER_LENGTH (source);
7666
7667 /* Breakdown NAME into REMAINDER . IDENTIFIER */
7668 base = p;
7669 p += (l-1);
7670 while (*p != '.' && p != base)
7671 p--;
7672
7673 /* We didn't find a '.'. Return an error */
7674 if (p == base)
7675 return 1;
7676
7677 *p = '\0';
7678 if (right)
7679 *right = get_identifier (p+1);
7680 *left = get_identifier (IDENTIFIER_POINTER (source));
7681 *p = '.';
7682
7683 return 0;
7684}
7685
e04a16fb 7686/* Patch tree nodes in a function body. When a BLOCK is found, push
5b09b33e
PB
7687 local variable decls if present.
7688 Same as java_complete_lhs, but does resolve static finals to values. */
e04a16fb
AG
7689
7690static tree
7691java_complete_tree (node)
7692 tree node;
5b09b33e
PB
7693{
7694 node = java_complete_lhs (node);
7695 if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
7f10c2e2
APB
7696 && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
7697 && !flag_emit_xref)
5b09b33e
PB
7698 {
7699 tree value = DECL_INITIAL (node);
7700 DECL_INITIAL (node) = NULL_TREE;
7701 value = fold_constant_for_init (value, node);
7702 DECL_INITIAL (node) = value;
7703 if (value != NULL_TREE)
7704 return value;
7705 }
7706 return node;
7707}
7708
2aa11e97
APB
7709static tree
7710java_stabilize_reference (node)
7711 tree node;
7712{
7713 if (TREE_CODE (node) == COMPOUND_EXPR)
7714 {
7715 tree op0 = TREE_OPERAND (node, 0);
7716 tree op1 = TREE_OPERAND (node, 1);
642f15d1 7717 TREE_OPERAND (node, 0) = save_expr (op0);
2aa11e97
APB
7718 TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
7719 return node;
7720 }
7721 else
7722 return stabilize_reference (node);
7723}
7724
5b09b33e
PB
7725/* Patch tree nodes in a function body. When a BLOCK is found, push
7726 local variable decls if present.
7727 Same as java_complete_tree, but does not resolve static finals to values. */
7728
7729static tree
7730java_complete_lhs (node)
7731 tree node;
e04a16fb 7732{
22eed1e6 7733 tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
b67d701b 7734 int flag;
e04a16fb
AG
7735
7736 /* CONVERT_EXPR always has its type set, even though it needs to be
b67d701b 7737 worked out. */
e04a16fb
AG
7738 if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
7739 return node;
7740
7741 /* The switch block implements cases processing container nodes
7742 first. Contained nodes are always written back. Leaves come
7743 next and return a value. */
7744 switch (TREE_CODE (node))
7745 {
7746 case BLOCK:
7747
7748 /* 1- Block section.
7749 Set the local values on decl names so we can identify them
7750 faster when they're referenced. At that stage, identifiers
7751 are legal so we don't check for declaration errors. */
7752 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
7753 {
7754 DECL_CONTEXT (cn) = current_function_decl;
7755 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
e04a16fb 7756 }
15fdcfe9
PB
7757 if (BLOCK_EXPR_BODY (node) == NULL_TREE)
7758 CAN_COMPLETE_NORMALLY (node) = 1;
7759 else
e04a16fb 7760 {
15fdcfe9
PB
7761 tree stmt = BLOCK_EXPR_BODY (node);
7762 tree *ptr;
7763 int error_seen = 0;
7764 if (TREE_CODE (stmt) == COMPOUND_EXPR)
7765 {
c877974e
APB
7766 /* Re-order from (((A; B); C); ...; Z) to
7767 (A; (B; (C ; (...; Z)))).
15fdcfe9
PB
7768 This makes it easier to scan the statements left-to-right
7769 without using recursion (which might overflow the stack
7770 if the block has many statements. */
7771 for (;;)
7772 {
7773 tree left = TREE_OPERAND (stmt, 0);
7774 if (TREE_CODE (left) != COMPOUND_EXPR)
7775 break;
7776 TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
7777 TREE_OPERAND (left, 1) = stmt;
7778 stmt = left;
7779 }
7780 BLOCK_EXPR_BODY (node) = stmt;
7781 }
7782
c877974e
APB
7783 /* Now do the actual complete, without deep recursion for
7784 long blocks. */
15fdcfe9 7785 ptr = &BLOCK_EXPR_BODY (node);
dc0b3eff
PB
7786 while (TREE_CODE (*ptr) == COMPOUND_EXPR
7787 && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
15fdcfe9
PB
7788 {
7789 tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
7790 tree *next = &TREE_OPERAND (*ptr, 1);
7791 TREE_OPERAND (*ptr, 0) = cur;
cd9643f7
PB
7792 if (cur == empty_stmt_node)
7793 {
7794 /* Optimization; makes it easier to detect empty bodies.
7795 Most useful for <clinit> with all-constant initializer. */
7796 *ptr = *next;
7797 continue;
7798 }
15fdcfe9
PB
7799 if (TREE_CODE (cur) == ERROR_MARK)
7800 error_seen++;
7801 else if (! CAN_COMPLETE_NORMALLY (cur))
7802 {
7803 wfl_op2 = *next;
7804 for (;;)
7805 {
7806 if (TREE_CODE (wfl_op2) == BLOCK)
7807 wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
7808 else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
7809 wfl_op2 = TREE_OPERAND (wfl_op2, 0);
7810 else
7811 break;
7812 }
7813 if (TREE_CODE (wfl_op2) != CASE_EXPR
dc0b3eff 7814 && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
82371d41 7815 unreachable_stmt_error (*ptr);
15fdcfe9
PB
7816 }
7817 ptr = next;
7818 }
7819 *ptr = java_complete_tree (*ptr);
7820
7821 if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
e04a16fb 7822 return error_mark_node;
15fdcfe9 7823 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
e04a16fb
AG
7824 }
7825 /* Turn local bindings to null */
7826 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
7827 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
7828
7829 TREE_TYPE (node) = void_type_node;
7830 break;
7831
7832 /* 2- They are expressions but ultimately deal with statements */
b67d701b 7833
b9f7e36c
APB
7834 case THROW_EXPR:
7835 wfl_op1 = TREE_OPERAND (node, 0);
7836 COMPLETE_CHECK_OP_0 (node);
15fdcfe9 7837 /* CAN_COMPLETE_NORMALLY (node) = 0; */
b9f7e36c
APB
7838 return patch_throw_statement (node, wfl_op1);
7839
7840 case SYNCHRONIZED_EXPR:
7841 wfl_op1 = TREE_OPERAND (node, 0);
b9f7e36c
APB
7842 return patch_synchronized_statement (node, wfl_op1);
7843
b67d701b
PB
7844 case TRY_EXPR:
7845 return patch_try_statement (node);
7846
a7d8d81f
PB
7847 case TRY_FINALLY_EXPR:
7848 COMPLETE_CHECK_OP_0 (node);
7849 COMPLETE_CHECK_OP_1 (node);
7850 CAN_COMPLETE_NORMALLY (node)
7851 = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
7852 && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
7853 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
7854 return node;
7855
5a005d9e
PB
7856 case CLEANUP_POINT_EXPR:
7857 COMPLETE_CHECK_OP_0 (node);
7858 TREE_TYPE (node) = void_type_node;
2aa11e97
APB
7859 CAN_COMPLETE_NORMALLY (node) =
7860 CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
5a005d9e
PB
7861 return node;
7862
7863 case WITH_CLEANUP_EXPR:
7864 COMPLETE_CHECK_OP_0 (node);
7865 COMPLETE_CHECK_OP_2 (node);
2aa11e97
APB
7866 CAN_COMPLETE_NORMALLY (node) =
7867 CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
5a005d9e
PB
7868 TREE_TYPE (node) = void_type_node;
7869 return node;
7870
e04a16fb
AG
7871 case LABELED_BLOCK_EXPR:
7872 PUSH_LABELED_BLOCK (node);
7873 if (LABELED_BLOCK_BODY (node))
7874 COMPLETE_CHECK_OP_1 (node);
7875 TREE_TYPE (node) = void_type_node;
7876 POP_LABELED_BLOCK ();
1fb89a4d
APB
7877
7878 if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
9dd939b2
APB
7879 {
7880 LABELED_BLOCK_BODY (node) = NULL_TREE;
7881 CAN_COMPLETE_NORMALLY (node) = 1;
7882 }
1fb89a4d 7883 else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
15fdcfe9 7884 CAN_COMPLETE_NORMALLY (node) = 1;
e04a16fb
AG
7885 return node;
7886
7887 case EXIT_BLOCK_EXPR:
7888 /* We don't complete operand 1, because it's the return value of
7889 the EXIT_BLOCK_EXPR which doesn't exist it Java */
7890 return patch_bc_statement (node);
7891
15fdcfe9
PB
7892 case CASE_EXPR:
7893 cn = java_complete_tree (TREE_OPERAND (node, 0));
7894 if (cn == error_mark_node)
7895 return cn;
7896
7897 /* First, the case expression must be constant */
7898 cn = fold (cn);
7899
ce6e9147 7900 if (!TREE_CONSTANT (cn) && !flag_emit_xref)
15fdcfe9
PB
7901 {
7902 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7903 parse_error_context (node, "Constant expression required");
7904 return error_mark_node;
7905 }
7906
7907 nn = ctxp->current_loop;
7908
7909 /* It must be assignable to the type of the switch expression. */
c877974e
APB
7910 if (!try_builtin_assignconv (NULL_TREE,
7911 TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
15fdcfe9
PB
7912 {
7913 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7914 parse_error_context
7915 (wfl_operator,
7916 "Incompatible type for case. Can't convert `%s' to `int'",
7917 lang_printable_name (TREE_TYPE (cn), 0));
7918 return error_mark_node;
7919 }
7920
7921 cn = fold (convert (int_type_node, cn));
7922
7923 /* Multiple instance of a case label bearing the same
7924 value is checked during code generation. The case
7925 expression is allright so far. */
7926 TREE_OPERAND (node, 0) = cn;
9bbc7d9f 7927 TREE_TYPE (node) = void_type_node;
15fdcfe9 7928 CAN_COMPLETE_NORMALLY (node) = 1;
10100cc7 7929 TREE_SIDE_EFFECTS (node) = 1;
15fdcfe9
PB
7930 break;
7931
7932 case DEFAULT_EXPR:
7933 nn = ctxp->current_loop;
7934 /* Only one default label is allowed per switch statement */
7935 if (SWITCH_HAS_DEFAULT (nn))
7936 {
7937 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7938 parse_error_context (wfl_operator,
7939 "Duplicate case label: `default'");
7940 return error_mark_node;
7941 }
7942 else
7943 SWITCH_HAS_DEFAULT (nn) = 1;
9bbc7d9f 7944 TREE_TYPE (node) = void_type_node;
10100cc7 7945 TREE_SIDE_EFFECTS (node) = 1;
15fdcfe9
PB
7946 CAN_COMPLETE_NORMALLY (node) = 1;
7947 break;
7948
b67d701b 7949 case SWITCH_EXPR:
e04a16fb
AG
7950 case LOOP_EXPR:
7951 PUSH_LOOP (node);
7952 /* Check whether the loop was enclosed in a labeled
7953 statement. If not, create one, insert the loop in it and
7954 return the node */
7955 nn = patch_loop_statement (node);
b67d701b 7956
e04a16fb 7957 /* Anyways, walk the body of the loop */
b67d701b
PB
7958 if (TREE_CODE (node) == LOOP_EXPR)
7959 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
7960 /* Switch statement: walk the switch expression and the cases */
7961 else
7962 node = patch_switch_statement (node);
7963
e04a16fb 7964 if (TREE_OPERAND (node, 0) == error_mark_node)
b635eb2f
PB
7965 nn = error_mark_node;
7966 else
15fdcfe9 7967 {
b635eb2f
PB
7968 TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
7969 /* If we returned something different, that's because we
7970 inserted a label. Pop the label too. */
7971 if (nn != node)
7972 {
7973 if (CAN_COMPLETE_NORMALLY (node))
7974 CAN_COMPLETE_NORMALLY (nn) = 1;
7975 POP_LABELED_BLOCK ();
7976 }
15fdcfe9 7977 }
e04a16fb
AG
7978 POP_LOOP ();
7979 return nn;
7980
7981 case EXIT_EXPR:
7982 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
7983 return patch_exit_expr (node);
7984
7985 case COND_EXPR:
7986 /* Condition */
7987 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
7988 if (TREE_OPERAND (node, 0) == error_mark_node)
7989 return error_mark_node;
7990 /* then-else branches */
7991 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
7992 if (TREE_OPERAND (node, 1) == error_mark_node)
7993 return error_mark_node;
7994 TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
7995 if (TREE_OPERAND (node, 2) == error_mark_node)
7996 return error_mark_node;
7997 return patch_if_else_statement (node);
7998 break;
7999
22eed1e6
APB
8000 case CONDITIONAL_EXPR:
8001 /* Condition */
8002 wfl_op1 = TREE_OPERAND (node, 0);
8003 COMPLETE_CHECK_OP_0 (node);
8004 wfl_op2 = TREE_OPERAND (node, 1);
8005 COMPLETE_CHECK_OP_1 (node);
8006 wfl_op3 = TREE_OPERAND (node, 2);
8007 COMPLETE_CHECK_OP_2 (node);
8008 return patch_conditional_expr (node, wfl_op1, wfl_op2);
8009
e04a16fb
AG
8010 /* 3- Expression section */
8011 case COMPOUND_EXPR:
15fdcfe9 8012 wfl_op2 = TREE_OPERAND (node, 1);
ac825856
APB
8013 TREE_OPERAND (node, 0) = nn =
8014 java_complete_tree (TREE_OPERAND (node, 0));
dc0b3eff
PB
8015 if (wfl_op2 == empty_stmt_node)
8016 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
8017 else
15fdcfe9 8018 {
dc0b3eff 8019 if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
bccaf73a 8020 {
dc0b3eff
PB
8021 /* An unreachable condition in a do-while statement
8022 is *not* (technically) an unreachable statement. */
8023 nn = wfl_op2;
8024 if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
8025 nn = EXPR_WFL_NODE (nn);
8026 if (TREE_CODE (nn) != EXIT_EXPR)
8027 {
8028 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
8029 parse_error_context (wfl_operator, "Unreachable statement");
8030 }
bccaf73a 8031 }
dc0b3eff
PB
8032 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
8033 if (TREE_OPERAND (node, 1) == error_mark_node)
8034 return error_mark_node;
8035 CAN_COMPLETE_NORMALLY (node)
8036 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
15fdcfe9 8037 }
e04a16fb
AG
8038 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
8039 break;
8040
8041 case RETURN_EXPR:
15fdcfe9 8042 /* CAN_COMPLETE_NORMALLY (node) = 0; */
e04a16fb
AG
8043 return patch_return (node);
8044
8045 case EXPR_WITH_FILE_LOCATION:
8046 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
8047 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
15fdcfe9 8048 {
5423609c 8049 tree wfl = node;
15fdcfe9 8050 node = resolve_expression_name (node, NULL);
dc0b3eff
PB
8051 if (node == error_mark_node)
8052 return node;
5423609c
APB
8053 /* Keep line number information somewhere were it doesn't
8054 disrupt the completion process. */
8055 if (flag_emit_xref)
8056 {
8057 EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
8058 TREE_OPERAND (node, 1) = wfl;
8059 }
15fdcfe9
PB
8060 CAN_COMPLETE_NORMALLY (node) = 1;
8061 }
e04a16fb
AG
8062 else
8063 {
5b09b33e
PB
8064 tree body;
8065 int save_lineno = lineno;
8066 lineno = EXPR_WFL_LINENO (node);
8067 body = java_complete_tree (EXPR_WFL_NODE (node));
8068 lineno = save_lineno;
15fdcfe9 8069 EXPR_WFL_NODE (node) = body;
dc0b3eff 8070 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
15fdcfe9 8071 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
cd9643f7
PB
8072 if (body == empty_stmt_node)
8073 {
8074 /* Optimization; makes it easier to detect empty bodies. */
8075 return body;
8076 }
dc0b3eff 8077 if (body == error_mark_node)
e04a16fb
AG
8078 {
8079 /* Its important for the evaluation of assignment that
8080 this mark on the TREE_TYPE is propagated. */
8081 TREE_TYPE (node) = error_mark_node;
8082 return error_mark_node;
8083 }
8084 else
8085 TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
15fdcfe9 8086
e04a16fb
AG
8087 }
8088 break;
8089
b67d701b 8090 case NEW_ARRAY_EXPR:
e04a16fb
AG
8091 /* Patch all the dimensions */
8092 flag = 0;
8093 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
8094 {
8095 int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
8096 tree dim = java_complete_tree (TREE_VALUE (cn));
8097 if (dim == error_mark_node)
8098 {
8099 flag = 1;
8100 continue;
8101 }
8102 else
8103 {
b9f7e36c 8104 TREE_VALUE (cn) = dim;
e04a16fb
AG
8105 /* Setup the location of the current dimension, for
8106 later error report. */
8107 TREE_PURPOSE (cn) =
8108 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
8109 EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
8110 }
8111 }
8112 /* They complete the array creation expression, if no errors
8113 were found. */
15fdcfe9 8114 CAN_COMPLETE_NORMALLY (node) = 1;
aee48ef8
PB
8115 return (flag ? error_mark_node
8116 : force_evaluation_order (patch_newarray (node)));
e04a16fb 8117
b67d701b 8118 case NEW_CLASS_EXPR:
e04a16fb 8119 case CALL_EXPR:
b67d701b 8120 /* Complete function's argument(s) first */
e04a16fb
AG
8121 if (complete_function_arguments (node))
8122 return error_mark_node;
8123 else
b9f7e36c 8124 {
22eed1e6
APB
8125 tree decl, wfl = TREE_OPERAND (node, 0);
8126 int in_this = CALL_THIS_CONSTRUCTOR_P (node);
8127
c877974e 8128 node = patch_method_invocation (node, NULL_TREE,
89e09b9a 8129 NULL_TREE, 0, &decl);
c877974e
APB
8130 if (node == error_mark_node)
8131 return error_mark_node;
8132
8133 check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
8134 /* If we call this(...), register signature and positions */
8135 if (in_this)
8136 DECL_CONSTRUCTOR_CALLS (current_function_decl) =
8137 tree_cons (wfl, decl,
8138 DECL_CONSTRUCTOR_CALLS (current_function_decl));
de4c7b02 8139 CAN_COMPLETE_NORMALLY (node) = 1;
dc0b3eff 8140 return force_evaluation_order (node);
b9f7e36c 8141 }
e04a16fb
AG
8142
8143 case MODIFY_EXPR:
8144 /* Save potential wfls */
8145 wfl_op1 = TREE_OPERAND (node, 0);
cd9643f7
PB
8146 TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
8147 if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
8148 && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
8149 && DECL_INITIAL (nn) != NULL_TREE)
8150 {
8151 tree value = fold_constant_for_init (nn, nn);
8152 if (value != NULL_TREE)
8153 {
8154 tree type = TREE_TYPE (value);
8155 if (JPRIMITIVE_TYPE_P (type) || type == string_ptr_type_node)
8156 return empty_stmt_node;
8157 }
8158 DECL_INITIAL (nn) = NULL_TREE;
8159 }
e04a16fb 8160 wfl_op2 = TREE_OPERAND (node, 1);
cd9643f7 8161
e04a16fb
AG
8162 if (TREE_OPERAND (node, 0) == error_mark_node)
8163 return error_mark_node;
8164
8165 if (COMPOUND_ASSIGN_P (wfl_op2))
8166 {
2aa11e97 8167 tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0));
e04a16fb
AG
8168
8169 /* Hand stablize the lhs on both places */
e04a16fb
AG
8170 TREE_OPERAND (node, 0) = lvalue;
8171 TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue;
2aa11e97
APB
8172
8173 /* Now complete the RHS. We write it back later on. */
8174 nn = java_complete_tree (TREE_OPERAND (node, 1));
8175
642f15d1
APB
8176 if ((cn = patch_string (nn)))
8177 nn = cn;
8178
2aa11e97
APB
8179 /* The last part of the rewrite for E1 op= E2 is to have
8180 E1 = (T)(E1 op E2), with T being the type of E1. */
642f15d1
APB
8181 nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2),
8182 TREE_TYPE (lvalue), nn));
e04a16fb
AG
8183 }
8184
f8976021
APB
8185 /* If we're about to patch a NEW_ARRAY_INIT, we call a special
8186 function to complete this RHS */
2aa11e97 8187 else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)
fdec99c6 8188 nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
f8976021 8189 TREE_OPERAND (node, 1));
2aa11e97 8190 /* Otherwise we simply complete the RHS */
f8976021
APB
8191 else
8192 nn = java_complete_tree (TREE_OPERAND (node, 1));
8193
e04a16fb 8194 if (nn == error_mark_node)
c0d87ff6 8195 return error_mark_node;
2aa11e97
APB
8196
8197 /* Write back the RHS as we evaluated it. */
e04a16fb 8198 TREE_OPERAND (node, 1) = nn;
b67d701b
PB
8199
8200 /* In case we're handling = with a String as a RHS, we need to
8201 produce a String out of the RHS (it might still be a
8202 STRING_CST or a StringBuffer at this stage */
8203 if ((nn = patch_string (TREE_OPERAND (node, 1))))
8204 TREE_OPERAND (node, 1) = nn;
15fdcfe9
PB
8205 node = patch_assignment (node, wfl_op1, wfl_op2);
8206 CAN_COMPLETE_NORMALLY (node) = 1;
8207 return node;
e04a16fb
AG
8208
8209 case MULT_EXPR:
8210 case PLUS_EXPR:
8211 case MINUS_EXPR:
8212 case LSHIFT_EXPR:
8213 case RSHIFT_EXPR:
8214 case URSHIFT_EXPR:
8215 case BIT_AND_EXPR:
8216 case BIT_XOR_EXPR:
8217 case BIT_IOR_EXPR:
8218 case TRUNC_MOD_EXPR:
8219 case RDIV_EXPR:
8220 case TRUTH_ANDIF_EXPR:
8221 case TRUTH_ORIF_EXPR:
8222 case EQ_EXPR:
8223 case NE_EXPR:
8224 case GT_EXPR:
8225 case GE_EXPR:
8226 case LT_EXPR:
8227 case LE_EXPR:
8228 /* Operands 0 and 1 are WFL in certain cases only. patch_binop
8229 knows how to handle those cases. */
8230 wfl_op1 = TREE_OPERAND (node, 0);
8231 wfl_op2 = TREE_OPERAND (node, 1);
b67d701b 8232
15fdcfe9 8233 CAN_COMPLETE_NORMALLY (node) = 1;
b67d701b
PB
8234 /* Don't complete string nodes if dealing with the PLUS operand. */
8235 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
2aa11e97
APB
8236 {
8237 nn = java_complete_tree (wfl_op1);
8238 if (nn == error_mark_node)
8239 return error_mark_node;
8240 if ((cn = patch_string (nn)))
8241 nn = cn;
8242 TREE_OPERAND (node, 0) = nn;
8243 }
b67d701b 8244 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
2aa11e97
APB
8245 {
8246 nn = java_complete_tree (wfl_op2);
8247 if (nn == error_mark_node)
8248 return error_mark_node;
8249 if ((cn = patch_string (nn)))
8250 nn = cn;
8251 TREE_OPERAND (node, 1) = nn;
8252 }
dc0b3eff 8253 return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
e04a16fb 8254
5e942c50
APB
8255 case INSTANCEOF_EXPR:
8256 wfl_op1 = TREE_OPERAND (node, 0);
8257 COMPLETE_CHECK_OP_0 (node);
ce6e9147
APB
8258 if (flag_emit_xref)
8259 {
8260 TREE_TYPE (node) = boolean_type_node;
8261 return node;
8262 }
5e942c50
APB
8263 return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
8264
b67d701b 8265 case UNARY_PLUS_EXPR:
e04a16fb
AG
8266 case NEGATE_EXPR:
8267 case TRUTH_NOT_EXPR:
8268 case BIT_NOT_EXPR:
8269 case PREDECREMENT_EXPR:
8270 case PREINCREMENT_EXPR:
8271 case POSTDECREMENT_EXPR:
8272 case POSTINCREMENT_EXPR:
8273 case CONVERT_EXPR:
8274 /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
8275 how to handle those cases. */
8276 wfl_op1 = TREE_OPERAND (node, 0);
15fdcfe9 8277 CAN_COMPLETE_NORMALLY (node) = 1;
e04a16fb
AG
8278 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
8279 if (TREE_OPERAND (node, 0) == error_mark_node)
8280 return error_mark_node;
4a5f66c3
APB
8281 node = patch_unaryop (node, wfl_op1);
8282 CAN_COMPLETE_NORMALLY (node) = 1;
8283 break;
e04a16fb
AG
8284
8285 case ARRAY_REF:
8286 /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
8287 how to handle those cases. */
8288 wfl_op1 = TREE_OPERAND (node, 0);
8289 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
8290 if (TREE_OPERAND (node, 0) == error_mark_node)
8291 return error_mark_node;
7f1d4866 8292 if (!flag_emit_class_files && !flag_emit_xref)
b67d701b 8293 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
e04a16fb
AG
8294 /* The same applies to wfl_op2 */
8295 wfl_op2 = TREE_OPERAND (node, 1);
8296 TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
8297 if (TREE_OPERAND (node, 1) == error_mark_node)
8298 return error_mark_node;
7f1d4866 8299 if (!flag_emit_class_files && !flag_emit_xref)
22eed1e6 8300 TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
939d7216 8301 return patch_array_ref (node);
e04a16fb 8302
63a212ed
PB
8303 case RECORD_TYPE:
8304 return node;;
8305
8306 case COMPONENT_REF:
8307 /* The first step in the re-write of qualified name handling. FIXME.
8308 So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
9bbc7d9f 8309 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
63a212ed
PB
8310 if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
8311 {
8312 tree name = TREE_OPERAND (node, 1);
8313 tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
8314 if (field == NULL_TREE)
8315 {
8316 error ("missing static field `%s'", IDENTIFIER_POINTER (name));
8317 return error_mark_node;
8318 }
8319 if (! FIELD_STATIC (field))
8320 {
8321 error ("not a static field `%s'", IDENTIFIER_POINTER (name));
8322 return error_mark_node;
8323 }
8324 return field;
8325 }
8326 else
8327 fatal ("unimplemented java_complete_tree for COMPONENT_REF");
9bbc7d9f 8328 break;
9bbc7d9f 8329
b67d701b 8330 case THIS_EXPR:
e04a16fb
AG
8331 /* Can't use THIS in a static environment */
8332 if (!current_this)
8333 {
8334 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8335 parse_error_context (wfl_operator, "Keyword `this' used outside "
8336 "allowed context");
8337 TREE_TYPE (node) = error_mark_node;
8338 return error_mark_node;
8339 }
22eed1e6
APB
8340 if (ctxp->explicit_constructor_p)
8341 {
8342 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8343 parse_error_context
8344 (wfl_operator, "Can't reference `this' or `super' before the "
8345 "superclass constructor has been called");
8346 TREE_TYPE (node) = error_mark_node;
8347 return error_mark_node;
8348 }
e04a16fb
AG
8349 return current_this;
8350
e04a16fb 8351 default:
15fdcfe9 8352 CAN_COMPLETE_NORMALLY (node) = 1;
b67d701b
PB
8353 /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
8354 and it's time to turn it into the appropriate String object
8355 */
8356 if ((node = patch_string (node)))
8357 return node;
e04a16fb
AG
8358 fatal ("No case for tree code `%s' - java_complete_tree\n",
8359 tree_code_name [TREE_CODE (node)]);
8360 }
8361 return node;
8362}
8363
8364/* Complete function call's argument. Return a non zero value is an
8365 error was found. */
8366
8367static int
8368complete_function_arguments (node)
8369 tree node;
8370{
8371 int flag = 0;
8372 tree cn;
8373
22eed1e6 8374 ctxp->explicit_constructor_p += (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
e04a16fb
AG
8375 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
8376 {
b67d701b 8377 tree wfl = TREE_VALUE (cn), parm, temp;
e04a16fb
AG
8378 parm = java_complete_tree (wfl);
8379 if (parm == error_mark_node)
8380 {
8381 flag = 1;
8382 continue;
8383 }
b67d701b
PB
8384 /* If have a string literal that we haven't transformed yet or a
8385 crafted string buffer, as a result of use of the the String
8386 `+' operator. Build `parm.toString()' and expand it. */
8387 if ((temp = patch_string (parm)))
b9f7e36c 8388 parm = temp;
5e942c50
APB
8389 /* Inline PRIMTYPE.TYPE read access */
8390 parm = maybe_build_primttype_type_ref (parm, wfl);
b9f7e36c 8391
5e942c50 8392 TREE_VALUE (cn) = parm;
e04a16fb 8393 }
22eed1e6 8394 ctxp->explicit_constructor_p -= (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
e04a16fb
AG
8395 return flag;
8396}
8397
8398/* Sometimes (for loops and variable initialized during their
8399 declaration), we want to wrap a statement around a WFL and turn it
8400 debugable. */
8401
8402static tree
8403build_debugable_stmt (location, stmt)
8404 int location;
8405 tree stmt;
8406{
8407 if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
8408 {
8409 stmt = build_expr_wfl (stmt, input_filename, 0, 0);
8410 EXPR_WFL_LINECOL (stmt) = location;
8411 }
8412 JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
8413 return stmt;
8414}
8415
8416static tree
8417build_expr_block (body, decls)
8418 tree body, decls;
8419{
8420 tree node = make_node (BLOCK);
8421 BLOCK_EXPR_DECLS (node) = decls;
b67d701b 8422 BLOCK_EXPR_BODY (node) = body;
e04a16fb
AG
8423 if (body)
8424 TREE_TYPE (node) = TREE_TYPE (body);
8425 TREE_SIDE_EFFECTS (node) = 1;
8426 return node;
8427}
8428
b67d701b
PB
8429/* Create a new function block and link it approriately to current
8430 function block chain */
e04a16fb
AG
8431
8432static tree
8433enter_block ()
8434{
b67d701b
PB
8435 return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
8436}
8437
8438/* Link block B supercontext to the previous block. The current
8439 function DECL is used as supercontext when enter_a_block is called
8440 for the first time for a given function. The current function body
8441 (DECL_FUNCTION_BODY) is set to be block B. */
8442
8443static tree
8444enter_a_block (b)
8445 tree b;
8446{
e04a16fb
AG
8447 tree fndecl = current_function_decl;
8448
f099f336
APB
8449 if (!fndecl) {
8450 BLOCK_SUPERCONTEXT (b) = current_static_block;
8451 current_static_block = b;
8452 }
8453
8454 else if (!DECL_FUNCTION_BODY (fndecl))
e04a16fb
AG
8455 {
8456 BLOCK_SUPERCONTEXT (b) = fndecl;
8457 DECL_FUNCTION_BODY (fndecl) = b;
8458 }
8459 else
8460 {
8461 BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
8462 DECL_FUNCTION_BODY (fndecl) = b;
8463 }
8464 return b;
8465}
8466
8467/* Exit a block by changing the current function body
8468 (DECL_FUNCTION_BODY) to the current block super context, only if
8469 the block being exited isn't the method's top level one. */
8470
8471static tree
8472exit_block ()
8473{
f099f336
APB
8474 tree b;
8475 if (current_function_decl)
8476 {
8477 b = DECL_FUNCTION_BODY (current_function_decl);
8478 if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
8479 DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
8480 }
8481 else
8482 {
8483 b = current_static_block;
e04a16fb 8484
f099f336
APB
8485 if (BLOCK_SUPERCONTEXT (b))
8486 current_static_block = BLOCK_SUPERCONTEXT (b);
8487 }
e04a16fb
AG
8488 return b;
8489}
8490
8491/* Lookup for NAME in the nested function's blocks, all the way up to
8492 the current toplevel one. It complies with Java's local variable
8493 scoping rules. */
8494
8495static tree
8496lookup_name_in_blocks (name)
8497 tree name;
8498{
f099f336 8499 tree b = GET_CURRENT_BLOCK (current_function_decl);
e04a16fb
AG
8500
8501 while (b != current_function_decl)
8502 {
8503 tree current;
8504
8505 /* Paranoid sanity check. To be removed */
8506 if (TREE_CODE (b) != BLOCK)
8507 fatal ("non block expr function body - lookup_name_in_blocks");
8508
8509 for (current = BLOCK_EXPR_DECLS (b); current;
8510 current = TREE_CHAIN (current))
8511 if (DECL_NAME (current) == name)
8512 return current;
8513 b = BLOCK_SUPERCONTEXT (b);
8514 }
8515 return NULL_TREE;
8516}
8517
8518static void
8519maybe_absorb_scoping_blocks ()
8520{
f099f336 8521 while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
e04a16fb
AG
8522 {
8523 tree b = exit_block ();
8524 java_method_add_stmt (current_function_decl, b);
8525 SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
8526 }
8527}
8528
8529\f
8530/* This section of the source is reserved to build_* functions that
8531 are building incomplete tree nodes and the patch_* functions that
8532 are completing them. */
8533
9bbc7d9f 8534/* Build a super() constructor invocation. Returns empty_stmt_node if
22eed1e6
APB
8535 we're currently dealing with the class java.lang.Object. */
8536
8537static tree
8538build_super_invocation ()
8539{
8540 if (current_class == object_type_node)
9bbc7d9f 8541 return empty_stmt_node;
22eed1e6
APB
8542 else
8543 {
9ee9b555 8544 tree super_wfl = build_wfl_node (super_identifier_node);
22eed1e6
APB
8545 return build_method_invocation (super_wfl, NULL_TREE);
8546 }
8547}
8548
8549/* Build a SUPER/THIS qualified method invocation. */
8550
8551static tree
8552build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
8553 int use_this;
8554 tree name, args;
8555 int lloc, rloc;
8556
8557{
8558 tree invok;
8559 tree wfl =
9ee9b555 8560 build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
22eed1e6
APB
8561 EXPR_WFL_LINECOL (wfl) = lloc;
8562 invok = build_method_invocation (name, args);
8563 return make_qualified_primary (wfl, invok, rloc);
8564}
8565
b67d701b 8566/* Build an incomplete CALL_EXPR node. */
e04a16fb
AG
8567
8568static tree
8569build_method_invocation (name, args)
8570 tree name;
8571 tree args;
8572{
8573 tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
8574 TREE_SIDE_EFFECTS (call) = 1;
b67d701b
PB
8575 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
8576 return call;
8577}
8578
8579/* Build an incomplete new xxx(...) node. */
8580
8581static tree
8582build_new_invocation (name, args)
8583 tree name, args;
8584{
8585 tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
8586 TREE_SIDE_EFFECTS (call) = 1;
e04a16fb
AG
8587 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
8588 return call;
8589}
8590
8591/* Build an incomplete assignment expression. */
8592
8593static tree
8594build_assignment (op, op_location, lhs, rhs)
8595 int op, op_location;
8596 tree lhs, rhs;
8597{
8598 tree assignment;
8599 /* Build the corresponding binop if we deal with a Compound
8600 Assignment operator. Mark the binop sub-tree as part of a
8601 Compound Assignment expression */
8602 if (op != ASSIGN_TK)
8603 {
8604 rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
8605 COMPOUND_ASSIGN_P (rhs) = 1;
8606 }
8607 assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
8608 TREE_SIDE_EFFECTS (assignment) = 1;
8609 EXPR_WFL_LINECOL (assignment) = op_location;
8610 return assignment;
8611}
8612
8613/* Print an INTEGER_CST node in a static buffer, and return the buffer. */
8614
15fdcfe9 8615char *
e04a16fb
AG
8616print_int_node (node)
8617 tree node;
8618{
8619 static char buffer [80];
8620 if (TREE_CONSTANT_OVERFLOW (node))
8621 sprintf (buffer, "<overflow>");
8622
8623 if (TREE_INT_CST_HIGH (node) == 0)
8624 sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
8625 TREE_INT_CST_LOW (node));
8626 else if (TREE_INT_CST_HIGH (node) == -1
8627 && TREE_INT_CST_LOW (node) != 0)
8628 {
8629 buffer [0] = '-';
8630 sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
8631 -TREE_INT_CST_LOW (node));
8632 }
8633 else
8634 sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
8635 TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
8636
8637 return buffer;
8638}
8639
7f1d4866
APB
8640/* Return 1 if an assignment to a FINAL is attempted in a non suitable
8641 context. */
5e942c50
APB
8642
8643static int
8644check_final_assignment (lvalue, wfl)
8645 tree lvalue, wfl;
8646{
7f1d4866
APB
8647 if (JDECL_P (lvalue)
8648 && FIELD_FINAL (lvalue) && !IS_CLINIT (current_function_decl))
5e942c50
APB
8649 {
8650 parse_error_context
8651 (wfl, "Can't assign a value to the final variable `%s'",
8652 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
8653 return 1;
8654 }
8655 return 0;
8656}
8657
8658/* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
8659 read. This is needed to avoid circularities in the implementation
8660 of these fields in libjava. */
8661
8662static tree
8663maybe_build_primttype_type_ref (rhs, wfl)
8664 tree rhs, wfl;
8665{
8666 tree to_return = NULL_TREE;
8667 tree rhs_type = TREE_TYPE (rhs);
8668 if (TREE_CODE (rhs) == COMPOUND_EXPR)
8669 {
8670 tree n = TREE_OPERAND (rhs, 1);
8671 if (TREE_CODE (n) == VAR_DECL
8672 && DECL_NAME (n) == TYPE_identifier_node
8673 && rhs_type == class_ptr_type)
8674 {
8675 char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
8676 if (!strncmp (self_name, "java.lang.", 10))
8677 to_return = build_primtype_type_ref (self_name);
8678 }
8679 }
8680 return (to_return ? to_return : rhs );
8681}
8682
e04a16fb
AG
8683/* 15.25 Assignment operators. */
8684
8685static tree
8686patch_assignment (node, wfl_op1, wfl_op2)
8687 tree node;
8688 tree wfl_op1;
8689 tree wfl_op2;
8690{
0a2138e2 8691 tree rhs = TREE_OPERAND (node, 1);
5e942c50 8692 tree lvalue = TREE_OPERAND (node, 0), llvalue;
e04a16fb 8693 tree lhs_type, rhs_type, new_rhs = NULL_TREE;
e04a16fb
AG
8694 int error_found = 0;
8695 int lvalue_from_array = 0;
8696
8697 /* Can't assign to a final. */
5e942c50
APB
8698 if (check_final_assignment (lvalue, wfl_op1))
8699 error_found = 1;
e04a16fb
AG
8700
8701 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8702
8703 /* Lhs can be a named variable */
34f4db93 8704 if (JDECL_P (lvalue))
e04a16fb 8705 {
e04a16fb
AG
8706 lhs_type = TREE_TYPE (lvalue);
8707 }
8708 /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
8709 comment on reason why */
8710 else if (TREE_CODE (wfl_op1) == ARRAY_REF)
8711 {
8712 lhs_type = TREE_TYPE (lvalue);
8713 lvalue_from_array = 1;
8714 }
8715 /* Or a field access */
8716 else if (TREE_CODE (lvalue) == COMPONENT_REF)
8717 lhs_type = TREE_TYPE (lvalue);
8718 /* Or a function return slot */
8719 else if (TREE_CODE (lvalue) == RESULT_DECL)
8720 lhs_type = TREE_TYPE (lvalue);
5e942c50
APB
8721 /* Otherwise, we might want to try to write into an optimized static
8722 final, this is an of a different nature, reported further on. */
8723 else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
1504b2b4 8724 && resolve_expression_name (wfl_op1, &llvalue))
5e942c50 8725 {
1504b2b4
APB
8726 if (check_final_assignment (llvalue, wfl_op1))
8727 {
8728 /* What we should do instead is resetting the all the flags
8729 previously set, exchange lvalue for llvalue and continue. */
8730 error_found = 1;
8731 return error_mark_node;
8732 }
8733 else
8734 lhs_type = TREE_TYPE (lvalue);
5e942c50
APB
8735 }
8736 else
e04a16fb
AG
8737 {
8738 parse_error_context (wfl_op1, "Invalid left hand side of assignment");
8739 error_found = 1;
8740 }
8741
8742 rhs_type = TREE_TYPE (rhs);
b67d701b 8743 /* 5.1 Try the assignment conversion for builtin type. */
0a2138e2 8744 new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
e04a16fb 8745
b67d701b 8746 /* 5.2 If it failed, try a reference conversion */
0a2138e2 8747 if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
b67d701b 8748 lhs_type = promote_type (rhs_type);
e04a16fb
AG
8749
8750 /* 15.25.2 If we have a compound assignment, convert RHS into the
8751 type of the LHS */
8752 else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
8753 new_rhs = convert (lhs_type, rhs);
8754
8755 /* Explicit cast required. This is an error */
8756 if (!new_rhs)
8757 {
0a2138e2
APB
8758 char *t1 = strdup (lang_printable_name (TREE_TYPE (rhs), 0));
8759 char *t2 = strdup (lang_printable_name (lhs_type, 0));
e04a16fb
AG
8760 tree wfl;
8761 char operation [32]; /* Max size known */
8762
8763 /* If the assignment is part of a declaration, we use the WFL of
8764 the declared variable to point out the error and call it a
8765 declaration problem. If the assignment is a genuine =
8766 operator, we call is a operator `=' problem, otherwise we
8767 call it an assignment problem. In both of these last cases,
8768 we use the WFL of the operator to indicate the error. */
8769
8770 if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
8771 {
8772 wfl = wfl_op1;
8773 strcpy (operation, "declaration");
8774 }
8775 else
8776 {
8777 wfl = wfl_operator;
8778 if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
8779 strcpy (operation, "assignment");
8780 else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
8781 strcpy (operation, "`return'");
8782 else
8783 strcpy (operation, "`='");
8784 }
8785
8786 parse_error_context
b67d701b 8787 (wfl, (!valid_cast_to_p (rhs_type, lhs_type) ?
e04a16fb
AG
8788 "Incompatible type for %s. Can't convert `%s' to `%s'" :
8789 "Incompatible type for %s. Explicit cast "
8790 "needed to convert `%s' to `%s'"), operation, t1, t2);
8791 free (t1); free (t2);
8792 error_found = 1;
8793 }
8794
c877974e
APB
8795 /* Inline read access to java.lang.PRIMTYPE.TYPE */
8796 if (new_rhs)
8797 new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
5e942c50 8798
e04a16fb
AG
8799 if (error_found)
8800 return error_mark_node;
8801
2622b947
APB
8802 /* 10.10: Array Store Exception runtime check */
8803 if (!flag_emit_class_files
e8fc7396 8804 && !flag_emit_xref
2622b947
APB
8805 && lvalue_from_array
8806 && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type))
8807 && !CLASS_FINAL (TYPE_NAME (GET_SKIP_TYPE (rhs_type))))
8808 {
8809 tree check;
8810 tree base = lvalue;
8811
8812 /* We need to retrieve the right argument for _Jv_CheckArrayStore */
8813 if (TREE_CODE (lvalue) == COMPOUND_EXPR)
8814 base = TREE_OPERAND (lvalue, 0);
8815 else
8816 {
8817 if (flag_bounds_check)
8818 base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
8819 else
8820 base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
8821 }
8822
8823 /* Build the invocation of _Jv_CheckArrayStore */
8824 check = build (CALL_EXPR, void_type_node,
8825 build_address_of (soft_checkarraystore_node),
8826 tree_cons (NULL_TREE, base,
8827 build_tree_list (NULL_TREE, new_rhs)),
8828 NULL_TREE);
8829 TREE_SIDE_EFFECTS (check) = 1;
8830
8831 /* We have to decide on an insertion point */
8832 if (TREE_CODE (lvalue) == COMPOUND_EXPR)
8833 {
8834 tree t;
8835 if (flag_bounds_check)
8836 {
8837 t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
8838 TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
8839 build (COMPOUND_EXPR, void_type_node, t, check);
8840 }
8841 else
8842 TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
8843 check, TREE_OPERAND (lvalue, 1));
8844 }
8845 else
8846 {
8847 /* Make sure the bound check will happen before the store check */
8848 if (flag_bounds_check)
8849 TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
8850 build (COMPOUND_EXPR, void_type_node,
8851 TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
8852 else
8853 lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
8854 }
8855 }
22eed1e6 8856
e04a16fb
AG
8857 TREE_OPERAND (node, 0) = lvalue;
8858 TREE_OPERAND (node, 1) = new_rhs;
8859 TREE_TYPE (node) = lhs_type;
8860 return node;
8861}
8862
b67d701b
PB
8863/* Check that type SOURCE can be cast into type DEST. If the cast
8864 can't occur at all, return 0 otherwise 1. This function is used to
8865 produce accurate error messages on the reasons why an assignment
8866 failed. */
e04a16fb 8867
b67d701b
PB
8868static tree
8869try_reference_assignconv (lhs_type, rhs)
8870 tree lhs_type, rhs;
e04a16fb 8871{
b67d701b
PB
8872 tree new_rhs = NULL_TREE;
8873 tree rhs_type = TREE_TYPE (rhs);
e04a16fb 8874
b67d701b
PB
8875 if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
8876 {
8877 /* `null' may be assigned to any reference type */
8878 if (rhs == null_pointer_node)
8879 new_rhs = null_pointer_node;
8880 /* Try the reference assignment conversion */
8881 else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
8882 new_rhs = rhs;
8883 /* This is a magic assignment that we process differently */
8884 else if (rhs == soft_exceptioninfo_call_node)
8885 new_rhs = rhs;
8886 }
8887 return new_rhs;
8888}
8889
8890/* Check that RHS can be converted into LHS_TYPE by the assignment
8891 conversion (5.2), for the cases of RHS being a builtin type. Return
8892 NULL_TREE if the conversion fails or if because RHS isn't of a
8893 builtin type. Return a converted RHS if the conversion is possible. */
8894
8895static tree
8896try_builtin_assignconv (wfl_op1, lhs_type, rhs)
8897 tree wfl_op1, lhs_type, rhs;
8898{
8899 tree new_rhs = NULL_TREE;
8900 tree rhs_type = TREE_TYPE (rhs);
8901
5e942c50
APB
8902 /* Zero accepted everywhere */
8903 if (TREE_CODE (rhs) == INTEGER_CST
8904 && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
8905 && JPRIMITIVE_TYPE_P (rhs_type))
8906 new_rhs = convert (lhs_type, rhs);
8907
b67d701b
PB
8908 /* 5.1.1 Try Identity Conversion,
8909 5.1.2 Try Widening Primitive Conversion */
5e942c50 8910 else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
b67d701b
PB
8911 new_rhs = convert (lhs_type, rhs);
8912
8913 /* Try a narrowing primitive conversion (5.1.3):
8914 - expression is a constant expression of type int AND
8915 - variable is byte, short or char AND
8916 - The value of the expression is representable in the type of the
8917 variable */
8918 else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
8919 && (lhs_type == byte_type_node || lhs_type == char_type_node
8920 || lhs_type == short_type_node))
8921 {
8922 if (int_fits_type_p (rhs, lhs_type))
8923 new_rhs = convert (lhs_type, rhs);
8924 else if (wfl_op1) /* Might be called with a NULL */
8925 parse_warning_context
8926 (wfl_op1, "Constant expression `%s' to wide for narrowing "
8927 "primitive conversion to `%s'",
0a2138e2 8928 print_int_node (rhs), lang_printable_name (lhs_type, 0));
b67d701b
PB
8929 /* Reported a warning that will turn into an error further
8930 down, so we don't return */
8931 }
8932
8933 return new_rhs;
8934}
8935
8936/* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
8937 conversion (5.1.1) or widening primitve conversion (5.1.2). Return
8938 0 is the conversion test fails. This implements parts the method
8939 invocation convertion (5.3). */
8940
8941static int
8942valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
8943 tree lhs_type, rhs_type;
8944{
acd663ee 8945 /* 5.1.1: This is the identity conversion part. */
5e942c50
APB
8946 if (lhs_type == rhs_type)
8947 return 1;
8948
acd663ee
APB
8949 /* Reject non primitive types */
8950 if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
b67d701b
PB
8951 return 0;
8952
acd663ee
APB
8953 /* 5.1.2: widening primitive conversion. byte, even if it's smaller
8954 than a char can't be converted into a char. Short can't too, but
8955 the < test below takes care of that */
b67d701b
PB
8956 if (lhs_type == char_type_node && rhs_type == byte_type_node)
8957 return 0;
8958
5e942c50
APB
8959 /* Accept all promoted type here. Note, we can't use <= in the test
8960 below, because we still need to bounce out assignments of short
8961 to char and the likes */
8962 if (lhs_type == int_type_node
8963 && (rhs_type == promoted_byte_type_node
8964 || rhs_type == promoted_short_type_node
8965 || rhs_type == promoted_char_type_node
8966 || rhs_type == promoted_boolean_type_node))
8967 return 1;
8968
acd663ee
APB
8969 /* From here, an integral is widened if its precision is smaller
8970 than the precision of the LHS or if the LHS is a floating point
8971 type, or the RHS is a float and the RHS a double. */
8972 if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type)
8973 && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
8974 || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
8975 || (rhs_type == float_type_node && lhs_type == double_type_node))
b67d701b
PB
8976 return 1;
8977
8978 return 0;
e04a16fb
AG
8979}
8980
8981/* Check that something of SOURCE type can be assigned or cast to
8982 something of DEST type at runtime. Return 1 if the operation is
8983 valid, 0 otherwise. If CAST is set to 1, we're treating the case
8984 were SOURCE is cast into DEST, which borrows a lot of the
8985 assignment check. */
8986
8987static int
8988valid_ref_assignconv_cast_p (source, dest, cast)
8989 tree source;
8990 tree dest;
8991 int cast;
8992{
09ed0f70
APB
8993 /* SOURCE or DEST might be null if not from a declared entity. */
8994 if (!source || !dest)
8995 return 0;
5e942c50
APB
8996 if (JNULLP_TYPE_P (source))
8997 return 1;
e04a16fb
AG
8998 if (TREE_CODE (source) == POINTER_TYPE)
8999 source = TREE_TYPE (source);
9000 if (TREE_CODE (dest) == POINTER_TYPE)
9001 dest = TREE_TYPE (dest);
9002 /* Case where SOURCE is a class type */
9003 if (TYPE_CLASS_P (source))
9004 {
9005 if (TYPE_CLASS_P (dest))
9006 return source == dest || inherits_from_p (source, dest)
0a2138e2 9007 || (cast && inherits_from_p (dest, source));
e04a16fb
AG
9008 if (TYPE_INTERFACE_P (dest))
9009 {
9010 /* If doing a cast and SOURCE is final, the operation is
9011 always correct a compile time (because even if SOURCE
9012 does not implement DEST, a subclass of SOURCE might). */
9013 if (cast && !CLASS_FINAL (TYPE_NAME (source)))
9014 return 1;
9015 /* Otherwise, SOURCE must implement DEST */
9016 return interface_of_p (dest, source);
9017 }
9018 /* DEST is an array, cast permited if SOURCE is of Object type */
9019 return (cast && source == object_type_node ? 1 : 0);
9020 }
9021 if (TYPE_INTERFACE_P (source))
9022 {
9023 if (TYPE_CLASS_P (dest))
9024 {
9025 /* If not casting, DEST must be the Object type */
9026 if (!cast)
9027 return dest == object_type_node;
9028 /* We're doing a cast. The cast is always valid is class
9029 DEST is not final, otherwise, DEST must implement SOURCE */
b67d701b 9030 else if (!CLASS_FINAL (TYPE_NAME (dest)))
e04a16fb
AG
9031 return 1;
9032 else
9033 return interface_of_p (source, dest);
9034 }
9035 if (TYPE_INTERFACE_P (dest))
9036 {
9037 /* If doing a cast, then if SOURCE and DEST contain method
9038 with the same signature but different return type, then
9039 this is a (compile time) error */
9040 if (cast)
9041 {
9042 tree method_source, method_dest;
9043 tree source_type;
0a2138e2 9044 tree source_sig;
e04a16fb
AG
9045 tree source_name;
9046 for (method_source = TYPE_METHODS (source); method_source;
9047 method_source = TREE_CHAIN (method_source))
9048 {
9049 source_sig =
9050 build_java_argument_signature (TREE_TYPE (method_source));
9051 source_type = TREE_TYPE (TREE_TYPE (method_source));
9052 source_name = DECL_NAME (method_source);
9053 for (method_dest = TYPE_METHODS (dest);
9054 method_dest; method_dest = TREE_CHAIN (method_dest))
9055 if (source_sig ==
9056 build_java_argument_signature (TREE_TYPE (method_dest))
9057 && source_name == DECL_NAME (method_dest)
9058 && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
9059 return 0;
9060 }
9061 return 1;
9062 }
9063 else
9064 return source == dest || interface_of_p (dest, source);
9065 }
9066 else /* Array */
9067 return 0;
9068 }
9069 if (TYPE_ARRAY_P (source))
9070 {
9071 if (TYPE_CLASS_P (dest))
9072 return dest == object_type_node;
09ed0f70
APB
9073 /* Can't cast an array to an interface unless the interface is
9074 java.lang.Cloneable */
e04a16fb 9075 if (TYPE_INTERFACE_P (dest))
09ed0f70 9076 return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
e04a16fb
AG
9077 else /* Arrays */
9078 {
9079 tree source_element_type = TYPE_ARRAY_ELEMENT (source);
9080 tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
9081
b9f7e36c
APB
9082 /* In case of severe errors, they turn out null */
9083 if (!dest_element_type || !source_element_type)
9084 return 0;
e04a16fb
AG
9085 if (source_element_type == dest_element_type)
9086 return 1;
9087 return valid_ref_assignconv_cast_p (source_element_type,
9088 dest_element_type, cast);
9089 }
9090 return 0;
9091 }
9092 return 0;
9093}
9094
b67d701b
PB
9095static int
9096valid_cast_to_p (source, dest)
9097 tree source;
9098 tree dest;
9099{
9100 if (TREE_CODE (source) == POINTER_TYPE)
9101 source = TREE_TYPE (source);
9102 if (TREE_CODE (dest) == POINTER_TYPE)
9103 dest = TREE_TYPE (dest);
9104
9105 if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
9106 return valid_ref_assignconv_cast_p (source, dest, 1);
9107
9108 else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
9109 return 1;
9110
9111 return 0;
9112}
9113
9114/* Method invocation conversion test. Return 1 if type SOURCE can be
9115 converted to type DEST through the methond invocation conversion
9116 process (5.3) */
9117
15fdcfe9
PB
9118static tree
9119do_unary_numeric_promotion (arg)
9120 tree arg;
9121{
9122 tree type = TREE_TYPE (arg);
9123 if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
9124 : TREE_CODE (type) == CHAR_TYPE)
9125 arg = convert (int_type_node, arg);
9126 return arg;
9127}
9128
acd663ee
APB
9129/* Return a non zero value if SOURCE can be converted into DEST using
9130 the method invocation conversion rule (5.3). */
b67d701b
PB
9131static int
9132valid_method_invocation_conversion_p (dest, source)
9133 tree dest, source;
9134{
e3884b71 9135 return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
acd663ee
APB
9136 && valid_builtin_assignconv_identity_widening_p (dest, source))
9137 || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
9138 && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
9139 && valid_ref_assignconv_cast_p (source, dest, 0)));
b67d701b
PB
9140}
9141
e04a16fb
AG
9142/* Build an incomplete binop expression. */
9143
9144static tree
9145build_binop (op, op_location, op1, op2)
9146 enum tree_code op;
9147 int op_location;
9148 tree op1, op2;
9149{
5e942c50 9150 tree binop = build (op, NULL_TREE, op1, op2);
e04a16fb
AG
9151 TREE_SIDE_EFFECTS (binop) = 1;
9152 /* Store the location of the operator, for better error report. The
9153 string of the operator will be rebuild based on the OP value. */
9154 EXPR_WFL_LINECOL (binop) = op_location;
9155 return binop;
9156}
9157
9158/* Build the string of the operator retained by NODE. If NODE is part
9159 of a compound expression, add an '=' at the end of the string. This
9160 function is called when an error needs to be reported on an
9161 operator. The string is returned as a pointer to a static character
9162 buffer. */
9163
9164static char *
9165operator_string (node)
9166 tree node;
9167{
9168#define BUILD_OPERATOR_STRING(S) \
9169 { \
9170 sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
9171 return buffer; \
9172 }
9173
9174 static char buffer [10];
9175 switch (TREE_CODE (node))
9176 {
9177 case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
9178 case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
9179 case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
9180 case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
9181 case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
9182 case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
9183 case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
9184 case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
9185 case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
9186 case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
9187 case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
9188 case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
9189 case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
9190 case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
9191 case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
9192 case GT_EXPR: BUILD_OPERATOR_STRING (">");
9193 case GE_EXPR: BUILD_OPERATOR_STRING (">=");
9194 case LT_EXPR: BUILD_OPERATOR_STRING ("<");
9195 case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
b67d701b 9196 case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
e04a16fb
AG
9197 case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
9198 case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
9199 case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
9200 case PREINCREMENT_EXPR: /* Fall through */
9201 case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
9202 case PREDECREMENT_EXPR: /* Fall through */
9203 case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
9204 default:
9205 fatal ("unregistered operator %s - operator_string",
9206 tree_code_name [TREE_CODE (node)]);
9207 }
9208 return NULL;
9209#undef BUILD_OPERATOR_STRING
9210}
9211
9212/* Binary operators (15.16 up to 15.18). We return error_mark_node on
9213 errors but we modify NODE so that it contains the type computed
9214 according to the expression, when it's fixed. Otherwise, we write
9215 error_mark_node as the type. It allows us to further the analysis
9216 of remaining nodes and detects more errors in certain cases. */
9217
9218static tree
9219patch_binop (node, wfl_op1, wfl_op2)
9220 tree node;
9221 tree wfl_op1;
9222 tree wfl_op2;
9223{
9224 tree op1 = TREE_OPERAND (node, 0);
9225 tree op2 = TREE_OPERAND (node, 1);
9226 tree op1_type = TREE_TYPE (op1);
9227 tree op2_type = TREE_TYPE (op2);
ab3a6dd6 9228 tree prom_type = NULL_TREE;
e04a16fb 9229 int code = TREE_CODE (node);
b67d701b 9230
e04a16fb
AG
9231 /* If 1, tell the routine that we have to return error_mark_node
9232 after checking for the initialization of the RHS */
9233 int error_found = 0;
9234
e04a16fb
AG
9235 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9236
e04a16fb
AG
9237 switch (code)
9238 {
9239 /* 15.16 Multiplicative operators */
9240 case MULT_EXPR: /* 15.16.1 Multiplication Operator * */
9241 case RDIV_EXPR: /* 15.16.2 Division Operator / */
9242 case TRUNC_MOD_EXPR: /* 15.16.3 Remainder operator % */
9243 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
9244 {
9245 if (!JPRIMITIVE_TYPE_P (op1_type))
9246 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9247 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
9248 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9249 TREE_TYPE (node) = error_mark_node;
9250 error_found = 1;
9251 break;
9252 }
9253 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9254 /* Change the division operator if necessary */
9255 if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
9256 TREE_SET_CODE (node, TRUNC_DIV_EXPR);
0b4d333e
APB
9257
9258 /* This one is more complicated. FLOATs are processed by a
9259 function call to soft_fmod. Duplicate the value of the
9260 COMPOUND_ASSIGN_P flag. */
e04a16fb 9261 if (code == TRUNC_MOD_EXPR)
0b4d333e
APB
9262 {
9263 tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
9264 COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
dc0b3eff
PB
9265 TREE_SIDE_EFFECTS (mod)
9266 = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
0b4d333e
APB
9267 return mod;
9268 }
e04a16fb
AG
9269 break;
9270
9271 /* 15.17 Additive Operators */
9272 case PLUS_EXPR: /* 15.17.1 String Concatenation Operator + */
b67d701b
PB
9273
9274 /* Operation is valid if either one argument is a string
9275 constant, a String object or a StringBuffer crafted for the
9276 purpose of the a previous usage of the String concatenation
9277 operator */
9278
9279 if (TREE_CODE (op1) == STRING_CST
9280 || TREE_CODE (op2) == STRING_CST
9281 || JSTRING_TYPE_P (op1_type)
9282 || JSTRING_TYPE_P (op2_type)
9283 || IS_CRAFTED_STRING_BUFFER_P (op1)
9284 || IS_CRAFTED_STRING_BUFFER_P (op2))
9285 return build_string_concatenation (op1, op2);
9286
e04a16fb
AG
9287 case MINUS_EXPR: /* 15.17.2 Additive Operators (+ and -) for
9288 Numeric Types */
9289 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
9290 {
9291 if (!JPRIMITIVE_TYPE_P (op1_type))
9292 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9293 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
9294 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9295 TREE_TYPE (node) = error_mark_node;
9296 error_found = 1;
9297 break;
9298 }
9299 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9300 break;
9301
9302 /* 15.18 Shift Operators */
9303 case LSHIFT_EXPR:
9304 case RSHIFT_EXPR:
9305 case URSHIFT_EXPR:
9306 if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
9307 {
9308 if (!JINTEGRAL_TYPE_P (op1_type))
9309 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
9310 else
9311 parse_error_context
9312 (wfl_operator, (JPRIMITIVE_TYPE_P (op2_type) ?
9313 "Incompatible type for `%s'. Explicit cast needed to convert "
9314 "shift distance from `%s' to integral" :
9315 "Incompatible type for `%s'. Can't convert shift distance from "
9316 "`%s' to integral"),
0a2138e2 9317 operator_string (node), lang_printable_name (op2_type, 0));
e04a16fb
AG
9318 TREE_TYPE (node) = error_mark_node;
9319 error_found = 1;
9320 break;
9321 }
9322
9323 /* Unary numeric promotion (5.6.1) is performed on each operand
9324 separatly */
15fdcfe9
PB
9325 op1 = do_unary_numeric_promotion (op1);
9326 op2 = do_unary_numeric_promotion (op2);
e04a16fb
AG
9327
9328 /* The type of the shift expression is the type of the promoted
9329 type of the left-hand operand */
9330 prom_type = TREE_TYPE (op1);
9331
9332 /* Shift int only up to 0x1f and long up to 0x3f */
9333 if (prom_type == int_type_node)
9334 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
9335 build_int_2 (0x1f, 0)));
9336 else
9337 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
9338 build_int_2 (0x3f, 0)));
9339
9340 /* The >>> operator is a >> operating on unsigned quantities */
15fdcfe9 9341 if (code == URSHIFT_EXPR && ! flag_emit_class_files)
e04a16fb 9342 {
0b4d333e 9343 tree to_return;
73333a87
AH
9344 tree utype = unsigned_type (prom_type);
9345 op1 = convert (utype, op1);
e04a16fb 9346 TREE_SET_CODE (node, RSHIFT_EXPR);
73333a87
AH
9347 TREE_OPERAND (node, 0) = op1;
9348 TREE_OPERAND (node, 1) = op2;
9349 TREE_TYPE (node) = utype;
0b4d333e
APB
9350 to_return = convert (prom_type, node);
9351 /* Copy the original value of the COMPOUND_ASSIGN_P flag */
9352 COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
dc0b3eff
PB
9353 TREE_SIDE_EFFECTS (to_return)
9354 = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
0b4d333e 9355 return to_return;
e04a16fb
AG
9356 }
9357 break;
5e942c50
APB
9358
9359 /* 15.19.1 Type Comparison Operator instaceof */
9360 case INSTANCEOF_EXPR:
9361
9362 TREE_TYPE (node) = boolean_type_node;
9363
9364 if (!(op2_type = resolve_type_during_patch (op2)))
9365 return error_mark_node;
9366
9367 /* The first operand must be a reference type or the null type */
9368 if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
9369 error_found = 1; /* Error reported further below */
9370
9371 /* The second operand must be a reference type */
9372 if (!JREFERENCE_TYPE_P (op2_type))
9373 {
9374 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
9375 parse_error_context
9376 (wfl_operator, "Invalid argument `%s' for `instanceof'",
9377 lang_printable_name (op2_type, 0));
9378 error_found = 1;
9379 }
9380
9381 if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
9382 {
9383 /* If the first operand is null, the result is always false */
9384 if (op1 == null_pointer_node)
9385 return boolean_false_node;
15fdcfe9
PB
9386 else if (flag_emit_class_files)
9387 {
9388 TREE_OPERAND (node, 1) = op2_type;
dc0b3eff 9389 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
15fdcfe9
PB
9390 return node;
9391 }
5e942c50
APB
9392 /* Otherwise we have to invoke instance of to figure it out */
9393 else
9394 {
9395 tree call =
9396 build (CALL_EXPR, boolean_type_node,
9397 build_address_of (soft_instanceof_node),
9398 tree_cons
9399 (NULL_TREE, op1,
9400 build_tree_list (NULL_TREE,
9401 build_class_ref (op2_type))),
9402 NULL_TREE);
dc0b3eff 9403 TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
5e942c50
APB
9404 return call;
9405 }
9406 }
9407 /* There is no way the expression operand can be an instance of
9408 the type operand. This is a compile time error. */
9409 else
9410 {
9411 char *t1 = strdup (lang_printable_name (op1_type, 0));
9412 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
9413 parse_error_context
9414 (wfl_operator, "Impossible for `%s' to be instance of `%s'",
9415 t1, lang_printable_name (op2_type, 0));
9416 free (t1);
9417 error_found = 1;
9418 }
e04a16fb 9419
5e942c50 9420 break;
e04a16fb
AG
9421
9422 /* 15.21 Bitwise and Logical Operators */
9423 case BIT_AND_EXPR:
9424 case BIT_XOR_EXPR:
9425 case BIT_IOR_EXPR:
9426 if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
9427 /* Binary numeric promotion is performed on both operand and the
9428 expression retain that type */
9429 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9430
9431 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE
9432 && TREE_CODE (op1_type) == BOOLEAN_TYPE)
9433 /* The type of the bitwise operator expression is BOOLEAN */
9434 prom_type = boolean_type_node;
9435 else
9436 {
9437 if (!JINTEGRAL_TYPE_P (op1_type))
9438 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
9439 if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
9440 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
9441 TREE_TYPE (node) = error_mark_node;
9442 error_found = 1;
9443 /* Insert a break here if adding thing before the switch's
9444 break for this case */
9445 }
9446 break;
9447
9448 /* 15.22 Conditional-And Operator */
9449 case TRUTH_ANDIF_EXPR:
9450 /* 15.23 Conditional-Or Operator */
9451 case TRUTH_ORIF_EXPR:
9452 /* Operands must be of BOOLEAN type */
9453 if (TREE_CODE (op1_type) != BOOLEAN_TYPE ||
9454 TREE_CODE (op2_type) != BOOLEAN_TYPE)
9455 {
9456 if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
9457 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
9458 if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
9459 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
9460 TREE_TYPE (node) = boolean_type_node;
9461 error_found = 1;
9462 break;
9463 }
9464 /* The type of the conditional operators is BOOLEAN */
9465 prom_type = boolean_type_node;
9466 break;
9467
9468 /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
9469 case LT_EXPR:
9470 case GT_EXPR:
9471 case LE_EXPR:
9472 case GE_EXPR:
9473 /* The type of each of the operands must be a primitive numeric
9474 type */
9475 if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
9476 {
9477 if (!JNUMERIC_TYPE_P (op1_type))
9478 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9479 if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
9480 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9481 TREE_TYPE (node) = boolean_type_node;
9482 error_found = 1;
9483 break;
9484 }
9485 /* Binary numeric promotion is performed on the operands */
9486 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9487 /* The type of the relation expression is always BOOLEAN */
9488 prom_type = boolean_type_node;
9489 break;
9490
9491 /* 15.20 Equality Operator */
9492 case EQ_EXPR:
9493 case NE_EXPR:
9494 /* 15.20.1 Numerical Equality Operators == and != */
9495 /* Binary numeric promotion is performed on the operands */
5e942c50 9496 if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
e04a16fb
AG
9497 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9498
9499 /* 15.20.2 Boolean Equality Operators == and != */
9500 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
9501 TREE_CODE (op2_type) == BOOLEAN_TYPE)
9502 ; /* Nothing to do here */
9503
9504 /* 15.20.3 Reference Equality Operators == and != */
5e942c50
APB
9505 /* Types have to be either references or the null type. If
9506 they're references, it must be possible to convert either
9507 type to the other by casting conversion. */
b9f7e36c
APB
9508 else if (op1 == null_pointer_node || op2 == null_pointer_node
9509 || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
5e942c50
APB
9510 && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
9511 || valid_ref_assignconv_cast_p (op2_type,
9512 op1_type, 1))))
e04a16fb
AG
9513 ; /* Nothing to do here */
9514
9515 /* Else we have an error figure what can't be converted into
9516 what and report the error */
9517 else
9518 {
9519 char *t1;
0a2138e2 9520 t1 = strdup (lang_printable_name (op1_type, 0));
e04a16fb
AG
9521 parse_error_context
9522 (wfl_operator, "Incompatible type for `%s'. Can't convert `%s' "
9523 "to `%s'", operator_string (node), t1,
0a2138e2 9524 lang_printable_name (op2_type, 0));
e04a16fb
AG
9525 free (t1);
9526 TREE_TYPE (node) = boolean_type_node;
9527 error_found = 1;
9528 break;
9529 }
9530 prom_type = boolean_type_node;
9531 break;
9532 }
9533
e04a16fb
AG
9534 if (error_found)
9535 return error_mark_node;
9536
9537 TREE_OPERAND (node, 0) = op1;
9538 TREE_OPERAND (node, 1) = op2;
9539 TREE_TYPE (node) = prom_type;
dc0b3eff
PB
9540 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
9541
ce6e9147
APB
9542 if (flag_emit_xref)
9543 return node;
9544
d1472141
PB
9545 /* fold does not respect side-effect order as required for Java but not C.
9546 * Also, it sometimes create SAVE_EXPRs which are bad when emitting
9547 * bytecode.
9548 */
9549 if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
9550 : ! TREE_SIDE_EFFECTS (node))
aee48ef8
PB
9551 node = fold (node);
9552 return node;
e04a16fb
AG
9553}
9554
b67d701b
PB
9555/* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
9556 zero value, the value of CSTE comes after the valude of STRING */
9557
9558static tree
9559do_merge_string_cste (cste, string, string_len, after)
9560 tree cste;
9561 char *string;
9562 int string_len, after;
9563{
9564 int len = TREE_STRING_LENGTH (cste) + string_len;
9565 char *old = TREE_STRING_POINTER (cste);
9566 TREE_STRING_LENGTH (cste) = len;
9567 TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
9568 if (after)
9569 {
9570 strcpy (TREE_STRING_POINTER (cste), string);
9571 strcat (TREE_STRING_POINTER (cste), old);
9572 }
9573 else
9574 {
9575 strcpy (TREE_STRING_POINTER (cste), old);
9576 strcat (TREE_STRING_POINTER (cste), string);
9577 }
9578 return cste;
9579}
9580
9581/* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
9582 new STRING_CST on success, NULL_TREE on failure */
9583
9584static tree
9585merge_string_cste (op1, op2, after)
9586 tree op1, op2;
9587 int after;
9588{
9589 /* Handle two string constants right away */
9590 if (TREE_CODE (op2) == STRING_CST)
9591 return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
9592 TREE_STRING_LENGTH (op2), after);
9593
9594 /* Reasonable integer constant can be treated right away */
9595 if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
9596 {
9597 static char *boolean_true = "true";
9598 static char *boolean_false = "false";
9599 static char *null_pointer = "null";
9600 char ch[3];
9601 char *string;
9602
9603 if (op2 == boolean_true_node)
9604 string = boolean_true;
9605 else if (op2 == boolean_false_node)
9606 string = boolean_false;
9607 else if (op2 == null_pointer_node)
9608 string = null_pointer;
9609 else if (TREE_TYPE (op2) == char_type_node)
9610 {
9611 ch[0] = (char )TREE_INT_CST_LOW (op2);
9612 ch[1] = '\0';
9613 string = ch;
9614 }
9615 else
9616 string = print_int_node (op2);
9617
9618 return do_merge_string_cste (op1, string, strlen (string), after);
9619 }
9620 return NULL_TREE;
9621}
9622
9623/* Tries to statically concatenate OP1 and OP2 if possible. Either one
9624 has to be a STRING_CST and the other part must be a STRING_CST or a
9625 INTEGRAL constant. Return a new STRING_CST if the operation
9626 succeed, NULL_TREE otherwise.
9627
9628 If the case we want to optimize for space, we might want to return
9629 NULL_TREE for each invocation of this routine. FIXME */
9630
9631static tree
9632string_constant_concatenation (op1, op2)
9633 tree op1, op2;
9634{
9635 if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
9636 {
0a2138e2 9637 tree string, rest;
b67d701b
PB
9638 int invert;
9639
9640 string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
9641 rest = (string == op1 ? op2 : op1);
9642 invert = (string == op1 ? 0 : 1 );
9643
9644 /* Walk REST, only if it looks reasonable */
9645 if (TREE_CODE (rest) != STRING_CST
9646 && !IS_CRAFTED_STRING_BUFFER_P (rest)
9647 && !JSTRING_TYPE_P (TREE_TYPE (rest))
9648 && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
9649 {
9650 rest = java_complete_tree (rest);
9651 if (rest == error_mark_node)
9652 return error_mark_node;
9653 rest = fold (rest);
9654 }
9655 return merge_string_cste (string, rest, invert);
9656 }
9657 return NULL_TREE;
9658}
9659
9660/* Implement the `+' operator. Does static optimization if possible,
9661 otherwise create (if necessary) and append elements to a
9662 StringBuffer. The StringBuffer will be carried around until it is
9663 used for a function call or an assignment. Then toString() will be
9664 called on it to turn it into a String object. */
9665
9666static tree
9667build_string_concatenation (op1, op2)
9668 tree op1, op2;
9669{
9670 tree result;
dc0b3eff 9671 int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
ce6e9147
APB
9672
9673 if (flag_emit_xref)
9674 return build (PLUS_EXPR, string_type_node, op1, op2);
b67d701b
PB
9675
9676 /* Try to do some static optimization */
9677 if ((result = string_constant_concatenation (op1, op2)))
9678 return result;
9679
c0d87ff6
PB
9680 /* Discard empty strings on either side of the expression */
9681 if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
acd663ee
APB
9682 {
9683 op1 = op2;
9684 op2 = NULL_TREE;
9685 }
c0d87ff6 9686 else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
acd663ee 9687 op2 = NULL_TREE;
b67d701b 9688
acd663ee 9689 /* If operands are string constant, turn then into object references */
b67d701b
PB
9690 if (TREE_CODE (op1) == STRING_CST)
9691 op1 = patch_string_cst (op1);
acd663ee 9692 if (op2 && TREE_CODE (op2) == STRING_CST)
b67d701b
PB
9693 op2 = patch_string_cst (op2);
9694
acd663ee
APB
9695 /* If either one of the constant is null and the other non null
9696 operand is a String object, return it. */
9697 if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
9698 return op1;
9699
b67d701b
PB
9700 /* If OP1 isn't already a StringBuffer, create and
9701 initialize a new one */
9702 if (!IS_CRAFTED_STRING_BUFFER_P (op1))
9703 {
9704 /* Two solutions here:
9705 1) OP1 is a string reference, we call new StringBuffer(OP1)
acd663ee 9706 2) OP1 is something else, we call new StringBuffer().append(OP1). */
b67d701b
PB
9707 if (JSTRING_TYPE_P (TREE_TYPE (op1)))
9708 op1 = BUILD_STRING_BUFFER (op1);
9709 else
9710 {
9711 tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
9712 op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
9713 }
9714 }
9715
acd663ee
APB
9716 if (op2)
9717 {
9718 /* OP1 is no longer the last node holding a crafted StringBuffer */
9719 IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
9720 /* Create a node for `{new...,xxx}.append (op2)' */
9721 if (op2)
9722 op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
9723 }
9724
b67d701b
PB
9725 /* Mark the last node holding a crafted StringBuffer */
9726 IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
dc0b3eff
PB
9727
9728 TREE_SIDE_EFFECTS (op1) = side_effects;
b67d701b
PB
9729 return op1;
9730}
9731
9732/* Patch the string node NODE. NODE can be a STRING_CST of a crafted
9733 StringBuffer. If no string were found to be patched, return
9734 NULL. */
9735
9736static tree
9737patch_string (node)
9738 tree node;
9739{
1179ebc2
APB
9740 if (node == error_mark_node)
9741 return error_mark_node;
b67d701b
PB
9742 if (TREE_CODE (node) == STRING_CST)
9743 return patch_string_cst (node);
9744 else if (IS_CRAFTED_STRING_BUFFER_P (node))
9745 {
c877974e 9746 int saved = ctxp->explicit_constructor_p;
b67d701b 9747 tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
c877974e
APB
9748 tree ret;
9749 /* Temporary disable forbid the use of `this'. */
9750 ctxp->explicit_constructor_p = 0;
9751 ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
9752 /* Restore it at its previous value */
9753 ctxp->explicit_constructor_p = saved;
9754 return ret;
b67d701b
PB
9755 }
9756 return NULL_TREE;
9757}
9758
9759/* Build the internal representation of a string constant. */
9760
9761static tree
9762patch_string_cst (node)
9763 tree node;
9764{
9765 int location;
15fdcfe9
PB
9766 if (! flag_emit_class_files)
9767 {
9768 push_obstacks (&permanent_obstack, &permanent_obstack);
9769 node = get_identifier (TREE_STRING_POINTER (node));
9770 location = alloc_name_constant (CONSTANT_String, node);
9771 node = build_ref_from_constant_pool (location);
9772 }
cd9643f7 9773 TREE_TYPE (node) = string_ptr_type_node;
b67d701b
PB
9774 TREE_CONSTANT (node) = 1;
9775 return node;
9776}
9777
9778/* Build an incomplete unary operator expression. */
e04a16fb
AG
9779
9780static tree
9781build_unaryop (op_token, op_location, op1)
9782 int op_token, op_location;
9783 tree op1;
9784{
9785 enum tree_code op;
9786 tree unaryop;
9787 switch (op_token)
9788 {
b67d701b 9789 case PLUS_TK: op = UNARY_PLUS_EXPR; break;
e04a16fb
AG
9790 case MINUS_TK: op = NEGATE_EXPR; break;
9791 case NEG_TK: op = TRUTH_NOT_EXPR; break;
9792 case NOT_TK: op = BIT_NOT_EXPR; break;
9793 default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
9794 op_token);
9795 }
9796
9797 unaryop = build1 (op, NULL_TREE, op1);
e04a16fb
AG
9798 TREE_SIDE_EFFECTS (unaryop) = 1;
9799 /* Store the location of the operator, for better error report. The
9800 string of the operator will be rebuild based on the OP value. */
9801 EXPR_WFL_LINECOL (unaryop) = op_location;
9802 return unaryop;
9803}
9804
9805/* Special case for the ++/-- operators, since they require an extra
9806 argument to build, which is set to NULL and patched
9807 later. IS_POST_P is 1 if the operator, 0 otherwise. */
9808
9809static tree
9810build_incdec (op_token, op_location, op1, is_post_p)
9811 int op_token, op_location;
9812 tree op1;
9813 int is_post_p;
9814{
9815 static enum tree_code lookup [2][2] =
9816 {
9817 { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
9818 { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
9819 };
9820 tree node = build (lookup [is_post_p][(op_token - DECR_TK)],
9821 NULL_TREE, op1, NULL_TREE);
9822 TREE_SIDE_EFFECTS (node) = 1;
9823 /* Store the location of the operator, for better error report. The
9824 string of the operator will be rebuild based on the OP value. */
9825 EXPR_WFL_LINECOL (node) = op_location;
9826 return node;
9827}
9828
9829/* Build an incomplete cast operator, based on the use of the
9830 CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
9831 set. java_complete_tree is trained to walk a CONVERT_EXPR even
9832 though its type is already set. */
9833
9834static tree
9835build_cast (location, type, exp)
9836 int location;
9837 tree type, exp;
9838{
9839 tree node = build1 (CONVERT_EXPR, type, exp);
9840 EXPR_WFL_LINECOL (node) = location;
9841 return node;
9842}
9843
9844/* 15.14 Unary operators. We return error_mark_node in case of error,
9845 but preserve the type of NODE if the type is fixed. */
9846
9847static tree
9848patch_unaryop (node, wfl_op)
9849 tree node;
9850 tree wfl_op;
9851{
9852 tree op = TREE_OPERAND (node, 0);
9853 tree op_type = TREE_TYPE (op);
ab3a6dd6 9854 tree prom_type = NULL_TREE, value, decl;
e04a16fb
AG
9855 int code = TREE_CODE (node);
9856 int error_found = 0;
9857
9858 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9859
9860 switch (code)
9861 {
9862 /* 15.13.2 Postfix Increment Operator ++ */
9863 case POSTINCREMENT_EXPR:
9864 /* 15.13.3 Postfix Increment Operator -- */
9865 case POSTDECREMENT_EXPR:
9866 /* 15.14.1 Prefix Increment Operator ++ */
9867 case PREINCREMENT_EXPR:
9868 /* 15.14.2 Prefix Decrement Operator -- */
9869 case PREDECREMENT_EXPR:
e28cd97b 9870 decl = strip_out_static_field_access_decl (op);
b3edebcf 9871 /* We really should have a JAVA_ARRAY_EXPR to avoid this */
e28cd97b 9872 if (!JDECL_P (decl)
b3edebcf
APB
9873 && TREE_CODE (decl) != COMPONENT_REF
9874 && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
9875 && TREE_CODE (decl) != INDIRECT_REF
9876 && !(TREE_CODE (decl) == COMPOUND_EXPR
9877 && TREE_OPERAND (decl, 1)
9878 && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
e04a16fb 9879 {
5e942c50
APB
9880 tree lvalue;
9881 /* Before screaming, check that we're not in fact trying to
9882 increment a optimized static final access, in which case
9883 we issue an different error message. */
9884 if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
9885 && resolve_expression_name (wfl_op, &lvalue)
9886 && check_final_assignment (lvalue, wfl_op)))
9887 parse_error_context (wfl_operator, "Invalid argument to `%s'",
9888 operator_string (node));
e04a16fb
AG
9889 TREE_TYPE (node) = error_mark_node;
9890 error_found = 1;
9891 }
5e942c50
APB
9892 else if (check_final_assignment (op, wfl_op))
9893 error_found = 1;
9894
e04a16fb
AG
9895 /* From now on, we know that op if a variable and that it has a
9896 valid wfl. We use wfl_op to locate errors related to the
9897 ++/-- operand. */
9898 else if (!JNUMERIC_TYPE_P (op_type))
9899 {
9900 parse_error_context
9901 (wfl_op, "Invalid argument type `%s' to `%s'",
0a2138e2 9902 lang_printable_name (op_type, 0), operator_string (node));
e04a16fb
AG
9903 TREE_TYPE (node) = error_mark_node;
9904 error_found = 1;
9905 }
9906 else
9907 {
4a5f66c3 9908 /* Before the addition, binary numeric promotion is performed on
e04a16fb 9909 both operands */
4a5f66c3
APB
9910 value = build_int_2 (1, 0);
9911 TREE_TYPE (node) =
9912 binary_numeric_promotion (op_type, TREE_TYPE (value), &op, &value);
9913 /* And write the promoted incremented and increment */
9914 TREE_OPERAND (node, 0) = op;
e04a16fb 9915 TREE_OPERAND (node, 1) = value;
4a5f66c3
APB
9916 /* Convert the overall back into its original type. */
9917 return fold (convert (op_type, node));
e04a16fb
AG
9918 }
9919 break;
9920
9921 /* 15.14.3 Unary Plus Operator + */
b67d701b 9922 case UNARY_PLUS_EXPR:
e04a16fb
AG
9923 /* 15.14.4 Unary Minus Operator - */
9924 case NEGATE_EXPR:
9925 if (!JNUMERIC_TYPE_P (op_type))
9926 {
9927 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
9928 TREE_TYPE (node) = error_mark_node;
9929 error_found = 1;
9930 }
9931 /* Unary numeric promotion is performed on operand */
9932 else
9933 {
15fdcfe9
PB
9934 op = do_unary_numeric_promotion (op);
9935 prom_type = TREE_TYPE (op);
b67d701b 9936 if (code == UNARY_PLUS_EXPR)
4a5f66c3 9937 return fold (op);
e04a16fb
AG
9938 }
9939 break;
9940
9941 /* 15.14.5 Bitwise Complement Operator ~ */
9942 case BIT_NOT_EXPR:
9943 if (!JINTEGRAL_TYPE_P (op_type))
9944 {
9945 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
9946 TREE_TYPE (node) = error_mark_node;
9947 error_found = 1;
9948 }
9949 else
9950 {
15fdcfe9
PB
9951 op = do_unary_numeric_promotion (op);
9952 prom_type = TREE_TYPE (op);
e04a16fb
AG
9953 }
9954 break;
9955
9956 /* 15.14.6 Logical Complement Operator ! */
9957 case TRUTH_NOT_EXPR:
9958 if (TREE_CODE (op_type) != BOOLEAN_TYPE)
9959 {
9960 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
c877974e
APB
9961 /* But the type is known. We will report an error if further
9962 attempt of a assignment is made with this rhs */
e04a16fb
AG
9963 TREE_TYPE (node) = boolean_type_node;
9964 error_found = 1;
9965 }
9966 else
9967 prom_type = boolean_type_node;
9968 break;
9969
9970 /* 15.15 Cast Expression */
9971 case CONVERT_EXPR:
0a2138e2 9972 value = patch_cast (node, wfl_operator);
e04a16fb 9973 if (value == error_mark_node)
c877974e
APB
9974 {
9975 /* If this cast is part of an assignment, we tell the code
9976 that deals with it not to complain about a mismatch,
9977 because things have been cast, anyways */
9978 TREE_TYPE (node) = error_mark_node;
9979 error_found = 1;
9980 }
9981 else
dc0b3eff
PB
9982 {
9983 value = fold (value);
9984 TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
9985 return value;
9986 }
e04a16fb
AG
9987 break;
9988 }
9989
e04a16fb
AG
9990 if (error_found)
9991 return error_mark_node;
4a5f66c3
APB
9992
9993 /* There are cases where node has been replaced by something else
9994 and we don't end up returning here: UNARY_PLUS_EXPR,
9995 CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
7525cc04 9996 TREE_OPERAND (node, 0) = fold (op);
4a5f66c3 9997 TREE_TYPE (node) = prom_type;
dc0b3eff 9998 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
e04a16fb
AG
9999 return fold (node);
10000}
10001
10002/* Generic type resolution that sometimes takes place during node
10003 patching. Returned the resolved type or generate an error
10004 message. Return the resolved type or NULL_TREE. */
10005
10006static tree
10007resolve_type_during_patch (type)
10008 tree type;
10009{
10010 if (unresolved_type_p (type, NULL))
10011 {
10012 tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
10013 if (!type_decl)
10014 {
10015 parse_error_context (type,
10016 "Class `%s' not found in type declaration",
10017 IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
10018 return NULL_TREE;
10019 }
10020 else
5e942c50
APB
10021 {
10022 CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
10023 return TREE_TYPE (type_decl);
10024 }
e04a16fb
AG
10025 }
10026 return type;
10027}
10028/* 5.5 Casting Conversion. error_mark_node is returned if an error is
10029 found. Otherwise NODE or something meant to replace it is returned. */
10030
10031static tree
0a2138e2 10032patch_cast (node, wfl_operator)
e04a16fb 10033 tree node;
e04a16fb
AG
10034 tree wfl_operator;
10035{
10036 tree op = TREE_OPERAND (node, 0);
10037 tree op_type = TREE_TYPE (op);
10038 tree cast_type = TREE_TYPE (node);
10039 char *t1;
10040
10041 /* First resolve OP_TYPE if unresolved */
10042 if (!(cast_type = resolve_type_during_patch (cast_type)))
10043 return error_mark_node;
10044
10045 /* Check on cast that are proven correct at compile time */
10046 if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
10047 {
10048 static tree convert_narrow ();
10049 /* Same type */
10050 if (cast_type == op_type)
10051 return node;
10052
0b4d333e
APB
10053 /* float and double type are converted to the original type main
10054 variant and then to the target type. */
10055 if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
10056 op = convert (integer_type_node, op);
10057
e04a16fb
AG
10058 /* Try widening/narowwing convertion. Potentially, things need
10059 to be worked out in gcc so we implement the extreme cases
10060 correctly. fold_convert() needs to be fixed. */
10061 return convert (cast_type, op);
10062 }
10063
0b4d333e
APB
10064 /* It's also valid to cast a boolean into a boolean */
10065 if (op_type == boolean_type_node && cast_type == boolean_type_node)
10066 return node;
10067
5e942c50
APB
10068 /* null can be casted to references */
10069 if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
10070 return build_null_of_type (cast_type);
10071
e04a16fb
AG
10072 /* The remaining legal casts involve conversion between reference
10073 types. Check for their compile time correctness. */
10074 if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type)
09ed0f70 10075 && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
e04a16fb
AG
10076 {
10077 TREE_TYPE (node) = promote_type (cast_type);
10078 /* Now, the case can be determined correct at compile time if
10079 OP_TYPE can be converted into CAST_TYPE by assignment
10080 conversion (5.2) */
10081
10082 if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
15fdcfe9
PB
10083 {
10084 TREE_SET_CODE (node, NOP_EXPR);
10085 return node;
10086 }
10087
10088 if (flag_emit_class_files)
10089 {
10090 TREE_SET_CODE (node, CONVERT_EXPR);
10091 return node;
10092 }
e04a16fb
AG
10093
10094 /* The cast requires a run-time check */
10095 return build (CALL_EXPR, promote_type (cast_type),
10096 build_address_of (soft_checkcast_node),
10097 tree_cons (NULL_TREE, build_class_ref (cast_type),
10098 build_tree_list (NULL_TREE, op)),
10099 NULL_TREE);
10100 }
10101
10102 /* Any other casts are proven incorrect at compile time */
0a2138e2 10103 t1 = strdup (lang_printable_name (op_type, 0));
e04a16fb 10104 parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
0a2138e2 10105 t1, lang_printable_name (cast_type, 0));
e04a16fb
AG
10106 free (t1);
10107 return error_mark_node;
10108}
10109
5e942c50
APB
10110/* Build a null constant and give it the type TYPE. */
10111
10112static tree
10113build_null_of_type (type)
10114 tree type;
10115{
10116 tree node = build_int_2 (0, 0);
10117 TREE_TYPE (node) = promote_type (type);
10118 return node;
10119}
10120
e04a16fb
AG
10121/* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
10122 a list of indices. */
10123static tree
10124build_array_ref (location, array, index)
10125 int location;
10126 tree array, index;
10127{
10128 tree node = build (ARRAY_REF, NULL_TREE, array, index);
10129 EXPR_WFL_LINECOL (node) = location;
10130 return node;
10131}
10132
10133/* 15.12 Array Access Expression */
10134
10135static tree
c877974e
APB
10136patch_array_ref (node)
10137 tree node;
e04a16fb
AG
10138{
10139 tree array = TREE_OPERAND (node, 0);
10140 tree array_type = TREE_TYPE (array);
10141 tree index = TREE_OPERAND (node, 1);
10142 tree index_type = TREE_TYPE (index);
e04a16fb
AG
10143 int error_found = 0;
10144
10145 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10146
e04a16fb
AG
10147 if (TREE_CODE (array_type) == POINTER_TYPE)
10148 array_type = TREE_TYPE (array_type);
10149
10150 /* The array reference must be an array */
10151 if (!TYPE_ARRAY_P (array_type))
10152 {
10153 parse_error_context
10154 (wfl_operator, "`[]' can only be applied to arrays. It can't be "
0a2138e2 10155 "applied to `%s'", lang_printable_name (array_type, 0));
e04a16fb
AG
10156 TREE_TYPE (node) = error_mark_node;
10157 error_found = 1;
10158 }
10159
10160 /* The array index underdoes unary numeric promotion. The promoted
10161 type must be int */
15fdcfe9
PB
10162 index = do_unary_numeric_promotion (index);
10163 if (TREE_TYPE (index) != int_type_node)
e04a16fb 10164 {
b67d701b 10165 int could_cast = valid_cast_to_p (index_type, int_type_node);
e04a16fb
AG
10166 parse_error_context
10167 (wfl_operator,
10168 (could_cast ? "Incompatible type for `[]'. Explicit cast needed to "
10169 "convert `%s' to `int'" : "Incompatible type for `[]'. "
10170 "Can't convert `%s' to `int'"),
0a2138e2 10171 lang_printable_name (index_type, 0));
e04a16fb
AG
10172 TREE_TYPE (node) = error_mark_node;
10173 error_found = 1;
10174 }
10175
e04a16fb
AG
10176 if (error_found)
10177 return error_mark_node;
e04a16fb 10178
5e942c50 10179 array_type = TYPE_ARRAY_ELEMENT (array_type);
5e942c50 10180
7f1d4866 10181 if (flag_emit_class_files || flag_emit_xref)
e04a16fb 10182 {
15fdcfe9
PB
10183 TREE_OPERAND (node, 0) = array;
10184 TREE_OPERAND (node, 1) = index;
e04a16fb
AG
10185 }
10186 else
939d7216
PB
10187 {
10188 /* The save_expr is for correct evaluation order. It would be cleaner
10189 to use force_evaluation_order (see comment there), but that is
10190 difficult when we also have to deal with bounds checking. */
10191 if (TREE_SIDE_EFFECTS (index))
10192 array = save_expr (array);
10193 node = build_java_arrayaccess (array, array_type, index);
10194 if (TREE_SIDE_EFFECTS (index))
10195 node = build (COMPOUND_EXPR, array_type, array, node);
10196 }
e04a16fb
AG
10197 TREE_TYPE (node) = array_type;
10198 return node;
10199}
10200
10201/* 15.9 Array Creation Expressions */
10202
10203static tree
10204build_newarray_node (type, dims, extra_dims)
10205 tree type;
10206 tree dims;
10207 int extra_dims;
10208{
10209 tree node =
b67d701b 10210 build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims),
e04a16fb 10211 build_int_2 (extra_dims, 0));
e04a16fb
AG
10212 return node;
10213}
10214
10215static tree
10216patch_newarray (node)
10217 tree node;
10218{
10219 tree type = TREE_OPERAND (node, 0);
10220 tree dims = TREE_OPERAND (node, 1);
10221 tree cdim, array_type;
10222 int error_found = 0;
10223 int ndims = 0;
10224 int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
e04a16fb
AG
10225
10226 /* Dimension types are verified. It's better for the types to be
10227 verified in order. */
10228 for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
10229 {
10230 int dim_error = 0;
10231 tree dim = TREE_VALUE (cdim);
10232
10233 /* Dim might have been saved during its evaluation */
10234 dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
10235
10236 /* The type of each specified dimension must be an integral type. */
10237 if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
10238 dim_error = 1;
10239
10240 /* Each expression undergoes an unary numeric promotion (5.6.1) and the
10241 promoted type must be int. */
10242 else
10243 {
15fdcfe9 10244 dim = do_unary_numeric_promotion (dim);
e04a16fb
AG
10245 if (TREE_TYPE (dim) != int_type_node)
10246 dim_error = 1;
10247 }
10248
10249 /* Report errors on types here */
10250 if (dim_error)
10251 {
10252 parse_error_context
10253 (TREE_PURPOSE (cdim),
10254 "Incompatible type for dimension in array creation expression. "
10255 "%s convert `%s' to `int'",
b67d701b 10256 (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
e04a16fb 10257 "Explicit cast needed to" : "Can't"),
0a2138e2 10258 lang_printable_name (TREE_TYPE (dim), 0));
e04a16fb
AG
10259 error_found = 1;
10260 }
10261
e04a16fb
AG
10262 TREE_PURPOSE (cdim) = NULL_TREE;
10263 }
10264
10265 /* Resolve array base type if unresolved */
10266 if (!(type = resolve_type_during_patch (type)))
10267 error_found = 1;
10268
10269 if (error_found)
10270 {
10271 /* We don't want further evaluation of this bogus array creation
10272 operation */
10273 TREE_TYPE (node) = error_mark_node;
10274 return error_mark_node;
10275 }
10276
15fdcfe9
PB
10277 /* Set array_type to the actual (promoted) array type of the result. */
10278 if (TREE_CODE (type) == RECORD_TYPE)
10279 type = build_pointer_type (type);
10280 while (--xdims >= 0)
10281 {
10282 type = promote_type (build_java_array_type (type, -1));
10283 }
10284 dims = nreverse (dims);
10285 array_type = type;
10286 for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
10287 {
10288 type = array_type;
10289 array_type = build_java_array_type (type,
10290 TREE_CODE (cdim) == INTEGER_CST ?
10291 TREE_INT_CST_LOW (cdim) : -1);
10292 array_type = promote_type (array_type);
10293 }
10294 dims = nreverse (dims);
10295
e04a16fb
AG
10296 /* The node is transformed into a function call. Things are done
10297 differently according to the number of dimensions. If the number
10298 of dimension is equal to 1, then the nature of the base type
10299 (primitive or not) matters. */
15fdcfe9 10300 if (ndims == 1)
fdec99c6 10301 return build_new_array (type, TREE_VALUE (dims));
e04a16fb 10302
e04a16fb
AG
10303 /* Can't reuse what's already written in expr.c because it uses the
10304 JVM stack representation. Provide a build_multianewarray. FIXME */
15fdcfe9 10305 return build (CALL_EXPR, array_type,
e04a16fb 10306 build_address_of (soft_multianewarray_node),
15fdcfe9 10307 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
e04a16fb 10308 tree_cons (NULL_TREE,
15fdcfe9 10309 build_int_2 (ndims, 0), dims )),
e04a16fb
AG
10310 NULL_TREE);
10311}
10312
f8976021
APB
10313/* 10.6 Array initializer. */
10314
10315/* Build a wfl for array element that don't have one, so we can
10316 pin-point errors. */
10317
10318static tree
10319maybe_build_array_element_wfl (node)
10320 tree node;
10321{
10322 if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
10323 return build_expr_wfl (NULL_TREE, ctxp->filename,
10324 ctxp->elc.line, ctxp->elc.prev_col);
10325 else
10326 return NULL_TREE;
10327}
10328
10329/* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
10330 identification of initialized arrays easier to detect during walk
10331 and expansion. */
10332
10333static tree
10334build_new_array_init (location, values)
10335 int location;
10336 tree values;
10337{
10338 tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
10339 tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
5bba4807 10340 EXPR_WFL_LINECOL (to_return) = location;
f8976021
APB
10341 return to_return;
10342}
10343
10344/* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
10345 occurred. Otherwise return NODE after having set its type
10346 appropriately. */
10347
10348static tree
10349patch_new_array_init (type, node)
10350 tree type, node;
f8976021
APB
10351{
10352 int error_seen = 0;
fdec99c6 10353 tree current, element_type;
f8976021 10354 HOST_WIDE_INT length;
fdec99c6
PB
10355 int all_constant = 1;
10356 tree init = TREE_OPERAND (node, 0);
f8976021 10357
fdec99c6
PB
10358 if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
10359 {
10360 parse_error_context (node,
10361 "Invalid array initializer for non-array type `%s'",
10362 lang_printable_name (type, 1));
10363 return error_mark_node;
10364 }
10365 type = TREE_TYPE (type);
10366 element_type = TYPE_ARRAY_ELEMENT (type);
f8976021 10367
fdec99c6
PB
10368 CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
10369
10370 for (length = 0, current = CONSTRUCTOR_ELTS (init);
10371 current; length++, current = TREE_CHAIN (current))
f8976021 10372 {
fdec99c6
PB
10373 tree elt = TREE_VALUE (current);
10374 if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
f8976021 10375 {
fdec99c6 10376 error_seen |= array_constructor_check_entry (element_type, current);
5bba4807
PB
10377 elt = TREE_VALUE (current);
10378 /* When compiling to native code, STRING_CST is converted to
10379 INDIRECT_REF, but still with a TREE_CONSTANT flag. */
10380 if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
fdec99c6 10381 all_constant = 0;
f8976021 10382 }
fdec99c6
PB
10383 else
10384 {
10385 TREE_VALUE (current) = patch_new_array_init (element_type, elt);
10386 TREE_PURPOSE (current) = NULL_TREE;
10387 all_constant = 0;
10388 }
10389 if (elt && TREE_VALUE (elt) == error_mark_node)
10390 error_seen = 1;
f8976021
APB
10391 }
10392
10393 if (error_seen)
10394 return error_mark_node;
10395
10396 /* Create a new type. We can't reuse the one we have here by
10397 patching its dimension because it originally is of dimension -1
10398 hence reused by gcc. This would prevent triangular arrays. */
fdec99c6
PB
10399 type = build_java_array_type (element_type, length);
10400 TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
10401 TREE_TYPE (node) = promote_type (type);
10402 TREE_CONSTANT (init) = all_constant;
bc3ca41b 10403 TREE_CONSTANT (node) = all_constant;
f8976021
APB
10404 return node;
10405}
10406
10407/* Verify that one entry of the initializer element list can be
10408 assigned to the array base type. Report 1 if an error occurred, 0
10409 otherwise. */
10410
10411static int
10412array_constructor_check_entry (type, entry)
10413 tree type, entry;
10414{
10415 char *array_type_string = NULL; /* For error reports */
10416 tree value, type_value, new_value, wfl_value, patched;
10417 int error_seen = 0;
10418
10419 new_value = NULL_TREE;
10420 wfl_value = TREE_VALUE (entry);
10421
f8976021 10422 value = java_complete_tree (TREE_VALUE (entry));
1179ebc2 10423 /* patch_string return error_mark_node if arg is error_mark_node */
f8976021
APB
10424 if ((patched = patch_string (value)))
10425 value = patched;
1179ebc2
APB
10426 if (value == error_mark_node)
10427 return 1;
f8976021 10428
f8976021
APB
10429 type_value = TREE_TYPE (value);
10430
1179ebc2 10431 /* At anytime, try_builtin_assignconv can report a warning on
f8976021
APB
10432 constant overflow during narrowing. */
10433 SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
10434 new_value = try_builtin_assignconv (wfl_operator, type, value);
10435 if (!new_value && (new_value = try_reference_assignconv (type, value)))
10436 type_value = promote_type (type);
10437
10438 /* Check and report errors */
10439 if (!new_value)
10440 {
10441 char *msg = (!valid_cast_to_p (type_value, type) ?
10442 "Can't" : "Explicit cast needed to");
10443 if (!array_type_string)
10444 array_type_string = strdup (lang_printable_name (type, 1));
10445 parse_error_context
10446 (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
10447 msg, lang_printable_name (type_value, 1), array_type_string);
10448 error_seen = 1;
10449 }
10450
10451 if (new_value)
10452 {
10453 new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
10454 TREE_VALUE (entry) = new_value;
10455 }
10456
10457 if (array_type_string)
10458 free (array_type_string);
10459
10460 TREE_PURPOSE (entry) = NULL_TREE;
10461 return error_seen;
10462}
10463
e04a16fb
AG
10464static tree
10465build_this (location)
10466 int location;
10467{
9ee9b555 10468 tree node = build_wfl_node (this_identifier_node);
b67d701b 10469 TREE_SET_CODE (node, THIS_EXPR);
e04a16fb
AG
10470 EXPR_WFL_LINECOL (node) = location;
10471 return node;
10472}
10473
10474/* 14.15 The return statement. It builds a modify expression that
10475 assigns the returned value to the RESULT_DECL that hold the value
10476 to be returned. */
10477
10478static tree
10479build_return (location, op)
10480 int location;
10481 tree op;
10482{
10483 tree node = build1 (RETURN_EXPR, NULL_TREE, op);
10484 EXPR_WFL_LINECOL (node) = location;
b67d701b 10485 node = build_debugable_stmt (location, node);
e04a16fb
AG
10486 return node;
10487}
10488
10489static tree
10490patch_return (node)
10491 tree node;
10492{
10493 tree return_exp = TREE_OPERAND (node, 0);
10494 tree meth = current_function_decl;
10495 tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
e04a16fb
AG
10496 int error_found = 0;
10497
10498 TREE_TYPE (node) = error_mark_node;
10499 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10500
10501 /* It's invalid to have a return value within a function that is
10502 declared with the keyword void or that is a constructor */
10503 if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
10504 error_found = 1;
10505
f099f336 10506 /* It's invalid to use a return statement in a static block */
7f1d4866 10507 if (IS_CLINIT (current_function_decl))
f099f336
APB
10508 error_found = 1;
10509
e04a16fb
AG
10510 /* It's invalid to have a no return value within a function that
10511 isn't declared with the keyword `void' */
10512 if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
10513 error_found = 2;
10514
10515 if (error_found)
10516 {
7f1d4866 10517 if (IS_CLINIT (current_function_decl))
f099f336
APB
10518 parse_error_context (wfl_operator,
10519 "`return' inside static initializer.");
10520
10521 else if (!DECL_CONSTRUCTOR_P (meth))
22eed1e6
APB
10522 {
10523 char *t = strdup (lang_printable_name (mtype, 0));
10524 parse_error_context (wfl_operator,
10525 "`return' with%s value from `%s %s'",
10526 (error_found == 1 ? "" : "out"),
10527 t, lang_printable_name (meth, 0));
10528 free (t);
10529 }
10530 else
10531 parse_error_context (wfl_operator,
10532 "`return' with value from constructor `%s'",
10533 lang_printable_name (meth, 0));
e04a16fb
AG
10534 return error_mark_node;
10535 }
10536
5e942c50
APB
10537 /* If we have a return_exp, build a modify expression and expand
10538 it. Note: at that point, the assignment is declared valid, but we
10539 may want to carry some more hacks */
e04a16fb
AG
10540 if (return_exp)
10541 {
5e942c50
APB
10542 tree exp = java_complete_tree (return_exp);
10543 tree modify, patched;
10544
10545 /* If the function returned value and EXP are booleans, EXP has
10546 to be converted into the type of DECL_RESULT, which is integer
10547 (see complete_start_java_method) */
10548 if (TREE_TYPE (exp) == boolean_type_node &&
10549 TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
10550 exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
10551
10552 /* `null' can be assigned to a function returning a reference */
10553 if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
10554 exp == null_pointer_node)
10555 exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
10556
10557 if ((patched = patch_string (exp)))
10558 exp = patched;
10559
10560 modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
e04a16fb
AG
10561 EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
10562 modify = java_complete_tree (modify);
5e942c50 10563
e04a16fb
AG
10564 if (modify != error_mark_node)
10565 {
10566 TREE_SIDE_EFFECTS (modify) = 1;
10567 TREE_OPERAND (node, 0) = modify;
10568 }
10569 else
10570 return error_mark_node;
10571 }
10572 TREE_TYPE (node) = void_type_node;
10573 TREE_SIDE_EFFECTS (node) = 1;
10574 return node;
10575}
10576
10577/* 14.8 The if Statement */
10578
10579static tree
10580build_if_else_statement (location, expression, if_body, else_body)
10581 int location;
10582 tree expression, if_body, else_body;
10583{
10584 tree node;
e04a16fb 10585 if (!else_body)
9bbc7d9f 10586 else_body = empty_stmt_node;
e04a16fb
AG
10587 node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
10588 EXPR_WFL_LINECOL (node) = location;
b67d701b 10589 node = build_debugable_stmt (location, node);
e04a16fb
AG
10590 return node;
10591}
10592
10593static tree
10594patch_if_else_statement (node)
10595 tree node;
10596{
10597 tree expression = TREE_OPERAND (node, 0);
10598
10599 TREE_TYPE (node) = error_mark_node;
10600 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10601
10602 /* The type of expression must be boolean */
b67d701b
PB
10603 if (TREE_TYPE (expression) != boolean_type_node
10604 && TREE_TYPE (expression) != promoted_boolean_type_node)
e04a16fb
AG
10605 {
10606 parse_error_context
10607 (wfl_operator,
10608 "Incompatible type for `if'. Can't convert `%s' to `boolean'",
0a2138e2 10609 lang_printable_name (TREE_TYPE (expression), 0));
e04a16fb
AG
10610 return error_mark_node;
10611 }
10612
10613 TREE_TYPE (node) = void_type_node;
10614 TREE_SIDE_EFFECTS (node) = 1;
15fdcfe9 10615 CAN_COMPLETE_NORMALLY (node)
9bbc7d9f
PB
10616 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
10617 | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
e04a16fb
AG
10618 return node;
10619}
10620
10621/* 14.6 Labeled Statements */
10622
10623/* Action taken when a lableled statement is parsed. a new
10624 LABELED_BLOCK_EXPR is created. No statement is attached to the
b635eb2f 10625 label, yet. LABEL can be NULL_TREE for artificially-generated blocks. */
e04a16fb
AG
10626
10627static tree
0a2138e2 10628build_labeled_block (location, label)
e04a16fb 10629 int location;
0a2138e2 10630 tree label;
e04a16fb 10631{
b635eb2f 10632 tree label_name ;
e04a16fb 10633 tree label_decl, node;
b635eb2f
PB
10634 if (label == NULL_TREE || label == continue_identifier_node)
10635 label_name = label;
10636 else
e04a16fb 10637 {
b635eb2f
PB
10638 label_name = merge_qualified_name (label_id, label);
10639 /* Issue an error if we try to reuse a label that was previously
10640 declared */
10641 if (IDENTIFIER_LOCAL_VALUE (label_name))
10642 {
10643 EXPR_WFL_LINECOL (wfl_operator) = location;
10644 parse_error_context (wfl_operator, "Declaration of `%s' shadows "
10645 "a previous label declaration",
10646 IDENTIFIER_POINTER (label));
10647 EXPR_WFL_LINECOL (wfl_operator) =
10648 EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
10649 parse_error_context (wfl_operator, "This is the location of the "
10650 "previous declaration of label `%s'",
10651 IDENTIFIER_POINTER (label));
10652 java_error_count--;
10653 }
e04a16fb
AG
10654 }
10655
10656 label_decl = create_label_decl (label_name);
10657 node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
10658 EXPR_WFL_LINECOL (node) = location;
10659 TREE_SIDE_EFFECTS (node) = 1;
10660 return node;
10661}
10662
b67d701b 10663/* A labeled statement LBE is attached a statement. */
e04a16fb
AG
10664
10665static tree
b635eb2f 10666finish_labeled_statement (lbe, statement)
e04a16fb
AG
10667 tree lbe; /* Labeled block expr */
10668 tree statement;
10669{
10670 /* In anyways, tie the loop to its statement */
10671 LABELED_BLOCK_BODY (lbe) = statement;
b635eb2f
PB
10672 pop_labeled_block ();
10673 POP_LABELED_BLOCK ();
e04a16fb
AG
10674 return lbe;
10675}
10676
10677/* 14.10, 14.11, 14.12 Loop Statements */
10678
10679/* Create an empty LOOP_EXPR and make it the last in the nested loop
10680 list. */
10681
10682static tree
10683build_new_loop (loop_body)
10684 tree loop_body;
10685{
10686 tree loop = build (LOOP_EXPR, NULL_TREE, loop_body);
10687 TREE_SIDE_EFFECTS (loop) = 1;
10688 PUSH_LOOP (loop);
10689 return loop;
10690}
10691
10692/* Create a loop body according to the following structure:
10693 COMPOUND_EXPR
10694 COMPOUND_EXPR (loop main body)
10695 EXIT_EXPR (this order is for while/for loops.
10696 LABELED_BLOCK_EXPR the order is reversed for do loops)
34f4db93 10697 LABEL_DECL (a continue occuring here branches at the
e04a16fb
AG
10698 BODY end of this labeled block)
10699 INCREMENT (if any)
10700
10701 REVERSED, if non zero, tells that the loop condition expr comes
b67d701b
PB
10702 after the body, like in the do-while loop.
10703
10704 To obtain a loop, the loop body structure described above is
10705 encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
10706
10707 LABELED_BLOCK_EXPR
10708 LABEL_DECL (use this label to exit the loop)
10709 LOOP_EXPR
10710 <structure described above> */
e04a16fb
AG
10711
10712static tree
10713build_loop_body (location, condition, reversed)
10714 int location;
10715 tree condition;
10716 int reversed;
10717{
0a2138e2 10718 tree first, second, body;
e04a16fb
AG
10719
10720 condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
10721 EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
10722 condition = build_debugable_stmt (location, condition);
10723 TREE_SIDE_EFFECTS (condition) = 1;
10724
b635eb2f 10725 body = build_labeled_block (0, continue_identifier_node);
e04a16fb
AG
10726 first = (reversed ? body : condition);
10727 second = (reversed ? condition : body);
10728 return
10729 build (COMPOUND_EXPR, NULL_TREE,
9bbc7d9f 10730 build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
e04a16fb
AG
10731}
10732
10733/* Install CONDITION (if any) and loop BODY (using REVERSED to tell
10734 their order) on the current loop. Unlink the current loop from the
10735 loop list. */
10736
10737static tree
b635eb2f 10738finish_loop_body (location, condition, body, reversed)
e04a16fb
AG
10739 int location;
10740 tree condition, body;
10741 int reversed;
10742{
10743 tree to_return = ctxp->current_loop;
10744 tree loop_body = LOOP_EXPR_BODY (to_return);
10745 if (condition)
10746 {
10747 tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
10748 /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
10749 The real EXIT_EXPR is one operand further. */
10750 EXPR_WFL_LINECOL (cnode) = location;
10751 /* This one is for accurate error reports */
10752 EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
10753 TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
10754 }
10755 LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
10756 POP_LOOP ();
10757 return to_return;
10758}
10759
b635eb2f 10760/* Tailored version of finish_loop_body for FOR loops, when FOR
e04a16fb
AG
10761 loops feature the condition part */
10762
10763static tree
b635eb2f 10764finish_for_loop (location, condition, update, body)
e04a16fb
AG
10765 int location;
10766 tree condition, update, body;
10767{
10768 /* Put the condition and the loop body in place */
b635eb2f 10769 tree loop = finish_loop_body (location, condition, body, 0);
e04a16fb
AG
10770 /* LOOP is the current loop which has been now popped of the loop
10771 stack. Install the update block */
10772 LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
10773 return loop;
10774}
10775
10776/* If the loop isn't surrounded by a labeled statement, create one and
b635eb2f 10777 insert LOOP as its body. */
e04a16fb
AG
10778
10779static tree
10780patch_loop_statement (loop)
10781 tree loop;
10782{
cd9643f7
PB
10783 tree loop_label;
10784 tree block = ctxp->current_labeled_block;
10785 TREE_TYPE (loop) = void_type_node;
10786 if (block != NULL_TREE)
e04a16fb 10787 {
cd9643f7
PB
10788 tree block_body = LABELED_BLOCK_BODY (block);
10789 if (IS_FOR_LOOP_P (loop))
10790 {
10791 if (TREE_CODE (block_body) == BLOCK)
10792 {
10793 block_body = BLOCK_EXPR_BODY (block_body);
10794 if (block_body == loop
10795 || (TREE_CODE (block_body) == COMPOUND_EXPR
10796 && TREE_OPERAND (block_body, 1) == loop))
10797 return loop;
10798 }
10799 }
10800 else
10801 {
10802 if (block_body == loop)
10803 return loop;
10804 }
e04a16fb 10805 }
cd9643f7
PB
10806 loop_label = build_labeled_block (0, NULL_TREE);
10807 LABELED_BLOCK_BODY (loop_label) = loop;
10808 PUSH_LABELED_BLOCK (loop_label);
10809 loop = loop_label;
b635eb2f 10810 return loop;
e04a16fb
AG
10811}
10812
10813/* 14.13, 14.14: break and continue Statements */
10814
10815/* Build a break or a continue statement. a null NAME indicates an
10816 unlabeled break/continue statement. */
10817
10818static tree
10819build_bc_statement (location, is_break, name)
10820 int location, is_break;
10821 tree name;
10822{
10823 tree break_continue, label_block_expr = NULL_TREE;
10824
10825 if (name)
10826 {
10827 if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE
10828 (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
10829 /* Null means that we don't have a target for this named
10830 break/continue. In this case, we make the target to be the
10831 label name, so that the error can be reported accuratly in
10832 patch_bc_statement. */
10833 label_block_expr = EXPR_WFL_NODE (name);
10834 }
10835 /* Unlabeled break/continue will be handled during the
10836 break/continue patch operation */
10837 break_continue
10838 = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
10839
10840 IS_BREAK_STMT_P (break_continue) = is_break;
10841 TREE_SIDE_EFFECTS (break_continue) = 1;
10842 EXPR_WFL_LINECOL (break_continue) = location;
b67d701b 10843 break_continue = build_debugable_stmt (location, break_continue);
e04a16fb
AG
10844 return break_continue;
10845}
10846
10847/* Verification of a break/continue statement. */
10848
10849static tree
10850patch_bc_statement (node)
10851 tree node;
10852{
10853 tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
b635eb2f 10854 tree labeled_block = ctxp->current_labeled_block;
b67d701b 10855 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
e04a16fb 10856
e04a16fb 10857 /* Having an identifier here means that the target is unknown. */
b635eb2f 10858 if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
e04a16fb
AG
10859 {
10860 parse_error_context (wfl_operator, "No label definition found for `%s'",
10861 IDENTIFIER_POINTER (bc_label));
10862 return error_mark_node;
10863 }
b635eb2f 10864 if (! IS_BREAK_STMT_P (node))
e04a16fb 10865 {
b635eb2f
PB
10866 /* It's a continue statement. */
10867 for (;; labeled_block = TREE_CHAIN (labeled_block))
e04a16fb 10868 {
b635eb2f
PB
10869 if (labeled_block == NULL_TREE)
10870 {
10871 if (bc_label == NULL_TREE)
10872 parse_error_context (wfl_operator,
10873 "`continue' must be in loop");
10874 else
1504b2b4
APB
10875 parse_error_context
10876 (wfl_operator, "continue label `%s' does not name a loop",
10877 IDENTIFIER_POINTER (bc_label));
b635eb2f
PB
10878 return error_mark_node;
10879 }
10880 if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
10881 == continue_identifier_node)
10882 && (bc_label == NULL_TREE
10883 || TREE_CHAIN (labeled_block) == bc_label))
10884 {
10885 bc_label = labeled_block;
10886 break;
10887 }
e04a16fb 10888 }
e04a16fb 10889 }
b635eb2f 10890 else if (!bc_label)
34f4db93 10891 {
b635eb2f 10892 for (;; labeled_block = TREE_CHAIN (labeled_block))
e04a16fb 10893 {
b635eb2f
PB
10894 if (labeled_block == NULL_TREE)
10895 {
10896 parse_error_context (wfl_operator,
10897 "`break' must be in loop or switch");
10898 return error_mark_node;
10899 }
10900 target_stmt = LABELED_BLOCK_BODY (labeled_block);
10901 if (TREE_CODE (target_stmt) == SWITCH_EXPR
10902 || TREE_CODE (target_stmt) == LOOP_EXPR)
10903 {
10904 bc_label = labeled_block;
10905 break;
10906 }
e04a16fb 10907 }
e04a16fb
AG
10908 }
10909
b635eb2f 10910 EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
15fdcfe9
PB
10911 CAN_COMPLETE_NORMALLY (bc_label) = 1;
10912
e04a16fb
AG
10913 /* Our break/continue don't return values. */
10914 TREE_TYPE (node) = void_type_node;
10915 /* Encapsulate the break within a compound statement so that it's
10916 expanded all the times by expand_expr (and not clobered
10917 sometimes, like after a if statement) */
10918 node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
10919 TREE_SIDE_EFFECTS (node) = 1;
10920 return node;
10921}
10922
10923/* Process the exit expression belonging to a loop. Its type must be
10924 boolean. */
10925
10926static tree
10927patch_exit_expr (node)
10928 tree node;
10929{
10930 tree expression = TREE_OPERAND (node, 0);
10931 TREE_TYPE (node) = error_mark_node;
10932 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10933
10934 /* The type of expression must be boolean */
10935 if (TREE_TYPE (expression) != boolean_type_node)
10936 {
10937 parse_error_context
10938 (wfl_operator,
10939 "Incompatible type for loop conditional. Can't convert `%s' to "
10940 "`boolean'",
0a2138e2 10941 lang_printable_name (TREE_TYPE (expression), 0));
e04a16fb
AG
10942 return error_mark_node;
10943 }
10944 /* Now we know things are allright, invert the condition, fold and
10945 return */
10946 TREE_OPERAND (node, 0) =
10947 fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
15fdcfe9
PB
10948
10949 if (! integer_zerop (TREE_OPERAND (node, 0))
10950 && ctxp->current_loop != NULL_TREE
10951 && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
10952 CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
10953 if (! integer_onep (TREE_OPERAND (node, 0)))
10954 CAN_COMPLETE_NORMALLY (node) = 1;
10955
10956
e04a16fb
AG
10957 TREE_TYPE (node) = void_type_node;
10958 return node;
10959}
b67d701b
PB
10960
10961/* 14.9 Switch statement */
10962
10963static tree
10964patch_switch_statement (node)
10965 tree node;
10966{
c877974e 10967 tree se = TREE_OPERAND (node, 0), se_type;
b67d701b
PB
10968
10969 /* Complete the switch expression */
10970 se = TREE_OPERAND (node, 0) = java_complete_tree (se);
10971 se_type = TREE_TYPE (se);
10972 /* The type of the switch expression must be char, byte, short or
10973 int */
10974 if (!JINTEGRAL_TYPE_P (se_type))
10975 {
10976 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10977 parse_error_context (wfl_operator, "Incompatible type for `switch'. "
10978 "Can't convert `%s' to `int'",
0a2138e2 10979 lang_printable_name (se_type, 0));
b67d701b
PB
10980 /* This is what java_complete_tree will check */
10981 TREE_OPERAND (node, 0) = error_mark_node;
10982 return error_mark_node;
10983 }
10984
15fdcfe9 10985 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
b67d701b
PB
10986
10987 /* Ready to return */
15fdcfe9 10988 if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
b67d701b
PB
10989 {
10990 TREE_TYPE (node) = error_mark_node;
10991 return error_mark_node;
10992 }
10993 TREE_TYPE (node) = void_type_node;
10994 TREE_SIDE_EFFECTS (node) = 1;
15fdcfe9 10995 CAN_COMPLETE_NORMALLY (node)
c877974e
APB
10996 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
10997 || ! SWITCH_HAS_DEFAULT (node);
b67d701b
PB
10998 return node;
10999}
11000
b67d701b
PB
11001/* 14.18 The try statement */
11002
b67d701b 11003static tree
a7d8d81f 11004build_try_statement (location, try_block, catches)
b67d701b 11005 int location;
a7d8d81f
PB
11006 tree try_block, catches;
11007{
11008 tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
b67d701b 11009 EXPR_WFL_LINECOL (node) = location;
a7d8d81f 11010 return node;
b67d701b
PB
11011}
11012
a7d8d81f
PB
11013static tree
11014build_try_finally_statement (location, try_block, finally)
11015 int location;
11016 tree try_block, finally;
b67d701b 11017{
a7d8d81f
PB
11018 tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
11019 EXPR_WFL_LINECOL (node) = location;
11020 return node;
b67d701b
PB
11021}
11022
11023static tree
11024patch_try_statement (node)
11025 tree node;
11026{
11027 int error_found = 0;
11028 tree try = TREE_OPERAND (node, 0);
11029 /* Exception handlers are considered in left to right order */
11030 tree catch = nreverse (TREE_OPERAND (node, 1));
b9f7e36c 11031 tree current, caught_type_list = NULL_TREE;
b67d701b
PB
11032
11033 /* Check catch clauses, if any. Every time we find an error, we try
b9f7e36c
APB
11034 to process the next catch clause. We process the catch clause before
11035 the try block so that when processing the try block we can check thrown
11036 exceptions againts the caught type list. */
b67d701b
PB
11037 for (current = catch; current; current = TREE_CHAIN (current))
11038 {
11039 tree carg_decl, carg_type;
11040 tree sub_current, catch_block, catch_clause;
11041 int unreachable;
11042
b67d701b 11043 /* At this point, the structure of the catch clause is
b67d701b
PB
11044 CATCH_EXPR (catch node)
11045 BLOCK (with the decl of the parameter)
11046 COMPOUND_EXPR
7525cc04 11047 MODIFY_EXPR (assignment of the catch parameter)
b67d701b 11048 BLOCK (catch clause block)
a7d8d81f
PB
11049 */
11050 catch_clause = TREE_OPERAND (current, 0);
b67d701b
PB
11051 carg_decl = BLOCK_EXPR_DECLS (catch_clause);
11052 carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
11053
11054 /* Catch clauses can't have more than one parameter declared,
11055 but it's already enforced by the grammar. Make sure that the
11056 only parameter of the clause statement in of class Throwable
11057 or a subclass of Throwable, but that was done earlier. The
11058 catch clause parameter type has also been resolved. */
11059
11060 /* Just make sure that the catch clause parameter type inherits
11061 from java.lang.Throwable */
11062 if (!inherits_from_p (carg_type, throwable_type_node))
11063 {
11064 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
11065 parse_error_context (wfl_operator,
11066 "Can't catch class `%s'. Catch clause "
11067 "parameter type must be a subclass of "
11068 "class `java.lang.Throwable'",
0a2138e2 11069 lang_printable_name (carg_type, 0));
b67d701b
PB
11070 error_found = 1;
11071 continue;
11072 }
11073
11074 /* Partial check for unreachable catch statement: The catch
11075 clause is reachable iff is no earlier catch block A in
11076 the try statement such that the type of the catch
11077 clause's parameter is the same as or a subclass of the
11078 type of A's parameter */
11079 unreachable = 0;
11080 for (sub_current = catch;
11081 sub_current != current; sub_current = TREE_CHAIN (sub_current))
11082 {
11083 tree sub_catch_clause, decl;
a7d8d81f 11084 sub_catch_clause = TREE_OPERAND (sub_current, 0);
b67d701b
PB
11085 decl = BLOCK_EXPR_DECLS (sub_catch_clause);
11086
11087 if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
11088 {
11089 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
11090 parse_error_context
11091 (wfl_operator, "`catch' not reached because of the catch "
11092 "clause at line %d", EXPR_WFL_LINENO (sub_current));
11093 unreachable = error_found = 1;
11094 break;
11095 }
11096 }
b67d701b
PB
11097 /* Complete the catch clause block */
11098 catch_block = java_complete_tree (TREE_OPERAND (current, 0));
11099 if (catch_block == error_mark_node)
11100 {
11101 error_found = 1;
11102 continue;
11103 }
15fdcfe9
PB
11104 if (CAN_COMPLETE_NORMALLY (catch_block))
11105 CAN_COMPLETE_NORMALLY (node) = 1;
b67d701b 11106 TREE_OPERAND (current, 0) = catch_block;
15fdcfe9
PB
11107
11108 if (unreachable)
11109 continue;
11110
11111 /* Things to do here: the exception must be thrown */
11112
11113 /* Link this type to the caught type list */
11114 caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
b67d701b
PB
11115 }
11116
b9f7e36c
APB
11117 PUSH_EXCEPTIONS (caught_type_list);
11118 if ((try = java_complete_tree (try)) == error_mark_node)
11119 error_found = 1;
15fdcfe9
PB
11120 if (CAN_COMPLETE_NORMALLY (try))
11121 CAN_COMPLETE_NORMALLY (node) = 1;
b9f7e36c
APB
11122 POP_EXCEPTIONS ();
11123
b67d701b
PB
11124 /* Verification ends here */
11125 if (error_found)
11126 return error_mark_node;
11127
11128 TREE_OPERAND (node, 0) = try;
11129 TREE_OPERAND (node, 1) = catch;
b67d701b
PB
11130 TREE_TYPE (node) = void_type_node;
11131 return node;
11132}
b9f7e36c
APB
11133
11134/* 14.17 The synchronized Statement */
11135
11136static tree
11137patch_synchronized_statement (node, wfl_op1)
11138 tree node, wfl_op1;
11139{
5a005d9e 11140 tree expr = java_complete_tree (TREE_OPERAND (node, 0));
b9f7e36c 11141 tree block = TREE_OPERAND (node, 1);
5a005d9e 11142
d8fccff5 11143 tree enter, exit, expr_decl, assignment;
5a005d9e
PB
11144
11145 if (expr == error_mark_node)
11146 {
11147 block = java_complete_tree (block);
11148 return expr;
11149 }
b9f7e36c
APB
11150
11151 /* The TYPE of expr must be a reference type */
5a005d9e 11152 if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
b9f7e36c
APB
11153 {
11154 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11155 parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
11156 ". Can't convert `%s' to `java.lang.Object'",
0a2138e2 11157 lang_printable_name (TREE_TYPE (expr), 0));
b9f7e36c
APB
11158 return error_mark_node;
11159 }
11160
ce6e9147
APB
11161 if (flag_emit_xref)
11162 {
11163 TREE_OPERAND (node, 0) = expr;
11164 TREE_OPERAND (node, 1) = java_complete_tree (block);
11165 CAN_COMPLETE_NORMALLY (node) = 1;
11166 return node;
11167 }
11168
b9f7e36c
APB
11169 /* Generate a try-finally for the synchronized statement, except
11170 that the handler that catches all throw exception calls
11171 _Jv_MonitorExit and then rethrow the exception.
11172 The synchronized statement is then implemented as:
11173 TRY
11174 {
11175 _Jv_MonitorEnter (expression)
11176 synchronized_block
11177 _Jv_MonitorExit (expression)
11178 }
11179 CATCH_ALL
11180 {
11181 e = _Jv_exception_info ();
11182 _Jv_MonitorExit (expression)
11183 Throw (e);
11184 } */
11185
5a005d9e
PB
11186 expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
11187 BUILD_MONITOR_ENTER (enter, expr_decl);
11188 BUILD_MONITOR_EXIT (exit, expr_decl);
11189 CAN_COMPLETE_NORMALLY (enter) = 1;
11190 CAN_COMPLETE_NORMALLY (exit) = 1;
96847892
AH
11191 assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
11192 TREE_SIDE_EFFECTS (assignment) = 1;
5a005d9e
PB
11193 node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
11194 build (COMPOUND_EXPR, NULL_TREE,
11195 build (WITH_CLEANUP_EXPR, NULL_TREE,
11196 build (COMPOUND_EXPR, NULL_TREE,
96847892 11197 assignment, enter),
5a005d9e
PB
11198 NULL_TREE, exit),
11199 block));
11200 node = build_expr_block (node, expr_decl);
11201
11202 return java_complete_tree (node);
b9f7e36c
APB
11203}
11204
11205/* 14.16 The throw Statement */
11206
11207static tree
11208patch_throw_statement (node, wfl_op1)
11209 tree node, wfl_op1;
11210{
11211 tree expr = TREE_OPERAND (node, 0);
11212 tree type = TREE_TYPE (expr);
11213 int unchecked_ok = 0, tryblock_throws_ok = 0;
11214
11215 /* Thrown expression must be assignable to java.lang.Throwable */
11216 if (!try_reference_assignconv (throwable_type_node, expr))
11217 {
11218 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11219 parse_error_context (wfl_operator, "Can't throw `%s'; it must be a "
11220 "subclass of class `java.lang.Throwable'",
0a2138e2 11221 lang_printable_name (type, 0));
b9f7e36c
APB
11222 /* If the thrown expression was a reference, we further the
11223 compile-time check. */
11224 if (!JREFERENCE_TYPE_P (type))
11225 return error_mark_node;
11226 }
11227
11228 /* At least one of the following must be true */
11229
11230 /* The type of the throw expression is a not checked exception,
11231 i.e. is a unchecked expression. */
c877974e 11232 unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
b9f7e36c
APB
11233
11234 /* Throw is contained in a try statement and at least one catch
11235 clause can receive the thrown expression or the current method is
11236 declared to throw such an exception. Or, the throw statement is
11237 contained in a method or constructor declaration and the type of
11238 the Expression is assignable to at least one type listed in the
11239 throws clause the declaration. */
11240 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11241 if (!unchecked_ok)
f099f336 11242 tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
b9f7e36c
APB
11243 if (!(unchecked_ok || tryblock_throws_ok))
11244 {
11245 /* If there is a surrounding try block that has no matching
11246 clatch clause, report it first. A surrounding try block exits
11247 only if there is something after the list of checked
11248 exception thrown by the current function (if any). */
11249 if (IN_TRY_BLOCK_P ())
11250 parse_error_context (wfl_operator, "Checked exception `%s' can't be "
11251 "caught by any of the catch clause(s) "
11252 "of the surrounding `try' block",
0a2138e2 11253 lang_printable_name (type, 0));
b9f7e36c
APB
11254 /* If we have no surrounding try statement and the method doesn't have
11255 any throws, report it now. FIXME */
f099f336
APB
11256
11257 /* We report that the exception can't be throw from a try block
11258 in all circumstances but when the `throw' is inside a static
11259 block. */
b9f7e36c
APB
11260 else if (!EXCEPTIONS_P (currently_caught_type_list)
11261 && !tryblock_throws_ok)
f099f336 11262 {
7f1d4866 11263 if (IS_CLINIT (current_function_decl))
f099f336
APB
11264 parse_error_context (wfl_operator, "Checked exception `%s' can't "
11265 "be thrown in initializer",
11266 lang_printable_name (type, 0));
11267 else
11268 parse_error_context (wfl_operator, "Checked exception `%s' isn't "
11269 "thrown from a `try' block",
11270 lang_printable_name (type, 0));
11271 }
b9f7e36c
APB
11272 /* Otherwise, the current method doesn't have the appropriate
11273 throws declaration */
11274 else
11275 parse_error_context (wfl_operator, "Checked exception `%s' doesn't "
11276 "match any of current method's `throws' "
11277 "declaration(s)",
0a2138e2 11278 lang_printable_name (type, 0));
b9f7e36c
APB
11279 return error_mark_node;
11280 }
11281
ce6e9147 11282 if (! flag_emit_class_files && ! flag_emit_xref)
15fdcfe9 11283 BUILD_THROW (node, expr);
ce6e9147
APB
11284
11285 /* If doing xrefs, keep the location where the `throw' was seen. */
11286 if (flag_emit_xref)
11287 EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
b9f7e36c
APB
11288 return node;
11289}
11290
11291/* Check that exception said to be thrown by method DECL can be
11292 effectively caught from where DECL is invoked. */
11293
11294static void
11295check_thrown_exceptions (location, decl)
11296 int location;
11297 tree decl;
11298{
11299 tree throws;
11300 /* For all the unchecked exceptions thrown by DECL */
11301 for (throws = DECL_FUNCTION_THROWS (decl); throws;
11302 throws = TREE_CHAIN (throws))
0a2138e2 11303 if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
b9f7e36c 11304 {
3e78f871
PB
11305#if 1
11306 /* Temporary hack to suppresses errors about cloning arrays. FIXME */
11307 if (DECL_NAME (decl) == get_identifier ("clone"))
11308 continue;
11309#endif
b9f7e36c
APB
11310 EXPR_WFL_LINECOL (wfl_operator) = location;
11311 parse_error_context
11312 (wfl_operator, "Exception `%s' must be caught, or it must be "
11313 "declared in the `throws' clause of `%s'",
0a2138e2 11314 lang_printable_name (TREE_VALUE (throws), 0),
b9f7e36c
APB
11315 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
11316 }
11317}
11318
c877974e 11319/* Return 1 if checked EXCEPTION is caught at the current nesting level of
b9f7e36c
APB
11320 try-catch blocks, OR is listed in the `throws' clause of the
11321 current method. */
11322
11323static int
0a2138e2 11324check_thrown_exceptions_do (exception)
b9f7e36c
APB
11325 tree exception;
11326{
11327 tree list = currently_caught_type_list;
c877974e 11328 resolve_and_layout (exception, NULL_TREE);
b9f7e36c
APB
11329 /* First, all the nested try-catch-finally at that stage. The
11330 last element contains `throws' clause exceptions, if any. */
c877974e
APB
11331 if (IS_UNCHECKED_EXCEPTION_P (exception))
11332 return 1;
b9f7e36c
APB
11333 while (list)
11334 {
11335 tree caught;
11336 for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
11337 if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
11338 return 1;
11339 list = TREE_CHAIN (list);
11340 }
11341 return 0;
11342}
11343
11344static void
11345purge_unchecked_exceptions (mdecl)
11346 tree mdecl;
11347{
11348 tree throws = DECL_FUNCTION_THROWS (mdecl);
11349 tree new = NULL_TREE;
11350
11351 while (throws)
11352 {
11353 tree next = TREE_CHAIN (throws);
c877974e 11354 if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
b9f7e36c
APB
11355 {
11356 TREE_CHAIN (throws) = new;
11357 new = throws;
11358 }
11359 throws = next;
11360 }
11361 /* List is inverted here, but it doesn't matter */
11362 DECL_FUNCTION_THROWS (mdecl) = new;
11363}
22eed1e6
APB
11364
11365/* 15.24 Conditional Operator ?: */
11366
11367static tree
11368patch_conditional_expr (node, wfl_cond, wfl_op1)
11369 tree node, wfl_cond, wfl_op1;
11370{
11371 tree cond = TREE_OPERAND (node, 0);
11372 tree op1 = TREE_OPERAND (node, 1);
11373 tree op2 = TREE_OPERAND (node, 2);
22eed1e6 11374 tree resulting_type = NULL_TREE;
ac825856 11375 tree t1, t2, patched;
22eed1e6
APB
11376 int error_found = 0;
11377
ac825856
APB
11378 /* Operands of ?: might be StringBuffers crafted as a result of a
11379 string concatenation. Obtain a descent operand here. */
11380 if ((patched = patch_string (op1)))
11381 TREE_OPERAND (node, 1) = op1 = patched;
11382 if ((patched = patch_string (op2)))
11383 TREE_OPERAND (node, 2) = op2 = patched;
11384
11385 t1 = TREE_TYPE (op1);
11386 t2 = TREE_TYPE (op2);
11387
22eed1e6
APB
11388 /* The first expression must be a boolean */
11389 if (TREE_TYPE (cond) != boolean_type_node)
11390 {
11391 SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
11392 parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
11393 "convert `%s' to `boolean'",
11394 lang_printable_name (TREE_TYPE (cond), 0));
11395 error_found = 1;
11396 }
11397
11398 /* Second and third can be numeric, boolean (i.e. primitive),
11399 references or null. Anything else results in an error */
11400 if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
11401 || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node)
11402 && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
11403 || (t1 == boolean_type_node && t2 == boolean_type_node)))
11404 error_found = 1;
11405
11406 /* Determine the type of the conditional expression. Same types are
11407 easy to deal with */
11408 else if (t1 == t2)
11409 resulting_type = t1;
11410
11411 /* There are different rules for numeric types */
11412 else if (JNUMERIC_TYPE_P (t1))
11413 {
11414 /* if byte/short found, the resulting type is short */
11415 if ((t1 == byte_type_node && t2 == short_type_node)
11416 || (t1 == short_type_node && t2 == byte_type_node))
11417 resulting_type = short_type_node;
11418
11419 /* If t1 is a constant int and t2 is of type byte, short or char
11420 and t1's value fits in t2, then the resulting type is t2 */
11421 else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
11422 && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
11423 resulting_type = t2;
11424
11425 /* If t2 is a constant int and t1 is of type byte, short or char
11426 and t2's value fits in t1, then the resulting type is t1 */
11427 else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
11428 && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
11429 resulting_type = t1;
11430
11431 /* Otherwise, binary numeric promotion is applied and the
11432 resulting type is the promoted type of operand 1 and 2 */
11433 else
11434 resulting_type = binary_numeric_promotion (t2, t2,
11435 &TREE_OPERAND (node, 1),
11436 &TREE_OPERAND (node, 2));
11437 }
11438
11439 /* Cases of a reference and a null type */
11440 else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
11441 resulting_type = t1;
11442
11443 else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
11444 resulting_type = t2;
11445
11446 /* Last case: different reference types. If a type can be converted
11447 into the other one by assignment conversion, the latter
11448 determines the type of the expression */
11449 else if ((resulting_type = try_reference_assignconv (t1, op2)))
11450 resulting_type = promote_type (t1);
11451
11452 else if ((resulting_type = try_reference_assignconv (t2, op1)))
11453 resulting_type = promote_type (t2);
11454
11455 /* If we don't have any resulting type, we're in trouble */
11456 if (!resulting_type)
11457 {
11458 char *t = strdup (lang_printable_name (t1, 0));
11459 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11460 parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
11461 "convert `%s' to `%s'", t,
11462 lang_printable_name (t2, 0));
11463 free (t);
11464 error_found = 1;
11465 }
11466
11467 if (error_found)
11468 {
11469 TREE_TYPE (node) = error_mark_node;
11470 return error_mark_node;
11471 }
11472
11473 TREE_TYPE (node) = resulting_type;
11474 TREE_SET_CODE (node, COND_EXPR);
15fdcfe9 11475 CAN_COMPLETE_NORMALLY (node) = 1;
22eed1e6
APB
11476 return node;
11477}
ac825856 11478
5b09b33e
PB
11479/* Try to constant fold NODE.
11480 If NODE is not a constant expression, return NULL_EXPR.
11481 CONTEXT is a static final VAR_DECL whose initializer we are folding. */
11482
11483static tree
11484fold_constant_for_init (node, context)
11485 tree node;
11486 tree context;
11487{
11488 tree op0, op1, val;
11489 enum tree_code code = TREE_CODE (node);
11490
11491 if (code == INTEGER_CST || code == REAL_CST || code == STRING_CST)
11492 return node;
cd9643f7 11493 if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL)
5b09b33e
PB
11494 return NULL_TREE;
11495
11496 switch (code)
11497 {
5b09b33e
PB
11498 case PLUS_EXPR:
11499 case MINUS_EXPR:
bc3ca41b
PB
11500 case MULT_EXPR:
11501 case TRUNC_MOD_EXPR:
11502 case RDIV_EXPR:
5b09b33e
PB
11503 case LSHIFT_EXPR:
11504 case RSHIFT_EXPR:
11505 case URSHIFT_EXPR:
11506 case BIT_AND_EXPR:
11507 case BIT_XOR_EXPR:
11508 case BIT_IOR_EXPR:
5b09b33e
PB
11509 case TRUTH_ANDIF_EXPR:
11510 case TRUTH_ORIF_EXPR:
11511 case EQ_EXPR:
11512 case NE_EXPR:
11513 case GT_EXPR:
11514 case GE_EXPR:
11515 case LT_EXPR:
11516 case LE_EXPR:
11517 op0 = TREE_OPERAND (node, 0);
11518 op1 = TREE_OPERAND (node, 1);
11519 val = fold_constant_for_init (op0, context);
11520 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11521 return NULL_TREE;
11522 TREE_OPERAND (node, 0) = val;
11523 val = fold_constant_for_init (op1, context);
11524 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11525 return NULL_TREE;
11526 TREE_OPERAND (node, 1) = val;
11527 return patch_binop (node, op0, op1);
11528
11529 case UNARY_PLUS_EXPR:
11530 case NEGATE_EXPR:
11531 case TRUTH_NOT_EXPR:
11532 case BIT_NOT_EXPR:
11533 case CONVERT_EXPR:
11534 op0 = TREE_OPERAND (node, 0);
11535 val = fold_constant_for_init (op0, context);
11536 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11537 return NULL_TREE;
11538 TREE_OPERAND (node, 0) = val;
5a005d9e 11539 return patch_unaryop (node, op0);
5b09b33e
PB
11540 break;
11541
11542 case COND_EXPR:
11543 val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
11544 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11545 return NULL_TREE;
11546 TREE_OPERAND (node, 0) = val;
11547 val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
11548 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11549 return NULL_TREE;
11550 TREE_OPERAND (node, 1) = val;
11551 val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
11552 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11553 return NULL_TREE;
11554 TREE_OPERAND (node, 2) = val;
11555 return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
11556 : TREE_OPERAND (node, 2);
11557
11558 case VAR_DECL:
11559 if (! FIELD_STATIC (node) || ! FIELD_FINAL (node)
11560 || DECL_INITIAL (node) == NULL_TREE)
11561 return NULL_TREE;
11562 val = DECL_INITIAL (node);
11563 /* Guard against infinite recursion. */
11564 DECL_INITIAL (node) = NULL_TREE;
cd9643f7 11565 val = fold_constant_for_init (val, node);
5b09b33e
PB
11566 DECL_INITIAL (node) = val;
11567 return val;
11568
11569 case EXPR_WITH_FILE_LOCATION:
11570 /* Compare java_complete_tree and resolve_expression_name. */
11571 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11572 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11573 {
11574 tree name = EXPR_WFL_NODE (node);
11575 tree decl;
11576 if (PRIMARY_P (node))
11577 return NULL_TREE;
11578 else if (! QUALIFIED_P (name))
11579 {
11580 decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
cd9643f7 11581 if (decl == NULL_TREE || ! FIELD_STATIC (decl))
5b09b33e
PB
11582 return NULL_TREE;
11583 return fold_constant_for_init (decl, decl);
11584 }
11585 else
11586 {
11587#if 0
11588 /* Wait until the USE_COMPONENT_REF re-write. FIXME. */
11589 qualify_ambiguous_name (node);
11590 if (resolve_field_access (node, &decl, NULL)
11591 && decl != NULL_TREE)
11592 return fold_constant_for_init (decl, decl);
11593#endif
11594 return NULL_TREE;
11595 }
11596 }
11597 else
11598 {
11599 op0 = TREE_OPERAND (node, 0);
11600 val = fold_constant_for_init (op0, context);
11601 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11602 return NULL_TREE;
11603 TREE_OPERAND (node, 0) = val;
11604 return val;
11605 }
11606
bc3ca41b
PB
11607#ifdef USE_COMPONENT_REF
11608 case IDENTIFIER:
11609 case COMPONENT_REF:
11610 ?;
11611#endif
11612
5b09b33e
PB
11613 default:
11614 return NULL_TREE;
11615 }
11616}
bc3ca41b
PB
11617
11618#ifdef USE_COMPONENT_REF
11619/* Context is 'T' for TypeName, 'P' for PackageName,
11620 'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
11621
11622tree
11623resolve_simple_name (name, context)
11624 tree name;
11625 int context;
11626{
11627}
11628
11629tree
11630resolve_qualified_name (name, context)
11631 tree name;
11632 int context;
11633{
11634}
11635#endif
This page took 1.691891 seconds and 5 git commands to generate.