]> gcc.gnu.org Git - gcc.git/blame - gcc/java/parse.y
decl.c (make_typename_type): Complain if we don't find a type when trying to make...
[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 */
d4370213 251struct parser_ctxt *ctxp;
e04a16fb 252
d4370213 253/* List of things that were analyzed for which code will be generated */
b351b287
APB
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 2293
4504ead1 2294 bzero ((PTR) new, sizeof (struct parser_ctxt));
e04a16fb
AG
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
d4370213
APB
5323 /* If doing xreferencing, replace the line number with the WFL
5324 compound value */
5325 if (flag_emit_xref)
5326 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
5327
e04a16fb
AG
5328 /* Don't try to use an INIT statement when an error was found */
5329 if (init && java_error_count)
5330 init = NULL_TREE;
c583dd46
APB
5331
5332 /* Add the initialization function to the current function's code */
5333 if (init)
e04a16fb 5334 {
c583dd46
APB
5335 /* Name might have been readjusted */
5336 EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
5337 MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
5338 java_method_add_stmt (current_function_decl,
5339 build_debugable_stmt (EXPR_WFL_LINECOL (init),
5340 init));
5341 }
5342
5343 /* Setup dependency the type of the decl */
5344 if (must_chain)
5345 {
5346 jdep *dep;
5347 register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
5348 dep = CLASSD_LAST (ctxp->classd_list);
5349 JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
e04a16fb
AG
5350 }
5351 }
5352 SOURCE_FRONTEND_DEBUG (("Defined locals"));
5353}
5354
5355/* Called during parsing. Build decls from argument list. */
5356
5357static void
5358source_start_java_method (fndecl)
5359 tree fndecl;
5360{
5361 tree tem;
5362 tree parm_decl;
5363 int i;
5364
e04a16fb
AG
5365 current_function_decl = fndecl;
5366
5367 /* New scope for the function */
5368 enter_block ();
5369 for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
de4c7b02 5370 tem != end_params_node; tem = TREE_CHAIN (tem), i++)
e04a16fb
AG
5371 {
5372 tree type = TREE_VALUE (tem);
5373 tree name = TREE_PURPOSE (tem);
5374
23a79c61
APB
5375 /* If type is incomplete. Create an incomplete decl and ask for
5376 the decl to be patched later */
e04a16fb
AG
5377 if (INCOMPLETE_TYPE_P (type))
5378 {
5379 jdep *jdep;
c877974e
APB
5380 tree real_type = GET_REAL_TYPE (type);
5381 parm_decl = build_decl (PARM_DECL, name, real_type);
23a79c61 5382 type = obtain_incomplete_type (type);
e04a16fb
AG
5383 register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
5384 jdep = CLASSD_LAST (ctxp->classd_list);
5385 JDEP_MISC (jdep) = name;
5386 JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
5387 }
5388 else
5389 parm_decl = build_decl (PARM_DECL, name, type);
5390
5391 BLOCK_CHAIN_DECL (parm_decl);
5392 }
5393 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
5394 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
5395 nreverse (tem);
5396 DECL_ARG_SLOT_COUNT (current_function_decl) = i;
5397}
5398
22eed1e6
APB
5399/* Called during parsing. Creates an artificial method declaration. */
5400
5401static tree
5402create_artificial_method (class, flags, type, name, args)
5403 tree class;
5404 int flags;
5405 tree type, name, args;
5406{
5407 int saved_lineno = lineno;
5408 tree mdecl;
5409
5410 lineno = 0;
5411 mdecl = make_node (FUNCTION_TYPE);
5412 TREE_TYPE (mdecl) = type;
5413 TYPE_ARG_TYPES (mdecl) = args;
5414 mdecl = add_method (class, flags, name, build_java_signature (mdecl));
5415 lineno = saved_lineno;
5416 DECL_ARTIFICIAL (mdecl) = 1;
5417 return mdecl;
5418}
5419
5420/* Starts the body if an artifical method. */
5421
5422static void
5423start_artificial_method_body (mdecl)
5424 tree mdecl;
5425{
5426 DECL_SOURCE_LINE (mdecl) = 1;
5427 DECL_SOURCE_LINE_MERGE (mdecl, 1);
5428 source_start_java_method (mdecl);
5429 enter_block ();
5430}
5431
5432static void
5433end_artificial_method_body (mdecl)
5434 tree mdecl;
5435{
5436 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
5437 exit_block ();
5438}
5439
e04a16fb
AG
5440/* Called during expansion. Push decls formerly built from argument
5441 list so they're usable during expansion. */
5442
5443static void
5444expand_start_java_method (fndecl)
5445 tree fndecl;
5446{
5447 tree tem, *ptr;
e04a16fb 5448
e04a16fb
AG
5449 current_function_decl = fndecl;
5450
5451 announce_function (fndecl);
5452 pushlevel (1); /* Push parameters */
5453 ptr = &DECL_ARGUMENTS (fndecl);
5454 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
5455 while (tem)
5456 {
5457 tree next = TREE_CHAIN (tem);
b67d701b
PB
5458 tree type = TREE_TYPE (tem);
5459#ifdef PROMOTE_PROTOTYPES
5460 if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
5461 && INTEGRAL_TYPE_P (type))
5462 type = integer_type_node;
5463#endif
5464 DECL_ARG_TYPE (tem) = type;
e04a16fb
AG
5465 layout_decl (tem, 0);
5466 pushdecl (tem);
e04a16fb
AG
5467 *ptr = tem;
5468 ptr = &TREE_CHAIN (tem);
5469 tem = next;
5470 }
5471 *ptr = NULL_TREE;
5472 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
5473 lineno = DECL_SOURCE_LINE_FIRST (fndecl);
e04a16fb
AG
5474}
5475
5476/* Terminate a function and expand its body. */
5477
5478static void
5479source_end_java_method ()
5480{
5481 tree fndecl = current_function_decl;
5482
5483 java_parser_context_save_global ();
5484 lineno = ctxp->last_ccb_indent1;
5485
b67d701b
PB
5486 /* Set EH language codes */
5487 java_set_exception_lang_code ();
5488
e04a16fb
AG
5489 /* Generate function's code */
5490 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
5491 && ! flag_emit_class_files)
5492 expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
5493
5494 /* pop out of its parameters */
5495 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
5496 poplevel (1, 0, 1);
5497 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5498
5499 /* Generate rtl for function exit. */
5500 if (! flag_emit_class_files)
5501 {
5502 lineno = DECL_SOURCE_LINE_LAST (fndecl);
b67d701b
PB
5503 /* Emit catch-finally clauses */
5504 emit_handlers ();
e04a16fb
AG
5505 expand_function_end (input_filename, lineno, 0);
5506
5507 /* Run the optimizers and output assembler code for this function. */
5508 rest_of_compilation (fndecl);
5509 }
5510
5511 current_function_decl = NULL_TREE;
5512 /* permanent_allocation (1); */
5513 java_parser_context_restore_global ();
5514}
5515
5516/* Record EXPR in the current function block. Complements compound
5517 expression second operand if necessary. */
5518
5519tree
5520java_method_add_stmt (fndecl, expr)
5521 tree fndecl, expr;
5522{
f099f336 5523 return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
b67d701b 5524}
e04a16fb 5525
b67d701b
PB
5526static tree
5527add_stmt_to_block (b, type, stmt)
5528 tree b, type, stmt;
5529{
5530 tree body = BLOCK_EXPR_BODY (b), c;
5531
e04a16fb
AG
5532 if (java_error_count)
5533 return body;
b67d701b
PB
5534
5535 if ((c = add_stmt_to_compound (body, type, stmt)) == body)
e04a16fb
AG
5536 return body;
5537
b67d701b
PB
5538 BLOCK_EXPR_BODY (b) = c;
5539 TREE_SIDE_EFFECTS (c) = 1;
5540 return c;
e04a16fb
AG
5541}
5542
5543/* Add STMT to EXISTING if possible, otherwise create a new
5544 COMPOUND_EXPR and add STMT to it. */
5545
5546static tree
5547add_stmt_to_compound (existing, type, stmt)
5548 tree existing, type, stmt;
5549{
15fdcfe9
PB
5550 if (existing)
5551 return build (COMPOUND_EXPR, type, existing, stmt);
e04a16fb 5552 else
15fdcfe9 5553 return stmt;
e04a16fb
AG
5554}
5555
5556/* Hold THIS for the scope of the current public method decl. */
5557static tree current_this;
5558
1886c9d8
APB
5559void java_layout_seen_class_methods ()
5560{
5561 tree previous_list = all_class_list;
5562 tree end = NULL_TREE;
5563 tree current;
5564
5565 while (1)
5566 {
5567 for (current = previous_list;
5568 current != end; current = TREE_CHAIN (current))
5569 layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
5570
5571 if (previous_list != all_class_list)
5572 {
5573 end = previous_list;
5574 previous_list = all_class_list;
5575 }
5576 else
5577 break;
5578 }
5579}
5580
23a79c61
APB
5581/* Layout the methods of all classes loaded in one way on an
5582 other. Check methods of source parsed classes. Then reorder the
5583 fields and layout the classes or the type of all source parsed
5584 classes */
e04a16fb
AG
5585
5586void
5587java_layout_classes ()
5588{
5589 tree current;
bc3ca41b 5590 int save_error_count = java_error_count;
5e942c50 5591
23a79c61 5592 /* Layout the methods of all classes seen so far */
1886c9d8 5593 java_layout_seen_class_methods ();
23a79c61
APB
5594 java_parse_abort_on_error ();
5595 all_class_list = NULL_TREE;
5596
5597 /* Then check the methods of all parsed classes */
5598 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
5599 if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
5600 CHECK_METHODS (TREE_VALUE (current));
5601 java_parse_abort_on_error ();
5602
5e942c50 5603 for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
e04a16fb 5604 {
5e942c50 5605 current_class = TREE_TYPE (TREE_VALUE (current));
22eed1e6 5606
c877974e
APB
5607 /* Reverse the fields, but leave the dummy field in front.
5608 Fields are already ordered for Object and Class */
5609 if (TYPE_FIELDS (current_class) && current_class != object_type_node
5610 && current_class != class_type_node)
5611 {
23a79c61
APB
5612 /* If the dummy field is there, reverse the right fields and
5613 just layout the type for proper fields offset */
c877974e
APB
5614 if (!DECL_NAME (TYPE_FIELDS (current_class)))
5615 {
5616 tree fields = TYPE_FIELDS (current_class);
5617 TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
5618 TYPE_SIZE (current_class) = NULL_TREE;
5619 layout_type (current_class);
5620 }
23a79c61
APB
5621 /* We don't have a dummy field, we need to layout the class,
5622 after having reversed the fields */
c877974e
APB
5623 else
5624 {
5625 TYPE_FIELDS (current_class) =
5626 nreverse (TYPE_FIELDS (current_class));
5627 TYPE_SIZE (current_class) = NULL_TREE;
5628 layout_class (current_class);
5629 }
5630 }
23a79c61
APB
5631 else
5632 layout_class (current_class);
5e942c50 5633
c877974e
APB
5634 /* From now on, the class is considered completely loaded */
5635 CLASS_LOADED_P (current_class) = 1;
5636
5e942c50
APB
5637 /* Error reported by the caller */
5638 if (java_error_count)
5639 return;
e04a16fb 5640 }
23a79c61
APB
5641
5642 /* We might have reloaded classes durign the process of laying out
5643 classes for code generation. We must layout the methods of those
5644 late additions, as constructor checks might use them */
1886c9d8 5645 java_layout_seen_class_methods ();
23a79c61 5646 java_parse_abort_on_error ();
e04a16fb
AG
5647}
5648
5649/* Expand all methods in all registered classes. */
5650
5651void
5652java_complete_expand_methods ()
5653{
5654 tree current;
5655
5656 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5657 {
e04a16fb
AG
5658 tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
5659 tree decl;
e04a16fb
AG
5660
5661 current_class = TREE_TYPE (current);
5662
5663 /* Initialize a new constant pool */
5664 init_outgoing_cpool ();
5665
7525cc04
APB
5666 /* We want <clinit> (if any) to be processed first. */
5667 decl = tree_last (TYPE_METHODS (class_type));
5668 if (decl && DECL_NAME (decl) == clinit_identifier_node)
5669 {
5670 tree list = nreverse (TYPE_METHODS (class_type));
5671 list = TREE_CHAIN (list);
5672 TREE_CHAIN (decl) = NULL_TREE;
5673 TYPE_METHODS (class_type) = chainon (decl, nreverse (list));
5674 }
5675
e04a16fb
AG
5676 /* Don't process function bodies in interfaces */
5677 if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
5678 for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5679 {
5680 current_function_decl = decl;
5681 /* Don't generate debug info on line zero when expanding a
5682 generated constructor. */
5683 if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl))
5684 {
5685 /* If we found errors, it's too dangerous to try to generate
5686 and expand a constructor */
5687 if (!java_error_count)
5688 {
5689 restore_line_number_status (1);
5690 java_complete_expand_method (decl);
5691 restore_line_number_status (0);
5692 }
5693 }
5e942c50
APB
5694 else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
5695 continue;
5696 else
e04a16fb
AG
5697 java_complete_expand_method (decl);
5698 }
5699
22eed1e6
APB
5700 /* Now verify constructor circularity (stop after the first one
5701 we find) */
5702 if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
5703 for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5704 if (DECL_CONSTRUCTOR_P (decl) &&
5705 verify_constructor_circularity (decl, decl))
5706 break;
5707
e04a16fb
AG
5708 /* Make the class data, register it and run the rest of decl
5709 compilation on it */
63a212ed
PB
5710 if (!java_error_count)
5711 {
5712 if (flag_emit_class_files)
5713 write_classfile (current_class);
f099f336
APB
5714 if (flag_emit_xref)
5715 expand_xref (current_class);
aabd7048 5716 else if (! flag_syntax_only)
63a212ed
PB
5717 finish_class (current_class);
5718 }
e04a16fb
AG
5719 }
5720}
5721
b9f7e36c
APB
5722/* Hold a list of catch clauses list. The first element of this list is
5723 the list of the catch clauses of the currently analysed try block. */
5724static tree currently_caught_type_list;
5725
e04a16fb
AG
5726/* Complete and expand a method. */
5727
5728static void
5729java_complete_expand_method (mdecl)
5730 tree mdecl;
5731{
22eed1e6
APB
5732 /* Fix constructors before expanding them */
5733 if (DECL_CONSTRUCTOR_P (mdecl))
5734 fix_constructors (mdecl);
e04a16fb 5735
22eed1e6 5736 /* Expand functions that have a body */
e04a16fb
AG
5737 if (DECL_FUNCTION_BODY (mdecl))
5738 {
9bbc7d9f
PB
5739 tree fbody = DECL_FUNCTION_BODY (mdecl);
5740 tree block_body = BLOCK_EXPR_BODY (fbody);
e04a16fb 5741 expand_start_java_method (mdecl);
939d7216 5742 build_result_decl (mdecl);
e04a16fb
AG
5743
5744 current_this
5745 = (!METHOD_STATIC (mdecl) ?
5746 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
5747
b9f7e36c
APB
5748 /* Purge the `throws' list of unchecked exceptions */
5749 purge_unchecked_exceptions (mdecl);
5750
5751 /* Install exceptions thrown with `throws' */
5752 PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
5753
9bbc7d9f 5754 if (block_body != NULL_TREE)
bc3ca41b 5755 {
f099f336
APB
5756 /* Prevent the use of `this' inside <clinit> */
5757 if (DECL_NAME (current_function_decl) == clinit_identifier_node)
5758 ctxp->explicit_constructor_p = 1;
5759
bc3ca41b
PB
5760 block_body = java_complete_tree (block_body);
5761 check_for_initialization (block_body);
f099f336 5762 ctxp->explicit_constructor_p = 0;
bc3ca41b 5763 }
9bbc7d9f 5764 BLOCK_EXPR_BODY (fbody) = block_body;
5e942c50 5765
9bbc7d9f
PB
5766 if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
5767 && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
82371d41 5768 missing_return_error (current_function_decl);
7525cc04 5769
939d7216
PB
5770 complete_start_java_method (mdecl);
5771
e04a16fb
AG
5772 /* Don't go any further if we've found error(s) during the
5773 expansion */
5774 if (!java_error_count)
5775 source_end_java_method ();
22eed1e6
APB
5776 else
5777 {
5778 pushdecl_force_head (DECL_ARGUMENTS (mdecl));
5779 poplevel (1, 0, 1);
5780 }
b9f7e36c
APB
5781
5782 /* Pop the exceptions and sanity check */
5783 POP_EXCEPTIONS();
5784 if (currently_caught_type_list)
5785 fatal ("Exception list non empty - java_complete_expand_method");
e04a16fb
AG
5786 }
5787}
5788
22eed1e6
APB
5789/* Craft a body for default constructor. Patch existing constructor
5790 bodies with call to super() and field initialization statements if
5791 necessary. */
5792
5793static void
5794fix_constructors (mdecl)
5795 tree mdecl;
5796{
5797 tree body = DECL_FUNCTION_BODY (mdecl);
22eed1e6 5798
22eed1e6
APB
5799 if (!body)
5800 {
89e09b9a
PB
5801 /* The constructor body must be crafted by hand. It's the
5802 constructor we defined when we realize we didn't have the
5803 CLASSNAME() constructor */
5804
22eed1e6
APB
5805 tree compound;
5806
5807 /* It is an error for the compiler to generate a default
5808 constructor if the superclass doesn't have a constructor that
5809 takes no argument */
5810 if (verify_constructor_super ())
5811 {
5812 tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (current_class));
5813 char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
5814 parse_error_context (lookup_cl (TYPE_NAME (current_class)),
5815 "No constructor matching `%s()' found in "
5816 "class `%s'", n, n);
5817 }
5818
5819 start_artificial_method_body (mdecl);
5820
5821 /* We don't generate a super constructor invocation if we're
5822 compiling java.lang.Object. build_super_invocation takes care
5823 of that. */
5824 compound = java_method_add_stmt (mdecl, build_super_invocation ());
22eed1e6
APB
5825
5826 end_artificial_method_body (mdecl);
5827 }
5828 /* Search for an explicit constructor invocation */
5829 else
5830 {
5831 int found = 0;
5832 tree main_block = BLOCK_EXPR_BODY (body);
5833 tree compound = NULL_TREE;
5834
5835 while (body)
5836 switch (TREE_CODE (body))
5837 {
5838 case CALL_EXPR:
5839 found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
5840 body = NULL_TREE;
5841 break;
5842 case COMPOUND_EXPR:
5843 case EXPR_WITH_FILE_LOCATION:
5844 body = TREE_OPERAND (body, 0);
5845 break;
5846 case BLOCK:
5847 body = BLOCK_EXPR_BODY (body);
5848 break;
5849 default:
5850 found = 0;
5851 body = NULL_TREE;
5852 }
5853 /* The constructor is missing an invocation of super() */
5854 if (!found)
5855 compound = add_stmt_to_compound (compound, NULL_TREE,
5856 build_super_invocation ());
5857
22eed1e6
APB
5858 /* Fix the constructor main block if we're adding extra stmts */
5859 if (compound)
5860 {
5861 compound = add_stmt_to_compound (compound, NULL_TREE,
5862 BLOCK_EXPR_BODY (main_block));
5863 BLOCK_EXPR_BODY (main_block) = compound;
5864 }
5865 }
5866}
5867
5868/* Browse constructors in the super class, searching for a constructor
5869 that doesn't take any argument. Return 0 if one is found, 1
5870 otherwise. */
5871
5872static int
5873verify_constructor_super ()
5874{
5875 tree class = CLASSTYPE_SUPER (current_class);
5876 if (!class)
5877 return 0;
5878
5879 if (class)
5880 {
5881 tree mdecl;
5882 for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
5883 {
5884 if (DECL_CONSTRUCTOR_P (mdecl)
de4c7b02 5885 && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) == end_params_node)
22eed1e6
APB
5886 return 0;
5887 }
5888 }
5889 return 1;
5890}
5891
e04a16fb
AG
5892/* Expand finals. */
5893
5894void
5895java_expand_finals ()
5896{
5897}
5898
22eed1e6 5899/* Generate code for all context remembered for code generation. */
b351b287
APB
5900
5901void
5902java_expand_classes ()
5903{
bc3ca41b 5904 int save_error_count = java_error_count;
23a79c61
APB
5905 java_parse_abort_on_error ();
5906 if (!(ctxp = ctxp_for_generation))
5e942c50
APB
5907 return;
5908 java_layout_classes ();
5909 java_parse_abort_on_error ();
5910
b351b287
APB
5911 for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
5912 {
5913 ctxp = ctxp_for_generation;
5914 lang_init_source (2); /* Error msgs have method prototypes */
5915 java_complete_expand_methods (); /* Complete and expand method bodies */
5916 java_parse_abort_on_error ();
5917 java_expand_finals (); /* Expand and check the finals */
5918 java_parse_abort_on_error ();
5919 java_check_final (); /* Check unitialized final */
5920 java_parse_abort_on_error ();
5921 }
b351b287
APB
5922}
5923
e04a16fb
AG
5924/* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
5925 a tree list node containing RIGHT. Fore coming RIGHTs will be
5926 chained to this hook. LOCATION contains the location of the
5927 separating `.' operator. */
5928
5929static tree
5930make_qualified_primary (primary, right, location)
5931 tree primary, right;
5932 int location;
5933{
5934 tree wfl;
5935
5936 /* We want to process THIS . xxx symbolicaly, to keep it consistent
5937 with the way we're processing SUPER. A THIS from a primary as a
5938 different form than a SUPER. Turn THIS into something symbolic */
b67d701b 5939 if (TREE_CODE (primary) == THIS_EXPR)
e04a16fb 5940 {
9ee9b555 5941 wfl = build_wfl_node (this_identifier_node);
e04a16fb
AG
5942 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
5943 wfl = make_qualified_name (wfl, right, location);
5944 PRIMARY_P (wfl) = 1;
5945 return wfl;
5946 }
5947 /* Other non WFL node are wrapped around a WFL */
5948 else if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
5949 {
5950 wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
5951 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
5952 EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (primary, NULL_TREE);
5953 }
5954 else
5955 {
5956 wfl = primary;
5957 if (!EXPR_WFL_QUALIFICATION (primary))
5958 EXPR_WFL_QUALIFICATION (primary) =
5959 build_tree_list (primary, NULL_TREE);
5960 }
5961
5962 EXPR_WFL_LINECOL (right) = location;
5963 chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
5964 PRIMARY_P (wfl) = 1;
5965 return wfl;
5966}
5967
5968/* Simple merge of two name separated by a `.' */
5969
5970static tree
5971merge_qualified_name (left, right)
5972 tree left, right;
5973{
5974 tree node;
5975 obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
5976 IDENTIFIER_LENGTH (left));
5977 obstack_1grow (&temporary_obstack, '.');
5978 obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
5979 IDENTIFIER_LENGTH (right));
5980 node = get_identifier (obstack_base (&temporary_obstack));
5981 obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
5982 QUALIFIED_P (node) = 1;
5983 return node;
5984}
5985
5986/* Merge the two parts of a qualified name into LEFT. Set the
5987 location information of the resulting node to LOCATION, usually
5988 inherited from the location information of the `.' operator. */
5989
5990static tree
5991make_qualified_name (left, right, location)
5992 tree left, right;
5993 int location;
5994{
bc3ca41b
PB
5995#ifdef USE_COMPONENT_REF
5996 tree node = build (COMPONENT_REF, NULL_TREE, left, right);
5997 EXPR_WFL_LINECOL (node) = location;
5998 return node;
5999#else
e04a16fb
AG
6000 tree left_id = EXPR_WFL_NODE (left);
6001 tree right_id = EXPR_WFL_NODE (right);
6002 tree wfl, merge;
6003
6004 merge = merge_qualified_name (left_id, right_id);
6005
6006 /* Left wasn't qualified and is now qualified */
6007 if (!QUALIFIED_P (left_id))
6008 {
6009 tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
6010 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
6011 EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
6012 }
6013
6014 wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
6015 EXPR_WFL_LINECOL (wfl) = location;
6016 chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
6017
6018 EXPR_WFL_NODE (left) = merge;
6019 return left;
bc3ca41b 6020#endif
e04a16fb
AG
6021}
6022
6023/* Extract the last identifier component of the qualified in WFL. The
6024 last identifier is removed from the linked list */
6025
6026static tree
6027cut_identifier_in_qualified (wfl)
6028 tree wfl;
6029{
6030 tree q;
6031 tree previous = NULL_TREE;
6032 for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
6033 if (!TREE_CHAIN (q))
6034 {
6035 if (!previous)
6036 fatal ("Operating on a non qualified qualified WFL - "
6037 "cut_identifier_in_qualified");
6038 TREE_CHAIN (previous) = NULL_TREE;
6039 return TREE_PURPOSE (q);
6040 }
6041}
6042
6043/* Resolve the expression name NAME. Return its decl. */
6044
6045static tree
5e942c50 6046resolve_expression_name (id, orig)
e04a16fb 6047 tree id;
5e942c50 6048 tree *orig;
e04a16fb
AG
6049{
6050 tree name = EXPR_WFL_NODE (id);
6051 tree decl;
6052
6053 /* 6.5.5.1: Simple expression names */
6054 if (!PRIMARY_P (id) && !QUALIFIED_P (name))
6055 {
6056 /* 15.13.1: NAME can appear within the scope of a local variable
6057 declaration */
6058 if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
6059 return decl;
6060
6061 /* 15.13.1: NAME can appear within a class declaration */
6062 else
6063 {
6064 decl = lookup_field_wrapper (current_class, name);
6065 if (decl)
6066 {
6067 int fs = FIELD_STATIC (decl);
6068 /* Instance variable (8.3.1.1) can't appear within
6069 static method, static initializer or initializer for
6070 a static variable. */
6071 if (!fs && METHOD_STATIC (current_function_decl))
6072 {
6073 parse_error_context
6074 (id, "Can't make a static reference to nonstatic variable "
6075 "`%s' in class `%s'",
6076 IDENTIFIER_POINTER (name),
6077 IDENTIFIER_POINTER (DECL_NAME
6078 (TYPE_NAME (current_class))));
6079 return error_mark_node;
6080 }
22eed1e6
APB
6081 /* Instance variables can't appear as an argument of
6082 an explicit constructor invocation */
6083 if (!fs && ctxp->explicit_constructor_p)
6084 {
6085 parse_error_context
6086 (id, "Can't reference `%s' before the superclass "
6087 "constructor has been called", IDENTIFIER_POINTER (name));
6088 return error_mark_node;
6089 }
5e942c50
APB
6090
6091 /* Otherwise build what it takes to access the field */
e04a16fb
AG
6092 decl = build_field_ref ((fs ? NULL_TREE : current_this),
6093 current_class, name);
5e942c50
APB
6094 if (fs && !flag_emit_class_files)
6095 decl = build_class_init (current_class, decl);
6096 /* We may be asked to save the real field access node */
6097 if (orig)
6098 *orig = decl;
6099 /* And we return what we got */
5b09b33e 6100 return decl;
e04a16fb
AG
6101 }
6102 /* Fall down to error report on undefined variable */
6103 }
6104 }
6105 /* 6.5.5.2 Qualified Expression Names */
6106 else
6107 {
5e942c50
APB
6108 if (orig)
6109 *orig = NULL_TREE;
e04a16fb
AG
6110 qualify_ambiguous_name (id);
6111 /* 15.10.1 Field Access Using a Primary and/or Expression Name */
6112 /* 15.10.2: Accessing Superclass Members using super */
6113 return resolve_field_access (id, NULL, NULL);
6114 }
6115
6116 /* We've got an error here */
6117 parse_error_context (id, "Undefined variable `%s'",
6118 IDENTIFIER_POINTER (name));
6119
6120 return error_mark_node;
6121}
6122
6123/* 15.10.1 Field Acess Using a Primary and/or Expression Name.
6124 We return something suitable to generate the field access. We also
6125 return the field decl in FIELD_DECL and its type in FIELD_TYPE. If
6126 recipient's address can be null. */
6127
6128static tree
6129resolve_field_access (qual_wfl, field_decl, field_type)
6130 tree qual_wfl;
6131 tree *field_decl, *field_type;
6132{
6133 int is_static = 0;
6134 tree field_ref;
6135 tree decl, where_found, type_found;
6136
6137 if (resolve_qualified_expression_name (qual_wfl, &decl,
6138 &where_found, &type_found))
6139 return error_mark_node;
6140
6141 /* Resolve the LENGTH field of an array here */
6142 if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
6143 && ! flag_emit_class_files)
6144 {
6145 tree length = build_java_array_length_access (where_found);
6146 field_ref =
6147 build_java_arraynull_check (type_found, length, int_type_node);
6148 }
6149 /* We might have been trying to resolve field.method(). In which
6150 case, the resolution is over and decl is the answer */
34f4db93 6151 else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
e04a16fb 6152 field_ref = decl;
34f4db93 6153 else if (JDECL_P (decl))
e04a16fb 6154 {
5e942c50
APB
6155 int static_final_found = 0;
6156 if (!type_found)
6157 type_found = DECL_CONTEXT (decl);
34f4db93 6158 is_static = JDECL_P (decl) && FIELD_STATIC (decl);
5e942c50
APB
6159 if (FIELD_FINAL (decl)
6160 && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
6161 && DECL_LANG_SPECIFIC (decl)
7525cc04 6162 && DECL_INITIAL (decl))
5e942c50 6163 {
7525cc04 6164 field_ref = DECL_INITIAL (decl);
5e942c50
APB
6165 static_final_found = 1;
6166 }
6167 else
6168 field_ref = build_field_ref ((is_static ? NULL_TREE : where_found),
6169 type_found, DECL_NAME (decl));
e04a16fb
AG
6170 if (field_ref == error_mark_node)
6171 return error_mark_node;
c877974e 6172 if (is_static && !static_final_found && !flag_emit_class_files)
e04a16fb
AG
6173 {
6174 field_ref = build_class_init (type_found, field_ref);
6175 /* If the static field was identified by an expression that
6176 needs to be generated, make the field access a compound
6177 expression whose first part of the evaluation of the
6178 field selector part. */
c877974e
APB
6179 if (where_found && TREE_CODE (where_found) != TYPE_DECL
6180 && TREE_CODE (where_found) != RECORD_TYPE)
e04a16fb
AG
6181 {
6182 tree type = QUAL_DECL_TYPE (field_ref);
6183 field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
6184 }
6185 }
6186 }
6187 else
6188 field_ref = decl;
6189
6190 if (field_decl)
6191 *field_decl = decl;
6192 if (field_type)
c877974e
APB
6193 *field_type = (QUAL_DECL_TYPE (decl) ?
6194 QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
e04a16fb
AG
6195 return field_ref;
6196}
6197
e28cd97b
APB
6198/* If NODE is an access to f static field, strip out the class
6199 initialization part and return the field decl, otherwise, return
6200 NODE. */
6201
6202static tree
6203strip_out_static_field_access_decl (node)
6204 tree node;
6205{
6206 if (TREE_CODE (node) == COMPOUND_EXPR)
6207 {
6208 tree op1 = TREE_OPERAND (node, 1);
6209 if (TREE_CODE (op1) == COMPOUND_EXPR)
6210 {
6211 tree call = TREE_OPERAND (op1, 0);
6212 if (TREE_CODE (call) == CALL_EXPR
6213 && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
6214 && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
6215 == soft_initclass_node)
6216 return TREE_OPERAND (op1, 1);
6217 }
6218 }
6219 return node;
6220}
6221
e04a16fb
AG
6222/* 6.5.5.2: Qualified Expression Names */
6223
6224static int
6225resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
6226 tree wfl;
6227 tree *found_decl, *type_found, *where_found;
6228{
6229 int from_type = 0; /* Field search initiated from a type */
6230 int from_super = 0, from_cast = 0;
6231 int previous_call_static = 0;
6232 int is_static;
6233 tree decl = NULL_TREE, type = NULL_TREE, q;
c877974e 6234 *type_found = *where_found = NULL_TREE;
e04a16fb
AG
6235
6236 for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
6237 {
6238 tree qual_wfl = QUAL_WFL (q);
6239
6240 /* 15.10.1 Field Access Using a Primary */
e04a16fb
AG
6241 switch (TREE_CODE (qual_wfl))
6242 {
6243 case CALL_EXPR:
b67d701b 6244 case NEW_CLASS_EXPR:
e04a16fb
AG
6245 /* If the access to the function call is a non static field,
6246 build the code to access it. */
34f4db93 6247 if (JDECL_P (decl) && !FIELD_STATIC (decl))
e04a16fb 6248 {
ac825856
APB
6249 decl = maybe_access_field (decl, *where_found,
6250 DECL_CONTEXT (decl));
e04a16fb
AG
6251 if (decl == error_mark_node)
6252 return 1;
6253 }
6254 /* And code for the function call */
6255 if (complete_function_arguments (qual_wfl))
6256 return 1;
89e09b9a
PB
6257 if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
6258 CALL_USING_SUPER (qual_wfl) = 1;
e04a16fb 6259 *where_found =
89e09b9a 6260 patch_method_invocation (qual_wfl, decl, type, &is_static, NULL);
e04a16fb
AG
6261 if (*where_found == error_mark_node)
6262 return 1;
6263 *type_found = type = QUAL_DECL_TYPE (*where_found);
6264
6265 /* If the previous call was static and this one is too,
6266 build a compound expression to hold the two (because in
6267 that case, previous function calls aren't transported as
6268 forcoming function's argument. */
6269 if (previous_call_static && is_static)
6270 {
6271 decl = build (COMPOUND_EXPR, type, decl, *where_found);
6272 TREE_SIDE_EFFECTS (decl) = 1;
6273 }
6274 else
6275 {
6276 previous_call_static = is_static;
6277 decl = *where_found;
6278 }
6279 continue;
6280
d8fccff5
APB
6281 case NEW_ARRAY_EXPR:
6282 *where_found = decl = java_complete_tree (qual_wfl);
6283 if (decl == error_mark_node)
6284 return 1;
6285 *type_found = type = QUAL_DECL_TYPE (decl);
6286 CLASS_LOADED_P (type) = 1;
6287 continue;
6288
e04a16fb
AG
6289 case CONVERT_EXPR:
6290 *where_found = decl = java_complete_tree (qual_wfl);
6291 if (decl == error_mark_node)
6292 return 1;
6293 *type_found = type = QUAL_DECL_TYPE (decl);
6294 from_cast = 1;
6295 continue;
6296
22eed1e6 6297 case CONDITIONAL_EXPR:
5e942c50 6298 case STRING_CST:
22eed1e6
APB
6299 *where_found = decl = java_complete_tree (qual_wfl);
6300 if (decl == error_mark_node)
6301 return 1;
6302 *type_found = type = QUAL_DECL_TYPE (decl);
6303 continue;
6304
e04a16fb
AG
6305 case ARRAY_REF:
6306 /* If the access to the function call is a non static field,
6307 build the code to access it. */
34f4db93 6308 if (JDECL_P (decl) && !FIELD_STATIC (decl))
e04a16fb
AG
6309 {
6310 decl = maybe_access_field (decl, *where_found, type);
6311 if (decl == error_mark_node)
6312 return 1;
6313 }
6314 /* And code for the array reference expression */
6315 decl = java_complete_tree (qual_wfl);
6316 if (decl == error_mark_node)
6317 return 1;
6318 type = QUAL_DECL_TYPE (decl);
6319 continue;
0a2138e2
APB
6320
6321 default:
6322 /* Fix for -Wall Just go to the next statement. Don't
6323 continue */
e04a16fb
AG
6324 }
6325
6326 /* If we fall here, we weren't processing a (static) function call. */
6327 previous_call_static = 0;
6328
6329 /* It can be the keyword THIS */
6330 if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
6331 {
6332 if (!current_this)
6333 {
6334 parse_error_context
6335 (wfl, "Keyword `this' used outside allowed context");
6336 return 1;
6337 }
6338 /* We have to generate code for intermediate acess */
6339 *where_found = decl = current_this;
5e942c50 6340 *type_found = type = QUAL_DECL_TYPE (decl);
e04a16fb
AG
6341 continue;
6342 }
6343
6344 /* 15.10.2 Accessing Superclass Members using SUPER */
6345 if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
6346 {
6347 tree node;
6348 /* Check on the restricted use of SUPER */
6349 if (METHOD_STATIC (current_function_decl)
6350 || current_class == object_type_node)
6351 {
6352 parse_error_context
6353 (wfl, "Keyword `super' used outside allowed context");
6354 return 1;
6355 }
6356 /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
6357 node = build_cast (EXPR_WFL_LINECOL (qual_wfl),
6358 CLASSTYPE_SUPER (current_class),
6359 build_this (EXPR_WFL_LINECOL (qual_wfl)));
6360 *where_found = decl = java_complete_tree (node);
22eed1e6
APB
6361 if (decl == error_mark_node)
6362 return 1;
e04a16fb
AG
6363 *type_found = type = QUAL_DECL_TYPE (decl);
6364 from_super = from_type = 1;
6365 continue;
6366 }
6367
6368 /* 15.13.1: Can't search for field name in packages, so we
6369 assume a variable/class name was meant. */
6370 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
6371 {
5e942c50
APB
6372 tree name = resolve_package (wfl, &q);
6373 if (name)
6374 {
6375 *where_found = decl = resolve_no_layout (name, qual_wfl);
6376 /* We wan't to be absolutely that the class is laid
6377 out. We're going to search something inside it. */
6378 *type_found = type = TREE_TYPE (decl);
6379 layout_class (type);
6380 from_type = 1;
6381 /* Should be a list, really. FIXME */
6382 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 1;
6383 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 0;
6384 }
e04a16fb 6385 else
5e942c50
APB
6386 {
6387 if (from_super || from_cast)
6388 parse_error_context
6389 ((from_cast ? qual_wfl : wfl),
6390 "No variable `%s' defined in class `%s'",
6391 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
6392 lang_printable_name (type, 0));
6393 else
6394 parse_error_context
6395 (qual_wfl, "Undefined variable or class name: `%s'",
6396 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
6397 return 1;
6398 }
e04a16fb
AG
6399 }
6400
6401 /* We have a type name. It's been already resolved when the
6402 expression was qualified. */
6403 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
6404 {
6405 if (!(decl = QUAL_RESOLUTION (q)))
6406 return 1; /* Error reported already */
6407
6408 if (not_accessible_p (TREE_TYPE (decl), decl, 0))
6409 {
6410 parse_error_context
6411 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
6412 java_accstring_lookup (get_access_flags_from_decl (decl)),
2aa11e97 6413 GET_TYPE_NAME (type),
e04a16fb
AG
6414 IDENTIFIER_POINTER (DECL_NAME (decl)),
6415 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
6416 return 1;
6417 }
5e942c50 6418 check_deprecation (qual_wfl, decl);
e04a16fb
AG
6419
6420 type = TREE_TYPE (decl);
6421 from_type = 1;
6422 }
6423 /* We resolve and expression name */
6424 else
6425 {
6426 tree field_decl;
6427
6428 /* If there exists an early resolution, use it. That occurs
6429 only once and we know that there are more things to
6430 come. Don't do that when processing something after SUPER
6431 (we need more thing to be put in place below */
6432 if (!from_super && QUAL_RESOLUTION (q))
b67d701b
PB
6433 {
6434 decl = QUAL_RESOLUTION (q);
c877974e 6435 if (!type)
5e942c50 6436 {
c877974e
APB
6437 if (!FIELD_STATIC (decl))
6438 *where_found = current_this;
6439 else
6440 {
6441 *where_found = TREE_TYPE (decl);
6442 if (TREE_CODE (*where_found) == POINTER_TYPE)
6443 *where_found = TREE_TYPE (*where_found);
6444 }
5e942c50 6445 }
b67d701b 6446 }
e04a16fb
AG
6447
6448 /* We have to search for a field, knowing the type of its
6449 container. The flag FROM_TYPE indicates that we resolved
6450 the last member of the expression as a type name, which
5e942c50
APB
6451 means that for the resolution of this field, we'll look
6452 for other errors than if it was resolved as a member of
6453 an other field. */
e04a16fb
AG
6454 else
6455 {
6456 int is_static;
5e942c50
APB
6457 tree field_decl_type; /* For layout */
6458
e04a16fb
AG
6459 if (!from_type && !JREFERENCE_TYPE_P (type))
6460 {
6461 parse_error_context
6462 (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
6463 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
0a2138e2 6464 lang_printable_name (type, 0),
e04a16fb
AG
6465 IDENTIFIER_POINTER (DECL_NAME (field_decl)));
6466 return 1;
6467 }
6468
dc0b3eff
PB
6469 field_decl = lookup_field_wrapper (type,
6470 EXPR_WFL_NODE (qual_wfl));
6471 if (field_decl == NULL_TREE)
e04a16fb
AG
6472 {
6473 parse_error_context
2aa11e97 6474 (qual_wfl, "No variable `%s' defined in type `%s'",
e04a16fb 6475 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
2aa11e97 6476 GET_TYPE_NAME (type));
e04a16fb
AG
6477 return 1;
6478 }
dc0b3eff
PB
6479 if (field_decl == error_mark_node)
6480 return 1;
5e942c50
APB
6481
6482 /* Layout the type of field_decl, since we may need
c877974e
APB
6483 it. Don't do primitive types or loaded classes. The
6484 situation of non primitive arrays may not handled
6485 properly here. FIXME */
5e942c50
APB
6486 if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
6487 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
6488 else
6489 field_decl_type = TREE_TYPE (field_decl);
6490 if (!JPRIMITIVE_TYPE_P (field_decl_type)
c877974e
APB
6491 && !CLASS_LOADED_P (field_decl_type)
6492 && !TYPE_ARRAY_P (field_decl_type))
6493 resolve_and_layout (field_decl_type, NULL_TREE);
6494 if (TYPE_ARRAY_P (field_decl_type))
6495 CLASS_LOADED_P (field_decl_type) = 1;
e04a16fb
AG
6496
6497 /* Check on accessibility here */
6498 if (not_accessible_p (type, field_decl, from_super))
6499 {
6500 parse_error_context
6501 (qual_wfl,
6502 "Can't access %s field `%s.%s' from `%s'",
6503 java_accstring_lookup
6504 (get_access_flags_from_decl (field_decl)),
2aa11e97 6505 GET_TYPE_NAME (type),
e04a16fb
AG
6506 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
6507 IDENTIFIER_POINTER
6508 (DECL_NAME (TYPE_NAME (current_class))));
6509 return 1;
6510 }
5e942c50 6511 check_deprecation (qual_wfl, field_decl);
e04a16fb
AG
6512
6513 /* There are things to check when fields are accessed
6514 from type. There are no restrictions on a static
6515 declaration of the field when it is accessed from an
6516 interface */
6517 is_static = FIELD_STATIC (field_decl);
6518 if (!from_super && from_type
6519 && !TYPE_INTERFACE_P (type) && !is_static)
6520 {
6521 parse_error_context
6522 (qual_wfl, "Can't make a static reference to nonstatic "
6523 "variable `%s' in class `%s'",
6524 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
6525 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
6526 return 1;
6527 }
6528 from_cast = from_super = 0;
6529
5e942c50
APB
6530 /* If we need to generate something to get a proper
6531 handle on what this field is accessed from, do it
6532 now. */
e04a16fb
AG
6533 if (!is_static)
6534 {
c583dd46 6535 decl = maybe_access_field (decl, *where_found, *type_found);
e04a16fb
AG
6536 if (decl == error_mark_node)
6537 return 1;
6538 }
6539
6540 /* We want to keep the location were found it, and the type
6541 we found. */
6542 *where_found = decl;
6543 *type_found = type;
6544
6545 /* This is the decl found and eventually the next one to
6546 search from */
6547 decl = field_decl;
6548 }
e04a16fb
AG
6549 from_type = 0;
6550 type = QUAL_DECL_TYPE (decl);
6551 }
6552 }
6553 *found_decl = decl;
6554 return 0;
6555}
6556
6557/* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
6558 can't be accessed from REFERENCE (a record type). */
6559
6560int not_accessible_p (reference, member, from_super)
6561 tree reference, member;
6562 int from_super;
6563{
6564 int access_flag = get_access_flags_from_decl (member);
6565
6566 /* Access always granted for members declared public */
6567 if (access_flag & ACC_PUBLIC)
6568 return 0;
6569
6570 /* Check access on protected members */
6571 if (access_flag & ACC_PROTECTED)
6572 {
6573 /* Access granted if it occurs from within the package
6574 containing the class in which the protected member is
6575 declared */
6576 if (class_in_current_package (DECL_CONTEXT (member)))
6577 return 0;
6578
9bbc7d9f
PB
6579 /* If accessed with the form `super.member', then access is granted */
6580 if (from_super)
6581 return 0;
e04a16fb 6582
9bbc7d9f
PB
6583 /* Otherwise, access is granted if occuring from the class where
6584 member is declared or a subclass of it */
6585 if (inherits_from_p (reference, current_class))
6586 return 0;
e04a16fb
AG
6587 return 1;
6588 }
6589
6590 /* Check access on private members. Access is granted only if it
c877974e 6591 occurs from within the class in witch it is declared */
e04a16fb
AG
6592 if (access_flag & ACC_PRIVATE)
6593 return (current_class == DECL_CONTEXT (member) ? 0 : 1);
6594
6595 /* Default access are permitted only when occuring within the
6596 package in which the type (REFERENCE) is declared. In other words,
6597 REFERENCE is defined in the current package */
6598 if (ctxp->package)
6599 return !class_in_current_package (reference);
6600
6601 /* Otherwise, access is granted */
6602 return 0;
6603}
6604
5e942c50
APB
6605/* Test deprecated decl access. */
6606static void
6607check_deprecation (wfl, decl)
6608 tree wfl, decl;
6609{
6610 char *file = DECL_SOURCE_FILE (decl);
6611 /* Complain if the field is deprecated and the file it was defined
6612 in isn't compiled at the same time the file which contains its
6613 use is */
6614 if (DECL_DEPRECATED (decl)
6615 && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
6616 {
6617 char the [20];
6618 switch (TREE_CODE (decl))
6619 {
6620 case FUNCTION_DECL:
6621 strcpy (the, "method");
6622 break;
6623 case FIELD_DECL:
6624 strcpy (the, "field");
6625 break;
6626 case TYPE_DECL:
6627 strcpy (the, "class");
6628 break;
15fdcfe9
PB
6629 default:
6630 fatal ("unexpected DECL code - check_deprecation");
5e942c50
APB
6631 }
6632 parse_warning_context
6633 (wfl, "The %s `%s' in class `%s' has been deprecated",
6634 the, lang_printable_name (decl, 0),
6635 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
6636 }
6637}
6638
e04a16fb
AG
6639/* Returns 1 if class was declared in the current package, 0 otherwise */
6640
6641static int
6642class_in_current_package (class)
6643 tree class;
6644{
6645 static tree cache = NULL_TREE;
6646 int qualified_flag;
6647 tree left;
6648
6649 if (cache == class)
6650 return 1;
6651
6652 qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
6653
6654 /* If the current package is empty and the name of CLASS is
6655 qualified, class isn't in the current package. If there is a
6656 current package and the name of the CLASS is not qualified, class
6657 isn't in the current package */
0a2138e2 6658 if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
e04a16fb
AG
6659 return 0;
6660
6661 /* If there is not package and the name of CLASS isn't qualified,
6662 they belong to the same unnamed package */
6663 if (!ctxp->package && !qualified_flag)
6664 return 1;
6665
6666 /* Compare the left part of the name of CLASS with the package name */
6667 breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
6668 if (ctxp->package == left)
6669 {
6670 cache = class;
6671 return 1;
6672 }
6673 return 0;
6674}
6675
6676/* This function may generate code to access DECL from WHERE. This is
6677 done only if certain conditions meet. */
6678
6679static tree
6680maybe_access_field (decl, where, type)
6681 tree decl, where, type;
6682{
5e942c50
APB
6683 if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
6684 && !FIELD_STATIC (decl))
e04a16fb 6685 decl = build_field_ref (where ? where : current_this,
c583dd46
APB
6686 (type ? type : DECL_CONTEXT (decl)),
6687 DECL_NAME (decl));
e04a16fb
AG
6688 return decl;
6689}
6690
15fdcfe9 6691/* Build a method invocation, by patching PATCH. If non NULL
e04a16fb
AG
6692 and according to the situation, PRIMARY and WHERE may be
6693 used. IS_STATIC is set to 1 if the invoked function is static. */
6694
6695static tree
89e09b9a 6696patch_method_invocation (patch, primary, where, is_static, ret_decl)
e04a16fb
AG
6697 tree patch, primary, where;
6698 int *is_static;
b9f7e36c 6699 tree *ret_decl;
e04a16fb
AG
6700{
6701 tree wfl = TREE_OPERAND (patch, 0);
6702 tree args = TREE_OPERAND (patch, 1);
6703 tree name = EXPR_WFL_NODE (wfl);
5e942c50 6704 tree list;
22eed1e6 6705 int is_static_flag = 0;
89e09b9a 6706 int is_super_init = 0;
bccaf73a 6707 tree this_arg = NULL_TREE;
e04a16fb
AG
6708
6709 /* Should be overriden if everything goes well. Otherwise, if
6710 something fails, it should keep this value. It stop the
6711 evaluation of a bogus assignment. See java_complete_tree,
6712 MODIFY_EXPR: for the reasons why we sometimes want to keep on
6713 evaluating an assignment */
6714 TREE_TYPE (patch) = error_mark_node;
6715
6716 /* Since lookup functions are messing with line numbers, save the
6717 context now. */
6718 java_parser_context_save_global ();
6719
6720 /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
6721
6722 /* Resolution of qualified name, excluding constructors */
6723 if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
6724 {
6725 tree class_decl, identifier, identifier_wfl;
6726 /* Extract the last IDENTIFIER of the qualified
6727 expression. This is a wfl and we will use it's location
6728 data during error report. */
6729 identifier_wfl = cut_identifier_in_qualified (wfl);
6730 identifier = EXPR_WFL_NODE (identifier_wfl);
6731
6732 /* Given the context, IDENTIFIER is syntactically qualified
6733 as a MethodName. We need to qualify what's before */
6734 qualify_ambiguous_name (wfl);
6735
6736 /* Package resolution are erroneous */
6737 if (RESOLVE_PACKAGE_NAME_P (wfl))
6738 {
6739 tree remainder;
6740 breakdown_qualified (&remainder, NULL, EXPR_WFL_NODE (wfl));
6741 parse_error_context (wfl, "Can't search method `%s' in package "
6742 "`%s'",IDENTIFIER_POINTER (identifier),
6743 IDENTIFIER_POINTER (remainder));
b9f7e36c 6744 PATCH_METHOD_RETURN_ERROR ();
e04a16fb
AG
6745 }
6746 /* We're resolving a call from a type */
6747 else if (RESOLVE_TYPE_NAME_P (wfl))
6748 {
6749 tree decl = QUAL_RESOLUTION (EXPR_WFL_QUALIFICATION (wfl));
6750 tree name = DECL_NAME (decl);
6751 tree type;
6752
6753 class_decl = resolve_and_layout (name, wfl);
6754 if (CLASS_INTERFACE (decl))
6755 {
6756 parse_error_context
6757 (identifier_wfl, "Can't make static reference to method "
6758 "`%s' in interface `%s'", IDENTIFIER_POINTER (identifier),
6759 IDENTIFIER_POINTER (name));
b9f7e36c 6760 PATCH_METHOD_RETURN_ERROR ();
e04a16fb
AG
6761 }
6762 /* Look the method up in the type selector. The method ought
6763 to be static. */
6764 type = TREE_TYPE (class_decl);
6765 list = lookup_method_invoke (0, wfl, type, identifier, args);
6766 if (list && !METHOD_STATIC (list))
6767 {
0a2138e2 6768 char *fct_name = strdup (lang_printable_name (list, 0));
e04a16fb
AG
6769 parse_error_context
6770 (identifier_wfl,
6771 "Can't make static reference to method `%s %s' in class `%s'",
0a2138e2
APB
6772 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
6773 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
e04a16fb 6774 free (fct_name);
b9f7e36c 6775 PATCH_METHOD_RETURN_ERROR ();
e04a16fb 6776 }
5e942c50 6777 args = nreverse (args);
e04a16fb
AG
6778 }
6779 /* We're resolving an expression name */
6780 else
6781 {
6782 tree field, type;
6783
6784 /* 1- Find the field to which the call applies */
6785 field = resolve_field_access (wfl, NULL, &type);
6786 if (field == error_mark_node)
b9f7e36c 6787 PATCH_METHOD_RETURN_ERROR ();
c3f2a476
APB
6788 /* field is used in lieu of a primary. It alows us not to
6789 report errors on erroneous use of `this' in
6790 constructors. */
6791 primary = field;
e04a16fb
AG
6792
6793 /* 2- Do the layout of the class where the last field
6794 was found, so we can search it. */
c877974e 6795 class_decl = resolve_and_layout (type, NULL_TREE);
3e78f871 6796 if (class_decl != NULL_TREE)
c877974e
APB
6797 type = TREE_TYPE (class_decl);
6798
e04a16fb
AG
6799 /* 3- Retrieve a filtered list of method matches, Refine
6800 if necessary. In any cases, point out errors. */
6801 list = lookup_method_invoke (0, identifier_wfl, type,
6802 identifier, args);
6803
6804 /* 4- Add the field as an argument */
bccaf73a
PB
6805 args = nreverse (args);
6806 this_arg = field;
e04a16fb
AG
6807 }
6808
5e942c50 6809 /* IDENTIFIER_WFL will be used to report any problem further */
e04a16fb
AG
6810 wfl = identifier_wfl;
6811 }
6812 /* Resolution of simple names, names generated after a primary: or
6813 constructors */
6814 else
6815 {
6816 tree class_to_search;
6817 int lc; /* Looking for Constructor */
6818
6819 /* We search constructor in their target class */
6820 if (CALL_CONSTRUCTOR_P (patch))
6821 {
22eed1e6
APB
6822 if (TREE_CODE (patch) == NEW_CLASS_EXPR)
6823 class_to_search = EXPR_WFL_NODE (wfl);
6824 else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
6825 this_identifier_node)
6826 class_to_search = NULL_TREE;
6827 else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
6828 super_identifier_node)
e04a16fb 6829 {
89e09b9a 6830 is_super_init = 1;
22eed1e6
APB
6831 if (CLASSTYPE_SUPER (current_class))
6832 class_to_search =
6833 DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
6834 else
6835 {
6836 parse_error_context (wfl, "Can't invoke super constructor "
6837 "on java.lang.Object");
6838 PATCH_METHOD_RETURN_ERROR ();
6839 }
e04a16fb 6840 }
22eed1e6
APB
6841
6842 /* Class to search is NULL if we're searching the current one */
6843 if (class_to_search)
e04a16fb 6844 {
23a79c61
APB
6845 class_to_search = resolve_and_layout (class_to_search,
6846 NULL_TREE);
22eed1e6
APB
6847 if (!class_to_search)
6848 {
6849 parse_error_context
6850 (wfl, "Class `%s' not found in type declaration",
6851 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
6852 PATCH_METHOD_RETURN_ERROR ();
6853 }
6854
5e942c50
APB
6855 /* Can't instantiate an abstract class, but we can
6856 invoke it's constructor. It's use within the `new'
6857 context is denied here. */
6858 if (CLASS_ABSTRACT (class_to_search)
6859 && TREE_CODE (patch) == NEW_CLASS_EXPR)
22eed1e6
APB
6860 {
6861 parse_error_context
6862 (wfl, "Class `%s' is an abstract class. It can't be "
6863 "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
6864 PATCH_METHOD_RETURN_ERROR ();
6865 }
6866 class_to_search = TREE_TYPE (class_to_search);
e04a16fb 6867 }
22eed1e6
APB
6868 else
6869 class_to_search = current_class;
e04a16fb
AG
6870 lc = 1;
6871 }
6872 /* This is a regular search in the local class, unless an
6873 alternate class is specified. */
6874 else
6875 {
6876 class_to_search = (where ? where : current_class);
6877 lc = 0;
6878 }
6879
6880 /* NAME is a simple identifier or comes from a primary. Search
6881 in the class whose declaration contain the method being
6882 invoked. */
c877974e 6883 resolve_and_layout (class_to_search, NULL_TREE);
e04a16fb
AG
6884 list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
6885
6886 /* Don't continue if no method were found, as the next statement
6887 can't be executed then. */
b9f7e36c
APB
6888 if (!list)
6889 PATCH_METHOD_RETURN_ERROR ();
e04a16fb
AG
6890
6891 /* Check for static reference if non static methods */
6892 if (check_for_static_method_reference (wfl, patch, list,
6893 class_to_search, primary))
b9f7e36c 6894 PATCH_METHOD_RETURN_ERROR ();
e04a16fb 6895
22eed1e6
APB
6896 /* Non static methods are called with the current object extra
6897 argument. If patch a `new TYPE()', the argument is the value
6898 returned by the object allocator. If method is resolved as a
6899 primary, use the primary otherwise use the current THIS. */
b9f7e36c 6900 args = nreverse (args);
bccaf73a
PB
6901 if (TREE_CODE (patch) != NEW_CLASS_EXPR)
6902 this_arg = primary ? primary : current_this;
e04a16fb 6903 }
b67d701b 6904
e04a16fb
AG
6905 /* Merge point of all resolution schemes. If we have nothing, this
6906 is an error, already signaled */
b9f7e36c
APB
6907 if (!list)
6908 PATCH_METHOD_RETURN_ERROR ();
b67d701b 6909
e04a16fb
AG
6910 /* Check accessibility, position the is_static flag, build and
6911 return the call */
9bbc7d9f 6912 if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
e04a16fb 6913 {
0a2138e2 6914 char *fct_name = strdup (lang_printable_name (list, 0));
e04a16fb
AG
6915 parse_error_context
6916 (wfl, "Can't access %s method `%s %s.%s' from `%s'",
6917 java_accstring_lookup (get_access_flags_from_decl (list)),
0a2138e2 6918 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
5e942c50
APB
6919 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))),
6920 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
e04a16fb 6921 free (fct_name);
b9f7e36c 6922 PATCH_METHOD_RETURN_ERROR ();
e04a16fb 6923 }
5e942c50 6924 check_deprecation (wfl, list);
22eed1e6
APB
6925
6926 is_static_flag = METHOD_STATIC (list);
bccaf73a
PB
6927 if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
6928 args = tree_cons (NULL_TREE, this_arg, args);
22eed1e6 6929
c3f2a476
APB
6930 /* In the context of an explicit constructor invocation, we can't
6931 invoke any method relying on `this'. Exceptions are: we're
6932 invoking a static function, primary exists and is not the current
6933 this, we're creating a new object. */
22eed1e6 6934 if (ctxp->explicit_constructor_p
c3f2a476
APB
6935 && !is_static_flag
6936 && (!primary || primary == current_this)
6937 && (TREE_CODE (patch) != NEW_CLASS_EXPR))
22eed1e6
APB
6938 {
6939 parse_error_context
6940 (wfl, "Can't reference `this' before the superclass constructor has "
6941 "been called");
6942 PATCH_METHOD_RETURN_ERROR ();
6943 }
e04a16fb 6944 java_parser_context_restore_global ();
22eed1e6
APB
6945 if (is_static)
6946 *is_static = is_static_flag;
b9f7e36c
APB
6947 /* Sometimes, we want the decl of the selected method. Such as for
6948 EH checking */
6949 if (ret_decl)
6950 *ret_decl = list;
89e09b9a
PB
6951 patch = patch_invoke (patch, list, args);
6952 if (is_super_init && CLASS_HAS_FINIT_P (current_class))
6953 {
6954 /* Generate the code used to initialize fields declared with an
6955 initialization statement. For now, it returns a call the the
6956 artificial function $finit$, if required. */
6957
6958 tree finit_call =
6959 build_method_invocation (build_expr_wfl (finit_identifier_node,
6960 input_filename, 0, 0),
6961 NULL_TREE);
6962 patch = build (COMPOUND_EXPR, void_type_node, patch,
6963 java_complete_tree (finit_call));
6964 CAN_COMPLETE_NORMALLY (patch) = 1;
6965 }
6966 return patch;
e04a16fb
AG
6967}
6968
6969/* Check that we're not trying to do a static reference to a method in
6970 non static method. Return 1 if it's the case, 0 otherwise. */
6971
6972static int
6973check_for_static_method_reference (wfl, node, method, where, primary)
6974 tree wfl, node, method, where, primary;
6975{
6976 if (METHOD_STATIC (current_function_decl)
6977 && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
6978 {
0a2138e2 6979 char *fct_name = strdup (lang_printable_name (method, 0));
e04a16fb
AG
6980 parse_error_context
6981 (wfl, "Can't make static reference to method `%s %s' in class `%s'",
0a2138e2 6982 lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
e04a16fb
AG
6983 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
6984 free (fct_name);
6985 return 1;
6986 }
6987 return 0;
6988}
6989
6990/* Patch an invoke expression METHOD and ARGS, based on its invocation
6991 mode. */
6992
6993static tree
89e09b9a 6994patch_invoke (patch, method, args)
e04a16fb 6995 tree patch, method, args;
e04a16fb
AG
6996{
6997 tree dtable, func;
0a2138e2 6998 tree original_call, t, ta;
e04a16fb 6999
5e942c50
APB
7000 /* Last step for args: convert build-in types. If we're dealing with
7001 a new TYPE() type call, the first argument to the constructor
7002 isn't found in the incomming argument list, but delivered by
7003 `new' */
7004 t = TYPE_ARG_TYPES (TREE_TYPE (method));
7005 if (TREE_CODE (patch) == NEW_CLASS_EXPR)
7006 t = TREE_CHAIN (t);
ac825856
APB
7007 for (ta = args; t != end_params_node && ta;
7008 t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
b9f7e36c
APB
7009 if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
7010 TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
7011 TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
22eed1e6 7012
15fdcfe9
PB
7013 if (flag_emit_class_files)
7014 func = method;
7015 else
e04a16fb 7016 {
15fdcfe9 7017 tree signature = build_java_signature (TREE_TYPE (method));
89e09b9a 7018 switch (invocation_mode (method, CALL_USING_SUPER (patch)))
15fdcfe9
PB
7019 {
7020 case INVOKE_VIRTUAL:
7021 dtable = invoke_build_dtable (0, args);
7022 func = build_invokevirtual (dtable, method);
7023 break;
b9f7e36c 7024
15fdcfe9
PB
7025 case INVOKE_SUPER:
7026 case INVOKE_STATIC:
7027 func = build_known_method_ref (method, TREE_TYPE (method),
7028 DECL_CONTEXT (method),
7029 signature, args);
7030 break;
e04a16fb 7031
15fdcfe9
PB
7032 case INVOKE_INTERFACE:
7033 dtable = invoke_build_dtable (1, args);
7034 func = build_invokeinterface (dtable, DECL_NAME (method), signature);
7035 break;
5e942c50 7036
15fdcfe9 7037 default:
89e09b9a 7038 fatal ("internal error - unknown invocation_mode result");
15fdcfe9
PB
7039 }
7040
7041 /* Ensure self_type is initialized, (invokestatic). FIXME */
7042 func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
e04a16fb
AG
7043 }
7044
e04a16fb
AG
7045 TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
7046 TREE_OPERAND (patch, 0) = func;
7047 TREE_OPERAND (patch, 1) = args;
7048 original_call = patch;
7049
22eed1e6
APB
7050 /* We're processing a `new TYPE ()' form. New is called an its
7051 returned value is the first argument to the constructor. We build
7052 a COMPOUND_EXPR and use saved expression so that the overall NEW
7053 expression value is a pointer to a newly created and initialized
7054 class. */
7055 if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
e04a16fb
AG
7056 {
7057 tree class = DECL_CONTEXT (method);
7058 tree c1, saved_new, size, new;
15fdcfe9
PB
7059 if (flag_emit_class_files)
7060 {
7061 TREE_TYPE (patch) = build_pointer_type (class);
7062 return patch;
7063 }
e04a16fb
AG
7064 if (!TYPE_SIZE (class))
7065 safe_layout_class (class);
7066 size = size_in_bytes (class);
7067 new = build (CALL_EXPR, promote_type (class),
7068 build_address_of (alloc_object_node),
7069 tree_cons (NULL_TREE, build_class_ref (class),
7070 build_tree_list (NULL_TREE,
7071 size_in_bytes (class))),
7072 NULL_TREE);
7073 saved_new = save_expr (new);
7074 c1 = build_tree_list (NULL_TREE, saved_new);
7075 TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
7076 TREE_OPERAND (original_call, 1) = c1;
7077 TREE_SET_CODE (original_call, CALL_EXPR);
7078 patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
7079 }
7080 return patch;
7081}
7082
7083static int
7084invocation_mode (method, super)
7085 tree method;
7086 int super;
7087{
7088 int access = get_access_flags_from_decl (method);
7089
22eed1e6
APB
7090 if (super)
7091 return INVOKE_SUPER;
7092
82371d41 7093 if (access & ACC_STATIC || access & ACC_FINAL || access & ACC_PRIVATE)
e04a16fb
AG
7094 return INVOKE_STATIC;
7095
7096 if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
7097 return INVOKE_STATIC;
7098
e04a16fb
AG
7099 if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
7100 return INVOKE_INTERFACE;
7101
7102 if (DECL_CONSTRUCTOR_P (method))
7103 return INVOKE_STATIC;
22eed1e6 7104
e04a16fb
AG
7105 return INVOKE_VIRTUAL;
7106}
7107
b67d701b
PB
7108/* Retrieve a refined list of matching methods. It covers the step
7109 15.11.2 (Compile-Time Step 2) */
e04a16fb
AG
7110
7111static tree
7112lookup_method_invoke (lc, cl, class, name, arg_list)
7113 int lc;
7114 tree cl;
7115 tree class, name, arg_list;
7116{
de4c7b02 7117 tree atl = end_params_node; /* Arg Type List */
c877974e 7118 tree method, signature, list, node;
b67d701b 7119 char *candidates; /* Used for error report */
e04a16fb 7120
5e942c50 7121 /* Fix the arguments */
e04a16fb
AG
7122 for (node = arg_list; node; node = TREE_CHAIN (node))
7123 {
e3884b71 7124 tree current_arg = TREE_TYPE (TREE_VALUE (node));
c877974e 7125 /* Non primitive type may have to be resolved */
e3884b71 7126 if (!JPRIMITIVE_TYPE_P (current_arg))
c877974e
APB
7127 resolve_and_layout (current_arg, NULL_TREE);
7128 /* And promoted */
b67d701b 7129 if (TREE_CODE (current_arg) == RECORD_TYPE)
c877974e 7130 current_arg = promote_type (current_arg);
5e942c50 7131 atl = tree_cons (NULL_TREE, current_arg, atl);
e04a16fb 7132 }
e04a16fb 7133
5e942c50
APB
7134 /* Find all candidates and then refine the list, searching for the
7135 most specific method. */
7136 list = find_applicable_accessible_methods_list (lc, class, name, atl);
7137 list = find_most_specific_methods_list (list);
b67d701b
PB
7138 if (list && !TREE_CHAIN (list))
7139 return TREE_VALUE (list);
e04a16fb 7140
b67d701b
PB
7141 /* Issue an error. List candidates if any. Candidates are listed
7142 only if accessible (non accessible methods may end-up here for
7143 the sake of a better error report). */
7144 candidates = NULL;
7145 if (list)
e04a16fb 7146 {
e04a16fb 7147 tree current;
b67d701b 7148 obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
e04a16fb
AG
7149 for (current = list; current; current = TREE_CHAIN (current))
7150 {
b67d701b
PB
7151 tree cm = TREE_VALUE (current);
7152 char string [4096];
7153 if (!cm || not_accessible_p (class, cm, 0))
7154 continue;
b67d701b 7155 sprintf
22eed1e6
APB
7156 (string, " `%s' in `%s'%s",
7157 get_printable_method_name (cm),
b67d701b
PB
7158 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
7159 (TREE_CHAIN (current) ? "\n" : ""));
7160 obstack_grow (&temporary_obstack, string, strlen (string));
7161 }
7162 obstack_1grow (&temporary_obstack, '\0');
7163 candidates = obstack_finish (&temporary_obstack);
7164 }
7165 /* Issue the error message */
c877974e
APB
7166 method = make_node (FUNCTION_TYPE);
7167 TYPE_ARG_TYPES (method) = atl;
b67d701b 7168 signature = build_java_argument_signature (method);
22eed1e6
APB
7169 parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
7170 (lc ? "constructor" : "method"),
7171 (lc ?
7172 IDENTIFIER_POINTER(DECL_NAME (TYPE_NAME (class))) :
7173 IDENTIFIER_POINTER (name)),
b67d701b
PB
7174 IDENTIFIER_POINTER (signature),
7175 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))),
7176 (candidates ? candidates : ""));
7177 return NULL_TREE;
7178}
7179
5e942c50
APB
7180/* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
7181 when we're looking for a constructor. */
b67d701b
PB
7182
7183static tree
5e942c50
APB
7184find_applicable_accessible_methods_list (lc, class, name, arglist)
7185 int lc;
b67d701b
PB
7186 tree class, name, arglist;
7187{
b67d701b
PB
7188 tree list = NULL_TREE, all_list = NULL_TREE;
7189
1982388a
APB
7190 /* Search interfaces */
7191 if (CLASS_INTERFACE (TYPE_NAME (class)))
b67d701b 7192 {
de0b553f
APB
7193 static tree searched_interfaces = NULL_TREE;
7194 static int search_not_done = 0;
1982388a
APB
7195 int i, n;
7196 tree basetype_vec = TYPE_BINFO_BASETYPES (class);
7197
de0b553f
APB
7198 /* Have we searched this interface already? */
7199 if (searched_interfaces)
7200 {
7201 tree current;
7202 for (current = searched_interfaces;
7203 current; current = TREE_CHAIN (current))
7204 if (TREE_VALUE (current) == class)
7205 return NULL;
7206 }
7207 searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
7208
1982388a
APB
7209 search_applicable_methods_list
7210 (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
7211
7212 n = TREE_VEC_LENGTH (basetype_vec);
7213 for (i = 0; i < n; i++)
b67d701b 7214 {
de0b553f
APB
7215 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
7216 tree rlist;
7217
7218 /* Skip java.lang.Object (we'll search it once later.) */
7219 if (t == object_type_node)
7220 continue;
7221
7222 search_not_done++;
7223 rlist = find_applicable_accessible_methods_list (lc, t, name,
7224 arglist);
1982388a 7225 all_list = chainon (rlist, (list ? list : all_list));
de0b553f
APB
7226 search_not_done--;
7227 }
7228
7229 /* We're done. Reset the searched interfaces list and finally search
7230 java.lang.Object */
7231 if (!search_not_done)
7232 {
7233 searched_interfaces = NULL_TREE;
7234 search_applicable_methods_list (lc, TYPE_METHODS (object_type_node),
7235 name, arglist, &list, &all_list);
e04a16fb 7236 }
e04a16fb 7237 }
1982388a
APB
7238 /* Search classes */
7239 else
7240 while (class != NULL_TREE)
7241 {
7242 search_applicable_methods_list
7243 (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
7244 class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
7245 }
7246
b67d701b
PB
7247 /* Either return the list obtained or all selected (but
7248 inaccessible) methods for better error report. */
7249 return (!list ? all_list : list);
7250}
e04a16fb 7251
1982388a
APB
7252/* Effectively search for the approriate method in method */
7253
7254static void
7255search_applicable_methods_list(lc, method, name, arglist, list, all_list)
7256 int lc;
7257 tree method, name, arglist;
7258 tree *list, *all_list;
7259{
7260 for (; method; method = TREE_CHAIN (method))
7261 {
7262 /* When dealing with constructor, stop here, otherwise search
7263 other classes */
7264 if (lc && !DECL_CONSTRUCTOR_P (method))
7265 continue;
7266 else if (!lc && (DECL_CONSTRUCTOR_P (method)
7267 || (GET_METHOD_NAME (method) != name)))
7268 continue;
7269
7270 if (argument_types_convertible (method, arglist))
7271 {
7272 /* Retain accessible methods only */
7273 if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
7274 method, 0))
7275 *list = tree_cons (NULL_TREE, method, *list);
7276 else
7277 /* Also retain all selected method here */
7278 *all_list = tree_cons (NULL_TREE, method, *list);
7279 }
7280 }
7281}
7282
b67d701b
PB
7283/* 15.11.2.2 Choose the Most Specific Method */
7284
7285static tree
7286find_most_specific_methods_list (list)
7287 tree list;
7288{
7289 int max = 0;
7290 tree current, new_list = NULL_TREE;
7291 for (current = list; current; current = TREE_CHAIN (current))
e04a16fb 7292 {
b67d701b
PB
7293 tree method;
7294 DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
7295
7296 for (method = list; method; method = TREE_CHAIN (method))
7297 {
7298 /* Don't test a method against itself */
7299 if (method == current)
7300 continue;
7301
7302 /* Compare arguments and location where method where declared */
7303 if (argument_types_convertible (TREE_VALUE (method),
7304 TREE_VALUE (current))
7305 && valid_method_invocation_conversion_p
7306 (DECL_CONTEXT (TREE_VALUE (method)),
7307 DECL_CONTEXT (TREE_VALUE (current))))
7308 {
7309 int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
7310 max = (v > max ? v : max);
7311 }
7312 }
e04a16fb
AG
7313 }
7314
b67d701b
PB
7315 /* Review the list and select the maximally specific methods */
7316 for (current = list; current; current = TREE_CHAIN (current))
7317 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
7318 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
7319
7320 /* If we can't find one, lower expectations and try to gather multiple
7321 maximally specific methods */
7322 while (!new_list)
7323 {
7324 while (--max > 0)
7325 {
7326 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
7327 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
7328 }
7329 return new_list;
7330 }
7331
7332 return new_list;
e04a16fb
AG
7333}
7334
b67d701b
PB
7335/* Make sure that the type of each M2_OR_ARGLIST arguments can be
7336 converted by method invocation conversion (5.3) to the type of the
7337 corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
7338 to change less often than M1. */
e04a16fb 7339
b67d701b
PB
7340static int
7341argument_types_convertible (m1, m2_or_arglist)
7342 tree m1, m2_or_arglist;
e04a16fb 7343{
b67d701b
PB
7344 static tree m2_arg_value = NULL_TREE;
7345 static tree m2_arg_cache = NULL_TREE;
e04a16fb 7346
b67d701b 7347 register tree m1_arg, m2_arg;
e04a16fb 7348
b67d701b
PB
7349 m1_arg = TYPE_ARG_TYPES (TREE_TYPE (m1));
7350 if (!METHOD_STATIC (m1))
7351 m1_arg = TREE_CHAIN (m1_arg);
e04a16fb 7352
b67d701b
PB
7353 if (m2_arg_value == m2_or_arglist)
7354 m2_arg = m2_arg_cache;
7355 else
7356 {
7357 /* M2_OR_ARGLIST can be a function DECL or a raw list of
7358 argument types */
7359 if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
7360 {
7361 m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
7362 if (!METHOD_STATIC (m2_or_arglist))
7363 m2_arg = TREE_CHAIN (m2_arg);
7364 }
7365 else
7366 m2_arg = m2_or_arglist;
e04a16fb 7367
b67d701b
PB
7368 m2_arg_value = m2_or_arglist;
7369 m2_arg_cache = m2_arg;
7370 }
e04a16fb 7371
de4c7b02 7372 while (m1_arg != end_params_node && m2_arg != end_params_node)
b67d701b 7373 {
c877974e 7374 resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
b67d701b
PB
7375 if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
7376 TREE_VALUE (m2_arg)))
7377 break;
7378 m1_arg = TREE_CHAIN (m1_arg);
7379 m2_arg = TREE_CHAIN (m2_arg);
e04a16fb 7380 }
de4c7b02 7381 return m1_arg == end_params_node && m2_arg == end_params_node;
e04a16fb
AG
7382}
7383
7384/* Qualification routines */
7385
7386static void
7387qualify_ambiguous_name (id)
7388 tree id;
7389{
7390 tree qual, qual_wfl, name, decl, ptr_type, saved_current_class;
d8fccff5 7391 int again, super_found = 0, this_found = 0, new_array_found = 0;
e04a16fb
AG
7392
7393 /* We first qualify the first element, then derive qualification of
7394 others based on the first one. If the first element is qualified
7395 by a resolution (field or type), this resolution is stored in the
7396 QUAL_RESOLUTION of the qual element being examined. We need to
7397 save the current_class since the use of SUPER might change the
7398 its value. */
7399 saved_current_class = current_class;
7400 qual = EXPR_WFL_QUALIFICATION (id);
7401 do {
7402
7403 /* Simple qualified expression feature a qual_wfl that is a
7404 WFL. Expression derived from a primary feature more complicated
7405 things like a CALL_EXPR. Expression from primary need to be
7406 worked out to extract the part on which the qualification will
7407 take place. */
7408 qual_wfl = QUAL_WFL (qual);
7409 switch (TREE_CODE (qual_wfl))
7410 {
7411 case CALL_EXPR:
7412 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7413 if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
7414 {
7415 qual = EXPR_WFL_QUALIFICATION (qual_wfl);
7416 qual_wfl = QUAL_WFL (qual);
7417 }
7418 break;
d8fccff5
APB
7419 case NEW_ARRAY_EXPR:
7420 qual = TREE_CHAIN (qual);
7421 new_array_found = again = 1;
7422 continue;
b67d701b 7423 case NEW_CLASS_EXPR:
e04a16fb 7424 case CONVERT_EXPR:
e04a16fb
AG
7425 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7426 break;
c583dd46
APB
7427 case ARRAY_REF:
7428 while (TREE_CODE (qual_wfl) == ARRAY_REF)
7429 qual_wfl = TREE_OPERAND (qual_wfl, 0);
7430 break;
0a2138e2
APB
7431 default:
7432 /* Fix for -Wall. Just break doing nothing */
7433 break;
e04a16fb
AG
7434 }
7435 name = EXPR_WFL_NODE (qual_wfl);
7436 ptr_type = current_class;
7437 again = 0;
7438 /* If we have a THIS (from a primary), we set the context accordingly */
7439 if (name == this_identifier_node)
7440 {
7441 qual = TREE_CHAIN (qual);
7442 qual_wfl = QUAL_WFL (qual);
22eed1e6
APB
7443 if (TREE_CODE (qual_wfl) == CALL_EXPR)
7444 again = 1;
7445 else
7446 name = EXPR_WFL_NODE (qual_wfl);
e04a16fb
AG
7447 this_found = 1;
7448 }
7449 /* If we have a SUPER, we set the context accordingly */
7450 if (name == super_identifier_node)
7451 {
7452 current_class = CLASSTYPE_SUPER (ptr_type);
7453 /* Check that there is such a thing as a super class. If not,
7454 return. The error will be caught later on, during the
7455 resolution */
7456 if (!current_class)
7457 {
7458 current_class = saved_current_class;
7459 return;
7460 }
7461 qual = TREE_CHAIN (qual);
7462 /* Do one more interation to set things up */
7463 super_found = again = 1;
7464 }
09ed0f70
APB
7465 /* Loop one more time if we're dealing with ?: or a string
7466 constant, or a convert expression */
5e942c50 7467 if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR
09ed0f70
APB
7468 || TREE_CODE (qual_wfl) == STRING_CST
7469 || TREE_CODE (qual_wfl) == CONVERT_EXPR)
22eed1e6
APB
7470 {
7471 qual = TREE_CHAIN (qual);
7472 qual_wfl = QUAL_WFL (qual);
7473 again = 1;
7474 }
e04a16fb
AG
7475 } while (again);
7476
7477 /* If name appears within the scope of a location variable
7478 declaration or parameter declaration, then it is an expression
7479 name. We don't carry this test out if we're in the context of the
7480 use of SUPER or THIS */
e04a16fb
AG
7481 if (!this_found && !super_found && (decl = IDENTIFIER_LOCAL_VALUE (name)))
7482 {
7483 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
7484 QUAL_RESOLUTION (qual) = decl;
7485 }
7486
7487 /* If within the class/interface NAME was found to be used there
7488 exists a (possibly inherited) field named NAME, then this is an
d8fccff5
APB
7489 expression name. If we saw a NEW_ARRAY_EXPR before and want to
7490 address length, it is OK. */
7491 else if ((decl = lookup_field_wrapper (ptr_type, name))
7492 || (new_array_found && name == length_identifier_node))
e04a16fb
AG
7493 {
7494 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
d8fccff5 7495 QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
e04a16fb
AG
7496 }
7497
7498 /* We reclassify NAME as a type name if:
7499 - NAME is a class/interface declared within the compilation
7500 unit containing NAME,
7501 - NAME is imported via a single-type-import declaration,
7502 - NAME is declared in an another compilation unit of the package
7503 of the compilation unit containing NAME,
7504 - NAME is declared by exactly on type-import-on-demand declaration
7505 of the compilation unit containing NAME. */
7506 else if ((decl = resolve_and_layout (name, NULL_TREE)))
7507 {
7508 RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
7509 QUAL_RESOLUTION (qual) = decl;
7510 }
7511
7512 /* Method call are expression name */
9bbc7d9f
PB
7513 else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
7514 || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF)
e04a16fb
AG
7515 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
7516
7517 /* Check here that NAME isn't declared by more than one
7518 type-import-on-demand declaration of the compilation unit
7519 containing NAME. FIXME */
7520
7521 /* Otherwise, NAME is reclassified as a package name */
7522 else
7523 RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
7524
7525 /* Propagate the qualification accross other components of the
7526 qualified name */
7527 for (qual = TREE_CHAIN (qual); qual;
7528 qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
7529 {
7530 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
7531 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
7532 else
7533 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
7534 }
7535
7536 /* Store the global qualification for the ambiguous part of ID back
7537 into ID fields */
7538 if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
7539 RESOLVE_EXPRESSION_NAME_P (id) = 1;
7540 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
7541 RESOLVE_TYPE_NAME_P (id) = 1;
7542 else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
7543 RESOLVE_PACKAGE_NAME_P (id) = 1;
7544
7545 /* Restore the current class */
7546 current_class = saved_current_class;
7547}
7548
7549static int
7550breakdown_qualified (left, right, source)
7551 tree *left, *right, source;
7552{
7553 char *p = IDENTIFIER_POINTER (source), *base;
7554 int l = IDENTIFIER_LENGTH (source);
7555
7556 /* Breakdown NAME into REMAINDER . IDENTIFIER */
7557 base = p;
7558 p += (l-1);
7559 while (*p != '.' && p != base)
7560 p--;
7561
7562 /* We didn't find a '.'. Return an error */
7563 if (p == base)
7564 return 1;
7565
7566 *p = '\0';
7567 if (right)
7568 *right = get_identifier (p+1);
7569 *left = get_identifier (IDENTIFIER_POINTER (source));
7570 *p = '.';
7571
7572 return 0;
7573}
7574
e04a16fb 7575/* Patch tree nodes in a function body. When a BLOCK is found, push
5b09b33e
PB
7576 local variable decls if present.
7577 Same as java_complete_lhs, but does resolve static finals to values. */
e04a16fb
AG
7578
7579static tree
7580java_complete_tree (node)
7581 tree node;
5b09b33e
PB
7582{
7583 node = java_complete_lhs (node);
7584 if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
7585 && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE)
7586 {
7587 tree value = DECL_INITIAL (node);
7588 DECL_INITIAL (node) = NULL_TREE;
7589 value = fold_constant_for_init (value, node);
7590 DECL_INITIAL (node) = value;
7591 if (value != NULL_TREE)
7592 return value;
7593 }
7594 return node;
7595}
7596
2aa11e97
APB
7597static tree
7598java_stabilize_reference (node)
7599 tree node;
7600{
7601 if (TREE_CODE (node) == COMPOUND_EXPR)
7602 {
7603 tree op0 = TREE_OPERAND (node, 0);
7604 tree op1 = TREE_OPERAND (node, 1);
642f15d1 7605 TREE_OPERAND (node, 0) = save_expr (op0);
2aa11e97
APB
7606 TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
7607 return node;
7608 }
7609 else
7610 return stabilize_reference (node);
7611}
7612
5b09b33e
PB
7613/* Patch tree nodes in a function body. When a BLOCK is found, push
7614 local variable decls if present.
7615 Same as java_complete_tree, but does not resolve static finals to values. */
7616
7617static tree
7618java_complete_lhs (node)
7619 tree node;
e04a16fb 7620{
22eed1e6 7621 tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
b67d701b 7622 int flag;
e04a16fb
AG
7623
7624 /* CONVERT_EXPR always has its type set, even though it needs to be
b67d701b 7625 worked out. */
e04a16fb
AG
7626 if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
7627 return node;
7628
7629 /* The switch block implements cases processing container nodes
7630 first. Contained nodes are always written back. Leaves come
7631 next and return a value. */
7632 switch (TREE_CODE (node))
7633 {
7634 case BLOCK:
7635
7636 /* 1- Block section.
7637 Set the local values on decl names so we can identify them
7638 faster when they're referenced. At that stage, identifiers
7639 are legal so we don't check for declaration errors. */
7640 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
7641 {
7642 DECL_CONTEXT (cn) = current_function_decl;
7643 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
e04a16fb 7644 }
15fdcfe9
PB
7645 if (BLOCK_EXPR_BODY (node) == NULL_TREE)
7646 CAN_COMPLETE_NORMALLY (node) = 1;
7647 else
e04a16fb 7648 {
15fdcfe9
PB
7649 tree stmt = BLOCK_EXPR_BODY (node);
7650 tree *ptr;
7651 int error_seen = 0;
7652 if (TREE_CODE (stmt) == COMPOUND_EXPR)
7653 {
c877974e
APB
7654 /* Re-order from (((A; B); C); ...; Z) to
7655 (A; (B; (C ; (...; Z)))).
15fdcfe9
PB
7656 This makes it easier to scan the statements left-to-right
7657 without using recursion (which might overflow the stack
7658 if the block has many statements. */
7659 for (;;)
7660 {
7661 tree left = TREE_OPERAND (stmt, 0);
7662 if (TREE_CODE (left) != COMPOUND_EXPR)
7663 break;
7664 TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
7665 TREE_OPERAND (left, 1) = stmt;
7666 stmt = left;
7667 }
7668 BLOCK_EXPR_BODY (node) = stmt;
7669 }
7670
c877974e
APB
7671 /* Now do the actual complete, without deep recursion for
7672 long blocks. */
15fdcfe9 7673 ptr = &BLOCK_EXPR_BODY (node);
dc0b3eff
PB
7674 while (TREE_CODE (*ptr) == COMPOUND_EXPR
7675 && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
15fdcfe9
PB
7676 {
7677 tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
7678 tree *next = &TREE_OPERAND (*ptr, 1);
7679 TREE_OPERAND (*ptr, 0) = cur;
7680 if (TREE_CODE (cur) == ERROR_MARK)
7681 error_seen++;
7682 else if (! CAN_COMPLETE_NORMALLY (cur))
7683 {
7684 wfl_op2 = *next;
7685 for (;;)
7686 {
7687 if (TREE_CODE (wfl_op2) == BLOCK)
7688 wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
7689 else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
7690 wfl_op2 = TREE_OPERAND (wfl_op2, 0);
7691 else
7692 break;
7693 }
7694 if (TREE_CODE (wfl_op2) != CASE_EXPR
dc0b3eff 7695 && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
82371d41 7696 unreachable_stmt_error (*ptr);
15fdcfe9
PB
7697 }
7698 ptr = next;
7699 }
7700 *ptr = java_complete_tree (*ptr);
7701
7702 if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
e04a16fb 7703 return error_mark_node;
15fdcfe9 7704 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
e04a16fb
AG
7705 }
7706 /* Turn local bindings to null */
7707 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
7708 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
7709
7710 TREE_TYPE (node) = void_type_node;
7711 break;
7712
7713 /* 2- They are expressions but ultimately deal with statements */
b67d701b 7714
b9f7e36c
APB
7715 case THROW_EXPR:
7716 wfl_op1 = TREE_OPERAND (node, 0);
7717 COMPLETE_CHECK_OP_0 (node);
15fdcfe9 7718 /* CAN_COMPLETE_NORMALLY (node) = 0; */
b9f7e36c
APB
7719 return patch_throw_statement (node, wfl_op1);
7720
7721 case SYNCHRONIZED_EXPR:
7722 wfl_op1 = TREE_OPERAND (node, 0);
b9f7e36c
APB
7723 return patch_synchronized_statement (node, wfl_op1);
7724
b67d701b
PB
7725 case TRY_EXPR:
7726 return patch_try_statement (node);
7727
a7d8d81f
PB
7728 case TRY_FINALLY_EXPR:
7729 COMPLETE_CHECK_OP_0 (node);
7730 COMPLETE_CHECK_OP_1 (node);
7731 CAN_COMPLETE_NORMALLY (node)
7732 = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
7733 && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
7734 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
7735 return node;
7736
5a005d9e
PB
7737 case CLEANUP_POINT_EXPR:
7738 COMPLETE_CHECK_OP_0 (node);
7739 TREE_TYPE (node) = void_type_node;
2aa11e97
APB
7740 CAN_COMPLETE_NORMALLY (node) =
7741 CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
5a005d9e
PB
7742 return node;
7743
7744 case WITH_CLEANUP_EXPR:
7745 COMPLETE_CHECK_OP_0 (node);
7746 COMPLETE_CHECK_OP_2 (node);
2aa11e97
APB
7747 CAN_COMPLETE_NORMALLY (node) =
7748 CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
5a005d9e
PB
7749 TREE_TYPE (node) = void_type_node;
7750 return node;
7751
e04a16fb
AG
7752 case LABELED_BLOCK_EXPR:
7753 PUSH_LABELED_BLOCK (node);
7754 if (LABELED_BLOCK_BODY (node))
7755 COMPLETE_CHECK_OP_1 (node);
7756 TREE_TYPE (node) = void_type_node;
7757 POP_LABELED_BLOCK ();
15fdcfe9
PB
7758 if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
7759 CAN_COMPLETE_NORMALLY (node) = 1;
e04a16fb
AG
7760 return node;
7761
7762 case EXIT_BLOCK_EXPR:
7763 /* We don't complete operand 1, because it's the return value of
7764 the EXIT_BLOCK_EXPR which doesn't exist it Java */
7765 return patch_bc_statement (node);
7766
15fdcfe9
PB
7767 case CASE_EXPR:
7768 cn = java_complete_tree (TREE_OPERAND (node, 0));
7769 if (cn == error_mark_node)
7770 return cn;
7771
7772 /* First, the case expression must be constant */
7773 cn = fold (cn);
7774
7775 if (!TREE_CONSTANT (cn))
7776 {
7777 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7778 parse_error_context (node, "Constant expression required");
7779 return error_mark_node;
7780 }
7781
7782 nn = ctxp->current_loop;
7783
7784 /* It must be assignable to the type of the switch expression. */
c877974e
APB
7785 if (!try_builtin_assignconv (NULL_TREE,
7786 TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
15fdcfe9
PB
7787 {
7788 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7789 parse_error_context
7790 (wfl_operator,
7791 "Incompatible type for case. Can't convert `%s' to `int'",
7792 lang_printable_name (TREE_TYPE (cn), 0));
7793 return error_mark_node;
7794 }
7795
7796 cn = fold (convert (int_type_node, cn));
7797
7798 /* Multiple instance of a case label bearing the same
7799 value is checked during code generation. The case
7800 expression is allright so far. */
7801 TREE_OPERAND (node, 0) = cn;
9bbc7d9f 7802 TREE_TYPE (node) = void_type_node;
15fdcfe9 7803 CAN_COMPLETE_NORMALLY (node) = 1;
10100cc7 7804 TREE_SIDE_EFFECTS (node) = 1;
15fdcfe9
PB
7805 break;
7806
7807 case DEFAULT_EXPR:
7808 nn = ctxp->current_loop;
7809 /* Only one default label is allowed per switch statement */
7810 if (SWITCH_HAS_DEFAULT (nn))
7811 {
7812 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7813 parse_error_context (wfl_operator,
7814 "Duplicate case label: `default'");
7815 return error_mark_node;
7816 }
7817 else
7818 SWITCH_HAS_DEFAULT (nn) = 1;
9bbc7d9f 7819 TREE_TYPE (node) = void_type_node;
10100cc7 7820 TREE_SIDE_EFFECTS (node) = 1;
15fdcfe9
PB
7821 CAN_COMPLETE_NORMALLY (node) = 1;
7822 break;
7823
b67d701b 7824 case SWITCH_EXPR:
e04a16fb
AG
7825 case LOOP_EXPR:
7826 PUSH_LOOP (node);
7827 /* Check whether the loop was enclosed in a labeled
7828 statement. If not, create one, insert the loop in it and
7829 return the node */
7830 nn = patch_loop_statement (node);
b67d701b 7831
e04a16fb 7832 /* Anyways, walk the body of the loop */
b67d701b
PB
7833 if (TREE_CODE (node) == LOOP_EXPR)
7834 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
7835 /* Switch statement: walk the switch expression and the cases */
7836 else
7837 node = patch_switch_statement (node);
7838
e04a16fb 7839 if (TREE_OPERAND (node, 0) == error_mark_node)
b635eb2f
PB
7840 nn = error_mark_node;
7841 else
15fdcfe9 7842 {
b635eb2f
PB
7843 TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
7844 /* If we returned something different, that's because we
7845 inserted a label. Pop the label too. */
7846 if (nn != node)
7847 {
7848 if (CAN_COMPLETE_NORMALLY (node))
7849 CAN_COMPLETE_NORMALLY (nn) = 1;
7850 POP_LABELED_BLOCK ();
7851 }
15fdcfe9 7852 }
e04a16fb
AG
7853 POP_LOOP ();
7854 return nn;
7855
7856 case EXIT_EXPR:
7857 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
7858 return patch_exit_expr (node);
7859
7860 case COND_EXPR:
7861 /* Condition */
7862 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
7863 if (TREE_OPERAND (node, 0) == error_mark_node)
7864 return error_mark_node;
7865 /* then-else branches */
7866 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
7867 if (TREE_OPERAND (node, 1) == error_mark_node)
7868 return error_mark_node;
7869 TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
7870 if (TREE_OPERAND (node, 2) == error_mark_node)
7871 return error_mark_node;
7872 return patch_if_else_statement (node);
7873 break;
7874
22eed1e6
APB
7875 case CONDITIONAL_EXPR:
7876 /* Condition */
7877 wfl_op1 = TREE_OPERAND (node, 0);
7878 COMPLETE_CHECK_OP_0 (node);
7879 wfl_op2 = TREE_OPERAND (node, 1);
7880 COMPLETE_CHECK_OP_1 (node);
7881 wfl_op3 = TREE_OPERAND (node, 2);
7882 COMPLETE_CHECK_OP_2 (node);
7883 return patch_conditional_expr (node, wfl_op1, wfl_op2);
7884
e04a16fb
AG
7885 /* 3- Expression section */
7886 case COMPOUND_EXPR:
15fdcfe9 7887 wfl_op2 = TREE_OPERAND (node, 1);
ac825856
APB
7888 TREE_OPERAND (node, 0) = nn =
7889 java_complete_tree (TREE_OPERAND (node, 0));
dc0b3eff
PB
7890 if (wfl_op2 == empty_stmt_node)
7891 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
7892 else
15fdcfe9 7893 {
dc0b3eff 7894 if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
bccaf73a 7895 {
dc0b3eff
PB
7896 /* An unreachable condition in a do-while statement
7897 is *not* (technically) an unreachable statement. */
7898 nn = wfl_op2;
7899 if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
7900 nn = EXPR_WFL_NODE (nn);
7901 if (TREE_CODE (nn) != EXIT_EXPR)
7902 {
7903 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
7904 parse_error_context (wfl_operator, "Unreachable statement");
7905 }
bccaf73a 7906 }
dc0b3eff
PB
7907 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
7908 if (TREE_OPERAND (node, 1) == error_mark_node)
7909 return error_mark_node;
7910 CAN_COMPLETE_NORMALLY (node)
7911 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
15fdcfe9 7912 }
e04a16fb
AG
7913 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
7914 break;
7915
7916 case RETURN_EXPR:
15fdcfe9 7917 /* CAN_COMPLETE_NORMALLY (node) = 0; */
e04a16fb
AG
7918 return patch_return (node);
7919
7920 case EXPR_WITH_FILE_LOCATION:
7921 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
7922 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
15fdcfe9
PB
7923 {
7924 node = resolve_expression_name (node, NULL);
dc0b3eff
PB
7925 if (node == error_mark_node)
7926 return node;
15fdcfe9
PB
7927 CAN_COMPLETE_NORMALLY (node) = 1;
7928 }
e04a16fb
AG
7929 else
7930 {
5b09b33e
PB
7931 tree body;
7932 int save_lineno = lineno;
7933 lineno = EXPR_WFL_LINENO (node);
7934 body = java_complete_tree (EXPR_WFL_NODE (node));
7935 lineno = save_lineno;
15fdcfe9 7936 EXPR_WFL_NODE (node) = body;
dc0b3eff 7937 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
15fdcfe9 7938 CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
dc0b3eff 7939 if (body == error_mark_node)
e04a16fb
AG
7940 {
7941 /* Its important for the evaluation of assignment that
7942 this mark on the TREE_TYPE is propagated. */
7943 TREE_TYPE (node) = error_mark_node;
7944 return error_mark_node;
7945 }
7946 else
7947 TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
15fdcfe9 7948
e04a16fb
AG
7949 }
7950 break;
7951
b67d701b 7952 case NEW_ARRAY_EXPR:
e04a16fb
AG
7953 /* Patch all the dimensions */
7954 flag = 0;
7955 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
7956 {
7957 int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
7958 tree dim = java_complete_tree (TREE_VALUE (cn));
7959 if (dim == error_mark_node)
7960 {
7961 flag = 1;
7962 continue;
7963 }
7964 else
7965 {
b9f7e36c 7966 TREE_VALUE (cn) = dim;
e04a16fb
AG
7967 /* Setup the location of the current dimension, for
7968 later error report. */
7969 TREE_PURPOSE (cn) =
7970 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
7971 EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
7972 }
7973 }
7974 /* They complete the array creation expression, if no errors
7975 were found. */
15fdcfe9 7976 CAN_COMPLETE_NORMALLY (node) = 1;
aee48ef8
PB
7977 return (flag ? error_mark_node
7978 : force_evaluation_order (patch_newarray (node)));
e04a16fb 7979
b67d701b 7980 case NEW_CLASS_EXPR:
e04a16fb 7981 case CALL_EXPR:
b67d701b 7982 /* Complete function's argument(s) first */
e04a16fb
AG
7983 if (complete_function_arguments (node))
7984 return error_mark_node;
7985 else
b9f7e36c 7986 {
22eed1e6
APB
7987 tree decl, wfl = TREE_OPERAND (node, 0);
7988 int in_this = CALL_THIS_CONSTRUCTOR_P (node);
7989
c877974e 7990 node = patch_method_invocation (node, NULL_TREE,
89e09b9a 7991 NULL_TREE, 0, &decl);
c877974e
APB
7992 if (node == error_mark_node)
7993 return error_mark_node;
7994
7995 check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
7996 /* If we call this(...), register signature and positions */
7997 if (in_this)
7998 DECL_CONSTRUCTOR_CALLS (current_function_decl) =
7999 tree_cons (wfl, decl,
8000 DECL_CONSTRUCTOR_CALLS (current_function_decl));
de4c7b02 8001 CAN_COMPLETE_NORMALLY (node) = 1;
dc0b3eff 8002 return force_evaluation_order (node);
b9f7e36c 8003 }
e04a16fb
AG
8004
8005 case MODIFY_EXPR:
8006 /* Save potential wfls */
8007 wfl_op1 = TREE_OPERAND (node, 0);
8008 wfl_op2 = TREE_OPERAND (node, 1);
5b09b33e 8009 TREE_OPERAND (node, 0) = java_complete_lhs (wfl_op1);
e04a16fb
AG
8010 if (TREE_OPERAND (node, 0) == error_mark_node)
8011 return error_mark_node;
8012
8013 if (COMPOUND_ASSIGN_P (wfl_op2))
8014 {
2aa11e97 8015 tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0));
e04a16fb
AG
8016
8017 /* Hand stablize the lhs on both places */
e04a16fb
AG
8018 TREE_OPERAND (node, 0) = lvalue;
8019 TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue;
2aa11e97
APB
8020
8021 /* Now complete the RHS. We write it back later on. */
8022 nn = java_complete_tree (TREE_OPERAND (node, 1));
8023
642f15d1
APB
8024 if ((cn = patch_string (nn)))
8025 nn = cn;
8026
2aa11e97
APB
8027 /* The last part of the rewrite for E1 op= E2 is to have
8028 E1 = (T)(E1 op E2), with T being the type of E1. */
642f15d1
APB
8029 nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2),
8030 TREE_TYPE (lvalue), nn));
e04a16fb
AG
8031 }
8032
f8976021
APB
8033 /* If we're about to patch a NEW_ARRAY_INIT, we call a special
8034 function to complete this RHS */
2aa11e97 8035 else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)
fdec99c6 8036 nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
f8976021 8037 TREE_OPERAND (node, 1));
2aa11e97 8038 /* Otherwise we simply complete the RHS */
f8976021
APB
8039 else
8040 nn = java_complete_tree (TREE_OPERAND (node, 1));
8041
e04a16fb 8042 if (nn == error_mark_node)
c0d87ff6 8043 return error_mark_node;
2aa11e97
APB
8044
8045 /* Write back the RHS as we evaluated it. */
e04a16fb 8046 TREE_OPERAND (node, 1) = nn;
b67d701b
PB
8047
8048 /* In case we're handling = with a String as a RHS, we need to
8049 produce a String out of the RHS (it might still be a
8050 STRING_CST or a StringBuffer at this stage */
8051 if ((nn = patch_string (TREE_OPERAND (node, 1))))
8052 TREE_OPERAND (node, 1) = nn;
15fdcfe9
PB
8053 node = patch_assignment (node, wfl_op1, wfl_op2);
8054 CAN_COMPLETE_NORMALLY (node) = 1;
7525cc04
APB
8055
8056 /* Before returning the node, in the context of a static field
8057 assignment in <clinit>, we may want to carray further
8058 optimizations. (VAR_DECL means it's a static field. See
8059 add_field. */
8060 if (DECL_NAME (current_function_decl) == clinit_identifier_node
5b09b33e 8061 && MODIFY_EXPR_FROM_INITIALIZATION_P (node)
7525cc04
APB
8062 && TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL)
8063 node = patch_initialized_static_field (node);
8064
15fdcfe9 8065 return node;
e04a16fb
AG
8066
8067 case MULT_EXPR:
8068 case PLUS_EXPR:
8069 case MINUS_EXPR:
8070 case LSHIFT_EXPR:
8071 case RSHIFT_EXPR:
8072 case URSHIFT_EXPR:
8073 case BIT_AND_EXPR:
8074 case BIT_XOR_EXPR:
8075 case BIT_IOR_EXPR:
8076 case TRUNC_MOD_EXPR:
8077 case RDIV_EXPR:
8078 case TRUTH_ANDIF_EXPR:
8079 case TRUTH_ORIF_EXPR:
8080 case EQ_EXPR:
8081 case NE_EXPR:
8082 case GT_EXPR:
8083 case GE_EXPR:
8084 case LT_EXPR:
8085 case LE_EXPR:
8086 /* Operands 0 and 1 are WFL in certain cases only. patch_binop
8087 knows how to handle those cases. */
8088 wfl_op1 = TREE_OPERAND (node, 0);
8089 wfl_op2 = TREE_OPERAND (node, 1);
b67d701b 8090
15fdcfe9 8091 CAN_COMPLETE_NORMALLY (node) = 1;
b67d701b
PB
8092 /* Don't complete string nodes if dealing with the PLUS operand. */
8093 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
2aa11e97
APB
8094 {
8095 nn = java_complete_tree (wfl_op1);
8096 if (nn == error_mark_node)
8097 return error_mark_node;
8098 if ((cn = patch_string (nn)))
8099 nn = cn;
8100 TREE_OPERAND (node, 0) = nn;
8101 }
b67d701b 8102 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
2aa11e97
APB
8103 {
8104 nn = java_complete_tree (wfl_op2);
8105 if (nn == error_mark_node)
8106 return error_mark_node;
8107 if ((cn = patch_string (nn)))
8108 nn = cn;
8109 TREE_OPERAND (node, 1) = nn;
8110 }
dc0b3eff 8111 return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
e04a16fb 8112
5e942c50
APB
8113 case INSTANCEOF_EXPR:
8114 wfl_op1 = TREE_OPERAND (node, 0);
8115 COMPLETE_CHECK_OP_0 (node);
8116 return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
8117
b67d701b 8118 case UNARY_PLUS_EXPR:
e04a16fb
AG
8119 case NEGATE_EXPR:
8120 case TRUTH_NOT_EXPR:
8121 case BIT_NOT_EXPR:
8122 case PREDECREMENT_EXPR:
8123 case PREINCREMENT_EXPR:
8124 case POSTDECREMENT_EXPR:
8125 case POSTINCREMENT_EXPR:
8126 case CONVERT_EXPR:
8127 /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
8128 how to handle those cases. */
8129 wfl_op1 = TREE_OPERAND (node, 0);
15fdcfe9 8130 CAN_COMPLETE_NORMALLY (node) = 1;
e04a16fb
AG
8131 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
8132 if (TREE_OPERAND (node, 0) == error_mark_node)
8133 return error_mark_node;
4a5f66c3
APB
8134 node = patch_unaryop (node, wfl_op1);
8135 CAN_COMPLETE_NORMALLY (node) = 1;
8136 break;
e04a16fb
AG
8137
8138 case ARRAY_REF:
8139 /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
8140 how to handle those cases. */
8141 wfl_op1 = TREE_OPERAND (node, 0);
8142 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
8143 if (TREE_OPERAND (node, 0) == error_mark_node)
8144 return error_mark_node;
b67d701b
PB
8145 if (!flag_emit_class_files)
8146 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
e04a16fb
AG
8147 /* The same applies to wfl_op2 */
8148 wfl_op2 = TREE_OPERAND (node, 1);
8149 TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
8150 if (TREE_OPERAND (node, 1) == error_mark_node)
8151 return error_mark_node;
22eed1e6
APB
8152 if (!flag_emit_class_files)
8153 TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
939d7216 8154 return patch_array_ref (node);
e04a16fb 8155
63a212ed
PB
8156 case RECORD_TYPE:
8157 return node;;
8158
8159 case COMPONENT_REF:
8160 /* The first step in the re-write of qualified name handling. FIXME.
8161 So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
9bbc7d9f 8162 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
63a212ed
PB
8163 if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
8164 {
8165 tree name = TREE_OPERAND (node, 1);
8166 tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
8167 if (field == NULL_TREE)
8168 {
8169 error ("missing static field `%s'", IDENTIFIER_POINTER (name));
8170 return error_mark_node;
8171 }
8172 if (! FIELD_STATIC (field))
8173 {
8174 error ("not a static field `%s'", IDENTIFIER_POINTER (name));
8175 return error_mark_node;
8176 }
8177 return field;
8178 }
8179 else
8180 fatal ("unimplemented java_complete_tree for COMPONENT_REF");
9bbc7d9f 8181 break;
9bbc7d9f 8182
b67d701b 8183 case THIS_EXPR:
e04a16fb
AG
8184 /* Can't use THIS in a static environment */
8185 if (!current_this)
8186 {
8187 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8188 parse_error_context (wfl_operator, "Keyword `this' used outside "
8189 "allowed context");
8190 TREE_TYPE (node) = error_mark_node;
8191 return error_mark_node;
8192 }
22eed1e6
APB
8193 if (ctxp->explicit_constructor_p)
8194 {
8195 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8196 parse_error_context
8197 (wfl_operator, "Can't reference `this' or `super' before the "
8198 "superclass constructor has been called");
8199 TREE_TYPE (node) = error_mark_node;
8200 return error_mark_node;
8201 }
e04a16fb
AG
8202 return current_this;
8203
e04a16fb 8204 default:
15fdcfe9 8205 CAN_COMPLETE_NORMALLY (node) = 1;
b67d701b
PB
8206 /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
8207 and it's time to turn it into the appropriate String object
8208 */
8209 if ((node = patch_string (node)))
8210 return node;
e04a16fb
AG
8211 fatal ("No case for tree code `%s' - java_complete_tree\n",
8212 tree_code_name [TREE_CODE (node)]);
8213 }
8214 return node;
8215}
8216
8217/* Complete function call's argument. Return a non zero value is an
8218 error was found. */
8219
8220static int
8221complete_function_arguments (node)
8222 tree node;
8223{
8224 int flag = 0;
8225 tree cn;
8226
22eed1e6 8227 ctxp->explicit_constructor_p += (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
e04a16fb
AG
8228 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
8229 {
b67d701b 8230 tree wfl = TREE_VALUE (cn), parm, temp;
e04a16fb
AG
8231 parm = java_complete_tree (wfl);
8232 if (parm == error_mark_node)
8233 {
8234 flag = 1;
8235 continue;
8236 }
b67d701b
PB
8237 /* If have a string literal that we haven't transformed yet or a
8238 crafted string buffer, as a result of use of the the String
8239 `+' operator. Build `parm.toString()' and expand it. */
8240 if ((temp = patch_string (parm)))
b9f7e36c 8241 parm = temp;
5e942c50
APB
8242 /* Inline PRIMTYPE.TYPE read access */
8243 parm = maybe_build_primttype_type_ref (parm, wfl);
b9f7e36c 8244
5e942c50 8245 TREE_VALUE (cn) = parm;
e04a16fb 8246 }
22eed1e6 8247 ctxp->explicit_constructor_p -= (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
e04a16fb
AG
8248 return flag;
8249}
8250
8251/* Sometimes (for loops and variable initialized during their
8252 declaration), we want to wrap a statement around a WFL and turn it
8253 debugable. */
8254
8255static tree
8256build_debugable_stmt (location, stmt)
8257 int location;
8258 tree stmt;
8259{
8260 if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
8261 {
8262 stmt = build_expr_wfl (stmt, input_filename, 0, 0);
8263 EXPR_WFL_LINECOL (stmt) = location;
8264 }
8265 JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
8266 return stmt;
8267}
8268
8269static tree
8270build_expr_block (body, decls)
8271 tree body, decls;
8272{
8273 tree node = make_node (BLOCK);
8274 BLOCK_EXPR_DECLS (node) = decls;
b67d701b 8275 BLOCK_EXPR_BODY (node) = body;
e04a16fb
AG
8276 if (body)
8277 TREE_TYPE (node) = TREE_TYPE (body);
8278 TREE_SIDE_EFFECTS (node) = 1;
8279 return node;
8280}
8281
b67d701b
PB
8282/* Create a new function block and link it approriately to current
8283 function block chain */
e04a16fb
AG
8284
8285static tree
8286enter_block ()
8287{
b67d701b
PB
8288 return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
8289}
8290
8291/* Link block B supercontext to the previous block. The current
8292 function DECL is used as supercontext when enter_a_block is called
8293 for the first time for a given function. The current function body
8294 (DECL_FUNCTION_BODY) is set to be block B. */
8295
8296static tree
8297enter_a_block (b)
8298 tree b;
8299{
e04a16fb
AG
8300 tree fndecl = current_function_decl;
8301
f099f336
APB
8302 if (!fndecl) {
8303 BLOCK_SUPERCONTEXT (b) = current_static_block;
8304 current_static_block = b;
8305 }
8306
8307 else if (!DECL_FUNCTION_BODY (fndecl))
e04a16fb
AG
8308 {
8309 BLOCK_SUPERCONTEXT (b) = fndecl;
8310 DECL_FUNCTION_BODY (fndecl) = b;
8311 }
8312 else
8313 {
8314 BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
8315 DECL_FUNCTION_BODY (fndecl) = b;
8316 }
8317 return b;
8318}
8319
8320/* Exit a block by changing the current function body
8321 (DECL_FUNCTION_BODY) to the current block super context, only if
8322 the block being exited isn't the method's top level one. */
8323
8324static tree
8325exit_block ()
8326{
f099f336
APB
8327 tree b;
8328 if (current_function_decl)
8329 {
8330 b = DECL_FUNCTION_BODY (current_function_decl);
8331 if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
8332 DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
8333 }
8334 else
8335 {
8336 b = current_static_block;
e04a16fb 8337
f099f336
APB
8338 if (BLOCK_SUPERCONTEXT (b))
8339 current_static_block = BLOCK_SUPERCONTEXT (b);
8340 }
e04a16fb
AG
8341 return b;
8342}
8343
8344/* Lookup for NAME in the nested function's blocks, all the way up to
8345 the current toplevel one. It complies with Java's local variable
8346 scoping rules. */
8347
8348static tree
8349lookup_name_in_blocks (name)
8350 tree name;
8351{
f099f336 8352 tree b = GET_CURRENT_BLOCK (current_function_decl);
e04a16fb
AG
8353
8354 while (b != current_function_decl)
8355 {
8356 tree current;
8357
8358 /* Paranoid sanity check. To be removed */
8359 if (TREE_CODE (b) != BLOCK)
8360 fatal ("non block expr function body - lookup_name_in_blocks");
8361
8362 for (current = BLOCK_EXPR_DECLS (b); current;
8363 current = TREE_CHAIN (current))
8364 if (DECL_NAME (current) == name)
8365 return current;
8366 b = BLOCK_SUPERCONTEXT (b);
8367 }
8368 return NULL_TREE;
8369}
8370
8371static void
8372maybe_absorb_scoping_blocks ()
8373{
f099f336 8374 while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
e04a16fb
AG
8375 {
8376 tree b = exit_block ();
8377 java_method_add_stmt (current_function_decl, b);
8378 SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
8379 }
8380}
8381
8382\f
8383/* This section of the source is reserved to build_* functions that
8384 are building incomplete tree nodes and the patch_* functions that
8385 are completing them. */
8386
9bbc7d9f 8387/* Build a super() constructor invocation. Returns empty_stmt_node if
22eed1e6
APB
8388 we're currently dealing with the class java.lang.Object. */
8389
8390static tree
8391build_super_invocation ()
8392{
8393 if (current_class == object_type_node)
9bbc7d9f 8394 return empty_stmt_node;
22eed1e6
APB
8395 else
8396 {
9ee9b555 8397 tree super_wfl = build_wfl_node (super_identifier_node);
22eed1e6
APB
8398 return build_method_invocation (super_wfl, NULL_TREE);
8399 }
8400}
8401
8402/* Build a SUPER/THIS qualified method invocation. */
8403
8404static tree
8405build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
8406 int use_this;
8407 tree name, args;
8408 int lloc, rloc;
8409
8410{
8411 tree invok;
8412 tree wfl =
9ee9b555 8413 build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
22eed1e6
APB
8414 EXPR_WFL_LINECOL (wfl) = lloc;
8415 invok = build_method_invocation (name, args);
8416 return make_qualified_primary (wfl, invok, rloc);
8417}
8418
b67d701b 8419/* Build an incomplete CALL_EXPR node. */
e04a16fb
AG
8420
8421static tree
8422build_method_invocation (name, args)
8423 tree name;
8424 tree args;
8425{
8426 tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
8427 TREE_SIDE_EFFECTS (call) = 1;
b67d701b
PB
8428 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
8429 return call;
8430}
8431
8432/* Build an incomplete new xxx(...) node. */
8433
8434static tree
8435build_new_invocation (name, args)
8436 tree name, args;
8437{
8438 tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
8439 TREE_SIDE_EFFECTS (call) = 1;
e04a16fb
AG
8440 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
8441 return call;
8442}
8443
8444/* Build an incomplete assignment expression. */
8445
8446static tree
8447build_assignment (op, op_location, lhs, rhs)
8448 int op, op_location;
8449 tree lhs, rhs;
8450{
8451 tree assignment;
8452 /* Build the corresponding binop if we deal with a Compound
8453 Assignment operator. Mark the binop sub-tree as part of a
8454 Compound Assignment expression */
8455 if (op != ASSIGN_TK)
8456 {
8457 rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
8458 COMPOUND_ASSIGN_P (rhs) = 1;
8459 }
8460 assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
8461 TREE_SIDE_EFFECTS (assignment) = 1;
8462 EXPR_WFL_LINECOL (assignment) = op_location;
8463 return assignment;
8464}
8465
8466/* Print an INTEGER_CST node in a static buffer, and return the buffer. */
8467
15fdcfe9 8468char *
e04a16fb
AG
8469print_int_node (node)
8470 tree node;
8471{
8472 static char buffer [80];
8473 if (TREE_CONSTANT_OVERFLOW (node))
8474 sprintf (buffer, "<overflow>");
8475
8476 if (TREE_INT_CST_HIGH (node) == 0)
8477 sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
8478 TREE_INT_CST_LOW (node));
8479 else if (TREE_INT_CST_HIGH (node) == -1
8480 && TREE_INT_CST_LOW (node) != 0)
8481 {
8482 buffer [0] = '-';
8483 sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
8484 -TREE_INT_CST_LOW (node));
8485 }
8486 else
8487 sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
8488 TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
8489
8490 return buffer;
8491}
8492
5e942c50
APB
8493/* Return 1 if you an assignment of a FINAL is attempted */
8494
8495static int
8496check_final_assignment (lvalue, wfl)
8497 tree lvalue, wfl;
8498{
34f4db93 8499 if (JDECL_P (lvalue) && FIELD_FINAL (lvalue) &&
7525cc04 8500 DECL_NAME (current_function_decl) != clinit_identifier_node)
5e942c50
APB
8501 {
8502 parse_error_context
8503 (wfl, "Can't assign a value to the final variable `%s'",
8504 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
8505 return 1;
8506 }
8507 return 0;
8508}
8509
8510/* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
8511 read. This is needed to avoid circularities in the implementation
8512 of these fields in libjava. */
8513
8514static tree
8515maybe_build_primttype_type_ref (rhs, wfl)
8516 tree rhs, wfl;
8517{
8518 tree to_return = NULL_TREE;
8519 tree rhs_type = TREE_TYPE (rhs);
8520 if (TREE_CODE (rhs) == COMPOUND_EXPR)
8521 {
8522 tree n = TREE_OPERAND (rhs, 1);
8523 if (TREE_CODE (n) == VAR_DECL
8524 && DECL_NAME (n) == TYPE_identifier_node
8525 && rhs_type == class_ptr_type)
8526 {
8527 char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
8528 if (!strncmp (self_name, "java.lang.", 10))
8529 to_return = build_primtype_type_ref (self_name);
8530 }
8531 }
8532 return (to_return ? to_return : rhs );
8533}
8534
e04a16fb
AG
8535/* 15.25 Assignment operators. */
8536
8537static tree
8538patch_assignment (node, wfl_op1, wfl_op2)
8539 tree node;
8540 tree wfl_op1;
8541 tree wfl_op2;
8542{
0a2138e2 8543 tree rhs = TREE_OPERAND (node, 1);
5e942c50 8544 tree lvalue = TREE_OPERAND (node, 0), llvalue;
e04a16fb 8545 tree lhs_type, rhs_type, new_rhs = NULL_TREE;
e04a16fb
AG
8546 int error_found = 0;
8547 int lvalue_from_array = 0;
8548
8549 /* Can't assign to a final. */
5e942c50
APB
8550 if (check_final_assignment (lvalue, wfl_op1))
8551 error_found = 1;
e04a16fb
AG
8552
8553 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8554
8555 /* Lhs can be a named variable */
34f4db93 8556 if (JDECL_P (lvalue))
e04a16fb 8557 {
e04a16fb
AG
8558 lhs_type = TREE_TYPE (lvalue);
8559 }
8560 /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
8561 comment on reason why */
8562 else if (TREE_CODE (wfl_op1) == ARRAY_REF)
8563 {
8564 lhs_type = TREE_TYPE (lvalue);
8565 lvalue_from_array = 1;
8566 }
8567 /* Or a field access */
8568 else if (TREE_CODE (lvalue) == COMPONENT_REF)
8569 lhs_type = TREE_TYPE (lvalue);
8570 /* Or a function return slot */
8571 else if (TREE_CODE (lvalue) == RESULT_DECL)
8572 lhs_type = TREE_TYPE (lvalue);
5e942c50
APB
8573 /* Otherwise, we might want to try to write into an optimized static
8574 final, this is an of a different nature, reported further on. */
8575 else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
1504b2b4 8576 && resolve_expression_name (wfl_op1, &llvalue))
5e942c50 8577 {
1504b2b4
APB
8578 if (check_final_assignment (llvalue, wfl_op1))
8579 {
8580 /* What we should do instead is resetting the all the flags
8581 previously set, exchange lvalue for llvalue and continue. */
8582 error_found = 1;
8583 return error_mark_node;
8584 }
8585 else
8586 lhs_type = TREE_TYPE (lvalue);
5e942c50
APB
8587 }
8588 else
e04a16fb
AG
8589 {
8590 parse_error_context (wfl_op1, "Invalid left hand side of assignment");
8591 error_found = 1;
8592 }
8593
8594 rhs_type = TREE_TYPE (rhs);
b67d701b 8595 /* 5.1 Try the assignment conversion for builtin type. */
0a2138e2 8596 new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
e04a16fb 8597
b67d701b 8598 /* 5.2 If it failed, try a reference conversion */
0a2138e2 8599 if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
b67d701b 8600 lhs_type = promote_type (rhs_type);
e04a16fb
AG
8601
8602 /* 15.25.2 If we have a compound assignment, convert RHS into the
8603 type of the LHS */
8604 else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
8605 new_rhs = convert (lhs_type, rhs);
8606
8607 /* Explicit cast required. This is an error */
8608 if (!new_rhs)
8609 {
0a2138e2
APB
8610 char *t1 = strdup (lang_printable_name (TREE_TYPE (rhs), 0));
8611 char *t2 = strdup (lang_printable_name (lhs_type, 0));
e04a16fb
AG
8612 tree wfl;
8613 char operation [32]; /* Max size known */
8614
8615 /* If the assignment is part of a declaration, we use the WFL of
8616 the declared variable to point out the error and call it a
8617 declaration problem. If the assignment is a genuine =
8618 operator, we call is a operator `=' problem, otherwise we
8619 call it an assignment problem. In both of these last cases,
8620 we use the WFL of the operator to indicate the error. */
8621
8622 if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
8623 {
8624 wfl = wfl_op1;
8625 strcpy (operation, "declaration");
8626 }
8627 else
8628 {
8629 wfl = wfl_operator;
8630 if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
8631 strcpy (operation, "assignment");
8632 else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
8633 strcpy (operation, "`return'");
8634 else
8635 strcpy (operation, "`='");
8636 }
8637
8638 parse_error_context
b67d701b 8639 (wfl, (!valid_cast_to_p (rhs_type, lhs_type) ?
e04a16fb
AG
8640 "Incompatible type for %s. Can't convert `%s' to `%s'" :
8641 "Incompatible type for %s. Explicit cast "
8642 "needed to convert `%s' to `%s'"), operation, t1, t2);
8643 free (t1); free (t2);
8644 error_found = 1;
8645 }
8646
c877974e
APB
8647 /* Inline read access to java.lang.PRIMTYPE.TYPE */
8648 if (new_rhs)
8649 new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
5e942c50 8650
e04a16fb
AG
8651 if (error_found)
8652 return error_mark_node;
8653
8654 /* If we built a compound expression as the result of a reference
8655 assignment into an array element, return it here. */
8656 if (TREE_CODE (node) == COMPOUND_EXPR)
8657 return node;
22eed1e6 8658
e04a16fb
AG
8659 TREE_OPERAND (node, 0) = lvalue;
8660 TREE_OPERAND (node, 1) = new_rhs;
8661 TREE_TYPE (node) = lhs_type;
8662 return node;
8663}
8664
7525cc04
APB
8665/* Optimize static (final) field initialized upon declaration.
8666 - If the field is static final and is assigned to a primitive
8667 constant type, then set its DECL_INITIAL to the value.
8668 - More to come. */
8669
8670static tree
8671patch_initialized_static_field (node)
8672 tree node;
8673{
8674 tree field = TREE_OPERAND (node, 0);
8675 tree value = TREE_OPERAND (node, 1);
8676
5b09b33e 8677 if (DECL_INITIAL (field) != NULL_TREE)
7525cc04 8678 {
5b09b33e
PB
8679 tree type = TREE_TYPE (value);
8680 if (FIELD_FINAL (field) && TREE_CONSTANT (value)
8681 && (JPRIMITIVE_TYPE_P (type)
8682 || (flag_emit_class_files
8683 && TREE_CODE (type) == POINTER_TYPE
8684 && TREE_TYPE (type) == string_type_node)))
8685 {
8686 DECL_INITIAL (field) = value;
8687 return empty_stmt_node;
8688 }
8689 DECL_INITIAL (field) = NULL_TREE;
7525cc04
APB
8690 }
8691 return node;
8692}
8693
b67d701b
PB
8694/* Check that type SOURCE can be cast into type DEST. If the cast
8695 can't occur at all, return 0 otherwise 1. This function is used to
8696 produce accurate error messages on the reasons why an assignment
8697 failed. */
e04a16fb 8698
b67d701b
PB
8699static tree
8700try_reference_assignconv (lhs_type, rhs)
8701 tree lhs_type, rhs;
e04a16fb 8702{
b67d701b
PB
8703 tree new_rhs = NULL_TREE;
8704 tree rhs_type = TREE_TYPE (rhs);
e04a16fb 8705
b67d701b
PB
8706 if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
8707 {
8708 /* `null' may be assigned to any reference type */
8709 if (rhs == null_pointer_node)
8710 new_rhs = null_pointer_node;
8711 /* Try the reference assignment conversion */
8712 else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
8713 new_rhs = rhs;
8714 /* This is a magic assignment that we process differently */
8715 else if (rhs == soft_exceptioninfo_call_node)
8716 new_rhs = rhs;
8717 }
8718 return new_rhs;
8719}
8720
8721/* Check that RHS can be converted into LHS_TYPE by the assignment
8722 conversion (5.2), for the cases of RHS being a builtin type. Return
8723 NULL_TREE if the conversion fails or if because RHS isn't of a
8724 builtin type. Return a converted RHS if the conversion is possible. */
8725
8726static tree
8727try_builtin_assignconv (wfl_op1, lhs_type, rhs)
8728 tree wfl_op1, lhs_type, rhs;
8729{
8730 tree new_rhs = NULL_TREE;
8731 tree rhs_type = TREE_TYPE (rhs);
8732
5e942c50
APB
8733 /* Zero accepted everywhere */
8734 if (TREE_CODE (rhs) == INTEGER_CST
8735 && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
8736 && JPRIMITIVE_TYPE_P (rhs_type))
8737 new_rhs = convert (lhs_type, rhs);
8738
b67d701b
PB
8739 /* 5.1.1 Try Identity Conversion,
8740 5.1.2 Try Widening Primitive Conversion */
5e942c50 8741 else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
b67d701b
PB
8742 new_rhs = convert (lhs_type, rhs);
8743
8744 /* Try a narrowing primitive conversion (5.1.3):
8745 - expression is a constant expression of type int AND
8746 - variable is byte, short or char AND
8747 - The value of the expression is representable in the type of the
8748 variable */
8749 else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
8750 && (lhs_type == byte_type_node || lhs_type == char_type_node
8751 || lhs_type == short_type_node))
8752 {
8753 if (int_fits_type_p (rhs, lhs_type))
8754 new_rhs = convert (lhs_type, rhs);
8755 else if (wfl_op1) /* Might be called with a NULL */
8756 parse_warning_context
8757 (wfl_op1, "Constant expression `%s' to wide for narrowing "
8758 "primitive conversion to `%s'",
0a2138e2 8759 print_int_node (rhs), lang_printable_name (lhs_type, 0));
b67d701b
PB
8760 /* Reported a warning that will turn into an error further
8761 down, so we don't return */
8762 }
8763
8764 return new_rhs;
8765}
8766
8767/* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
8768 conversion (5.1.1) or widening primitve conversion (5.1.2). Return
8769 0 is the conversion test fails. This implements parts the method
8770 invocation convertion (5.3). */
8771
8772static int
8773valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
8774 tree lhs_type, rhs_type;
8775{
acd663ee 8776 /* 5.1.1: This is the identity conversion part. */
5e942c50
APB
8777 if (lhs_type == rhs_type)
8778 return 1;
8779
acd663ee
APB
8780 /* Reject non primitive types */
8781 if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
b67d701b
PB
8782 return 0;
8783
acd663ee
APB
8784 /* 5.1.2: widening primitive conversion. byte, even if it's smaller
8785 than a char can't be converted into a char. Short can't too, but
8786 the < test below takes care of that */
b67d701b
PB
8787 if (lhs_type == char_type_node && rhs_type == byte_type_node)
8788 return 0;
8789
5e942c50
APB
8790 /* Accept all promoted type here. Note, we can't use <= in the test
8791 below, because we still need to bounce out assignments of short
8792 to char and the likes */
8793 if (lhs_type == int_type_node
8794 && (rhs_type == promoted_byte_type_node
8795 || rhs_type == promoted_short_type_node
8796 || rhs_type == promoted_char_type_node
8797 || rhs_type == promoted_boolean_type_node))
8798 return 1;
8799
acd663ee
APB
8800 /* From here, an integral is widened if its precision is smaller
8801 than the precision of the LHS or if the LHS is a floating point
8802 type, or the RHS is a float and the RHS a double. */
8803 if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type)
8804 && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
8805 || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
8806 || (rhs_type == float_type_node && lhs_type == double_type_node))
b67d701b
PB
8807 return 1;
8808
8809 return 0;
e04a16fb
AG
8810}
8811
8812/* Check that something of SOURCE type can be assigned or cast to
8813 something of DEST type at runtime. Return 1 if the operation is
8814 valid, 0 otherwise. If CAST is set to 1, we're treating the case
8815 were SOURCE is cast into DEST, which borrows a lot of the
8816 assignment check. */
8817
8818static int
8819valid_ref_assignconv_cast_p (source, dest, cast)
8820 tree source;
8821 tree dest;
8822 int cast;
8823{
09ed0f70
APB
8824 /* SOURCE or DEST might be null if not from a declared entity. */
8825 if (!source || !dest)
8826 return 0;
5e942c50
APB
8827 if (JNULLP_TYPE_P (source))
8828 return 1;
e04a16fb
AG
8829 if (TREE_CODE (source) == POINTER_TYPE)
8830 source = TREE_TYPE (source);
8831 if (TREE_CODE (dest) == POINTER_TYPE)
8832 dest = TREE_TYPE (dest);
8833 /* Case where SOURCE is a class type */
8834 if (TYPE_CLASS_P (source))
8835 {
8836 if (TYPE_CLASS_P (dest))
8837 return source == dest || inherits_from_p (source, dest)
0a2138e2 8838 || (cast && inherits_from_p (dest, source));
e04a16fb
AG
8839 if (TYPE_INTERFACE_P (dest))
8840 {
8841 /* If doing a cast and SOURCE is final, the operation is
8842 always correct a compile time (because even if SOURCE
8843 does not implement DEST, a subclass of SOURCE might). */
8844 if (cast && !CLASS_FINAL (TYPE_NAME (source)))
8845 return 1;
8846 /* Otherwise, SOURCE must implement DEST */
8847 return interface_of_p (dest, source);
8848 }
8849 /* DEST is an array, cast permited if SOURCE is of Object type */
8850 return (cast && source == object_type_node ? 1 : 0);
8851 }
8852 if (TYPE_INTERFACE_P (source))
8853 {
8854 if (TYPE_CLASS_P (dest))
8855 {
8856 /* If not casting, DEST must be the Object type */
8857 if (!cast)
8858 return dest == object_type_node;
8859 /* We're doing a cast. The cast is always valid is class
8860 DEST is not final, otherwise, DEST must implement SOURCE */
b67d701b 8861 else if (!CLASS_FINAL (TYPE_NAME (dest)))
e04a16fb
AG
8862 return 1;
8863 else
8864 return interface_of_p (source, dest);
8865 }
8866 if (TYPE_INTERFACE_P (dest))
8867 {
8868 /* If doing a cast, then if SOURCE and DEST contain method
8869 with the same signature but different return type, then
8870 this is a (compile time) error */
8871 if (cast)
8872 {
8873 tree method_source, method_dest;
8874 tree source_type;
0a2138e2 8875 tree source_sig;
e04a16fb
AG
8876 tree source_name;
8877 for (method_source = TYPE_METHODS (source); method_source;
8878 method_source = TREE_CHAIN (method_source))
8879 {
8880 source_sig =
8881 build_java_argument_signature (TREE_TYPE (method_source));
8882 source_type = TREE_TYPE (TREE_TYPE (method_source));
8883 source_name = DECL_NAME (method_source);
8884 for (method_dest = TYPE_METHODS (dest);
8885 method_dest; method_dest = TREE_CHAIN (method_dest))
8886 if (source_sig ==
8887 build_java_argument_signature (TREE_TYPE (method_dest))
8888 && source_name == DECL_NAME (method_dest)
8889 && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
8890 return 0;
8891 }
8892 return 1;
8893 }
8894 else
8895 return source == dest || interface_of_p (dest, source);
8896 }
8897 else /* Array */
8898 return 0;
8899 }
8900 if (TYPE_ARRAY_P (source))
8901 {
8902 if (TYPE_CLASS_P (dest))
8903 return dest == object_type_node;
09ed0f70
APB
8904 /* Can't cast an array to an interface unless the interface is
8905 java.lang.Cloneable */
e04a16fb 8906 if (TYPE_INTERFACE_P (dest))
09ed0f70 8907 return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
e04a16fb
AG
8908 else /* Arrays */
8909 {
8910 tree source_element_type = TYPE_ARRAY_ELEMENT (source);
8911 tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
8912
b9f7e36c
APB
8913 /* In case of severe errors, they turn out null */
8914 if (!dest_element_type || !source_element_type)
8915 return 0;
e04a16fb
AG
8916 if (source_element_type == dest_element_type)
8917 return 1;
8918 return valid_ref_assignconv_cast_p (source_element_type,
8919 dest_element_type, cast);
8920 }
8921 return 0;
8922 }
8923 return 0;
8924}
8925
b67d701b
PB
8926static int
8927valid_cast_to_p (source, dest)
8928 tree source;
8929 tree dest;
8930{
8931 if (TREE_CODE (source) == POINTER_TYPE)
8932 source = TREE_TYPE (source);
8933 if (TREE_CODE (dest) == POINTER_TYPE)
8934 dest = TREE_TYPE (dest);
8935
8936 if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
8937 return valid_ref_assignconv_cast_p (source, dest, 1);
8938
8939 else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
8940 return 1;
8941
8942 return 0;
8943}
8944
8945/* Method invocation conversion test. Return 1 if type SOURCE can be
8946 converted to type DEST through the methond invocation conversion
8947 process (5.3) */
8948
15fdcfe9
PB
8949static tree
8950do_unary_numeric_promotion (arg)
8951 tree arg;
8952{
8953 tree type = TREE_TYPE (arg);
8954 if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
8955 : TREE_CODE (type) == CHAR_TYPE)
8956 arg = convert (int_type_node, arg);
8957 return arg;
8958}
8959
acd663ee
APB
8960/* Return a non zero value if SOURCE can be converted into DEST using
8961 the method invocation conversion rule (5.3). */
b67d701b
PB
8962static int
8963valid_method_invocation_conversion_p (dest, source)
8964 tree dest, source;
8965{
e3884b71 8966 return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
acd663ee
APB
8967 && valid_builtin_assignconv_identity_widening_p (dest, source))
8968 || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
8969 && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
8970 && valid_ref_assignconv_cast_p (source, dest, 0)));
b67d701b
PB
8971}
8972
e04a16fb
AG
8973/* Build an incomplete binop expression. */
8974
8975static tree
8976build_binop (op, op_location, op1, op2)
8977 enum tree_code op;
8978 int op_location;
8979 tree op1, op2;
8980{
5e942c50 8981 tree binop = build (op, NULL_TREE, op1, op2);
e04a16fb
AG
8982 TREE_SIDE_EFFECTS (binop) = 1;
8983 /* Store the location of the operator, for better error report. The
8984 string of the operator will be rebuild based on the OP value. */
8985 EXPR_WFL_LINECOL (binop) = op_location;
8986 return binop;
8987}
8988
8989/* Build the string of the operator retained by NODE. If NODE is part
8990 of a compound expression, add an '=' at the end of the string. This
8991 function is called when an error needs to be reported on an
8992 operator. The string is returned as a pointer to a static character
8993 buffer. */
8994
8995static char *
8996operator_string (node)
8997 tree node;
8998{
8999#define BUILD_OPERATOR_STRING(S) \
9000 { \
9001 sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
9002 return buffer; \
9003 }
9004
9005 static char buffer [10];
9006 switch (TREE_CODE (node))
9007 {
9008 case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
9009 case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
9010 case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
9011 case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
9012 case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
9013 case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
9014 case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
9015 case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
9016 case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
9017 case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
9018 case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
9019 case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
9020 case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
9021 case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
9022 case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
9023 case GT_EXPR: BUILD_OPERATOR_STRING (">");
9024 case GE_EXPR: BUILD_OPERATOR_STRING (">=");
9025 case LT_EXPR: BUILD_OPERATOR_STRING ("<");
9026 case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
b67d701b 9027 case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
e04a16fb
AG
9028 case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
9029 case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
9030 case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
9031 case PREINCREMENT_EXPR: /* Fall through */
9032 case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
9033 case PREDECREMENT_EXPR: /* Fall through */
9034 case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
9035 default:
9036 fatal ("unregistered operator %s - operator_string",
9037 tree_code_name [TREE_CODE (node)]);
9038 }
9039 return NULL;
9040#undef BUILD_OPERATOR_STRING
9041}
9042
9043/* Binary operators (15.16 up to 15.18). We return error_mark_node on
9044 errors but we modify NODE so that it contains the type computed
9045 according to the expression, when it's fixed. Otherwise, we write
9046 error_mark_node as the type. It allows us to further the analysis
9047 of remaining nodes and detects more errors in certain cases. */
9048
9049static tree
9050patch_binop (node, wfl_op1, wfl_op2)
9051 tree node;
9052 tree wfl_op1;
9053 tree wfl_op2;
9054{
9055 tree op1 = TREE_OPERAND (node, 0);
9056 tree op2 = TREE_OPERAND (node, 1);
9057 tree op1_type = TREE_TYPE (op1);
9058 tree op2_type = TREE_TYPE (op2);
9059 tree prom_type;
9060 int code = TREE_CODE (node);
b67d701b 9061
e04a16fb
AG
9062 /* If 1, tell the routine that we have to return error_mark_node
9063 after checking for the initialization of the RHS */
9064 int error_found = 0;
9065
e04a16fb
AG
9066 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9067
e04a16fb
AG
9068 switch (code)
9069 {
9070 /* 15.16 Multiplicative operators */
9071 case MULT_EXPR: /* 15.16.1 Multiplication Operator * */
9072 case RDIV_EXPR: /* 15.16.2 Division Operator / */
9073 case TRUNC_MOD_EXPR: /* 15.16.3 Remainder operator % */
9074 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
9075 {
9076 if (!JPRIMITIVE_TYPE_P (op1_type))
9077 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9078 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
9079 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9080 TREE_TYPE (node) = error_mark_node;
9081 error_found = 1;
9082 break;
9083 }
9084 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9085 /* Change the division operator if necessary */
9086 if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
9087 TREE_SET_CODE (node, TRUNC_DIV_EXPR);
0b4d333e
APB
9088
9089 /* This one is more complicated. FLOATs are processed by a
9090 function call to soft_fmod. Duplicate the value of the
9091 COMPOUND_ASSIGN_P flag. */
e04a16fb 9092 if (code == TRUNC_MOD_EXPR)
0b4d333e
APB
9093 {
9094 tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
9095 COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
dc0b3eff
PB
9096 TREE_SIDE_EFFECTS (mod)
9097 = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
0b4d333e
APB
9098 return mod;
9099 }
e04a16fb
AG
9100 break;
9101
9102 /* 15.17 Additive Operators */
9103 case PLUS_EXPR: /* 15.17.1 String Concatenation Operator + */
b67d701b
PB
9104
9105 /* Operation is valid if either one argument is a string
9106 constant, a String object or a StringBuffer crafted for the
9107 purpose of the a previous usage of the String concatenation
9108 operator */
9109
9110 if (TREE_CODE (op1) == STRING_CST
9111 || TREE_CODE (op2) == STRING_CST
9112 || JSTRING_TYPE_P (op1_type)
9113 || JSTRING_TYPE_P (op2_type)
9114 || IS_CRAFTED_STRING_BUFFER_P (op1)
9115 || IS_CRAFTED_STRING_BUFFER_P (op2))
9116 return build_string_concatenation (op1, op2);
9117
e04a16fb
AG
9118 case MINUS_EXPR: /* 15.17.2 Additive Operators (+ and -) for
9119 Numeric Types */
9120 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
9121 {
9122 if (!JPRIMITIVE_TYPE_P (op1_type))
9123 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9124 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
9125 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9126 TREE_TYPE (node) = error_mark_node;
9127 error_found = 1;
9128 break;
9129 }
9130 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9131 break;
9132
9133 /* 15.18 Shift Operators */
9134 case LSHIFT_EXPR:
9135 case RSHIFT_EXPR:
9136 case URSHIFT_EXPR:
9137 if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
9138 {
9139 if (!JINTEGRAL_TYPE_P (op1_type))
9140 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
9141 else
9142 parse_error_context
9143 (wfl_operator, (JPRIMITIVE_TYPE_P (op2_type) ?
9144 "Incompatible type for `%s'. Explicit cast needed to convert "
9145 "shift distance from `%s' to integral" :
9146 "Incompatible type for `%s'. Can't convert shift distance from "
9147 "`%s' to integral"),
0a2138e2 9148 operator_string (node), lang_printable_name (op2_type, 0));
e04a16fb
AG
9149 TREE_TYPE (node) = error_mark_node;
9150 error_found = 1;
9151 break;
9152 }
9153
9154 /* Unary numeric promotion (5.6.1) is performed on each operand
9155 separatly */
15fdcfe9
PB
9156 op1 = do_unary_numeric_promotion (op1);
9157 op2 = do_unary_numeric_promotion (op2);
e04a16fb
AG
9158
9159 /* The type of the shift expression is the type of the promoted
9160 type of the left-hand operand */
9161 prom_type = TREE_TYPE (op1);
9162
9163 /* Shift int only up to 0x1f and long up to 0x3f */
9164 if (prom_type == int_type_node)
9165 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
9166 build_int_2 (0x1f, 0)));
9167 else
9168 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
9169 build_int_2 (0x3f, 0)));
9170
9171 /* The >>> operator is a >> operating on unsigned quantities */
15fdcfe9 9172 if (code == URSHIFT_EXPR && ! flag_emit_class_files)
e04a16fb 9173 {
0b4d333e 9174 tree to_return;
73333a87
AH
9175 tree utype = unsigned_type (prom_type);
9176 op1 = convert (utype, op1);
e04a16fb 9177 TREE_SET_CODE (node, RSHIFT_EXPR);
73333a87
AH
9178 TREE_OPERAND (node, 0) = op1;
9179 TREE_OPERAND (node, 1) = op2;
9180 TREE_TYPE (node) = utype;
0b4d333e
APB
9181 to_return = convert (prom_type, node);
9182 /* Copy the original value of the COMPOUND_ASSIGN_P flag */
9183 COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
dc0b3eff
PB
9184 TREE_SIDE_EFFECTS (to_return)
9185 = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
0b4d333e 9186 return to_return;
e04a16fb
AG
9187 }
9188 break;
5e942c50
APB
9189
9190 /* 15.19.1 Type Comparison Operator instaceof */
9191 case INSTANCEOF_EXPR:
9192
9193 TREE_TYPE (node) = boolean_type_node;
9194
9195 if (!(op2_type = resolve_type_during_patch (op2)))
9196 return error_mark_node;
9197
9198 /* The first operand must be a reference type or the null type */
9199 if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
9200 error_found = 1; /* Error reported further below */
9201
9202 /* The second operand must be a reference type */
9203 if (!JREFERENCE_TYPE_P (op2_type))
9204 {
9205 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
9206 parse_error_context
9207 (wfl_operator, "Invalid argument `%s' for `instanceof'",
9208 lang_printable_name (op2_type, 0));
9209 error_found = 1;
9210 }
9211
9212 if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
9213 {
9214 /* If the first operand is null, the result is always false */
9215 if (op1 == null_pointer_node)
9216 return boolean_false_node;
15fdcfe9
PB
9217 else if (flag_emit_class_files)
9218 {
9219 TREE_OPERAND (node, 1) = op2_type;
dc0b3eff 9220 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
15fdcfe9
PB
9221 return node;
9222 }
5e942c50
APB
9223 /* Otherwise we have to invoke instance of to figure it out */
9224 else
9225 {
9226 tree call =
9227 build (CALL_EXPR, boolean_type_node,
9228 build_address_of (soft_instanceof_node),
9229 tree_cons
9230 (NULL_TREE, op1,
9231 build_tree_list (NULL_TREE,
9232 build_class_ref (op2_type))),
9233 NULL_TREE);
dc0b3eff 9234 TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
5e942c50
APB
9235 return call;
9236 }
9237 }
9238 /* There is no way the expression operand can be an instance of
9239 the type operand. This is a compile time error. */
9240 else
9241 {
9242 char *t1 = strdup (lang_printable_name (op1_type, 0));
9243 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
9244 parse_error_context
9245 (wfl_operator, "Impossible for `%s' to be instance of `%s'",
9246 t1, lang_printable_name (op2_type, 0));
9247 free (t1);
9248 error_found = 1;
9249 }
e04a16fb 9250
5e942c50 9251 break;
e04a16fb
AG
9252
9253 /* 15.21 Bitwise and Logical Operators */
9254 case BIT_AND_EXPR:
9255 case BIT_XOR_EXPR:
9256 case BIT_IOR_EXPR:
9257 if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
9258 /* Binary numeric promotion is performed on both operand and the
9259 expression retain that type */
9260 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9261
9262 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE
9263 && TREE_CODE (op1_type) == BOOLEAN_TYPE)
9264 /* The type of the bitwise operator expression is BOOLEAN */
9265 prom_type = boolean_type_node;
9266 else
9267 {
9268 if (!JINTEGRAL_TYPE_P (op1_type))
9269 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
9270 if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
9271 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
9272 TREE_TYPE (node) = error_mark_node;
9273 error_found = 1;
9274 /* Insert a break here if adding thing before the switch's
9275 break for this case */
9276 }
9277 break;
9278
9279 /* 15.22 Conditional-And Operator */
9280 case TRUTH_ANDIF_EXPR:
9281 /* 15.23 Conditional-Or Operator */
9282 case TRUTH_ORIF_EXPR:
9283 /* Operands must be of BOOLEAN type */
9284 if (TREE_CODE (op1_type) != BOOLEAN_TYPE ||
9285 TREE_CODE (op2_type) != BOOLEAN_TYPE)
9286 {
9287 if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
9288 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
9289 if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
9290 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
9291 TREE_TYPE (node) = boolean_type_node;
9292 error_found = 1;
9293 break;
9294 }
9295 /* The type of the conditional operators is BOOLEAN */
9296 prom_type = boolean_type_node;
9297 break;
9298
9299 /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
9300 case LT_EXPR:
9301 case GT_EXPR:
9302 case LE_EXPR:
9303 case GE_EXPR:
9304 /* The type of each of the operands must be a primitive numeric
9305 type */
9306 if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
9307 {
9308 if (!JNUMERIC_TYPE_P (op1_type))
9309 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9310 if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
9311 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9312 TREE_TYPE (node) = boolean_type_node;
9313 error_found = 1;
9314 break;
9315 }
9316 /* Binary numeric promotion is performed on the operands */
9317 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9318 /* The type of the relation expression is always BOOLEAN */
9319 prom_type = boolean_type_node;
9320 break;
9321
9322 /* 15.20 Equality Operator */
9323 case EQ_EXPR:
9324 case NE_EXPR:
9325 /* 15.20.1 Numerical Equality Operators == and != */
9326 /* Binary numeric promotion is performed on the operands */
5e942c50 9327 if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
e04a16fb
AG
9328 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9329
9330 /* 15.20.2 Boolean Equality Operators == and != */
9331 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
9332 TREE_CODE (op2_type) == BOOLEAN_TYPE)
9333 ; /* Nothing to do here */
9334
9335 /* 15.20.3 Reference Equality Operators == and != */
5e942c50
APB
9336 /* Types have to be either references or the null type. If
9337 they're references, it must be possible to convert either
9338 type to the other by casting conversion. */
b9f7e36c
APB
9339 else if (op1 == null_pointer_node || op2 == null_pointer_node
9340 || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
5e942c50
APB
9341 && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
9342 || valid_ref_assignconv_cast_p (op2_type,
9343 op1_type, 1))))
e04a16fb
AG
9344 ; /* Nothing to do here */
9345
9346 /* Else we have an error figure what can't be converted into
9347 what and report the error */
9348 else
9349 {
9350 char *t1;
0a2138e2 9351 t1 = strdup (lang_printable_name (op1_type, 0));
e04a16fb
AG
9352 parse_error_context
9353 (wfl_operator, "Incompatible type for `%s'. Can't convert `%s' "
9354 "to `%s'", operator_string (node), t1,
0a2138e2 9355 lang_printable_name (op2_type, 0));
e04a16fb
AG
9356 free (t1);
9357 TREE_TYPE (node) = boolean_type_node;
9358 error_found = 1;
9359 break;
9360 }
9361 prom_type = boolean_type_node;
9362 break;
9363 }
9364
e04a16fb
AG
9365 if (error_found)
9366 return error_mark_node;
9367
9368 TREE_OPERAND (node, 0) = op1;
9369 TREE_OPERAND (node, 1) = op2;
9370 TREE_TYPE (node) = prom_type;
dc0b3eff
PB
9371 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
9372
d1472141
PB
9373 /* fold does not respect side-effect order as required for Java but not C.
9374 * Also, it sometimes create SAVE_EXPRs which are bad when emitting
9375 * bytecode.
9376 */
9377 if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
9378 : ! TREE_SIDE_EFFECTS (node))
aee48ef8
PB
9379 node = fold (node);
9380 return node;
e04a16fb
AG
9381}
9382
b67d701b
PB
9383/* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
9384 zero value, the value of CSTE comes after the valude of STRING */
9385
9386static tree
9387do_merge_string_cste (cste, string, string_len, after)
9388 tree cste;
9389 char *string;
9390 int string_len, after;
9391{
9392 int len = TREE_STRING_LENGTH (cste) + string_len;
9393 char *old = TREE_STRING_POINTER (cste);
9394 TREE_STRING_LENGTH (cste) = len;
9395 TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
9396 if (after)
9397 {
9398 strcpy (TREE_STRING_POINTER (cste), string);
9399 strcat (TREE_STRING_POINTER (cste), old);
9400 }
9401 else
9402 {
9403 strcpy (TREE_STRING_POINTER (cste), old);
9404 strcat (TREE_STRING_POINTER (cste), string);
9405 }
9406 return cste;
9407}
9408
9409/* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
9410 new STRING_CST on success, NULL_TREE on failure */
9411
9412static tree
9413merge_string_cste (op1, op2, after)
9414 tree op1, op2;
9415 int after;
9416{
9417 /* Handle two string constants right away */
9418 if (TREE_CODE (op2) == STRING_CST)
9419 return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
9420 TREE_STRING_LENGTH (op2), after);
9421
9422 /* Reasonable integer constant can be treated right away */
9423 if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
9424 {
9425 static char *boolean_true = "true";
9426 static char *boolean_false = "false";
9427 static char *null_pointer = "null";
9428 char ch[3];
9429 char *string;
9430
9431 if (op2 == boolean_true_node)
9432 string = boolean_true;
9433 else if (op2 == boolean_false_node)
9434 string = boolean_false;
9435 else if (op2 == null_pointer_node)
9436 string = null_pointer;
9437 else if (TREE_TYPE (op2) == char_type_node)
9438 {
9439 ch[0] = (char )TREE_INT_CST_LOW (op2);
9440 ch[1] = '\0';
9441 string = ch;
9442 }
9443 else
9444 string = print_int_node (op2);
9445
9446 return do_merge_string_cste (op1, string, strlen (string), after);
9447 }
9448 return NULL_TREE;
9449}
9450
9451/* Tries to statically concatenate OP1 and OP2 if possible. Either one
9452 has to be a STRING_CST and the other part must be a STRING_CST or a
9453 INTEGRAL constant. Return a new STRING_CST if the operation
9454 succeed, NULL_TREE otherwise.
9455
9456 If the case we want to optimize for space, we might want to return
9457 NULL_TREE for each invocation of this routine. FIXME */
9458
9459static tree
9460string_constant_concatenation (op1, op2)
9461 tree op1, op2;
9462{
9463 if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
9464 {
0a2138e2 9465 tree string, rest;
b67d701b
PB
9466 int invert;
9467
9468 string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
9469 rest = (string == op1 ? op2 : op1);
9470 invert = (string == op1 ? 0 : 1 );
9471
9472 /* Walk REST, only if it looks reasonable */
9473 if (TREE_CODE (rest) != STRING_CST
9474 && !IS_CRAFTED_STRING_BUFFER_P (rest)
9475 && !JSTRING_TYPE_P (TREE_TYPE (rest))
9476 && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
9477 {
9478 rest = java_complete_tree (rest);
9479 if (rest == error_mark_node)
9480 return error_mark_node;
9481 rest = fold (rest);
9482 }
9483 return merge_string_cste (string, rest, invert);
9484 }
9485 return NULL_TREE;
9486}
9487
9488/* Implement the `+' operator. Does static optimization if possible,
9489 otherwise create (if necessary) and append elements to a
9490 StringBuffer. The StringBuffer will be carried around until it is
9491 used for a function call or an assignment. Then toString() will be
9492 called on it to turn it into a String object. */
9493
9494static tree
9495build_string_concatenation (op1, op2)
9496 tree op1, op2;
9497{
9498 tree result;
dc0b3eff 9499 int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
b67d701b
PB
9500
9501 /* Try to do some static optimization */
9502 if ((result = string_constant_concatenation (op1, op2)))
9503 return result;
9504
c0d87ff6
PB
9505 /* Discard empty strings on either side of the expression */
9506 if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
acd663ee
APB
9507 {
9508 op1 = op2;
9509 op2 = NULL_TREE;
9510 }
c0d87ff6 9511 else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
acd663ee 9512 op2 = NULL_TREE;
b67d701b 9513
acd663ee 9514 /* If operands are string constant, turn then into object references */
b67d701b
PB
9515 if (TREE_CODE (op1) == STRING_CST)
9516 op1 = patch_string_cst (op1);
acd663ee 9517 if (op2 && TREE_CODE (op2) == STRING_CST)
b67d701b
PB
9518 op2 = patch_string_cst (op2);
9519
acd663ee
APB
9520 /* If either one of the constant is null and the other non null
9521 operand is a String object, return it. */
9522 if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
9523 return op1;
9524
b67d701b
PB
9525 /* If OP1 isn't already a StringBuffer, create and
9526 initialize a new one */
9527 if (!IS_CRAFTED_STRING_BUFFER_P (op1))
9528 {
9529 /* Two solutions here:
9530 1) OP1 is a string reference, we call new StringBuffer(OP1)
acd663ee 9531 2) OP1 is something else, we call new StringBuffer().append(OP1). */
b67d701b
PB
9532 if (JSTRING_TYPE_P (TREE_TYPE (op1)))
9533 op1 = BUILD_STRING_BUFFER (op1);
9534 else
9535 {
9536 tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
9537 op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
9538 }
9539 }
9540
acd663ee
APB
9541 if (op2)
9542 {
9543 /* OP1 is no longer the last node holding a crafted StringBuffer */
9544 IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
9545 /* Create a node for `{new...,xxx}.append (op2)' */
9546 if (op2)
9547 op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
9548 }
9549
b67d701b
PB
9550 /* Mark the last node holding a crafted StringBuffer */
9551 IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
dc0b3eff
PB
9552
9553 TREE_SIDE_EFFECTS (op1) = side_effects;
b67d701b
PB
9554 return op1;
9555}
9556
9557/* Patch the string node NODE. NODE can be a STRING_CST of a crafted
9558 StringBuffer. If no string were found to be patched, return
9559 NULL. */
9560
9561static tree
9562patch_string (node)
9563 tree node;
9564{
1179ebc2
APB
9565 if (node == error_mark_node)
9566 return error_mark_node;
b67d701b
PB
9567 if (TREE_CODE (node) == STRING_CST)
9568 return patch_string_cst (node);
9569 else if (IS_CRAFTED_STRING_BUFFER_P (node))
9570 {
c877974e 9571 int saved = ctxp->explicit_constructor_p;
b67d701b 9572 tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
c877974e
APB
9573 tree ret;
9574 /* Temporary disable forbid the use of `this'. */
9575 ctxp->explicit_constructor_p = 0;
9576 ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
9577 /* Restore it at its previous value */
9578 ctxp->explicit_constructor_p = saved;
9579 return ret;
b67d701b
PB
9580 }
9581 return NULL_TREE;
9582}
9583
9584/* Build the internal representation of a string constant. */
9585
9586static tree
9587patch_string_cst (node)
9588 tree node;
9589{
9590 int location;
15fdcfe9
PB
9591 if (! flag_emit_class_files)
9592 {
9593 push_obstacks (&permanent_obstack, &permanent_obstack);
9594 node = get_identifier (TREE_STRING_POINTER (node));
9595 location = alloc_name_constant (CONSTANT_String, node);
9596 node = build_ref_from_constant_pool (location);
9597 }
b67d701b
PB
9598 TREE_TYPE (node) = promote_type (string_type_node);
9599 TREE_CONSTANT (node) = 1;
9600 return node;
9601}
9602
9603/* Build an incomplete unary operator expression. */
e04a16fb
AG
9604
9605static tree
9606build_unaryop (op_token, op_location, op1)
9607 int op_token, op_location;
9608 tree op1;
9609{
9610 enum tree_code op;
9611 tree unaryop;
9612 switch (op_token)
9613 {
b67d701b 9614 case PLUS_TK: op = UNARY_PLUS_EXPR; break;
e04a16fb
AG
9615 case MINUS_TK: op = NEGATE_EXPR; break;
9616 case NEG_TK: op = TRUTH_NOT_EXPR; break;
9617 case NOT_TK: op = BIT_NOT_EXPR; break;
9618 default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
9619 op_token);
9620 }
9621
9622 unaryop = build1 (op, NULL_TREE, op1);
e04a16fb
AG
9623 TREE_SIDE_EFFECTS (unaryop) = 1;
9624 /* Store the location of the operator, for better error report. The
9625 string of the operator will be rebuild based on the OP value. */
9626 EXPR_WFL_LINECOL (unaryop) = op_location;
9627 return unaryop;
9628}
9629
9630/* Special case for the ++/-- operators, since they require an extra
9631 argument to build, which is set to NULL and patched
9632 later. IS_POST_P is 1 if the operator, 0 otherwise. */
9633
9634static tree
9635build_incdec (op_token, op_location, op1, is_post_p)
9636 int op_token, op_location;
9637 tree op1;
9638 int is_post_p;
9639{
9640 static enum tree_code lookup [2][2] =
9641 {
9642 { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
9643 { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
9644 };
9645 tree node = build (lookup [is_post_p][(op_token - DECR_TK)],
9646 NULL_TREE, op1, NULL_TREE);
9647 TREE_SIDE_EFFECTS (node) = 1;
9648 /* Store the location of the operator, for better error report. The
9649 string of the operator will be rebuild based on the OP value. */
9650 EXPR_WFL_LINECOL (node) = op_location;
9651 return node;
9652}
9653
9654/* Build an incomplete cast operator, based on the use of the
9655 CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
9656 set. java_complete_tree is trained to walk a CONVERT_EXPR even
9657 though its type is already set. */
9658
9659static tree
9660build_cast (location, type, exp)
9661 int location;
9662 tree type, exp;
9663{
9664 tree node = build1 (CONVERT_EXPR, type, exp);
9665 EXPR_WFL_LINECOL (node) = location;
9666 return node;
9667}
9668
9669/* 15.14 Unary operators. We return error_mark_node in case of error,
9670 but preserve the type of NODE if the type is fixed. */
9671
9672static tree
9673patch_unaryop (node, wfl_op)
9674 tree node;
9675 tree wfl_op;
9676{
9677 tree op = TREE_OPERAND (node, 0);
9678 tree op_type = TREE_TYPE (op);
e28cd97b 9679 tree prom_type, value, decl;
e04a16fb
AG
9680 int code = TREE_CODE (node);
9681 int error_found = 0;
9682
9683 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9684
9685 switch (code)
9686 {
9687 /* 15.13.2 Postfix Increment Operator ++ */
9688 case POSTINCREMENT_EXPR:
9689 /* 15.13.3 Postfix Increment Operator -- */
9690 case POSTDECREMENT_EXPR:
9691 /* 15.14.1 Prefix Increment Operator ++ */
9692 case PREINCREMENT_EXPR:
9693 /* 15.14.2 Prefix Decrement Operator -- */
9694 case PREDECREMENT_EXPR:
e28cd97b
APB
9695 decl = strip_out_static_field_access_decl (op);
9696 if (!JDECL_P (decl)
9697 && !((TREE_CODE (decl) == INDIRECT_REF
9698 || TREE_CODE (decl) == COMPONENT_REF)
9699 && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))))
e04a16fb 9700 {
5e942c50
APB
9701 tree lvalue;
9702 /* Before screaming, check that we're not in fact trying to
9703 increment a optimized static final access, in which case
9704 we issue an different error message. */
9705 if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
9706 && resolve_expression_name (wfl_op, &lvalue)
9707 && check_final_assignment (lvalue, wfl_op)))
9708 parse_error_context (wfl_operator, "Invalid argument to `%s'",
9709 operator_string (node));
e04a16fb
AG
9710 TREE_TYPE (node) = error_mark_node;
9711 error_found = 1;
9712 }
5e942c50
APB
9713 else if (check_final_assignment (op, wfl_op))
9714 error_found = 1;
9715
e04a16fb
AG
9716 /* From now on, we know that op if a variable and that it has a
9717 valid wfl. We use wfl_op to locate errors related to the
9718 ++/-- operand. */
9719 else if (!JNUMERIC_TYPE_P (op_type))
9720 {
9721 parse_error_context
9722 (wfl_op, "Invalid argument type `%s' to `%s'",
0a2138e2 9723 lang_printable_name (op_type, 0), operator_string (node));
e04a16fb
AG
9724 TREE_TYPE (node) = error_mark_node;
9725 error_found = 1;
9726 }
9727 else
9728 {
4a5f66c3 9729 /* Before the addition, binary numeric promotion is performed on
e04a16fb 9730 both operands */
4a5f66c3
APB
9731 value = build_int_2 (1, 0);
9732 TREE_TYPE (node) =
9733 binary_numeric_promotion (op_type, TREE_TYPE (value), &op, &value);
9734 /* And write the promoted incremented and increment */
9735 TREE_OPERAND (node, 0) = op;
e04a16fb 9736 TREE_OPERAND (node, 1) = value;
4a5f66c3
APB
9737 /* Convert the overall back into its original type. */
9738 return fold (convert (op_type, node));
e04a16fb
AG
9739 }
9740 break;
9741
9742 /* 15.14.3 Unary Plus Operator + */
b67d701b 9743 case UNARY_PLUS_EXPR:
e04a16fb
AG
9744 /* 15.14.4 Unary Minus Operator - */
9745 case NEGATE_EXPR:
9746 if (!JNUMERIC_TYPE_P (op_type))
9747 {
9748 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
9749 TREE_TYPE (node) = error_mark_node;
9750 error_found = 1;
9751 }
9752 /* Unary numeric promotion is performed on operand */
9753 else
9754 {
15fdcfe9
PB
9755 op = do_unary_numeric_promotion (op);
9756 prom_type = TREE_TYPE (op);
b67d701b 9757 if (code == UNARY_PLUS_EXPR)
4a5f66c3 9758 return fold (op);
e04a16fb
AG
9759 }
9760 break;
9761
9762 /* 15.14.5 Bitwise Complement Operator ~ */
9763 case BIT_NOT_EXPR:
9764 if (!JINTEGRAL_TYPE_P (op_type))
9765 {
9766 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
9767 TREE_TYPE (node) = error_mark_node;
9768 error_found = 1;
9769 }
9770 else
9771 {
15fdcfe9
PB
9772 op = do_unary_numeric_promotion (op);
9773 prom_type = TREE_TYPE (op);
e04a16fb
AG
9774 }
9775 break;
9776
9777 /* 15.14.6 Logical Complement Operator ! */
9778 case TRUTH_NOT_EXPR:
9779 if (TREE_CODE (op_type) != BOOLEAN_TYPE)
9780 {
9781 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
c877974e
APB
9782 /* But the type is known. We will report an error if further
9783 attempt of a assignment is made with this rhs */
e04a16fb
AG
9784 TREE_TYPE (node) = boolean_type_node;
9785 error_found = 1;
9786 }
9787 else
9788 prom_type = boolean_type_node;
9789 break;
9790
9791 /* 15.15 Cast Expression */
9792 case CONVERT_EXPR:
0a2138e2 9793 value = patch_cast (node, wfl_operator);
e04a16fb 9794 if (value == error_mark_node)
c877974e
APB
9795 {
9796 /* If this cast is part of an assignment, we tell the code
9797 that deals with it not to complain about a mismatch,
9798 because things have been cast, anyways */
9799 TREE_TYPE (node) = error_mark_node;
9800 error_found = 1;
9801 }
9802 else
dc0b3eff
PB
9803 {
9804 value = fold (value);
9805 TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
9806 return value;
9807 }
e04a16fb
AG
9808 break;
9809 }
9810
e04a16fb
AG
9811 if (error_found)
9812 return error_mark_node;
4a5f66c3
APB
9813
9814 /* There are cases where node has been replaced by something else
9815 and we don't end up returning here: UNARY_PLUS_EXPR,
9816 CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
7525cc04 9817 TREE_OPERAND (node, 0) = fold (op);
4a5f66c3 9818 TREE_TYPE (node) = prom_type;
dc0b3eff 9819 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
e04a16fb
AG
9820 return fold (node);
9821}
9822
9823/* Generic type resolution that sometimes takes place during node
9824 patching. Returned the resolved type or generate an error
9825 message. Return the resolved type or NULL_TREE. */
9826
9827static tree
9828resolve_type_during_patch (type)
9829 tree type;
9830{
9831 if (unresolved_type_p (type, NULL))
9832 {
9833 tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
9834 if (!type_decl)
9835 {
9836 parse_error_context (type,
9837 "Class `%s' not found in type declaration",
9838 IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
9839 return NULL_TREE;
9840 }
9841 else
5e942c50
APB
9842 {
9843 CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
9844 return TREE_TYPE (type_decl);
9845 }
e04a16fb
AG
9846 }
9847 return type;
9848}
9849/* 5.5 Casting Conversion. error_mark_node is returned if an error is
9850 found. Otherwise NODE or something meant to replace it is returned. */
9851
9852static tree
0a2138e2 9853patch_cast (node, wfl_operator)
e04a16fb 9854 tree node;
e04a16fb
AG
9855 tree wfl_operator;
9856{
9857 tree op = TREE_OPERAND (node, 0);
9858 tree op_type = TREE_TYPE (op);
9859 tree cast_type = TREE_TYPE (node);
9860 char *t1;
9861
9862 /* First resolve OP_TYPE if unresolved */
9863 if (!(cast_type = resolve_type_during_patch (cast_type)))
9864 return error_mark_node;
9865
9866 /* Check on cast that are proven correct at compile time */
9867 if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
9868 {
9869 static tree convert_narrow ();
9870 /* Same type */
9871 if (cast_type == op_type)
9872 return node;
9873
0b4d333e
APB
9874 /* float and double type are converted to the original type main
9875 variant and then to the target type. */
9876 if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
9877 op = convert (integer_type_node, op);
9878
e04a16fb
AG
9879 /* Try widening/narowwing convertion. Potentially, things need
9880 to be worked out in gcc so we implement the extreme cases
9881 correctly. fold_convert() needs to be fixed. */
9882 return convert (cast_type, op);
9883 }
9884
0b4d333e
APB
9885 /* It's also valid to cast a boolean into a boolean */
9886 if (op_type == boolean_type_node && cast_type == boolean_type_node)
9887 return node;
9888
5e942c50
APB
9889 /* null can be casted to references */
9890 if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
9891 return build_null_of_type (cast_type);
9892
e04a16fb
AG
9893 /* The remaining legal casts involve conversion between reference
9894 types. Check for their compile time correctness. */
9895 if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type)
09ed0f70 9896 && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
e04a16fb
AG
9897 {
9898 TREE_TYPE (node) = promote_type (cast_type);
9899 /* Now, the case can be determined correct at compile time if
9900 OP_TYPE can be converted into CAST_TYPE by assignment
9901 conversion (5.2) */
9902
9903 if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
15fdcfe9
PB
9904 {
9905 TREE_SET_CODE (node, NOP_EXPR);
9906 return node;
9907 }
9908
9909 if (flag_emit_class_files)
9910 {
9911 TREE_SET_CODE (node, CONVERT_EXPR);
9912 return node;
9913 }
e04a16fb
AG
9914
9915 /* The cast requires a run-time check */
9916 return build (CALL_EXPR, promote_type (cast_type),
9917 build_address_of (soft_checkcast_node),
9918 tree_cons (NULL_TREE, build_class_ref (cast_type),
9919 build_tree_list (NULL_TREE, op)),
9920 NULL_TREE);
9921 }
9922
9923 /* Any other casts are proven incorrect at compile time */
0a2138e2 9924 t1 = strdup (lang_printable_name (op_type, 0));
e04a16fb 9925 parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
0a2138e2 9926 t1, lang_printable_name (cast_type, 0));
e04a16fb
AG
9927 free (t1);
9928 return error_mark_node;
9929}
9930
5e942c50
APB
9931/* Build a null constant and give it the type TYPE. */
9932
9933static tree
9934build_null_of_type (type)
9935 tree type;
9936{
9937 tree node = build_int_2 (0, 0);
9938 TREE_TYPE (node) = promote_type (type);
9939 return node;
9940}
9941
e04a16fb
AG
9942/* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
9943 a list of indices. */
9944static tree
9945build_array_ref (location, array, index)
9946 int location;
9947 tree array, index;
9948{
9949 tree node = build (ARRAY_REF, NULL_TREE, array, index);
9950 EXPR_WFL_LINECOL (node) = location;
9951 return node;
9952}
9953
9954/* 15.12 Array Access Expression */
9955
9956static tree
c877974e
APB
9957patch_array_ref (node)
9958 tree node;
e04a16fb
AG
9959{
9960 tree array = TREE_OPERAND (node, 0);
9961 tree array_type = TREE_TYPE (array);
9962 tree index = TREE_OPERAND (node, 1);
9963 tree index_type = TREE_TYPE (index);
e04a16fb
AG
9964 int error_found = 0;
9965
9966 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9967
e04a16fb
AG
9968 if (TREE_CODE (array_type) == POINTER_TYPE)
9969 array_type = TREE_TYPE (array_type);
9970
9971 /* The array reference must be an array */
9972 if (!TYPE_ARRAY_P (array_type))
9973 {
9974 parse_error_context
9975 (wfl_operator, "`[]' can only be applied to arrays. It can't be "
0a2138e2 9976 "applied to `%s'", lang_printable_name (array_type, 0));
e04a16fb
AG
9977 TREE_TYPE (node) = error_mark_node;
9978 error_found = 1;
9979 }
9980
9981 /* The array index underdoes unary numeric promotion. The promoted
9982 type must be int */
15fdcfe9
PB
9983 index = do_unary_numeric_promotion (index);
9984 if (TREE_TYPE (index) != int_type_node)
e04a16fb 9985 {
b67d701b 9986 int could_cast = valid_cast_to_p (index_type, int_type_node);
e04a16fb
AG
9987 parse_error_context
9988 (wfl_operator,
9989 (could_cast ? "Incompatible type for `[]'. Explicit cast needed to "
9990 "convert `%s' to `int'" : "Incompatible type for `[]'. "
9991 "Can't convert `%s' to `int'"),
0a2138e2 9992 lang_printable_name (index_type, 0));
e04a16fb
AG
9993 TREE_TYPE (node) = error_mark_node;
9994 error_found = 1;
9995 }
9996
e04a16fb
AG
9997 if (error_found)
9998 return error_mark_node;
e04a16fb 9999
5e942c50 10000 array_type = TYPE_ARRAY_ELEMENT (array_type);
5e942c50 10001
e04a16fb
AG
10002 if (flag_emit_class_files)
10003 {
15fdcfe9
PB
10004 TREE_OPERAND (node, 0) = array;
10005 TREE_OPERAND (node, 1) = index;
e04a16fb
AG
10006 }
10007 else
939d7216
PB
10008 {
10009 /* The save_expr is for correct evaluation order. It would be cleaner
10010 to use force_evaluation_order (see comment there), but that is
10011 difficult when we also have to deal with bounds checking. */
10012 if (TREE_SIDE_EFFECTS (index))
10013 array = save_expr (array);
10014 node = build_java_arrayaccess (array, array_type, index);
10015 if (TREE_SIDE_EFFECTS (index))
10016 node = build (COMPOUND_EXPR, array_type, array, node);
10017 }
e04a16fb
AG
10018 TREE_TYPE (node) = array_type;
10019 return node;
10020}
10021
10022/* 15.9 Array Creation Expressions */
10023
10024static tree
10025build_newarray_node (type, dims, extra_dims)
10026 tree type;
10027 tree dims;
10028 int extra_dims;
10029{
10030 tree node =
b67d701b 10031 build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims),
e04a16fb 10032 build_int_2 (extra_dims, 0));
e04a16fb
AG
10033 return node;
10034}
10035
10036static tree
10037patch_newarray (node)
10038 tree node;
10039{
10040 tree type = TREE_OPERAND (node, 0);
10041 tree dims = TREE_OPERAND (node, 1);
10042 tree cdim, array_type;
10043 int error_found = 0;
10044 int ndims = 0;
10045 int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
e04a16fb
AG
10046
10047 /* Dimension types are verified. It's better for the types to be
10048 verified in order. */
10049 for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
10050 {
10051 int dim_error = 0;
10052 tree dim = TREE_VALUE (cdim);
10053
10054 /* Dim might have been saved during its evaluation */
10055 dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
10056
10057 /* The type of each specified dimension must be an integral type. */
10058 if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
10059 dim_error = 1;
10060
10061 /* Each expression undergoes an unary numeric promotion (5.6.1) and the
10062 promoted type must be int. */
10063 else
10064 {
15fdcfe9 10065 dim = do_unary_numeric_promotion (dim);
e04a16fb
AG
10066 if (TREE_TYPE (dim) != int_type_node)
10067 dim_error = 1;
10068 }
10069
10070 /* Report errors on types here */
10071 if (dim_error)
10072 {
10073 parse_error_context
10074 (TREE_PURPOSE (cdim),
10075 "Incompatible type for dimension in array creation expression. "
10076 "%s convert `%s' to `int'",
b67d701b 10077 (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
e04a16fb 10078 "Explicit cast needed to" : "Can't"),
0a2138e2 10079 lang_printable_name (TREE_TYPE (dim), 0));
e04a16fb
AG
10080 error_found = 1;
10081 }
10082
e04a16fb
AG
10083 TREE_PURPOSE (cdim) = NULL_TREE;
10084 }
10085
10086 /* Resolve array base type if unresolved */
10087 if (!(type = resolve_type_during_patch (type)))
10088 error_found = 1;
10089
10090 if (error_found)
10091 {
10092 /* We don't want further evaluation of this bogus array creation
10093 operation */
10094 TREE_TYPE (node) = error_mark_node;
10095 return error_mark_node;
10096 }
10097
15fdcfe9
PB
10098 /* Set array_type to the actual (promoted) array type of the result. */
10099 if (TREE_CODE (type) == RECORD_TYPE)
10100 type = build_pointer_type (type);
10101 while (--xdims >= 0)
10102 {
10103 type = promote_type (build_java_array_type (type, -1));
10104 }
10105 dims = nreverse (dims);
10106 array_type = type;
10107 for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
10108 {
10109 type = array_type;
10110 array_type = build_java_array_type (type,
10111 TREE_CODE (cdim) == INTEGER_CST ?
10112 TREE_INT_CST_LOW (cdim) : -1);
10113 array_type = promote_type (array_type);
10114 }
10115 dims = nreverse (dims);
10116
e04a16fb
AG
10117 /* The node is transformed into a function call. Things are done
10118 differently according to the number of dimensions. If the number
10119 of dimension is equal to 1, then the nature of the base type
10120 (primitive or not) matters. */
15fdcfe9 10121 if (ndims == 1)
fdec99c6 10122 return build_new_array (type, TREE_VALUE (dims));
e04a16fb 10123
e04a16fb
AG
10124 /* Can't reuse what's already written in expr.c because it uses the
10125 JVM stack representation. Provide a build_multianewarray. FIXME */
15fdcfe9 10126 return build (CALL_EXPR, array_type,
e04a16fb 10127 build_address_of (soft_multianewarray_node),
15fdcfe9 10128 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
e04a16fb 10129 tree_cons (NULL_TREE,
15fdcfe9 10130 build_int_2 (ndims, 0), dims )),
e04a16fb
AG
10131 NULL_TREE);
10132}
10133
f8976021
APB
10134/* 10.6 Array initializer. */
10135
10136/* Build a wfl for array element that don't have one, so we can
10137 pin-point errors. */
10138
10139static tree
10140maybe_build_array_element_wfl (node)
10141 tree node;
10142{
10143 if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
10144 return build_expr_wfl (NULL_TREE, ctxp->filename,
10145 ctxp->elc.line, ctxp->elc.prev_col);
10146 else
10147 return NULL_TREE;
10148}
10149
10150/* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
10151 identification of initialized arrays easier to detect during walk
10152 and expansion. */
10153
10154static tree
10155build_new_array_init (location, values)
10156 int location;
10157 tree values;
10158{
10159 tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
10160 tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
5bba4807 10161 EXPR_WFL_LINECOL (to_return) = location;
f8976021
APB
10162 return to_return;
10163}
10164
10165/* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
10166 occurred. Otherwise return NODE after having set its type
10167 appropriately. */
10168
10169static tree
10170patch_new_array_init (type, node)
10171 tree type, node;
f8976021
APB
10172{
10173 int error_seen = 0;
fdec99c6 10174 tree current, element_type;
f8976021 10175 HOST_WIDE_INT length;
fdec99c6
PB
10176 int all_constant = 1;
10177 tree init = TREE_OPERAND (node, 0);
f8976021 10178
fdec99c6
PB
10179 if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
10180 {
10181 parse_error_context (node,
10182 "Invalid array initializer for non-array type `%s'",
10183 lang_printable_name (type, 1));
10184 return error_mark_node;
10185 }
10186 type = TREE_TYPE (type);
10187 element_type = TYPE_ARRAY_ELEMENT (type);
f8976021 10188
fdec99c6
PB
10189 CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
10190
10191 for (length = 0, current = CONSTRUCTOR_ELTS (init);
10192 current; length++, current = TREE_CHAIN (current))
f8976021 10193 {
fdec99c6
PB
10194 tree elt = TREE_VALUE (current);
10195 if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
f8976021 10196 {
fdec99c6 10197 error_seen |= array_constructor_check_entry (element_type, current);
5bba4807
PB
10198 elt = TREE_VALUE (current);
10199 /* When compiling to native code, STRING_CST is converted to
10200 INDIRECT_REF, but still with a TREE_CONSTANT flag. */
10201 if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
fdec99c6 10202 all_constant = 0;
f8976021 10203 }
fdec99c6
PB
10204 else
10205 {
10206 TREE_VALUE (current) = patch_new_array_init (element_type, elt);
10207 TREE_PURPOSE (current) = NULL_TREE;
10208 all_constant = 0;
10209 }
10210 if (elt && TREE_VALUE (elt) == error_mark_node)
10211 error_seen = 1;
f8976021
APB
10212 }
10213
10214 if (error_seen)
10215 return error_mark_node;
10216
10217 /* Create a new type. We can't reuse the one we have here by
10218 patching its dimension because it originally is of dimension -1
10219 hence reused by gcc. This would prevent triangular arrays. */
fdec99c6
PB
10220 type = build_java_array_type (element_type, length);
10221 TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
10222 TREE_TYPE (node) = promote_type (type);
10223 TREE_CONSTANT (init) = all_constant;
bc3ca41b 10224 TREE_CONSTANT (node) = all_constant;
f8976021
APB
10225 return node;
10226}
10227
10228/* Verify that one entry of the initializer element list can be
10229 assigned to the array base type. Report 1 if an error occurred, 0
10230 otherwise. */
10231
10232static int
10233array_constructor_check_entry (type, entry)
10234 tree type, entry;
10235{
10236 char *array_type_string = NULL; /* For error reports */
10237 tree value, type_value, new_value, wfl_value, patched;
10238 int error_seen = 0;
10239
10240 new_value = NULL_TREE;
10241 wfl_value = TREE_VALUE (entry);
10242
f8976021 10243 value = java_complete_tree (TREE_VALUE (entry));
1179ebc2 10244 /* patch_string return error_mark_node if arg is error_mark_node */
f8976021
APB
10245 if ((patched = patch_string (value)))
10246 value = patched;
1179ebc2
APB
10247 if (value == error_mark_node)
10248 return 1;
f8976021 10249
f8976021
APB
10250 type_value = TREE_TYPE (value);
10251
1179ebc2 10252 /* At anytime, try_builtin_assignconv can report a warning on
f8976021
APB
10253 constant overflow during narrowing. */
10254 SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
10255 new_value = try_builtin_assignconv (wfl_operator, type, value);
10256 if (!new_value && (new_value = try_reference_assignconv (type, value)))
10257 type_value = promote_type (type);
10258
10259 /* Check and report errors */
10260 if (!new_value)
10261 {
10262 char *msg = (!valid_cast_to_p (type_value, type) ?
10263 "Can't" : "Explicit cast needed to");
10264 if (!array_type_string)
10265 array_type_string = strdup (lang_printable_name (type, 1));
10266 parse_error_context
10267 (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
10268 msg, lang_printable_name (type_value, 1), array_type_string);
10269 error_seen = 1;
10270 }
10271
10272 if (new_value)
10273 {
10274 new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
10275 TREE_VALUE (entry) = new_value;
10276 }
10277
10278 if (array_type_string)
10279 free (array_type_string);
10280
10281 TREE_PURPOSE (entry) = NULL_TREE;
10282 return error_seen;
10283}
10284
e04a16fb
AG
10285static tree
10286build_this (location)
10287 int location;
10288{
9ee9b555 10289 tree node = build_wfl_node (this_identifier_node);
b67d701b 10290 TREE_SET_CODE (node, THIS_EXPR);
e04a16fb
AG
10291 EXPR_WFL_LINECOL (node) = location;
10292 return node;
10293}
10294
10295/* 14.15 The return statement. It builds a modify expression that
10296 assigns the returned value to the RESULT_DECL that hold the value
10297 to be returned. */
10298
10299static tree
10300build_return (location, op)
10301 int location;
10302 tree op;
10303{
10304 tree node = build1 (RETURN_EXPR, NULL_TREE, op);
10305 EXPR_WFL_LINECOL (node) = location;
b67d701b 10306 node = build_debugable_stmt (location, node);
e04a16fb
AG
10307 return node;
10308}
10309
10310static tree
10311patch_return (node)
10312 tree node;
10313{
10314 tree return_exp = TREE_OPERAND (node, 0);
10315 tree meth = current_function_decl;
10316 tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
e04a16fb
AG
10317 int error_found = 0;
10318
10319 TREE_TYPE (node) = error_mark_node;
10320 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10321
10322 /* It's invalid to have a return value within a function that is
10323 declared with the keyword void or that is a constructor */
10324 if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
10325 error_found = 1;
10326
f099f336
APB
10327 /* It's invalid to use a return statement in a static block */
10328 if (DECL_NAME (current_function_decl) == clinit_identifier_node)
10329 error_found = 1;
10330
e04a16fb
AG
10331 /* It's invalid to have a no return value within a function that
10332 isn't declared with the keyword `void' */
10333 if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
10334 error_found = 2;
10335
10336 if (error_found)
10337 {
f099f336
APB
10338 if (DECL_NAME (current_function_decl) == clinit_identifier_node)
10339 parse_error_context (wfl_operator,
10340 "`return' inside static initializer.");
10341
10342 else if (!DECL_CONSTRUCTOR_P (meth))
22eed1e6
APB
10343 {
10344 char *t = strdup (lang_printable_name (mtype, 0));
10345 parse_error_context (wfl_operator,
10346 "`return' with%s value from `%s %s'",
10347 (error_found == 1 ? "" : "out"),
10348 t, lang_printable_name (meth, 0));
10349 free (t);
10350 }
10351 else
10352 parse_error_context (wfl_operator,
10353 "`return' with value from constructor `%s'",
10354 lang_printable_name (meth, 0));
e04a16fb
AG
10355 return error_mark_node;
10356 }
10357
5e942c50
APB
10358 /* If we have a return_exp, build a modify expression and expand
10359 it. Note: at that point, the assignment is declared valid, but we
10360 may want to carry some more hacks */
e04a16fb
AG
10361 if (return_exp)
10362 {
5e942c50
APB
10363 tree exp = java_complete_tree (return_exp);
10364 tree modify, patched;
10365
10366 /* If the function returned value and EXP are booleans, EXP has
10367 to be converted into the type of DECL_RESULT, which is integer
10368 (see complete_start_java_method) */
10369 if (TREE_TYPE (exp) == boolean_type_node &&
10370 TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
10371 exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
10372
10373 /* `null' can be assigned to a function returning a reference */
10374 if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
10375 exp == null_pointer_node)
10376 exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
10377
10378 if ((patched = patch_string (exp)))
10379 exp = patched;
10380
10381 modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
e04a16fb
AG
10382 EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
10383 modify = java_complete_tree (modify);
5e942c50 10384
e04a16fb
AG
10385 if (modify != error_mark_node)
10386 {
10387 TREE_SIDE_EFFECTS (modify) = 1;
10388 TREE_OPERAND (node, 0) = modify;
10389 }
10390 else
10391 return error_mark_node;
10392 }
10393 TREE_TYPE (node) = void_type_node;
10394 TREE_SIDE_EFFECTS (node) = 1;
10395 return node;
10396}
10397
10398/* 14.8 The if Statement */
10399
10400static tree
10401build_if_else_statement (location, expression, if_body, else_body)
10402 int location;
10403 tree expression, if_body, else_body;
10404{
10405 tree node;
e04a16fb 10406 if (!else_body)
9bbc7d9f 10407 else_body = empty_stmt_node;
e04a16fb
AG
10408 node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
10409 EXPR_WFL_LINECOL (node) = location;
b67d701b 10410 node = build_debugable_stmt (location, node);
e04a16fb
AG
10411 return node;
10412}
10413
10414static tree
10415patch_if_else_statement (node)
10416 tree node;
10417{
10418 tree expression = TREE_OPERAND (node, 0);
10419
10420 TREE_TYPE (node) = error_mark_node;
10421 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10422
10423 /* The type of expression must be boolean */
b67d701b
PB
10424 if (TREE_TYPE (expression) != boolean_type_node
10425 && TREE_TYPE (expression) != promoted_boolean_type_node)
e04a16fb
AG
10426 {
10427 parse_error_context
10428 (wfl_operator,
10429 "Incompatible type for `if'. Can't convert `%s' to `boolean'",
0a2138e2 10430 lang_printable_name (TREE_TYPE (expression), 0));
e04a16fb
AG
10431 return error_mark_node;
10432 }
10433
10434 TREE_TYPE (node) = void_type_node;
10435 TREE_SIDE_EFFECTS (node) = 1;
15fdcfe9 10436 CAN_COMPLETE_NORMALLY (node)
9bbc7d9f
PB
10437 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
10438 | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
e04a16fb
AG
10439 return node;
10440}
10441
10442/* 14.6 Labeled Statements */
10443
10444/* Action taken when a lableled statement is parsed. a new
10445 LABELED_BLOCK_EXPR is created. No statement is attached to the
b635eb2f 10446 label, yet. LABEL can be NULL_TREE for artificially-generated blocks. */
e04a16fb
AG
10447
10448static tree
0a2138e2 10449build_labeled_block (location, label)
e04a16fb 10450 int location;
0a2138e2 10451 tree label;
e04a16fb 10452{
b635eb2f 10453 tree label_name ;
e04a16fb 10454 tree label_decl, node;
b635eb2f
PB
10455 if (label == NULL_TREE || label == continue_identifier_node)
10456 label_name = label;
10457 else
e04a16fb 10458 {
b635eb2f
PB
10459 label_name = merge_qualified_name (label_id, label);
10460 /* Issue an error if we try to reuse a label that was previously
10461 declared */
10462 if (IDENTIFIER_LOCAL_VALUE (label_name))
10463 {
10464 EXPR_WFL_LINECOL (wfl_operator) = location;
10465 parse_error_context (wfl_operator, "Declaration of `%s' shadows "
10466 "a previous label declaration",
10467 IDENTIFIER_POINTER (label));
10468 EXPR_WFL_LINECOL (wfl_operator) =
10469 EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
10470 parse_error_context (wfl_operator, "This is the location of the "
10471 "previous declaration of label `%s'",
10472 IDENTIFIER_POINTER (label));
10473 java_error_count--;
10474 }
e04a16fb
AG
10475 }
10476
10477 label_decl = create_label_decl (label_name);
10478 node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
10479 EXPR_WFL_LINECOL (node) = location;
10480 TREE_SIDE_EFFECTS (node) = 1;
10481 return node;
10482}
10483
b67d701b 10484/* A labeled statement LBE is attached a statement. */
e04a16fb
AG
10485
10486static tree
b635eb2f 10487finish_labeled_statement (lbe, statement)
e04a16fb
AG
10488 tree lbe; /* Labeled block expr */
10489 tree statement;
10490{
10491 /* In anyways, tie the loop to its statement */
10492 LABELED_BLOCK_BODY (lbe) = statement;
10493
10494 /* Ok, if statement is a for loop, we have to attach the labeled
10495 statement to the block the for loop belongs to and return the
10496 block instead */
10497 if (TREE_CODE (statement) == LOOP_EXPR && IS_FOR_LOOP_P (statement))
10498 {
10499 java_method_add_stmt (current_function_decl, lbe);
b635eb2f 10500 lbe = exit_block ();
e04a16fb 10501 }
b635eb2f
PB
10502 pop_labeled_block ();
10503 POP_LABELED_BLOCK ();
e04a16fb
AG
10504 return lbe;
10505}
10506
10507/* 14.10, 14.11, 14.12 Loop Statements */
10508
10509/* Create an empty LOOP_EXPR and make it the last in the nested loop
10510 list. */
10511
10512static tree
10513build_new_loop (loop_body)
10514 tree loop_body;
10515{
10516 tree loop = build (LOOP_EXPR, NULL_TREE, loop_body);
10517 TREE_SIDE_EFFECTS (loop) = 1;
10518 PUSH_LOOP (loop);
10519 return loop;
10520}
10521
10522/* Create a loop body according to the following structure:
10523 COMPOUND_EXPR
10524 COMPOUND_EXPR (loop main body)
10525 EXIT_EXPR (this order is for while/for loops.
10526 LABELED_BLOCK_EXPR the order is reversed for do loops)
34f4db93 10527 LABEL_DECL (a continue occuring here branches at the
e04a16fb
AG
10528 BODY end of this labeled block)
10529 INCREMENT (if any)
10530
10531 REVERSED, if non zero, tells that the loop condition expr comes
b67d701b
PB
10532 after the body, like in the do-while loop.
10533
10534 To obtain a loop, the loop body structure described above is
10535 encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
10536
10537 LABELED_BLOCK_EXPR
10538 LABEL_DECL (use this label to exit the loop)
10539 LOOP_EXPR
10540 <structure described above> */
e04a16fb
AG
10541
10542static tree
10543build_loop_body (location, condition, reversed)
10544 int location;
10545 tree condition;
10546 int reversed;
10547{
0a2138e2 10548 tree first, second, body;
e04a16fb
AG
10549
10550 condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
10551 EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
10552 condition = build_debugable_stmt (location, condition);
10553 TREE_SIDE_EFFECTS (condition) = 1;
10554
b635eb2f 10555 body = build_labeled_block (0, continue_identifier_node);
e04a16fb
AG
10556 first = (reversed ? body : condition);
10557 second = (reversed ? condition : body);
10558 return
10559 build (COMPOUND_EXPR, NULL_TREE,
9bbc7d9f 10560 build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
e04a16fb
AG
10561}
10562
10563/* Install CONDITION (if any) and loop BODY (using REVERSED to tell
10564 their order) on the current loop. Unlink the current loop from the
10565 loop list. */
10566
10567static tree
b635eb2f 10568finish_loop_body (location, condition, body, reversed)
e04a16fb
AG
10569 int location;
10570 tree condition, body;
10571 int reversed;
10572{
10573 tree to_return = ctxp->current_loop;
10574 tree loop_body = LOOP_EXPR_BODY (to_return);
10575 if (condition)
10576 {
10577 tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
10578 /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
10579 The real EXIT_EXPR is one operand further. */
10580 EXPR_WFL_LINECOL (cnode) = location;
10581 /* This one is for accurate error reports */
10582 EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
10583 TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
10584 }
10585 LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
10586 POP_LOOP ();
10587 return to_return;
10588}
10589
b635eb2f 10590/* Tailored version of finish_loop_body for FOR loops, when FOR
e04a16fb
AG
10591 loops feature the condition part */
10592
10593static tree
b635eb2f 10594finish_for_loop (location, condition, update, body)
e04a16fb
AG
10595 int location;
10596 tree condition, update, body;
10597{
10598 /* Put the condition and the loop body in place */
b635eb2f 10599 tree loop = finish_loop_body (location, condition, body, 0);
e04a16fb
AG
10600 /* LOOP is the current loop which has been now popped of the loop
10601 stack. Install the update block */
10602 LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
10603 return loop;
10604}
10605
10606/* If the loop isn't surrounded by a labeled statement, create one and
b635eb2f 10607 insert LOOP as its body. */
e04a16fb
AG
10608
10609static tree
10610patch_loop_statement (loop)
10611 tree loop;
10612{
b635eb2f 10613 if (! LOOP_HAS_LABEL_P (loop))
e04a16fb 10614 {
b635eb2f 10615 tree loop_label = build_labeled_block (0, NULL_TREE);
e04a16fb
AG
10616 LABELED_BLOCK_BODY (loop_label) = loop;
10617 PUSH_LABELED_BLOCK (loop_label);
b635eb2f 10618 loop = loop_label;
e04a16fb 10619 }
b635eb2f
PB
10620 TREE_TYPE (loop) = void_type_node;
10621 return loop;
e04a16fb
AG
10622}
10623
10624/* 14.13, 14.14: break and continue Statements */
10625
10626/* Build a break or a continue statement. a null NAME indicates an
10627 unlabeled break/continue statement. */
10628
10629static tree
10630build_bc_statement (location, is_break, name)
10631 int location, is_break;
10632 tree name;
10633{
10634 tree break_continue, label_block_expr = NULL_TREE;
10635
10636 if (name)
10637 {
10638 if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE
10639 (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
10640 /* Null means that we don't have a target for this named
10641 break/continue. In this case, we make the target to be the
10642 label name, so that the error can be reported accuratly in
10643 patch_bc_statement. */
10644 label_block_expr = EXPR_WFL_NODE (name);
10645 }
10646 /* Unlabeled break/continue will be handled during the
10647 break/continue patch operation */
10648 break_continue
10649 = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
10650
10651 IS_BREAK_STMT_P (break_continue) = is_break;
10652 TREE_SIDE_EFFECTS (break_continue) = 1;
10653 EXPR_WFL_LINECOL (break_continue) = location;
b67d701b 10654 break_continue = build_debugable_stmt (location, break_continue);
e04a16fb
AG
10655 return break_continue;
10656}
10657
10658/* Verification of a break/continue statement. */
10659
10660static tree
10661patch_bc_statement (node)
10662 tree node;
10663{
10664 tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
b635eb2f 10665 tree labeled_block = ctxp->current_labeled_block;
b67d701b 10666 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
e04a16fb 10667
e04a16fb 10668 /* Having an identifier here means that the target is unknown. */
b635eb2f 10669 if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
e04a16fb
AG
10670 {
10671 parse_error_context (wfl_operator, "No label definition found for `%s'",
10672 IDENTIFIER_POINTER (bc_label));
10673 return error_mark_node;
10674 }
b635eb2f 10675 if (! IS_BREAK_STMT_P (node))
e04a16fb 10676 {
b635eb2f
PB
10677 /* It's a continue statement. */
10678 for (;; labeled_block = TREE_CHAIN (labeled_block))
e04a16fb 10679 {
b635eb2f
PB
10680 if (labeled_block == NULL_TREE)
10681 {
10682 if (bc_label == NULL_TREE)
10683 parse_error_context (wfl_operator,
10684 "`continue' must be in loop");
10685 else
1504b2b4
APB
10686 parse_error_context
10687 (wfl_operator, "continue label `%s' does not name a loop",
10688 IDENTIFIER_POINTER (bc_label));
b635eb2f
PB
10689 return error_mark_node;
10690 }
10691 if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
10692 == continue_identifier_node)
10693 && (bc_label == NULL_TREE
10694 || TREE_CHAIN (labeled_block) == bc_label))
10695 {
10696 bc_label = labeled_block;
10697 break;
10698 }
e04a16fb 10699 }
e04a16fb 10700 }
b635eb2f 10701 else if (!bc_label)
34f4db93 10702 {
b635eb2f 10703 for (;; labeled_block = TREE_CHAIN (labeled_block))
e04a16fb 10704 {
b635eb2f
PB
10705 if (labeled_block == NULL_TREE)
10706 {
10707 parse_error_context (wfl_operator,
10708 "`break' must be in loop or switch");
10709 return error_mark_node;
10710 }
10711 target_stmt = LABELED_BLOCK_BODY (labeled_block);
10712 if (TREE_CODE (target_stmt) == SWITCH_EXPR
10713 || TREE_CODE (target_stmt) == LOOP_EXPR)
10714 {
10715 bc_label = labeled_block;
10716 break;
10717 }
e04a16fb 10718 }
e04a16fb
AG
10719 }
10720
b635eb2f 10721 EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
15fdcfe9
PB
10722 CAN_COMPLETE_NORMALLY (bc_label) = 1;
10723
e04a16fb
AG
10724 /* Our break/continue don't return values. */
10725 TREE_TYPE (node) = void_type_node;
10726 /* Encapsulate the break within a compound statement so that it's
10727 expanded all the times by expand_expr (and not clobered
10728 sometimes, like after a if statement) */
10729 node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
10730 TREE_SIDE_EFFECTS (node) = 1;
10731 return node;
10732}
10733
10734/* Process the exit expression belonging to a loop. Its type must be
10735 boolean. */
10736
10737static tree
10738patch_exit_expr (node)
10739 tree node;
10740{
10741 tree expression = TREE_OPERAND (node, 0);
10742 TREE_TYPE (node) = error_mark_node;
10743 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10744
10745 /* The type of expression must be boolean */
10746 if (TREE_TYPE (expression) != boolean_type_node)
10747 {
10748 parse_error_context
10749 (wfl_operator,
10750 "Incompatible type for loop conditional. Can't convert `%s' to "
10751 "`boolean'",
0a2138e2 10752 lang_printable_name (TREE_TYPE (expression), 0));
e04a16fb
AG
10753 return error_mark_node;
10754 }
10755 /* Now we know things are allright, invert the condition, fold and
10756 return */
10757 TREE_OPERAND (node, 0) =
10758 fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
15fdcfe9
PB
10759
10760 if (! integer_zerop (TREE_OPERAND (node, 0))
10761 && ctxp->current_loop != NULL_TREE
10762 && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
10763 CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
10764 if (! integer_onep (TREE_OPERAND (node, 0)))
10765 CAN_COMPLETE_NORMALLY (node) = 1;
10766
10767
e04a16fb
AG
10768 TREE_TYPE (node) = void_type_node;
10769 return node;
10770}
b67d701b
PB
10771
10772/* 14.9 Switch statement */
10773
10774static tree
10775patch_switch_statement (node)
10776 tree node;
10777{
c877974e 10778 tree se = TREE_OPERAND (node, 0), se_type;
b67d701b
PB
10779
10780 /* Complete the switch expression */
10781 se = TREE_OPERAND (node, 0) = java_complete_tree (se);
10782 se_type = TREE_TYPE (se);
10783 /* The type of the switch expression must be char, byte, short or
10784 int */
10785 if (!JINTEGRAL_TYPE_P (se_type))
10786 {
10787 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10788 parse_error_context (wfl_operator, "Incompatible type for `switch'. "
10789 "Can't convert `%s' to `int'",
0a2138e2 10790 lang_printable_name (se_type, 0));
b67d701b
PB
10791 /* This is what java_complete_tree will check */
10792 TREE_OPERAND (node, 0) = error_mark_node;
10793 return error_mark_node;
10794 }
10795
15fdcfe9 10796 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
b67d701b
PB
10797
10798 /* Ready to return */
15fdcfe9 10799 if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
b67d701b
PB
10800 {
10801 TREE_TYPE (node) = error_mark_node;
10802 return error_mark_node;
10803 }
10804 TREE_TYPE (node) = void_type_node;
10805 TREE_SIDE_EFFECTS (node) = 1;
15fdcfe9 10806 CAN_COMPLETE_NORMALLY (node)
c877974e
APB
10807 = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
10808 || ! SWITCH_HAS_DEFAULT (node);
b67d701b
PB
10809 return node;
10810}
10811
b67d701b
PB
10812/* 14.18 The try statement */
10813
b67d701b 10814static tree
a7d8d81f 10815build_try_statement (location, try_block, catches)
b67d701b 10816 int location;
a7d8d81f
PB
10817 tree try_block, catches;
10818{
10819 tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
b67d701b 10820 EXPR_WFL_LINECOL (node) = location;
a7d8d81f 10821 return node;
b67d701b
PB
10822}
10823
a7d8d81f
PB
10824static tree
10825build_try_finally_statement (location, try_block, finally)
10826 int location;
10827 tree try_block, finally;
b67d701b 10828{
a7d8d81f
PB
10829 tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
10830 EXPR_WFL_LINECOL (node) = location;
10831 return node;
b67d701b
PB
10832}
10833
10834static tree
10835patch_try_statement (node)
10836 tree node;
10837{
10838 int error_found = 0;
10839 tree try = TREE_OPERAND (node, 0);
10840 /* Exception handlers are considered in left to right order */
10841 tree catch = nreverse (TREE_OPERAND (node, 1));
b9f7e36c 10842 tree current, caught_type_list = NULL_TREE;
b67d701b
PB
10843
10844 /* Check catch clauses, if any. Every time we find an error, we try
b9f7e36c
APB
10845 to process the next catch clause. We process the catch clause before
10846 the try block so that when processing the try block we can check thrown
10847 exceptions againts the caught type list. */
b67d701b
PB
10848 for (current = catch; current; current = TREE_CHAIN (current))
10849 {
10850 tree carg_decl, carg_type;
10851 tree sub_current, catch_block, catch_clause;
10852 int unreachable;
10853
b67d701b 10854 /* At this point, the structure of the catch clause is
b67d701b
PB
10855 CATCH_EXPR (catch node)
10856 BLOCK (with the decl of the parameter)
10857 COMPOUND_EXPR
7525cc04 10858 MODIFY_EXPR (assignment of the catch parameter)
b67d701b 10859 BLOCK (catch clause block)
a7d8d81f
PB
10860 */
10861 catch_clause = TREE_OPERAND (current, 0);
b67d701b
PB
10862 carg_decl = BLOCK_EXPR_DECLS (catch_clause);
10863 carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
10864
10865 /* Catch clauses can't have more than one parameter declared,
10866 but it's already enforced by the grammar. Make sure that the
10867 only parameter of the clause statement in of class Throwable
10868 or a subclass of Throwable, but that was done earlier. The
10869 catch clause parameter type has also been resolved. */
10870
10871 /* Just make sure that the catch clause parameter type inherits
10872 from java.lang.Throwable */
10873 if (!inherits_from_p (carg_type, throwable_type_node))
10874 {
10875 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
10876 parse_error_context (wfl_operator,
10877 "Can't catch class `%s'. Catch clause "
10878 "parameter type must be a subclass of "
10879 "class `java.lang.Throwable'",
0a2138e2 10880 lang_printable_name (carg_type, 0));
b67d701b
PB
10881 error_found = 1;
10882 continue;
10883 }
10884
10885 /* Partial check for unreachable catch statement: The catch
10886 clause is reachable iff is no earlier catch block A in
10887 the try statement such that the type of the catch
10888 clause's parameter is the same as or a subclass of the
10889 type of A's parameter */
10890 unreachable = 0;
10891 for (sub_current = catch;
10892 sub_current != current; sub_current = TREE_CHAIN (sub_current))
10893 {
10894 tree sub_catch_clause, decl;
a7d8d81f 10895 sub_catch_clause = TREE_OPERAND (sub_current, 0);
b67d701b
PB
10896 decl = BLOCK_EXPR_DECLS (sub_catch_clause);
10897
10898 if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
10899 {
10900 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
10901 parse_error_context
10902 (wfl_operator, "`catch' not reached because of the catch "
10903 "clause at line %d", EXPR_WFL_LINENO (sub_current));
10904 unreachable = error_found = 1;
10905 break;
10906 }
10907 }
b67d701b
PB
10908 /* Complete the catch clause block */
10909 catch_block = java_complete_tree (TREE_OPERAND (current, 0));
10910 if (catch_block == error_mark_node)
10911 {
10912 error_found = 1;
10913 continue;
10914 }
15fdcfe9
PB
10915 if (CAN_COMPLETE_NORMALLY (catch_block))
10916 CAN_COMPLETE_NORMALLY (node) = 1;
b67d701b 10917 TREE_OPERAND (current, 0) = catch_block;
15fdcfe9
PB
10918
10919 if (unreachable)
10920 continue;
10921
10922 /* Things to do here: the exception must be thrown */
10923
10924 /* Link this type to the caught type list */
10925 caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
b67d701b
PB
10926 }
10927
b9f7e36c
APB
10928 PUSH_EXCEPTIONS (caught_type_list);
10929 if ((try = java_complete_tree (try)) == error_mark_node)
10930 error_found = 1;
15fdcfe9
PB
10931 if (CAN_COMPLETE_NORMALLY (try))
10932 CAN_COMPLETE_NORMALLY (node) = 1;
b9f7e36c
APB
10933 POP_EXCEPTIONS ();
10934
b67d701b
PB
10935 /* Verification ends here */
10936 if (error_found)
10937 return error_mark_node;
10938
10939 TREE_OPERAND (node, 0) = try;
10940 TREE_OPERAND (node, 1) = catch;
b67d701b
PB
10941 TREE_TYPE (node) = void_type_node;
10942 return node;
10943}
b9f7e36c
APB
10944
10945/* 14.17 The synchronized Statement */
10946
10947static tree
10948patch_synchronized_statement (node, wfl_op1)
10949 tree node, wfl_op1;
10950{
5a005d9e 10951 tree expr = java_complete_tree (TREE_OPERAND (node, 0));
b9f7e36c 10952 tree block = TREE_OPERAND (node, 1);
5a005d9e 10953
d8fccff5 10954 tree enter, exit, expr_decl, assignment;
5a005d9e
PB
10955
10956 if (expr == error_mark_node)
10957 {
10958 block = java_complete_tree (block);
10959 return expr;
10960 }
b9f7e36c
APB
10961
10962 /* The TYPE of expr must be a reference type */
5a005d9e 10963 if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
b9f7e36c
APB
10964 {
10965 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
10966 parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
10967 ". Can't convert `%s' to `java.lang.Object'",
0a2138e2 10968 lang_printable_name (TREE_TYPE (expr), 0));
b9f7e36c
APB
10969 return error_mark_node;
10970 }
10971
10972 /* Generate a try-finally for the synchronized statement, except
10973 that the handler that catches all throw exception calls
10974 _Jv_MonitorExit and then rethrow the exception.
10975 The synchronized statement is then implemented as:
10976 TRY
10977 {
10978 _Jv_MonitorEnter (expression)
10979 synchronized_block
10980 _Jv_MonitorExit (expression)
10981 }
10982 CATCH_ALL
10983 {
10984 e = _Jv_exception_info ();
10985 _Jv_MonitorExit (expression)
10986 Throw (e);
10987 } */
10988
5a005d9e
PB
10989 expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
10990 BUILD_MONITOR_ENTER (enter, expr_decl);
10991 BUILD_MONITOR_EXIT (exit, expr_decl);
10992 CAN_COMPLETE_NORMALLY (enter) = 1;
10993 CAN_COMPLETE_NORMALLY (exit) = 1;
96847892
AH
10994 assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
10995 TREE_SIDE_EFFECTS (assignment) = 1;
5a005d9e
PB
10996 node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
10997 build (COMPOUND_EXPR, NULL_TREE,
10998 build (WITH_CLEANUP_EXPR, NULL_TREE,
10999 build (COMPOUND_EXPR, NULL_TREE,
96847892 11000 assignment, enter),
5a005d9e
PB
11001 NULL_TREE, exit),
11002 block));
11003 node = build_expr_block (node, expr_decl);
11004
11005 return java_complete_tree (node);
b9f7e36c
APB
11006}
11007
11008/* 14.16 The throw Statement */
11009
11010static tree
11011patch_throw_statement (node, wfl_op1)
11012 tree node, wfl_op1;
11013{
11014 tree expr = TREE_OPERAND (node, 0);
11015 tree type = TREE_TYPE (expr);
11016 int unchecked_ok = 0, tryblock_throws_ok = 0;
11017
11018 /* Thrown expression must be assignable to java.lang.Throwable */
11019 if (!try_reference_assignconv (throwable_type_node, expr))
11020 {
11021 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11022 parse_error_context (wfl_operator, "Can't throw `%s'; it must be a "
11023 "subclass of class `java.lang.Throwable'",
0a2138e2 11024 lang_printable_name (type, 0));
b9f7e36c
APB
11025 /* If the thrown expression was a reference, we further the
11026 compile-time check. */
11027 if (!JREFERENCE_TYPE_P (type))
11028 return error_mark_node;
11029 }
11030
11031 /* At least one of the following must be true */
11032
11033 /* The type of the throw expression is a not checked exception,
11034 i.e. is a unchecked expression. */
c877974e 11035 unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
b9f7e36c
APB
11036
11037 /* Throw is contained in a try statement and at least one catch
11038 clause can receive the thrown expression or the current method is
11039 declared to throw such an exception. Or, the throw statement is
11040 contained in a method or constructor declaration and the type of
11041 the Expression is assignable to at least one type listed in the
11042 throws clause the declaration. */
11043 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11044 if (!unchecked_ok)
f099f336 11045 tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
b9f7e36c
APB
11046 if (!(unchecked_ok || tryblock_throws_ok))
11047 {
11048 /* If there is a surrounding try block that has no matching
11049 clatch clause, report it first. A surrounding try block exits
11050 only if there is something after the list of checked
11051 exception thrown by the current function (if any). */
11052 if (IN_TRY_BLOCK_P ())
11053 parse_error_context (wfl_operator, "Checked exception `%s' can't be "
11054 "caught by any of the catch clause(s) "
11055 "of the surrounding `try' block",
0a2138e2 11056 lang_printable_name (type, 0));
b9f7e36c
APB
11057 /* If we have no surrounding try statement and the method doesn't have
11058 any throws, report it now. FIXME */
f099f336
APB
11059
11060 /* We report that the exception can't be throw from a try block
11061 in all circumstances but when the `throw' is inside a static
11062 block. */
b9f7e36c
APB
11063 else if (!EXCEPTIONS_P (currently_caught_type_list)
11064 && !tryblock_throws_ok)
f099f336
APB
11065 {
11066 if (DECL_NAME (current_function_decl) == clinit_identifier_node)
11067 parse_error_context (wfl_operator, "Checked exception `%s' can't "
11068 "be thrown in initializer",
11069 lang_printable_name (type, 0));
11070 else
11071 parse_error_context (wfl_operator, "Checked exception `%s' isn't "
11072 "thrown from a `try' block",
11073 lang_printable_name (type, 0));
11074 }
b9f7e36c
APB
11075 /* Otherwise, the current method doesn't have the appropriate
11076 throws declaration */
11077 else
11078 parse_error_context (wfl_operator, "Checked exception `%s' doesn't "
11079 "match any of current method's `throws' "
11080 "declaration(s)",
0a2138e2 11081 lang_printable_name (type, 0));
b9f7e36c
APB
11082 return error_mark_node;
11083 }
11084
15fdcfe9
PB
11085 if (! flag_emit_class_files)
11086 BUILD_THROW (node, expr);
b9f7e36c
APB
11087 return node;
11088}
11089
11090/* Check that exception said to be thrown by method DECL can be
11091 effectively caught from where DECL is invoked. */
11092
11093static void
11094check_thrown_exceptions (location, decl)
11095 int location;
11096 tree decl;
11097{
11098 tree throws;
11099 /* For all the unchecked exceptions thrown by DECL */
11100 for (throws = DECL_FUNCTION_THROWS (decl); throws;
11101 throws = TREE_CHAIN (throws))
0a2138e2 11102 if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
b9f7e36c 11103 {
3e78f871
PB
11104#if 1
11105 /* Temporary hack to suppresses errors about cloning arrays. FIXME */
11106 if (DECL_NAME (decl) == get_identifier ("clone"))
11107 continue;
11108#endif
b9f7e36c
APB
11109 EXPR_WFL_LINECOL (wfl_operator) = location;
11110 parse_error_context
11111 (wfl_operator, "Exception `%s' must be caught, or it must be "
11112 "declared in the `throws' clause of `%s'",
0a2138e2 11113 lang_printable_name (TREE_VALUE (throws), 0),
b9f7e36c
APB
11114 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
11115 }
11116}
11117
c877974e 11118/* Return 1 if checked EXCEPTION is caught at the current nesting level of
b9f7e36c
APB
11119 try-catch blocks, OR is listed in the `throws' clause of the
11120 current method. */
11121
11122static int
0a2138e2 11123check_thrown_exceptions_do (exception)
b9f7e36c
APB
11124 tree exception;
11125{
11126 tree list = currently_caught_type_list;
c877974e 11127 resolve_and_layout (exception, NULL_TREE);
b9f7e36c
APB
11128 /* First, all the nested try-catch-finally at that stage. The
11129 last element contains `throws' clause exceptions, if any. */
c877974e
APB
11130 if (IS_UNCHECKED_EXCEPTION_P (exception))
11131 return 1;
b9f7e36c
APB
11132 while (list)
11133 {
11134 tree caught;
11135 for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
11136 if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
11137 return 1;
11138 list = TREE_CHAIN (list);
11139 }
11140 return 0;
11141}
11142
11143static void
11144purge_unchecked_exceptions (mdecl)
11145 tree mdecl;
11146{
11147 tree throws = DECL_FUNCTION_THROWS (mdecl);
11148 tree new = NULL_TREE;
11149
11150 while (throws)
11151 {
11152 tree next = TREE_CHAIN (throws);
c877974e 11153 if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
b9f7e36c
APB
11154 {
11155 TREE_CHAIN (throws) = new;
11156 new = throws;
11157 }
11158 throws = next;
11159 }
11160 /* List is inverted here, but it doesn't matter */
11161 DECL_FUNCTION_THROWS (mdecl) = new;
11162}
22eed1e6
APB
11163
11164/* 15.24 Conditional Operator ?: */
11165
11166static tree
11167patch_conditional_expr (node, wfl_cond, wfl_op1)
11168 tree node, wfl_cond, wfl_op1;
11169{
11170 tree cond = TREE_OPERAND (node, 0);
11171 tree op1 = TREE_OPERAND (node, 1);
11172 tree op2 = TREE_OPERAND (node, 2);
22eed1e6 11173 tree resulting_type = NULL_TREE;
ac825856 11174 tree t1, t2, patched;
22eed1e6
APB
11175 int error_found = 0;
11176
ac825856
APB
11177 /* Operands of ?: might be StringBuffers crafted as a result of a
11178 string concatenation. Obtain a descent operand here. */
11179 if ((patched = patch_string (op1)))
11180 TREE_OPERAND (node, 1) = op1 = patched;
11181 if ((patched = patch_string (op2)))
11182 TREE_OPERAND (node, 2) = op2 = patched;
11183
11184 t1 = TREE_TYPE (op1);
11185 t2 = TREE_TYPE (op2);
11186
22eed1e6
APB
11187 /* The first expression must be a boolean */
11188 if (TREE_TYPE (cond) != boolean_type_node)
11189 {
11190 SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
11191 parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
11192 "convert `%s' to `boolean'",
11193 lang_printable_name (TREE_TYPE (cond), 0));
11194 error_found = 1;
11195 }
11196
11197 /* Second and third can be numeric, boolean (i.e. primitive),
11198 references or null. Anything else results in an error */
11199 if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
11200 || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node)
11201 && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
11202 || (t1 == boolean_type_node && t2 == boolean_type_node)))
11203 error_found = 1;
11204
11205 /* Determine the type of the conditional expression. Same types are
11206 easy to deal with */
11207 else if (t1 == t2)
11208 resulting_type = t1;
11209
11210 /* There are different rules for numeric types */
11211 else if (JNUMERIC_TYPE_P (t1))
11212 {
11213 /* if byte/short found, the resulting type is short */
11214 if ((t1 == byte_type_node && t2 == short_type_node)
11215 || (t1 == short_type_node && t2 == byte_type_node))
11216 resulting_type = short_type_node;
11217
11218 /* If t1 is a constant int and t2 is of type byte, short or char
11219 and t1's value fits in t2, then the resulting type is t2 */
11220 else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
11221 && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
11222 resulting_type = t2;
11223
11224 /* If t2 is a constant int and t1 is of type byte, short or char
11225 and t2's value fits in t1, then the resulting type is t1 */
11226 else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
11227 && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
11228 resulting_type = t1;
11229
11230 /* Otherwise, binary numeric promotion is applied and the
11231 resulting type is the promoted type of operand 1 and 2 */
11232 else
11233 resulting_type = binary_numeric_promotion (t2, t2,
11234 &TREE_OPERAND (node, 1),
11235 &TREE_OPERAND (node, 2));
11236 }
11237
11238 /* Cases of a reference and a null type */
11239 else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
11240 resulting_type = t1;
11241
11242 else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
11243 resulting_type = t2;
11244
11245 /* Last case: different reference types. If a type can be converted
11246 into the other one by assignment conversion, the latter
11247 determines the type of the expression */
11248 else if ((resulting_type = try_reference_assignconv (t1, op2)))
11249 resulting_type = promote_type (t1);
11250
11251 else if ((resulting_type = try_reference_assignconv (t2, op1)))
11252 resulting_type = promote_type (t2);
11253
11254 /* If we don't have any resulting type, we're in trouble */
11255 if (!resulting_type)
11256 {
11257 char *t = strdup (lang_printable_name (t1, 0));
11258 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11259 parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
11260 "convert `%s' to `%s'", t,
11261 lang_printable_name (t2, 0));
11262 free (t);
11263 error_found = 1;
11264 }
11265
11266 if (error_found)
11267 {
11268 TREE_TYPE (node) = error_mark_node;
11269 return error_mark_node;
11270 }
11271
11272 TREE_TYPE (node) = resulting_type;
11273 TREE_SET_CODE (node, COND_EXPR);
15fdcfe9 11274 CAN_COMPLETE_NORMALLY (node) = 1;
22eed1e6
APB
11275 return node;
11276}
ac825856 11277
5b09b33e
PB
11278/* Try to constant fold NODE.
11279 If NODE is not a constant expression, return NULL_EXPR.
11280 CONTEXT is a static final VAR_DECL whose initializer we are folding. */
11281
11282static tree
11283fold_constant_for_init (node, context)
11284 tree node;
11285 tree context;
11286{
11287 tree op0, op1, val;
11288 enum tree_code code = TREE_CODE (node);
11289
11290 if (code == INTEGER_CST || code == REAL_CST || code == STRING_CST)
11291 return node;
11292 if (TREE_TYPE (node) != NULL_TREE)
11293 return NULL_TREE;
11294
11295 switch (code)
11296 {
5b09b33e
PB
11297 case PLUS_EXPR:
11298 case MINUS_EXPR:
bc3ca41b
PB
11299 case MULT_EXPR:
11300 case TRUNC_MOD_EXPR:
11301 case RDIV_EXPR:
5b09b33e
PB
11302 case LSHIFT_EXPR:
11303 case RSHIFT_EXPR:
11304 case URSHIFT_EXPR:
11305 case BIT_AND_EXPR:
11306 case BIT_XOR_EXPR:
11307 case BIT_IOR_EXPR:
5b09b33e
PB
11308 case TRUTH_ANDIF_EXPR:
11309 case TRUTH_ORIF_EXPR:
11310 case EQ_EXPR:
11311 case NE_EXPR:
11312 case GT_EXPR:
11313 case GE_EXPR:
11314 case LT_EXPR:
11315 case LE_EXPR:
11316 op0 = TREE_OPERAND (node, 0);
11317 op1 = TREE_OPERAND (node, 1);
11318 val = fold_constant_for_init (op0, context);
11319 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11320 return NULL_TREE;
11321 TREE_OPERAND (node, 0) = val;
11322 val = fold_constant_for_init (op1, context);
11323 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11324 return NULL_TREE;
11325 TREE_OPERAND (node, 1) = val;
11326 return patch_binop (node, op0, op1);
11327
11328 case UNARY_PLUS_EXPR:
11329 case NEGATE_EXPR:
11330 case TRUTH_NOT_EXPR:
11331 case BIT_NOT_EXPR:
11332 case CONVERT_EXPR:
11333 op0 = TREE_OPERAND (node, 0);
11334 val = fold_constant_for_init (op0, context);
11335 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11336 return NULL_TREE;
11337 TREE_OPERAND (node, 0) = val;
5a005d9e 11338 return patch_unaryop (node, op0);
5b09b33e
PB
11339 break;
11340
11341 case COND_EXPR:
11342 val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
11343 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11344 return NULL_TREE;
11345 TREE_OPERAND (node, 0) = val;
11346 val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
11347 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11348 return NULL_TREE;
11349 TREE_OPERAND (node, 1) = val;
11350 val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
11351 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11352 return NULL_TREE;
11353 TREE_OPERAND (node, 2) = val;
11354 return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
11355 : TREE_OPERAND (node, 2);
11356
11357 case VAR_DECL:
11358 if (! FIELD_STATIC (node) || ! FIELD_FINAL (node)
11359 || DECL_INITIAL (node) == NULL_TREE)
11360 return NULL_TREE;
11361 val = DECL_INITIAL (node);
11362 /* Guard against infinite recursion. */
11363 DECL_INITIAL (node) = NULL_TREE;
11364 val = fold_constant_for_init (val, DECL_CONTEXT (node));
11365 DECL_INITIAL (node) = val;
11366 return val;
11367
11368 case EXPR_WITH_FILE_LOCATION:
11369 /* Compare java_complete_tree and resolve_expression_name. */
11370 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11371 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11372 {
11373 tree name = EXPR_WFL_NODE (node);
11374 tree decl;
11375 if (PRIMARY_P (node))
11376 return NULL_TREE;
11377 else if (! QUALIFIED_P (name))
11378 {
11379 decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
11380 if (! FIELD_STATIC (decl))
11381 return NULL_TREE;
11382 return fold_constant_for_init (decl, decl);
11383 }
11384 else
11385 {
11386#if 0
11387 /* Wait until the USE_COMPONENT_REF re-write. FIXME. */
11388 qualify_ambiguous_name (node);
11389 if (resolve_field_access (node, &decl, NULL)
11390 && decl != NULL_TREE)
11391 return fold_constant_for_init (decl, decl);
11392#endif
11393 return NULL_TREE;
11394 }
11395 }
11396 else
11397 {
11398 op0 = TREE_OPERAND (node, 0);
11399 val = fold_constant_for_init (op0, context);
11400 if (val == NULL_TREE || ! TREE_CONSTANT (val))
11401 return NULL_TREE;
11402 TREE_OPERAND (node, 0) = val;
11403 return val;
11404 }
11405
bc3ca41b
PB
11406#ifdef USE_COMPONENT_REF
11407 case IDENTIFIER:
11408 case COMPONENT_REF:
11409 ?;
11410#endif
11411
5b09b33e
PB
11412 default:
11413 return NULL_TREE;
11414 }
11415}
bc3ca41b
PB
11416
11417#ifdef USE_COMPONENT_REF
11418/* Context is 'T' for TypeName, 'P' for PackageName,
11419 'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
11420
11421tree
11422resolve_simple_name (name, context)
11423 tree name;
11424 int context;
11425{
11426}
11427
11428tree
11429resolve_qualified_name (name, context)
11430 tree name;
11431 int context;
11432{
11433}
11434#endif
This page took 1.555155 seconds and 5 git commands to generate.