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