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