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