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