OSDN Git Service

2001-07-03 Alexandre Petit-Bianco <apbianco@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / parse.y
1 /* Source code parsing and tree node generation for the GNU compiler
2    for the Java(TM) language.
3    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
26
27 /* This file parses java source code and issues a tree node image
28 suitable for code generation (byte code and targeted CPU assembly
29 language).
30
31 The grammar conforms to the Java grammar described in "The Java(TM)
32 Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
33 1996, ISBN 0-201-63451-1"
34
35 The following modifications were brought to the original grammar:
36
37 method_body: added the rule '| block SC_TK'
38 static_initializer: added the rule 'static block SC_TK'. 
39
40 Note: All the extra rules described above should go away when the
41       empty_statement rule will work.
42
43 statement_nsi: 'nsi' should be read no_short_if.
44
45 Some rules have been modified to support JDK1.1 inner classes
46 definitions and other extensions.  */
47
48 %{
49 #include "config.h"
50 #include "system.h"
51 #include <dirent.h>
52 #include "tree.h"
53 #include "rtl.h"
54 #include "obstack.h"
55 #include "toplev.h"
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"
62 #include "convert.h"
63 #include "buffer.h"
64 #include "xref.h"
65 #include "function.h"
66 #include "except.h"
67 #include "ggc.h"
68
69 #ifndef DIR_SEPARATOR
70 #define DIR_SEPARATOR '/'
71 #endif
72
73 /* Local function prototypes */
74 static char *java_accstring_lookup PARAMS ((int));
75 static void  classitf_redefinition_error PARAMS ((const char *,tree, tree, tree));
76 static void  variable_redefinition_error PARAMS ((tree, tree, tree, int));
77 static tree  create_class PARAMS ((int, tree, tree, tree));
78 static tree  create_interface PARAMS ((int, tree, tree));
79 static void  end_class_declaration PARAMS ((int));
80 static tree  find_field PARAMS ((tree, tree));
81 static tree lookup_field_wrapper PARAMS ((tree, tree));
82 static int   duplicate_declaration_error_p PARAMS ((tree, tree, tree));
83 static void  register_fields PARAMS ((int, tree, tree));
84 static tree parser_qualified_classname PARAMS ((tree));
85 static int  parser_check_super PARAMS ((tree, tree, tree));
86 static int  parser_check_super_interface PARAMS ((tree, tree, tree));
87 static void check_modifiers_consistency PARAMS ((int));
88 static tree lookup_cl PARAMS ((tree));
89 static tree lookup_java_method2 PARAMS ((tree, tree, int));
90 static tree method_header PARAMS ((int, tree, tree, tree));
91 static void fix_method_argument_names PARAMS ((tree ,tree));
92 static tree method_declarator PARAMS ((tree, tree));
93 static void parse_warning_context PARAMS ((tree cl, const char *msg, ...))
94   ATTRIBUTE_PRINTF_2;
95 static void issue_warning_error_from_context PARAMS ((tree, const char *msg, va_list))
96   ATTRIBUTE_PRINTF (2, 0);
97 static void parse_ctor_invocation_error PARAMS ((void));
98 static tree parse_jdk1_1_error PARAMS ((const char *));
99 static void complete_class_report_errors PARAMS ((jdep *));
100 static int process_imports PARAMS ((void));
101 static void read_import_dir PARAMS ((tree));
102 static int find_in_imports_on_demand PARAMS ((tree));
103 static void find_in_imports PARAMS ((tree));
104 static void check_static_final_variable_assignment_flag PARAMS ((tree));
105 static void reset_static_final_variable_assignment_flag PARAMS ((tree));
106 static void check_final_variable_local_assignment_flag PARAMS ((tree, tree));
107 static void reset_final_variable_local_assignment_flag PARAMS ((tree));
108 static int  check_final_variable_indirect_assignment PARAMS ((tree));
109 static void check_final_variable_global_assignment_flag PARAMS ((tree));
110 static void check_inner_class_access PARAMS ((tree, tree, tree));
111 static int check_pkg_class_access PARAMS ((tree, tree));
112 static void register_package PARAMS ((tree));
113 static tree resolve_package PARAMS ((tree, tree *));
114 static tree lookup_package_type PARAMS ((const char *, int));
115 static tree resolve_class PARAMS ((tree, tree, tree, tree));
116 static void declare_local_variables PARAMS ((int, tree, tree));
117 static void source_start_java_method PARAMS ((tree));
118 static void source_end_java_method PARAMS ((void));
119 static tree find_name_in_single_imports PARAMS ((tree));
120 static void check_abstract_method_header PARAMS ((tree));
121 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
122 static tree resolve_expression_name PARAMS ((tree, tree *));
123 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
124 static int check_class_interface_creation PARAMS ((int, int, tree, 
125                                                   tree, tree, tree));
126 static tree patch_method_invocation PARAMS ((tree, tree, tree, int,
127                                             int *, tree *));
128 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
129 static int in_same_package PARAMS ((tree, tree));
130 static tree resolve_and_layout PARAMS ((tree, tree));
131 static tree qualify_and_find PARAMS ((tree, tree, tree));
132 static tree resolve_no_layout PARAMS ((tree, tree));
133 static int invocation_mode PARAMS ((tree, int));
134 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
135                                                             tree, tree));
136 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
137                                                    tree *, tree *));
138 static tree find_most_specific_methods_list PARAMS ((tree));
139 static int argument_types_convertible PARAMS ((tree, tree));
140 static tree patch_invoke PARAMS ((tree, tree, tree));
141 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
142 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
143 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
144 static tree obtain_incomplete_type PARAMS ((tree));
145 static tree java_complete_lhs PARAMS ((tree));
146 static tree java_complete_tree PARAMS ((tree));
147 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
148 static int analyze_clinit_body PARAMS ((tree));
149 static int maybe_yank_clinit PARAMS ((tree));
150 static void java_complete_expand_method PARAMS ((tree));
151 static int  unresolved_type_p PARAMS ((tree, tree *));
152 static void create_jdep_list PARAMS ((struct parser_ctxt *));
153 static tree build_expr_block PARAMS ((tree, tree));
154 static tree enter_block PARAMS ((void));
155 static tree exit_block PARAMS ((void));
156 static tree lookup_name_in_blocks PARAMS ((tree));
157 static void maybe_absorb_scoping_blocks PARAMS ((void));
158 static tree build_method_invocation PARAMS ((tree, tree));
159 static tree build_new_invocation PARAMS ((tree, tree));
160 static tree build_assignment PARAMS ((int, int, tree, tree));
161 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
162 static int check_final_assignment PARAMS ((tree ,tree));
163 static tree patch_assignment PARAMS ((tree, tree, tree ));
164 static tree patch_binop PARAMS ((tree, tree, tree));
165 static tree build_unaryop PARAMS ((int, int, tree));
166 static tree build_incdec PARAMS ((int, int, tree, int));
167 static tree patch_unaryop PARAMS ((tree, tree));
168 static tree build_cast PARAMS ((int, tree, tree));
169 static tree build_null_of_type PARAMS ((tree));
170 static tree patch_cast PARAMS ((tree, tree));
171 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
172 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
173 static int valid_cast_to_p PARAMS ((tree, tree));
174 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
175 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
176 static tree try_reference_assignconv PARAMS ((tree, tree));
177 static tree build_unresolved_array_type PARAMS ((tree));
178 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
179 static tree build_array_ref PARAMS ((int, tree, tree));
180 static tree patch_array_ref PARAMS ((tree));
181 static tree make_qualified_name PARAMS ((tree, tree, int));
182 static tree merge_qualified_name PARAMS ((tree, tree));
183 static tree make_qualified_primary PARAMS ((tree, tree, int));
184 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
185                                                      tree *, tree *));
186 static void qualify_ambiguous_name PARAMS ((tree));
187 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
188 static tree build_newarray_node PARAMS ((tree, tree, int));
189 static tree patch_newarray PARAMS ((tree));
190 static tree resolve_type_during_patch PARAMS ((tree));
191 static tree build_this PARAMS ((int));
192 static tree build_wfl_wrap PARAMS ((tree, int));
193 static tree build_return PARAMS ((int, tree));
194 static tree patch_return PARAMS ((tree));
195 static tree maybe_access_field PARAMS ((tree, tree, tree));
196 static int complete_function_arguments PARAMS ((tree));
197 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
198                                                       tree, tree));
199 static int not_accessible_p PARAMS ((tree, tree, tree, int));
200 static void check_deprecation PARAMS ((tree, tree));
201 static int class_in_current_package PARAMS ((tree));
202 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
203 static tree patch_if_else_statement PARAMS ((tree));
204 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
205 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
206 static tree patch_exit_expr PARAMS ((tree));
207 static tree build_labeled_block PARAMS ((int, tree));
208 static tree finish_labeled_statement PARAMS ((tree, tree));
209 static tree build_bc_statement PARAMS ((int, int, tree));
210 static tree patch_bc_statement PARAMS ((tree));
211 static tree patch_loop_statement PARAMS ((tree));
212 static tree build_new_loop PARAMS ((tree));
213 static tree build_loop_body PARAMS ((int, tree, int));
214 static tree finish_loop_body PARAMS ((int, tree, tree, int));
215 static tree build_debugable_stmt PARAMS ((int, tree));
216 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
217 static tree patch_switch_statement PARAMS ((tree));
218 static tree string_constant_concatenation PARAMS ((tree, tree));
219 static tree build_string_concatenation PARAMS ((tree, tree));
220 static tree patch_string_cst PARAMS ((tree));
221 static tree patch_string PARAMS ((tree));
222 static tree build_try_statement PARAMS ((int, tree, tree));
223 static tree build_try_finally_statement PARAMS ((int, tree, tree));
224 static tree patch_try_statement PARAMS ((tree));
225 static tree patch_synchronized_statement PARAMS ((tree, tree));
226 static tree patch_throw_statement PARAMS ((tree, tree));
227 static void check_thrown_exceptions PARAMS ((int, tree));
228 static int check_thrown_exceptions_do PARAMS ((tree));
229 static void purge_unchecked_exceptions PARAMS ((tree));
230 static void check_throws_clauses PARAMS ((tree, tree, tree));
231 static void finish_method_declaration PARAMS ((tree));
232 static tree build_super_invocation PARAMS ((tree));
233 static int verify_constructor_circularity PARAMS ((tree, tree));
234 static char *constructor_circularity_msg PARAMS ((tree, tree));
235 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
236                                                           int, int));
237 static const char *get_printable_method_name PARAMS ((tree));
238 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
239 static tree generate_finit PARAMS ((tree));
240 static void add_instance_initializer PARAMS ((tree));
241 static tree build_instance_initializer PARAMS ((tree));
242 static void fix_constructors PARAMS ((tree));
243 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
244                                                             tree, int *));
245 static void craft_constructor PARAMS ((tree, tree));
246 static int verify_constructor_super PARAMS ((tree));
247 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
248 static void start_artificial_method_body PARAMS ((tree));
249 static void end_artificial_method_body PARAMS ((tree));
250 static int check_method_redefinition PARAMS ((tree, tree));
251 static int check_method_types_complete PARAMS ((tree));
252 static void java_check_regular_methods PARAMS ((tree));
253 static void java_check_abstract_methods PARAMS ((tree));
254 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
255 static void unreachable_stmt_error PARAMS ((tree));
256 static tree find_expr_with_wfl PARAMS ((tree));
257 static void missing_return_error PARAMS ((tree));
258 static tree build_new_array_init PARAMS ((int, tree));
259 static tree patch_new_array_init PARAMS ((tree, tree));
260 static tree maybe_build_array_element_wfl PARAMS ((tree));
261 static int array_constructor_check_entry PARAMS ((tree, tree));
262 static const char *purify_type_name PARAMS ((const char *));
263 static tree fold_constant_for_init PARAMS ((tree, tree));
264 static tree strip_out_static_field_access_decl PARAMS ((tree));
265 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
266 static void static_ref_err PARAMS ((tree, tree, tree));
267 static void parser_add_interface PARAMS ((tree, tree, tree));
268 static void add_superinterfaces PARAMS ((tree, tree));
269 static tree jdep_resolve_class PARAMS ((jdep *));
270 static int note_possible_classname PARAMS ((const char *, int));
271 static void java_complete_expand_classes PARAMS ((void));
272 static void java_complete_expand_class PARAMS ((tree));
273 static void java_complete_expand_methods PARAMS ((tree));
274 static tree cut_identifier_in_qualified PARAMS ((tree));
275 static tree java_stabilize_reference PARAMS ((tree));
276 static tree do_unary_numeric_promotion PARAMS ((tree));
277 static char * operator_string PARAMS ((tree));
278 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
279 static tree merge_string_cste PARAMS ((tree, tree, int));
280 static tree java_refold PARAMS ((tree));
281 static int java_decl_equiv PARAMS ((tree, tree));
282 static int binop_compound_p PARAMS ((enum tree_code));
283 static tree search_loop PARAMS ((tree));
284 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
285 static int check_abstract_method_definitions PARAMS ((int, tree, tree));
286 static void java_check_abstract_method_definitions PARAMS ((tree));
287 static void java_debug_context_do PARAMS ((int));
288 static void java_parser_context_push_initialized_field PARAMS ((void));
289 static void java_parser_context_pop_initialized_field PARAMS ((void));
290 static tree reorder_static_initialized PARAMS ((tree));
291 static void java_parser_context_suspend PARAMS ((void));
292 static void java_parser_context_resume PARAMS ((void));
293 static int pop_current_osb PARAMS ((struct parser_ctxt *));
294
295 /* JDK 1.1 work. FIXME */
296
297 static tree maybe_make_nested_class_name PARAMS ((tree));
298 static void make_nested_class_name PARAMS ((tree));
299 static void set_nested_class_simple_name_value PARAMS ((tree, int));
300 static void link_nested_class_to_enclosing PARAMS ((void));
301 static tree find_as_inner_class PARAMS ((tree, tree, tree));
302 static tree find_as_inner_class_do PARAMS ((tree, tree));
303 static int check_inner_class_redefinition PARAMS ((tree, tree));
304
305 static tree build_thisn_assign PARAMS ((void));
306 static tree build_current_thisn PARAMS ((tree));
307 static tree build_access_to_thisn PARAMS ((tree, tree, int));
308 static tree maybe_build_thisn_access_method PARAMS ((tree));
309
310 static tree build_outer_field_access PARAMS ((tree, tree));
311 static tree build_outer_field_access_methods PARAMS ((tree));
312 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
313                                                   tree, tree));
314 static tree build_outer_method_access_method PARAMS ((tree));
315 static tree build_new_access_id PARAMS ((void));
316 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
317                                                     tree, tree));
318
319 static int outer_field_access_p PARAMS ((tree, tree));
320 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
321                                                  tree *, tree *));
322 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
323 static tree build_incomplete_class_ref PARAMS ((int, tree));
324 static tree patch_incomplete_class_ref PARAMS ((tree));
325 static tree create_anonymous_class PARAMS ((int, tree));
326 static void patch_anonymous_class PARAMS ((tree, tree, tree));
327 static void add_inner_class_fields PARAMS ((tree, tree));
328
329 static tree build_dot_class_method PARAMS ((tree));
330 static tree build_dot_class_method_invocation PARAMS ((tree));
331 static void create_new_parser_context PARAMS ((int));
332 static void mark_parser_ctxt PARAMS ((void *));
333 static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
334
335 /* Number of error found so far. */
336 int java_error_count; 
337 /* Number of warning found so far. */
338 int java_warning_count;
339 /* Tell when not to fold, when doing xrefs */
340 int do_not_fold;
341 /* Cyclic inheritance report, as it can be set by layout_class */
342 const char *cyclic_inheritance_report;
343  
344 /* Tell when we're within an instance initializer */
345 static int in_instance_initializer;
346
347 /* The current parser context */
348 struct parser_ctxt *ctxp;
349
350 /* List of things that were analyzed for which code will be generated */
351 struct parser_ctxt *ctxp_for_generation = NULL;
352
353 /* binop_lookup maps token to tree_code. It is used where binary
354    operations are involved and required by the parser. RDIV_EXPR
355    covers both integral/floating point division. The code is changed
356    once the type of both operator is worked out.  */
357
358 static enum tree_code binop_lookup[19] = 
359   { 
360     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
361     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
362     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
363     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
364     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
365    };
366 #define BINOP_LOOKUP(VALUE)                                             \
367   binop_lookup [((VALUE) - PLUS_TK) % ARRAY_SIZE (binop_lookup)]
368
369 /* This is the end index for binary operators that can also be used
370    in compound assignements. */
371 #define BINOP_COMPOUND_CANDIDATES 11
372
373 /* The "$L" identifier we use to create labels.  */
374 static tree label_id = NULL_TREE;
375
376 /* The "StringBuffer" identifier used for the String `+' operator. */
377 static tree wfl_string_buffer = NULL_TREE; 
378
379 /* The "append" identifier used for String `+' operator.  */
380 static tree wfl_append = NULL_TREE;
381
382 /* The "toString" identifier used for String `+' operator. */
383 static tree wfl_to_string = NULL_TREE;
384
385 /* The "java.lang" import qualified name.  */
386 static tree java_lang_id = NULL_TREE;
387
388 /* The generated `inst$' identifier used for generated enclosing
389    instance/field access functions.  */
390 static tree inst_id = NULL_TREE;
391
392 /* The "java.lang.Cloneable" qualified name.  */
393 static tree java_lang_cloneable = NULL_TREE;
394
395 /* The "java.io.Serializable" qualified name.  */
396 static tree java_io_serializable = NULL_TREE; 
397
398 /* Context and flag for static blocks */
399 static tree current_static_block = NULL_TREE;
400
401 /* The generated `write_parm_value$' identifier.  */
402 static tree wpv_id;
403
404 /* The list of all packages we've seen so far */
405 static tree package_list = NULL_TREE;
406  
407 /* Hold THIS for the scope of the current public method decl.  */
408 static tree current_this;
409
410 /* Hold a list of catch clauses list. The first element of this list is
411    the list of the catch clauses of the currently analysed try block. */
412 static tree currently_caught_type_list;
413
414 static tree src_parse_roots[1] = { NULL_TREE };
415
416 /* All classes seen from source code */
417 #define gclass_list src_parse_roots[0]
418
419 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
420    line and point it out.  */
421 /* Should point out the one that don't fit. ASCII/unicode, going
422    backward. FIXME */
423
424 #define check_modifiers(__message, __value, __mask) do {        \
425   if ((__value) & ~(__mask))                                    \
426     {                                                           \
427       int i, remainder = (__value) & ~(__mask);                 \
428       for (i = 0; i <= 10; i++)                                 \
429         if ((1 << i) & remainder)                               \
430           parse_error_context (ctxp->modifier_ctx [i], (__message), \
431                                java_accstring_lookup (1 << i)); \
432     }                                                           \
433 } while (0)
434
435 %}
436
437 %union {
438   tree node;
439   int sub_token;
440   struct {
441     int token;
442     int location;
443   } operator;
444   int value;
445 }
446
447 %{
448 #include "lex.c"
449 %}
450
451 %pure_parser
452
453 /* Things defined here have to match the order of what's in the
454    binop_lookup table.  */
455
456 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
457 %token   LS_TK           SRS_TK          ZRS_TK
458 %token   AND_TK          XOR_TK          OR_TK
459 %token   BOOL_AND_TK BOOL_OR_TK 
460 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
461
462 /* This maps to the same binop_lookup entry than the token above */
463
464 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
465 %token   REM_ASSIGN_TK   
466 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
467 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
468
469
470 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
471
472 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
473 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
474 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
475 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
476 %token   STRICT_TK
477
478 /* Keep those two in order, too */
479 %token   DECR_TK INCR_TK
480
481 /* From now one, things can be in any order */
482
483 %token   DEFAULT_TK      IF_TK              THROW_TK
484 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
485 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
486 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
487 %token   VOID_TK         CATCH_TK           INTERFACE_TK
488 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
489 %token   SUPER_TK        WHILE_TK           CLASS_TK
490 %token   SWITCH_TK       CONST_TK           TRY_TK
491 %token   FOR_TK          NEW_TK             CONTINUE_TK
492 %token   GOTO_TK         PACKAGE_TK         THIS_TK
493
494 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
495 %token   CHAR_TK         INTEGRAL_TK
496
497 %token   FLOAT_TK        DOUBLE_TK          FP_TK
498
499 %token   ID_TK
500
501 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
502
503 %token   ASSIGN_ANY_TK   ASSIGN_TK
504 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
505
506 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
507 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
508
509 %type    <value>        modifiers MODIFIER_TK final synchronized
510
511 %type    <node>         super ID_TK identifier
512 %type    <node>         name simple_name qualified_name
513 %type    <node>         type_declaration compilation_unit
514                         field_declaration method_declaration extends_interfaces
515                         interfaces interface_type_list
516                         class_member_declaration
517                         import_declarations package_declaration 
518                         type_declarations interface_body
519                         interface_member_declaration constant_declaration
520                         interface_member_declarations interface_type
521                         abstract_method_declaration interface_type_list
522 %type    <node>         class_body_declaration class_member_declaration
523                         static_initializer constructor_declaration block
524 %type    <node>         class_body_declarations constructor_header
525 %type    <node>         class_or_interface_type class_type class_type_list
526                         constructor_declarator explicit_constructor_invocation
527 %type    <node>         dim_expr dim_exprs this_or_super throws
528
529 %type    <node>         variable_declarator_id variable_declarator
530                         variable_declarators variable_initializer
531                         variable_initializers constructor_body
532                         array_initializer
533
534 %type    <node>         class_body block_end constructor_block_end
535 %type    <node>         statement statement_without_trailing_substatement
536                         labeled_statement if_then_statement label_decl
537                         if_then_else_statement while_statement for_statement
538                         statement_nsi labeled_statement_nsi do_statement
539                         if_then_else_statement_nsi while_statement_nsi
540                         for_statement_nsi statement_expression_list for_init
541                         for_update statement_expression expression_statement
542                         primary_no_new_array expression primary
543                         array_creation_expression array_type
544                         class_instance_creation_expression field_access
545                         method_invocation array_access something_dot_new
546                         argument_list postfix_expression while_expression 
547                         post_increment_expression post_decrement_expression
548                         unary_expression_not_plus_minus unary_expression
549                         pre_increment_expression pre_decrement_expression
550                         unary_expression_not_plus_minus cast_expression
551                         multiplicative_expression additive_expression
552                         shift_expression relational_expression 
553                         equality_expression and_expression 
554                         exclusive_or_expression inclusive_or_expression
555                         conditional_and_expression conditional_or_expression
556                         conditional_expression assignment_expression
557                         left_hand_side assignment for_header for_begin
558                         constant_expression do_statement_begin empty_statement
559                         switch_statement synchronized_statement throw_statement
560                         try_statement switch_expression switch_block
561                         catches catch_clause catch_clause_parameter finally
562                         anonymous_class_creation
563 %type    <node>         return_statement break_statement continue_statement
564
565 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
566 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
567 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
568 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
569 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
570 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
571 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
572 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
573 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
574 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
575 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
576 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
577 %type    <operator>     NEW_TK
578
579 %type    <node>         method_body 
580         
581 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
582                         STRING_LIT_TK NULL_TK VOID_TK
583
584 %type    <node>         IF_TK WHILE_TK FOR_TK
585
586 %type    <node>         formal_parameter_list formal_parameter
587                         method_declarator method_header
588
589 %type    <node>         primitive_type reference_type type 
590                         BOOLEAN_TK INTEGRAL_TK FP_TK
591
592 /* Added or modified JDK 1.1 rule types  */
593 %type    <node>         type_literals
594
595 %%
596 /* 19.2 Production from 2.3: The Syntactic Grammar  */
597 goal:
598                 {
599                   /* Register static variables with the garbage
600                      collector.  */
601                   ggc_add_tree_root (&label_id, 1);
602                   ggc_add_tree_root (&wfl_string_buffer, 1);
603                   ggc_add_tree_root (&wfl_append, 1);
604                   ggc_add_tree_root (&wfl_to_string, 1);
605                   ggc_add_tree_root (&java_lang_id, 1);
606                   ggc_add_tree_root (&inst_id, 1);
607                   ggc_add_tree_root (&java_lang_cloneable, 1);
608                   ggc_add_tree_root (&java_io_serializable, 1);
609                   ggc_add_tree_root (&current_static_block, 1);
610                   ggc_add_tree_root (&wpv_id, 1);
611                   ggc_add_tree_root (&package_list, 1);
612                   ggc_add_tree_root (&current_this, 1);
613                   ggc_add_tree_root (&currently_caught_type_list, 1);
614                   ggc_add_root (&ctxp, 1, 
615                                 sizeof (struct parser_ctxt *),
616                                 mark_parser_ctxt);
617                   ggc_add_root (&ctxp_for_generation, 1, 
618                                 sizeof (struct parser_ctxt *),
619                                 mark_parser_ctxt);
620                 }
621         compilation_unit
622                 {}
623 ;
624
625 /* 19.3 Productions from 3: Lexical structure  */
626 literal:
627         INT_LIT_TK
628 |       FP_LIT_TK
629 |       BOOL_LIT_TK
630 |       CHAR_LIT_TK
631 |       STRING_LIT_TK
632 |       NULL_TK
633 ;
634
635 /* 19.4 Productions from 4: Types, Values and Variables  */
636 type:
637         primitive_type
638 |       reference_type
639 ;
640
641 primitive_type:
642         INTEGRAL_TK
643 |       FP_TK
644 |       BOOLEAN_TK
645 ;
646
647 reference_type:
648         class_or_interface_type
649 |       array_type
650 ;
651
652 class_or_interface_type:
653         name
654 ;
655
656 class_type:
657         class_or_interface_type /* Default rule */
658 ;
659
660 interface_type:
661          class_or_interface_type
662 ;
663
664 array_type:
665         primitive_type dims
666                 { 
667                   int osb = pop_current_osb (ctxp);
668                   tree t = build_java_array_type (($1), -1);
669                   while (--osb)
670                     t = build_unresolved_array_type (t);
671                   $$ = t;
672                 }
673 |       name dims
674                 { 
675                   int osb = pop_current_osb (ctxp);
676                   tree t = $1;
677                   while (osb--)
678                     t = build_unresolved_array_type (t);
679                   $$ = t;
680                 }
681 ;
682
683 /* 19.5 Productions from 6: Names  */
684 name:
685         simple_name             /* Default rule */
686 |       qualified_name          /* Default rule */
687 ;
688
689 simple_name:
690         identifier              /* Default rule */
691 ;
692
693 qualified_name:
694         name DOT_TK identifier
695                 { $$ = make_qualified_name ($1, $3, $2.location); }
696 ;
697
698 identifier:
699         ID_TK
700 ;
701
702 /* 19.6: Production from 7: Packages  */
703 compilation_unit:
704                 {$$ = NULL;}
705 |       package_declaration
706 |       import_declarations
707 |       type_declarations
708 |       package_declaration import_declarations
709 |       package_declaration type_declarations
710 |       import_declarations type_declarations
711 |       package_declaration import_declarations type_declarations
712 ;
713
714 import_declarations:
715         import_declaration
716                 {
717                   $$ = NULL;
718                 }
719 |       import_declarations import_declaration
720                 {
721                   $$ = NULL;
722                 }
723 ;
724
725 type_declarations:
726         type_declaration
727 |       type_declarations type_declaration
728 ;
729
730 package_declaration:
731         PACKAGE_TK name SC_TK
732                 { 
733                   ctxp->package = EXPR_WFL_NODE ($2);
734                   register_package (ctxp->package);
735                 }
736 |       PACKAGE_TK error
737                 {yyerror ("Missing name"); RECOVER;}
738 |       PACKAGE_TK name error
739                 {yyerror ("';' expected"); RECOVER;}
740 ;
741
742 import_declaration:
743         single_type_import_declaration
744 |       type_import_on_demand_declaration
745 ;
746
747 single_type_import_declaration:
748         IMPORT_TK name SC_TK
749                 {
750                   tree name = EXPR_WFL_NODE ($2), last_name;
751                   int   i = IDENTIFIER_LENGTH (name)-1;
752                   const char *last = &IDENTIFIER_POINTER (name)[i];
753                   while (last != IDENTIFIER_POINTER (name))
754                     {
755                       if (last [0] == '.')
756                         break;
757                       last--;
758                     }
759                   last_name = get_identifier (++last);
760                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
761                     {
762                       tree err = find_name_in_single_imports (last_name);
763                       if (err && err != name)
764                         parse_error_context
765                           ($2, "Ambiguous class: `%s' and `%s'",
766                            IDENTIFIER_POINTER (name), 
767                            IDENTIFIER_POINTER (err));
768                       else
769                         REGISTER_IMPORT ($2, last_name);
770                     }
771                   else
772                     REGISTER_IMPORT ($2, last_name);
773                 }
774 |       IMPORT_TK error
775                 {yyerror ("Missing name"); RECOVER;}
776 |       IMPORT_TK name error
777                 {yyerror ("';' expected"); RECOVER;}
778 ;
779
780 type_import_on_demand_declaration:
781         IMPORT_TK name DOT_TK MULT_TK SC_TK
782                 {
783                   tree name = EXPR_WFL_NODE ($2);
784                   tree it;
785                   /* Search for duplicates. */
786                   for (it = ctxp->import_demand_list; it; it = TREE_CHAIN (it))
787                     if (EXPR_WFL_NODE (TREE_PURPOSE (it)) == name)
788                       break;
789                   /* Don't import the same thing more than once, just ignore
790                      duplicates (7.5.2) */
791                   if (! it)
792                     {
793                       read_import_dir ($2);
794                       ctxp->import_demand_list = 
795                         chainon (ctxp->import_demand_list,
796                                  build_tree_list ($2, NULL_TREE));
797                     }
798                 }
799 |       IMPORT_TK name DOT_TK error
800                 {yyerror ("'*' expected"); RECOVER;}
801 |       IMPORT_TK name DOT_TK MULT_TK error
802                 {yyerror ("';' expected"); RECOVER;}
803 ;
804
805 type_declaration:
806         class_declaration
807                 { end_class_declaration (0); }
808 |       interface_declaration
809                 { end_class_declaration (0); }
810 |       empty_statement
811 |       error
812                 {
813                   YYERROR_NOW;
814                   yyerror ("Class or interface declaration expected");
815                 }
816 ;
817
818 /* 19.7 Shortened from the original:
819    modifiers: modifier | modifiers modifier
820    modifier: any of public...  */
821 modifiers:
822         MODIFIER_TK
823                 {
824                   $$ = (1 << $1);
825                 }
826 |       modifiers MODIFIER_TK
827                 {
828                   int acc = (1 << $2);
829                   if ($$ & acc)
830                     parse_error_context 
831                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
832                        java_accstring_lookup (acc));
833                   else
834                     {
835                       $$ |= acc;
836                     }
837                 }
838 ;
839
840 /* 19.8.1 Production from $8.1: Class Declaration */
841 class_declaration:
842         modifiers CLASS_TK identifier super interfaces
843                 { create_class ($1, $3, $4, $5); }
844         class_body
845 |       CLASS_TK identifier super interfaces 
846                 { create_class (0, $2, $3, $4); }
847         class_body
848 |       modifiers CLASS_TK error
849                 {yyerror ("Missing class name"); RECOVER;}
850 |       CLASS_TK error
851                 {yyerror ("Missing class name"); RECOVER;}
852 |       CLASS_TK identifier error
853                 {
854                   if (!ctxp->class_err) yyerror ("'{' expected"); 
855                   DRECOVER(class1);
856                 }
857 |       modifiers CLASS_TK identifier error
858                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
859 ;
860
861 super:
862                 { $$ = NULL; }
863 |       EXTENDS_TK class_type
864                 { $$ = $2; }
865 |       EXTENDS_TK class_type error
866                 {yyerror ("'{' expected"); ctxp->class_err=1;}
867 |       EXTENDS_TK error
868                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
869 ;
870
871 interfaces:
872                 { $$ = NULL_TREE; }
873 |       IMPLEMENTS_TK interface_type_list
874                 { $$ = $2; }
875 |       IMPLEMENTS_TK error
876                 {
877                   ctxp->class_err=1;
878                   yyerror ("Missing interface name"); 
879                 }
880 ;
881
882 interface_type_list:
883         interface_type
884                 { 
885                   ctxp->interface_number = 1;
886                   $$ = build_tree_list ($1, NULL_TREE);
887                 }
888 |       interface_type_list C_TK interface_type
889                 { 
890                   ctxp->interface_number++;
891                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
892                 }
893 |       interface_type_list C_TK error
894                 {yyerror ("Missing interface name"); RECOVER;}
895 ;
896
897 class_body:
898         OCB_TK CCB_TK
899                 { 
900                   /* Store the location of the `}' when doing xrefs */
901                   if (flag_emit_xref)
902                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
903                       EXPR_WFL_ADD_COL ($2.location, 1);
904                   $$ = GET_CPC ();
905                 }
906 |       OCB_TK class_body_declarations CCB_TK
907                 { 
908                   /* Store the location of the `}' when doing xrefs */
909                   if (flag_emit_xref)
910                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
911                       EXPR_WFL_ADD_COL ($3.location, 1);
912                   $$ = GET_CPC ();
913                 }
914 ;
915
916 class_body_declarations:
917         class_body_declaration
918 |       class_body_declarations class_body_declaration
919 ;
920
921 class_body_declaration:
922         class_member_declaration
923 |       static_initializer
924 |       constructor_declaration
925 |       block                   /* Added, JDK1.1, instance initializer */
926                 {
927                   if ($1 != empty_stmt_node)
928                     {
929                       TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
930                       SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
931                     }
932                 }
933 ;
934
935 class_member_declaration:
936         field_declaration
937 |       method_declaration
938 |       class_declaration       /* Added, JDK1.1 inner classes */
939                 { end_class_declaration (1); }
940 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
941                 { end_class_declaration (1); }
942 |       empty_statement
943 ;
944
945 /* 19.8.2 Productions from 8.3: Field Declarations  */
946 field_declaration:
947         type variable_declarators SC_TK
948                 { register_fields (0, $1, $2); }
949 |       modifiers type variable_declarators SC_TK
950                 {
951                   check_modifiers 
952                     ("Illegal modifier `%s' for field declaration",
953                      $1, FIELD_MODIFIERS);
954                   check_modifiers_consistency ($1);
955                   register_fields ($1, $2, $3);
956                 }
957 ;
958
959 variable_declarators:
960         /* Should we use build_decl_list () instead ? FIXME */
961         variable_declarator     /* Default rule */
962 |       variable_declarators C_TK variable_declarator
963                 { $$ = chainon ($1, $3); }
964 |       variable_declarators C_TK error
965                 {yyerror ("Missing term"); RECOVER;}
966 ;
967
968 variable_declarator:
969         variable_declarator_id
970                 { $$ = build_tree_list ($1, NULL_TREE); }
971 |       variable_declarator_id ASSIGN_TK variable_initializer
972                 { 
973                   if (java_error_count)
974                     $3 = NULL_TREE;
975                   $$ = build_tree_list 
976                     ($1, build_assignment ($2.token, $2.location, $1, $3));
977                 }
978 |       variable_declarator_id ASSIGN_TK error
979                 {
980                   yyerror ("Missing variable initializer");
981                   $$ = build_tree_list ($1, NULL_TREE);
982                   RECOVER;
983                 }
984 |       variable_declarator_id ASSIGN_TK variable_initializer error
985                 {
986                   yyerror ("';' expected");
987                   $$ = build_tree_list ($1, NULL_TREE);
988                   RECOVER;
989                 }
990 ;
991
992 variable_declarator_id:
993         identifier
994 |       variable_declarator_id OSB_TK CSB_TK
995                 { $$ = build_unresolved_array_type ($1); }
996 |       identifier error
997                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
998 |       variable_declarator_id OSB_TK error
999                 { 
1000                   tree node = java_lval.node;
1001                   if (node && (TREE_CODE (node) == INTEGER_CST
1002                                || TREE_CODE (node) == EXPR_WITH_FILE_LOCATION))
1003                     yyerror ("Can't specify array dimension in a declaration");
1004                   else
1005                     yyerror ("']' expected");
1006                   DRECOVER(vdi);
1007                 }
1008 |       variable_declarator_id CSB_TK error
1009                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
1010 ;
1011
1012 variable_initializer:
1013         expression
1014 |       array_initializer
1015 ;
1016
1017 /* 19.8.3 Productions from 8.4: Method Declarations  */
1018 method_declaration:
1019         method_header 
1020                 {
1021                   current_function_decl = $1;
1022                   if (current_function_decl
1023                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
1024                     source_start_java_method (current_function_decl);
1025                   else
1026                     current_function_decl = NULL_TREE;
1027                 }
1028         method_body
1029                 { finish_method_declaration ($3); }
1030 |       method_header error
1031                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
1032 ;
1033
1034 method_header:  
1035         type method_declarator throws
1036                 { $$ = method_header (0, $1, $2, $3); }
1037 |       VOID_TK method_declarator throws
1038                 { $$ = method_header (0, void_type_node, $2, $3); }
1039 |       modifiers type method_declarator throws
1040                 { $$ = method_header ($1, $2, $3, $4); }
1041 |       modifiers VOID_TK method_declarator throws
1042                 { $$ = method_header ($1, void_type_node, $3, $4); }
1043 |       type error
1044                 {
1045                   yyerror ("Invalid method declaration, method name required");
1046                   RECOVER;
1047                 }
1048 |       modifiers type error
1049                 {RECOVER;}
1050 |       VOID_TK error
1051                 {yyerror ("Identifier expected"); RECOVER;}
1052 |       modifiers VOID_TK error
1053                 {yyerror ("Identifier expected"); RECOVER;}
1054 |       modifiers error
1055                 {
1056                   yyerror ("Invalid method declaration, return type required");
1057                   RECOVER;
1058                 }
1059 ;
1060
1061 method_declarator:
1062         identifier OP_TK CP_TK
1063                 { 
1064                   ctxp->formal_parameter_number = 0;
1065                   $$ = method_declarator ($1, NULL_TREE);
1066                 }
1067 |       identifier OP_TK formal_parameter_list CP_TK
1068                 { $$ = method_declarator ($1, $3); }
1069 |       method_declarator OSB_TK CSB_TK
1070                 {
1071                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1072                   TREE_PURPOSE ($1) = 
1073                     build_unresolved_array_type (TREE_PURPOSE ($1));
1074                   parse_warning_context 
1075                     (wfl_operator, 
1076                      "Discouraged form of returned type specification");
1077                 }
1078 |       identifier OP_TK error
1079                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1080 |       method_declarator OSB_TK error
1081                 {yyerror ("']' expected"); RECOVER;}
1082 ;
1083
1084 formal_parameter_list:
1085         formal_parameter
1086                 {
1087                   ctxp->formal_parameter_number = 1;
1088                 }
1089 |       formal_parameter_list C_TK formal_parameter
1090                 {
1091                   ctxp->formal_parameter_number += 1;
1092                   $$ = chainon ($1, $3);
1093                 }
1094 |       formal_parameter_list C_TK error
1095                 { yyerror ("Missing formal parameter term"); RECOVER; }
1096 ;
1097
1098 formal_parameter:
1099         type variable_declarator_id
1100                 {
1101                   $$ = build_tree_list ($2, $1);
1102                 }
1103 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1104                 { 
1105                   $$ = build_tree_list ($3, $2);
1106                   ARG_FINAL_P ($$) = 1;
1107                 }
1108 |       type error
1109                 {
1110                   yyerror ("Missing identifier"); RECOVER;
1111                   $$ = NULL_TREE;
1112                 }
1113 |       final type error
1114                 {
1115                   yyerror ("Missing identifier"); RECOVER;
1116                   $$ = NULL_TREE;
1117                 }
1118 ;
1119
1120 final:
1121         modifiers
1122                 {
1123                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1124                                    $1, ACC_FINAL);
1125                   if ($1 != ACC_FINAL)
1126                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1127                 }
1128 ;
1129
1130 throws:
1131                 { $$ = NULL_TREE; }
1132 |       THROWS_TK class_type_list
1133                 { $$ = $2; }
1134 |       THROWS_TK error
1135                 {yyerror ("Missing class type term"); RECOVER;}
1136 ;
1137
1138 class_type_list:
1139         class_type
1140                 { $$ = build_tree_list ($1, $1); }
1141 |       class_type_list C_TK class_type
1142                 { $$ = tree_cons ($3, $3, $1); }
1143 |       class_type_list C_TK error
1144                 {yyerror ("Missing class type term"); RECOVER;}
1145 ;
1146
1147 method_body:
1148         block
1149 |       SC_TK { $$ = NULL_TREE; }
1150 ;
1151
1152 /* 19.8.4 Productions from 8.5: Static Initializers  */
1153 static_initializer:
1154         static block
1155                 {
1156                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1157                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1158                   current_static_block = NULL_TREE;
1159                 }
1160 ;
1161
1162 static:                         /* Test lval.sub_token here */
1163         modifiers
1164                 {
1165                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1166                   /* Can't have a static initializer in an innerclass */
1167                   if ($1 | ACC_STATIC &&
1168                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1169                     parse_error_context 
1170                       (MODIFIER_WFL (STATIC_TK),
1171                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1172                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1173                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1174                 }
1175 ;
1176
1177 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1178 constructor_declaration:
1179         constructor_header
1180                 {
1181                   current_function_decl = $1;
1182                   source_start_java_method (current_function_decl);
1183                 }
1184         constructor_body
1185                 { finish_method_declaration ($3); }
1186 ;
1187
1188 constructor_header:
1189         constructor_declarator throws
1190                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1191 |       modifiers constructor_declarator throws
1192                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1193 ;
1194
1195 constructor_declarator:
1196         simple_name OP_TK CP_TK
1197                 { 
1198                   ctxp->formal_parameter_number = 0;  
1199                   $$ = method_declarator ($1, NULL_TREE);
1200                 }
1201 |       simple_name OP_TK formal_parameter_list CP_TK
1202                 { $$ = method_declarator ($1, $3); }
1203 ;
1204
1205 constructor_body:
1206         /* Unlike regular method, we always need a complete (empty)
1207            body so we can safely perform all the required code
1208            addition (super invocation and field initialization) */
1209         block_begin constructor_block_end
1210                 { 
1211                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1212                   $$ = $2;
1213                 }
1214 |       block_begin explicit_constructor_invocation constructor_block_end
1215                 { $$ = $3; }
1216 |       block_begin block_statements constructor_block_end
1217                 { $$ = $3; }
1218 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1219                 { $$ = $4; }
1220 ;
1221
1222 constructor_block_end:
1223         block_end
1224 ;
1225
1226 /* Error recovery for that rule moved down expression_statement: rule.  */
1227 explicit_constructor_invocation:
1228         this_or_super OP_TK CP_TK SC_TK
1229                 { 
1230                   $$ = build_method_invocation ($1, NULL_TREE); 
1231                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1232                   $$ = java_method_add_stmt (current_function_decl, $$);
1233                 }
1234 |       this_or_super OP_TK argument_list CP_TK SC_TK
1235                 { 
1236                   $$ = build_method_invocation ($1, $3); 
1237                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1238                   $$ = java_method_add_stmt (current_function_decl, $$);
1239                 }
1240         /* Added, JDK1.1 inner classes. Modified because the rule
1241            'primary' couldn't work.  */
1242 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1243                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1244 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1245                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1246 ;
1247
1248 this_or_super:                  /* Added, simplifies error diagnostics */
1249         THIS_TK
1250                 {
1251                   tree wfl = build_wfl_node (this_identifier_node);
1252                   EXPR_WFL_LINECOL (wfl) = $1.location;
1253                   $$ = wfl;
1254                 }
1255 |       SUPER_TK
1256                 {
1257                   tree wfl = build_wfl_node (super_identifier_node);
1258                   EXPR_WFL_LINECOL (wfl) = $1.location;
1259                   $$ = wfl;
1260                 }
1261 ;
1262
1263 /* 19.9 Productions from 9: Interfaces  */
1264 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1265 interface_declaration:
1266         INTERFACE_TK identifier
1267                 { create_interface (0, $2, NULL_TREE); }
1268         interface_body
1269 |       modifiers INTERFACE_TK identifier
1270                 { create_interface ($1, $3, NULL_TREE); }
1271         interface_body
1272 |       INTERFACE_TK identifier extends_interfaces
1273                 { create_interface (0, $2, $3); }
1274         interface_body
1275 |       modifiers INTERFACE_TK identifier extends_interfaces
1276                 { create_interface ($1, $3, $4); }
1277         interface_body
1278 |       INTERFACE_TK identifier error
1279                 {yyerror ("'{' expected"); RECOVER;}
1280 |       modifiers INTERFACE_TK identifier error
1281                 {yyerror ("'{' expected"); RECOVER;}
1282 ;
1283
1284 extends_interfaces:
1285         EXTENDS_TK interface_type
1286                 { 
1287                   ctxp->interface_number = 1;
1288                   $$ = build_tree_list ($2, NULL_TREE);
1289                 }
1290 |       extends_interfaces C_TK interface_type
1291                 { 
1292                   ctxp->interface_number++;
1293                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1294                 }
1295 |       EXTENDS_TK error
1296                 {yyerror ("Invalid interface type"); RECOVER;}
1297 |       extends_interfaces C_TK error
1298                 {yyerror ("Missing term"); RECOVER;}
1299 ;
1300
1301 interface_body:
1302         OCB_TK CCB_TK
1303                 { $$ = NULL_TREE; }
1304 |       OCB_TK interface_member_declarations CCB_TK
1305                 { $$ = NULL_TREE; }
1306 ;
1307
1308 interface_member_declarations:
1309         interface_member_declaration
1310 |       interface_member_declarations interface_member_declaration
1311 ;
1312
1313 interface_member_declaration:
1314         constant_declaration
1315 |       abstract_method_declaration
1316 |       class_declaration       /* Added, JDK1.1 inner classes */
1317                 { end_class_declaration (1); }
1318 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1319                 { end_class_declaration (1); }
1320 ;
1321
1322 constant_declaration:
1323         field_declaration
1324 ;
1325
1326 abstract_method_declaration:
1327         method_header SC_TK
1328                 { 
1329                   check_abstract_method_header ($1);
1330                   current_function_decl = NULL_TREE; /* FIXME ? */
1331                 }
1332 |       method_header error
1333                 {yyerror ("';' expected"); RECOVER;}
1334 ;
1335
1336 /* 19.10 Productions from 10: Arrays  */
1337 array_initializer:
1338         OCB_TK CCB_TK
1339                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1340 |       OCB_TK variable_initializers CCB_TK
1341                 { $$ = build_new_array_init ($1.location, $2); }
1342 |       OCB_TK variable_initializers C_TK CCB_TK
1343                 { $$ = build_new_array_init ($1.location, $2); }
1344 ;
1345
1346 variable_initializers:
1347         variable_initializer
1348                 { 
1349                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1350                                   $1, NULL_TREE);
1351                 }
1352 |       variable_initializers C_TK variable_initializer
1353                 {
1354                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1355                 }
1356 |       variable_initializers C_TK error
1357                 {yyerror ("Missing term"); RECOVER;}
1358 ;
1359
1360 /* 19.11 Production from 14: Blocks and Statements  */
1361 block:
1362         OCB_TK CCB_TK
1363                 { 
1364                   /* Store the location of the `}' when doing xrefs */
1365                   if (current_function_decl && flag_emit_xref)
1366                     DECL_END_SOURCE_LINE (current_function_decl) = 
1367                       EXPR_WFL_ADD_COL ($2.location, 1);
1368                   $$ = empty_stmt_node; 
1369                 }
1370 |       block_begin block_statements block_end
1371                 { $$ = $3; }
1372 ;
1373
1374 block_begin:
1375         OCB_TK
1376                 { enter_block (); }
1377 ;
1378
1379 block_end:
1380         CCB_TK
1381                 { 
1382                   maybe_absorb_scoping_blocks ();
1383                   /* Store the location of the `}' when doing xrefs */
1384                   if (current_function_decl && flag_emit_xref)
1385                     DECL_END_SOURCE_LINE (current_function_decl) = 
1386                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1387                   $$ = exit_block ();
1388                   if (!BLOCK_SUBBLOCKS ($$))
1389                     BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
1390                 }
1391 ;
1392
1393 block_statements:
1394         block_statement
1395 |       block_statements block_statement
1396 ;
1397
1398 block_statement:
1399         local_variable_declaration_statement
1400 |       statement
1401                 { java_method_add_stmt (current_function_decl, $1); }
1402 |       class_declaration       /* Added, JDK1.1 local classes */
1403                 { 
1404                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1405                   end_class_declaration (1);
1406                 }
1407 ;
1408
1409 local_variable_declaration_statement:
1410         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1411 ;
1412
1413 local_variable_declaration:
1414         type variable_declarators
1415                 { declare_local_variables (0, $1, $2); }
1416 |       final type variable_declarators /* Added, JDK1.1 final locals */
1417                 { declare_local_variables ($1, $2, $3); }
1418 ;
1419
1420 statement:
1421         statement_without_trailing_substatement
1422 |       labeled_statement
1423 |       if_then_statement
1424 |       if_then_else_statement
1425 |       while_statement
1426 |       for_statement
1427                 { $$ = exit_block (); }
1428 ;
1429
1430 statement_nsi:
1431         statement_without_trailing_substatement
1432 |       labeled_statement_nsi
1433 |       if_then_else_statement_nsi
1434 |       while_statement_nsi
1435 |       for_statement_nsi
1436                 { $$ = exit_block (); }
1437 ;
1438
1439 statement_without_trailing_substatement:
1440         block
1441 |       empty_statement
1442 |       expression_statement
1443 |       switch_statement
1444 |       do_statement
1445 |       break_statement
1446 |       continue_statement
1447 |       return_statement
1448 |       synchronized_statement
1449 |       throw_statement
1450 |       try_statement
1451 ;
1452
1453 empty_statement:
1454         SC_TK
1455                 { 
1456                   if (flag_extraneous_semicolon)
1457                     {
1458                       EXPR_WFL_SET_LINECOL (wfl_operator, lineno, -1);
1459                       parse_warning_context (wfl_operator, "An empty declaration is a deprecated feature that should not be used");
1460                     }
1461                   $$ = empty_stmt_node;
1462                 }
1463 ;
1464
1465 label_decl:
1466         identifier REL_CL_TK
1467                 {
1468                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1469                                             EXPR_WFL_NODE ($1));
1470                   pushlevel (2);
1471                   push_labeled_block ($$);
1472                   PUSH_LABELED_BLOCK ($$);
1473                 }
1474 ;
1475
1476 labeled_statement:
1477         label_decl statement
1478                 { $$ = finish_labeled_statement ($1, $2); }
1479 |       identifier error
1480                 {yyerror ("':' expected"); RECOVER;}
1481 ;
1482
1483 labeled_statement_nsi:
1484         label_decl statement_nsi
1485                 { $$ = finish_labeled_statement ($1, $2); }
1486 ;
1487
1488 /* We concentrate here a bunch of error handling rules that we couldn't write
1489    earlier, because expression_statement catches a missing ';'.  */
1490 expression_statement:
1491         statement_expression SC_TK
1492                 {
1493                   /* We have a statement. Generate a WFL around it so
1494                      we can debug it */
1495                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1496                   /* We know we have a statement, so set the debug
1497                      info to be eventually generate here. */
1498                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1499                 }
1500 |       error SC_TK 
1501                 {
1502                   YYNOT_TWICE yyerror ("Invalid expression statement");
1503                   DRECOVER (expr_stmt);
1504                 }
1505 |       error OCB_TK
1506                 {
1507                   YYNOT_TWICE yyerror ("Invalid expression statement");
1508                   DRECOVER (expr_stmt);
1509                 }
1510 |       error CCB_TK
1511                 {
1512                   YYNOT_TWICE yyerror ("Invalid expression statement");
1513                   DRECOVER (expr_stmt);
1514                 }
1515 |       this_or_super OP_TK error
1516                 {yyerror ("')' expected"); RECOVER;}
1517 |       this_or_super OP_TK CP_TK error
1518                 {
1519                   parse_ctor_invocation_error ();
1520                   RECOVER;
1521                 }
1522 |       this_or_super OP_TK argument_list error
1523                 {yyerror ("')' expected"); RECOVER;}
1524 |       this_or_super OP_TK argument_list CP_TK error
1525                 {
1526                   parse_ctor_invocation_error ();
1527                   RECOVER;
1528                 }
1529 |       name DOT_TK SUPER_TK error
1530                 {yyerror ("'(' expected"); RECOVER;}
1531 |       name DOT_TK SUPER_TK OP_TK error
1532                 {yyerror ("')' expected"); RECOVER;}
1533 |       name DOT_TK SUPER_TK OP_TK argument_list error
1534                 {yyerror ("')' expected"); RECOVER;}
1535 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1536                 {yyerror ("';' expected"); RECOVER;}
1537 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1538                 {yyerror ("';' expected"); RECOVER;}
1539 ;
1540
1541 statement_expression: 
1542         assignment
1543 |       pre_increment_expression
1544 |       pre_decrement_expression
1545 |       post_increment_expression
1546 |       post_decrement_expression
1547 |       method_invocation
1548 |       class_instance_creation_expression
1549 ;
1550
1551 if_then_statement:
1552         IF_TK OP_TK expression CP_TK statement
1553                 { 
1554                   $$ = build_if_else_statement ($2.location, $3, 
1555                                                 $5, NULL_TREE);
1556                 }
1557 |       IF_TK error
1558                 {yyerror ("'(' expected"); RECOVER;}
1559 |       IF_TK OP_TK error
1560                 {yyerror ("Missing term"); RECOVER;}
1561 |       IF_TK OP_TK expression error
1562                 {yyerror ("')' expected"); RECOVER;}
1563 ;
1564
1565 if_then_else_statement:
1566         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1567                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1568 ;
1569
1570 if_then_else_statement_nsi:
1571         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1572                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1573 ;
1574
1575 switch_statement:
1576         switch_expression
1577                 {
1578                   enter_block ();
1579                 }
1580         switch_block
1581                 { 
1582                   /* Make into "proper list" of COMPOUND_EXPRs.
1583                      I.e. make the last statment also have its own
1584                      COMPOUND_EXPR. */
1585                   maybe_absorb_scoping_blocks ();
1586                   TREE_OPERAND ($1, 1) = exit_block ();
1587                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1588                 }
1589 ;
1590
1591 switch_expression:
1592         SWITCH_TK OP_TK expression CP_TK
1593                 { 
1594                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1595                   EXPR_WFL_LINECOL ($$) = $2.location;
1596                 }
1597 |       SWITCH_TK error
1598                 {yyerror ("'(' expected"); RECOVER;}
1599 |       SWITCH_TK OP_TK error
1600                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1601 |       SWITCH_TK OP_TK expression CP_TK error
1602                 {yyerror ("'{' expected"); RECOVER;}
1603 ;
1604
1605 /* Default assignment is there to avoid type node on switch_block
1606    node. */
1607
1608 switch_block:
1609         OCB_TK CCB_TK
1610                 { $$ = NULL_TREE; }
1611 |       OCB_TK switch_labels CCB_TK
1612                 { $$ = NULL_TREE; }
1613 |       OCB_TK switch_block_statement_groups CCB_TK
1614                 { $$ = NULL_TREE; }
1615 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1616                 { $$ = NULL_TREE; }
1617 ;
1618
1619 switch_block_statement_groups: 
1620         switch_block_statement_group
1621 |       switch_block_statement_groups switch_block_statement_group
1622 ;
1623
1624 switch_block_statement_group:
1625         switch_labels block_statements
1626 ;
1627
1628 switch_labels:
1629         switch_label
1630 |       switch_labels switch_label
1631 ;
1632
1633 switch_label:
1634         CASE_TK constant_expression REL_CL_TK
1635                 { 
1636                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1637                   EXPR_WFL_LINECOL (lab) = $1.location;
1638                   java_method_add_stmt (current_function_decl, lab);
1639                 }
1640 |       DEFAULT_TK REL_CL_TK
1641                 { 
1642                   tree lab = build (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1643                   EXPR_WFL_LINECOL (lab) = $1.location;
1644                   java_method_add_stmt (current_function_decl, lab);
1645                 }
1646 |       CASE_TK error
1647                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1648 |       CASE_TK constant_expression error
1649                 {yyerror ("':' expected"); RECOVER;}
1650 |       DEFAULT_TK error
1651                 {yyerror ("':' expected"); RECOVER;}
1652 ;
1653
1654 while_expression:
1655         WHILE_TK OP_TK expression CP_TK
1656                 { 
1657                   tree body = build_loop_body ($2.location, $3, 0);
1658                   $$ = build_new_loop (body);
1659                 }
1660 ;
1661
1662 while_statement:
1663         while_expression statement
1664                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1665 |       WHILE_TK error
1666                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1667 |       WHILE_TK OP_TK error
1668                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1669 |       WHILE_TK OP_TK expression error
1670                 {yyerror ("')' expected"); RECOVER;}
1671 ;
1672
1673 while_statement_nsi:
1674         while_expression statement_nsi
1675                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1676 ;
1677
1678 do_statement_begin:
1679         DO_TK
1680                 { 
1681                   tree body = build_loop_body (0, NULL_TREE, 1);
1682                   $$ = build_new_loop (body);
1683                 }
1684         /* Need error handing here. FIXME */
1685 ;
1686
1687 do_statement: 
1688         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1689                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1690 ;
1691
1692 for_statement:
1693         for_begin SC_TK expression SC_TK for_update CP_TK statement
1694                 {
1695                   if (TREE_CODE_CLASS (TREE_CODE ($3)) == 'c')
1696                     $3 = build_wfl_node ($3);
1697                   $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);
1698                 }
1699 |       for_begin SC_TK SC_TK for_update CP_TK statement
1700                 { 
1701                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1702                   /* We have not condition, so we get rid of the EXIT_EXPR */
1703                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1704                     empty_stmt_node;
1705                 }
1706 |       for_begin SC_TK error
1707                 {yyerror ("Invalid control expression"); RECOVER;}
1708 |       for_begin SC_TK expression SC_TK error
1709                 {yyerror ("Invalid update expression"); RECOVER;}
1710 |       for_begin SC_TK SC_TK error
1711                 {yyerror ("Invalid update expression"); RECOVER;}
1712 ;
1713
1714 for_statement_nsi:
1715         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1716                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1717 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1718                 { 
1719                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1720                   /* We have not condition, so we get rid of the EXIT_EXPR */
1721                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1722                     empty_stmt_node;
1723                 }
1724 ;
1725
1726 for_header:
1727         FOR_TK OP_TK
1728                 { 
1729                   /* This scope defined for local variable that may be
1730                      defined within the scope of the for loop */
1731                   enter_block (); 
1732                 }
1733 |       FOR_TK error
1734                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1735 |       FOR_TK OP_TK error
1736                 {yyerror ("Invalid init statement"); RECOVER;}
1737 ;
1738
1739 for_begin:
1740         for_header for_init
1741                 { 
1742                   /* We now declare the loop body. The loop is
1743                      declared as a for loop. */
1744                   tree body = build_loop_body (0, NULL_TREE, 0);
1745                   $$ =  build_new_loop (body);
1746                   FOR_LOOP_P ($$) = 1;
1747                   /* The loop is added to the current block the for
1748                      statement is defined within */
1749                   java_method_add_stmt (current_function_decl, $$);
1750                 }
1751 ;
1752 for_init:                       /* Can be empty */
1753                 { $$ = empty_stmt_node; }
1754 |       statement_expression_list
1755                 { 
1756                   /* Init statement recorded within the previously
1757                      defined block scope */
1758                   $$ = java_method_add_stmt (current_function_decl, $1);
1759                 }
1760 |       local_variable_declaration
1761                 { 
1762                   /* Local variable are recorded within the previously
1763                      defined block scope */
1764                   $$ = NULL_TREE;
1765                 }
1766 |       statement_expression_list error
1767                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1768 ;
1769
1770 for_update:                     /* Can be empty */
1771                 {$$ = empty_stmt_node;}
1772 |       statement_expression_list
1773                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1774 ;
1775
1776 statement_expression_list:
1777         statement_expression
1778                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1779 |       statement_expression_list C_TK statement_expression
1780                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1781 |       statement_expression_list C_TK error
1782                 {yyerror ("Missing term"); RECOVER;}
1783 ;
1784
1785 break_statement:
1786         BREAK_TK SC_TK
1787                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1788 |       BREAK_TK identifier SC_TK
1789                 { $$ = build_bc_statement ($1.location, 1, $2); }
1790 |       BREAK_TK error
1791                 {yyerror ("Missing term"); RECOVER;}
1792 |       BREAK_TK identifier error
1793                 {yyerror ("';' expected"); RECOVER;}
1794 ;
1795
1796 continue_statement:
1797         CONTINUE_TK SC_TK
1798                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1799 |       CONTINUE_TK identifier SC_TK
1800                 { $$ = build_bc_statement ($1.location, 0, $2); }
1801 |       CONTINUE_TK error
1802                 {yyerror ("Missing term"); RECOVER;}
1803 |       CONTINUE_TK identifier error
1804                 {yyerror ("';' expected"); RECOVER;}
1805 ;
1806
1807 return_statement:
1808         RETURN_TK SC_TK
1809                 { $$ = build_return ($1.location, NULL_TREE); }
1810 |       RETURN_TK expression SC_TK
1811                 { $$ = build_return ($1.location, $2); }
1812 |       RETURN_TK error
1813                 {yyerror ("Missing term"); RECOVER;}
1814 |       RETURN_TK expression error
1815                 {yyerror ("';' expected"); RECOVER;}
1816 ;
1817
1818 throw_statement:
1819         THROW_TK expression SC_TK
1820                 { 
1821                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1822                   EXPR_WFL_LINECOL ($$) = $1.location;
1823                 }
1824 |       THROW_TK error
1825                 {yyerror ("Missing term"); RECOVER;}
1826 |       THROW_TK expression error
1827                 {yyerror ("';' expected"); RECOVER;}
1828 ;
1829
1830 synchronized_statement:
1831         synchronized OP_TK expression CP_TK block
1832                 { 
1833                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1834                   EXPR_WFL_LINECOL ($$) = 
1835                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1836                 }
1837 |       synchronized OP_TK expression CP_TK error
1838                 {yyerror ("'{' expected"); RECOVER;}
1839 |       synchronized error
1840                 {yyerror ("'(' expected"); RECOVER;}
1841 |       synchronized OP_TK error CP_TK
1842                 {yyerror ("Missing term"); RECOVER;}
1843 |       synchronized OP_TK error
1844                 {yyerror ("Missing term"); RECOVER;}
1845 ;
1846
1847 synchronized:
1848         modifiers
1849                 {
1850                   check_modifiers (
1851              "Illegal modifier `%s'. Only `synchronized' was expected here",
1852                                    $1, ACC_SYNCHRONIZED);
1853                   if ($1 != ACC_SYNCHRONIZED)
1854                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1855                       build_wfl_node (NULL_TREE);
1856                 }
1857 ;
1858
1859 try_statement:
1860         TRY_TK block catches
1861                 { $$ = build_try_statement ($1.location, $2, $3); }
1862 |       TRY_TK block finally
1863                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1864 |       TRY_TK block catches finally
1865                 { $$ = build_try_finally_statement 
1866                     ($1.location, build_try_statement ($1.location,
1867                                                        $2, $3), $4);
1868                 }
1869 |       TRY_TK error
1870                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1871 ;
1872
1873 catches:
1874         catch_clause
1875 |       catches catch_clause
1876                 { 
1877                   TREE_CHAIN ($2) = $1;
1878                   $$ = $2;
1879                 }
1880 ;
1881
1882 catch_clause:
1883         catch_clause_parameter block
1884                 { 
1885                   java_method_add_stmt (current_function_decl, $2);
1886                   exit_block ();
1887                   $$ = $1;
1888                 }
1889
1890 catch_clause_parameter:
1891         CATCH_TK OP_TK formal_parameter CP_TK
1892                 { 
1893                   /* We add a block to define a scope for
1894                      formal_parameter (CCBP). The formal parameter is
1895                      declared initialized by the appropriate function
1896                      call */
1897                   tree ccpb = enter_block ();
1898                   tree init = build_assignment
1899                     (ASSIGN_TK, $2.location, TREE_PURPOSE ($3), 
1900                      build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
1901                   declare_local_variables (0, TREE_VALUE ($3),
1902                                            build_tree_list (TREE_PURPOSE ($3),
1903                                                             init));
1904                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1905                   EXPR_WFL_LINECOL ($$) = $1.location;
1906                 }
1907 |       CATCH_TK error
1908                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1909 |       CATCH_TK OP_TK error 
1910                 {
1911                   yyerror ("Missing term or ')' expected"); 
1912                   RECOVER; $$ = NULL_TREE;
1913                 }
1914 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1915                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1916 ;
1917
1918 finally:
1919         FINALLY_TK block
1920                 { $$ = $2; }
1921 |       FINALLY_TK error
1922                 {yyerror ("'{' expected"); RECOVER; }
1923 ;
1924
1925 /* 19.12 Production from 15: Expressions  */
1926 primary:
1927         primary_no_new_array
1928 |       array_creation_expression
1929 ;
1930
1931 primary_no_new_array:
1932         literal
1933 |       THIS_TK
1934                 { $$ = build_this ($1.location); }
1935 |       OP_TK expression CP_TK
1936                 {$$ = $2;}
1937 |       class_instance_creation_expression
1938 |       field_access
1939 |       method_invocation
1940 |       array_access
1941 |       type_literals
1942         /* Added, JDK1.1 inner classes. Documentation is wrong
1943            refering to a 'ClassName' (class_name) rule that doesn't
1944            exist. Used name: instead.  */
1945 |       name DOT_TK THIS_TK
1946                 { 
1947                   tree wfl = build_wfl_node (this_identifier_node);
1948                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1949                 }
1950 |       OP_TK expression error 
1951                 {yyerror ("')' expected"); RECOVER;}
1952 |       name DOT_TK error
1953                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1954 |       primitive_type DOT_TK error
1955                 {yyerror ("'class' expected" ); RECOVER;}
1956 |       VOID_TK DOT_TK error
1957                 {yyerror ("'class' expected" ); RECOVER;}
1958 ;
1959
1960 type_literals:
1961         name DOT_TK CLASS_TK
1962                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1963 |       array_type DOT_TK CLASS_TK
1964                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1965 |       primitive_type DOT_TK CLASS_TK
1966                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1967 |       VOID_TK DOT_TK CLASS_TK
1968                 { 
1969                    $$ = build_incomplete_class_ref ($2.location,
1970                                                    void_type_node);
1971                 }
1972 ;
1973
1974 class_instance_creation_expression:
1975         NEW_TK class_type OP_TK argument_list CP_TK
1976                 { $$ = build_new_invocation ($2, $4); }
1977 |       NEW_TK class_type OP_TK CP_TK
1978                 { $$ = build_new_invocation ($2, NULL_TREE); }
1979 |       anonymous_class_creation
1980         /* Added, JDK1.1 inner classes, modified to use name or
1981            primary instead of primary solely which couldn't work in
1982            all situations.  */
1983 |       something_dot_new identifier OP_TK CP_TK
1984                 { 
1985                   tree ctor = build_new_invocation ($2, NULL_TREE);
1986                   $$ = make_qualified_primary ($1, ctor, 
1987                                                EXPR_WFL_LINECOL ($1));
1988                 }
1989 |       something_dot_new identifier OP_TK CP_TK class_body
1990 |       something_dot_new identifier OP_TK argument_list CP_TK
1991                 { 
1992                   tree ctor = build_new_invocation ($2, $4);
1993                   $$ = make_qualified_primary ($1, ctor, 
1994                                                EXPR_WFL_LINECOL ($1));
1995                 }
1996 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
1997 |       NEW_TK error SC_TK 
1998                 {yyerror ("'(' expected"); DRECOVER(new_1);}
1999 |       NEW_TK class_type error
2000                 {yyerror ("'(' expected"); RECOVER;}
2001 |       NEW_TK class_type OP_TK error
2002                 {yyerror ("')' or term expected"); RECOVER;}
2003 |       NEW_TK class_type OP_TK argument_list error
2004                 {yyerror ("')' expected"); RECOVER;}
2005 |       something_dot_new error
2006                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
2007 |       something_dot_new identifier error
2008                 {yyerror ("'(' expected"); RECOVER;}
2009 ;
2010
2011 /* Created after JDK1.1 rules originally added to
2012    class_instance_creation_expression, but modified to use
2013    'class_type' instead of 'TypeName' (type_name) which is mentionned
2014    in the documentation but doesn't exist. */
2015
2016 anonymous_class_creation:
2017         NEW_TK class_type OP_TK argument_list CP_TK 
2018                 { create_anonymous_class ($1.location, $2); }
2019         class_body
2020                 { 
2021                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2022                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2023
2024                   end_class_declaration (1);
2025
2026                   /* Now we can craft the new expression */
2027                   $$ = build_new_invocation (id, $4);
2028
2029                   /* Note that we can't possibly be here if
2030                      `class_type' is an interface (in which case the
2031                      anonymous class extends Object and implements
2032                      `class_type', hence its constructor can't have
2033                      arguments.) */
2034
2035                   /* Otherwise, the innerclass must feature a
2036                      constructor matching `argument_list'. Anonymous
2037                      classes are a bit special: it's impossible to
2038                      define constructor for them, hence constructors
2039                      must be generated following the hints provided by
2040                      the `new' expression. Whether a super constructor
2041                      of that nature exists or not is to be verified
2042                      later on in verify_constructor_super. 
2043
2044                      It's during the expansion of a `new' statement
2045                      refering to an anonymous class that a ctor will
2046                      be generated for the anonymous class, with the
2047                      right arguments. */
2048
2049                 }
2050 |       NEW_TK class_type OP_TK CP_TK 
2051                 { create_anonymous_class ($1.location, $2); }
2052         class_body         
2053                 { 
2054                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2055                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2056
2057                   end_class_declaration (1);
2058
2059                   /* Now we can craft the new expression. The
2060                      statement doesn't need to be remember so that a
2061                      constructor can be generated, since its signature
2062                      is already known. */
2063                   $$ = build_new_invocation (id, NULL_TREE);
2064                 }
2065 ;
2066
2067 something_dot_new:              /* Added, not part of the specs. */
2068         name DOT_TK NEW_TK
2069                 { $$ = $1; }
2070 |       primary DOT_TK NEW_TK
2071                 { $$ = $1; }
2072 ;
2073
2074 argument_list:
2075         expression
2076                 { 
2077                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2078                   ctxp->formal_parameter_number = 1; 
2079                 }
2080 |       argument_list C_TK expression
2081                 {
2082                   ctxp->formal_parameter_number += 1;
2083                   $$ = tree_cons (NULL_TREE, $3, $1);
2084                 }
2085 |       argument_list C_TK error
2086                 {yyerror ("Missing term"); RECOVER;}
2087 ;
2088
2089 array_creation_expression:
2090         NEW_TK primitive_type dim_exprs
2091                 { $$ = build_newarray_node ($2, $3, 0); }
2092 |       NEW_TK class_or_interface_type dim_exprs
2093                 { $$ = build_newarray_node ($2, $3, 0); }
2094 |       NEW_TK primitive_type dim_exprs dims
2095                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2096 |       NEW_TK class_or_interface_type dim_exprs dims
2097                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2098         /* Added, JDK1.1 anonymous array. Initial documentation rule
2099            modified */
2100 |       NEW_TK class_or_interface_type dims array_initializer
2101                 {
2102                   char *sig;
2103                   int osb = pop_current_osb (ctxp);
2104                   while (osb--)
2105                     obstack_1grow (&temporary_obstack, '[');
2106                   sig = obstack_finish (&temporary_obstack);
2107                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2108                               $2, get_identifier (sig), $4);
2109                 }
2110 |       NEW_TK primitive_type dims array_initializer
2111                 { 
2112                   int osb = pop_current_osb (ctxp);
2113                   tree type = $2;
2114                   while (osb--)
2115                     type = build_java_array_type (type, -1);
2116                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2117                               build_pointer_type (type), NULL_TREE, $4);
2118                 }
2119 |       NEW_TK error CSB_TK
2120                 {yyerror ("'[' expected"); DRECOVER ("]");}
2121 |       NEW_TK error OSB_TK
2122                 {yyerror ("']' expected"); RECOVER;}
2123 ;
2124
2125 dim_exprs:
2126         dim_expr
2127                 { $$ = build_tree_list (NULL_TREE, $1); }
2128 |       dim_exprs dim_expr
2129                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2130 ;
2131
2132 dim_expr:
2133         OSB_TK expression CSB_TK
2134                 { 
2135                   if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
2136                     {
2137                       $2 = build_wfl_node ($2);
2138                       TREE_TYPE ($2) = NULL_TREE;
2139                     }
2140                   EXPR_WFL_LINECOL ($2) = $1.location;
2141                   $$ = $2;
2142                 }
2143 |       OSB_TK expression error
2144                 {yyerror ("']' expected"); RECOVER;}
2145 |       OSB_TK error
2146                 {
2147                   yyerror ("Missing term");
2148                   yyerror ("']' expected");
2149                   RECOVER;
2150                 }
2151 ;
2152
2153 dims:                           
2154         OSB_TK CSB_TK
2155                 { 
2156                   int allocate = 0;
2157                   /* If not initialized, allocate memory for the osb
2158                      numbers stack */
2159                   if (!ctxp->osb_limit)
2160                     {
2161                       allocate = ctxp->osb_limit = 32;
2162                       ctxp->osb_depth = -1;
2163                     }
2164                   /* If capacity overflown, reallocate a bigger chunk */
2165                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2166                     allocate = ctxp->osb_limit << 1;
2167                   
2168                   if (allocate)
2169                     {
2170                       allocate *= sizeof (int);
2171                       if (ctxp->osb_number)
2172                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2173                                                             allocate);
2174                       else
2175                         ctxp->osb_number = (int *)xmalloc (allocate);
2176                     }
2177                   ctxp->osb_depth++;
2178                   CURRENT_OSB (ctxp) = 1;
2179                 }
2180 |       dims OSB_TK CSB_TK
2181                 { CURRENT_OSB (ctxp)++; }
2182 |       dims OSB_TK error
2183                 { yyerror ("']' expected"); RECOVER;}
2184 ;
2185
2186 field_access:
2187         primary DOT_TK identifier
2188                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2189                 /*  FIXME - REWRITE TO: 
2190                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2191 |       SUPER_TK DOT_TK identifier
2192                 {
2193                   tree super_wfl = build_wfl_node (super_identifier_node);
2194                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2195                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2196                 }
2197 |       SUPER_TK error
2198                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2199 ;
2200
2201 method_invocation:
2202         name OP_TK CP_TK
2203                 { $$ = build_method_invocation ($1, NULL_TREE); }
2204 |       name OP_TK argument_list CP_TK
2205                 { $$ = build_method_invocation ($1, $3); }
2206 |       primary DOT_TK identifier OP_TK CP_TK
2207                 { 
2208                   if (TREE_CODE ($1) == THIS_EXPR)
2209                     $$ = build_this_super_qualified_invocation 
2210                       (1, $3, NULL_TREE, 0, $2.location);
2211                   else
2212                     {
2213                       tree invok = build_method_invocation ($3, NULL_TREE);
2214                       $$ = make_qualified_primary ($1, invok, $2.location);
2215                     }
2216                 }
2217 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2218                 { 
2219                   if (TREE_CODE ($1) == THIS_EXPR)
2220                     $$ = build_this_super_qualified_invocation 
2221                       (1, $3, $5, 0, $2.location);
2222                   else
2223                     {
2224                       tree invok = build_method_invocation ($3, $5);
2225                       $$ = make_qualified_primary ($1, invok, $2.location);
2226                     }
2227                 }
2228 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2229                 { 
2230                   $$ = build_this_super_qualified_invocation 
2231                     (0, $3, NULL_TREE, $1.location, $2.location);
2232                 }
2233 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2234                 {
2235                   $$ = build_this_super_qualified_invocation 
2236                     (0, $3, $5, $1.location, $2.location);
2237                 }
2238         /* Screws up thing. I let it here until I'm convinced it can
2239            be removed. FIXME
2240 |       primary DOT_TK error
2241                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2242 |       SUPER_TK DOT_TK error CP_TK
2243                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2244 |       SUPER_TK DOT_TK error DOT_TK
2245                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2246 ;
2247
2248 array_access:
2249         name OSB_TK expression CSB_TK
2250                 { $$ = build_array_ref ($2.location, $1, $3); }
2251 |       primary_no_new_array OSB_TK expression CSB_TK
2252                 { $$ = build_array_ref ($2.location, $1, $3); }
2253 |       name OSB_TK error
2254                 {
2255                   yyerror ("Missing term and ']' expected");
2256                   DRECOVER(array_access);
2257                 }
2258 |       name OSB_TK expression error
2259                 {
2260                   yyerror ("']' expected");
2261                   DRECOVER(array_access);
2262                 }
2263 |       primary_no_new_array OSB_TK error
2264                 {
2265                   yyerror ("Missing term and ']' expected");
2266                   DRECOVER(array_access);
2267                 }
2268 |       primary_no_new_array OSB_TK expression error
2269                 {
2270                   yyerror ("']' expected");
2271                   DRECOVER(array_access);
2272                 }
2273 ;
2274
2275 postfix_expression:
2276         primary
2277 |       name
2278 |       post_increment_expression
2279 |       post_decrement_expression
2280 ;
2281
2282 post_increment_expression:
2283         postfix_expression INCR_TK
2284                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2285 ;
2286
2287 post_decrement_expression:
2288         postfix_expression DECR_TK
2289                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2290 ;
2291
2292 unary_expression:
2293         pre_increment_expression
2294 |       pre_decrement_expression
2295 |       PLUS_TK unary_expression
2296                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2297 |       MINUS_TK unary_expression
2298                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2299 |       unary_expression_not_plus_minus
2300 |       PLUS_TK error
2301                 {yyerror ("Missing term"); RECOVER}
2302 |       MINUS_TK error
2303                 {yyerror ("Missing term"); RECOVER}
2304 ;
2305
2306 pre_increment_expression:
2307         INCR_TK unary_expression
2308                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2309 |       INCR_TK error
2310                 {yyerror ("Missing term"); RECOVER}
2311 ;
2312
2313 pre_decrement_expression:
2314         DECR_TK unary_expression
2315                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2316 |       DECR_TK error
2317                 {yyerror ("Missing term"); RECOVER}
2318 ;
2319
2320 unary_expression_not_plus_minus:
2321         postfix_expression
2322 |       NOT_TK unary_expression
2323                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2324 |       NEG_TK unary_expression
2325                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2326 |       cast_expression
2327 |       NOT_TK error
2328                 {yyerror ("Missing term"); RECOVER}
2329 |       NEG_TK error
2330                 {yyerror ("Missing term"); RECOVER}
2331 ;
2332
2333 cast_expression:                /* Error handling here is potentially weak */
2334         OP_TK primitive_type dims CP_TK unary_expression
2335                 { 
2336                   tree type = $2;
2337                   int osb = pop_current_osb (ctxp);
2338                   while (osb--)
2339                     type = build_java_array_type (type, -1);
2340                   $$ = build_cast ($1.location, type, $5); 
2341                 }
2342 |       OP_TK primitive_type CP_TK unary_expression
2343                 { $$ = build_cast ($1.location, $2, $4); }
2344 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2345                 { $$ = build_cast ($1.location, $2, $4); }
2346 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2347                 { 
2348                   const char *ptr;
2349                   int osb = pop_current_osb (ctxp); 
2350                   while (osb--)
2351                     obstack_1grow (&temporary_obstack, '[');
2352                   obstack_grow0 (&temporary_obstack, 
2353                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2354                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2355                   ptr = obstack_finish (&temporary_obstack);
2356                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2357                   $$ = build_cast ($1.location, $2, $5);
2358                 }
2359 |       OP_TK primitive_type OSB_TK error
2360                 {yyerror ("']' expected, invalid type expression");}
2361 |       OP_TK error
2362                 {
2363                   YYNOT_TWICE yyerror ("Invalid type expression"); RECOVER;
2364                   RECOVER;
2365                 }
2366 |       OP_TK primitive_type dims CP_TK error
2367                 {yyerror ("Missing term"); RECOVER;}
2368 |       OP_TK primitive_type CP_TK error
2369                 {yyerror ("Missing term"); RECOVER;}
2370 |       OP_TK name dims CP_TK error
2371                 {yyerror ("Missing term"); RECOVER;}
2372 ;
2373
2374 multiplicative_expression:
2375         unary_expression
2376 |       multiplicative_expression MULT_TK unary_expression
2377                 { 
2378                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2379                                     $2.location, $1, $3);
2380                 }
2381 |       multiplicative_expression DIV_TK unary_expression
2382                 {
2383                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2384                                     $1, $3); 
2385                 }
2386 |       multiplicative_expression REM_TK unary_expression
2387                 {
2388                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2389                                     $1, $3); 
2390                 }
2391 |       multiplicative_expression MULT_TK error
2392                 {yyerror ("Missing term"); RECOVER;}
2393 |       multiplicative_expression DIV_TK error
2394                 {yyerror ("Missing term"); RECOVER;}
2395 |       multiplicative_expression REM_TK error
2396                 {yyerror ("Missing term"); RECOVER;}
2397 ;
2398
2399 additive_expression:
2400         multiplicative_expression
2401 |       additive_expression PLUS_TK multiplicative_expression
2402                 {
2403                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2404                                     $1, $3); 
2405                 }
2406 |       additive_expression MINUS_TK multiplicative_expression
2407                 {
2408                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2409                                     $1, $3); 
2410                 }
2411 |       additive_expression PLUS_TK error
2412                 {yyerror ("Missing term"); RECOVER;}
2413 |       additive_expression MINUS_TK error
2414                 {yyerror ("Missing term"); RECOVER;}
2415 ;
2416
2417 shift_expression:
2418         additive_expression
2419 |       shift_expression LS_TK additive_expression
2420                 {
2421                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2422                                     $1, $3); 
2423                 }
2424 |       shift_expression SRS_TK additive_expression
2425                 {
2426                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2427                                     $1, $3); 
2428                 }
2429 |       shift_expression ZRS_TK additive_expression
2430                 {
2431                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2432                                     $1, $3); 
2433                 }
2434 |       shift_expression LS_TK error
2435                 {yyerror ("Missing term"); RECOVER;}
2436 |       shift_expression SRS_TK error
2437                 {yyerror ("Missing term"); RECOVER;}
2438 |       shift_expression ZRS_TK error
2439                 {yyerror ("Missing term"); RECOVER;}
2440 ;
2441
2442 relational_expression:
2443         shift_expression
2444 |       relational_expression LT_TK shift_expression
2445                 {
2446                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2447                                     $1, $3); 
2448                 }
2449 |       relational_expression GT_TK shift_expression
2450                 {
2451                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2452                                     $1, $3); 
2453                 }
2454 |       relational_expression LTE_TK shift_expression
2455                 {
2456                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2457                                     $1, $3); 
2458                 }
2459 |       relational_expression GTE_TK shift_expression
2460                 {
2461                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2462                                     $1, $3); 
2463                 }
2464 |       relational_expression INSTANCEOF_TK reference_type
2465                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2466 |       relational_expression LT_TK error
2467                 {yyerror ("Missing term"); RECOVER;}
2468 |       relational_expression GT_TK error
2469                 {yyerror ("Missing term"); RECOVER;}
2470 |       relational_expression LTE_TK error
2471                 {yyerror ("Missing term"); RECOVER;}
2472 |       relational_expression GTE_TK error
2473                 {yyerror ("Missing term"); RECOVER;}
2474 |       relational_expression INSTANCEOF_TK error
2475                 {yyerror ("Invalid reference type"); RECOVER;}
2476 ;
2477
2478 equality_expression:
2479         relational_expression
2480 |       equality_expression EQ_TK relational_expression
2481                 {
2482                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2483                                     $1, $3); 
2484                 }
2485 |       equality_expression NEQ_TK relational_expression
2486                 {
2487                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2488                                     $1, $3); 
2489                 }
2490 |       equality_expression EQ_TK error
2491                 {yyerror ("Missing term"); RECOVER;}
2492 |       equality_expression NEQ_TK error
2493                 {yyerror ("Missing term"); RECOVER;}
2494 ;
2495
2496 and_expression:
2497         equality_expression
2498 |       and_expression AND_TK equality_expression
2499                 {
2500                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2501                                     $1, $3); 
2502                 }
2503 |       and_expression AND_TK error
2504                 {yyerror ("Missing term"); RECOVER;}
2505 ;
2506
2507 exclusive_or_expression:
2508         and_expression
2509 |       exclusive_or_expression XOR_TK and_expression
2510                 {
2511                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2512                                     $1, $3); 
2513                 }
2514 |       exclusive_or_expression XOR_TK error
2515                 {yyerror ("Missing term"); RECOVER;}
2516 ;
2517
2518 inclusive_or_expression:
2519         exclusive_or_expression
2520 |       inclusive_or_expression OR_TK exclusive_or_expression
2521                 {
2522                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2523                                     $1, $3); 
2524                 }
2525 |       inclusive_or_expression OR_TK error
2526                 {yyerror ("Missing term"); RECOVER;}
2527 ;
2528
2529 conditional_and_expression:
2530         inclusive_or_expression
2531 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2532                 {
2533                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2534                                     $1, $3); 
2535                 }
2536 |       conditional_and_expression BOOL_AND_TK error
2537                 {yyerror ("Missing term"); RECOVER;}
2538 ;
2539
2540 conditional_or_expression:
2541         conditional_and_expression
2542 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2543                 {
2544                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2545                                     $1, $3); 
2546                 }
2547 |       conditional_or_expression BOOL_OR_TK error
2548                 {yyerror ("Missing term"); RECOVER;}
2549 ;
2550
2551 conditional_expression:         /* Error handling here is weak */
2552         conditional_or_expression
2553 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2554                 {
2555                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2556                   EXPR_WFL_LINECOL ($$) = $2.location;
2557                 }
2558 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2559                 {
2560                   YYERROR_NOW;
2561                   yyerror ("Missing term");
2562                   DRECOVER (1);
2563                 }
2564 |       conditional_or_expression REL_QM_TK error
2565                 {yyerror ("Missing term"); DRECOVER (2);}
2566 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2567                 {yyerror ("Missing term"); DRECOVER (3);}
2568 ;
2569
2570 assignment_expression:
2571         conditional_expression
2572 |       assignment
2573 ;
2574
2575 assignment:
2576         left_hand_side assignment_operator assignment_expression
2577                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2578 |       left_hand_side assignment_operator error
2579                 {
2580                   YYNOT_TWICE yyerror ("Missing term");
2581                   DRECOVER (assign);
2582                 }
2583 ;
2584
2585 left_hand_side:
2586         name
2587 |       field_access
2588 |       array_access
2589 ;
2590
2591 assignment_operator:
2592         ASSIGN_ANY_TK
2593 |       ASSIGN_TK
2594 ;
2595
2596 expression:
2597         assignment_expression
2598 ;
2599
2600 constant_expression:
2601         expression
2602 ;
2603
2604 %%
2605
2606 /* Helper function to retrieve an OSB count. Should be used when the
2607    `dims:' rule is being used.  */
2608
2609 static int
2610 pop_current_osb (ctxp)
2611      struct parser_ctxt *ctxp;
2612 {
2613   int to_return;
2614
2615   if (ctxp->osb_depth < 0)
2616     abort ();
2617   
2618   to_return = CURRENT_OSB (ctxp);
2619   ctxp->osb_depth--;
2620   
2621   return to_return;
2622 }
2623
2624 \f
2625
2626 /* This section of the code deal with save/restoring parser contexts.
2627    Add mode documentation here. FIXME */
2628
2629 /* Helper function. Create a new parser context. With
2630    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2631    context is copied, otherwise, the new context is zeroed. The newly
2632    created context becomes the current one.  */
2633
2634 static void
2635 create_new_parser_context (copy_from_previous)
2636     int copy_from_previous;
2637 {
2638   struct parser_ctxt *new;
2639
2640   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2641   if (copy_from_previous)
2642     {
2643       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2644       new->saved_data_ctx = 1;
2645     }
2646   else
2647     memset ((PTR) new, 0, sizeof (struct parser_ctxt));
2648       
2649   new->next = ctxp;
2650   ctxp = new;
2651 }
2652
2653 /* Create a new parser context and make it the current one. */
2654
2655 void
2656 java_push_parser_context ()
2657 {
2658   create_new_parser_context (0);
2659 }  
2660
2661 void 
2662 java_pop_parser_context (generate)
2663      int generate;
2664 {
2665   tree current;
2666   struct parser_ctxt *toFree, *next;
2667
2668   if (!ctxp)
2669     return;
2670
2671   toFree = ctxp;
2672   next = ctxp->next;
2673   if (next)
2674     {
2675       lineno = ctxp->lineno;
2676       current_class = ctxp->class_type;
2677     }
2678
2679   /* If the old and new lexers differ, then free the old one.  */
2680   if (ctxp->lexer && next && ctxp->lexer != next->lexer)
2681     java_destroy_lexer (ctxp->lexer);
2682
2683   /* Set the single import class file flag to 0 for the current list
2684      of imported things */
2685   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2686     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 0;
2687
2688   /* And restore those of the previous context */
2689   if ((ctxp = next))            /* Assignment is really meant here */
2690     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2691       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1;
2692   
2693   /* If we pushed a context to parse a class intended to be generated,
2694      we keep it so we can remember the class. What we could actually
2695      do is to just update a list of class names.  */
2696   if (generate)
2697     {
2698       toFree->next = ctxp_for_generation;
2699       ctxp_for_generation = toFree;
2700     }
2701   else
2702     free (toFree);
2703 }
2704
2705 /* Create a parser context for the use of saving some global
2706    variables.  */
2707
2708 void
2709 java_parser_context_save_global ()
2710 {
2711   if (!ctxp)
2712     {
2713       java_push_parser_context ();
2714       ctxp->saved_data_ctx = 1;
2715     }
2716
2717   /* If this context already stores data, create a new one suitable
2718      for data storage. */
2719   else if (ctxp->saved_data)
2720     create_new_parser_context (1);
2721
2722   ctxp->lineno = lineno;
2723   ctxp->class_type = current_class;
2724   ctxp->filename = input_filename;
2725   ctxp->function_decl = current_function_decl;
2726   ctxp->saved_data = 1;
2727 }
2728
2729 /* Restore some global variables from the previous context. Make the
2730    previous context the current one.  */
2731
2732 void
2733 java_parser_context_restore_global ()
2734 {
2735   lineno = ctxp->lineno;
2736   current_class = ctxp->class_type;
2737   input_filename = ctxp->filename;
2738   if (wfl_operator)
2739     {
2740       tree s;
2741       BUILD_FILENAME_IDENTIFIER_NODE (s, input_filename);
2742       EXPR_WFL_FILENAME_NODE (wfl_operator) = s;
2743     }
2744   current_function_decl = ctxp->function_decl;
2745   ctxp->saved_data = 0;
2746   if (ctxp->saved_data_ctx)
2747     java_pop_parser_context (0);
2748 }
2749
2750 /* Suspend vital data for the current class/function being parsed so
2751    that an other class can be parsed. Used to let local/anonymous
2752    classes be parsed.  */
2753
2754 static void
2755 java_parser_context_suspend ()
2756 {
2757   /* This makes debugging through java_debug_context easier */
2758   static const char *name = "<inner buffer context>";
2759
2760   /* Duplicate the previous context, use it to save the globals we're
2761      interested in */
2762   create_new_parser_context (1);
2763   ctxp->function_decl = current_function_decl;
2764   ctxp->class_type = current_class;
2765
2766   /* Then create a new context which inherits all data from the
2767      previous one. This will be the new current context  */
2768   create_new_parser_context (1);
2769
2770   /* Help debugging */
2771   ctxp->next->filename = name;
2772 }
2773
2774 /* Resume vital data for the current class/function being parsed so
2775    that an other class can be parsed. Used to let local/anonymous
2776    classes be parsed.  The trick is the data storing file position
2777    informations must be restored to their current value, so parsing
2778    can resume as if no context was ever saved. */
2779
2780 static void
2781 java_parser_context_resume ()
2782 {
2783   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2784   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2785   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2786
2787   /* We need to inherit the list of classes to complete/generate */
2788   restored->classd_list = old->classd_list;
2789   restored->class_list = old->class_list;
2790
2791   /* Restore the current class and function from the saver */
2792   current_class = saver->class_type;
2793   current_function_decl = saver->function_decl;
2794
2795   /* Retrive the restored context */
2796   ctxp = restored;
2797
2798   /* Re-installed the data for the parsing to carry on */
2799   memcpy (&ctxp->marker_begining, &old->marker_begining, 
2800           (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2801
2802   /* Buffer context can now be discarded */
2803   free (saver);
2804   free (old);
2805 }
2806
2807 /* Add a new anchor node to which all statement(s) initializing static
2808    and non static initialized upon declaration field(s) will be
2809    linked.  */
2810
2811 static void
2812 java_parser_context_push_initialized_field ()
2813 {
2814   tree node;
2815
2816   node = build_tree_list (NULL_TREE, NULL_TREE);
2817   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2818   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2819
2820   node = build_tree_list (NULL_TREE, NULL_TREE);
2821   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2822   CPC_INITIALIZER_LIST (ctxp) = node;
2823
2824   node = build_tree_list (NULL_TREE, NULL_TREE);
2825   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2826   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2827 }
2828
2829 /* Pop the lists of initialized field. If this lists aren't empty,
2830    remember them so we can use it to create and populate the finit$
2831    or <clinit> functions. */
2832
2833 static void
2834 java_parser_context_pop_initialized_field ()
2835 {
2836   tree stmts;
2837   tree class_type = TREE_TYPE (GET_CPC ());
2838
2839   if (CPC_INITIALIZER_LIST (ctxp))
2840     {
2841       stmts = CPC_INITIALIZER_STMT (ctxp);
2842       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2843       if (stmts && !java_error_count)
2844         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2845     }
2846
2847   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2848     {
2849       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2850       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2851         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2852       /* Keep initialization in order to enforce 8.5 */
2853       if (stmts && !java_error_count)
2854         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2855     }
2856
2857   /* JDK 1.1 instance initializers */
2858   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2859     {
2860       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2861       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2862         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2863       if (stmts && !java_error_count)
2864         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2865     }
2866 }
2867
2868 static tree
2869 reorder_static_initialized (list)
2870      tree list;
2871 {
2872   /* We have to keep things in order. The alias initializer have to
2873      come first, then the initialized regular field, in reverse to
2874      keep them in lexical order. */
2875   tree marker, previous = NULL_TREE;
2876   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2877     if (TREE_CODE (marker) == TREE_LIST 
2878         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2879       break;
2880   
2881   /* No static initialized, the list is fine as is */
2882   if (!previous)
2883     list = TREE_CHAIN (marker);
2884
2885   /* No marker? reverse the whole list */
2886   else if (!marker)
2887     list = nreverse (list);
2888
2889   /* Otherwise, reverse what's after the marker and the new reordered
2890      sublist will replace the marker. */
2891   else
2892     {
2893       TREE_CHAIN (previous) = NULL_TREE;
2894       list = nreverse (list);
2895       list = chainon (TREE_CHAIN (marker), list);
2896     }
2897   return list;
2898 }
2899
2900 /* Helper functions to dump the parser context stack.  */
2901
2902 #define TAB_CONTEXT(C) \
2903   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2904
2905 static void
2906 java_debug_context_do (tab)
2907      int tab;
2908 {
2909   struct parser_ctxt *copy = ctxp;
2910   while (copy)
2911     {
2912       TAB_CONTEXT (tab);
2913       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2914       TAB_CONTEXT (tab);
2915       fprintf (stderr, "filename: %s\n", copy->filename);
2916       TAB_CONTEXT (tab);
2917       fprintf (stderr, "lineno: %d\n", copy->lineno);
2918       TAB_CONTEXT (tab);
2919       fprintf (stderr, "package: %s\n",
2920                (copy->package ? 
2921                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2922       TAB_CONTEXT (tab);
2923       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2924       TAB_CONTEXT (tab);
2925       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2926       copy = copy->next;
2927       tab += 2;
2928     }
2929 }
2930
2931 /* Dump the stacked up parser contexts. Intended to be called from a
2932    debugger.  */
2933
2934 void
2935 java_debug_context ()
2936 {
2937   java_debug_context_do (0);
2938 }
2939
2940 \f
2941
2942 /* Flag for the error report routine to issue the error the first time
2943    it's called (overriding the default behavior which is to drop the
2944    first invocation and honor the second one, taking advantage of a
2945    richer context.  */
2946 static int force_error = 0;
2947
2948 /* Reporting an constructor invocation error.  */
2949 static void
2950 parse_ctor_invocation_error ()
2951 {
2952   if (DECL_CONSTRUCTOR_P (current_function_decl))
2953     yyerror ("Constructor invocation must be first thing in a constructor"); 
2954   else
2955     yyerror ("Only constructors can invoke constructors");
2956 }
2957
2958 /* Reporting JDK1.1 features not implemented.  */
2959
2960 static tree
2961 parse_jdk1_1_error (msg)
2962     const char *msg;
2963 {
2964   sorry (": `%s' JDK1.1(TM) feature", msg);
2965   java_error_count++;
2966   return empty_stmt_node;
2967 }
2968
2969 static int do_warning = 0;
2970
2971 void
2972 yyerror (msg)
2973      const char *msg;
2974 {
2975   static java_lc elc;
2976   static int  prev_lineno;
2977   static const char *prev_msg;
2978
2979   int save_lineno;
2980   char *remainder, *code_from_source;
2981   
2982   if (!force_error && prev_lineno == lineno)
2983     return;
2984
2985   /* Save current error location but report latter, when the context is
2986      richer.  */
2987   if (ctxp->java_error_flag == 0)
2988     {
2989       ctxp->java_error_flag = 1;
2990       elc = ctxp->elc;
2991       /* Do something to use the previous line if we're reaching the
2992          end of the file... */
2993 #ifdef VERBOSE_SKELETON
2994       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2995 #endif
2996       return;
2997     }
2998
2999   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
3000   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
3001     return;
3002
3003   ctxp->java_error_flag = 0;
3004   if (do_warning)
3005     java_warning_count++;
3006   else
3007     java_error_count++;
3008   
3009   if (elc.col == 0 && msg && msg[1] == ';')
3010     {
3011       elc.col  = ctxp->p_line->char_col-1;
3012       elc.line = ctxp->p_line->lineno;
3013     }
3014
3015   save_lineno = lineno;
3016   prev_lineno = lineno = elc.line;
3017   prev_msg = msg;
3018
3019   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
3020   obstack_grow0 (&temporary_obstack, 
3021                  code_from_source, strlen (code_from_source));
3022   remainder = obstack_finish (&temporary_obstack);
3023   if (do_warning)
3024     warning ("%s.\n%s", msg, remainder);
3025   else
3026     error ("%s.\n%s", msg, remainder);
3027
3028   /* This allow us to cheaply avoid an extra 'Invalid expression
3029      statement' error report when errors have been already reported on
3030      the same line. This occurs when we report an error but don't have
3031      a synchronization point other than ';', which
3032      expression_statement is the only one to take care of.  */
3033   ctxp->prevent_ese = lineno = save_lineno;
3034 }
3035
3036 static void
3037 issue_warning_error_from_context (cl, msg, ap)
3038      tree cl;
3039      const char *msg;
3040      va_list ap;
3041 {
3042   const char *saved, *saved_input_filename;
3043   char buffer [4096];
3044   vsprintf (buffer, msg, ap);
3045   force_error = 1;
3046
3047   ctxp->elc.line = EXPR_WFL_LINENO (cl);
3048   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
3049                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
3050
3051   /* We have a CL, that's a good reason for using it if it contains data */
3052   saved = ctxp->filename;
3053   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
3054     ctxp->filename = EXPR_WFL_FILENAME (cl);
3055   saved_input_filename = input_filename;
3056   input_filename = ctxp->filename;
3057   java_error (NULL);
3058   java_error (buffer);
3059   ctxp->filename = saved;
3060   input_filename = saved_input_filename;
3061   force_error = 0;
3062 }
3063
3064 /* Issue an error message at a current source line CL */
3065
3066 void
3067 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
3068 {
3069 #ifndef ANSI_PROTOTYPES
3070   tree cl;
3071   const char *msg;
3072 #endif
3073   va_list ap;
3074
3075   VA_START (ap, msg);
3076 #ifndef ANSI_PROTOTYPES
3077   cl = va_arg (ap, tree);
3078   msg = va_arg (ap, const char *);
3079 #endif
3080   issue_warning_error_from_context (cl, msg, ap);
3081   va_end (ap);
3082 }
3083
3084 /* Issue a warning at a current source line CL */
3085
3086 static void
3087 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3088 {
3089 #ifndef ANSI_PROTOTYPES
3090   tree cl;
3091   const char *msg;
3092 #endif
3093   va_list ap;
3094
3095   VA_START (ap, msg);
3096 #ifndef ANSI_PROTOTYPES
3097   cl = va_arg (ap, tree);
3098   msg = va_arg (ap, const char *);
3099 #endif
3100
3101   force_error = do_warning = 1;
3102   issue_warning_error_from_context (cl, msg, ap);
3103   do_warning = force_error = 0;
3104   va_end (ap);
3105 }
3106
3107 static tree
3108 find_expr_with_wfl (node)
3109      tree node;
3110 {
3111   while (node)
3112     {
3113       char code;
3114       tree to_return;
3115
3116       switch (TREE_CODE (node))
3117         {
3118         case BLOCK:
3119           node = BLOCK_EXPR_BODY (node);
3120           continue;
3121
3122         case COMPOUND_EXPR:
3123           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3124           if (to_return)
3125             return to_return;
3126           node = TREE_OPERAND (node, 1);
3127           continue;
3128
3129         case LOOP_EXPR:
3130           node = TREE_OPERAND (node, 0);
3131           continue;
3132           
3133         case LABELED_BLOCK_EXPR:
3134           node = TREE_OPERAND (node, 1);
3135           continue;
3136
3137         default:
3138           code = TREE_CODE_CLASS (TREE_CODE (node));
3139           if (((code == '1') || (code == '2') || (code == 'e'))
3140               && EXPR_WFL_LINECOL (node))
3141             return node;
3142           return NULL_TREE;
3143         }
3144     }
3145   return NULL_TREE;
3146 }
3147
3148 /* Issue a missing return statement error. Uses METHOD to figure the
3149    last line of the method the error occurs in.  */
3150
3151 static void
3152 missing_return_error (method)
3153      tree method;
3154 {
3155   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3156   parse_error_context (wfl_operator, "Missing return statement");
3157 }
3158
3159 /* Issue an unreachable statement error. From NODE, find the next
3160    statement to report appropriately.  */
3161 static void
3162 unreachable_stmt_error (node)
3163      tree node;
3164 {
3165   /* Browse node to find the next expression node that has a WFL. Use
3166      the location to report the error */
3167   if (TREE_CODE (node) == COMPOUND_EXPR)
3168     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3169   else
3170     node = find_expr_with_wfl (node);
3171
3172   if (node)
3173     {
3174       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3175       parse_error_context (wfl_operator, "Unreachable statement");
3176     }
3177   else
3178     abort ();
3179 }
3180
3181 int
3182 java_report_errors ()
3183 {
3184   if (java_error_count)
3185     fprintf (stderr, "%d error%s", 
3186              java_error_count, (java_error_count == 1 ? "" : "s"));
3187   if (java_warning_count)
3188     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3189              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3190   if (java_error_count || java_warning_count)
3191     putc ('\n', stderr);
3192   return java_error_count;
3193 }
3194
3195 static char *
3196 java_accstring_lookup (flags)
3197      int flags;
3198 {
3199   static char buffer [80];
3200 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3201
3202   /* Access modifier looked-up first for easier report on forbidden
3203      access. */
3204   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3205   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3206   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3207   if (flags & ACC_STATIC) COPY_RETURN ("static");
3208   if (flags & ACC_FINAL) COPY_RETURN ("final");
3209   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3210   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3211   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3212   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3213   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3214   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3215
3216   buffer [0] = '\0';
3217   return buffer;
3218 #undef COPY_RETURN
3219 }
3220
3221 /* Issuing error messages upon redefinition of classes, interfaces or
3222    variables. */
3223
3224 static void
3225 classitf_redefinition_error (context, id, decl, cl)
3226      const char *context;
3227      tree id, decl, cl;
3228 {
3229   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3230                        context, IDENTIFIER_POINTER (id), 
3231                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3232   /* Here we should point out where its redefined. It's a unicode. FIXME */
3233 }
3234
3235 static void
3236 variable_redefinition_error (context, name, type, line)
3237      tree context, name, type;
3238      int line;
3239 {
3240   const char *type_name;
3241
3242   /* Figure a proper name for type. We might haven't resolved it */
3243   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3244     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3245   else
3246     type_name = lang_printable_name (type, 0);
3247
3248   parse_error_context (context,
3249                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3250                        IDENTIFIER_POINTER (name),
3251                        type_name, IDENTIFIER_POINTER (name), line);
3252 }
3253
3254 static tree
3255 build_array_from_name (type, type_wfl, name, ret_name)
3256      tree type, type_wfl, name, *ret_name;
3257 {
3258   int more_dims = 0;
3259   const char *string;
3260
3261   /* Eventually get more dims */
3262   string = IDENTIFIER_POINTER (name);
3263   while (string [more_dims] == '[')
3264     more_dims++;
3265   
3266   /* If we have, then craft a new type for this variable */
3267   if (more_dims)
3268     {
3269       tree save = type;
3270
3271       name = get_identifier (&string [more_dims]);
3272
3273       /* If we have a pointer, use its type */
3274       if (TREE_CODE (type) == POINTER_TYPE)
3275         type = TREE_TYPE (type);
3276
3277       /* Building the first dimension of a primitive type uses this
3278          function */
3279       if (JPRIMITIVE_TYPE_P (type))
3280         {
3281           type = build_java_array_type (type, -1);
3282           more_dims--;
3283         }
3284       /* Otherwise, if we have a WFL for this type, use it (the type
3285          is already an array on an unresolved type, and we just keep
3286          on adding dimensions) */
3287       else if (type_wfl)
3288         {
3289           int i = 0;
3290           type = type_wfl;
3291           string = IDENTIFIER_POINTER (TYPE_NAME (save));
3292           while (string[i]  == '[')
3293             ++i;
3294           more_dims += i;
3295         }
3296
3297       /* Add all the dimensions */
3298       while (more_dims--)
3299         type = build_unresolved_array_type (type);
3300
3301       /* The type may have been incomplete in the first place */
3302       if (type_wfl)
3303         type = obtain_incomplete_type (type);
3304     }
3305
3306   if (ret_name)
3307     *ret_name = name;
3308   return type;
3309 }
3310
3311 /* Build something that the type identifier resolver will identify as
3312    being an array to an unresolved type. TYPE_WFL is a WFL on a
3313    identifier. */
3314
3315 static tree
3316 build_unresolved_array_type (type_or_wfl)
3317      tree type_or_wfl;
3318 {
3319   const char *ptr;
3320   tree wfl;
3321
3322   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3323      just create a array type */
3324   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3325     return build_java_array_type (type_or_wfl, -1);
3326
3327   obstack_1grow (&temporary_obstack, '[');
3328   obstack_grow0 (&temporary_obstack,
3329                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3330                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3331   ptr = obstack_finish (&temporary_obstack);
3332   wfl = build_expr_wfl (get_identifier (ptr),
3333                         EXPR_WFL_FILENAME (type_or_wfl),
3334                         EXPR_WFL_LINENO (type_or_wfl),
3335                         EXPR_WFL_COLNO (type_or_wfl));
3336   /* Re-install the existing qualifications so that the type can be
3337      resolved properly. */
3338   EXPR_WFL_QUALIFICATION (wfl) = EXPR_WFL_QUALIFICATION (type_or_wfl);
3339   return wfl;
3340 }
3341
3342 static void
3343 parser_add_interface (class_decl, interface_decl, wfl)
3344      tree class_decl, interface_decl, wfl;
3345 {
3346   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3347     parse_error_context (wfl, "Interface `%s' repeated",
3348                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3349 }
3350
3351 /* Bulk of common class/interface checks. Return 1 if an error was
3352    encountered. TAG is 0 for a class, 1 for an interface.  */
3353
3354 static int
3355 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3356      int is_interface, flags;
3357      tree raw_name, qualified_name, decl, cl;
3358 {
3359   tree node;
3360   int sca = 0;                  /* Static class allowed */
3361   int icaf = 0;                 /* Inner class allowed flags */
3362   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3363
3364   if (!quiet_flag)
3365     fprintf (stderr, " %s%s %s", 
3366              (CPC_INNER_P () ? "inner" : ""),
3367              (is_interface ? "interface" : "class"), 
3368              IDENTIFIER_POINTER (qualified_name));
3369
3370   /* Scope of an interface/class type name:
3371        - Can't be imported by a single type import
3372        - Can't already exists in the package */
3373   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3374       && (node = find_name_in_single_imports (raw_name))
3375       && !CPC_INNER_P ())
3376     {
3377       parse_error_context 
3378         (cl, "%s name `%s' clashes with imported type `%s'",
3379          (is_interface ? "Interface" : "Class"),
3380          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3381       return 1;
3382     }
3383   if (decl && CLASS_COMPLETE_P (decl))
3384     {
3385       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3386                                    qualified_name, decl, cl);
3387       return 1;
3388     }
3389
3390   if (check_inner_class_redefinition (raw_name, cl))
3391     return 1;
3392
3393   /* If public, file name should match class/interface name, except
3394      when dealing with an inner class */
3395   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3396     {
3397       const char *f;
3398
3399       /* Contains OS dependent assumption on path separator. FIXME */
3400       for (f = &input_filename [strlen (input_filename)]; 
3401            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3402            f--)
3403         ;
3404       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3405         f++;
3406       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3407                    f , IDENTIFIER_LENGTH (raw_name)) ||
3408           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3409         parse_error_context
3410           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3411                              (is_interface ? "interface" : "class"),
3412                              IDENTIFIER_POINTER (qualified_name),
3413                              IDENTIFIER_POINTER (raw_name));
3414     }
3415
3416   /* Static classes can be declared only in top level classes. Note:
3417      once static, a inner class is a top level class. */
3418   if (flags & ACC_STATIC)
3419     {
3420       /* Catch the specific error of declaring an class inner class
3421          with no toplevel enclosing class. Prevent check_modifiers from
3422          complaining a second time */
3423       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3424         {
3425           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3426                                IDENTIFIER_POINTER (qualified_name));
3427           sca = ACC_STATIC;
3428         }
3429       /* Else, in the context of a top-level class declaration, let
3430          `check_modifiers' do its job, otherwise, give it a go */
3431       else
3432         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3433     }
3434
3435   /* Inner classes can be declared private or protected
3436      within their enclosing classes. */
3437   if (CPC_INNER_P ())
3438     {
3439       /* A class which is local to a block can't be public, private,
3440          protected or static. But it is created final, so allow this
3441          one. */
3442       if (current_function_decl)
3443         icaf = sca = uaaf = ACC_FINAL;
3444       else
3445         {
3446           check_modifiers_consistency (flags);
3447           icaf = ACC_PRIVATE|ACC_PROTECTED;
3448         }
3449     }
3450
3451   if (is_interface) 
3452     {
3453       if (CPC_INNER_P ())
3454         uaaf = INTERFACE_INNER_MODIFIERS;
3455       else
3456         uaaf = INTERFACE_MODIFIERS;
3457       
3458       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3459                        flags, uaaf);
3460     }
3461   else
3462     check_modifiers ((current_function_decl ?
3463                       "Illegal modifier `%s' for local class declaration" :
3464                       "Illegal modifier `%s' for class declaration"),
3465                      flags, uaaf|sca|icaf);
3466   return 0;
3467 }
3468
3469 static void
3470 make_nested_class_name (cpc_list)
3471      tree cpc_list;
3472 {
3473   tree name;
3474
3475   if (!cpc_list)
3476     return;
3477   else
3478     make_nested_class_name (TREE_CHAIN (cpc_list));
3479
3480   /* Pick the qualified name when dealing with the first upmost
3481      enclosing class */
3482   name = (TREE_CHAIN (cpc_list) ? 
3483           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3484   obstack_grow (&temporary_obstack,
3485                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3486   /* Why is NO_DOLLAR_IN_LABEL defined? */
3487 #if 0
3488 #ifdef NO_DOLLAR_IN_LABEL
3489   internal_error ("Can't use '$' as a separator for inner classes");
3490 #endif
3491 #endif
3492   obstack_1grow (&temporary_obstack, '$');
3493 }
3494
3495 /* Can't redefine a class already defined in an earlier scope. */
3496
3497 static int
3498 check_inner_class_redefinition (raw_name, cl)
3499      tree raw_name, cl;
3500 {
3501   tree scope_list;
3502
3503   for (scope_list = GET_CPC_LIST (); scope_list; 
3504        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3505     if (raw_name == GET_CPC_UN_NODE (scope_list))
3506       {
3507         parse_error_context 
3508           (cl, "The class name `%s' is already defined in this scope. An inner class may not have the same simple name as any of its enclosing classes",
3509            IDENTIFIER_POINTER (raw_name));
3510         return 1;
3511       }
3512   return 0;
3513 }
3514
3515 static tree
3516 find_as_inner_class (enclosing, name, cl)
3517      tree enclosing, name, cl;
3518 {
3519   tree qual, to_return;
3520   if (!enclosing)
3521     return NULL_TREE;
3522
3523   name = TYPE_NAME (name);
3524
3525   /* First search: within the scope of `enclosing', search for name */
3526   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3527     qual = EXPR_WFL_QUALIFICATION (cl);
3528   else if (cl)
3529     qual = build_tree_list (cl, NULL_TREE);
3530   else
3531     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3532   
3533   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3534     return to_return;
3535
3536   /* We're dealing with a qualified name. Try to resolve thing until
3537      we get something that is an enclosing class. */
3538   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3539     {
3540       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3541
3542       for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3543            qual = TREE_CHAIN (qual))
3544         {
3545           acc = merge_qualified_name (acc, 
3546                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3547           BUILD_PTR_FROM_NAME (ptr, acc);
3548
3549           /* Don't try to resolve ACC as a class name if it follows
3550              the current package name. We don't want to pick something
3551              that's accidentally there: for example `a.b.c' in package
3552              `a.b' shouldn't trigger loading `a' if it's there by
3553              itself. */
3554           if (ctxp->package
3555               && strstr (IDENTIFIER_POINTER (ctxp->package),
3556                          IDENTIFIER_POINTER (acc)))
3557             decl = NULL;
3558           else
3559             decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3560         }
3561
3562       /* A NULL qual and a decl means that the search ended
3563          successfully?!? We have to do something then. FIXME */
3564       
3565       if (decl)
3566         enclosing = decl;
3567       else
3568         qual = EXPR_WFL_QUALIFICATION (cl);
3569     }
3570   /* Otherwise, create a qual for the other part of the resolution. */
3571   else
3572     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3573
3574   return find_as_inner_class_do (qual, enclosing);
3575 }
3576
3577 /* We go inside the list of sub classes and try to find a way
3578    through. */
3579
3580 static tree
3581 find_as_inner_class_do (qual, enclosing)
3582      tree qual, enclosing;
3583 {
3584   if (!qual)
3585     return NULL_TREE;
3586
3587   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3588     {
3589       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3590       tree next_enclosing = NULL_TREE;
3591       tree inner_list;
3592
3593       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3594            inner_list; inner_list = TREE_CHAIN (inner_list))
3595         {
3596           if (TREE_VALUE (inner_list) == name_to_match)
3597             {
3598               next_enclosing = TREE_PURPOSE (inner_list);
3599               break;
3600             }
3601         }
3602       enclosing = next_enclosing;
3603     }
3604
3605   return (!qual && enclosing ? enclosing : NULL_TREE);
3606 }
3607
3608 /* Reach all inner classes and tie their unqualified name to a
3609    DECL. */
3610
3611 static void
3612 set_nested_class_simple_name_value (outer, set)
3613      tree outer;
3614      int set;
3615 {
3616   tree l;
3617
3618   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3619     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3620                                                 TREE_PURPOSE (l) : NULL_TREE);
3621 }
3622
3623 static void
3624 link_nested_class_to_enclosing ()
3625 {
3626   if (GET_ENCLOSING_CPC ())
3627     {
3628       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3629       DECL_INNER_CLASS_LIST (enclosing) = 
3630         tree_cons (GET_CPC (), GET_CPC_UN (),
3631                    DECL_INNER_CLASS_LIST (enclosing));
3632       enclosing = enclosing;
3633     }
3634 }
3635
3636 static tree
3637 maybe_make_nested_class_name (name)
3638      tree name;
3639 {
3640   tree id = NULL_TREE;
3641
3642   if (CPC_INNER_P ())
3643     {
3644       make_nested_class_name (GET_CPC_LIST ());
3645       obstack_grow0 (&temporary_obstack,
3646                      IDENTIFIER_POINTER (name), 
3647                      IDENTIFIER_LENGTH (name));
3648       id = get_identifier (obstack_finish (&temporary_obstack));
3649       if (ctxp->package)
3650         QUALIFIED_P (id) = 1;
3651     }
3652   return id;
3653 }
3654
3655 /* If DECL is NULL, create and push a new DECL, record the current
3656    line CL and do other maintenance things.  */
3657
3658 static tree
3659 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3660      tree decl, raw_name, qualified_name, cl;
3661 {
3662   if (!decl)
3663     decl = push_class (make_class (), qualified_name);
3664
3665   /* Take care of the file and line business */
3666   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3667   /* If we're emiting xrefs, store the line/col number information */
3668   if (flag_emit_xref)
3669     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3670   else
3671     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3672   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3673   CLASS_PARSED_P (TREE_TYPE (decl)) = 1;
3674   CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) =
3675     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3676
3677   PUSH_CPC (decl, raw_name);
3678   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3679
3680   /* Link the declaration to the already seen ones */
3681   TREE_CHAIN (decl) = ctxp->class_list;
3682   ctxp->class_list = decl;
3683
3684   /* Create a new nodes in the global lists */
3685   gclass_list = tree_cons (NULL_TREE, decl, gclass_list);
3686   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3687
3688   /* Install a new dependency list element */
3689   create_jdep_list (ctxp);
3690
3691   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3692                           IDENTIFIER_POINTER (qualified_name)));
3693   return decl;
3694 }
3695
3696 static void
3697 add_superinterfaces (decl, interface_list)
3698      tree decl, interface_list;
3699 {
3700   tree node;
3701   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3702      takes care of ensuring that:
3703        - This is an accessible interface type,
3704        - Circularity detection.
3705    parser_add_interface is then called. If present but not defined,
3706    the check operation is delayed until the super interface gets
3707    defined.  */
3708   for (node = interface_list; node; node = TREE_CHAIN (node))
3709     {
3710       tree current = TREE_PURPOSE (node);
3711       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3712       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3713         {
3714           if (!parser_check_super_interface (idecl, decl, current))
3715             parser_add_interface (decl, idecl, current);
3716         }
3717       else
3718         register_incomplete_type (JDEP_INTERFACE,
3719                                   current, decl, NULL_TREE);
3720     }
3721 }
3722
3723 /* Create an interface in pass1 and return its decl. Return the
3724    interface's decl in pass 2.  */
3725
3726 static tree
3727 create_interface (flags, id, super)
3728      int flags;
3729      tree id, super;
3730 {
3731   tree raw_name = EXPR_WFL_NODE (id);
3732   tree q_name = parser_qualified_classname (raw_name);
3733   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3734
3735   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3736
3737   /* Basic checks: scope, redefinition, modifiers */ 
3738   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3739     {
3740       PUSH_ERROR ();
3741       return NULL_TREE;
3742     }
3743
3744   /* Suspend the current parsing context if we're parsing an inner
3745      interface */
3746   if (CPC_INNER_P ())
3747     java_parser_context_suspend ();
3748
3749   /* Push a new context for (static) initialized upon declaration fields */
3750   java_parser_context_push_initialized_field ();
3751
3752   /* Interface modifiers check
3753        - public/abstract allowed (already done at that point)
3754        - abstract is obsolete (comes first, it's a warning, or should be)
3755        - Can't use twice the same (checked in the modifier rule) */
3756   if ((flags & ACC_ABSTRACT) && flag_redundant)
3757     parse_warning_context 
3758       (MODIFIER_WFL (ABSTRACT_TK),
3759        "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3760
3761   /* Create a new decl if DECL is NULL, otherwise fix it */
3762   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3763
3764   /* Set super info and mark the class a complete */
3765   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3766                   object_type_node, ctxp->interface_number);
3767   ctxp->interface_number = 0;
3768   CLASS_COMPLETE_P (decl) = 1;
3769   add_superinterfaces (decl, super);
3770
3771   return decl;
3772 }
3773
3774 /* Anonymous class counter. Will be reset to 1 every time a non
3775    anonymous class gets created. */
3776 static int anonymous_class_counter = 1;
3777
3778 /* Patch anonymous class CLASS, by either extending or implementing
3779    DEP.  */
3780
3781 static void
3782 patch_anonymous_class (type_decl, class_decl, wfl)
3783     tree type_decl, class_decl, wfl;
3784 {
3785   tree class = TREE_TYPE (class_decl);
3786   tree type =  TREE_TYPE (type_decl);
3787   tree binfo = TYPE_BINFO (class);
3788
3789   /* If it's an interface, implement it */
3790   if (CLASS_INTERFACE (type_decl))
3791     {
3792       tree s_binfo;
3793       int length;
3794
3795       if (parser_check_super_interface (type_decl, class_decl, wfl))
3796         return;
3797
3798       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3799       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3800       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3801       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3802       /* And add the interface */
3803       parser_add_interface (class_decl, type_decl, wfl);
3804     }
3805   /* Otherwise, it's a type we want to extend */
3806   else
3807     {
3808       if (parser_check_super (type_decl, class_decl, wfl))
3809         return;
3810       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3811     }
3812 }
3813
3814 static tree
3815 create_anonymous_class (location, type_name)
3816     int location;
3817     tree type_name;
3818 {
3819   char buffer [80];
3820   tree super = NULL_TREE, itf = NULL_TREE;
3821   tree id, type_decl, class;
3822
3823   /* The unqualified name of the anonymous class. It's just a number. */
3824   sprintf (buffer, "%d", anonymous_class_counter++);
3825   id = build_wfl_node (get_identifier (buffer));
3826   EXPR_WFL_LINECOL (id) = location;
3827
3828   /* We know about the type to extend/implement. We go ahead */
3829   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3830     {
3831       /* Create a class which either implements on extends the designated
3832          class. The class bears an innacessible name. */
3833       if (CLASS_INTERFACE (type_decl))
3834         {
3835           /* It's OK to modify it here. It's been already used and
3836              shouldn't be reused */
3837           ctxp->interface_number = 1;
3838           /* Interfaces should presented as a list of WFLs */
3839           itf = build_tree_list (type_name, NULL_TREE);
3840         }
3841       else
3842         super = type_name;
3843     }
3844
3845   class = create_class (ACC_FINAL, id, super, itf);
3846
3847   /* We didn't know anything about the stuff. We register a dependence. */
3848   if (!type_decl)
3849     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3850
3851   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3852   return class;
3853 }
3854
3855 /* Create a class in pass1 and return its decl. Return class
3856    interface's decl in pass 2.  */
3857
3858 static tree
3859 create_class (flags, id, super, interfaces)
3860      int flags;
3861      tree id, super, interfaces;
3862 {
3863   tree raw_name = EXPR_WFL_NODE (id);
3864   tree class_id, decl;
3865   tree super_decl_type;
3866
3867   class_id = parser_qualified_classname (raw_name);
3868   decl = IDENTIFIER_CLASS_VALUE (class_id);
3869   EXPR_WFL_NODE (id) = class_id;
3870
3871   /* Basic check: scope, redefinition, modifiers */
3872   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3873     {
3874       PUSH_ERROR ();
3875       return NULL_TREE;
3876     }
3877   
3878   /* Suspend the current parsing context if we're parsing an inner
3879      class or an anonymous class. */
3880   if (CPC_INNER_P ())
3881     java_parser_context_suspend ();
3882   /* Push a new context for (static) initialized upon declaration fields */
3883   java_parser_context_push_initialized_field ();
3884
3885   /* Class modifier check: 
3886        - Allowed modifier (already done at that point)
3887        - abstract AND final forbidden 
3888        - Public classes defined in the correct file */
3889   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3890     parse_error_context
3891       (id, "Class `%s' can't be declared both abstract and final",
3892        IDENTIFIER_POINTER (raw_name));
3893
3894   /* Create a new decl if DECL is NULL, otherwise fix it */
3895   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3896
3897   /* If SUPER exists, use it, otherwise use Object */
3898   if (super)
3899     {
3900       /* Can't extend java.lang.Object */
3901       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3902         {
3903           parse_error_context (id, "Can't extend `java.lang.Object'");
3904           return NULL_TREE;
3905         }
3906
3907       super_decl_type = 
3908         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3909     }
3910   else if (TREE_TYPE (decl) != object_type_node)
3911     super_decl_type = object_type_node;
3912   /* We're defining java.lang.Object */
3913   else
3914     super_decl_type = NULL_TREE;
3915
3916   /* A class nested in an interface is implicitly static. */
3917   if (INNER_CLASS_DECL_P (decl)
3918       && CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (DECL_CONTEXT (decl)))))
3919     {
3920       flags |= ACC_STATIC;
3921     }
3922
3923   /* Set super info and mark the class as complete. */
3924   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
3925                   ctxp->interface_number);
3926   ctxp->interface_number = 0;
3927   CLASS_COMPLETE_P (decl) = 1;
3928   add_superinterfaces (decl, interfaces);
3929
3930   /* Add the private this$<n> field, Replicate final locals still in
3931      scope as private final fields mangled like val$<local_name>.
3932      This doesn't not occur for top level (static) inner classes. */
3933   if (PURE_INNER_CLASS_DECL_P (decl))
3934     add_inner_class_fields (decl, current_function_decl);
3935
3936   /* If doing xref, store the location at which the inherited class
3937      (if any) was seen. */
3938   if (flag_emit_xref && super)
3939     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3940
3941   /* Eventually sets the @deprecated tag flag */
3942   CHECK_DEPRECATED (decl);
3943
3944   /* Reset the anonymous class counter when declaring non inner classes */
3945   if (!INNER_CLASS_DECL_P (decl))
3946     anonymous_class_counter = 1;
3947
3948   return decl;
3949 }
3950
3951 /* End a class declaration: register the statements used to create
3952    finit$ and <clinit>, pop the current class and resume the prior
3953    parser context if necessary.  */
3954
3955 static void
3956 end_class_declaration (resume)
3957      int resume;
3958 {
3959   /* If an error occured, context weren't pushed and won't need to be
3960      popped by a resume. */
3961   int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
3962
3963   java_parser_context_pop_initialized_field ();
3964   POP_CPC ();
3965   if (resume && no_error_occured)
3966     java_parser_context_resume ();
3967
3968   /* We're ending a class declaration, this is a good time to reset
3969      the interface cout. Note that might have been already done in
3970      create_interface, but if at that time an inner class was being
3971      dealt with, the interface count was reset in a context created
3972      for the sake of handling inner classes declaration. */
3973   ctxp->interface_number = 0;
3974 }
3975
3976 static void
3977 add_inner_class_fields (class_decl, fct_decl)
3978      tree class_decl;
3979      tree fct_decl;
3980 {
3981   tree block, marker, f;
3982
3983   f = add_field (TREE_TYPE (class_decl),
3984                  build_current_thisn (TREE_TYPE (class_decl)),
3985                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
3986                  ACC_PRIVATE);
3987   FIELD_THISN (f) = 1;
3988
3989   if (!fct_decl)
3990     return;
3991     
3992   for (block = GET_CURRENT_BLOCK (fct_decl); 
3993        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
3994     {
3995       tree decl;
3996       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
3997         {
3998           tree name, pname;
3999           tree wfl, init, list;
4000           
4001           /* Avoid non final arguments. */
4002           if (!LOCAL_FINAL_P (decl))
4003             continue;
4004           
4005           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
4006           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
4007           wfl = build_wfl_node (name);
4008           init = build_wfl_node (pname);
4009           /* Build an initialization for the field: it will be
4010              initialized by a parameter added to finit$, bearing a
4011              mangled name of the field itself (param$<n>.) The
4012              parameter is provided to finit$ by the constructor
4013              invoking it (hence the constructor will also feature a
4014              hidden parameter, set to the value of the outer context
4015              local at the time the inner class is created.)
4016              
4017              Note: we take into account all possible locals that can
4018              be accessed by the inner class. It's actually not trivial
4019              to minimize these aliases down to the ones really
4020              used. One way to do that would be to expand all regular
4021              methods first, then finit$ to get a picture of what's
4022              used.  It works with the exception that we would have to
4023              go back on all constructor invoked in regular methods to
4024              have their invokation reworked (to include the right amount
4025              of alias initializer parameters.)
4026
4027              The only real way around, I think, is a first pass to
4028              identify locals really used in the inner class. We leave
4029              the flag FIELD_LOCAL_ALIAS_USED around for that future
4030              use.
4031              
4032              On the other hand, it only affect local inner classes,
4033              whose constructors (and finit$ call) will be featuring
4034              unecessary arguments. It's easy for a developper to keep
4035              this number of parameter down by using the `final'
4036              keyword only when necessary. For the time being, we can
4037              issue a warning on unecessary finals. FIXME */
4038           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
4039                                    wfl, init);
4040
4041           /* Register the field. The TREE_LIST holding the part
4042              initialized/initializer will be marked ARG_FINAL_P so
4043              that the created field can be marked
4044              FIELD_LOCAL_ALIAS. */
4045           list = build_tree_list (wfl, init);
4046           ARG_FINAL_P (list) = 1;
4047           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
4048         }
4049     }
4050
4051   if (!CPC_INITIALIZER_STMT (ctxp))
4052     return;
4053
4054   /* If we ever registered an alias field, insert and marker to
4055      remeber where the list ends. The second part of the list (the one
4056      featuring initialized fields) so it can be later reversed to
4057      enforce 8.5. The marker will be removed during that operation. */
4058   marker = build_tree_list (NULL_TREE, NULL_TREE);
4059   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
4060   SET_CPC_INITIALIZER_STMT (ctxp, marker);
4061 }
4062
4063 /* Can't use lookup_field () since we don't want to load the class and
4064    can't set the CLASS_LOADED_P flag */
4065
4066 static tree
4067 find_field (class, name)
4068      tree class;
4069      tree name;
4070 {
4071   tree decl;
4072   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
4073     {
4074       if (DECL_NAME (decl) == name)
4075         return decl;
4076     }
4077   return NULL_TREE;
4078 }
4079
4080 /* Wrap around lookup_field that doesn't potentially upset the value
4081    of CLASS */
4082
4083 static tree
4084 lookup_field_wrapper (class, name)
4085      tree class, name;
4086 {
4087   tree type = class;
4088   tree decl = NULL_TREE;
4089   java_parser_context_save_global ();
4090
4091   /* Last chance: if we're within the context of an inner class, we
4092      might be trying to access a local variable defined in an outer
4093      context. We try to look for it now. */
4094   if (INNER_CLASS_TYPE_P (class) && TREE_CODE (name) == IDENTIFIER_NODE)
4095     {
4096       tree new_name;
4097       MANGLE_OUTER_LOCAL_VARIABLE_NAME (new_name, name);
4098       decl = lookup_field (&type, new_name);
4099       if (decl && decl != error_mark_node)
4100         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4101     }
4102   if (!decl || decl == error_mark_node)
4103     {
4104       type = class;
4105       decl = lookup_field (&type, name);
4106     }
4107
4108   java_parser_context_restore_global ();
4109   return decl == error_mark_node ? NULL : decl;
4110 }
4111
4112 /* Find duplicate field within the same class declarations and report
4113    the error. Returns 1 if a duplicated field was found, 0
4114    otherwise.  */
4115
4116 static int
4117 duplicate_declaration_error_p (new_field_name, new_type, cl)
4118      tree new_field_name, new_type, cl;
4119 {
4120   /* This might be modified to work with method decl as well */
4121   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4122   if (decl)
4123     {
4124       char *t1 = xstrdup (purify_type_name
4125                          ((TREE_CODE (new_type) == POINTER_TYPE 
4126                            && TREE_TYPE (new_type) == NULL_TREE) ?
4127                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4128                           lang_printable_name (new_type, 1)));
4129       /* The type may not have been completed by the time we report
4130          the error */
4131       char *t2 = xstrdup (purify_type_name
4132                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4133                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4134                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4135                           lang_printable_name (TREE_TYPE (decl), 1)));
4136       parse_error_context 
4137         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4138          t1, IDENTIFIER_POINTER (new_field_name),
4139          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4140          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4141       free (t1);
4142       free (t2);
4143       return 1;
4144     }
4145   return 0;
4146 }
4147
4148 /* Field registration routine. If TYPE doesn't exist, field
4149    declarations are linked to the undefined TYPE dependency list, to
4150    be later resolved in java_complete_class () */
4151
4152 static void
4153 register_fields (flags, type, variable_list)
4154      int flags;
4155      tree type, variable_list;
4156 {
4157   tree current, saved_type;
4158   tree class_type = NULL_TREE;
4159   int saved_lineno = lineno;
4160   int must_chain = 0;
4161   tree wfl = NULL_TREE;
4162
4163   if (GET_CPC ())
4164     class_type = TREE_TYPE (GET_CPC ());
4165
4166   if (!class_type || class_type == error_mark_node)
4167     return;
4168
4169   /* If we're adding fields to interfaces, those fields are public,
4170      static, final */
4171   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4172     {
4173       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4174                                  flags, ACC_PUBLIC, "interface field(s)");
4175       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4176                                  flags, ACC_STATIC, "interface field(s)");
4177       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4178                                  flags, ACC_FINAL, "interface field(s)");
4179       check_modifiers ("Illegal interface member modifier `%s'", flags,
4180                        INTERFACE_FIELD_MODIFIERS);
4181       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4182     }
4183
4184   /* Obtain a suitable type for resolution, if necessary */
4185   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4186
4187   /* If TYPE is fully resolved and we don't have a reference, make one */
4188   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4189
4190   for (current = variable_list, saved_type = type; current; 
4191        current = TREE_CHAIN (current), type = saved_type)
4192     {
4193       tree real_type;
4194       tree field_decl;
4195       tree cl = TREE_PURPOSE (current);
4196       tree init = TREE_VALUE (current);
4197       tree current_name = EXPR_WFL_NODE (cl);
4198
4199       /* Can't declare non-final static fields in inner classes */
4200       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4201           && !(flags & ACC_FINAL))
4202         parse_error_context 
4203           (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
4204            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4205            lang_printable_name (class_type, 0));
4206
4207       /* Process NAME, as it may specify extra dimension(s) for it */
4208       type = build_array_from_name (type, wfl, current_name, &current_name);
4209
4210       /* Type adjustment. We may have just readjusted TYPE because
4211          the variable specified more dimensions. Make sure we have
4212          a reference if we can and don't have one already. Also
4213          change the name if we have an init. */
4214       if (type != saved_type)
4215         {
4216           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4217           if (init)
4218             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4219         }
4220
4221       real_type = GET_REAL_TYPE (type);
4222       /* Check for redeclarations */
4223       if (duplicate_declaration_error_p (current_name, real_type, cl))
4224         continue;
4225
4226       /* Set lineno to the line the field was found and create a
4227          declaration for it. Eventually sets the @deprecated tag flag. */
4228       if (flag_emit_xref)
4229         lineno = EXPR_WFL_LINECOL (cl);
4230       else
4231         lineno = EXPR_WFL_LINENO (cl);
4232       field_decl = add_field (class_type, current_name, real_type, flags);
4233       CHECK_DEPRECATED (field_decl);
4234
4235       /* If the field denotes a final instance variable, then we
4236          allocate a LANG_DECL_SPECIFIC part to keep track of its
4237          initialization. We also mark whether the field was
4238          initialized upon it's declaration. We don't do that if the
4239          created field is an alias to a final local. */
4240       if (!ARG_FINAL_P (current) && (flags & ACC_FINAL))
4241         {
4242           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field_decl);
4243           DECL_FIELD_FINAL_WFL (field_decl) = cl;
4244           if ((flags & ACC_STATIC) && init)
4245             DECL_FIELD_FINAL_IUD (field_decl) = 1;
4246         }
4247
4248       /* If the couple initializer/initialized is marked ARG_FINAL_P,
4249          we mark the created field FIELD_LOCAL_ALIAS, so that we can
4250          hide parameters to this inner class finit$ and
4251          constructors. It also means that the field isn't final per
4252          say. */
4253       if (ARG_FINAL_P (current))
4254         {
4255           FIELD_LOCAL_ALIAS (field_decl) = 1;
4256           FIELD_FINAL (field_decl) = 0;
4257         }
4258       
4259       /* Check if we must chain. */
4260       if (must_chain)
4261         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4262           
4263       /* If we have an initialization value tied to the field */
4264       if (init)
4265         {
4266           /* The field is declared static */
4267           if (flags & ACC_STATIC)
4268             {
4269               /* We include the field and its initialization part into
4270                  a list used to generate <clinit>. After <clinit> is
4271                  walked, field initializations will be processed and
4272                  fields initialized with known constants will be taken
4273                  out of <clinit> and have their DECL_INITIAL set
4274                  appropriately. */
4275               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4276               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4277               if (TREE_OPERAND (init, 1) 
4278                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4279                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4280             }
4281           /* A non-static field declared with an immediate initialization is
4282              to be initialized in <init>, if any.  This field is remembered
4283              to be processed at the time of the generation of <init>. */
4284           else
4285             {
4286               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4287               SET_CPC_INITIALIZER_STMT (ctxp, init);
4288             }
4289           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4290           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4291         }
4292     }
4293   lineno = saved_lineno;
4294 }
4295
4296 /* Generate finit$, using the list of initialized fields to populate
4297    its body. finit$'s parameter(s) list is adjusted to include the
4298    one(s) used to initialized the field(s) caching outer context
4299    local(s). */
4300
4301 static tree
4302 generate_finit (class_type)
4303      tree class_type;
4304 {
4305   int count = 0;
4306   tree list = TYPE_FINIT_STMT_LIST (class_type);
4307   tree mdecl, current, parms;
4308
4309   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4310                                                   class_type, NULL_TREE, 
4311                                                   &count);
4312   CRAFTED_PARAM_LIST_FIXUP (parms);
4313   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4314                                     finit_identifier_node, parms);
4315   fix_method_argument_names (parms, mdecl);
4316   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4317                        mdecl, NULL_TREE);
4318   DECL_FUNCTION_NAP (mdecl) = count;
4319   start_artificial_method_body (mdecl);
4320
4321   for (current = list; current; current = TREE_CHAIN (current))
4322     java_method_add_stmt (mdecl, 
4323                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4324                                                 current));
4325   end_artificial_method_body (mdecl);
4326   return mdecl;
4327 }
4328
4329 static tree
4330 build_instance_initializer (mdecl)
4331      tree mdecl;
4332 {
4333   tree compound = NULL_TREE;
4334   tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
4335   tree current;
4336
4337   for (current = stmt_list; current; current = TREE_CHAIN (current))
4338     compound = add_stmt_to_compound (compound, NULL_TREE, current);
4339
4340   return compound;
4341 }
4342
4343 static void
4344 add_instance_initializer (mdecl)
4345      tree mdecl;
4346 {
4347   tree compound = build_instance_initializer (mdecl);
4348
4349   if (compound)
4350     java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
4351                                          NULL_TREE, compound));
4352 }
4353
4354 /* Shared accros method_declarator and method_header to remember the
4355    patch stage that was reached during the declaration of the method.
4356    A method DECL is built differently is there is no patch
4357    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4358    pending on the currently defined method.  */
4359
4360 static int patch_stage;
4361
4362 /* Check the method declaration and add the method to its current
4363    class.  If the argument list is known to contain incomplete types,
4364    the method is partially added and the registration will be resume
4365    once the method arguments resolved. If TYPE is NULL, we're dealing
4366    with a constructor.  */
4367
4368 static tree
4369 method_header (flags, type, mdecl, throws)
4370      int flags;
4371      tree type, mdecl, throws;
4372 {
4373   tree type_wfl = NULL_TREE;
4374   tree meth_name = NULL_TREE;
4375   tree current, orig_arg, this_class = NULL;
4376   tree id, meth;
4377   int saved_lineno;
4378   int constructor_ok = 0, must_chain;
4379   int count;
4380
4381   if (mdecl == error_mark_node)
4382     return error_mark_node;
4383   meth = TREE_VALUE (mdecl);
4384   id = TREE_PURPOSE (mdecl);
4385   
4386   check_modifiers_consistency (flags);
4387
4388   if (GET_CPC ())
4389     this_class = TREE_TYPE (GET_CPC ());
4390
4391   if (!this_class || this_class == error_mark_node)
4392     return NULL_TREE;
4393   
4394   /* There are some forbidden modifiers for an abstract method and its
4395      class must be abstract as well.  */
4396   if (type && (flags & ACC_ABSTRACT))
4397     {
4398       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4399       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4400       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4401       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4402       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4403       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4404           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4405         parse_error_context 
4406           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4407            IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())),
4408            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4409     }
4410
4411   /* Things to be checked when declaring a constructor */
4412   if (!type)
4413     {
4414       int ec = java_error_count;
4415       /* 8.6: Constructor declarations: we might be trying to define a
4416          method without specifying a return type. */
4417       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4418         parse_error_context 
4419           (id, "Invalid method declaration, return type required");
4420       /* 8.6.3: Constructor modifiers */
4421       else
4422         {
4423           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4424           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4425           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4426           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4427           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4428         }
4429       /* If we found error here, we don't consider it's OK to tread
4430          the method definition as a constructor, for the rest of this
4431          function */
4432       if (ec == java_error_count)
4433         constructor_ok = 1;
4434     }
4435
4436   /* Method declared within the scope of an interface are implicitly
4437      abstract and public. Conflicts with other erroneously provided
4438      modifiers are checked right after. */
4439
4440   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4441     {
4442       /* If FLAGS isn't set because of a modifier, turn the
4443          corresponding modifier WFL to NULL so we issue a warning on
4444          the obsolete use of the modifier */
4445       if (!(flags & ACC_PUBLIC))
4446         MODIFIER_WFL (PUBLIC_TK) = NULL;
4447       if (!(flags & ACC_ABSTRACT))
4448         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4449       flags |= ACC_PUBLIC;
4450       flags |= ACC_ABSTRACT;
4451     }
4452
4453   /* Inner class can't declare static methods */
4454   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4455     {
4456       parse_error_context 
4457         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4458          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4459          lang_printable_name (this_class, 0));
4460     }
4461
4462   /* Modifiers context reset moved up, so abstract method declaration
4463      modifiers can be later checked.  */
4464
4465   /* Set constructor returned type to void and method name to <init>,
4466      unless we found an error identifier the constructor (in which
4467      case we retain the original name) */
4468   if (!type)
4469     {
4470       type = void_type_node;
4471       if (constructor_ok)
4472         meth_name = init_identifier_node;
4473     }
4474   else
4475     meth_name = EXPR_WFL_NODE (id);
4476
4477   /* Do the returned type resolution and registration if necessary */
4478   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4479
4480   if (meth_name)
4481     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4482   EXPR_WFL_NODE (id) = meth_name;
4483   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4484
4485   if (must_chain)
4486     {
4487       patch_stage = JDEP_METHOD_RETURN;
4488       register_incomplete_type (patch_stage, type_wfl, id, type);
4489       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4490     }
4491   else
4492     TREE_TYPE (meth) = type;
4493
4494   saved_lineno = lineno;
4495   /* When defining an abstract or interface method, the curly
4496      bracket at level 1 doesn't exist because there is no function
4497      body */
4498   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4499             EXPR_WFL_LINENO (id));
4500
4501   /* Remember the original argument list */
4502   orig_arg = TYPE_ARG_TYPES (meth);
4503
4504   if (patch_stage)              /* includes ret type and/or all args */
4505     {
4506       jdep *jdep;
4507       meth = add_method_1 (this_class, flags, meth_name, meth);
4508       /* Patch for the return type */
4509       if (patch_stage == JDEP_METHOD_RETURN)
4510         {
4511           jdep = CLASSD_LAST (ctxp->classd_list);
4512           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4513         }
4514       /* This is the stop JDEP. METH allows the function's signature
4515          to be computed. */
4516       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4517     }
4518   else
4519     meth = add_method (this_class, flags, meth_name, 
4520                        build_java_signature (meth));
4521
4522   /* Remember final parameters */
4523   MARK_FINAL_PARMS (meth, orig_arg);
4524
4525   /* Fix the method argument list so we have the argument name
4526      information */
4527   fix_method_argument_names (orig_arg, meth);
4528
4529   /* Register the parameter number and re-install the current line
4530      number */
4531   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4532   lineno = saved_lineno;
4533
4534   /* Register exception specified by the `throws' keyword for
4535      resolution and set the method decl appropriate field to the list.
4536      Note: the grammar ensures that what we get here are class
4537      types. */
4538   if (throws)
4539     {
4540       throws = nreverse (throws);
4541       for (current = throws; current; current = TREE_CHAIN (current))
4542         {
4543           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4544                                     NULL_TREE, NULL_TREE);
4545           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4546             &TREE_VALUE (current);
4547         }
4548       DECL_FUNCTION_THROWS (meth) = throws;
4549     }
4550
4551   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4552     DECL_FUNCTION_WFL (meth) = id;
4553
4554   /* Set the flag if we correctly processed a constructor */
4555   if (constructor_ok)
4556     {
4557       DECL_CONSTRUCTOR_P (meth) = 1;
4558       /* Compute and store the number of artificial parameters declared
4559          for this constructor */
4560       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4561            current = TREE_CHAIN (current))
4562         if (FIELD_LOCAL_ALIAS (current))
4563           count++;
4564       DECL_FUNCTION_NAP (meth) = count;
4565     }
4566
4567   /* Eventually set the @deprecated tag flag */
4568   CHECK_DEPRECATED (meth);
4569
4570   /* If doing xref, store column and line number information instead
4571      of the line number only. */
4572   if (flag_emit_xref)
4573     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4574
4575   return meth;
4576 }
4577
4578 static void
4579 fix_method_argument_names (orig_arg, meth)
4580     tree orig_arg, meth;
4581 {
4582   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4583   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4584     {
4585       TREE_PURPOSE (arg) = this_identifier_node;
4586       arg = TREE_CHAIN (arg);
4587     }
4588   while (orig_arg != end_params_node)
4589     {
4590       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4591       orig_arg = TREE_CHAIN (orig_arg);
4592       arg = TREE_CHAIN (arg);
4593     }
4594 }
4595
4596 /* Complete the method declaration with METHOD_BODY.  */
4597
4598 static void
4599 finish_method_declaration (method_body)
4600      tree method_body;
4601 {
4602   int flags;
4603
4604   if (!current_function_decl)
4605     return;
4606
4607   flags = get_access_flags_from_decl (current_function_decl);
4608
4609   /* 8.4.5 Method Body */
4610   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4611     {
4612       tree name = DECL_NAME (current_function_decl);
4613       parse_error_context (DECL_FUNCTION_WFL (current_function_decl), 
4614                            "%s method `%s' can't have a body defined",
4615                            (METHOD_NATIVE (current_function_decl) ?
4616                             "Native" : "Abstract"),
4617                            IDENTIFIER_POINTER (name));
4618       method_body = NULL_TREE;
4619     }
4620   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4621     {
4622       tree name = DECL_NAME (current_function_decl);
4623       parse_error_context
4624         (DECL_FUNCTION_WFL (current_function_decl), 
4625          "Non native and non abstract method `%s' must have a body defined",
4626          IDENTIFIER_POINTER (name));
4627       method_body = NULL_TREE;
4628     }
4629
4630   if (flag_emit_class_files && method_body 
4631       && TREE_CODE (method_body) == NOP_EXPR 
4632       && TREE_TYPE (current_function_decl) 
4633       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4634     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4635
4636   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4637   maybe_absorb_scoping_blocks ();
4638   /* Exit function's body */
4639   exit_block ();
4640   /* Merge last line of the function with first line, directly in the
4641      function decl. It will be used to emit correct debug info. */
4642   if (!flag_emit_xref)
4643     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4644
4645   /* Since function's argument's list are shared, reset the
4646      ARG_FINAL_P parameter that might have been set on some of this
4647      function parameters. */
4648   UNMARK_FINAL_PARMS (current_function_decl);
4649   
4650   /* So we don't have an irrelevant function declaration context for
4651      the next static block we'll see. */
4652   current_function_decl = NULL_TREE;
4653 }
4654
4655 /* Build a an error message for constructor circularity errors.  */
4656
4657 static char *
4658 constructor_circularity_msg (from, to)
4659      tree from, to;
4660 {
4661   static char string [4096];
4662   char *t = xstrdup (lang_printable_name (from, 0));
4663   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4664   free (t);
4665   return string;
4666 }
4667
4668 /* Verify a circular call to METH. Return 1 if an error is found, 0
4669    otherwise.  */
4670
4671 static int
4672 verify_constructor_circularity (meth, current)
4673      tree meth, current;
4674 {
4675   static tree list = NULL_TREE;
4676   static int initialized_p;
4677   tree c;
4678
4679   /* If we haven't already registered LIST with the garbage collector,
4680      do so now.  */
4681   if (!initialized_p)
4682     {
4683       ggc_add_tree_root (&list, 1);
4684       initialized_p = 1;
4685     }
4686
4687   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4688     {
4689       if (TREE_VALUE (c) == meth)
4690         {
4691           char *t;
4692           if (list)
4693             {
4694               tree liste;
4695               list = nreverse (list);
4696               for (liste = list; liste; liste = TREE_CHAIN (liste))
4697                 {
4698                   parse_error_context 
4699                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4700                      constructor_circularity_msg
4701                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4702                   java_error_count--;
4703                 }
4704             }
4705           t = xstrdup (lang_printable_name (meth, 0));
4706           parse_error_context (TREE_PURPOSE (c), 
4707                                "%s: recursive invocation of constructor `%s'",
4708                                constructor_circularity_msg (current, meth), t);
4709           free (t);
4710           list = NULL_TREE;
4711           return 1;
4712         }
4713     }
4714   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4715     {
4716       list = tree_cons (c, current, list);
4717       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4718         return 1;
4719       list = TREE_CHAIN (list);
4720     }
4721   return 0;
4722 }
4723
4724 /* Check modifiers that can be declared but exclusively */
4725
4726 static void
4727 check_modifiers_consistency (flags)
4728      int flags;
4729 {
4730   int acc_count = 0;
4731   tree cl = NULL_TREE;
4732
4733   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4734   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4735   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4736   if (acc_count > 1)
4737     parse_error_context
4738       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4739
4740   acc_count = 0;
4741   cl = NULL_TREE;
4742   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
4743   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
4744   if (acc_count > 1)
4745     parse_error_context (cl,
4746                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4747 }
4748
4749 /* Check the methode header METH for abstract specifics features */
4750
4751 static void
4752 check_abstract_method_header (meth)
4753      tree meth;
4754 {
4755   int flags = get_access_flags_from_decl (meth);
4756
4757   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4758                               ACC_ABSTRACT, "abstract method",
4759                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4760   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4761                               ACC_PUBLIC, "abstract method",
4762                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4763
4764   check_modifiers ("Illegal modifier `%s' for interface method",
4765                   flags, INTERFACE_METHOD_MODIFIERS);
4766 }
4767
4768 /* Create a FUNCTION_TYPE node and start augmenting it with the
4769    declared function arguments. Arguments type that can't be resolved
4770    are left as they are, but the returned node is marked as containing
4771    incomplete types.  */
4772
4773 static tree
4774 method_declarator (id, list)
4775      tree id, list;
4776 {
4777   tree arg_types = NULL_TREE, current, node;
4778   tree meth = make_node (FUNCTION_TYPE);
4779   jdep *jdep;
4780
4781   patch_stage = JDEP_NO_PATCH;
4782
4783   if (GET_CPC () == error_mark_node)
4784     return error_mark_node;
4785
4786   /* If we're dealing with an inner class constructor, we hide the
4787      this$<n> decl in the name field of its parameter declaration.  We
4788      also might have to hide the outer context local alias
4789      initializers. Not done when the class is a toplevel class. */
4790   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4791       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4792     {
4793       tree aliases_list, type, thisn;
4794       /* First the aliases, linked to the regular parameters */
4795       aliases_list =
4796         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4797                                                 TREE_TYPE (GET_CPC ()),
4798                                                 NULL_TREE, NULL);
4799       list = chainon (nreverse (aliases_list), list);
4800
4801       /* Then this$<n> */
4802       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4803       thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
4804       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4805                         list);
4806     }
4807   
4808   for (current = list; current; current = TREE_CHAIN (current))
4809     {
4810       int must_chain = 0;
4811       tree wfl_name = TREE_PURPOSE (current);
4812       tree type = TREE_VALUE (current);
4813       tree name = EXPR_WFL_NODE (wfl_name);
4814       tree already, arg_node;
4815       tree type_wfl = NULL_TREE;
4816       tree real_type;
4817
4818       /* Obtain a suitable type for resolution, if necessary */
4819       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4820
4821       /* Process NAME, as it may specify extra dimension(s) for it */
4822       type = build_array_from_name (type, type_wfl, name, &name);
4823       EXPR_WFL_NODE (wfl_name) = name;
4824
4825       real_type = GET_REAL_TYPE (type);
4826       if (TREE_CODE (real_type) == RECORD_TYPE)
4827         {
4828           real_type = promote_type (real_type);
4829           if (TREE_CODE (type) == TREE_LIST)
4830             TREE_PURPOSE (type) = real_type;
4831         }
4832
4833       /* Check redefinition */
4834       for (already = arg_types; already; already = TREE_CHAIN (already))
4835         if (TREE_PURPOSE (already) == name)
4836           {
4837             parse_error_context
4838               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4839                IDENTIFIER_POINTER (name),
4840                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4841             break;
4842           }
4843
4844       /* If we've an incomplete argument type, we know there is a location
4845          to patch when the type get resolved, later.  */
4846       jdep = NULL;
4847       if (must_chain)
4848         {
4849           patch_stage = JDEP_METHOD;
4850           type = register_incomplete_type (patch_stage, 
4851                                            type_wfl, wfl_name, type);
4852           jdep = CLASSD_LAST (ctxp->classd_list);
4853           JDEP_MISC (jdep) = id;
4854         }
4855
4856       /* The argument node: a name and a (possibly) incomplete type.  */
4857       arg_node = build_tree_list (name, real_type);
4858       /* Remeber arguments declared final. */
4859       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
4860       
4861       if (jdep)
4862         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
4863       TREE_CHAIN (arg_node) = arg_types;
4864       arg_types = arg_node;
4865     }
4866   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
4867   node = build_tree_list (id, meth);
4868   return node;
4869 }
4870
4871 static int
4872 unresolved_type_p (wfl, returned)
4873      tree wfl;
4874      tree *returned;
4875      
4876 {
4877   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
4878     {
4879       if (returned)
4880         {
4881           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
4882           if (decl && current_class && (decl == TYPE_NAME (current_class)))
4883             *returned = TREE_TYPE (decl);
4884           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
4885             *returned = TREE_TYPE (GET_CPC ());
4886           else
4887             *returned = NULL_TREE;
4888         }
4889       return 1;
4890     }
4891   if (returned)
4892     *returned = wfl;
4893   return 0;
4894 }
4895
4896 /* From NAME, build a qualified identifier node using the
4897    qualification from the current package definition. */
4898
4899 static tree
4900 parser_qualified_classname (name)
4901      tree name;
4902 {
4903   tree nested_class_name;
4904
4905   if ((nested_class_name = maybe_make_nested_class_name (name)))
4906     return nested_class_name;
4907
4908   if (ctxp->package)
4909     return merge_qualified_name (ctxp->package, name);
4910   else 
4911     return name;
4912 }
4913
4914 /* Called once the type a interface extends is resolved. Returns 0 if
4915    everything is OK.  */
4916
4917 static int
4918 parser_check_super_interface (super_decl, this_decl, this_wfl)
4919      tree super_decl, this_decl, this_wfl;
4920 {
4921   tree super_type = TREE_TYPE (super_decl);
4922
4923   /* Has to be an interface */
4924   if (!CLASS_INTERFACE (super_decl))
4925     {
4926       parse_error_context 
4927         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
4928          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
4929          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
4930          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
4931           "interface" : "class"),
4932          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
4933       return 1;
4934     }
4935
4936   /* Check top-level interface access. Inner classes are subject to member 
4937      access rules (6.6.1). */
4938   if (! INNER_CLASS_P (super_type)
4939       && check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
4940     return 1;
4941
4942   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
4943                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4944                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4945   return 0;
4946 }
4947
4948 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
4949    0 if everthing is OK.  */
4950
4951 static int
4952 parser_check_super (super_decl, this_decl, wfl)
4953      tree super_decl, this_decl, wfl;
4954 {
4955   tree super_type = TREE_TYPE (super_decl);
4956
4957   /* SUPER should be a CLASS (neither an array nor an interface) */
4958   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
4959     {
4960       parse_error_context 
4961         (wfl, "Class `%s' can't subclass %s `%s'",
4962          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4963          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
4964          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4965       return 1;
4966     }
4967
4968   if (CLASS_FINAL (TYPE_NAME (super_type)))
4969     {
4970       parse_error_context (wfl, "Can't subclass final classes: %s",
4971                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4972       return 1;
4973     }
4974
4975   /* Check top-level class scope. Inner classes are subject to member access
4976      rules (6.6.1). */
4977   if (! INNER_CLASS_P (super_type)
4978       && (check_pkg_class_access (DECL_NAME (super_decl), wfl)))
4979     return 1;
4980   
4981   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
4982                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4983                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4984   return 0;
4985 }
4986
4987 /* Create a new dependency list and link it (in a LIFO manner) to the
4988    CTXP list of type dependency list.  */
4989
4990 static void
4991 create_jdep_list (ctxp)
4992      struct parser_ctxt *ctxp;
4993 {
4994   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
4995   new->first = new->last = NULL;
4996   new->next = ctxp->classd_list;
4997   ctxp->classd_list = new;
4998 }
4999
5000 static jdeplist *
5001 reverse_jdep_list (ctxp)
5002      struct parser_ctxt *ctxp;
5003 {
5004   register jdeplist *prev = NULL, *current, *next;
5005   for (current = ctxp->classd_list; current; current = next)
5006     {
5007       next = current->next;
5008       current->next = prev;
5009       prev = current;
5010     }
5011   return prev;
5012 }
5013
5014 /* Create a fake pointer based on the ID stored in
5015    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
5016    registered again. */
5017
5018 static tree
5019 obtain_incomplete_type (type_name)
5020      tree type_name;
5021 {
5022   tree ptr = NULL_TREE, name;
5023
5024   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
5025     name = EXPR_WFL_NODE (type_name);
5026   else if (INCOMPLETE_TYPE_P (type_name))
5027     name = TYPE_NAME (type_name);
5028   else
5029     abort ();
5030
5031   BUILD_PTR_FROM_NAME (ptr, name);
5032   layout_type (ptr);
5033
5034   return ptr;
5035 }
5036
5037 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
5038    non NULL instead of computing a new fake type based on WFL. The new
5039    dependency is inserted in the current type dependency list, in FIFO
5040    manner.  */
5041
5042 static tree
5043 register_incomplete_type (kind, wfl, decl, ptr)
5044      int kind;
5045      tree wfl, decl, ptr;
5046 {
5047   jdep *new = (jdep *)xmalloc (sizeof (jdep));
5048
5049   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
5050     ptr = obtain_incomplete_type (wfl);
5051
5052   JDEP_KIND (new) = kind;
5053   JDEP_DECL (new) = decl;
5054   JDEP_TO_RESOLVE (new) = ptr;
5055   JDEP_WFL (new) = wfl;
5056   JDEP_CHAIN (new) = NULL;
5057   JDEP_MISC (new) = NULL_TREE;
5058   /* For some dependencies, set the enclosing class of the current
5059      class to be the enclosing context */
5060   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE 
5061        || kind == JDEP_ANONYMOUS || kind == JDEP_FIELD)
5062       && GET_ENCLOSING_CPC ())
5063     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
5064   else
5065     JDEP_ENCLOSING (new) = GET_CPC ();
5066   JDEP_GET_PATCH (new) = (tree *)NULL;
5067
5068   JDEP_INSERT (ctxp->classd_list, new);
5069
5070   return ptr;
5071 }
5072
5073 void
5074 java_check_circular_reference ()
5075 {
5076   tree current;
5077   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5078     {
5079       tree type = TREE_TYPE (current);
5080       if (CLASS_INTERFACE (current))
5081         {
5082           /* Check all interfaces this class extends */
5083           tree basetype_vec = TYPE_BINFO_BASETYPES (type);
5084           int n, i;
5085
5086           if (!basetype_vec)
5087             return;
5088           n = TREE_VEC_LENGTH (basetype_vec);
5089           for (i = 0; i < n; i++)
5090             {
5091               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
5092               if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node 
5093                   && interface_of_p (type, BINFO_TYPE (vec_elt)))
5094                 parse_error_context (lookup_cl (current),
5095                                      "Cyclic interface inheritance");
5096             }
5097         }
5098       else
5099         if (inherits_from_p (CLASSTYPE_SUPER (type), type))
5100           parse_error_context (lookup_cl (current), 
5101                                "Cyclic class inheritance%s",
5102                                (cyclic_inheritance_report ?
5103                                 cyclic_inheritance_report : ""));
5104     }
5105 }
5106
5107 /* Augment the parameter list PARM with parameters crafted to
5108    initialize outer context locals aliases. Through ARTIFICIAL, a
5109    count is kept of the number of crafted parameters. MODE governs
5110    what eventually gets created: something suitable for a function
5111    creation or a function invocation, either the constructor or
5112    finit$.  */
5113
5114 static tree
5115 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
5116     int mode;
5117     tree class_type, parm;
5118     int *artificial;
5119 {
5120   tree field;
5121   tree additional_parms = NULL_TREE;
5122
5123   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5124     if (FIELD_LOCAL_ALIAS (field))
5125       {
5126         const char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5127         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5128         tree mangled_id;
5129
5130         switch (mode)
5131           {
5132           case AIPL_FUNCTION_DECLARATION:
5133             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5134                                                          &buffer [4]);
5135             purpose = build_wfl_node (mangled_id);
5136             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5137               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5138             else
5139               value = TREE_TYPE (field);
5140             break;
5141
5142           case AIPL_FUNCTION_CREATION:
5143             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (purpose,
5144                                                          &buffer [4]);
5145             value = TREE_TYPE (field);
5146             break;
5147
5148           case AIPL_FUNCTION_FINIT_INVOCATION:
5149             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5150                                                          &buffer [4]);
5151             /* Now, this is wrong. purpose should always be the NAME
5152                of something and value its matching value (decl, type,
5153                etc...) FIXME -- but there is a lot to fix. */
5154
5155             /* When invoked for this kind of operation, we already
5156                know whether a field is used or not. */
5157             purpose = TREE_TYPE (field);
5158             value = build_wfl_node (mangled_id);
5159             break;
5160
5161           case AIPL_FUNCTION_CTOR_INVOCATION:
5162             /* There are two case: the constructor invokation happends
5163                outside the local inner, in which case, locales from the outer
5164                context are directly used.
5165
5166                Otherwise, we fold to using the alias directly. */
5167             if (class_type == current_class)
5168               value = field;
5169             else
5170               {
5171                 name = get_identifier (&buffer[4]);
5172                 value = IDENTIFIER_LOCAL_VALUE (name);
5173               }
5174             break;
5175           }
5176         additional_parms = tree_cons (purpose, value, additional_parms);
5177         if (artificial)
5178           *artificial +=1;
5179       }
5180   if (additional_parms)
5181     {
5182       if (ANONYMOUS_CLASS_P (class_type) 
5183           && mode == AIPL_FUNCTION_CTOR_INVOCATION)
5184         additional_parms = nreverse (additional_parms);
5185       parm = chainon (additional_parms, parm);
5186     }
5187
5188    return parm;
5189 }
5190
5191 /* Craft a constructor for CLASS_DECL -- what we should do when none
5192    where found. ARGS is non NULL when a special signature must be
5193    enforced. This is the case for anonymous classes.  */
5194
5195 static void
5196 craft_constructor (class_decl, args)
5197      tree class_decl, args;
5198 {
5199   tree class_type = TREE_TYPE (class_decl);
5200   tree parm = NULL_TREE;
5201   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5202                ACC_PUBLIC : 0);
5203   int i = 0, artificial = 0;
5204   tree decl, ctor_name;
5205   char buffer [80];
5206   
5207   /* The constructor name is <init> unless we're dealing with an
5208      anonymous class, in which case the name will be fixed after having
5209      be expanded. */
5210   if (ANONYMOUS_CLASS_P (class_type))
5211     ctor_name = DECL_NAME (class_decl);
5212   else
5213     ctor_name = init_identifier_node;
5214
5215   /* If we're dealing with an inner class constructor, we hide the
5216      this$<n> decl in the name field of its parameter declaration. */
5217   if (PURE_INNER_CLASS_TYPE_P (class_type))
5218     {
5219       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5220       parm = tree_cons (build_current_thisn (class_type),
5221                         build_pointer_type (type), parm);
5222
5223       /* Some more arguments to be hidden here. The values of the local
5224          variables of the outer context that the inner class needs to see. */
5225       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5226                                                      class_type, parm, 
5227                                                      &artificial);
5228     }
5229
5230   /* Then if there are any args to be enforced, enforce them now */
5231   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5232     {
5233       sprintf (buffer, "parm%d", i++);
5234       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5235     }
5236
5237   CRAFTED_PARAM_LIST_FIXUP (parm);
5238   decl = create_artificial_method (class_type, flags, void_type_node, 
5239                                    ctor_name, parm);
5240   fix_method_argument_names (parm, decl);
5241   /* Now, mark the artificial parameters. */
5242   DECL_FUNCTION_NAP (decl) = artificial;
5243   DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
5244 }
5245
5246
5247 /* Fix the constructors. This will be called right after circular
5248    references have been checked. It is necessary to fix constructors
5249    early even if no code generation will take place for that class:
5250    some generated constructor might be required by the class whose
5251    compilation triggered this one to be simply loaded.  */
5252
5253 void
5254 java_fix_constructors ()
5255 {
5256   tree current;
5257
5258   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5259     {
5260       tree class_type = TREE_TYPE (current);
5261       int saw_ctor = 0;
5262       tree decl;
5263
5264       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5265         continue;
5266
5267       current_class = class_type;
5268       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5269         {
5270           if (DECL_CONSTRUCTOR_P (decl))
5271             {
5272               fix_constructors (decl);
5273               saw_ctor = 1;
5274             }
5275         }
5276
5277       /* Anonymous class constructor can't be generated that early. */
5278       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5279         craft_constructor (current, NULL_TREE);
5280     }
5281 }
5282
5283 /* safe_layout_class just makes sure that we can load a class without
5284    disrupting the current_class, input_file, lineno, etc, information
5285    about the class processed currently.  */
5286
5287 void
5288 safe_layout_class (class)
5289      tree class;
5290 {
5291   tree save_current_class = current_class;
5292   const char *save_input_filename = input_filename;
5293   int save_lineno = lineno;
5294
5295   layout_class (class);
5296
5297   current_class = save_current_class;
5298   input_filename = save_input_filename;
5299   lineno = save_lineno;
5300 }
5301
5302 static tree
5303 jdep_resolve_class (dep)
5304      jdep *dep;
5305 {
5306   tree decl;
5307
5308   if (JDEP_RESOLVED_P (dep))
5309     decl = JDEP_RESOLVED_DECL (dep);
5310   else
5311     {
5312       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5313                             JDEP_DECL (dep), JDEP_WFL (dep));
5314       JDEP_RESOLVED (dep, decl);
5315     }
5316     
5317   if (!decl)
5318     complete_class_report_errors (dep);
5319   else if (PURE_INNER_CLASS_DECL_P (decl))
5320     {
5321       tree inner = TREE_TYPE (decl);
5322       if (! CLASS_LOADED_P (inner))
5323         {
5324           safe_layout_class (inner);
5325           if (TYPE_SIZE (inner) == error_mark_node)
5326             TYPE_SIZE (inner) = NULL_TREE;
5327         }
5328       check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
5329     }
5330   return decl;
5331 }
5332
5333 /* Complete unsatisfied class declaration and their dependencies */
5334
5335 void
5336 java_complete_class ()
5337 {
5338   tree cclass;
5339   jdeplist *cclassd;
5340   int error_found;
5341   tree type;
5342
5343   /* Process imports */
5344   process_imports ();
5345
5346   /* Rever things so we have the right order */
5347   ctxp->class_list = nreverse (ctxp->class_list);
5348   ctxp->classd_list = reverse_jdep_list (ctxp);
5349
5350   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5351        cclass && cclassd; 
5352        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5353     {
5354       jdep *dep;
5355       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5356         {
5357           tree decl;
5358           if (!(decl = jdep_resolve_class (dep)))
5359             continue;
5360
5361           /* Now it's time to patch */
5362           switch (JDEP_KIND (dep))
5363             {
5364             case JDEP_SUPER:
5365               /* Simply patch super */
5366               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5367                 continue;
5368               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5369                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5370               break;
5371
5372             case JDEP_FIELD:
5373               {
5374                 /* We do part of the job done in add_field */
5375                 tree field_decl = JDEP_DECL (dep);
5376                 tree field_type = TREE_TYPE (decl);
5377                 if (TREE_CODE (field_type) == RECORD_TYPE)
5378                   field_type = promote_type (field_type);
5379                 TREE_TYPE (field_decl) = field_type;
5380                 DECL_ALIGN (field_decl) = 0;
5381                 DECL_USER_ALIGN (field_decl) = 0;
5382                 layout_decl (field_decl, 0);
5383                 SOURCE_FRONTEND_DEBUG 
5384                   (("Completed field/var decl `%s' with `%s'",
5385                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5386                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5387                 break;
5388               }
5389             case JDEP_METHOD:   /* We start patching a method */
5390             case JDEP_METHOD_RETURN:
5391               error_found = 0;
5392               while (1)
5393                 {
5394                   if (decl)
5395                     {
5396                       type = TREE_TYPE(decl);
5397                       if (TREE_CODE (type) == RECORD_TYPE)
5398                         type = promote_type (type);
5399                       JDEP_APPLY_PATCH (dep, type);
5400                       SOURCE_FRONTEND_DEBUG 
5401                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5402                            "Completing fct `%s' with ret type `%s'":
5403                            "Completing arg `%s' with type `%s'"),
5404                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5405                                               (JDEP_DECL_WFL (dep))),
5406                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5407                     }
5408                   else
5409                     error_found = 1;
5410                   dep = JDEP_CHAIN (dep);
5411                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5412                     break;
5413                   else
5414                     decl = jdep_resolve_class (dep);
5415                 }
5416               if (!error_found)
5417                 {
5418                   tree mdecl = JDEP_DECL (dep), signature;
5419                   /* Recompute and reset the signature, check first that
5420                      all types are now defined. If they're not,
5421                      dont build the signature. */
5422                   if (check_method_types_complete (mdecl))
5423                     {
5424                       signature = build_java_signature (TREE_TYPE (mdecl));
5425                       set_java_signature (TREE_TYPE (mdecl), signature);
5426                     }
5427                 }
5428               else
5429                 continue;
5430               break;
5431
5432             case JDEP_INTERFACE:
5433               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5434                                                 JDEP_WFL (dep)))
5435                 continue;
5436               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5437               break;
5438
5439             case JDEP_PARM:
5440             case JDEP_VARIABLE:
5441               type = TREE_TYPE(decl);
5442               if (TREE_CODE (type) == RECORD_TYPE)
5443                 type = promote_type (type);
5444               JDEP_APPLY_PATCH (dep, type);
5445               break;
5446
5447             case JDEP_TYPE:
5448               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5449               SOURCE_FRONTEND_DEBUG 
5450                 (("Completing a random type dependency on a '%s' node",
5451                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5452               break;
5453
5454             case JDEP_EXCEPTION:
5455               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5456               SOURCE_FRONTEND_DEBUG 
5457                 (("Completing `%s' `throws' argument node",
5458                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5459               break;
5460
5461             case JDEP_ANONYMOUS:
5462               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5463               break;
5464
5465             default:
5466               abort ();
5467             }
5468         }
5469     }
5470   return;
5471 }
5472
5473 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5474    array.  */
5475
5476 static tree
5477 resolve_class (enclosing, class_type, decl, cl)
5478      tree enclosing, class_type, decl, cl;
5479 {
5480   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5481   const char *base = name;
5482   tree resolved_type = TREE_TYPE (class_type);
5483   tree resolved_type_decl;
5484   
5485   if (resolved_type != NULL_TREE)
5486     {
5487       tree resolved_type_decl = TYPE_NAME (resolved_type);
5488       if (resolved_type_decl == NULL_TREE
5489           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5490         {
5491           resolved_type_decl = build_decl (TYPE_DECL,
5492                                            TYPE_NAME (class_type),
5493                                            resolved_type);
5494         }
5495       return resolved_type_decl;
5496     }
5497
5498   /* 1- Check to see if we have an array. If true, find what we really
5499      want to resolve  */
5500   while (name[0] == '[')
5501     name++;
5502   if (base != name)
5503     {
5504       TYPE_NAME (class_type) = get_identifier (name);
5505       WFL_STRIP_BRACKET (cl, cl);
5506     }
5507
5508   /* 2- Resolve the bare type */
5509   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5510                                                decl, cl)))
5511     return NULL_TREE;
5512   resolved_type = TREE_TYPE (resolved_type_decl);
5513
5514   /* 3- If we have and array, reconstruct the array down to its nesting */
5515   if (base != name)
5516     {
5517       while (base != name)
5518         {
5519           resolved_type = build_java_array_type (resolved_type, -1);
5520           name--;
5521         }
5522       /* A TYPE_NAME that is a TYPE_DECL was set in
5523          build_java_array_type, return it. */
5524       resolved_type_decl = TYPE_NAME (resolved_type);
5525     }
5526   TREE_TYPE (class_type) = resolved_type;
5527   return resolved_type_decl;
5528 }
5529
5530 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5531    are used to report error messages. Do not try to replace TYPE_NAME
5532    (class_type) by a variable, since it is changed by
5533    find_in_imports{_on_demand} and (but it doesn't really matter)
5534    qualify_and_find.  */
5535
5536 tree
5537 do_resolve_class (enclosing, class_type, decl, cl)
5538      tree enclosing, class_type, decl, cl;
5539 {
5540   tree new_class_decl, super;
5541   struct hash_table _ht, *circularity_hash = &_ht;
5542
5543   /* This hash table is used to register the classes we're going
5544      through when searching the current class as an inner class, in
5545      order to detect circular references. Remember to free it before
5546      returning the section 0- of this function. */
5547   hash_table_init (circularity_hash, hash_newfunc,
5548                    java_hash_hash_tree_node, java_hash_compare_tree_node);
5549
5550   /* 0- Search in the current class as an inner class.
5551      Maybe some code here should be added to load the class or
5552      something, at least if the class isn't an inner class and ended
5553      being loaded from class file. FIXME. */
5554   while (enclosing)
5555     {
5556       tree intermediate;
5557
5558       hash_lookup (circularity_hash, 
5559                    (const  hash_table_key) enclosing, TRUE, NULL);
5560
5561       if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
5562         {
5563           hash_table_free (circularity_hash);
5564           return new_class_decl;
5565         }
5566
5567       intermediate = enclosing;
5568       /* Explore enclosing contexts. */
5569       while (INNER_CLASS_DECL_P (intermediate))
5570         {
5571           intermediate = DECL_CONTEXT (intermediate);
5572           if ((new_class_decl = find_as_inner_class (intermediate, 
5573                                                      class_type, cl)))
5574             {
5575               hash_table_free (circularity_hash);
5576               return new_class_decl;
5577             }
5578         }
5579
5580       /* Now go to the upper classes, bail out if necessary. */
5581       super = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
5582       if (!super || super == object_type_node)
5583         break;
5584
5585       if (TREE_CODE (super) == POINTER_TYPE)
5586         super = do_resolve_class (NULL, super, NULL, NULL);
5587       else
5588         super = TYPE_NAME (super);
5589
5590       /* We may not have checked for circular inheritance yet, so do so
5591          here to prevent an infinite loop. */
5592       if (hash_lookup (circularity_hash,
5593                        (const hash_table_key) super, FALSE, NULL))
5594         {
5595           if (!cl)
5596             cl = lookup_cl (enclosing);
5597           
5598           parse_error_context
5599             (cl, "Cyclic inheritance involving %s",
5600              IDENTIFIER_POINTER (DECL_NAME (enclosing)));
5601           break;
5602         }
5603       enclosing = super;
5604     }
5605
5606   hash_table_free (circularity_hash);
5607
5608   /* 1- Check for the type in single imports. This will change
5609      TYPE_NAME() if something relevant is found */
5610   find_in_imports (class_type);
5611
5612   /* 2- And check for the type in the current compilation unit */
5613   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5614     {
5615       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5616           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5617         load_class (TYPE_NAME (class_type), 0);
5618       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5619     }
5620
5621   /* 3- Search according to the current package definition */
5622   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5623     {
5624       if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
5625                                              TYPE_NAME (class_type))))
5626         return new_class_decl;
5627     }
5628
5629   /* 4- Check the import on demands. Don't allow bar.baz to be
5630      imported from foo.* */
5631   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5632     if (find_in_imports_on_demand (class_type))
5633       return NULL_TREE;
5634
5635   /* If found in find_in_imports_on_demant, the type has already been
5636      loaded. */
5637   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5638     return new_class_decl;
5639
5640   /* 5- Try with a name qualified with the package name we've seen so far */
5641   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5642     {
5643       tree package;
5644
5645       /* If there is a current package (ctxp->package), it's the first
5646          element of package_list and we can skip it. */
5647       for (package = (ctxp->package ? 
5648                       TREE_CHAIN (package_list) : package_list);
5649            package; package = TREE_CHAIN (package))
5650         if ((new_class_decl = qualify_and_find (class_type,
5651                                                TREE_PURPOSE (package), 
5652                                                TYPE_NAME (class_type))))
5653           return new_class_decl;
5654     }
5655
5656   /* 5- Check an other compilation unit that bears the name of type */
5657   load_class (TYPE_NAME (class_type), 0);
5658   
5659   if (!cl)
5660     cl = lookup_cl (decl);
5661   
5662   /* If we don't have a value for CL, then we're being called recursively. 
5663      We can't check package access just yet, but it will be taken care of
5664      by the caller. */
5665   if (cl)
5666     {
5667       if (check_pkg_class_access (TYPE_NAME (class_type), cl))
5668         return NULL_TREE;
5669     }
5670   
5671   /* 6- Last call for a resolution */
5672   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5673 }
5674
5675 static tree
5676 qualify_and_find (class_type, package, name)
5677      tree class_type, package, name;
5678 {
5679   tree new_qualified = merge_qualified_name (package, name);
5680   tree new_class_decl;
5681
5682   if (!IDENTIFIER_CLASS_VALUE (new_qualified))
5683     load_class (new_qualified, 0);
5684   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
5685     {
5686       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5687           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5688         load_class (new_qualified, 0);
5689       TYPE_NAME (class_type) = new_qualified;
5690       return IDENTIFIER_CLASS_VALUE (new_qualified);
5691     }
5692   return NULL_TREE;
5693 }
5694
5695 /* Resolve NAME and lay it out (if not done and if not the current
5696    parsed class). Return a decl node. This function is meant to be
5697    called when type resolution is necessary during the walk pass.  */
5698
5699 static tree
5700 resolve_and_layout (something, cl)
5701      tree something;
5702      tree cl;
5703 {
5704   tree decl, decl_type;
5705
5706   /* Don't do that on the current class */
5707   if (something == current_class)
5708     return TYPE_NAME (current_class);
5709
5710   /* Don't do anything for void and other primitive types */
5711   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5712     return NULL_TREE;
5713
5714   /* Pointer types can be reall pointer types or fake pointers. When
5715      finding a real pointer, recheck for primitive types */
5716   if (TREE_CODE (something) == POINTER_TYPE)
5717     {
5718       if (TREE_TYPE (something))
5719         {
5720           something = TREE_TYPE (something);
5721           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5722             return NULL_TREE;
5723         }
5724       else
5725         something = TYPE_NAME (something);
5726     }
5727
5728   /* Don't do anything for arrays of primitive types */
5729   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5730       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5731     return NULL_TREE;
5732
5733   /* Something might be a WFL */
5734   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5735     something = EXPR_WFL_NODE (something);
5736
5737   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5738      TYPE_DECL or a real TYPE */
5739   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5740     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5741             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5742
5743   if (!(decl = resolve_no_layout (something, cl)))
5744     return NULL_TREE;
5745
5746   /* Resolve and layout if necessary */
5747   decl_type = TREE_TYPE (decl);
5748   layout_class_methods (decl_type);
5749   /* Check methods */
5750   if (CLASS_FROM_SOURCE_P (decl_type))
5751     java_check_methods (decl);
5752   /* Layout the type if necessary */ 
5753   if (decl_type != current_class && !CLASS_LOADED_P (decl_type))
5754     safe_layout_class (decl_type);
5755
5756   return decl;
5757 }
5758
5759 /* Resolve a class, returns its decl but doesn't perform any
5760    layout. The current parsing context is saved and restored */
5761
5762 static tree
5763 resolve_no_layout (name, cl)
5764      tree name, cl;
5765 {
5766   tree ptr, decl;
5767   BUILD_PTR_FROM_NAME (ptr, name);
5768   java_parser_context_save_global ();
5769   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5770   java_parser_context_restore_global ();
5771   
5772   return decl;
5773 }
5774
5775 /* Called when reporting errors. Skip leader '[' in a complex array
5776    type description that failed to be resolved.  */
5777
5778 static const char *
5779 purify_type_name (name)
5780      const char *name;
5781 {
5782   while (*name && *name == '[')
5783     name++;
5784   return name;
5785 }
5786
5787 /* The type CURRENT refers to can't be found. We print error messages.  */
5788
5789 static void
5790 complete_class_report_errors (dep)
5791      jdep *dep;
5792 {
5793   const char *name;
5794
5795   if (!JDEP_WFL (dep))
5796     return;
5797
5798   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5799   switch (JDEP_KIND (dep))
5800     {
5801     case JDEP_SUPER:
5802       parse_error_context  
5803         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5804          purify_type_name (name),
5805          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5806       break;
5807     case JDEP_FIELD:
5808       parse_error_context
5809         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5810          purify_type_name (name),
5811          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5812       break;
5813     case JDEP_METHOD:           /* Covers arguments */
5814       parse_error_context
5815         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5816          purify_type_name (name),
5817          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5818          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5819       break;
5820     case JDEP_METHOD_RETURN:    /* Covers return type */
5821       parse_error_context
5822         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
5823          purify_type_name (name),
5824          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
5825       break;
5826     case JDEP_INTERFACE:
5827       parse_error_context
5828         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
5829          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
5830          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
5831          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5832       break;
5833     case JDEP_VARIABLE:
5834       parse_error_context
5835         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
5836          purify_type_name (IDENTIFIER_POINTER 
5837                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
5838          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5839       break;
5840     case JDEP_EXCEPTION:        /* As specified by `throws' */
5841       parse_error_context 
5842           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
5843          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
5844       break;
5845     default:
5846       /* Fix for -Wall. Just break doing nothing. The error will be
5847          caught later */
5848       break;
5849     }
5850 }
5851
5852 /* Return a static string containing the DECL prototype string. If
5853    DECL is a constructor, use the class name instead of the form
5854    <init> */
5855
5856 static const char *
5857 get_printable_method_name (decl)
5858      tree decl;
5859 {
5860   const char *to_return;
5861   tree name = NULL_TREE;
5862
5863   if (DECL_CONSTRUCTOR_P (decl))
5864     {
5865       name = DECL_NAME (decl);
5866       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
5867     }
5868       
5869   to_return = lang_printable_name (decl, 0);
5870   if (DECL_CONSTRUCTOR_P (decl))
5871     DECL_NAME (decl) = name;
5872   
5873   return to_return;
5874 }
5875
5876 /* Track method being redefined inside the same class. As a side
5877    effect, set DECL_NAME to an IDENTIFIER (prior entering this
5878    function it's a FWL, so we can track errors more accurately.)  */
5879
5880 static int
5881 check_method_redefinition (class, method)
5882      tree class, method;
5883 {
5884   tree redef, sig;
5885
5886   /* There's no need to verify <clinit> and finit$ */
5887   if (DECL_CLINIT_P (method) || DECL_FINIT_P (method))
5888     return 0;
5889
5890   sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
5891   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
5892     {
5893       if (redef == method)
5894         break;
5895       if (DECL_NAME (redef) == DECL_NAME (method)
5896           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef))
5897           && !DECL_ARTIFICIAL (method))
5898         {
5899           parse_error_context 
5900             (DECL_FUNCTION_WFL (method), "Duplicate %s declaration `%s'",
5901              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
5902              get_printable_method_name (redef));
5903           return 1;
5904         }
5905     }
5906   return 0;
5907 }
5908
5909 /* Return 1 if check went ok, 0 otherwise.  */
5910 static int
5911 check_abstract_method_definitions (do_interface, class_decl, type)
5912      int do_interface;
5913      tree class_decl, type;
5914 {
5915   tree class = TREE_TYPE (class_decl);
5916   tree method, end_type;
5917   int ok = 1;
5918
5919   end_type = (do_interface ? object_type_node : type);
5920   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
5921     {
5922       tree other_super, other_method, method_sig, method_name;
5923       int found = 0;
5924       int end_type_reached = 0;
5925       
5926       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
5927         continue;
5928       
5929       /* Now verify that somewhere in between TYPE and CLASS,
5930          abstract method METHOD gets a non abstract definition
5931          that is inherited by CLASS.  */
5932       
5933       method_sig = build_java_signature (TREE_TYPE (method));
5934       method_name = DECL_NAME (method);
5935       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
5936         method_name = EXPR_WFL_NODE (method_name);
5937
5938       other_super = class;
5939       do {
5940         if (other_super == end_type)
5941           end_type_reached = 1;
5942         
5943         /* Method search */
5944         for (other_method = TYPE_METHODS (other_super); other_method;
5945             other_method = TREE_CHAIN (other_method))
5946           {
5947             tree s = build_java_signature (TREE_TYPE (other_method));
5948             tree other_name = DECL_NAME (other_method);
5949             
5950             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
5951               other_name = EXPR_WFL_NODE (other_name);
5952             if (!DECL_CLINIT_P (other_method)
5953                 && !DECL_CONSTRUCTOR_P (other_method)
5954                 && method_name == other_name
5955                 && method_sig == s
5956                 && !METHOD_ABSTRACT (other_method))
5957              {
5958                found = 1;
5959                break;
5960              }
5961           }
5962         other_super = CLASSTYPE_SUPER (other_super);
5963       } while (!end_type_reached);
5964  
5965       /* Report that abstract METHOD didn't find an implementation
5966          that CLASS can use. */
5967       if (!found)
5968         {
5969           char *t = xstrdup (lang_printable_name 
5970                             (TREE_TYPE (TREE_TYPE (method)), 0));
5971           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
5972           
5973           parse_error_context 
5974             (lookup_cl (class_decl),
5975              "Class `%s' doesn't define the abstract method `%s %s' from %s `%s'. This method must be defined or %s `%s' must be declared abstract",
5976              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5977              t, lang_printable_name (method, 0), 
5978              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
5979               "interface" : "class"),
5980              IDENTIFIER_POINTER (ccn),
5981              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
5982              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
5983           ok = 0;
5984           free (t);
5985         }
5986     }
5987
5988   if (ok && do_interface)
5989     {
5990       /* Check for implemented interfaces. */
5991       int i;
5992       tree vector = TYPE_BINFO_BASETYPES (type);
5993       for (i = 1; ok && vector && i < TREE_VEC_LENGTH (vector); i++)
5994         {
5995           tree super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5996           ok = check_abstract_method_definitions (1, class_decl, super);
5997         }
5998     }
5999
6000   return ok;
6001 }
6002
6003 /* Check that CLASS_DECL somehow implements all inherited abstract
6004    methods.  */
6005
6006 static void
6007 java_check_abstract_method_definitions (class_decl)
6008      tree class_decl;
6009 {
6010   tree class = TREE_TYPE (class_decl);
6011   tree super, vector;
6012   int i;
6013
6014   if (CLASS_ABSTRACT (class_decl))
6015     return;
6016
6017   /* Check for inherited types */
6018   super = class;
6019   do {
6020     super = CLASSTYPE_SUPER (super);
6021     check_abstract_method_definitions (0, class_decl, super);
6022   } while (super != object_type_node);
6023
6024   /* Check for implemented interfaces. */
6025   vector = TYPE_BINFO_BASETYPES (class);
6026   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
6027     {
6028       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
6029       check_abstract_method_definitions (1, class_decl, super);
6030     }
6031 }
6032
6033 /* Check all the types method DECL uses and return 1 if all of them
6034    are now complete, 0 otherwise. This is used to check whether its
6035    safe to build a method signature or not.  */
6036
6037 static int
6038 check_method_types_complete (decl)
6039      tree decl;
6040 {
6041   tree type = TREE_TYPE (decl);
6042   tree args;
6043
6044   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
6045     return 0;
6046   
6047   args = TYPE_ARG_TYPES (type);
6048   if (TREE_CODE (type) == METHOD_TYPE)
6049     args = TREE_CHAIN (args);
6050   for (; args != end_params_node; args = TREE_CHAIN (args))
6051     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
6052       return 0;
6053
6054   return 1;
6055 }
6056
6057 /* Visible interface to check methods contained in CLASS_DECL */
6058
6059 void
6060 java_check_methods (class_decl)
6061      tree class_decl;
6062 {
6063   if (CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)))
6064     return;
6065
6066   if (CLASS_INTERFACE (class_decl))
6067     java_check_abstract_methods (class_decl);
6068   else
6069     java_check_regular_methods (class_decl);
6070   
6071   CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)) = 1;
6072 }
6073
6074 /* Check all the methods of CLASS_DECL. Methods are first completed
6075    then checked according to regular method existance rules.  If no
6076    constructor for CLASS_DECL were encountered, then build its
6077    declaration.  */
6078
6079 static void
6080 java_check_regular_methods (class_decl)
6081      tree class_decl;
6082 {
6083   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
6084   tree method;
6085   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
6086   tree found = NULL_TREE;
6087   tree mthrows;
6088
6089   /* It is not necessary to check methods defined in java.lang.Object */
6090   if (class == object_type_node)
6091     return;
6092
6093   if (!TYPE_NVIRTUALS (class))
6094     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6095
6096   /* Should take interfaces into account. FIXME */
6097   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
6098     {
6099       tree sig;
6100       tree method_wfl = DECL_FUNCTION_WFL (method);
6101       int aflags;
6102
6103       /* Check for redefinitions */
6104       if (check_method_redefinition (class, method))
6105         continue;
6106
6107       /* If we see one constructor a mark so we don't generate the
6108          default one. Also skip other verifications: constructors
6109          can't be inherited hence hiden or overriden */
6110      if (DECL_CONSTRUCTOR_P (method))
6111        {
6112          saw_constructor = 1;
6113          continue;
6114        }
6115
6116       /* We verify things thrown by the method. They must inherits from
6117          java.lang.Throwable */
6118       for (mthrows = DECL_FUNCTION_THROWS (method);
6119            mthrows; mthrows = TREE_CHAIN (mthrows))
6120         {
6121           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
6122             parse_error_context 
6123               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
6124                IDENTIFIER_POINTER 
6125                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
6126         }
6127
6128       sig = build_java_argument_signature (TREE_TYPE (method));
6129       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
6130
6131       /* Inner class can't declare static methods */
6132       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
6133         {
6134           char *t = xstrdup (lang_printable_name (class, 0));
6135           parse_error_context 
6136             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
6137              lang_printable_name (method, 0), t);
6138           free (t);
6139         }
6140
6141       /* Nothing overrides or it's a private method. */
6142       if (!found)
6143         continue;
6144       if (METHOD_PRIVATE (found))
6145         {
6146           found = NULL_TREE;
6147           continue;
6148         }
6149
6150       /* If `found' is declared in an interface, make sure the
6151          modifier matches. */
6152       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6153           && clinit_identifier_node != DECL_NAME (found)
6154           && !METHOD_PUBLIC (method))
6155         {
6156           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6157           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6158                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6159                                lang_printable_name (method, 0),
6160                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6161         }
6162
6163       /* Can't override a method with the same name and different return
6164          types. */
6165       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6166         {
6167           char *t = xstrdup 
6168             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6169           parse_error_context 
6170             (method_wfl,
6171              "Method `%s' was defined with return type `%s' in class `%s'", 
6172              lang_printable_name (found, 0), t,
6173              IDENTIFIER_POINTER 
6174                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6175           free (t);
6176         }
6177
6178       aflags = get_access_flags_from_decl (found);
6179
6180       /* Can't override final. Can't override static. */
6181       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6182         {
6183           /* Static *can* override static */
6184           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6185             continue;
6186           parse_error_context 
6187             (method_wfl,
6188              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6189              (METHOD_FINAL (found) ? "Final" : "Static"),
6190              lang_printable_name (found, 0),
6191              (METHOD_FINAL (found) ? "final" : "static"),
6192              IDENTIFIER_POINTER
6193                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6194           continue;
6195         }
6196
6197       /* Static method can't override instance method. */
6198       if (METHOD_STATIC (method))
6199         {
6200           parse_error_context 
6201             (method_wfl,
6202              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6203              lang_printable_name (found, 0),
6204              IDENTIFIER_POINTER
6205                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6206           continue;
6207         }
6208
6209       /* - Overriding/hiding public must be public
6210          - Overriding/hiding protected must be protected or public
6211          - If the overriden or hidden method has default (package)
6212            access, then the overriding or hiding method must not be
6213            private; otherwise, a compile-time error occurs.  If
6214            `found' belongs to an interface, things have been already
6215            taken care of.  */
6216       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6217           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6218               || (METHOD_PROTECTED (found) 
6219                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6220               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6221                   && METHOD_PRIVATE (method))))
6222         {
6223           parse_error_context 
6224             (method_wfl,
6225              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6226              (METHOD_PUBLIC (method) ? "public" : 
6227               (METHOD_PRIVATE (method) ? "private" : "protected")),
6228              IDENTIFIER_POINTER (DECL_NAME 
6229                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6230           continue;
6231         }
6232
6233       /* Overriding methods must have compatible `throws' clauses on checked
6234          exceptions, if any */
6235       check_throws_clauses (method, method_wfl, found);
6236
6237       /* Inheriting multiple methods with the same signature. FIXME */
6238     }
6239   
6240   if (!TYPE_NVIRTUALS (class))
6241     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6242
6243   /* Search for inherited abstract method not yet implemented in this
6244      class.  */
6245   java_check_abstract_method_definitions (class_decl);
6246
6247   if (!saw_constructor)
6248     abort ();
6249 }
6250
6251 /* Return a non zero value if the `throws' clause of METHOD (if any)
6252    is incompatible with the `throws' clause of FOUND (if any).  */
6253
6254 static void
6255 check_throws_clauses (method, method_wfl, found)
6256      tree method, method_wfl, found;
6257 {
6258   tree mthrows, fthrows;
6259
6260   /* Can't check these things with class loaded from bytecode. FIXME */
6261   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6262     return;
6263
6264   for (mthrows = DECL_FUNCTION_THROWS (method);
6265        mthrows; mthrows = TREE_CHAIN (mthrows))
6266     {
6267       /* We don't verify unchecked expressions */
6268       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6269         continue;
6270       /* Checked expression must be compatible */
6271       for (fthrows = DECL_FUNCTION_THROWS (found); 
6272            fthrows; fthrows = TREE_CHAIN (fthrows))
6273         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6274           break;
6275       if (!fthrows)
6276         {
6277           parse_error_context 
6278             (method_wfl, "Invalid checked exception class `%s' in `throws' clause. The exception must be a subclass of an exception thrown by `%s' from class `%s'",
6279              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6280              lang_printable_name (found, 0),
6281              IDENTIFIER_POINTER 
6282                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6283         }
6284     }
6285 }
6286
6287 /* Check abstract method of interface INTERFACE */
6288
6289 static void
6290 java_check_abstract_methods (interface_decl)
6291      tree interface_decl;
6292 {
6293   int i, n;
6294   tree method, basetype_vec, found;
6295   tree interface = TREE_TYPE (interface_decl);
6296
6297   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6298     {
6299       /* 2- Check for double definition inside the defining interface */
6300       if (check_method_redefinition (interface, method))
6301         continue;
6302
6303       /* 3- Overriding is OK as far as we preserve the return type and
6304          the thrown exceptions (FIXME) */
6305       found = lookup_java_interface_method2 (interface, method);
6306       if (found)
6307         {
6308           char *t;
6309           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6310           parse_error_context 
6311             (DECL_FUNCTION_WFL (found),
6312              "Method `%s' was defined with return type `%s' in class `%s'",
6313              lang_printable_name (found, 0), t,
6314              IDENTIFIER_POINTER 
6315                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6316           free (t);
6317           continue;
6318         }
6319     }
6320
6321   /* 4- Inherited methods can't differ by their returned types */
6322   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6323     return;
6324   n = TREE_VEC_LENGTH (basetype_vec);
6325   for (i = 0; i < n; i++)
6326     {
6327       tree sub_interface_method, sub_interface;
6328       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6329       if (!vec_elt)
6330         continue;
6331       sub_interface = BINFO_TYPE (vec_elt);
6332       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6333            sub_interface_method;
6334            sub_interface_method = TREE_CHAIN (sub_interface_method))
6335         {
6336           found = lookup_java_interface_method2 (interface, 
6337                                                  sub_interface_method);
6338           if (found && (found != sub_interface_method))
6339             {
6340               parse_error_context 
6341                 (lookup_cl (sub_interface_method),
6342                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6343                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6344                  lang_printable_name (found, 0),
6345                  IDENTIFIER_POINTER 
6346                    (DECL_NAME (TYPE_NAME 
6347                                (DECL_CONTEXT (sub_interface_method)))),
6348                  IDENTIFIER_POINTER 
6349                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6350             }
6351         }
6352     }
6353 }
6354
6355 /* Lookup methods in interfaces using their name and partial
6356    signature. Return a matching method only if their types differ.  */
6357
6358 static tree
6359 lookup_java_interface_method2 (class, method_decl)
6360      tree class, method_decl;
6361 {
6362   int i, n;
6363   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6364
6365   if (!basetype_vec)
6366     return NULL_TREE;
6367
6368   n = TREE_VEC_LENGTH (basetype_vec);
6369   for (i = 0; i < n; i++)
6370     {
6371       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6372       if ((BINFO_TYPE (vec_elt) != object_type_node)
6373           && (to_return = 
6374               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6375         return to_return;
6376     }
6377   for (i = 0; i < n; i++)
6378     {
6379       to_return = lookup_java_interface_method2 
6380         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6381       if (to_return)
6382         return to_return;
6383     }
6384
6385   return NULL_TREE;
6386 }
6387
6388 /* Lookup method using their name and partial signature. Return a
6389    matching method only if their types differ.  */
6390
6391 static tree
6392 lookup_java_method2 (clas, method_decl, do_interface)
6393      tree clas, method_decl;
6394      int do_interface;
6395 {
6396   tree method, method_signature, method_name, method_type, name;
6397
6398   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6399   name = DECL_NAME (method_decl);
6400   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6401                  EXPR_WFL_NODE (name) : name);
6402   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6403
6404   while (clas != NULL_TREE)
6405     {
6406       for (method = TYPE_METHODS (clas);
6407            method != NULL_TREE;  method = TREE_CHAIN (method))
6408         {
6409           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6410           tree name = DECL_NAME (method);
6411           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6412                EXPR_WFL_NODE (name) : name) == method_name
6413               && method_sig == method_signature 
6414               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6415             return method;
6416         }
6417       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6418     }
6419   return NULL_TREE;
6420 }
6421
6422 /* Return the line that matches DECL line number, and try its best to
6423    position the column number. Used during error reports.  */
6424
6425 static tree
6426 lookup_cl (decl)
6427      tree decl;
6428 {
6429   static tree cl = NULL_TREE;
6430   char *line, *found;
6431   
6432   if (!decl)
6433     return NULL_TREE;
6434
6435   if (cl == NULL_TREE)
6436     {
6437       cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6438       ggc_add_tree_root (&cl, 1);
6439     }
6440
6441   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6442   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6443
6444   line = java_get_line_col (EXPR_WFL_FILENAME (cl), 
6445                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6446
6447   found = strstr ((const char *)line, 
6448                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6449   if (found)
6450     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6451
6452   return cl;
6453 }
6454
6455 /* Look for a simple name in the single-type import list */
6456
6457 static tree
6458 find_name_in_single_imports (name)
6459      tree name;
6460 {
6461   tree node;
6462
6463   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6464     if (TREE_VALUE (node) == name)
6465       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6466
6467   return NULL_TREE;
6468 }
6469
6470 /* Process all single-type import. */
6471
6472 static int
6473 process_imports ()
6474 {
6475   tree import;
6476   int error_found;
6477
6478   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6479     {
6480       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6481       char *original_name;
6482
6483       obstack_grow0 (&temporary_obstack,
6484                      IDENTIFIER_POINTER (to_be_found),
6485                      IDENTIFIER_LENGTH (to_be_found));
6486       original_name = obstack_finish (&temporary_obstack);
6487
6488       /* Don't load twice something already defined. */
6489       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6490         continue;
6491       
6492       while (1)
6493         {
6494           tree left;
6495
6496           QUALIFIED_P (to_be_found) = 1;
6497           load_class (to_be_found, 0);
6498           error_found =
6499             check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6500           
6501           /* We found it, we can bail out */
6502           if (IDENTIFIER_CLASS_VALUE (to_be_found))
6503             break;
6504
6505           /* We haven't found it. Maybe we're trying to access an
6506              inner class.  The only way for us to know is to try again
6507              after having dropped a qualifier. If we can't break it further,
6508              we have an error. */
6509           if (breakdown_qualified (&left, NULL, to_be_found))
6510             break;
6511
6512           to_be_found = left;
6513         }
6514       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6515         {
6516           parse_error_context (TREE_PURPOSE (import),
6517                                "Class or interface `%s' not found in import",
6518                                original_name);
6519           error_found = 1;
6520         }
6521
6522       obstack_free (&temporary_obstack, original_name);
6523       if (error_found)
6524         return 1;
6525     }
6526   return 0;
6527 }
6528
6529 /* Possibly find and mark a class imported by a single-type import
6530    statement.  */
6531
6532 static void
6533 find_in_imports (class_type)
6534      tree class_type;
6535 {
6536   tree import;
6537
6538   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6539     if (TREE_VALUE (import) == TYPE_NAME (class_type))
6540       {
6541         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6542         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6543       }
6544 }
6545
6546 static int
6547 note_possible_classname (name, len)
6548      const char *name;
6549      int len;
6550 {
6551   tree node;
6552   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6553     len = len - 5;
6554   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6555     len = len - 6;
6556   else
6557     return 0;
6558   node = ident_subst (name, len, "", '/', '.', "");
6559   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6560   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6561   return 1;
6562 }
6563
6564 /* Read a import directory, gathering potential match for further type
6565    references. Indifferently reads a filesystem or a ZIP archive
6566    directory.  */
6567
6568 static void
6569 read_import_dir (wfl)
6570      tree wfl;
6571 {
6572   tree package_id = EXPR_WFL_NODE (wfl);
6573   const char *package_name = IDENTIFIER_POINTER (package_id);
6574   int package_length = IDENTIFIER_LENGTH (package_id);
6575   DIR *dirp = NULL;
6576   JCF *saved_jcf = current_jcf;
6577
6578   int found = 0;
6579   int k;
6580   void *entry;
6581   struct buffer filename[1];
6582
6583
6584   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6585     return;
6586   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6587
6588   BUFFER_INIT (filename);
6589   buffer_grow (filename, package_length + 100);
6590
6591   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6592     {
6593       const char *entry_name = jcf_path_name (entry);
6594       int entry_length = strlen (entry_name);
6595       if (jcf_path_is_zipfile (entry))
6596         {
6597           ZipFile *zipf;
6598           buffer_grow (filename, entry_length);
6599           memcpy (filename->data, entry_name, entry_length - 1);
6600           filename->data[entry_length-1] = '\0';
6601           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6602           if (zipf == NULL)
6603             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6604           else
6605             {
6606               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6607               BUFFER_RESET (filename);
6608               for (k = 0; k < package_length; k++)
6609                 {
6610                   char ch = package_name[k];
6611                   *filename->ptr++ = ch == '.' ? '/' : ch;
6612                 }
6613               *filename->ptr++ = '/';
6614
6615               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6616                 {
6617                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6618                   int current_entry_len = zipd->filename_length;
6619
6620                   if (current_entry_len >= BUFFER_LENGTH (filename)
6621                       && strncmp (filename->data, current_entry, 
6622                                   BUFFER_LENGTH (filename)) != 0)
6623                     continue;
6624                   found |= note_possible_classname (current_entry,
6625                                                     current_entry_len);
6626                 }
6627             }
6628         }
6629       else
6630         {
6631           BUFFER_RESET (filename);
6632           buffer_grow (filename, entry_length + package_length + 4);
6633           strcpy (filename->data, entry_name);
6634           filename->ptr = filename->data + entry_length;
6635           for (k = 0; k < package_length; k++)
6636             {
6637               char ch = package_name[k];
6638               *filename->ptr++ = ch == '.' ? '/' : ch;
6639             }
6640           *filename->ptr = '\0';
6641
6642           dirp = opendir (filename->data);
6643           if (dirp == NULL)
6644             continue;
6645           *filename->ptr++ = '/';
6646           for (;;)
6647             {
6648               int len; 
6649               const char *d_name;
6650               struct dirent *direntp = readdir (dirp);
6651               if (!direntp)
6652                 break;
6653               d_name = direntp->d_name;
6654               len = strlen (direntp->d_name);
6655               buffer_grow (filename, len+1);
6656               strcpy (filename->ptr, d_name);
6657               found |= note_possible_classname (filename->data + entry_length,
6658                                                 package_length+len+1);
6659             }
6660           if (dirp)
6661             closedir (dirp);
6662         }
6663     }
6664
6665   free (filename->data);
6666
6667   /* Here we should have a unified way of retrieving an entry, to be
6668      indexed. */
6669   if (!found)
6670     {
6671       static int first = 1;
6672       if (first)
6673         {
6674           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6675           java_error_count++;
6676           first = 0;
6677         }
6678       else
6679         parse_error_context (wfl, "Package `%s' not found in import",
6680                              package_name);
6681       current_jcf = saved_jcf;
6682       return;
6683     }
6684   current_jcf = saved_jcf;
6685 }
6686
6687 /* Possibly find a type in the import on demands specified
6688    types. Returns 1 if an error occured, 0 otherwise. Run throught the
6689    entire list, to detected potential double definitions.  */
6690                  
6691 static int
6692 find_in_imports_on_demand (class_type)
6693      tree class_type;
6694 {
6695   tree node, import, node_to_use = NULL_TREE;
6696   int seen_once = -1;
6697   tree cl = NULL_TREE;
6698
6699   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6700     {
6701       const char *id_name;
6702       obstack_grow (&temporary_obstack, 
6703                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6704                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6705       obstack_1grow (&temporary_obstack, '.');
6706       obstack_grow0 (&temporary_obstack, 
6707                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6708                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6709       id_name = obstack_finish (&temporary_obstack);
6710               
6711       node = maybe_get_identifier (id_name);
6712       if (node && IS_A_CLASSFILE_NAME (node))
6713         {
6714           if (seen_once < 0)
6715             {
6716               cl = TREE_PURPOSE (import);
6717               seen_once = 1;
6718               node_to_use = node;
6719             }
6720           else
6721             {
6722               seen_once++;
6723               parse_error_context 
6724                 (TREE_PURPOSE (import), 
6725                  "Type `%s' also potentially defined in package `%s'",
6726                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6727                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6728             }
6729         }
6730     }
6731
6732   if (seen_once == 1)
6733     {
6734       /* Setup lineno so that it refers to the line of the import (in
6735          case we parse a class file and encounter errors */
6736       tree decl;
6737       int saved_lineno = lineno;
6738       lineno = EXPR_WFL_LINENO (cl);
6739       TYPE_NAME (class_type) = node_to_use;
6740       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6741       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6742       /* If there is no DECL set for the class or if the class isn't
6743          loaded and not seen in source yet, the load */
6744       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6745                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6746         {
6747           load_class (node_to_use, 0);
6748           decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6749         }
6750       lineno = saved_lineno;
6751       if (! INNER_CLASS_P (TREE_TYPE (decl)))
6752         return check_pkg_class_access (TYPE_NAME (class_type), cl);
6753       else
6754         /* 6.6.1: Inner classes are subject to member access rules. */
6755         return 0;
6756     }
6757   else
6758     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6759 }
6760
6761 /* Add package NAME to the list of package encountered so far. To
6762    speed up class lookup in do_resolve_class, we make sure a
6763    particular package is added only once.  */
6764
6765 static void
6766 register_package (name)
6767      tree name;
6768 {
6769   static struct hash_table _pht, *pht = NULL;
6770
6771   if (!pht)
6772     {
6773       hash_table_init (&_pht, hash_newfunc, 
6774                        java_hash_hash_tree_node, java_hash_compare_tree_node);
6775       pht = &_pht;
6776     }
6777   
6778   if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
6779     {
6780       package_list = chainon (package_list, build_tree_list (name, NULL));
6781       hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
6782     }
6783 }
6784
6785 static tree
6786 resolve_package (pkg, next)
6787      tree pkg, *next;
6788 {
6789   tree current, acc;
6790   tree type_name = NULL_TREE;
6791   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6792
6793   /* The trick is to determine when the package name stops and were
6794      the name of something contained in the package starts. Then we
6795      return a fully qualified name of what we want to get. */
6796
6797   /* Do a quick search on well known package names */
6798   if (!strncmp (name, "java.lang.reflect", 17))
6799     {
6800       *next = 
6801         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6802       type_name = lookup_package_type (name, 17);
6803     }
6804   else if (!strncmp (name, "java.lang", 9))
6805     {
6806       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6807       type_name = lookup_package_type (name, 9);
6808     }
6809
6810   /* If we found something here, return */
6811   if (type_name)
6812     return type_name; 
6813
6814   *next = EXPR_WFL_QUALIFICATION (pkg);
6815
6816   /* Try to progressively construct a type name */
6817   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6818     for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
6819          current; current = TREE_CHAIN (current))
6820       {
6821         acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
6822         if ((type_name = resolve_no_layout (acc, NULL_TREE)))
6823           {
6824             type_name = acc;
6825             /* resolve_package should be used in a loop, hence we
6826                point at this one to naturally process the next one at
6827                the next iteration. */
6828             *next = current;
6829             break;
6830           }
6831       }
6832   return type_name;
6833 }
6834
6835 static tree
6836 lookup_package_type (name, from)
6837      const char *name;
6838      int from;
6839 {
6840   char subname [128];
6841   const char *sub = &name[from+1];
6842   while (*sub != '.' && *sub)
6843     sub++;
6844   strncpy (subname, name, sub-name);
6845   subname [sub-name] = '\0';
6846   return get_identifier (subname);
6847 }
6848
6849 /* Check accessibility of inner classes according to member access rules. 
6850    DECL is the inner class, ENCLOSING_DECL is the class from which the
6851    access is being attempted. */
6852
6853 static void
6854 check_inner_class_access (decl, enclosing_decl, cl)
6855      tree decl, enclosing_decl, cl;
6856 {
6857   const char *access;
6858   tree enclosing_decl_type;
6859
6860   /* We don't issue an error message when CL is null. CL can be null
6861      as a result of processing a JDEP crafted by source_start_java_method
6862      for the purpose of patching its parm decl. But the error would
6863      have been already trapped when fixing the method's signature.
6864      DECL can also be NULL in case of earlier errors. */
6865   if (!decl || !cl)
6866     return;
6867
6868   enclosing_decl_type = TREE_TYPE (enclosing_decl);
6869
6870   if (CLASS_PRIVATE (decl))
6871     {
6872       /* Access is permitted only within the body of the top-level
6873          class in which DECL is declared. */
6874       tree top_level = decl;
6875       while (DECL_CONTEXT (top_level))
6876         top_level = DECL_CONTEXT (top_level);      
6877       while (DECL_CONTEXT (enclosing_decl))
6878         enclosing_decl = DECL_CONTEXT (enclosing_decl);
6879       if (top_level == enclosing_decl)
6880         return;      
6881       access = "private";
6882     }
6883   else if (CLASS_PROTECTED (decl))
6884     {
6885       tree decl_context;
6886       /* Access is permitted from within the same package... */
6887       if (in_same_package (decl, enclosing_decl))
6888         return;
6889       
6890       /* ... or from within the body of a subtype of the context in which
6891          DECL is declared. */
6892       decl_context = DECL_CONTEXT (decl);
6893       while (enclosing_decl)
6894         {
6895           if (CLASS_INTERFACE (decl))
6896             {
6897               if (interface_of_p (TREE_TYPE (decl_context), 
6898                                   enclosing_decl_type))
6899                 return;
6900             }
6901           else
6902             {
6903               /* Eww. The order of the arguments is different!! */
6904               if (inherits_from_p (enclosing_decl_type, 
6905                                    TREE_TYPE (decl_context)))
6906                 return;
6907             }
6908           enclosing_decl = DECL_CONTEXT (enclosing_decl);
6909         }      
6910       access = "protected";
6911     }
6912   else if (! CLASS_PUBLIC (decl))
6913     {
6914       /* Access is permitted only from within the same package as DECL. */
6915       if (in_same_package (decl, enclosing_decl))
6916         return;
6917       access = "non-public";
6918     }
6919   else
6920     /* Class is public. */
6921     return;
6922
6923   parse_error_context (cl, "Nested %s %s is %s; cannot be accessed from here",
6924                        (CLASS_INTERFACE (decl) ? "interface" : "class"),
6925                        lang_printable_name (decl, 0), access);
6926 }
6927
6928 /* Accessibility check for top-level classes. If CLASS_NAME is in a foreign 
6929    package, it must be PUBLIC. Return 0 if no access violations were found, 
6930    1 otherwise.  */
6931
6932 static int
6933 check_pkg_class_access (class_name, cl)
6934      tree class_name;
6935      tree cl;
6936 {
6937   tree type;
6938
6939   if (!IDENTIFIER_CLASS_VALUE (class_name))
6940     return 0;
6941
6942   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
6943     return 0;
6944
6945   if (!CLASS_PUBLIC (TYPE_NAME (type)))
6946     {
6947       /* Access to a private class within the same package is
6948          allowed. */
6949       tree l, r;
6950       breakdown_qualified (&l, &r, class_name);
6951       if (!QUALIFIED_P (class_name) && !ctxp->package)
6952         /* Both in the empty package. */
6953         return 0;
6954       if (l == ctxp->package)
6955         /* Both in the same package. */
6956         return 0;
6957
6958       parse_error_context 
6959         (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
6960          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
6961          IDENTIFIER_POINTER (class_name));
6962       return 1;
6963     }
6964   return 0;
6965 }
6966
6967 /* Local variable declaration. */
6968
6969 static void
6970 declare_local_variables (modifier, type, vlist)
6971      int modifier;
6972      tree type;
6973      tree vlist;
6974 {
6975   tree decl, current, saved_type;
6976   tree type_wfl = NULL_TREE;
6977   int must_chain = 0;
6978   int final_p = 0;
6979
6980   /* Push a new block if statements were seen between the last time we
6981      pushed a block and now. Keep a count of blocks to close */
6982   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
6983     {
6984       tree b = enter_block ();
6985       BLOCK_IS_IMPLICIT (b) = 1;
6986     }
6987
6988   if (modifier)
6989     {
6990       int i;
6991       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
6992       if (modifier == ACC_FINAL)
6993         final_p = 1;
6994       else 
6995         {
6996           parse_error_context 
6997             (ctxp->modifier_ctx [i], 
6998              "Only `final' is allowed as a local variables modifier");
6999           return;
7000         }
7001     }
7002
7003   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
7004      hold the TYPE value if a new incomplete has to be created (as
7005      opposed to being found already existing and reused). */
7006   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
7007
7008   /* If TYPE is fully resolved and we don't have a reference, make one */
7009   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
7010
7011   /* Go through all the declared variables */
7012   for (current = vlist, saved_type = type; current;
7013        current = TREE_CHAIN (current), type = saved_type)
7014     {
7015       tree other, real_type;
7016       tree wfl  = TREE_PURPOSE (current);
7017       tree name = EXPR_WFL_NODE (wfl);
7018       tree init = TREE_VALUE (current);
7019
7020       /* Process NAME, as it may specify extra dimension(s) for it */
7021       type = build_array_from_name (type, type_wfl, name, &name);
7022
7023       /* Variable redefinition check */
7024       if ((other = lookup_name_in_blocks (name)))
7025         {
7026           variable_redefinition_error (wfl, name, TREE_TYPE (other),
7027                                        DECL_SOURCE_LINE (other));
7028           continue;
7029         }
7030
7031       /* Type adjustment. We may have just readjusted TYPE because
7032          the variable specified more dimensions. Make sure we have
7033          a reference if we can and don't have one already. */
7034       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
7035
7036       real_type = GET_REAL_TYPE (type);
7037       /* Never layout this decl. This will be done when its scope
7038          will be entered */
7039       decl = build_decl (VAR_DECL, name, real_type);
7040       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
7041       LOCAL_FINAL (decl) = final_p;
7042       BLOCK_CHAIN_DECL (decl);
7043       
7044       /* If doing xreferencing, replace the line number with the WFL
7045          compound value */
7046       if (flag_emit_xref)
7047         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
7048       
7049       /* Don't try to use an INIT statement when an error was found */
7050       if (init && java_error_count)
7051         init = NULL_TREE;
7052       
7053       /* Add the initialization function to the current function's code */
7054       if (init)
7055         {
7056           /* Name might have been readjusted */
7057           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
7058           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
7059           java_method_add_stmt (current_function_decl,
7060                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
7061                                                       init));
7062         }
7063     
7064       /* Setup dependency the type of the decl */
7065       if (must_chain)
7066         {
7067           jdep *dep;
7068           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
7069           dep = CLASSD_LAST (ctxp->classd_list);
7070           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
7071         }
7072     }
7073   SOURCE_FRONTEND_DEBUG (("Defined locals"));
7074 }
7075
7076 /* Called during parsing. Build decls from argument list.  */
7077
7078 static void
7079 source_start_java_method (fndecl)
7080      tree fndecl;
7081 {
7082   tree tem;
7083   tree parm_decl;
7084   int i;
7085
7086   if (!fndecl)
7087     return;
7088
7089   current_function_decl = fndecl;
7090
7091   /* New scope for the function */
7092   enter_block ();
7093   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
7094        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
7095     {
7096       tree type = TREE_VALUE (tem);
7097       tree name = TREE_PURPOSE (tem);
7098       
7099       /* If type is incomplete. Create an incomplete decl and ask for
7100          the decl to be patched later */
7101       if (INCOMPLETE_TYPE_P (type))
7102         {
7103           jdep *jdep;
7104           tree real_type = GET_REAL_TYPE (type);
7105           parm_decl = build_decl (PARM_DECL, name, real_type);
7106           type = obtain_incomplete_type (type);
7107           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
7108           jdep = CLASSD_LAST (ctxp->classd_list);
7109           JDEP_MISC (jdep) = name;
7110           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
7111         }
7112       else
7113         parm_decl = build_decl (PARM_DECL, name, type);
7114
7115       /* Remember if a local variable was declared final (via its
7116          TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
7117       if (ARG_FINAL_P (tem))
7118         {
7119           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (parm_decl);
7120           LOCAL_FINAL (parm_decl) = 1;
7121         }
7122
7123       BLOCK_CHAIN_DECL (parm_decl);
7124     }
7125   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7126   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
7127     nreverse (tem);
7128   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
7129   DECL_MAX_LOCALS (current_function_decl) = i;
7130 }
7131
7132 /* Called during parsing. Creates an artificial method declaration.  */
7133
7134 static tree
7135 create_artificial_method (class, flags, type, name, args)
7136      tree class;
7137      int flags;
7138      tree type, name, args;
7139 {
7140   tree mdecl;
7141
7142   java_parser_context_save_global ();
7143   lineno = 0;                                                               
7144   mdecl = make_node (FUNCTION_TYPE);                                
7145   TREE_TYPE (mdecl) = type;
7146   TYPE_ARG_TYPES (mdecl) = args;
7147   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
7148   java_parser_context_restore_global ();
7149   DECL_ARTIFICIAL (mdecl) = 1;                                      
7150   return mdecl;
7151 }
7152
7153 /* Starts the body if an artifical method.  */
7154
7155 static void
7156 start_artificial_method_body (mdecl)
7157      tree mdecl;
7158 {
7159   DECL_SOURCE_LINE (mdecl) = 1;
7160   DECL_SOURCE_LINE_MERGE (mdecl, 1);
7161   source_start_java_method (mdecl);
7162   enter_block ();
7163 }
7164
7165 static void
7166 end_artificial_method_body (mdecl)
7167      tree mdecl;
7168 {
7169   /* exit_block modifies DECL_FUNCTION_BODY (current_function_decl).
7170      It has to be evaluated first. (if mdecl is current_function_decl,
7171      we have an undefined behavior if no temporary variable is used.) */
7172   tree b = exit_block ();
7173   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = b;
7174   exit_block ();
7175 }
7176
7177 /* Terminate a function and expand its body.  */
7178
7179 static void
7180 source_end_java_method ()
7181 {
7182   tree fndecl = current_function_decl;
7183
7184   if (!fndecl)
7185     return;
7186
7187   java_parser_context_save_global ();
7188   lineno = ctxp->last_ccb_indent1;
7189
7190   /* Turn function bodies with only a NOP expr null, so they don't get
7191      generated at all and we won't get warnings when using the -W
7192      -Wall flags. */
7193   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7194     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7195
7196   /* Generate function's code */
7197   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7198       && ! flag_emit_class_files
7199       && ! flag_emit_xref)
7200     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7201
7202   /* pop out of its parameters */
7203   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7204   poplevel (1, 0, 1);
7205   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7206
7207   /* Generate rtl for function exit.  */
7208   if (! flag_emit_class_files && ! flag_emit_xref)
7209     {
7210       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7211       expand_function_end (input_filename, lineno, 0);
7212
7213       /* Run the optimizers and output assembler code for this function. */
7214       rest_of_compilation (fndecl);
7215     }
7216
7217   current_function_decl = NULL_TREE;
7218   java_parser_context_restore_global ();
7219 }
7220
7221 /* Record EXPR in the current function block. Complements compound
7222    expression second operand if necessary.  */
7223
7224 tree
7225 java_method_add_stmt (fndecl, expr)
7226      tree fndecl, expr;
7227 {
7228   if (!GET_CURRENT_BLOCK (fndecl))
7229     return NULL_TREE;
7230   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7231 }
7232
7233 static tree
7234 add_stmt_to_block (b, type, stmt)
7235      tree b, type, stmt;
7236 {
7237   tree body = BLOCK_EXPR_BODY (b), c;
7238   
7239   if (java_error_count)
7240     return body;
7241     
7242   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7243     return body;
7244
7245   BLOCK_EXPR_BODY (b) = c;
7246   TREE_SIDE_EFFECTS (c) = 1;
7247   return c;
7248 }
7249
7250 /* Add STMT to EXISTING if possible, otherwise create a new
7251    COMPOUND_EXPR and add STMT to it. */
7252
7253 static tree
7254 add_stmt_to_compound (existing, type, stmt)
7255      tree existing, type, stmt;
7256 {
7257   if (existing)
7258     return build (COMPOUND_EXPR, type, existing, stmt);
7259   else
7260     return stmt;
7261 }
7262
7263 void java_layout_seen_class_methods ()
7264 {
7265   tree previous_list = all_class_list;
7266   tree end = NULL_TREE;
7267   tree current;
7268
7269   while (1)
7270     {
7271       for (current = previous_list; 
7272            current != end; current = TREE_CHAIN (current))
7273         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7274       
7275       if (previous_list != all_class_list)
7276         {
7277           end = previous_list;
7278           previous_list = all_class_list;
7279         }
7280       else
7281         break;
7282     }
7283 }
7284
7285 void
7286 java_reorder_fields ()
7287 {
7288   static tree stop_reordering = NULL_TREE;
7289   static int initialized_p;
7290   tree current;
7291
7292   /* Register STOP_REORDERING with the garbage collector.  */
7293   if (!initialized_p)
7294     {
7295       ggc_add_tree_root (&stop_reordering, 1);
7296       initialized_p = 1;
7297     }
7298
7299   for (current = gclass_list; current; current = TREE_CHAIN (current))
7300     {
7301       current_class = TREE_TYPE (TREE_VALUE (current));
7302
7303       if (current_class == stop_reordering)
7304         break;
7305
7306       /* Reverse the fields, but leave the dummy field in front.
7307          Fields are already ordered for Object and Class */
7308       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7309           && current_class != class_type_node)
7310       {
7311         /* If the dummy field is there, reverse the right fields and
7312            just layout the type for proper fields offset */
7313         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7314           {
7315             tree fields = TYPE_FIELDS (current_class);
7316             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7317             TYPE_SIZE (current_class) = NULL_TREE;
7318           }
7319         /* We don't have a dummy field, we need to layout the class,
7320            after having reversed the fields */
7321         else
7322           {
7323             TYPE_FIELDS (current_class) = 
7324               nreverse (TYPE_FIELDS (current_class));
7325             TYPE_SIZE (current_class) = NULL_TREE;
7326           }
7327       }
7328     }
7329   stop_reordering = TREE_TYPE (TREE_VALUE (gclass_list));
7330 }
7331
7332 /* Layout the methods of all classes loaded in one way or another.
7333    Check methods of source parsed classes. Then reorder the
7334    fields and layout the classes or the type of all source parsed
7335    classes */
7336
7337 void
7338 java_layout_classes ()
7339 {
7340   tree current;
7341   int save_error_count = java_error_count;
7342
7343   /* Layout the methods of all classes seen so far */
7344   java_layout_seen_class_methods ();
7345   java_parse_abort_on_error ();
7346   all_class_list = NULL_TREE;
7347
7348   /* Then check the methods of all parsed classes */
7349   for (current = gclass_list; current; current = TREE_CHAIN (current))
7350     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7351       java_check_methods (TREE_VALUE (current));
7352   java_parse_abort_on_error ();
7353
7354   for (current = gclass_list; current; current = TREE_CHAIN (current))
7355     {
7356       current_class = TREE_TYPE (TREE_VALUE (current));
7357       layout_class (current_class);
7358
7359       /* Error reported by the caller */
7360       if (java_error_count)
7361         return;
7362     }
7363
7364   /* We might have reloaded classes durign the process of laying out
7365      classes for code generation. We must layout the methods of those
7366      late additions, as constructor checks might use them */
7367   java_layout_seen_class_methods ();
7368   java_parse_abort_on_error ();
7369 }
7370
7371 /* Expand methods in the current set of classes rememebered for
7372    generation.  */
7373
7374 static void
7375 java_complete_expand_classes ()
7376 {
7377   tree current;
7378
7379   do_not_fold = flag_emit_xref;
7380
7381   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7382     if (!INNER_CLASS_DECL_P (current))
7383       java_complete_expand_class (current);
7384 }
7385
7386 /* Expand the methods found in OUTER, starting first by OUTER's inner
7387    classes, if any.  */
7388
7389 static void
7390 java_complete_expand_class (outer)
7391      tree outer;
7392 {
7393   tree inner_list;
7394
7395   set_nested_class_simple_name_value (outer, 1); /* Set */
7396
7397   /* We need to go after all inner classes and start expanding them,
7398      starting with most nested ones. We have to do that because nested
7399      classes might add functions to outer classes */
7400
7401   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7402        inner_list; inner_list = TREE_CHAIN (inner_list))
7403     java_complete_expand_class (TREE_PURPOSE (inner_list));
7404
7405   java_complete_expand_methods (outer);
7406   set_nested_class_simple_name_value (outer, 0); /* Reset */
7407 }
7408
7409 /* Expand methods registered in CLASS_DECL. The general idea is that
7410    we expand regular methods first. This allows us get an estimate on
7411    how outer context local alias fields are really used so we can add
7412    to the constructor just enough code to initialize them properly (it
7413    also lets us generate finit$ correctly.) Then we expand the
7414    constructors and then <clinit>.  */
7415
7416 static void
7417 java_complete_expand_methods (class_decl)
7418      tree class_decl;
7419 {
7420   tree clinit, finit, decl, first_decl;
7421
7422   current_class = TREE_TYPE (class_decl);
7423
7424   /* Find whether the class has final variables */
7425   for (decl = TYPE_FIELDS (current_class); decl; decl = TREE_CHAIN (decl))
7426     if (FIELD_FINAL (decl))
7427       {
7428         TYPE_HAS_FINAL_VARIABLE (current_class) = 1;
7429         break;
7430       }
7431
7432   /* Initialize a new constant pool */
7433   init_outgoing_cpool ();
7434
7435   /* Pre-expand <clinit> to figure whether we really need it or
7436      not. If we do need it, we pre-expand the static fields so they're
7437      ready to be used somewhere else. <clinit> will be fully expanded
7438      after we processed the constructors. */
7439   first_decl = TYPE_METHODS (current_class);
7440   clinit = maybe_generate_pre_expand_clinit (current_class);
7441
7442   /* Then generate finit$ (if we need to) because constructor will
7443    try to use it.*/
7444   if (TYPE_FINIT_STMT_LIST (current_class))
7445     {
7446       finit = generate_finit (current_class);
7447       java_complete_expand_method (finit);
7448     }
7449
7450   /* Now do the constructors */
7451   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7452     {
7453       int no_body;
7454
7455       if (!DECL_CONSTRUCTOR_P (decl))
7456         continue;
7457       
7458       no_body = !DECL_FUNCTION_BODY (decl);
7459       /* Don't generate debug info on line zero when expanding a
7460          generated constructor. */
7461       if (no_body)
7462         restore_line_number_status (1);
7463
7464       /* Reset the final local variable assignment flags */
7465       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7466         reset_final_variable_local_assignment_flag (current_class);
7467
7468       java_complete_expand_method (decl);
7469
7470       /* Check for missed out final variable assignment */
7471       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7472         check_final_variable_local_assignment_flag (current_class, decl);
7473       
7474       if (no_body)
7475         restore_line_number_status (0);
7476     }
7477
7478   /* First, do the ordinary methods. */
7479   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7480     {
7481       /* Skip abstract or native methods -- but do handle native
7482          methods when generating JNI stubs.  */
7483       if (METHOD_ABSTRACT (decl)
7484           || (! flag_jni && METHOD_NATIVE (decl))
7485           || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7486         continue;
7487
7488       if (METHOD_NATIVE (decl))
7489         {
7490           tree body = build_jni_stub (decl);
7491           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7492         }
7493
7494       java_complete_expand_method (decl);
7495     }
7496
7497   /* If there is indeed a <clinit>, fully expand it now */
7498   if (clinit)
7499     {
7500       /* Reset the final local variable assignment flags */
7501       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7502         reset_static_final_variable_assignment_flag (current_class);
7503       /* Prevent the use of `this' inside <clinit> */
7504       ctxp->explicit_constructor_p = 1;
7505       java_complete_expand_method (clinit);
7506       ctxp->explicit_constructor_p = 0;
7507       /* Check for missed out static final variable assignment */
7508       if (TYPE_HAS_FINAL_VARIABLE (current_class)
7509           && !CLASS_INTERFACE (class_decl))
7510         check_static_final_variable_assignment_flag (current_class);
7511     }
7512   
7513   /* We might have generated a class$ that we now want to expand */
7514   if (TYPE_DOT_CLASS (current_class))
7515     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7516
7517   /* Now verify constructor circularity (stop after the first one we
7518      prove wrong.) */
7519   if (!CLASS_INTERFACE (class_decl))
7520     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7521       if (DECL_CONSTRUCTOR_P (decl) 
7522           && verify_constructor_circularity (decl, decl))
7523         break;
7524
7525   /* Final check on the initialization of final variables. */
7526   if (TYPE_HAS_FINAL_VARIABLE (current_class))
7527     {
7528       check_final_variable_global_assignment_flag (current_class);
7529       /* If we have an interface, check for uninitialized fields. */
7530       if (CLASS_INTERFACE (class_decl))
7531         check_static_final_variable_assignment_flag (current_class);
7532     }
7533
7534   /* Save the constant pool. We'll need to restore it later. */
7535   TYPE_CPOOL (current_class) = outgoing_cpool;
7536 }
7537
7538 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7539    safely used in some other methods/constructors.  */
7540
7541 static tree
7542 maybe_generate_pre_expand_clinit (class_type)
7543      tree class_type;
7544 {
7545   tree current, mdecl;
7546
7547   if (!TYPE_CLINIT_STMT_LIST (class_type))
7548     return NULL_TREE;
7549
7550   /* Go through all static fields and pre expand them */
7551   for (current = TYPE_FIELDS (class_type); current; 
7552        current = TREE_CHAIN (current))
7553     if (FIELD_STATIC (current))
7554       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7555
7556   /* Then build the <clinit> method */
7557   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7558                                     clinit_identifier_node, end_params_node);
7559   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7560                        mdecl, NULL_TREE);
7561   start_artificial_method_body (mdecl);
7562
7563   /* We process the list of assignment we produced as the result of
7564      the declaration of initialized static field and add them as
7565      statement to the <clinit> method. */
7566   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7567        current = TREE_CHAIN (current))
7568     {
7569       tree stmt = current;
7570       /* We build the assignment expression that will initialize the
7571          field to its value. There are strict rules on static
7572          initializers (8.5). FIXME */
7573       if (TREE_CODE (stmt) != BLOCK && stmt != empty_stmt_node)
7574         stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
7575       java_method_add_stmt (mdecl, stmt);
7576     }
7577
7578   end_artificial_method_body (mdecl);
7579
7580   /* Now we want to place <clinit> as the last method (because we need
7581      it at least for interface so that it doesn't interfere with the
7582      dispatch table based lookup. */
7583   if (TREE_CHAIN (TYPE_METHODS (class_type)))
7584     {
7585       current = TREE_CHAIN (TYPE_METHODS (class_type));
7586       TYPE_METHODS (class_type) = current;
7587
7588       while (TREE_CHAIN (current))
7589         current = TREE_CHAIN (current);
7590
7591       TREE_CHAIN (current) = mdecl;
7592       TREE_CHAIN (mdecl) = NULL_TREE;
7593     }
7594
7595   return mdecl;
7596 }
7597
7598 /* Analyzes a method body and look for something that isn't a
7599    MODIFY_EXPR with a constant value.  */
7600
7601 static int
7602 analyze_clinit_body (bbody)
7603      tree bbody;
7604 {
7605   while (bbody)
7606     switch (TREE_CODE (bbody))
7607       {
7608       case BLOCK:
7609         bbody = BLOCK_EXPR_BODY (bbody);
7610         break;
7611         
7612       case EXPR_WITH_FILE_LOCATION:
7613         bbody = EXPR_WFL_NODE (bbody);
7614         break;
7615         
7616       case COMPOUND_EXPR:
7617         if (analyze_clinit_body (TREE_OPERAND (bbody, 0)))
7618           return 1;
7619         bbody = TREE_OPERAND (bbody, 1);
7620         break;
7621         
7622       case MODIFY_EXPR:
7623         /* Return 0 if the operand is constant, 1 otherwise.  */
7624         return ! TREE_CONSTANT (TREE_OPERAND (bbody, 1));
7625
7626       default:
7627         return 1;
7628       }
7629   return 0;
7630 }
7631
7632
7633 /* See whether we could get rid of <clinit>. Criteria are: all static
7634    final fields have constant initial values and the body of <clinit>
7635    is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
7636
7637 static int
7638 maybe_yank_clinit (mdecl)
7639      tree mdecl;
7640 {
7641   tree type, current;
7642   tree fbody, bbody;
7643   int found = 0;
7644   
7645   if (!DECL_CLINIT_P (mdecl))
7646     return 0;
7647
7648   /* If the body isn't empty, then we keep <clinit>. Note that if
7649      we're emitting classfiles, this isn't enough not to rule it
7650      out. */
7651   fbody = DECL_FUNCTION_BODY (mdecl);
7652   bbody = BLOCK_EXPR_BODY (fbody);
7653   if (bbody && bbody != error_mark_node)
7654     bbody = BLOCK_EXPR_BODY (bbody);
7655   else
7656     return 0;
7657   if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
7658     return 0;
7659   
7660   type = DECL_CONTEXT (mdecl);
7661   current = TYPE_FIELDS (type);
7662
7663   for (current = (current ? TREE_CHAIN (current) : current); 
7664        current; current = TREE_CHAIN (current))
7665     {
7666       tree f_init;
7667
7668       /* We're not interested in non static field */
7669       if (!FIELD_STATIC (current))
7670         continue;
7671
7672       /* Anything that isn't String or a basic type is ruled out -- or
7673          if we know how to deal with it (when doing things natively) we
7674          should generated an empty <clinit> so that SUID are computed
7675          correctly. */
7676       if (! JSTRING_TYPE_P (TREE_TYPE (current))
7677           && ! JNUMERIC_TYPE_P (TREE_TYPE (current)))
7678         break;
7679           
7680       f_init = DECL_INITIAL (current);
7681       /* If we're emitting native code, we want static final fields to
7682          have constant initializers. If we don't meet these
7683          conditions, we keep <clinit> */
7684       if (!flag_emit_class_files
7685           && !(FIELD_FINAL (current) && f_init && TREE_CONSTANT (f_init)))
7686         break;
7687       /* If we're emitting bytecode, we want static fields to have
7688          constant initializers or no initializer. If we don't meet
7689          these conditions, we keep <clinit> */
7690       if (flag_emit_class_files && f_init && !TREE_CONSTANT (f_init))
7691         break;
7692     }
7693
7694   /* Now we analyze the method body and look for something that
7695      isn't a MODIFY_EXPR */
7696   if (bbody == empty_stmt_node)
7697     found = 0;
7698   else
7699     found = analyze_clinit_body (bbody);
7700
7701   if (current || found)
7702     return 0;
7703
7704   /* Get rid of <clinit> in the class' list of methods */
7705   if (TYPE_METHODS (type) == mdecl)
7706     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
7707   else
7708     for (current = TYPE_METHODS (type); current; 
7709          current = TREE_CHAIN (current))
7710       if (TREE_CHAIN (current) == mdecl)
7711         {
7712           TREE_CHAIN (current) = TREE_CHAIN (mdecl);
7713           break;
7714         }
7715
7716   return 1;
7717 }
7718
7719
7720 /* Complete and expand a method.  */
7721
7722 static void
7723 java_complete_expand_method (mdecl)
7724      tree mdecl;
7725 {
7726   int yank_clinit = 0;
7727
7728   current_function_decl = mdecl;
7729   /* Fix constructors before expanding them */
7730   if (DECL_CONSTRUCTOR_P (mdecl))
7731     fix_constructors (mdecl);
7732   
7733   /* Expand functions that have a body */
7734   if (DECL_FUNCTION_BODY (mdecl))
7735     {
7736       tree fbody = DECL_FUNCTION_BODY (mdecl);
7737       tree block_body = BLOCK_EXPR_BODY (fbody);
7738       tree exception_copy = NULL_TREE;
7739       tree tem, *ptr;
7740
7741       current_function_decl = mdecl;
7742
7743       if (! quiet_flag)
7744         fprintf (stderr, " [%s.",
7745                  lang_printable_name (DECL_CONTEXT (mdecl), 0));
7746       announce_function (mdecl);
7747       if (! quiet_flag)
7748         fprintf (stderr, "]");
7749
7750       pushlevel (1);            /* Prepare for a parameter push */
7751       ptr = &DECL_ARGUMENTS (mdecl);
7752       tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7753       while (tem)
7754         {
7755           tree next = TREE_CHAIN (tem);
7756           tree type = TREE_TYPE (tem);
7757           if (PROMOTE_PROTOTYPES
7758               && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
7759               && INTEGRAL_TYPE_P (type))
7760             type = integer_type_node;
7761           DECL_ARG_TYPE (tem) = type;
7762           layout_decl (tem, 0);
7763           pushdecl (tem);
7764           *ptr = tem;
7765           ptr = &TREE_CHAIN (tem);
7766           tem = next;
7767         }
7768       *ptr = NULL_TREE;
7769       pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7770       lineno = DECL_SOURCE_LINE_FIRST (mdecl);
7771
7772       build_result_decl (mdecl);
7773
7774       current_this 
7775         = (!METHOD_STATIC (mdecl) ? 
7776            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7777
7778       /* Purge the `throws' list of unchecked exceptions. If we're
7779          doing xref, save a copy of the list and re-install it
7780          later. */
7781       if (flag_emit_xref)
7782         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7783
7784       purge_unchecked_exceptions (mdecl);
7785
7786       /* Install exceptions thrown with `throws' */
7787       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7788
7789       if (block_body != NULL_TREE)
7790         {
7791           block_body = java_complete_tree (block_body);
7792
7793           if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
7794             check_for_initialization (block_body);
7795           ctxp->explicit_constructor_p = 0;
7796         }
7797
7798       BLOCK_EXPR_BODY (fbody) = block_body;
7799
7800       /* If we saw a return but couldn't evaluate it properly, we'll
7801          have an error_mark_node here. */
7802       if (block_body != error_mark_node
7803           && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7804           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7805           && !flag_emit_xref)
7806         missing_return_error (current_function_decl);
7807
7808       /* Check wether we could just get rid of clinit, now the picture
7809          is complete. */
7810       if (!(yank_clinit = maybe_yank_clinit (mdecl)))
7811         complete_start_java_method (mdecl); 
7812       
7813       /* Don't go any further if we've found error(s) during the
7814          expansion */
7815       if (!java_error_count && !yank_clinit)
7816         source_end_java_method ();
7817       else
7818         {
7819           if (java_error_count)
7820             pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7821           poplevel (1, 0, 1);
7822         }
7823
7824       /* Pop the exceptions and sanity check */
7825       POP_EXCEPTIONS();
7826       if (currently_caught_type_list)
7827         abort ();
7828
7829       if (flag_emit_xref)
7830         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7831     }
7832 }
7833
7834 \f
7835
7836 /* This section of the code deals with accessing enclosing context
7837    fields either directly by using the relevant access to this$<n> or
7838    by invoking an access method crafted for that purpose.  */
7839
7840 /* Build the necessary access from an inner class to an outer
7841    class. This routine could be optimized to cache previous result
7842    (decl, current_class and returned access).  When an access method
7843    needs to be generated, it always takes the form of a read. It might
7844    be later turned into a write by calling outer_field_access_fix.  */
7845
7846 static tree
7847 build_outer_field_access (id, decl)
7848      tree id, decl;
7849 {
7850   tree access = NULL_TREE;
7851   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7852   tree decl_ctx = DECL_CONTEXT (decl);
7853
7854   /* If the immediate enclosing context of the current class is the
7855      field decl's class or inherits from it; build the access as
7856      `this$<n>.<field>'. Note that we will break the `private' barrier
7857      if we're not emitting bytecodes. */
7858   if ((ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
7859       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7860     {
7861       tree thisn = build_current_thisn (current_class);
7862       access = make_qualified_primary (build_wfl_node (thisn), 
7863                                        id, EXPR_WFL_LINECOL (id));
7864     }
7865   /* Otherwise, generate access methods to outer this and access the
7866      field (either using an access method or by direct access.) */
7867   else
7868     {
7869       int lc = EXPR_WFL_LINECOL (id);
7870
7871       /* Now we chain the required number of calls to the access$0 to
7872          get a hold to the enclosing instance we need, and then we
7873          build the field access. */
7874       access = build_access_to_thisn (current_class, decl_ctx, lc);
7875
7876       /* If the field is private and we're generating bytecode, then
7877          we generate an access method */
7878       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7879         {
7880           tree name = build_outer_field_access_methods (decl);
7881           access = build_outer_field_access_expr (lc, decl_ctx,
7882                                                   name, access, NULL_TREE);
7883         }
7884       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7885          Once again we break the `private' access rule from a foreign
7886          class. */
7887       else
7888         access = make_qualified_primary (access, id, lc);
7889     }
7890   return resolve_expression_name (access, NULL);
7891 }
7892
7893 /* Return a non zero value if NODE describes an outer field inner
7894    access.  */
7895
7896 static int
7897 outer_field_access_p (type, decl)
7898     tree type, decl;
7899 {
7900   if (!INNER_CLASS_TYPE_P (type) 
7901       || TREE_CODE (decl) != FIELD_DECL
7902       || DECL_CONTEXT (decl) == type)
7903     return 0;
7904   
7905   /* If the inner class extends the declaration context of the field
7906      we're try to acces, then this isn't an outer field access */
7907   if (inherits_from_p (type, DECL_CONTEXT (decl)))
7908     return 0;
7909
7910   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7911        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7912     {
7913       if (type == DECL_CONTEXT (decl))
7914         return 1;
7915
7916       if (!DECL_CONTEXT (TYPE_NAME (type)))
7917         {
7918           /* Before we give up, see whether the field is inherited from
7919              the enclosing context we're considering. */
7920           if (inherits_from_p (type, DECL_CONTEXT (decl)))
7921             return 1;
7922           break;
7923         }
7924     }
7925
7926   return 0;
7927 }
7928
7929 /* Return a non zero value if NODE represents an outer field inner
7930    access that was been already expanded. As a side effect, it returns
7931    the name of the field being accessed and the argument passed to the
7932    access function, suitable for a regeneration of the access method
7933    call if necessary. */
7934
7935 static int
7936 outer_field_expanded_access_p (node, name, arg_type, arg)
7937     tree node, *name, *arg_type, *arg;
7938 {
7939   int identified = 0;
7940
7941   if (TREE_CODE (node) != CALL_EXPR)
7942     return 0;
7943
7944   /* Well, gcj generates slightly different tree nodes when compiling
7945      to native or bytecodes. It's the case for function calls. */
7946
7947   if (flag_emit_class_files 
7948       && TREE_CODE (node) == CALL_EXPR
7949       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7950     identified = 1;
7951   else if (!flag_emit_class_files)
7952     {
7953       node = TREE_OPERAND (node, 0);
7954       
7955       if (node && TREE_OPERAND (node, 0)
7956           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7957         {
7958           node = TREE_OPERAND (node, 0);
7959           if (TREE_OPERAND (node, 0)
7960               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7961               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
7962                   (DECL_NAME (TREE_OPERAND (node, 0)))))
7963             identified = 1;
7964         }
7965     }
7966
7967   if (identified && name && arg_type && arg)
7968     {
7969       tree argument = TREE_OPERAND (node, 1);
7970       *name = DECL_NAME (TREE_OPERAND (node, 0));
7971       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7972       *arg = TREE_VALUE (argument);
7973     }
7974   return identified;
7975 }
7976
7977 /* Detect in NODE an outer field read access from an inner class and
7978    transform it into a write with RHS as an argument. This function is
7979    called from the java_complete_lhs when an assignment to a LHS can
7980    be identified. */
7981
7982 static tree
7983 outer_field_access_fix (wfl, node, rhs)
7984     tree wfl, node, rhs;
7985 {
7986   tree name, arg_type, arg;
7987   
7988   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7989     {
7990       /* At any rate, check whether we're trying to assign a value to
7991          a final. */
7992       tree accessed = (JDECL_P (node) ? node : 
7993                        (TREE_CODE (node) == COMPONENT_REF ? 
7994                         TREE_OPERAND (node, 1) : node));
7995       if (check_final_assignment (accessed, wfl))
7996         return error_mark_node;
7997   
7998       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
7999                                             arg_type, name, arg, rhs);
8000       return java_complete_tree (node);
8001     }
8002   return NULL_TREE;
8003 }
8004
8005 /* Construct the expression that calls an access method:
8006      <type>.access$<n>(<arg1> [, <arg2>]); 
8007
8008    ARG2 can be NULL and will be omitted in that case. It will denote a
8009    read access.  */
8010
8011 static tree
8012 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
8013     int lc;
8014     tree type, access_method_name, arg1, arg2;
8015 {
8016   tree args, cn, access;
8017
8018   args = arg1 ? arg1 : 
8019     build_wfl_node (build_current_thisn (current_class));
8020   args = build_tree_list (NULL_TREE, args);
8021
8022   if (arg2)
8023     args = tree_cons (NULL_TREE, arg2, args);
8024
8025   access = build_method_invocation (build_wfl_node (access_method_name), args);
8026   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
8027   return make_qualified_primary (cn, access, lc);
8028 }
8029
8030 static tree
8031 build_new_access_id ()
8032 {
8033   static int access_n_counter = 1;
8034   char buffer [128];
8035
8036   sprintf (buffer, "access$%d", access_n_counter++);
8037   return get_identifier (buffer);
8038 }
8039
8040 /* Create the static access functions for the outer field DECL. We define a
8041    read:
8042      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
8043        return inst$.field;
8044      }
8045    and a write access:
8046      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
8047                                      TREE_TYPE (<field>) value$) {
8048        return inst$.field = value$;
8049      }
8050    We should have a usage flags on the DECL so we can lazily turn the ones
8051    we're using for code generation. FIXME.
8052 */
8053
8054 static tree
8055 build_outer_field_access_methods (decl)
8056     tree decl;
8057 {
8058   tree id, args, stmt, mdecl;
8059   
8060   if (FIELD_INNER_ACCESS_P (decl))
8061     return FIELD_INNER_ACCESS (decl);
8062
8063   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
8064  
8065   /* Create the identifier and a function named after it. */
8066   id = build_new_access_id ();
8067
8068   /* The identifier is marked as bearing the name of a generated write
8069      access function for outer field accessed from inner classes. */
8070   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8071
8072   /* Create the read access */
8073   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
8074   TREE_CHAIN (args) = end_params_node;
8075   stmt = make_qualified_primary (build_wfl_node (inst_id),
8076                                  build_wfl_node (DECL_NAME (decl)), 0);
8077   stmt = build_return (0, stmt);
8078   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8079                                            TREE_TYPE (decl), id, args, stmt);
8080   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8081
8082   /* Create the write access method. No write access for final variable */
8083   if (!FIELD_FINAL (decl))
8084     {
8085       args = build_tree_list (inst_id, 
8086                               build_pointer_type (DECL_CONTEXT (decl)));
8087       TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
8088       TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
8089       stmt = make_qualified_primary (build_wfl_node (inst_id),
8090                                      build_wfl_node (DECL_NAME (decl)), 0);
8091       stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
8092                                                 build_wfl_node (wpv_id)));
8093       mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8094                                                TREE_TYPE (decl), id, 
8095                                                args, stmt);
8096     }
8097   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8098
8099   /* Return the access name */
8100   return FIELD_INNER_ACCESS (decl) = id;
8101 }
8102
8103 /* Build an field access method NAME.  */
8104
8105 static tree 
8106 build_outer_field_access_method (class, type, name, args, body)
8107     tree class, type, name, args, body;
8108 {
8109   tree saved_current_function_decl, mdecl;
8110
8111   /* Create the method */
8112   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
8113   fix_method_argument_names (args, mdecl);
8114   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8115
8116   /* Attach the method body. */
8117   saved_current_function_decl = current_function_decl;
8118   start_artificial_method_body (mdecl);
8119   java_method_add_stmt (mdecl, body);
8120   end_artificial_method_body (mdecl);
8121   current_function_decl = saved_current_function_decl;
8122
8123   return mdecl;
8124 }
8125
8126 \f
8127 /* This section deals with building access function necessary for
8128    certain kinds of method invocation from inner classes.  */
8129
8130 static tree
8131 build_outer_method_access_method (decl)
8132     tree decl;
8133 {
8134   tree saved_current_function_decl, mdecl;
8135   tree args = NULL_TREE, call_args = NULL_TREE;
8136   tree carg, id, body, class;
8137   char buffer [80];
8138   int parm_id_count = 0;
8139
8140   /* Test this abort with an access to a private field */
8141   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
8142     abort ();
8143
8144   /* Check the cache first */
8145   if (DECL_FUNCTION_INNER_ACCESS (decl))
8146     return DECL_FUNCTION_INNER_ACCESS (decl);
8147
8148   class = DECL_CONTEXT (decl);
8149
8150   /* Obtain an access identifier and mark it */
8151   id = build_new_access_id ();
8152   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8153
8154   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
8155   /* Create the arguments, as much as the original */
8156   for (; carg && carg != end_params_node; 
8157        carg = TREE_CHAIN (carg))
8158     {
8159       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
8160       args = chainon (args, build_tree_list (get_identifier (buffer), 
8161                                              TREE_VALUE (carg)));
8162     }
8163   args = chainon (args, end_params_node);
8164
8165   /* Create the method */
8166   mdecl = create_artificial_method (class, ACC_STATIC, 
8167                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
8168   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8169   /* There is a potential bug here. We should be able to use
8170      fix_method_argument_names, but then arg names get mixed up and
8171      eventually a constructor will have its this$0 altered and the
8172      outer context won't be assignment properly. The test case is
8173      stub.java FIXME */
8174   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
8175
8176   /* Attach the method body. */
8177   saved_current_function_decl = current_function_decl;
8178   start_artificial_method_body (mdecl);
8179
8180   /* The actual method invocation uses the same args. When invoking a
8181      static methods that way, we don't want to skip the first
8182      argument. */
8183   carg = args;
8184   if (!METHOD_STATIC (decl))
8185     carg = TREE_CHAIN (carg);
8186   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
8187     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
8188                            call_args);
8189
8190   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
8191                                   call_args);
8192   if (!METHOD_STATIC (decl))
8193     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
8194                                    body, 0);
8195   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
8196     body = build_return (0, body);
8197   java_method_add_stmt (mdecl,body);
8198   end_artificial_method_body (mdecl);
8199   current_function_decl = saved_current_function_decl;
8200
8201   /* Back tag the access function so it know what it accesses */
8202   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
8203
8204   /* Tag the current method so it knows it has an access generated */
8205   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
8206 }
8207
8208 \f
8209 /* This section of the code deals with building expressions to access
8210    the enclosing instance of an inner class. The enclosing instance is
8211    kept in a generated field called this$<n>, with <n> being the
8212    inner class nesting level (starting from 0.)  */
8213     
8214 /* Build an access to a given this$<n>, always chaining access call to
8215    others. Access methods to this$<n> are build on the fly if
8216    necessary. This CAN'T be used to solely access this$<n-1> from
8217    this$<n> (which alway yield to special cases and optimization, see
8218    for example build_outer_field_access).  */
8219
8220 static tree
8221 build_access_to_thisn (from, to, lc)
8222      tree from, to;
8223      int lc;
8224 {
8225   tree access = NULL_TREE;
8226
8227   while (from != to)
8228     {
8229       if (!access)
8230         {
8231           access = build_current_thisn (from);
8232           access = build_wfl_node (access);
8233         }
8234       else
8235         {
8236           tree access0_wfl, cn;
8237
8238           maybe_build_thisn_access_method (from);
8239           access0_wfl = build_wfl_node (access0_identifier_node);
8240           cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
8241           EXPR_WFL_LINECOL (access0_wfl) = lc;
8242           access = build_tree_list (NULL_TREE, access);
8243           access = build_method_invocation (access0_wfl, access);
8244           access = make_qualified_primary (cn, access, lc);
8245         }
8246
8247       /* if FROM isn't an inter class, that's fine, we've done
8248          enough. What we're looking for can be accessed from there. */
8249       from = DECL_CONTEXT (TYPE_NAME (from));
8250       if (!from)
8251         break;
8252       from = TREE_TYPE (from);
8253     }
8254   return access;
8255 }
8256
8257 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
8258    is returned if nothing needs to be generated. Otherwise, the method
8259    generated and a method decl is returned.  
8260
8261    NOTE: These generated methods should be declared in a class file
8262    attribute so that they can't be referred to directly.  */
8263
8264 static tree
8265 maybe_build_thisn_access_method (type)
8266     tree type;
8267 {
8268   tree mdecl, args, stmt, rtype;
8269   tree saved_current_function_decl;
8270
8271   /* If TYPE is a top-level class, no access method is required.
8272      If there already is such an access method, bail out. */
8273   if (CLASS_ACCESS0_GENERATED_P (type) || !PURE_INNER_CLASS_TYPE_P (type))
8274     return NULL_TREE;
8275
8276   /* We generate the method. The method looks like:
8277      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
8278   */
8279   args = build_tree_list (inst_id, build_pointer_type (type));
8280   TREE_CHAIN (args) = end_params_node;
8281   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
8282   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
8283                                     access0_identifier_node, args);
8284   fix_method_argument_names (args, mdecl);
8285   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
8286   stmt = build_current_thisn (type);
8287   stmt = make_qualified_primary (build_wfl_node (inst_id), 
8288                                  build_wfl_node (stmt), 0);
8289   stmt = build_return (0, stmt);
8290
8291   saved_current_function_decl = current_function_decl;
8292   start_artificial_method_body (mdecl);
8293   java_method_add_stmt (mdecl, stmt);
8294   end_artificial_method_body (mdecl);
8295   current_function_decl = saved_current_function_decl;
8296
8297   CLASS_ACCESS0_GENERATED_P (type) = 1;
8298
8299   return mdecl;
8300 }
8301
8302 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
8303    the first level of innerclassing. this$1 for the next one, etc...
8304    This function can be invoked with TYPE to NULL, available and then
8305    has to count the parser context.  */
8306
8307 static tree
8308 build_current_thisn (type)
8309     tree type;
8310 {
8311   static int saved_i = -1;
8312   static tree saved_thisn = NULL_TREE;
8313   static tree saved_type = NULL_TREE;
8314   static int saved_type_i = 0;
8315   static int initialized_p;
8316   tree decl;
8317   char buffer [80];
8318   int i = 0;
8319
8320   /* Register SAVED_THISN and SAVED_TYPE with the garbage collector.  */
8321   if (!initialized_p)
8322     {
8323       ggc_add_tree_root (&saved_thisn, 1);
8324       ggc_add_tree_root (&saved_type, 1);
8325       initialized_p = 1;
8326     }
8327
8328   if (type)
8329     {
8330       if (type == saved_type)
8331         i = saved_type_i;
8332       else
8333         {
8334           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
8335                decl; decl = DECL_CONTEXT (decl), i++)
8336             ;
8337       
8338           saved_type = type;
8339           saved_type_i = i;
8340         }
8341     }
8342   else
8343     i = list_length (GET_CPC_LIST ())-2;
8344
8345   if (i == saved_i)
8346     return saved_thisn;
8347     
8348   sprintf (buffer, "this$%d", i);
8349   saved_i = i;
8350   saved_thisn = get_identifier (buffer);
8351   return saved_thisn;
8352 }
8353
8354 /* Return the assignement to the hidden enclosing context `this$<n>'
8355    by the second incoming parameter to the innerclass constructor. The
8356    form used is `this.this$<n> = this$<n>;'.  */
8357
8358 static tree
8359 build_thisn_assign ()
8360 {
8361   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
8362     {
8363       tree thisn = build_current_thisn (current_class);
8364       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
8365                                          build_wfl_node (thisn), 0);
8366       tree rhs = build_wfl_node (thisn);
8367       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
8368       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
8369     }
8370   return NULL_TREE;
8371 }
8372
8373 \f
8374 /* Building the synthetic `class$' used to implement the `.class' 1.1
8375    extension for non primitive types. This method looks like:
8376
8377     static Class class$(String type) throws NoClassDefFoundError
8378     {
8379       try {return (java.lang.Class.forName (String));}
8380       catch (ClassNotFoundException e) {
8381         throw new NoClassDefFoundError(e.getMessage());}
8382     } */
8383
8384 static tree
8385 build_dot_class_method (class)
8386      tree class;
8387 {
8388 #define BWF(S) build_wfl_node (get_identifier ((S)))
8389 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8390   tree args, tmp, saved_current_function_decl, mdecl;
8391   tree stmt, throw_stmt, catch, catch_block, try_block;
8392   tree catch_clause_param;
8393   tree class_not_found_exception, no_class_def_found_error;
8394
8395   static tree get_message_wfl, type_parm_wfl;
8396
8397   if (!get_message_wfl)
8398     {
8399       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8400       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8401       ggc_add_tree_root (&get_message_wfl, 1);
8402       ggc_add_tree_root (&type_parm_wfl, 1);
8403     }
8404
8405   /* Build the arguments */
8406   args = build_tree_list (get_identifier ("type$"),
8407                           build_pointer_type (string_type_node));
8408   TREE_CHAIN (args) = end_params_node;
8409
8410   /* Build the qualified name java.lang.Class.forName */
8411   tmp = MQN (MQN (MQN (BWF ("java"), 
8412                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8413
8414   /* For things we have to catch and throw */
8415   class_not_found_exception = 
8416     lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8417   no_class_def_found_error = 
8418     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8419   load_class (class_not_found_exception, 1);
8420   load_class (no_class_def_found_error, 1);
8421
8422   /* Create the "class$" function */
8423   mdecl = create_artificial_method (class, ACC_STATIC, 
8424                                     build_pointer_type (class_type_node),
8425                                     classdollar_identifier_node, args);
8426   DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8427                                                   no_class_def_found_error);
8428   
8429   /* We start by building the try block. We need to build:
8430        return (java.lang.Class.forName (type)); */
8431   stmt = build_method_invocation (tmp, 
8432                                   build_tree_list (NULL_TREE, type_parm_wfl));
8433   stmt = build_return (0, stmt);
8434   /* Put it in a block. That's the try block */
8435   try_block = build_expr_block (stmt, NULL_TREE);
8436
8437   /* Now onto the catch block. We start by building the expression
8438      throwing a new exception: 
8439        throw new NoClassDefFoundError (_.getMessage); */
8440   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8441                                     get_message_wfl, 0);
8442   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8443   
8444   /* Build new NoClassDefFoundError (_.getMessage) */
8445   throw_stmt = build_new_invocation 
8446     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8447      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8448
8449   /* Build the throw, (it's too early to use BUILD_THROW) */
8450   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8451
8452   /* Build the catch block to encapsulate all this. We begin by
8453      building an decl for the catch clause parameter and link it to
8454      newly created block, the catch block. */
8455   catch_clause_param = 
8456     build_decl (VAR_DECL, wpv_id, 
8457                 build_pointer_type (class_not_found_exception));
8458   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8459   
8460   /* We initialize the variable with the exception handler. */
8461   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8462                  build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
8463   add_stmt_to_block (catch_block, NULL_TREE, catch);
8464
8465   /* We add the statement throwing the new exception */
8466   add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8467
8468   /* Build a catch expression for all this */
8469   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8470
8471   /* Build the try/catch sequence */
8472   stmt = build_try_statement (0, try_block, catch_block);
8473
8474   fix_method_argument_names (args, mdecl);
8475   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8476   saved_current_function_decl = current_function_decl;
8477   start_artificial_method_body (mdecl);
8478   java_method_add_stmt (mdecl, stmt);
8479   end_artificial_method_body (mdecl);
8480   current_function_decl = saved_current_function_decl;
8481   TYPE_DOT_CLASS (class) = mdecl;
8482
8483   return mdecl;
8484 }
8485
8486 static tree
8487 build_dot_class_method_invocation (type)
8488      tree type;
8489 {
8490   tree sig_id, s;
8491
8492   if (TYPE_ARRAY_P (type))
8493     sig_id = build_java_signature (type);
8494   else
8495     sig_id = DECL_NAME (TYPE_NAME (type));
8496
8497   s = build_string (IDENTIFIER_LENGTH (sig_id), 
8498                     IDENTIFIER_POINTER (sig_id));
8499   return build_method_invocation (build_wfl_node (classdollar_identifier_node),
8500                                   build_tree_list (NULL_TREE, s));
8501 }
8502
8503 /* This section of the code deals with constructor.  */
8504
8505 /* Craft a body for default constructor. Patch existing constructor
8506    bodies with call to super() and field initialization statements if
8507    necessary.  */
8508
8509 static void
8510 fix_constructors (mdecl)
8511      tree mdecl;
8512 {
8513   tree body = DECL_FUNCTION_BODY (mdecl);
8514   tree thisn_assign, compound = NULL_TREE;
8515   tree class_type = DECL_CONTEXT (mdecl);
8516
8517   if (DECL_FIXED_CONSTRUCTOR_P (mdecl))
8518     return;
8519   DECL_FIXED_CONSTRUCTOR_P (mdecl) = 1;
8520
8521   if (!body)
8522     {
8523       /* It is an error for the compiler to generate a default
8524          constructor if the superclass doesn't have a constructor that
8525          takes no argument, or the same args for an anonymous class */
8526       if (verify_constructor_super (mdecl))
8527         {
8528           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8529           tree save = DECL_NAME (mdecl);
8530           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8531           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8532           parse_error_context
8533             (lookup_cl (TYPE_NAME (class_type)), 
8534              "No constructor matching `%s' found in class `%s'",
8535              lang_printable_name (mdecl, 0), n);
8536           DECL_NAME (mdecl) = save;
8537         }
8538       
8539       /* The constructor body must be crafted by hand. It's the
8540          constructor we defined when we realize we didn't have the
8541          CLASSNAME() constructor */
8542       start_artificial_method_body (mdecl);
8543       
8544       /* Insert an assignment to the this$<n> hidden field, if
8545          necessary */
8546       if ((thisn_assign = build_thisn_assign ()))
8547         java_method_add_stmt (mdecl, thisn_assign);
8548
8549       /* We don't generate a super constructor invocation if we're
8550          compiling java.lang.Object. build_super_invocation takes care
8551          of that. */
8552       java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8553
8554       /* Insert the instance initializer block right here, after the
8555          super invocation. */
8556       add_instance_initializer (mdecl);
8557
8558       end_artificial_method_body (mdecl);
8559     }
8560   /* Search for an explicit constructor invocation */
8561   else 
8562     {
8563       int found = 0;
8564       int invokes_this = 0;
8565       tree found_call = NULL_TREE;
8566       tree main_block = BLOCK_EXPR_BODY (body);
8567       tree ii;                  /* Instance Initializer */
8568       
8569       while (body)
8570         switch (TREE_CODE (body))
8571           {
8572           case CALL_EXPR:
8573             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8574             if (CALL_THIS_CONSTRUCTOR_P (body))
8575               invokes_this = 1;
8576             body = NULL_TREE;
8577             break;
8578           case COMPOUND_EXPR:
8579           case EXPR_WITH_FILE_LOCATION:
8580             found_call = body;
8581             body = TREE_OPERAND (body, 0);
8582             break;
8583           case BLOCK:
8584             found_call = body;
8585             body = BLOCK_EXPR_BODY (body);
8586             break;
8587           default:
8588             found = 0;
8589             body = NULL_TREE;
8590           }
8591
8592       /* Generate the assignment to this$<n>, if necessary */
8593       if ((thisn_assign = build_thisn_assign ()))
8594         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8595
8596       /* The constructor is missing an invocation of super() */
8597       if (!found)
8598         compound = add_stmt_to_compound (compound, NULL_TREE,
8599                                          build_super_invocation (mdecl));
8600       /* Explicit super() invokation should take place before the
8601          instance initializer blocks. */
8602       else
8603         {
8604           compound = add_stmt_to_compound (compound, NULL_TREE,
8605                                            TREE_OPERAND (found_call, 0));
8606           TREE_OPERAND (found_call, 0) = empty_stmt_node;
8607         }
8608       
8609       /* Insert the instance initializer block right after. */
8610       if (!invokes_this && (ii = build_instance_initializer (mdecl)))
8611         compound = add_stmt_to_compound (compound, NULL_TREE, ii);
8612
8613       /* Fix the constructor main block if we're adding extra stmts */
8614       if (compound)
8615         {
8616           compound = add_stmt_to_compound (compound, NULL_TREE,
8617                                            BLOCK_EXPR_BODY (main_block));
8618           BLOCK_EXPR_BODY (main_block) = compound;
8619         }
8620     }
8621 }
8622
8623 /* Browse constructors in the super class, searching for a constructor
8624    that doesn't take any argument. Return 0 if one is found, 1
8625    otherwise.  If the current class is an anonymous inner class, look
8626    for something that has the same signature. */
8627
8628 static int
8629 verify_constructor_super (mdecl)
8630      tree mdecl;
8631 {
8632   tree class = CLASSTYPE_SUPER (current_class);
8633   int super_inner = PURE_INNER_CLASS_TYPE_P (class);
8634   tree sdecl;
8635
8636   if (!class)
8637     return 0;
8638
8639   if (ANONYMOUS_CLASS_P (current_class))
8640     {
8641       tree mdecl_arg_type;
8642       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8643       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8644         if (DECL_CONSTRUCTOR_P (sdecl))
8645           {
8646             tree m_arg_type;
8647             tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8648             if (super_inner)
8649               arg_type = TREE_CHAIN (arg_type);
8650             for (m_arg_type = mdecl_arg_type; 
8651                  (arg_type != end_params_node 
8652                   && m_arg_type != end_params_node);
8653                  arg_type = TREE_CHAIN (arg_type), 
8654                    m_arg_type = TREE_CHAIN (m_arg_type))
8655               if (TREE_VALUE (arg_type) != TREE_VALUE (m_arg_type))
8656                 break;
8657
8658             if (arg_type == end_params_node && m_arg_type == end_params_node)
8659               return 0;
8660           }
8661     }
8662   else
8663     {
8664       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8665         {
8666           tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8667           if (super_inner)
8668             arg = TREE_CHAIN (arg);
8669           if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
8670             return 0;
8671         }
8672     }
8673   return 1;
8674 }
8675
8676 /* Generate code for all context remembered for code generation.  */
8677
8678 void
8679 java_expand_classes ()
8680 {
8681   int save_error_count = 0;
8682   static struct parser_ctxt *cur_ctxp = NULL;
8683
8684   java_parse_abort_on_error ();
8685   if (!(ctxp = ctxp_for_generation))
8686     return;
8687   java_layout_classes ();
8688   java_parse_abort_on_error ();
8689
8690   cur_ctxp = ctxp_for_generation;
8691   for (; cur_ctxp; cur_ctxp = cur_ctxp->next)
8692     {
8693       ctxp = cur_ctxp;
8694       input_filename = ctxp->filename;
8695       lang_init_source (2);            /* Error msgs have method prototypes */
8696       java_complete_expand_classes (); /* Complete and expand classes */
8697       java_parse_abort_on_error ();
8698     }
8699   input_filename = main_input_filename;
8700
8701   /* Find anonymous classes and expand their constructor, now they
8702      have been fixed. */
8703   for (cur_ctxp = ctxp_for_generation;  cur_ctxp;  cur_ctxp = cur_ctxp->next)
8704     {
8705       tree current;
8706       ctxp = cur_ctxp;
8707       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8708         {
8709           current_class = TREE_TYPE (current);
8710           if (ANONYMOUS_CLASS_P (current_class))
8711             {
8712               tree d;
8713               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8714                 {
8715                   if (DECL_CONSTRUCTOR_P (d))
8716                     {
8717                       restore_line_number_status (1);
8718                       java_complete_expand_method (d);
8719                       restore_line_number_status (0);
8720                       break;    /* We now there are no other ones */
8721                     }
8722                 }
8723             }
8724         }
8725     }
8726
8727   /* If we've found error at that stage, don't try to generate
8728      anything, unless we're emitting xrefs or checking the syntax only
8729      (but not using -fsyntax-only for the purpose of generating
8730      bytecode. */
8731   if (java_error_count && !flag_emit_xref 
8732       && (!flag_syntax_only && !flag_emit_class_files))
8733     return;
8734
8735   /* Now things are stable, go for generation of the class data. */
8736   for (cur_ctxp = ctxp_for_generation;  cur_ctxp;  cur_ctxp = cur_ctxp->next)
8737     {
8738       tree current;
8739       ctxp = cur_ctxp;
8740       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8741         {
8742           current_class = TREE_TYPE (current);
8743           outgoing_cpool = TYPE_CPOOL (current_class);
8744           if (flag_emit_class_files)
8745             write_classfile (current_class);
8746           if (flag_emit_xref)
8747             expand_xref (current_class);
8748           else if (! flag_syntax_only)
8749             finish_class ();
8750         }
8751     }
8752 }
8753
8754 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8755    a tree list node containing RIGHT. Fore coming RIGHTs will be
8756    chained to this hook. LOCATION contains the location of the
8757    separating `.' operator.  */
8758
8759 static tree
8760 make_qualified_primary (primary, right, location)
8761      tree primary, right;
8762      int location;
8763 {
8764   tree wfl;
8765
8766   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8767     wfl = build_wfl_wrap (primary, location);
8768   else
8769     {
8770       wfl = primary;
8771       /* If wfl wasn't qualified, we build a first anchor */
8772       if (!EXPR_WFL_QUALIFICATION (wfl))
8773         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8774     }
8775
8776   /* And chain them */
8777   EXPR_WFL_LINECOL (right) = location;
8778   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8779   PRIMARY_P (wfl) =  1;
8780   return wfl;
8781 }
8782
8783 /* Simple merge of two name separated by a `.' */
8784
8785 static tree
8786 merge_qualified_name (left, right)
8787      tree left, right;
8788 {
8789   tree node;
8790   if (!left && !right)
8791     return NULL_TREE;
8792
8793   if (!left)
8794     return right;
8795
8796   if (!right)
8797     return left;
8798
8799   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8800                 IDENTIFIER_LENGTH (left));
8801   obstack_1grow (&temporary_obstack, '.');
8802   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8803                  IDENTIFIER_LENGTH (right));
8804   node =  get_identifier (obstack_base (&temporary_obstack));
8805   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8806   QUALIFIED_P (node) = 1;
8807   return node;
8808 }
8809
8810 /* Merge the two parts of a qualified name into LEFT.  Set the
8811    location information of the resulting node to LOCATION, usually
8812    inherited from the location information of the `.' operator. */
8813
8814 static tree
8815 make_qualified_name (left, right, location)
8816      tree left, right;
8817      int location;
8818 {
8819 #ifdef USE_COMPONENT_REF
8820   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8821   EXPR_WFL_LINECOL (node) = location;
8822   return node;
8823 #else
8824   tree left_id = EXPR_WFL_NODE (left);
8825   tree right_id = EXPR_WFL_NODE (right);
8826   tree wfl, merge;
8827
8828   merge = merge_qualified_name (left_id, right_id);
8829
8830   /* Left wasn't qualified and is now qualified */
8831   if (!QUALIFIED_P (left_id))
8832     {
8833       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8834       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8835       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8836     }
8837   
8838   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8839   EXPR_WFL_LINECOL (wfl) = location;
8840   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8841
8842   EXPR_WFL_NODE (left) = merge;
8843   return left;
8844 #endif
8845 }
8846
8847 /* Extract the last identifier component of the qualified in WFL. The
8848    last identifier is removed from the linked list */
8849
8850 static tree
8851 cut_identifier_in_qualified (wfl)
8852      tree wfl;
8853 {
8854   tree q;
8855   tree previous = NULL_TREE;
8856   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8857     if (!TREE_CHAIN (q))
8858       {
8859         if (!previous)
8860           /* Operating on a non qualified qualified WFL.  */
8861           abort ();
8862
8863         TREE_CHAIN (previous) = NULL_TREE;
8864         return TREE_PURPOSE (q);
8865       }
8866 }
8867
8868 /* Resolve the expression name NAME. Return its decl.  */
8869
8870 static tree
8871 resolve_expression_name (id, orig)
8872      tree id;
8873      tree *orig;
8874 {
8875   tree name = EXPR_WFL_NODE (id);
8876   tree decl;
8877
8878   /* 6.5.5.1: Simple expression names */
8879   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8880     {
8881       /* 15.13.1: NAME can appear within the scope of a local variable
8882          declaration */
8883       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8884         return decl;
8885
8886       /* 15.13.1: NAME can appear within a class declaration */
8887       else 
8888         {
8889           decl = lookup_field_wrapper (current_class, name);
8890           if (decl)
8891             {
8892               tree access = NULL_TREE;
8893               int fs = FIELD_STATIC (decl);
8894
8895               /* If we're accessing an outer scope local alias, make
8896                  sure we change the name of the field we're going to
8897                  build access to. */
8898               if (FIELD_LOCAL_ALIAS_USED (decl))
8899                 name = DECL_NAME (decl);
8900
8901               /* Instance variable (8.3.1.1) can't appear within
8902                  static method, static initializer or initializer for
8903                  a static variable. */
8904               if (!fs && METHOD_STATIC (current_function_decl))
8905                 {
8906                   static_ref_err (id, name, current_class);
8907                   return error_mark_node;
8908                 }
8909               /* Instance variables can't appear as an argument of
8910                  an explicit constructor invocation */
8911               if (!fs && ctxp->explicit_constructor_p
8912                   && !enclosing_context_p (DECL_CONTEXT (decl), current_class))
8913                 {
8914                   parse_error_context
8915                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8916                   return error_mark_node;
8917                 }
8918
8919               /* If we're processing an inner class and we're trying
8920                  to access a field belonging to an outer class, build
8921                  the access to the field */
8922               if (!fs && outer_field_access_p (current_class, decl))
8923                 {
8924                   if (CLASS_STATIC (TYPE_NAME (current_class)))
8925                     {
8926                       static_ref_err (id, DECL_NAME (decl), current_class);
8927                       return error_mark_node;
8928                     }
8929                   return build_outer_field_access (id, decl);
8930                 }
8931
8932               /* Otherwise build what it takes to access the field */
8933               access = build_field_ref ((fs ? NULL_TREE : current_this),
8934                                         DECL_CONTEXT (decl), name);
8935               if (fs)
8936                 access = maybe_build_class_init_for_field (decl, access);
8937               /* We may be asked to save the real field access node */
8938               if (orig)
8939                 *orig = access;
8940               /* And we return what we got */
8941               return access;
8942             }
8943           /* Fall down to error report on undefined variable */
8944         }
8945     }
8946   /* 6.5.5.2 Qualified Expression Names */
8947   else
8948     {
8949       if (orig)
8950         *orig = NULL_TREE;
8951       qualify_ambiguous_name (id);
8952       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8953       /* 15.10.2: Accessing Superclass Members using super */
8954       return resolve_field_access (id, orig, NULL);
8955     }
8956
8957   /* We've got an error here */
8958   if (INNER_CLASS_TYPE_P (current_class))
8959     parse_error_context (id, 
8960                          "Local variable `%s' can't be accessed from within the inner class `%s' unless it is declared final",
8961                          IDENTIFIER_POINTER (name),
8962                          IDENTIFIER_POINTER (DECL_NAME
8963                                              (TYPE_NAME (current_class))));
8964   else
8965     parse_error_context (id, "Undefined variable `%s'", 
8966                          IDENTIFIER_POINTER (name));
8967
8968   return error_mark_node;
8969 }
8970
8971 static void
8972 static_ref_err (wfl, field_id, class_type)
8973     tree wfl, field_id, class_type;
8974 {
8975   parse_error_context 
8976     (wfl, 
8977      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8978      IDENTIFIER_POINTER (field_id), 
8979      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8980 }
8981
8982 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8983    We return something suitable to generate the field access. We also
8984    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
8985    recipient's address can be null. */
8986
8987 static tree
8988 resolve_field_access (qual_wfl, field_decl, field_type)
8989      tree qual_wfl;
8990      tree *field_decl, *field_type;
8991 {
8992   int is_static = 0;
8993   tree field_ref;
8994   tree decl, where_found, type_found;
8995
8996   if (resolve_qualified_expression_name (qual_wfl, &decl,
8997                                          &where_found, &type_found))
8998     return error_mark_node;
8999
9000   /* Resolve the LENGTH field of an array here */
9001   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
9002       && type_found && TYPE_ARRAY_P (type_found) 
9003       && ! flag_emit_class_files && ! flag_emit_xref)
9004     {
9005       tree length = build_java_array_length_access (where_found);
9006       field_ref = length;
9007
9008       /* In case we're dealing with a static array, we need to
9009          initialize its class before the array length can be fetched.
9010          It's also a good time to create a DECL_RTL for the field if
9011          none already exists, otherwise if the field was declared in a
9012          class found in an external file and hasn't been (and won't
9013          be) accessed for its value, none will be created. */
9014       if (TREE_CODE (where_found) == VAR_DECL && FIELD_STATIC (where_found))
9015         {
9016           build_static_field_ref (where_found);
9017           field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
9018         }
9019     }
9020   /* We might have been trying to resolve field.method(). In which
9021      case, the resolution is over and decl is the answer */
9022   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
9023     field_ref = decl;
9024   else if (JDECL_P (decl))
9025     {
9026       if (!type_found)
9027         type_found = DECL_CONTEXT (decl);
9028       is_static = FIELD_STATIC (decl);
9029       field_ref = build_field_ref ((is_static && !flag_emit_xref? 
9030                                     NULL_TREE : where_found), 
9031                                    type_found, DECL_NAME (decl));
9032       if (field_ref == error_mark_node)
9033         return error_mark_node;
9034       if (is_static)
9035         field_ref = maybe_build_class_init_for_field (decl, field_ref);
9036     }
9037   else
9038     field_ref = decl;
9039
9040   if (field_decl)
9041     *field_decl = decl;
9042   if (field_type)
9043     *field_type = (QUAL_DECL_TYPE (decl) ? 
9044                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
9045   return field_ref;
9046 }
9047
9048 /* If NODE is an access to f static field, strip out the class
9049    initialization part and return the field decl, otherwise, return
9050    NODE. */
9051
9052 static tree
9053 strip_out_static_field_access_decl (node)
9054     tree node;
9055 {
9056   if (TREE_CODE (node) == COMPOUND_EXPR)
9057     {
9058       tree op1 = TREE_OPERAND (node, 1);
9059       if (TREE_CODE (op1) == COMPOUND_EXPR)
9060          {
9061            tree call = TREE_OPERAND (op1, 0);
9062            if (TREE_CODE (call) == CALL_EXPR
9063                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
9064                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
9065                == soft_initclass_node)
9066              return TREE_OPERAND (op1, 1);
9067          }
9068       else if (JDECL_P (op1))
9069         return op1;
9070     }
9071   return node;
9072 }
9073
9074 /* 6.5.5.2: Qualified Expression Names */
9075
9076 static int
9077 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
9078      tree wfl;
9079      tree *found_decl, *type_found, *where_found;
9080 {
9081   int from_type = 0;            /* Field search initiated from a type */
9082   int from_super = 0, from_cast = 0, from_qualified_this = 0;
9083   int previous_call_static = 0;
9084   int is_static;
9085   tree decl = NULL_TREE, type = NULL_TREE, q;
9086   /* For certain for of inner class instantiation */
9087   tree saved_current, saved_this;               
9088 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
9089   { current_class = saved_current; current_this = saved_this;}
9090
9091   *type_found = *where_found = NULL_TREE;
9092
9093   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
9094     {
9095       tree qual_wfl = QUAL_WFL (q);
9096       tree ret_decl;            /* for EH checking */
9097       int location;             /* for EH checking */
9098
9099       /* 15.10.1 Field Access Using a Primary */
9100       switch (TREE_CODE (qual_wfl))
9101         {
9102         case CALL_EXPR:
9103         case NEW_CLASS_EXPR:
9104           /* If the access to the function call is a non static field,
9105              build the code to access it. */
9106           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9107             {
9108               decl = maybe_access_field (decl, *where_found, 
9109                                          DECL_CONTEXT (decl));
9110               if (decl == error_mark_node)
9111                 return 1;
9112             }
9113
9114           /* And code for the function call */
9115           if (complete_function_arguments (qual_wfl))
9116             return 1;
9117
9118           /* We might have to setup a new current class and a new this
9119              for the search of an inner class, relative to the type of
9120              a expression resolved as `decl'. The current values are
9121              saved and restored shortly after */
9122           saved_current = current_class;
9123           saved_this = current_this;
9124           if (decl 
9125               && (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9126                   || from_qualified_this))
9127             {
9128               /* If we still have `from_qualified_this', we have the form
9129                  <T>.this.f() and we need to build <T>.this */
9130               if (from_qualified_this)
9131                 {
9132                   decl = build_access_to_thisn (current_class, type, 0);
9133                   decl = java_complete_tree (decl);
9134                   type = TREE_TYPE (TREE_TYPE (decl));
9135                 }
9136               current_class = type;
9137               current_this = decl;
9138               from_qualified_this = 0;
9139             }
9140
9141           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
9142             CALL_USING_SUPER (qual_wfl) = 1;
9143           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
9144                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
9145           *where_found = patch_method_invocation (qual_wfl, decl, type,
9146                                                   from_super,
9147                                                   &is_static, &ret_decl);
9148           if (*where_found == error_mark_node)
9149             {
9150               RESTORE_THIS_AND_CURRENT_CLASS;
9151               return 1;
9152             }
9153           *type_found = type = QUAL_DECL_TYPE (*where_found);
9154
9155           /* If we're creating an inner class instance, check for that
9156              an enclosing instance is in scope */
9157           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9158               && INNER_ENCLOSING_SCOPE_CHECK (type))
9159             {
9160               parse_error_context 
9161                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
9162                  lang_printable_name (type, 0),
9163                  (!current_this ? "" :
9164                   "; an explicit one must be provided when creating this inner class"));
9165               RESTORE_THIS_AND_CURRENT_CLASS;
9166               return 1;
9167             }
9168
9169           /* In case we had to change then to resolve a inner class
9170              instantiation using a primary qualified by a `new' */
9171           RESTORE_THIS_AND_CURRENT_CLASS;
9172
9173           /* EH check. No check on access$<n> functions */
9174           if (location 
9175               && !OUTER_FIELD_ACCESS_IDENTIFIER_P 
9176                     (DECL_NAME (current_function_decl)))
9177             check_thrown_exceptions (location, ret_decl);
9178
9179           /* If the previous call was static and this one is too,
9180              build a compound expression to hold the two (because in
9181              that case, previous function calls aren't transported as
9182              forcoming function's argument. */
9183           if (previous_call_static && is_static)
9184             {
9185               decl = build (COMPOUND_EXPR, type, decl, *where_found);
9186               TREE_SIDE_EFFECTS (decl) = 1;
9187             }
9188           else
9189             {
9190               previous_call_static = is_static;
9191               decl = *where_found;
9192             }
9193           from_type = 0;
9194           continue;
9195
9196         case NEW_ARRAY_EXPR:
9197         case NEW_ANONYMOUS_ARRAY_EXPR:
9198           *where_found = decl = java_complete_tree (qual_wfl);
9199           if (decl == error_mark_node)
9200             return 1;
9201           *type_found = type = QUAL_DECL_TYPE (decl);
9202           continue;
9203
9204         case CONVERT_EXPR:
9205           *where_found = decl = java_complete_tree (qual_wfl);
9206           if (decl == error_mark_node)
9207             return 1;
9208           *type_found = type = QUAL_DECL_TYPE (decl);
9209           from_cast = 1;
9210           continue;
9211
9212         case CONDITIONAL_EXPR:
9213         case STRING_CST:
9214         case MODIFY_EXPR:
9215           *where_found = decl = java_complete_tree (qual_wfl);
9216           if (decl == error_mark_node)
9217             return 1;
9218           *type_found = type = QUAL_DECL_TYPE (decl);
9219           continue;
9220
9221         case ARRAY_REF:
9222           /* If the access to the function call is a non static field,
9223              build the code to access it. */
9224           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9225             {
9226               decl = maybe_access_field (decl, *where_found, type);
9227               if (decl == error_mark_node)
9228                 return 1;
9229             }
9230           /* And code for the array reference expression */
9231           decl = java_complete_tree (qual_wfl);
9232           if (decl == error_mark_node)
9233             return 1;
9234           type = QUAL_DECL_TYPE (decl);
9235           continue;
9236
9237         case PLUS_EXPR:
9238           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9239             return 1;
9240           if ((type = patch_string (decl)))
9241             decl = type;
9242           *where_found = QUAL_RESOLUTION (q) = decl;
9243           *type_found = type = TREE_TYPE (decl);
9244           break;
9245
9246         case CLASS_LITERAL:
9247           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9248             return 1;
9249           *where_found = QUAL_RESOLUTION (q) = decl;
9250           *type_found = type = TREE_TYPE (decl);
9251           break;
9252
9253         default:
9254           /* Fix for -Wall Just go to the next statement. Don't
9255              continue */
9256           break;
9257         }
9258
9259       /* If we fall here, we weren't processing a (static) function call. */
9260       previous_call_static = 0;
9261
9262       /* It can be the keyword THIS */
9263       if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION
9264           && EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
9265         {
9266           if (!current_this)
9267             {
9268               parse_error_context 
9269                 (wfl, "Keyword `this' used outside allowed context");
9270               return 1;
9271             }
9272           if (ctxp->explicit_constructor_p
9273               && type == current_class)
9274             {
9275               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9276               return 1;
9277             }
9278           /* We have to generate code for intermediate acess */
9279           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
9280             {
9281               *where_found = decl = current_this;
9282               *type_found = type = QUAL_DECL_TYPE (decl);
9283             }
9284           /* We're trying to access the this from somewhere else. Make sure
9285              it's allowed before doing so. */
9286           else
9287             {
9288               if (!enclosing_context_p (type, current_class))
9289                 {
9290                   char *p  = xstrdup (lang_printable_name (type, 0));
9291                   parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'", 
9292                                        p, p, 
9293                                        lang_printable_name (current_class, 0));
9294                   free (p);
9295                   return 1;
9296                 }
9297               from_qualified_this = 1;
9298               /* If there's nothing else after that, we need to
9299                  produce something now, otherwise, the section of the
9300                  code that needs to produce <T>.this will generate
9301                  what is necessary. */
9302               if (!TREE_CHAIN (q))
9303                 {
9304                   decl = build_access_to_thisn (current_class, type, 0);
9305                   *where_found = decl = java_complete_tree (decl);
9306                   *type_found = type = TREE_TYPE (decl);
9307                 }
9308             }
9309
9310           from_type = 0;
9311           continue;
9312         }
9313
9314       /* 15.10.2 Accessing Superclass Members using SUPER */
9315       if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION
9316           && EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
9317         {
9318           tree node;
9319           /* Check on the restricted use of SUPER */
9320           if (METHOD_STATIC (current_function_decl)
9321               || current_class == object_type_node)
9322             {
9323               parse_error_context 
9324                 (wfl, "Keyword `super' used outside allowed context");
9325               return 1;
9326             }
9327           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
9328           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
9329                              CLASSTYPE_SUPER (current_class),
9330                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
9331           *where_found = decl = java_complete_tree (node);
9332           if (decl == error_mark_node)
9333             return 1;
9334           *type_found = type = QUAL_DECL_TYPE (decl);
9335           from_super = from_type = 1;
9336           continue;
9337         }
9338
9339       /* 15.13.1: Can't search for field name in packages, so we
9340          assume a variable/class name was meant. */
9341       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
9342         {
9343           tree name = resolve_package (wfl, &q);
9344           if (name)
9345             {
9346               tree list;
9347               *where_found = decl = resolve_no_layout (name, qual_wfl);
9348               /* We want to be absolutely sure that the class is laid
9349                  out. We're going to search something inside it. */
9350               *type_found = type = TREE_TYPE (decl);
9351               layout_class (type);
9352               from_type = 1;
9353
9354               /* Fix them all the way down, if any are left. */
9355               if (q)
9356                 {
9357                   list = TREE_CHAIN (q);
9358                   while (list)
9359                     {
9360                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
9361                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
9362                       list = TREE_CHAIN (list);
9363                     }
9364                 }
9365             }
9366           else
9367             {
9368               if (from_super || from_cast)
9369                 parse_error_context 
9370                   ((from_cast ? qual_wfl : wfl),
9371                    "No variable `%s' defined in class `%s'",
9372                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9373                    lang_printable_name (type, 0));
9374               else
9375                 parse_error_context
9376                   (qual_wfl, "Undefined variable or class name: `%s'",
9377                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
9378               return 1;
9379             }
9380         }
9381
9382       /* We have a type name. It's been already resolved when the
9383          expression was qualified. */
9384       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
9385         {
9386           if (!(decl = QUAL_RESOLUTION (q)))
9387             return 1;           /* Error reported already */
9388
9389           /* Sneak preview. If next we see a `new', we're facing a
9390              qualification with resulted in a type being selected
9391              instead of a field.  Report the error */
9392           if(TREE_CHAIN (q) 
9393              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
9394             {
9395               parse_error_context (qual_wfl, "Undefined variable `%s'",
9396                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9397               return 1;
9398             }
9399
9400           if (not_accessible_p (TREE_TYPE (decl), decl, type, 0))
9401             {
9402               parse_error_context 
9403                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
9404                  java_accstring_lookup (get_access_flags_from_decl (decl)),
9405                  GET_TYPE_NAME (type),
9406                  IDENTIFIER_POINTER (DECL_NAME (decl)),
9407                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9408               return 1;
9409             }
9410           check_deprecation (qual_wfl, decl);
9411
9412           type = TREE_TYPE (decl);
9413           from_type = 1;
9414         }
9415       /* We resolve and expression name */
9416       else 
9417         {
9418           tree field_decl = NULL_TREE;
9419
9420           /* If there exists an early resolution, use it. That occurs
9421              only once and we know that there are more things to
9422              come. Don't do that when processing something after SUPER
9423              (we need more thing to be put in place below */
9424           if (!from_super && QUAL_RESOLUTION (q))
9425             {
9426               decl = QUAL_RESOLUTION (q);
9427               if (!type)
9428                 {
9429                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
9430                     {
9431                       if (current_this)
9432                         *where_found = current_this;
9433                       else
9434                         {
9435                           static_ref_err (qual_wfl, DECL_NAME (decl),
9436                                           current_class);
9437                           return 1;
9438                         }
9439                       if (outer_field_access_p (current_class, decl))
9440                         decl = build_outer_field_access (qual_wfl, decl);
9441                     }
9442                   else
9443                     {
9444                       *where_found = TREE_TYPE (decl);
9445                       if (TREE_CODE (*where_found) == POINTER_TYPE)
9446                         *where_found = TREE_TYPE (*where_found);
9447                     }
9448                 }
9449             }
9450
9451           /* We have to search for a field, knowing the type of its
9452              container. The flag FROM_TYPE indicates that we resolved
9453              the last member of the expression as a type name, which
9454              means that for the resolution of this field, we'll look
9455              for other errors than if it was resolved as a member of
9456              an other field. */
9457           else
9458             {
9459               int is_static;
9460               tree field_decl_type; /* For layout */
9461
9462               if (!from_type && !JREFERENCE_TYPE_P (type))
9463                 {
9464                   parse_error_context 
9465                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9466                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9467                      lang_printable_name (type, 0),
9468                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9469                   return 1;
9470                 }
9471               
9472               field_decl = lookup_field_wrapper (type,
9473                                                  EXPR_WFL_NODE (qual_wfl));
9474
9475               /* Maybe what we're trying to access to is an inner
9476                  class, only if decl is a TYPE_DECL. */
9477               if (!field_decl && TREE_CODE (decl) == TYPE_DECL)
9478                 {
9479                   tree ptr, inner_decl;
9480
9481                   BUILD_PTR_FROM_NAME (ptr, EXPR_WFL_NODE (qual_wfl));
9482                   inner_decl = resolve_class (decl, ptr, NULL_TREE, qual_wfl);
9483                   if (inner_decl)
9484                     {
9485                       check_inner_class_access (inner_decl, decl, qual_wfl); 
9486                       type = TREE_TYPE (inner_decl);
9487                       decl = inner_decl;
9488                       from_type = 1;
9489                       continue;
9490                     }
9491                 }
9492
9493               if (field_decl == NULL_TREE)
9494                 {
9495                   parse_error_context 
9496                     (qual_wfl, "No variable `%s' defined in type `%s'",
9497                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9498                      GET_TYPE_NAME (type));
9499                   return 1;
9500                 }
9501               if (field_decl == error_mark_node)
9502                 return 1;
9503
9504               /* Layout the type of field_decl, since we may need
9505                  it. Don't do primitive types or loaded classes. The
9506                  situation of non primitive arrays may not handled
9507                  properly here. FIXME */
9508               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9509                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9510               else
9511                 field_decl_type = TREE_TYPE (field_decl);
9512               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9513                   && !CLASS_LOADED_P (field_decl_type)
9514                   && !TYPE_ARRAY_P (field_decl_type))
9515                 resolve_and_layout (field_decl_type, NULL_TREE);
9516               
9517               /* Check on accessibility here */
9518               if (not_accessible_p (current_class, field_decl,
9519                                     DECL_CONTEXT (field_decl), from_super))
9520                 {
9521                   parse_error_context 
9522                     (qual_wfl,
9523                      "Can't access %s field `%s.%s' from `%s'",
9524                      java_accstring_lookup 
9525                        (get_access_flags_from_decl (field_decl)),
9526                      GET_TYPE_NAME (type),
9527                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9528                      IDENTIFIER_POINTER 
9529                        (DECL_NAME (TYPE_NAME (current_class))));
9530                   return 1;
9531                 }
9532               check_deprecation (qual_wfl, field_decl);
9533               
9534               /* There are things to check when fields are accessed
9535                  from type. There are no restrictions on a static
9536                  declaration of the field when it is accessed from an
9537                  interface */
9538               is_static = FIELD_STATIC (field_decl);
9539               if (!from_super && from_type 
9540                   && !TYPE_INTERFACE_P (type) 
9541                   && !is_static 
9542                   && (current_function_decl 
9543                       && METHOD_STATIC (current_function_decl)))
9544                 {
9545                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9546                   return 1;
9547                 }
9548               from_cast = from_super = 0;
9549
9550               /* It's an access from a type but it isn't static, we
9551                  make it relative to `this'. */
9552               if (!is_static && from_type)
9553                 decl = current_this;
9554
9555               /* If we need to generate something to get a proper
9556                  handle on what this field is accessed from, do it
9557                  now. */
9558               if (!is_static)
9559                 {
9560                   decl = maybe_access_field (decl, *where_found, *type_found);
9561                   if (decl == error_mark_node)
9562                     return 1;
9563                 }
9564
9565               /* We want to keep the location were found it, and the type
9566                  we found. */
9567               *where_found = decl;
9568               *type_found = type;
9569
9570               /* Generate the correct expression for field access from
9571                  qualified this */
9572               if (from_qualified_this)
9573                 {
9574                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9575                   from_qualified_this = 0;
9576                 }
9577
9578               /* This is the decl found and eventually the next one to
9579                  search from */
9580               decl = field_decl;
9581             }
9582           from_type = 0;
9583           type = QUAL_DECL_TYPE (decl);
9584
9585           /* Sneak preview. If decl is qualified by a `new', report
9586              the error here to be accurate on the peculiar construct */
9587           if (TREE_CHAIN (q) 
9588               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9589               && !JREFERENCE_TYPE_P (type))
9590             {
9591               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9592                                    lang_printable_name (type, 0));
9593               return 1;
9594             }
9595         }
9596       /* `q' might have changed due to a after package resolution
9597          re-qualification */
9598       if (!q)
9599         break;
9600     }
9601   *found_decl = decl;
9602   return 0;
9603 }
9604
9605 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9606    can't be accessed from REFERENCE (a record type). If MEMBER
9607    features a protected access, we then use WHERE which, if non null,
9608    holds the type of MEMBER's access that is checked against
9609    6.6.2.1. This function should be used when decl is a field or a
9610    method.  */
9611
9612 static int
9613 not_accessible_p (reference, member, where, from_super)
9614      tree reference, member;
9615      tree where;
9616      int from_super;
9617 {
9618   int access_flag = get_access_flags_from_decl (member);
9619
9620   /* Inner classes are processed by check_inner_class_access */
9621   if (INNER_CLASS_TYPE_P (reference))
9622     return 0;
9623
9624   /* Access always granted for members declared public */
9625   if (access_flag & ACC_PUBLIC)
9626     return 0;
9627   
9628   /* Check access on protected members */
9629   if (access_flag & ACC_PROTECTED)
9630     {
9631       /* Access granted if it occurs from within the package
9632          containing the class in which the protected member is
9633          declared */
9634       if (class_in_current_package (DECL_CONTEXT (member)))
9635         return 0;
9636
9637       /* If accessed with the form `super.member', then access is granted */
9638       if (from_super)
9639         return 0;
9640
9641       /* If where is active, access was made through a
9642          qualifier. Access is granted if the type of the qualifier is
9643          or is a sublass of the type the access made from (6.6.2.1.)  */
9644       if (where && !inherits_from_p (reference, where))
9645         return 1;
9646
9647       /* Otherwise, access is granted if occuring from the class where
9648          member is declared or a subclass of it. Find the right
9649          context to perform the check */
9650       if (PURE_INNER_CLASS_TYPE_P (reference))
9651         {
9652           while (INNER_CLASS_TYPE_P (reference))
9653             {
9654               if (inherits_from_p (reference, DECL_CONTEXT (member)))
9655                 return 0;
9656               reference = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (reference)));
9657             }
9658         }
9659       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9660         return 0;
9661       return 1;
9662     }
9663
9664   /* Check access on private members. Access is granted only if it
9665      occurs from within the class in which it is declared -- that does
9666      it for innerclasses too. */
9667   if (access_flag & ACC_PRIVATE)
9668     {
9669       if (reference == DECL_CONTEXT (member))
9670         return 0;
9671       if (enclosing_context_p (reference, DECL_CONTEXT (member)))
9672         return 0;
9673       return 1;
9674     }
9675
9676   /* Default access are permitted only when occuring within the
9677      package in which the type (REFERENCE) is declared. In other words,
9678      REFERENCE is defined in the current package */
9679   if (ctxp->package)
9680     return !class_in_current_package (reference);
9681
9682   /* Otherwise, access is granted */
9683   return 0;
9684 }
9685
9686 /* Test deprecated decl access.  */
9687 static void
9688 check_deprecation (wfl, decl)
9689      tree wfl, decl;
9690 {
9691   const char *file = DECL_SOURCE_FILE (decl);
9692   /* Complain if the field is deprecated and the file it was defined
9693      in isn't compiled at the same time the file which contains its
9694      use is */
9695   if (DECL_DEPRECATED (decl) 
9696       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9697     {
9698       char the [20];
9699       switch (TREE_CODE (decl))
9700         {
9701         case FUNCTION_DECL:
9702           strcpy (the, "method");
9703           break;
9704         case FIELD_DECL:
9705           strcpy (the, "field");
9706           break;
9707         case TYPE_DECL:
9708           strcpy (the, "class");
9709           break;
9710         default:
9711           abort ();
9712         }
9713       parse_warning_context 
9714         (wfl, "The %s `%s' in class `%s' has been deprecated", 
9715          the, lang_printable_name (decl, 0),
9716          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9717     }
9718 }
9719
9720 /* Returns 1 if class was declared in the current package, 0 otherwise */
9721
9722 static int
9723 class_in_current_package (class)
9724      tree class;
9725 {
9726   static tree cache = NULL_TREE;
9727   int qualified_flag;
9728   tree left;
9729
9730   if (cache == class)
9731     return 1;
9732
9733   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9734
9735   /* If the current package is empty and the name of CLASS is
9736      qualified, class isn't in the current package.  If there is a
9737      current package and the name of the CLASS is not qualified, class
9738      isn't in the current package */
9739   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9740     return 0;
9741
9742   /* If there is not package and the name of CLASS isn't qualified,
9743      they belong to the same unnamed package */
9744   if (!ctxp->package && !qualified_flag)
9745     return 1;
9746
9747   /* Compare the left part of the name of CLASS with the package name */
9748   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9749   if (ctxp->package == left)
9750     {
9751       static int initialized_p;
9752       /* Register CACHE with the garbage collector.  */
9753       if (!initialized_p)
9754         {
9755           ggc_add_tree_root (&cache, 1);
9756           initialized_p = 1;
9757         }
9758
9759       cache = class;
9760       return 1;
9761     }
9762   return 0;
9763 }
9764
9765 /* This function may generate code to access DECL from WHERE. This is
9766    done only if certain conditions meet.  */
9767
9768 static tree
9769 maybe_access_field (decl, where, type)
9770   tree decl, where, type;
9771 {
9772   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9773       && !FIELD_STATIC (decl))
9774     decl = build_field_ref (where ? where : current_this, 
9775                             (type ? type : DECL_CONTEXT (decl)),
9776                             DECL_NAME (decl));
9777   return decl;
9778 }
9779
9780 /* Build a method invocation, by patching PATCH. If non NULL
9781    and according to the situation, PRIMARY and WHERE may be
9782    used. IS_STATIC is set to 1 if the invoked function is static. */
9783
9784 static tree
9785 patch_method_invocation (patch, primary, where, from_super,
9786                         is_static, ret_decl)
9787      tree patch, primary, where;
9788      int from_super;
9789      int *is_static;
9790      tree *ret_decl;
9791 {
9792   tree wfl = TREE_OPERAND (patch, 0);
9793   tree args = TREE_OPERAND (patch, 1);
9794   tree name = EXPR_WFL_NODE (wfl);
9795   tree list;
9796   int is_static_flag = 0;
9797   int is_super_init = 0;
9798   tree this_arg = NULL_TREE;
9799   int is_array_clone_call = 0;
9800   
9801   /* Should be overriden if everything goes well. Otherwise, if
9802      something fails, it should keep this value. It stop the
9803      evaluation of a bogus assignment. See java_complete_tree,
9804      MODIFY_EXPR: for the reasons why we sometimes want to keep on
9805      evaluating an assignment */
9806   TREE_TYPE (patch) = error_mark_node;
9807
9808   /* Since lookup functions are messing with line numbers, save the
9809      context now.  */
9810   java_parser_context_save_global ();
9811
9812   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9813
9814   /* Resolution of qualified name, excluding constructors */
9815   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9816     {
9817       tree identifier, identifier_wfl, type, resolved;
9818       /* Extract the last IDENTIFIER of the qualified
9819          expression. This is a wfl and we will use it's location
9820          data during error report. */
9821       identifier_wfl = cut_identifier_in_qualified (wfl);
9822       identifier = EXPR_WFL_NODE (identifier_wfl);
9823       
9824       /* Given the context, IDENTIFIER is syntactically qualified
9825          as a MethodName. We need to qualify what's before */
9826       qualify_ambiguous_name (wfl);
9827       resolved = resolve_field_access (wfl, NULL, NULL);
9828
9829       if (resolved == error_mark_node)
9830         PATCH_METHOD_RETURN_ERROR ();
9831
9832       type = GET_SKIP_TYPE (resolved);
9833       resolve_and_layout (type, NULL_TREE);
9834       
9835       if (JPRIMITIVE_TYPE_P (type))
9836         {
9837           parse_error_context
9838             (identifier_wfl,
9839              "Can't invoke a method on primitive type `%s'",
9840              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9841           PATCH_METHOD_RETURN_ERROR ();         
9842         }
9843
9844       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9845       args = nreverse (args);
9846
9847       /* We're resolving a call from a type */
9848       if (TREE_CODE (resolved) == TYPE_DECL)
9849         {
9850           if (CLASS_INTERFACE (resolved))
9851             {
9852               parse_error_context
9853                 (identifier_wfl,
9854                 "Can't make static reference to method `%s' in interface `%s'",
9855                  IDENTIFIER_POINTER (identifier), 
9856                  IDENTIFIER_POINTER (name));
9857               PATCH_METHOD_RETURN_ERROR ();
9858             }
9859           if (list && !METHOD_STATIC (list))
9860             {
9861               char *fct_name = xstrdup (lang_printable_name (list, 0));
9862               parse_error_context 
9863                 (identifier_wfl,
9864                  "Can't make static reference to method `%s %s' in class `%s'",
9865                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9866                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9867               free (fct_name);
9868               PATCH_METHOD_RETURN_ERROR ();
9869             }
9870         }
9871       else
9872         this_arg = primary = resolved;
9873       
9874       if (TYPE_ARRAY_P (type) && identifier == get_identifier ("clone"))
9875         is_array_clone_call = 1;
9876       
9877       /* IDENTIFIER_WFL will be used to report any problem further */
9878       wfl = identifier_wfl;
9879     }
9880   /* Resolution of simple names, names generated after a primary: or
9881      constructors */
9882   else
9883     {
9884       tree class_to_search = NULL_TREE;
9885       int lc;                   /* Looking for Constructor */
9886       
9887       /* We search constructor in their target class */
9888       if (CALL_CONSTRUCTOR_P (patch))
9889         {
9890           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9891             class_to_search = EXPR_WFL_NODE (wfl);
9892           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
9893                    this_identifier_node)
9894             class_to_search = NULL_TREE;
9895           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9896                    super_identifier_node)
9897             {
9898               is_super_init = 1;
9899               if (CLASSTYPE_SUPER (current_class))
9900                 class_to_search = 
9901                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9902               else
9903                 {
9904                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9905                   PATCH_METHOD_RETURN_ERROR ();
9906                 }
9907             }
9908
9909           /* Class to search is NULL if we're searching the current one */
9910           if (class_to_search)
9911             {
9912               class_to_search = resolve_and_layout (class_to_search, wfl);
9913
9914               if (!class_to_search)
9915                 {
9916                   parse_error_context 
9917                     (wfl, "Class `%s' not found in type declaration",
9918                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9919                   PATCH_METHOD_RETURN_ERROR ();
9920                 }
9921               
9922               /* Can't instantiate an abstract class, but we can
9923                  invoke it's constructor. It's use within the `new'
9924                  context is denied here. */
9925               if (CLASS_ABSTRACT (class_to_search) 
9926                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
9927                 {
9928                   parse_error_context 
9929                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9930                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9931                   PATCH_METHOD_RETURN_ERROR ();
9932                 }
9933
9934               class_to_search = TREE_TYPE (class_to_search);
9935             }
9936           else
9937             class_to_search = current_class;
9938           lc = 1;
9939         }
9940       /* This is a regular search in the local class, unless an
9941          alternate class is specified. */
9942       else
9943         {
9944           if (where != NULL_TREE)
9945             class_to_search = where;
9946           else if (QUALIFIED_P (name))
9947             class_to_search = current_class;
9948           else
9949             {
9950               class_to_search = current_class;
9951
9952               for (;;)
9953                 {
9954                   if (has_method (class_to_search, name))
9955                     break;
9956                   if (! INNER_CLASS_TYPE_P (class_to_search))
9957                     {
9958                       parse_error_context (wfl,
9959                                            "No method named `%s' in scope",
9960                                            IDENTIFIER_POINTER (name));
9961                       PATCH_METHOD_RETURN_ERROR ();
9962                     }
9963                   class_to_search
9964                     = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_to_search)));
9965                 }
9966             }
9967           lc = 0;
9968         }
9969
9970       /* NAME is a simple identifier or comes from a primary. Search
9971          in the class whose declaration contain the method being
9972          invoked. */
9973       resolve_and_layout (class_to_search, NULL_TREE);
9974
9975       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9976       /* Don't continue if no method were found, as the next statement
9977          can't be executed then. */
9978       if (!list)
9979         PATCH_METHOD_RETURN_ERROR ();
9980       
9981       if (TYPE_ARRAY_P (class_to_search)
9982           && DECL_NAME (list) == get_identifier ("clone"))
9983         is_array_clone_call = 1;
9984
9985       /* Check for static reference if non static methods */
9986       if (check_for_static_method_reference (wfl, patch, list, 
9987                                              class_to_search, primary))
9988         PATCH_METHOD_RETURN_ERROR ();
9989
9990       /* Check for inner classes creation from illegal contexts */
9991       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9992                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9993           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9994         {
9995           parse_error_context 
9996             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9997              lang_printable_name (class_to_search, 0),
9998              (!current_this ? "" :
9999               "; an explicit one must be provided when creating this inner class"));
10000           PATCH_METHOD_RETURN_ERROR ();
10001         }
10002
10003       /* Non static methods are called with the current object extra
10004          argument. If patch a `new TYPE()', the argument is the value
10005          returned by the object allocator. If method is resolved as a
10006          primary, use the primary otherwise use the current THIS. */
10007       args = nreverse (args);
10008       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
10009         {
10010           this_arg = primary ? primary : current_this;
10011
10012           /* If we're using an access method, things are different.
10013              There are two familly of cases:
10014
10015              1) We're not generating bytecodes:
10016
10017              - LIST is non static. It's invocation is transformed from
10018                x(a1,...,an) into this$<n>.x(a1,....an).
10019              - LIST is static. It's invocation is transformed from
10020                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
10021
10022              2) We're generating bytecodes:
10023              
10024              - LIST is non static. It's invocation is transformed from
10025                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
10026              - LIST is static. It's invocation is transformed from
10027                x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
10028
10029              Of course, this$<n> can be abitrary complex, ranging from
10030              this$0 (the immediate outer context) to 
10031              access$0(access$0(...(this$0))). 
10032              
10033              maybe_use_access_method returns a non zero value if the
10034              this_arg has to be moved into the (then generated) stub
10035              argument list. In the meantime, the selected function
10036              might have be replaced by a generated stub. */
10037           if (maybe_use_access_method (is_super_init, &list, &this_arg))
10038             {
10039               args = tree_cons (NULL_TREE, this_arg, args);
10040               this_arg = NULL_TREE; /* So it doesn't get chained twice */
10041             }
10042         }
10043     }
10044
10045   /* Merge point of all resolution schemes. If we have nothing, this
10046      is an error, already signaled */
10047   if (!list) 
10048     PATCH_METHOD_RETURN_ERROR ();
10049
10050   /* Check accessibility, position the is_static flag, build and
10051      return the call */
10052   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list,
10053                         (primary ? TREE_TYPE (TREE_TYPE (primary)) : 
10054                          NULL_TREE), from_super)
10055       /* Calls to clone() on array types are permitted as a special-case. */
10056       && !is_array_clone_call)
10057     {
10058       const char *fct_name = IDENTIFIER_POINTER (DECL_NAME (list));
10059       const char *access =
10060         java_accstring_lookup (get_access_flags_from_decl (list));
10061       const char *klass =
10062         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list))));
10063       const char *refklass =
10064         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
10065       const char *what = (DECL_CONSTRUCTOR_P (list)
10066                           ? "constructor" : "method");
10067       /* FIXME: WFL yields the wrong message here but I don't know
10068          what else to use.  */
10069       parse_error_context (wfl,
10070                            "Can't access %s %s `%s.%s' from `%s'",
10071                            access, what, klass, fct_name, refklass);
10072       PATCH_METHOD_RETURN_ERROR ();
10073     }
10074   check_deprecation (wfl, list);
10075
10076   /* If invoking a innerclass constructor, there are hidden parameters
10077      to pass */
10078   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
10079       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10080     {
10081       /* And make sure we add the accessed local variables to be saved
10082          in field aliases. */
10083       args = build_alias_initializer_parameter_list
10084         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
10085
10086       /* Secretly pass the current_this/primary as a second argument */
10087       if (primary || current_this)
10088         {
10089           tree extra_arg;
10090           tree this_type = (current_this ?
10091                             TREE_TYPE (TREE_TYPE (current_this)) : NULL_TREE);
10092           /* Method's (list) enclosing context */
10093           tree mec = DECL_CONTEXT (TYPE_NAME (DECL_CONTEXT (list)));
10094           /* If we have a primary, use it. */
10095           if (primary)
10096             extra_arg = primary;
10097           /* The current `this' is an inner class but isn't a direct
10098              enclosing context for the inner class we're trying to
10099              create. Build an access to the proper enclosing context
10100              and use it. */
10101           else if (current_this && PURE_INNER_CLASS_TYPE_P (this_type)
10102                    && this_type != TREE_TYPE (mec))
10103             {
10104
10105               extra_arg = build_access_to_thisn (current_class,
10106                                                  TREE_TYPE (mec), 0);
10107               extra_arg = java_complete_tree (extra_arg);
10108             }
10109           /* Otherwise, just use the current `this' as an enclosing
10110              context. */
10111           else
10112             extra_arg = current_this;
10113           args = tree_cons (NULL_TREE, extra_arg, args);
10114         }
10115       else
10116         args = tree_cons (NULL_TREE, integer_zero_node, args);
10117     }
10118
10119   /* This handles the situation where a constructor invocation needs
10120      to have an enclosing context passed as a second parameter (the
10121      constructor is one of an inner class. We extract it from the
10122      current function.  */
10123   if (is_super_init && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10124     {
10125       tree enclosing_decl = DECL_CONTEXT (TYPE_NAME (current_class));
10126       tree extra_arg;
10127
10128       if (ANONYMOUS_CLASS_P (current_class) || !DECL_CONTEXT (enclosing_decl))
10129         {
10130           extra_arg = DECL_FUNCTION_BODY (current_function_decl);
10131           extra_arg = TREE_CHAIN (BLOCK_EXPR_DECLS (extra_arg));
10132         }
10133       else
10134         {
10135           tree dest = TREE_TYPE (DECL_CONTEXT (enclosing_decl));
10136           extra_arg = 
10137             build_access_to_thisn (TREE_TYPE (enclosing_decl), dest, 0);
10138           extra_arg = java_complete_tree (extra_arg);
10139         }
10140       args = tree_cons (NULL_TREE, extra_arg, args);
10141     }
10142
10143   is_static_flag = METHOD_STATIC (list);
10144   if (! is_static_flag && this_arg != NULL_TREE)
10145     args = tree_cons (NULL_TREE, this_arg, args);
10146
10147   /* In the context of an explicit constructor invocation, we can't
10148      invoke any method relying on `this'. Exceptions are: we're
10149      invoking a static function, primary exists and is not the current
10150      this, we're creating a new object. */
10151   if (ctxp->explicit_constructor_p 
10152       && !is_static_flag 
10153       && (!primary || primary == current_this)
10154       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
10155     {
10156       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
10157       PATCH_METHOD_RETURN_ERROR ();
10158     }
10159   java_parser_context_restore_global ();
10160   if (is_static) 
10161     *is_static = is_static_flag;
10162   /* Sometimes, we want the decl of the selected method. Such as for
10163      EH checking */
10164   if (ret_decl)
10165     *ret_decl = list;
10166   patch = patch_invoke (patch, list, args);
10167   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
10168     {
10169       tree finit_parms, finit_call;
10170       
10171       /* Prepare to pass hidden parameters to finit$, if any. */
10172       finit_parms = build_alias_initializer_parameter_list 
10173         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
10174       
10175       finit_call = 
10176         build_method_invocation (build_wfl_node (finit_identifier_node),
10177                                  finit_parms);
10178
10179       /* Generate the code used to initialize fields declared with an
10180          initialization statement and build a compound statement along
10181          with the super constructor invocation. */
10182       patch = build (COMPOUND_EXPR, void_type_node, patch,
10183                      java_complete_tree (finit_call));
10184       CAN_COMPLETE_NORMALLY (patch) = 1;
10185     }
10186   return patch;
10187 }
10188
10189 /* Check that we're not trying to do a static reference to a method in
10190    non static method. Return 1 if it's the case, 0 otherwise. */
10191
10192 static int
10193 check_for_static_method_reference (wfl, node, method, where, primary)
10194      tree wfl, node, method, where, primary;
10195 {
10196   if (METHOD_STATIC (current_function_decl) 
10197       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
10198     {
10199       char *fct_name = xstrdup (lang_printable_name (method, 0));
10200       parse_error_context 
10201         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
10202          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
10203          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
10204       free (fct_name);
10205       return 1;
10206     }
10207   return 0;
10208 }
10209
10210 /* Fix the invocation of *MDECL if necessary in the case of a
10211    invocation from an inner class. *THIS_ARG might be modified
10212    appropriately and an alternative access to *MDECL might be
10213    returned.  */
10214
10215 static int
10216 maybe_use_access_method (is_super_init, mdecl, this_arg)
10217      int is_super_init;
10218      tree *mdecl, *this_arg;
10219 {
10220   tree ctx;
10221   tree md = *mdecl, ta = *this_arg;
10222   int to_return = 0;
10223   int non_static_context = !METHOD_STATIC (md);
10224
10225   if (is_super_init 
10226       || DECL_CONTEXT (md) == current_class
10227       || !PURE_INNER_CLASS_TYPE_P (current_class) 
10228       || DECL_FINIT_P (md))
10229     return 0;
10230   
10231   /* If we're calling a method found in an enclosing class, generate
10232      what it takes to retrieve the right this. Don't do that if we're
10233      invoking a static method. Note that if MD's type is unrelated to
10234      CURRENT_CLASS, then the current this can be used. */
10235
10236   if (non_static_context && DECL_CONTEXT (md) != object_type_node)
10237     {
10238       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
10239       if (inherits_from_p (ctx, DECL_CONTEXT (md)))
10240         {
10241           ta = build_current_thisn (current_class);
10242           ta = build_wfl_node (ta);
10243         }
10244       else
10245         {
10246           tree type = ctx;
10247           while (type)
10248             {
10249               maybe_build_thisn_access_method (type);
10250               if (inherits_from_p (type, DECL_CONTEXT (md)))
10251                 {
10252                   ta = build_access_to_thisn (ctx, type, 0);
10253                   break;
10254                 }
10255               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
10256                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
10257             }
10258         }
10259       ta = java_complete_tree (ta);
10260     }
10261
10262   /* We might have to use an access method to get to MD. We can
10263      break the method access rule as far as we're not generating
10264      bytecode */
10265   if (METHOD_PRIVATE (md) && flag_emit_class_files)
10266     {
10267       md = build_outer_method_access_method (md);
10268       to_return = 1;
10269     }
10270
10271   *mdecl = md;
10272   *this_arg = ta;
10273
10274   /* Returnin a non zero value indicates we were doing a non static
10275      method invokation that is now a static invocation. It will have
10276      callee displace `this' to insert it in the regular argument
10277      list. */
10278   return (non_static_context && to_return);
10279 }
10280
10281 /* Patch an invoke expression METHOD and ARGS, based on its invocation
10282    mode.  */
10283
10284 static tree
10285 patch_invoke (patch, method, args)
10286      tree patch, method, args;
10287 {
10288   tree dtable, func;
10289   tree original_call, t, ta;
10290   tree check = NULL_TREE;
10291
10292   /* Last step for args: convert build-in types. If we're dealing with
10293      a new TYPE() type call, the first argument to the constructor
10294      isn't found in the incoming argument list, but delivered by
10295      `new' */
10296   t = TYPE_ARG_TYPES (TREE_TYPE (method));
10297   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10298     t = TREE_CHAIN (t);
10299   for (ta = args; t != end_params_node && ta; 
10300        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
10301     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
10302         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
10303       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
10304
10305   /* Resolve unresolved returned type isses */
10306   t = TREE_TYPE (TREE_TYPE (method));
10307   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
10308     resolve_and_layout (TREE_TYPE (t), NULL);
10309
10310   if (flag_emit_class_files || flag_emit_xref)
10311     func = method;
10312   else
10313     {
10314       tree signature = build_java_signature (TREE_TYPE (method));
10315       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
10316         {
10317         case INVOKE_VIRTUAL:
10318           dtable = invoke_build_dtable (0, args);
10319           func = build_invokevirtual (dtable, method);
10320           break;
10321
10322         case INVOKE_NONVIRTUAL:
10323           /* If the object for the method call is null, we throw an
10324              exception.  We don't do this if the object is the current
10325              method's `this'.  In other cases we just rely on an
10326              optimization pass to eliminate redundant checks.  */
10327           if (TREE_VALUE (args) != current_this)
10328             {
10329               /* We use a save_expr here to make sure we only evaluate
10330                  the new `self' expression once.  */
10331               tree save_arg = save_expr (TREE_VALUE (args));
10332               TREE_VALUE (args) = save_arg;
10333               check = java_check_reference (save_arg, 1);
10334             }
10335           /* Fall through.  */
10336
10337         case INVOKE_SUPER:
10338         case INVOKE_STATIC:
10339           func = build_known_method_ref (method, TREE_TYPE (method),
10340                                          DECL_CONTEXT (method),
10341                                          signature, args);
10342           break;
10343
10344         case INVOKE_INTERFACE:
10345           dtable = invoke_build_dtable (1, args);
10346           func = build_invokeinterface (dtable, method);
10347           break;
10348
10349         default:
10350           abort ();
10351         }
10352
10353       /* Ensure self_type is initialized, (invokestatic). FIXME */
10354       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
10355     }
10356
10357   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
10358   TREE_OPERAND (patch, 0) = func;
10359   TREE_OPERAND (patch, 1) = args;
10360   original_call = patch;
10361
10362   /* We're processing a `new TYPE ()' form. New is called and its
10363      returned value is the first argument to the constructor. We build
10364      a COMPOUND_EXPR and use saved expression so that the overall NEW
10365      expression value is a pointer to a newly created and initialized
10366      class. */
10367   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
10368     {
10369       tree class = DECL_CONTEXT (method);
10370       tree c1, saved_new, size, new;
10371       if (flag_emit_class_files || flag_emit_xref)
10372         {
10373           TREE_TYPE (patch) = build_pointer_type (class);
10374           return patch;
10375         }
10376       if (!TYPE_SIZE (class))
10377         safe_layout_class (class);
10378       size = size_in_bytes (class);
10379       new = build (CALL_EXPR, promote_type (class),
10380                    build_address_of (alloc_object_node),
10381                    tree_cons (NULL_TREE, build_class_ref (class),
10382                               build_tree_list (NULL_TREE, 
10383                                                size_in_bytes (class))),
10384                    NULL_TREE);
10385       saved_new = save_expr (new);
10386       c1 = build_tree_list (NULL_TREE, saved_new);
10387       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
10388       TREE_OPERAND (original_call, 1) = c1;
10389       TREE_SET_CODE (original_call, CALL_EXPR);
10390       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
10391     }
10392
10393   /* If CHECK is set, then we are building a check to see if the object
10394      is NULL.  */
10395   if (check != NULL_TREE)
10396     {
10397       patch = build (COMPOUND_EXPR, TREE_TYPE (patch), check, patch);
10398       TREE_SIDE_EFFECTS (patch) = 1;
10399     }
10400
10401   return patch;
10402 }
10403
10404 static int
10405 invocation_mode (method, super)
10406      tree method;
10407      int super;
10408 {
10409   int access = get_access_flags_from_decl (method);
10410
10411   if (super)
10412     return INVOKE_SUPER;
10413
10414   if (access & ACC_STATIC)
10415     return INVOKE_STATIC;
10416
10417   /* We have to look for a constructor before we handle nonvirtual
10418      calls; otherwise the constructor will look nonvirtual.  */
10419   if (DECL_CONSTRUCTOR_P (method))
10420     return INVOKE_STATIC;
10421
10422   if (access & ACC_FINAL || access & ACC_PRIVATE)
10423     return INVOKE_NONVIRTUAL;
10424
10425   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
10426     return INVOKE_NONVIRTUAL;
10427
10428   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
10429     return INVOKE_INTERFACE;
10430
10431   return INVOKE_VIRTUAL;
10432 }
10433
10434 /* Retrieve a refined list of matching methods. It covers the step
10435    15.11.2 (Compile-Time Step 2) */
10436
10437 static tree
10438 lookup_method_invoke (lc, cl, class, name, arg_list)
10439      int lc;
10440      tree cl;
10441      tree class, name, arg_list;
10442 {
10443   tree atl = end_params_node;           /* Arg Type List */
10444   tree method, signature, list, node;
10445   const char *candidates;               /* Used for error report */
10446   char *dup;
10447
10448   /* Fix the arguments */
10449   for (node = arg_list; node; node = TREE_CHAIN (node))
10450     {
10451       tree current_arg = TREE_TYPE (TREE_VALUE (node));
10452       /* Non primitive type may have to be resolved */
10453       if (!JPRIMITIVE_TYPE_P (current_arg))
10454         resolve_and_layout (current_arg, NULL_TREE);
10455       /* And promoted */
10456       if (TREE_CODE (current_arg) == RECORD_TYPE)
10457         current_arg = promote_type (current_arg);
10458       atl = tree_cons (NULL_TREE, current_arg, atl);
10459     }
10460
10461   /* Presto. If we're dealing with an anonymous class and a
10462      constructor call, generate the right constructor now, since we
10463      know the arguments' types. */
10464
10465   if (lc && ANONYMOUS_CLASS_P (class))
10466     craft_constructor (TYPE_NAME (class), atl);
10467
10468   /* Find all candidates and then refine the list, searching for the
10469      most specific method. */
10470   list = find_applicable_accessible_methods_list (lc, class, name, atl);
10471   list = find_most_specific_methods_list (list);
10472   if (list && !TREE_CHAIN (list))
10473     return TREE_VALUE (list);
10474
10475   /* Issue an error. List candidates if any. Candidates are listed
10476      only if accessible (non accessible methods may end-up here for
10477      the sake of a better error report). */
10478   candidates = NULL;
10479   if (list)
10480     {
10481       tree current;
10482       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
10483       for (current = list; current; current = TREE_CHAIN (current))
10484         {
10485           tree cm = TREE_VALUE (current);
10486           char string [4096];
10487           if (!cm || not_accessible_p (class, cm, NULL_TREE, 0))
10488             continue;
10489           sprintf 
10490             (string, "  `%s' in `%s'%s",
10491              get_printable_method_name (cm),
10492              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
10493              (TREE_CHAIN (current) ? "\n" : ""));
10494           obstack_grow (&temporary_obstack, string, strlen (string));
10495         }
10496       obstack_1grow (&temporary_obstack, '\0');
10497       candidates = obstack_finish (&temporary_obstack);
10498     }
10499   /* Issue the error message */
10500   method = make_node (FUNCTION_TYPE);
10501   TYPE_ARG_TYPES (method) = atl;
10502   signature = build_java_argument_signature (method);
10503   dup = xstrdup (lang_printable_name (class, 0));
10504   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
10505                        (lc ? "constructor" : "method"),
10506                        (lc ? dup : IDENTIFIER_POINTER (name)),
10507                        IDENTIFIER_POINTER (signature), dup,
10508                        (candidates ? candidates : ""));
10509   free (dup);
10510   return NULL_TREE;
10511 }
10512
10513 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
10514    when we're looking for a constructor. */
10515
10516 static tree
10517 find_applicable_accessible_methods_list (lc, class, name, arglist)
10518      int lc;
10519      tree class, name, arglist;
10520 {
10521   static struct hash_table t, *searched_classes = NULL;
10522   static int search_not_done = 0;
10523   tree list = NULL_TREE, all_list = NULL_TREE;
10524
10525   /* Check the hash table to determine if this class has been searched 
10526      already. */
10527   if (searched_classes)
10528     {
10529       if (hash_lookup (searched_classes, 
10530                       (const hash_table_key) class, FALSE, NULL))
10531        return NULL;
10532     }
10533   else
10534     {
10535       hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
10536                       java_hash_compare_tree_node);
10537       searched_classes = &t;
10538     }
10539     
10540   search_not_done++;
10541   hash_lookup (searched_classes, 
10542                (const hash_table_key) class, TRUE, NULL);
10543
10544   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
10545     {
10546       load_class (class, 1);
10547       safe_layout_class (class);
10548     }
10549
10550   /* Search interfaces */
10551   if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
10552       && CLASS_INTERFACE (TYPE_NAME (class)))
10553     {
10554       int i, n;
10555       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10556       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10557                                       name, arglist, &list, &all_list);
10558       n = TREE_VEC_LENGTH (basetype_vec);
10559       for (i = 1; i < n; i++)
10560         {
10561           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10562           tree rlist;
10563
10564           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
10565                                                            arglist);
10566           list = chainon (rlist, list);
10567         }
10568     }
10569   /* Search classes */
10570   else
10571     {
10572       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10573                                       name, arglist, &list, &all_list);
10574
10575       /* When looking finit$ or class$, we turn LC to 1 so that we
10576          only search in class. Note that we should have found
10577          something at this point. */
10578       if (ID_FINIT_P (name) || ID_CLASSDOLLAR_P (name))
10579         {
10580           lc = 1;
10581           if (!list)
10582             abort ();
10583         }
10584
10585       /* We must search all interfaces of this class */
10586       if (!lc)
10587       {
10588         tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10589         int n = TREE_VEC_LENGTH (basetype_vec), i;
10590         for (i = 1; i < n; i++)
10591           {
10592             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10593             if (t != object_type_node)
10594               {
10595                 tree rlist
10596                   = find_applicable_accessible_methods_list (lc, t,
10597                                                              name, arglist);
10598                 list = chainon (rlist, list);
10599               }
10600           }
10601       }
10602
10603       /* Search superclass */
10604       if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
10605         {
10606           tree rlist;
10607           class = CLASSTYPE_SUPER (class);
10608           rlist = find_applicable_accessible_methods_list (lc, class, 
10609                                                            name, arglist);
10610           list = chainon (rlist, list);
10611         }
10612     }
10613
10614   search_not_done--;
10615
10616   /* We're done. Reset the searched classes list and finally search
10617      java.lang.Object if it wasn't searched already. */
10618   if (!search_not_done)
10619     {
10620       if (!lc
10621           && TYPE_METHODS (object_type_node)
10622           && !hash_lookup (searched_classes, 
10623                            (const hash_table_key) object_type_node, 
10624                            FALSE, NULL))
10625         {
10626           search_applicable_methods_list (lc, 
10627                                           TYPE_METHODS (object_type_node),
10628                                           name, arglist, &list, &all_list);
10629         }
10630       hash_table_free (searched_classes);
10631       searched_classes = NULL;
10632     }
10633
10634   /* Either return the list obtained or all selected (but
10635      inaccessible) methods for better error report. */
10636   return (!list ? all_list : list);
10637 }
10638
10639 /* Effectively search for the appropriate method in method */
10640
10641 static void 
10642 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10643      int lc;
10644      tree method, name, arglist;
10645      tree *list, *all_list;
10646 {
10647   for (; method; method = TREE_CHAIN (method))
10648     {
10649       /* When dealing with constructor, stop here, otherwise search
10650          other classes */
10651       if (lc && !DECL_CONSTRUCTOR_P (method))
10652         continue;
10653       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10654                        || (DECL_NAME (method) != name)))
10655         continue;
10656
10657       if (argument_types_convertible (method, arglist))
10658         {
10659           /* Retain accessible methods only */
10660           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10661                                  method, NULL_TREE, 0))
10662             *list = tree_cons (NULL_TREE, method, *list);
10663           else
10664             /* Also retain all selected method here */
10665             *all_list = tree_cons (NULL_TREE, method, *list);
10666         }
10667     }
10668 }
10669
10670 /* 15.11.2.2 Choose the Most Specific Method */
10671
10672 static tree
10673 find_most_specific_methods_list (list)
10674      tree list;
10675 {
10676   int max = 0;
10677   int abstract, candidates;
10678   tree current, new_list = NULL_TREE;
10679   for (current = list; current; current = TREE_CHAIN (current))
10680     {
10681       tree method;
10682       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10683
10684       for (method = list; method; method = TREE_CHAIN (method))
10685         {
10686           tree method_v, current_v;
10687           /* Don't test a method against itself */
10688           if (method == current)
10689             continue;
10690
10691           method_v = TREE_VALUE (method);
10692           current_v = TREE_VALUE (current);
10693
10694           /* Compare arguments and location where methods where declared */
10695           if (argument_types_convertible (method_v, current_v))
10696             {
10697               if (valid_method_invocation_conversion_p 
10698                   (DECL_CONTEXT (method_v), DECL_CONTEXT (current_v))
10699                   || (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v))
10700                       && enclosing_context_p (DECL_CONTEXT (method_v),
10701                                               DECL_CONTEXT (current_v))))
10702                 {
10703                   int v = (DECL_SPECIFIC_COUNT (current_v) += 
10704                     (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v)) ? 2 : 1));
10705                   max = (v > max ? v : max);
10706                 }
10707             }
10708         }
10709     }
10710
10711   /* Review the list and select the maximally specific methods */
10712   for (current = list, abstract = -1, candidates = -1;
10713        current; current = TREE_CHAIN (current))
10714     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10715       {
10716         new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10717         abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
10718         candidates++;
10719       }
10720
10721   /* If we have several and they're all abstract, just pick the
10722      closest one. */
10723   if (candidates > 0 && (candidates == abstract))
10724     {
10725       new_list = nreverse (new_list);
10726       TREE_CHAIN (new_list) = NULL_TREE;
10727     }
10728
10729   /* We have several (we couldn't find a most specific), all but one
10730      are abstract, we pick the only non abstract one. */
10731   if (candidates > 0 && (candidates == abstract+1))
10732     {
10733       for (current = new_list; current; current = TREE_CHAIN (current))
10734         if (!METHOD_ABSTRACT (TREE_VALUE (current)))
10735           {
10736             TREE_CHAIN (current) = NULL_TREE;
10737             new_list = current;
10738           }
10739     }
10740
10741   /* If we can't find one, lower expectations and try to gather multiple
10742      maximally specific methods */
10743   while (!new_list && max)
10744     {
10745       while (--max > 0)
10746         {
10747           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10748             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10749         }
10750     }
10751
10752   return new_list;
10753 }
10754
10755 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10756    converted by method invocation conversion (5.3) to the type of the
10757    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10758    to change less often than M1. */
10759
10760 static int
10761 argument_types_convertible (m1, m2_or_arglist)
10762     tree m1, m2_or_arglist;
10763 {
10764   static tree m2_arg_value = NULL_TREE;
10765   static tree m2_arg_cache = NULL_TREE;
10766   static int initialized_p;
10767
10768   register tree m1_arg, m2_arg;
10769
10770   /* Register M2_ARG_VALUE and M2_ARG_CACHE with the garbage
10771      collector.  */
10772   if (!initialized_p)
10773     {
10774       ggc_add_tree_root (&m2_arg_value, 1);
10775       ggc_add_tree_root (&m2_arg_cache, 1);
10776       initialized_p = 1;
10777     }
10778
10779   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10780
10781   if (m2_arg_value == m2_or_arglist)
10782     m2_arg = m2_arg_cache;
10783   else
10784     {
10785       /* M2_OR_ARGLIST can be a function DECL or a raw list of
10786          argument types */
10787       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10788         {
10789           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10790           if (!METHOD_STATIC (m2_or_arglist))
10791             m2_arg = TREE_CHAIN (m2_arg);
10792         }
10793       else
10794         m2_arg = m2_or_arglist;
10795
10796       m2_arg_value = m2_or_arglist;
10797       m2_arg_cache = m2_arg;
10798     }
10799
10800   while (m1_arg != end_params_node && m2_arg != end_params_node)
10801     {
10802       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10803       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10804                                                  TREE_VALUE (m2_arg)))
10805         break;
10806       m1_arg = TREE_CHAIN (m1_arg);
10807       m2_arg = TREE_CHAIN (m2_arg);
10808     }
10809   return m1_arg == end_params_node && m2_arg == end_params_node;
10810 }
10811
10812 /* Qualification routines */
10813
10814 static void
10815 qualify_ambiguous_name (id)
10816      tree id;
10817 {
10818   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10819     saved_current_class;
10820   int again, super_found = 0, this_found = 0, new_array_found = 0;
10821   int code;
10822
10823   /* We first qualify the first element, then derive qualification of
10824      others based on the first one. If the first element is qualified
10825      by a resolution (field or type), this resolution is stored in the
10826      QUAL_RESOLUTION of the qual element being examined. We need to
10827      save the current_class since the use of SUPER might change the
10828      its value. */
10829   saved_current_class = current_class;
10830   qual = EXPR_WFL_QUALIFICATION (id);
10831   do {
10832
10833     /* Simple qualified expression feature a qual_wfl that is a
10834        WFL. Expression derived from a primary feature more complicated
10835        things like a CALL_EXPR. Expression from primary need to be
10836        worked out to extract the part on which the qualification will
10837        take place. */
10838     qual_wfl = QUAL_WFL (qual);
10839     switch (TREE_CODE (qual_wfl))
10840       {
10841       case CALL_EXPR:
10842         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10843         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10844           {
10845             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10846             qual_wfl = QUAL_WFL (qual);
10847           }
10848         break;
10849       case NEW_ARRAY_EXPR:
10850       case NEW_ANONYMOUS_ARRAY_EXPR:
10851         qual = TREE_CHAIN (qual);
10852         again = new_array_found = 1;
10853         continue;
10854       case CONVERT_EXPR:
10855         break;
10856       case NEW_CLASS_EXPR:
10857         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10858         break;
10859       case ARRAY_REF:
10860         while (TREE_CODE (qual_wfl) == ARRAY_REF)
10861           qual_wfl = TREE_OPERAND (qual_wfl, 0);
10862         break;
10863       case STRING_CST:
10864         qual = TREE_CHAIN (qual);
10865         qual_wfl = QUAL_WFL (qual);
10866         break;
10867       case CLASS_LITERAL:
10868         qual = TREE_CHAIN (qual);
10869         qual_wfl = QUAL_WFL (qual);
10870       break;
10871       default:
10872         /* Fix for -Wall. Just break doing nothing */
10873         break;
10874       }
10875
10876     ptr_type = current_class;
10877     again = 0;
10878     code = TREE_CODE (qual_wfl);
10879
10880     /* Pos evaluation: non WFL leading expression nodes */
10881     if (code == CONVERT_EXPR
10882         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10883       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10884
10885     else if (code == INTEGER_CST)
10886       name = qual_wfl;
10887     
10888     else if (code == CONVERT_EXPR &&
10889              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10890       name = TREE_OPERAND (qual_wfl, 0);
10891     
10892     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10893              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10894       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10895
10896     else if (code == TREE_LIST)
10897       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10898
10899     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
10900              || code == PLUS_EXPR)
10901       {
10902         qual = TREE_CHAIN (qual);
10903         qual_wfl = QUAL_WFL (qual);
10904         again = 1;
10905       }
10906     else
10907       {
10908         name = EXPR_WFL_NODE (qual_wfl);
10909         if (!name)
10910           {
10911             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10912             again = 1;
10913           }
10914       }
10915
10916     /* If we have a THIS (from a primary), we set the context accordingly */
10917     if (name == this_identifier_node)
10918       {
10919         /* This isn't really elegant. One more added irregularity
10920            before I start using COMPONENT_REF (hopefully very soon.)  */
10921         if (TREE_CODE (TREE_PURPOSE (qual)) == ARRAY_REF
10922             && TREE_CODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
10923                EXPR_WITH_FILE_LOCATION
10924             && EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) == 
10925                this_identifier_node)
10926             {
10927               qual = TREE_OPERAND (TREE_PURPOSE (qual), 0);
10928               qual = EXPR_WFL_QUALIFICATION (qual);
10929             }
10930         qual = TREE_CHAIN (qual);
10931         qual_wfl = QUAL_WFL (qual);
10932         if (TREE_CODE (qual_wfl) == CALL_EXPR)
10933           again = 1;
10934         else if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION)
10935           name = EXPR_WFL_NODE (qual_wfl);
10936         else if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
10937           name = TREE_OPERAND (qual_wfl, 0);
10938         this_found = 1;
10939       }
10940     /* If we have a SUPER, we set the context accordingly */
10941     if (name == super_identifier_node)
10942       {
10943         current_class = CLASSTYPE_SUPER (ptr_type);
10944         /* Check that there is such a thing as a super class. If not,
10945            return.  The error will be caught later on, during the
10946            resolution */
10947         if (!current_class)
10948           {
10949             current_class = saved_current_class;
10950             return;
10951           }
10952         qual = TREE_CHAIN (qual);
10953         /* Do one more interation to set things up */
10954         super_found = again = 1;
10955       }
10956   } while (again);
10957   
10958   /* If name appears within the scope of a local variable declaration
10959      or parameter declaration, then it is an expression name. We don't
10960      carry this test out if we're in the context of the use of SUPER
10961      or THIS */
10962   if (!this_found && !super_found 
10963       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10964       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10965     {
10966       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10967       QUAL_RESOLUTION (qual) = decl;
10968     }
10969
10970   /* If within the class/interface NAME was found to be used there
10971      exists a (possibly inherited) field named NAME, then this is an
10972      expression name. If we saw a NEW_ARRAY_EXPR before and want to
10973      address length, it is OK. */
10974   else if ((decl = lookup_field_wrapper (ptr_type, name))
10975            || name == length_identifier_node)
10976     {
10977       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10978       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10979     }
10980
10981   /* We reclassify NAME as yielding to a type name resolution if:
10982      - NAME is a class/interface declared within the compilation
10983        unit containing NAME,
10984      - NAME is imported via a single-type-import declaration,
10985      - NAME is declared in an another compilation unit of the package
10986        of the compilation unit containing NAME,
10987      - NAME is declared by exactly on type-import-on-demand declaration
10988      of the compilation unit containing NAME. 
10989      - NAME is actually a STRING_CST. */
10990   else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10991            || (decl = resolve_and_layout (name, NULL_TREE)))
10992     {
10993       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10994       QUAL_RESOLUTION (qual) = decl;
10995     }
10996
10997   /* Method call, array references and cast are expression name */
10998   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10999            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
11000            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR
11001            || TREE_CODE (QUAL_WFL (qual)) == MODIFY_EXPR)
11002     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11003
11004   /* Check here that NAME isn't declared by more than one
11005      type-import-on-demand declaration of the compilation unit
11006      containing NAME. FIXME */
11007
11008   /* Otherwise, NAME is reclassified as a package name */
11009   else 
11010     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
11011
11012   /* Propagate the qualification accross other components of the
11013      qualified name */
11014   for (qual = TREE_CHAIN (qual); qual;
11015        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
11016     {
11017       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
11018         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
11019       else 
11020         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
11021     }
11022
11023   /* Store the global qualification for the ambiguous part of ID back
11024      into ID fields */
11025   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
11026     RESOLVE_EXPRESSION_NAME_P (id) = 1;
11027   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
11028     RESOLVE_TYPE_NAME_P (id) = 1;
11029   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
11030     RESOLVE_PACKAGE_NAME_P (id) = 1;
11031
11032   /* Restore the current class */
11033   current_class = saved_current_class;
11034 }
11035
11036 static int
11037 breakdown_qualified (left, right, source)
11038     tree *left, *right, source;
11039 {
11040   char *p, *base;
11041   int   l = IDENTIFIER_LENGTH (source);
11042
11043   base = alloca (l + 1);
11044   memcpy (base, IDENTIFIER_POINTER (source), l + 1);
11045
11046   /* Breakdown NAME into REMAINDER . IDENTIFIER */
11047   p = base + l - 1;
11048   while (*p != '.' && p != base)
11049     p--;
11050
11051   /* We didn't find a '.'. Return an error */
11052   if (p == base)
11053     return 1;
11054
11055   *p = '\0';
11056   if (right)
11057     *right = get_identifier (p+1);
11058   *left = get_identifier (base);
11059   
11060   return 0;
11061 }
11062
11063 /* Return TRUE if two classes are from the same package. */
11064
11065 static int
11066 in_same_package (name1, name2)
11067   tree name1, name2;
11068 {
11069   tree tmp;
11070   tree pkg1;
11071   tree pkg2;
11072   
11073   if (TREE_CODE (name1) == TYPE_DECL)
11074     name1 = DECL_NAME (name1);
11075   if (TREE_CODE (name2) == TYPE_DECL)
11076     name2 = DECL_NAME (name2);
11077
11078   if (QUALIFIED_P (name1) != QUALIFIED_P (name2))
11079     /* One in empty package. */
11080     return 0;
11081
11082   if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0)
11083     /* Both in empty package. */
11084     return 1;
11085
11086   breakdown_qualified (&pkg1, &tmp, name1);
11087   breakdown_qualified (&pkg2, &tmp, name2);
11088   
11089   return (pkg1 == pkg2);
11090 }
11091
11092 /* Patch tree nodes in a function body. When a BLOCK is found, push
11093    local variable decls if present.
11094    Same as java_complete_lhs, but does resolve static finals to values. */
11095
11096 static tree
11097 java_complete_tree (node)
11098      tree node;
11099 {
11100   node = java_complete_lhs (node);
11101   if (JDECL_P (node) && CLASS_FINAL_VARIABLE_P (node)
11102       && DECL_INITIAL (node) != NULL_TREE
11103       && !flag_emit_xref)
11104     {
11105       tree value = DECL_INITIAL (node);
11106       DECL_INITIAL (node) = NULL_TREE;
11107       value = fold_constant_for_init (value, node);
11108       DECL_INITIAL (node) = value;
11109       if (value != NULL_TREE)
11110         {
11111           /* fold_constant_for_init sometimes widen the original type
11112              of the constant (i.e. byte to int.) It's not desirable,
11113              especially if NODE is a function argument. */
11114           if (TREE_CODE (value) == INTEGER_CST
11115               && TREE_TYPE (node) != TREE_TYPE (value))
11116             return convert (TREE_TYPE (node), value);
11117           else
11118             return value;
11119         }
11120       else
11121         DECL_FIELD_FINAL_IUD (node) = 0;
11122     }
11123   return node;
11124 }
11125
11126 static tree
11127 java_stabilize_reference (node)
11128      tree node;
11129 {
11130   if (TREE_CODE (node) == COMPOUND_EXPR)
11131     {
11132       tree op0 = TREE_OPERAND (node, 0);
11133       tree op1 = TREE_OPERAND (node, 1);
11134       TREE_OPERAND (node, 0) = save_expr (op0);
11135       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
11136       return node;
11137     }
11138   return stabilize_reference (node);
11139 }
11140
11141 /* Patch tree nodes in a function body. When a BLOCK is found, push
11142    local variable decls if present.
11143    Same as java_complete_tree, but does not resolve static finals to values. */
11144
11145 static tree
11146 java_complete_lhs (node)
11147      tree node;
11148 {
11149   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
11150   int flag;
11151
11152   /* CONVERT_EXPR always has its type set, even though it needs to be
11153      worked out. */
11154   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
11155     return node;
11156
11157   /* The switch block implements cases processing container nodes
11158      first.  Contained nodes are always written back. Leaves come
11159      next and return a value. */
11160   switch (TREE_CODE (node))
11161     {
11162     case BLOCK:
11163
11164       /* 1- Block section.
11165          Set the local values on decl names so we can identify them
11166          faster when they're referenced. At that stage, identifiers
11167          are legal so we don't check for declaration errors. */
11168       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11169         {
11170           DECL_CONTEXT (cn) = current_function_decl;
11171           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
11172         }
11173       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
11174           CAN_COMPLETE_NORMALLY (node) = 1;
11175       else
11176         {
11177           tree stmt = BLOCK_EXPR_BODY (node);
11178           tree *ptr;
11179           int error_seen = 0;
11180           if (TREE_CODE (stmt) == COMPOUND_EXPR)
11181             {
11182               /* Re-order from (((A; B); C); ...; Z) to 
11183                  (A; (B; (C ; (...; Z)))).
11184                  This makes it easier to scan the statements left-to-right
11185                  without using recursion (which might overflow the stack
11186                  if the block has many statements. */
11187               for (;;)
11188                 {
11189                   tree left = TREE_OPERAND (stmt, 0);
11190                   if (TREE_CODE (left) != COMPOUND_EXPR)
11191                     break;
11192                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
11193                   TREE_OPERAND (left, 1) = stmt;
11194                   stmt = left;
11195                 }
11196               BLOCK_EXPR_BODY (node) = stmt;
11197             }
11198
11199           /* Now do the actual complete, without deep recursion for
11200              long blocks. */
11201           ptr = &BLOCK_EXPR_BODY (node);
11202           while (TREE_CODE (*ptr) == COMPOUND_EXPR
11203                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
11204             {
11205               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
11206               tree *next = &TREE_OPERAND (*ptr, 1);
11207               TREE_OPERAND (*ptr, 0) = cur;
11208               if (cur == empty_stmt_node)
11209                 {
11210                   /* Optimization;  makes it easier to detect empty bodies.
11211                      Most useful for <clinit> with all-constant initializer. */
11212                   *ptr = *next;
11213                   continue;
11214                 }
11215               if (TREE_CODE (cur) == ERROR_MARK)
11216                 error_seen++;
11217               else if (! CAN_COMPLETE_NORMALLY (cur))
11218                 {
11219                   wfl_op2 = *next;
11220                   for (;;)
11221                     {
11222                       if (TREE_CODE (wfl_op2) == BLOCK)
11223                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
11224                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
11225                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
11226                       else
11227                         break;
11228                     }
11229                   if (TREE_CODE (wfl_op2) != CASE_EXPR
11230                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
11231                     unreachable_stmt_error (*ptr);
11232                 }
11233               ptr = next;
11234             }
11235           *ptr = java_complete_tree (*ptr);
11236
11237           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
11238             return error_mark_node;
11239           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
11240         }
11241       /* Turn local bindings to null */
11242       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11243         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
11244
11245       TREE_TYPE (node) = void_type_node;
11246       break;
11247
11248       /* 2- They are expressions but ultimately deal with statements */
11249
11250     case THROW_EXPR:
11251       wfl_op1 = TREE_OPERAND (node, 0);
11252       COMPLETE_CHECK_OP_0 (node);
11253       /* 14.19 A throw statement cannot complete normally. */
11254       CAN_COMPLETE_NORMALLY (node) = 0;
11255       return patch_throw_statement (node, wfl_op1);
11256
11257     case SYNCHRONIZED_EXPR:
11258       wfl_op1 = TREE_OPERAND (node, 0);
11259       return patch_synchronized_statement (node, wfl_op1);
11260
11261     case TRY_EXPR:
11262       return patch_try_statement (node);
11263
11264     case TRY_FINALLY_EXPR:
11265       COMPLETE_CHECK_OP_0 (node);
11266       COMPLETE_CHECK_OP_1 (node);
11267       if (TREE_OPERAND (node, 0) == empty_stmt_node)
11268         return TREE_OPERAND (node, 1);
11269       if (TREE_OPERAND (node, 1) == empty_stmt_node)
11270         return TREE_OPERAND (node, 0);
11271       CAN_COMPLETE_NORMALLY (node)
11272         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
11273            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
11274       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
11275       return node;
11276
11277     case CLEANUP_POINT_EXPR:
11278       COMPLETE_CHECK_OP_0 (node);
11279       TREE_TYPE (node) = void_type_node;
11280       CAN_COMPLETE_NORMALLY (node) = 
11281         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
11282       return node;
11283
11284     case WITH_CLEANUP_EXPR:
11285       COMPLETE_CHECK_OP_0 (node);
11286       COMPLETE_CHECK_OP_2 (node);
11287       CAN_COMPLETE_NORMALLY (node) = 
11288         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
11289       TREE_TYPE (node) = void_type_node;
11290       return node;
11291
11292     case LABELED_BLOCK_EXPR:
11293       PUSH_LABELED_BLOCK (node);
11294       if (LABELED_BLOCK_BODY (node))
11295         COMPLETE_CHECK_OP_1 (node);
11296       TREE_TYPE (node) = void_type_node;
11297       POP_LABELED_BLOCK ();
11298
11299       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
11300         {
11301           LABELED_BLOCK_BODY (node) = NULL_TREE;
11302           CAN_COMPLETE_NORMALLY (node) = 1;
11303         }
11304       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
11305         CAN_COMPLETE_NORMALLY (node) = 1;
11306       return node;
11307
11308     case EXIT_BLOCK_EXPR:
11309       /* We don't complete operand 1, because it's the return value of
11310          the EXIT_BLOCK_EXPR which doesn't exist it Java */
11311       return patch_bc_statement (node);
11312
11313     case CASE_EXPR:
11314       cn = java_complete_tree (TREE_OPERAND (node, 0));
11315       if (cn == error_mark_node)
11316         return cn;
11317
11318       /* First, the case expression must be constant. Values of final
11319          fields are accepted. */
11320       cn = fold (cn);
11321       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
11322           && JDECL_P (TREE_OPERAND (cn, 1))
11323           && FIELD_FINAL (TREE_OPERAND (cn, 1))
11324           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
11325         {
11326           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
11327                                        TREE_OPERAND (cn, 1));
11328         }
11329
11330       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
11331         {
11332           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11333           parse_error_context (node, "Constant expression required");
11334           return error_mark_node;
11335         }
11336
11337       nn = ctxp->current_loop;
11338
11339       /* It must be assignable to the type of the switch expression. */
11340       if (!try_builtin_assignconv (NULL_TREE, 
11341                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
11342         {
11343           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11344           parse_error_context 
11345             (wfl_operator,
11346              "Incompatible type for case. Can't convert `%s' to `int'",
11347              lang_printable_name (TREE_TYPE (cn), 0));
11348           return error_mark_node;
11349         }
11350
11351       cn = fold (convert (int_type_node, cn));
11352
11353       /* Multiple instance of a case label bearing the same
11354          value is checked during code generation. The case
11355          expression is allright so far. */
11356       if (TREE_CODE (cn) == VAR_DECL)
11357         cn = DECL_INITIAL (cn);
11358       TREE_OPERAND (node, 0) = cn;
11359       TREE_TYPE (node) = void_type_node;
11360       CAN_COMPLETE_NORMALLY (node) = 1;
11361       TREE_SIDE_EFFECTS (node) = 1;
11362       break;
11363
11364     case DEFAULT_EXPR:
11365       nn = ctxp->current_loop;
11366       /* Only one default label is allowed per switch statement */
11367       if (SWITCH_HAS_DEFAULT (nn))
11368         {
11369           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11370           parse_error_context (wfl_operator, 
11371                                "Duplicate case label: `default'");
11372           return error_mark_node;
11373         }
11374       else
11375         SWITCH_HAS_DEFAULT (nn) = 1;
11376       TREE_TYPE (node) = void_type_node;
11377       TREE_SIDE_EFFECTS (node) = 1;
11378       CAN_COMPLETE_NORMALLY (node) = 1;
11379       break;
11380
11381     case SWITCH_EXPR:
11382     case LOOP_EXPR:
11383       PUSH_LOOP (node);
11384       /* Check whether the loop was enclosed in a labeled
11385          statement. If not, create one, insert the loop in it and
11386          return the node */
11387       nn = patch_loop_statement (node);
11388
11389       /* Anyways, walk the body of the loop */
11390       if (TREE_CODE (node) == LOOP_EXPR)
11391         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11392       /* Switch statement: walk the switch expression and the cases */
11393       else
11394         node = patch_switch_statement (node);
11395
11396       if (node == error_mark_node || TREE_OPERAND (node, 0) == error_mark_node)
11397         nn = error_mark_node;
11398       else
11399         {
11400           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
11401           /* If we returned something different, that's because we
11402              inserted a label. Pop the label too. */
11403           if (nn != node)
11404             {
11405               if (CAN_COMPLETE_NORMALLY (node))
11406                 CAN_COMPLETE_NORMALLY (nn) = 1;
11407               POP_LABELED_BLOCK ();
11408             }
11409         }
11410       POP_LOOP ();
11411       return nn;
11412
11413     case EXIT_EXPR:
11414       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11415       return patch_exit_expr (node);
11416
11417     case COND_EXPR:
11418       /* Condition */
11419       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11420       if (TREE_OPERAND (node, 0) == error_mark_node)
11421         return error_mark_node;
11422       /* then-else branches */
11423       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11424       if (TREE_OPERAND (node, 1) == error_mark_node)
11425         return error_mark_node;
11426       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
11427       if (TREE_OPERAND (node, 2) == error_mark_node)
11428         return error_mark_node;
11429       return patch_if_else_statement (node);
11430       break;
11431
11432     case CONDITIONAL_EXPR:
11433       /* Condition */
11434       wfl_op1 = TREE_OPERAND (node, 0);
11435       COMPLETE_CHECK_OP_0 (node);
11436       wfl_op2 = TREE_OPERAND (node, 1);
11437       COMPLETE_CHECK_OP_1 (node);
11438       wfl_op3 = TREE_OPERAND (node, 2);
11439       COMPLETE_CHECK_OP_2 (node);
11440       return patch_conditional_expr (node, wfl_op1, wfl_op2);
11441
11442       /* 3- Expression section */
11443     case COMPOUND_EXPR:
11444       wfl_op2 = TREE_OPERAND (node, 1);
11445       TREE_OPERAND (node, 0) = nn = 
11446         java_complete_tree (TREE_OPERAND (node, 0));
11447       if (wfl_op2 == empty_stmt_node)
11448         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
11449       else
11450         {
11451           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
11452             {
11453               /* An unreachable condition in a do-while statement
11454                  is *not* (technically) an unreachable statement. */
11455               nn = wfl_op2;
11456               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
11457                 nn = EXPR_WFL_NODE (nn);
11458               if (TREE_CODE (nn) != EXIT_EXPR)
11459                 {
11460                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
11461                   parse_error_context (wfl_operator, "Unreachable statement");
11462                 }
11463             }
11464           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11465           if (TREE_OPERAND (node, 1) == error_mark_node)
11466             return error_mark_node;
11467           CAN_COMPLETE_NORMALLY (node)
11468             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
11469         }
11470       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
11471       break;
11472
11473     case RETURN_EXPR:
11474       /* CAN_COMPLETE_NORMALLY (node) = 0; */
11475       return patch_return (node);
11476
11477     case EXPR_WITH_FILE_LOCATION:
11478       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11479           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11480         {
11481           tree wfl = node;
11482           node = resolve_expression_name (node, NULL);
11483           if (node == error_mark_node)
11484             return node;
11485           /* Keep line number information somewhere were it doesn't
11486              disrupt the completion process. */
11487           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
11488             {
11489               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
11490               TREE_OPERAND (node, 1) = wfl;
11491             }
11492           CAN_COMPLETE_NORMALLY (node) = 1;
11493         }
11494       else
11495         {
11496           tree body;
11497           int save_lineno = lineno;
11498           lineno = EXPR_WFL_LINENO (node);
11499           body = java_complete_tree (EXPR_WFL_NODE (node));
11500           lineno = save_lineno;
11501           EXPR_WFL_NODE (node) = body;
11502           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
11503           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
11504           if (body == empty_stmt_node || TREE_CONSTANT (body))
11505             {
11506               /* Makes it easier to constant fold, detect empty bodies. */
11507               return body;
11508             }
11509           if (body == error_mark_node)
11510             {
11511               /* Its important for the evaluation of assignment that
11512                  this mark on the TREE_TYPE is propagated. */
11513               TREE_TYPE (node) = error_mark_node;
11514               return error_mark_node;
11515             }
11516           else
11517             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
11518           
11519         }
11520       break;
11521
11522     case NEW_ARRAY_EXPR:
11523       /* Patch all the dimensions */
11524       flag = 0;
11525       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11526         {
11527           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
11528           tree dim = convert (int_type_node, 
11529                               java_complete_tree (TREE_VALUE (cn)));
11530           if (dim == error_mark_node)
11531             {
11532               flag = 1;
11533               continue;
11534             }
11535           else
11536             {
11537               TREE_VALUE (cn) = dim;
11538               /* Setup the location of the current dimension, for
11539                  later error report. */
11540               TREE_PURPOSE (cn) = 
11541                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
11542               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
11543             }
11544         }
11545       /* They complete the array creation expression, if no errors
11546          were found. */
11547       CAN_COMPLETE_NORMALLY (node) = 1;
11548       return (flag ? error_mark_node
11549               : force_evaluation_order (patch_newarray (node)));
11550
11551     case NEW_ANONYMOUS_ARRAY_EXPR:
11552       /* Create the array type if necessary. */
11553       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
11554         {
11555           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
11556           if (!(type = resolve_type_during_patch (type)))
11557             return error_mark_node;
11558           type = build_array_from_name (type, NULL_TREE,
11559                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
11560           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
11561         }
11562       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
11563                                    ANONYMOUS_ARRAY_INITIALIZER (node));
11564       if (node == error_mark_node)
11565         return error_mark_node;
11566       CAN_COMPLETE_NORMALLY (node) = 1;
11567       return node;
11568
11569     case NEW_CLASS_EXPR:
11570     case CALL_EXPR:
11571       /* Complete function's argument(s) first */
11572       if (complete_function_arguments (node))
11573         return error_mark_node;
11574       else
11575         {
11576           tree decl, wfl = TREE_OPERAND (node, 0);
11577           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
11578           int from_super = (EXPR_WFL_NODE (TREE_OPERAND (node, 0)) ==
11579                            super_identifier_node);
11580
11581           node = patch_method_invocation (node, NULL_TREE, NULL_TREE,
11582                                           from_super, 0, &decl);
11583           if (node == error_mark_node)
11584             return error_mark_node;
11585
11586           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
11587           /* If we call this(...), register signature and positions */
11588           if (in_this)
11589             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
11590               tree_cons (wfl, decl, 
11591                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
11592           CAN_COMPLETE_NORMALLY (node) = 1;
11593           return force_evaluation_order (node);
11594         }
11595
11596     case MODIFY_EXPR:
11597       /* Save potential wfls */
11598       wfl_op1 = TREE_OPERAND (node, 0);
11599       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
11600       
11601       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
11602           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
11603           && DECL_INITIAL (nn) != NULL_TREE)
11604         {
11605           tree value;
11606           
11607           value = fold_constant_for_init (nn, nn);
11608
11609           if (value != NULL_TREE)
11610             {
11611               tree type = TREE_TYPE (value);
11612               if (JPRIMITIVE_TYPE_P (type) || 
11613                   (type == string_ptr_type_node && ! flag_emit_class_files))
11614                 return empty_stmt_node;
11615             }
11616           if (! flag_emit_class_files)
11617             DECL_INITIAL (nn) = NULL_TREE;
11618           if (CLASS_FINAL_VARIABLE_P (nn))
11619             DECL_FIELD_FINAL_IUD (nn) = 0;
11620         }
11621       wfl_op2 = TREE_OPERAND (node, 1);
11622
11623       if (TREE_OPERAND (node, 0) == error_mark_node)
11624         return error_mark_node;
11625
11626       flag = COMPOUND_ASSIGN_P (wfl_op2);
11627       if (flag)
11628         {
11629           /* This might break when accessing outer field from inner
11630              class. TESTME, FIXME */
11631           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
11632
11633           /* Hand stabilize the lhs on both places */
11634           TREE_OPERAND (node, 0) = lvalue;
11635           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
11636             (flag_emit_class_files ? lvalue : save_expr (lvalue));
11637
11638           /* 15.25.2.a: Left hand is not an array access. FIXME */
11639           /* Now complete the RHS. We write it back later on. */
11640           nn = java_complete_tree (TREE_OPERAND (node, 1));
11641
11642           if ((cn = patch_string (nn)))
11643             nn = cn;
11644
11645           /* The last part of the rewrite for E1 op= E2 is to have 
11646              E1 = (T)(E1 op E2), with T being the type of E1. */
11647           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
11648                                                TREE_TYPE (lvalue), nn));
11649
11650           /* If the assignment is compound and has reference type,
11651              then ensure the LHS has type String and nothing else.  */
11652           if (JREFERENCE_TYPE_P (TREE_TYPE (lvalue))
11653               && ! JSTRING_TYPE_P (TREE_TYPE (lvalue)))
11654             parse_error_context (wfl_op2,
11655                                  "Incompatible type for `+='. Can't convert `%s' to `java.lang.String'",
11656                                  lang_printable_name (TREE_TYPE (lvalue), 0));
11657
11658           /* 15.25.2.b: Left hand is an array access. FIXME */
11659         }
11660
11661       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
11662          function to complete this RHS. Note that a NEW_ARRAY_INIT
11663          might have been already fully expanded if created as a result
11664          of processing an anonymous array initializer. We avoid doing
11665          the operation twice by testing whether the node already bears
11666          a type. */
11667       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
11668         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
11669                                    TREE_OPERAND (node, 1));
11670       /* Otherwise we simply complete the RHS */
11671       else
11672         nn = java_complete_tree (TREE_OPERAND (node, 1));
11673
11674       if (nn == error_mark_node)
11675         return error_mark_node;
11676
11677       /* Write back the RHS as we evaluated it. */
11678       TREE_OPERAND (node, 1) = nn;
11679
11680       /* In case we're handling = with a String as a RHS, we need to
11681          produce a String out of the RHS (it might still be a
11682          STRING_CST or a StringBuffer at this stage */
11683       if ((nn = patch_string (TREE_OPERAND (node, 1))))
11684         TREE_OPERAND (node, 1) = nn;
11685
11686       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
11687                                         TREE_OPERAND (node, 1))))
11688         {
11689           /* We return error_mark_node if outer_field_access_fix
11690              detects we write into a final. */
11691           if (nn == error_mark_node)
11692             return error_mark_node;
11693           node = nn;
11694         }
11695       else
11696         {
11697           node = patch_assignment (node, wfl_op1, wfl_op2);
11698           /* Reorganize the tree if necessary. */
11699           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
11700                        || JSTRING_P (TREE_TYPE (node))))
11701             node = java_refold (node);
11702         }
11703       
11704       CAN_COMPLETE_NORMALLY (node) = 1;
11705       return node;
11706
11707     case MULT_EXPR:
11708     case PLUS_EXPR:
11709     case MINUS_EXPR:
11710     case LSHIFT_EXPR:
11711     case RSHIFT_EXPR:
11712     case URSHIFT_EXPR:
11713     case BIT_AND_EXPR:
11714     case BIT_XOR_EXPR:
11715     case BIT_IOR_EXPR:
11716     case TRUNC_MOD_EXPR:
11717     case TRUNC_DIV_EXPR:
11718     case RDIV_EXPR:
11719     case TRUTH_ANDIF_EXPR:
11720     case TRUTH_ORIF_EXPR:
11721     case EQ_EXPR: 
11722     case NE_EXPR:
11723     case GT_EXPR:
11724     case GE_EXPR:
11725     case LT_EXPR:
11726     case LE_EXPR:
11727       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
11728          knows how to handle those cases. */
11729       wfl_op1 = TREE_OPERAND (node, 0);
11730       wfl_op2 = TREE_OPERAND (node, 1);
11731
11732       CAN_COMPLETE_NORMALLY (node) = 1;
11733       /* Don't complete string nodes if dealing with the PLUS operand. */
11734       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11735         {
11736           nn = java_complete_tree (wfl_op1);
11737           if (nn == error_mark_node)
11738             return error_mark_node;
11739
11740           TREE_OPERAND (node, 0) = nn;
11741         }
11742       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11743         {
11744           nn = java_complete_tree (wfl_op2);
11745           if (nn == error_mark_node)
11746             return error_mark_node;
11747
11748           TREE_OPERAND (node, 1) = nn;
11749         }
11750       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11751
11752     case INSTANCEOF_EXPR:
11753       wfl_op1 = TREE_OPERAND (node, 0);
11754       COMPLETE_CHECK_OP_0 (node);
11755       if (flag_emit_xref)
11756         {
11757           TREE_TYPE (node) = boolean_type_node;
11758           return node;
11759         }
11760       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11761
11762     case UNARY_PLUS_EXPR:
11763     case NEGATE_EXPR:
11764     case TRUTH_NOT_EXPR:
11765     case BIT_NOT_EXPR:
11766     case PREDECREMENT_EXPR:
11767     case PREINCREMENT_EXPR:
11768     case POSTDECREMENT_EXPR:
11769     case POSTINCREMENT_EXPR:
11770     case CONVERT_EXPR:
11771       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11772          how to handle those cases. */
11773       wfl_op1 = TREE_OPERAND (node, 0);
11774       CAN_COMPLETE_NORMALLY (node) = 1;
11775       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11776       if (TREE_OPERAND (node, 0) == error_mark_node)
11777         return error_mark_node;
11778       node = patch_unaryop (node, wfl_op1);
11779       CAN_COMPLETE_NORMALLY (node) = 1;
11780       break;
11781
11782     case ARRAY_REF:
11783       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11784          how to handle those cases. */
11785       wfl_op1 = TREE_OPERAND (node, 0);
11786       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11787       if (TREE_OPERAND (node, 0) == error_mark_node)
11788         return error_mark_node;
11789       if (!flag_emit_class_files && !flag_emit_xref)
11790         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11791       /* The same applies to wfl_op2 */
11792       wfl_op2 = TREE_OPERAND (node, 1);
11793       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11794       if (TREE_OPERAND (node, 1) == error_mark_node)
11795         return error_mark_node;
11796       if (!flag_emit_class_files && !flag_emit_xref)
11797         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11798       return patch_array_ref (node);
11799
11800     case RECORD_TYPE:
11801       return node;;
11802
11803     case COMPONENT_REF:
11804       /* The first step in the re-write of qualified name handling.  FIXME.
11805          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11806       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11807       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11808         {
11809           tree name = TREE_OPERAND (node, 1);
11810           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11811           if (field == NULL_TREE)
11812             {
11813               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11814               return error_mark_node;
11815             }
11816           if (! FIELD_STATIC (field))
11817             {
11818               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11819               return error_mark_node;
11820             }
11821           return field;
11822         }
11823       else
11824         abort ();
11825       break;
11826
11827     case THIS_EXPR:
11828       /* Can't use THIS in a static environment */
11829       if (!current_this)
11830         {
11831           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11832           parse_error_context (wfl_operator,
11833                                "Keyword `this' used outside allowed context");
11834           TREE_TYPE (node) = error_mark_node;
11835           return error_mark_node;
11836         }
11837       if (ctxp->explicit_constructor_p)
11838         {
11839           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11840           parse_error_context 
11841             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11842           TREE_TYPE (node) = error_mark_node;
11843           return error_mark_node;
11844         }
11845       return current_this;
11846       
11847     case CLASS_LITERAL:
11848       CAN_COMPLETE_NORMALLY (node) = 1;
11849       node = patch_incomplete_class_ref (node);
11850       if (node == error_mark_node)
11851         return error_mark_node;
11852       break;
11853
11854     case INSTANCE_INITIALIZERS_EXPR:
11855       in_instance_initializer++;
11856       node = java_complete_tree (TREE_OPERAND (node, 0));
11857       in_instance_initializer--;
11858       if (node != error_mark_node)
11859         TREE_TYPE (node) = void_type_node;
11860       else
11861         return error_mark_node;
11862       break;
11863
11864     default:
11865       CAN_COMPLETE_NORMALLY (node) = 1;
11866       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11867          and it's time to turn it into the appropriate String object */
11868       if ((nn = patch_string (node)))
11869         node = nn;
11870       else
11871         internal_error ("No case for %s", tree_code_name [TREE_CODE (node)]);
11872     }
11873   return node;
11874 }
11875
11876 /* Complete function call's argument. Return a non zero value is an
11877    error was found.  */
11878
11879 static int
11880 complete_function_arguments (node)
11881      tree node;
11882 {
11883   int flag = 0;
11884   tree cn;
11885
11886   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11887   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11888     {
11889       tree wfl = TREE_VALUE (cn), parm, temp;
11890       parm = java_complete_tree (wfl);
11891
11892       if (parm == error_mark_node)
11893         {
11894           flag = 1;
11895           continue;
11896         }
11897       /* If have a string literal that we haven't transformed yet or a
11898          crafted string buffer, as a result of use of the the String
11899          `+' operator. Build `parm.toString()' and expand it. */
11900       if ((temp = patch_string (parm)))
11901         parm = temp;
11902       /* Inline PRIMTYPE.TYPE read access */
11903       parm = maybe_build_primttype_type_ref (parm, wfl);
11904
11905       TREE_VALUE (cn) = parm;
11906     }
11907   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11908   return flag;
11909 }
11910
11911 /* Sometimes (for loops and variable initialized during their
11912    declaration), we want to wrap a statement around a WFL and turn it
11913    debugable.  */
11914
11915 static tree
11916 build_debugable_stmt (location, stmt)
11917     int location;
11918     tree stmt;
11919 {
11920   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11921     {
11922       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11923       EXPR_WFL_LINECOL (stmt) = location;
11924     }
11925   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11926   return stmt;
11927 }
11928
11929 static tree
11930 build_expr_block (body, decls)
11931      tree body, decls;
11932 {
11933   tree node = make_node (BLOCK);
11934   BLOCK_EXPR_DECLS (node) = decls;
11935   BLOCK_EXPR_BODY (node) = body;
11936   if (body)
11937     TREE_TYPE (node) = TREE_TYPE (body);
11938   TREE_SIDE_EFFECTS (node) = 1;
11939   return node;
11940 }
11941
11942 /* Create a new function block and link it approriately to current
11943    function block chain */
11944
11945 static tree
11946 enter_block ()
11947 {
11948   tree b = build_expr_block (NULL_TREE, NULL_TREE);
11949
11950   /* Link block B supercontext to the previous block. The current
11951      function DECL is used as supercontext when enter_a_block is called
11952      for the first time for a given function. The current function body
11953      (DECL_FUNCTION_BODY) is set to be block B.  */
11954
11955   tree fndecl = current_function_decl; 
11956
11957   if (!fndecl) {
11958     BLOCK_SUPERCONTEXT (b) = current_static_block;
11959     current_static_block = b;
11960   }
11961
11962   else if (!DECL_FUNCTION_BODY (fndecl))
11963     {
11964       BLOCK_SUPERCONTEXT (b) = fndecl;
11965       DECL_FUNCTION_BODY (fndecl) = b;
11966     }
11967   else
11968     {
11969       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11970       DECL_FUNCTION_BODY (fndecl) = b;
11971     }
11972   return b;
11973 }
11974
11975 /* Exit a block by changing the current function body
11976    (DECL_FUNCTION_BODY) to the current block super context, only if
11977    the block being exited isn't the method's top level one.  */
11978
11979 static tree
11980 exit_block ()
11981 {
11982   tree b;
11983   if (current_function_decl)
11984     {
11985       b = DECL_FUNCTION_BODY (current_function_decl);
11986       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11987         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11988     }
11989   else
11990     {
11991       b = current_static_block;
11992
11993       if (BLOCK_SUPERCONTEXT (b))
11994         current_static_block = BLOCK_SUPERCONTEXT (b);
11995     }
11996   return b;
11997 }
11998
11999 /* Lookup for NAME in the nested function's blocks, all the way up to
12000    the current toplevel one. It complies with Java's local variable
12001    scoping rules.  */
12002
12003 static tree
12004 lookup_name_in_blocks (name)
12005      tree name;
12006 {
12007   tree b = GET_CURRENT_BLOCK (current_function_decl);
12008
12009   while (b != current_function_decl)
12010     {
12011       tree current;
12012
12013       /* Paranoid sanity check. To be removed */
12014       if (TREE_CODE (b) != BLOCK)
12015         abort ();
12016
12017       for (current = BLOCK_EXPR_DECLS (b); current; 
12018            current = TREE_CHAIN (current))
12019         if (DECL_NAME (current) == name)
12020           return current;
12021       b = BLOCK_SUPERCONTEXT (b);
12022     }
12023   return NULL_TREE;
12024 }
12025
12026 static void
12027 maybe_absorb_scoping_blocks ()
12028 {
12029   while (BLOCK_IS_IMPLICIT (GET_CURRENT_BLOCK (current_function_decl)))
12030     {
12031       tree b = exit_block ();
12032       java_method_add_stmt (current_function_decl, b);
12033       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
12034     }
12035 }
12036
12037 \f
12038 /* This section of the source is reserved to build_* functions that
12039    are building incomplete tree nodes and the patch_* functions that
12040    are completing them.  */
12041
12042 /* Wrap a non WFL node around a WFL.  */
12043
12044 static tree
12045 build_wfl_wrap (node, location)
12046     tree node;
12047     int location;
12048 {
12049   tree wfl, node_to_insert = node;
12050   
12051   /* We want to process THIS . xxx symbolicaly, to keep it consistent
12052      with the way we're processing SUPER. A THIS from a primary as a
12053      different form than a SUPER. Turn THIS into something symbolic */
12054   if (TREE_CODE (node) == THIS_EXPR)
12055     node_to_insert = wfl = build_wfl_node (this_identifier_node);
12056   else
12057     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
12058
12059   EXPR_WFL_LINECOL (wfl) = location;
12060   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
12061   return wfl;
12062 }
12063
12064 /* Build a super() constructor invocation. Returns empty_stmt_node if
12065    we're currently dealing with the class java.lang.Object. */
12066
12067 static tree
12068 build_super_invocation (mdecl)
12069      tree mdecl;
12070 {
12071   if (DECL_CONTEXT (mdecl) == object_type_node)
12072     return empty_stmt_node;
12073   else
12074     {
12075       tree super_wfl = build_wfl_node (super_identifier_node);
12076       tree a = NULL_TREE, t;
12077       /* If we're dealing with an anonymous class, pass the arguments
12078          of the crafted constructor along. */
12079       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
12080         {
12081           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
12082           for (; t != end_params_node; t = TREE_CHAIN (t))
12083             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
12084         }
12085       return build_method_invocation (super_wfl, a);
12086     }
12087 }
12088
12089 /* Build a SUPER/THIS qualified method invocation.  */
12090
12091 static tree
12092 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
12093      int use_this;
12094      tree name, args;
12095      int lloc, rloc;
12096 {
12097   tree invok;
12098   tree wfl = 
12099     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
12100   EXPR_WFL_LINECOL (wfl) = lloc;
12101   invok = build_method_invocation (name, args);
12102   return make_qualified_primary (wfl, invok, rloc);
12103 }
12104
12105 /* Build an incomplete CALL_EXPR node. */
12106
12107 static tree
12108 build_method_invocation (name, args)
12109     tree name;
12110     tree args;
12111 {
12112   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
12113   TREE_SIDE_EFFECTS (call) = 1;
12114   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12115   return call;
12116 }
12117
12118 /* Build an incomplete new xxx(...) node. */
12119
12120 static tree
12121 build_new_invocation (name, args)
12122     tree name, args;
12123 {
12124   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
12125   TREE_SIDE_EFFECTS (call) = 1;
12126   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12127   return call;
12128 }
12129
12130 /* Build an incomplete assignment expression. */
12131
12132 static tree
12133 build_assignment (op, op_location, lhs, rhs)
12134      int op, op_location;
12135      tree lhs, rhs;
12136 {
12137   tree assignment;
12138   /* Build the corresponding binop if we deal with a Compound
12139      Assignment operator. Mark the binop sub-tree as part of a
12140      Compound Assignment expression */
12141   if (op != ASSIGN_TK)
12142     {
12143       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
12144       COMPOUND_ASSIGN_P (rhs) = 1;
12145     }
12146   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
12147   TREE_SIDE_EFFECTS (assignment) = 1;
12148   EXPR_WFL_LINECOL (assignment) = op_location;
12149   return assignment;
12150 }
12151
12152 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
12153
12154 char *
12155 print_int_node (node)
12156     tree node;
12157 {
12158   static char buffer [80];
12159   if (TREE_CONSTANT_OVERFLOW (node))
12160     sprintf (buffer, "<overflow>");
12161     
12162   if (TREE_INT_CST_HIGH (node) == 0)
12163     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
12164              TREE_INT_CST_LOW (node));
12165   else if (TREE_INT_CST_HIGH (node) == -1
12166            && TREE_INT_CST_LOW (node) != 0)
12167     {
12168       buffer [0] = '-';
12169       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
12170                -TREE_INT_CST_LOW (node));
12171     }
12172   else
12173     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
12174              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
12175
12176   return buffer;
12177 }
12178
12179 \f
12180
12181 /* This section of the code handle assignment check with FINAL
12182    variables.  */
12183
12184 static void
12185 reset_static_final_variable_assignment_flag (class)
12186      tree class;
12187 {
12188   tree field;
12189   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12190     if (CLASS_FINAL_VARIABLE_P (field))
12191       DECL_FIELD_FINAL_LIIC (field) = 0;
12192 }
12193
12194 /* Figure whether all final static variable have been initialized.  */
12195
12196 static void
12197 check_static_final_variable_assignment_flag (class)
12198      tree class;
12199 {
12200   tree field;
12201
12202   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12203     if (CLASS_FINAL_VARIABLE_P (field)
12204         && !DECL_FIELD_FINAL_IUD (field) && !DECL_FIELD_FINAL_LIIC (field))
12205       parse_error_context
12206         (DECL_FIELD_FINAL_WFL (field),
12207          "Blank static final variable `%s' may not have been initialized",
12208          IDENTIFIER_POINTER (DECL_NAME (field)));
12209 }
12210
12211 /* This function marks all final variable locally unassigned.  */
12212
12213 static void
12214 reset_final_variable_local_assignment_flag (class)
12215      tree class;
12216 {
12217   tree field;
12218   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12219     if (FINAL_VARIABLE_P (field))
12220       DECL_FIELD_FINAL_LIIC (field) = 0;
12221 }
12222
12223 /* Figure whether all final variables have beem initialized in MDECL
12224    and mark MDECL accordingly.  */
12225
12226 static void
12227 check_final_variable_local_assignment_flag (class, mdecl)
12228      tree class;
12229      tree mdecl;
12230 {
12231   tree field;
12232   int initialized = 0;
12233   int non_initialized = 0; 
12234
12235   if (DECL_FUNCTION_SYNTHETIC_CTOR (mdecl))
12236     return;
12237
12238   /* First find out whether all final variables or no final variable
12239      are initialized in this ctor. We don't take into account final
12240      variable that have been initialized upon declaration.  */
12241   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12242     if (FINAL_VARIABLE_P (field) && !DECL_FIELD_FINAL_IUD (field))
12243       {
12244         if (DECL_FIELD_FINAL_LIIC (field))
12245           initialized++;
12246         else
12247           non_initialized++;
12248       }
12249
12250   /* There were no non initialized variable and no initialized variable.
12251      This ctor is fine. */
12252   if (!non_initialized && !initialized)
12253     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12254   /* If no variables have been initialized, that fine. We'll check
12255      later whether this ctor calls a constructor which initializes
12256      them. We mark the ctor as not initializing all its finals. */
12257   else if (initialized == 0)
12258     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 0;
12259   /* If we have a mixed bag, then we have a problem. We need to report
12260      all the variables we're not initializing.  */
12261   else if (initialized && non_initialized)
12262     {
12263       DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 0;
12264       for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12265         if (FIELD_FINAL (field)
12266             && !DECL_FIELD_FINAL_IUD (field) && !DECL_FIELD_FINAL_LIIC (field))
12267           {
12268             parse_error_context 
12269               (lookup_cl (mdecl),
12270                "Blank final variable `%s' may not have been initialized in this constructor",
12271                IDENTIFIER_POINTER (DECL_NAME (field)));
12272             DECL_FIELD_FINAL_IERR (field) = 1;
12273           }
12274     }
12275   /* Otherwise we know this ctor is initializing all its final
12276      variable. We mark it so. */
12277   else
12278     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12279 }
12280
12281 /* This function recurses in a simple what through STMT and stops when
12282    it finds a constructor call. It then verifies that the called
12283    constructor initialized its final properly. Return 1 upon success,
12284    0 or -1 otherwise.  */
12285
12286 static int
12287 check_final_variable_indirect_assignment (stmt)
12288      tree stmt;
12289 {
12290   int res;
12291   switch (TREE_CODE (stmt))
12292     {
12293     case EXPR_WITH_FILE_LOCATION:
12294       return check_final_variable_indirect_assignment (EXPR_WFL_NODE (stmt));
12295     case COMPOUND_EXPR:
12296       res = check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 0));
12297       if (res)
12298         return res;
12299       return check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 1));
12300     case SAVE_EXPR:
12301       return check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 0));
12302     case CALL_EXPR:
12303       {
12304         tree decl = TREE_OPERAND (stmt, 0);
12305         tree fbody;
12306
12307         if (TREE_CODE (decl) != FUNCTION_DECL)
12308           decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
12309         if (TREE_CODE (decl) != FUNCTION_DECL)
12310           abort ();
12311         if (DECL_FUNCTION_ALL_FINAL_INITIALIZED (decl))
12312           return 1;
12313         if (DECL_FINIT_P (decl) || DECL_CONTEXT (decl) != current_class)
12314           return -1;
12315         fbody = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
12316         if (fbody == error_mark_node)
12317           return -1;
12318         fbody = BLOCK_EXPR_BODY (fbody);
12319         return check_final_variable_indirect_assignment (fbody);
12320       }
12321     default:
12322       break;
12323     }
12324   return 0;
12325 }
12326
12327 /* This is the last chance to catch a final variable initialization
12328    problem. This routine will report an error if a final variable was
12329    never (globally) initialized and never reported as not having been
12330    initialized properly. */
12331
12332 static void
12333 check_final_variable_global_assignment_flag (class)
12334      tree class;
12335 {
12336   tree field, mdecl;
12337   int nnctor = 0;
12338
12339   /* We go through all natural ctors and see whether they're
12340      initializing all their final variables or not. */
12341   current_function_decl = NULL_TREE; /* For the error report. */
12342   for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
12343     if (DECL_CONSTRUCTOR_P (mdecl) && ! DECL_FUNCTION_SYNTHETIC_CTOR (mdecl))
12344       {
12345         if (!DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl))
12346           {
12347             /* It doesn't. Maybe it calls a constructor that initializes
12348                them.  find out. */
12349             tree fbody = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl));
12350             if (fbody == error_mark_node)
12351               continue;
12352             fbody = BLOCK_EXPR_BODY (fbody);
12353             if (check_final_variable_indirect_assignment (fbody) == 1)
12354               {
12355                 DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12356                 nnctor++;
12357               }
12358             else
12359               parse_error_context
12360                 (lookup_cl (mdecl),
12361                  "Final variable initialization error in this constructor");
12362           }
12363         else
12364           nnctor++;
12365       }
12366
12367   /* Finally we catch final variables that never were initialized */
12368   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12369     if (FINAL_VARIABLE_P (field)
12370         /* If the field wasn't initialized upon declaration */
12371         && !DECL_FIELD_FINAL_IUD (field)
12372         /* There wasn't natural ctor in which the field could have been
12373            initialized */
12374         && !nnctor
12375         /* If we never reported a problem with this field */
12376         && !DECL_FIELD_FINAL_IERR (field))
12377       {
12378         current_function_decl = NULL;
12379         parse_error_context
12380           (DECL_FIELD_FINAL_WFL (field),
12381            "Final variable `%s' hasn't been initialized upon its declaration",
12382            IDENTIFIER_POINTER (DECL_NAME (field)));
12383       }
12384
12385 }
12386
12387 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
12388    context.  */
12389
12390 static int
12391 check_final_assignment (lvalue, wfl)
12392      tree lvalue, wfl;
12393 {
12394   if (TREE_CODE (lvalue) != COMPONENT_REF && !JDECL_P (lvalue))
12395     return 0;
12396
12397   if (TREE_CODE (lvalue) == COMPONENT_REF
12398       && JDECL_P (TREE_OPERAND (lvalue, 1)))
12399     lvalue = TREE_OPERAND (lvalue, 1);
12400
12401   if (!FIELD_FINAL (lvalue))
12402     return 0;
12403
12404   /* Now the logic. We can modify a final VARIABLE:
12405      1) in finit$, (its declaration was followed by an initialization,)
12406      2) consistently in each natural ctor, if it wasn't initialized in
12407         finit$ or once in <clinit>.  In any other cases, an error should be
12408         reported. */
12409   if (DECL_FINIT_P (current_function_decl))
12410     {
12411       DECL_FIELD_FINAL_IUD (lvalue) = 1;
12412       return 0;
12413     }
12414
12415   if (!DECL_FUNCTION_SYNTHETIC_CTOR (current_function_decl)
12416       /* Only if it wasn't given a value upon initialization */
12417       && DECL_LANG_SPECIFIC (lvalue) && !DECL_FIELD_FINAL_IUD (lvalue)
12418       /* If it was never assigned a value in this constructor */
12419       && !DECL_FIELD_FINAL_LIIC (lvalue))
12420     {
12421       /* Turn the locally assigned flag on, it will be checked later
12422          on to point out at discrepancies. */
12423       DECL_FIELD_FINAL_LIIC (lvalue) = 1;
12424       if (DECL_CLINIT_P (current_function_decl))
12425         DECL_FIELD_FINAL_IUD (lvalue) = 1;
12426       return 0;
12427     }
12428
12429   /* Other problems should be reported right away. */
12430   parse_error_context 
12431     (wfl, "Can't %sassign a value to the final variable `%s'",
12432      (FIELD_STATIC (lvalue) ? "re" : ""),
12433      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
12434
12435   /* Note that static field can be initialized once and only once. */
12436   if (FIELD_STATIC (lvalue))
12437     DECL_FIELD_FINAL_IERR (lvalue) = 1;
12438
12439   return 1;
12440 }
12441
12442 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
12443    read. This is needed to avoid circularities in the implementation
12444    of these fields in libjava. */
12445
12446 static tree
12447 maybe_build_primttype_type_ref (rhs, wfl)
12448     tree rhs, wfl;
12449 {
12450   tree to_return = NULL_TREE;
12451   tree rhs_type = TREE_TYPE (rhs);
12452   if (TREE_CODE (rhs) == COMPOUND_EXPR)
12453     {
12454       tree n = TREE_OPERAND (rhs, 1);
12455       if (TREE_CODE (n) == VAR_DECL 
12456           && DECL_NAME (n) == TYPE_identifier_node
12457           && rhs_type == class_ptr_type
12458           && TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION
12459           && TREE_CODE (EXPR_WFL_NODE (wfl)) == IDENTIFIER_NODE)
12460         {
12461           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
12462           if (!strncmp (self_name, "java.lang.", 10))
12463             to_return = build_primtype_type_ref (self_name);
12464         }
12465     }
12466   return (to_return ? to_return : rhs );
12467 }
12468
12469 /* 15.25 Assignment operators. */
12470
12471 static tree
12472 patch_assignment (node, wfl_op1, wfl_op2)
12473      tree node;
12474      tree wfl_op1;
12475      tree wfl_op2;
12476 {
12477   tree rhs = TREE_OPERAND (node, 1);
12478   tree lvalue = TREE_OPERAND (node, 0), llvalue;
12479   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
12480   int error_found = 0;
12481   int lvalue_from_array = 0;
12482
12483   /* Can't assign to a (blank) final. */
12484   if (check_final_assignment (lvalue, wfl_op1))
12485     error_found = 1;
12486
12487   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12488
12489   /* Lhs can be a named variable */
12490   if (JDECL_P (lvalue))
12491     {
12492       lhs_type = TREE_TYPE (lvalue);
12493     }
12494   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
12495      comment on reason why */
12496   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
12497     {
12498       lhs_type = TREE_TYPE (lvalue);
12499       lvalue_from_array = 1;
12500     }
12501   /* Or a field access */
12502   else if (TREE_CODE (lvalue) == COMPONENT_REF)
12503     lhs_type = TREE_TYPE (lvalue);
12504   /* Or a function return slot */
12505   else if (TREE_CODE (lvalue) == RESULT_DECL)
12506     lhs_type = TREE_TYPE (lvalue);
12507   /* Otherwise, we might want to try to write into an optimized static
12508      final, this is an of a different nature, reported further on. */
12509   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
12510            && resolve_expression_name (wfl_op1, &llvalue))
12511     {
12512       if (!error_found && check_final_assignment (llvalue, wfl_op1))
12513         {
12514           /* What we should do instead is resetting the all the flags
12515              previously set, exchange lvalue for llvalue and continue. */
12516           error_found = 1;
12517           return error_mark_node;
12518         }
12519       else 
12520         lhs_type = TREE_TYPE (lvalue);
12521     }
12522   else 
12523     {
12524       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
12525       error_found = 1;
12526     }
12527
12528   rhs_type = TREE_TYPE (rhs);
12529   /* 5.1 Try the assignment conversion for builtin type. */
12530   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
12531
12532   /* 5.2 If it failed, try a reference conversion */
12533   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
12534     lhs_type = promote_type (rhs_type);
12535
12536   /* 15.25.2 If we have a compound assignment, convert RHS into the
12537      type of the LHS */
12538   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12539     new_rhs = convert (lhs_type, rhs);
12540
12541   /* Explicit cast required. This is an error */
12542   if (!new_rhs)
12543     {
12544       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
12545       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
12546       tree wfl;
12547       char operation [32];      /* Max size known */
12548
12549       /* If the assignment is part of a declaration, we use the WFL of
12550          the declared variable to point out the error and call it a
12551          declaration problem. If the assignment is a genuine =
12552          operator, we call is a operator `=' problem, otherwise we
12553          call it an assignment problem. In both of these last cases,
12554          we use the WFL of the operator to indicate the error. */
12555
12556       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
12557         {
12558           wfl = wfl_op1;
12559           strcpy (operation, "declaration");
12560         }
12561       else
12562         {
12563           wfl = wfl_operator;
12564           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12565             strcpy (operation, "assignment");
12566           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
12567             strcpy (operation, "`return'");
12568           else
12569             strcpy (operation, "`='");
12570         }
12571
12572       if (!valid_cast_to_p (rhs_type, lhs_type))
12573         parse_error_context
12574           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
12575            operation, t1, t2);
12576       else
12577         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
12578                              operation, t1, t2);
12579       free (t1); free (t2);
12580       error_found = 1;
12581     }
12582
12583   /* Inline read access to java.lang.PRIMTYPE.TYPE */
12584   if (new_rhs)
12585     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
12586
12587   if (error_found)
12588     return error_mark_node;
12589
12590   /* 10.10: Array Store Exception runtime check */
12591   if (!flag_emit_class_files
12592       && !flag_emit_xref
12593       && lvalue_from_array 
12594       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
12595     {
12596       tree check;
12597       tree base = lvalue;
12598
12599       /* We need to retrieve the right argument for
12600          _Jv_CheckArrayStore.  This is somewhat complicated by bounds
12601          and null pointer checks, both of which wrap the operand in
12602          one layer of COMPOUND_EXPR.  */
12603       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
12604         base = TREE_OPERAND (lvalue, 0);
12605       else
12606         {
12607           tree op = TREE_OPERAND (base, 0);
12608           
12609           /* We can have a SAVE_EXPR here when doing String +=.  */
12610           if (TREE_CODE (op) == SAVE_EXPR)
12611             op = TREE_OPERAND (op, 0);
12612           if (flag_bounds_check)
12613             base = TREE_OPERAND (TREE_OPERAND (op, 1), 0);
12614           else
12615             base = TREE_OPERAND (op, 0);
12616         }
12617
12618       /* Build the invocation of _Jv_CheckArrayStore */
12619       new_rhs = save_expr (new_rhs);
12620       check = build (CALL_EXPR, void_type_node,
12621                      build_address_of (soft_checkarraystore_node),
12622                      tree_cons (NULL_TREE, base,
12623                                 build_tree_list (NULL_TREE, new_rhs)),
12624                      NULL_TREE);
12625       TREE_SIDE_EFFECTS (check) = 1;
12626
12627       /* We have to decide on an insertion point */
12628       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
12629         {
12630           tree t;
12631           if (flag_bounds_check)
12632             {
12633               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
12634               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
12635                 build (COMPOUND_EXPR, void_type_node, t, check);
12636             }
12637           else
12638             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
12639                                               check, TREE_OPERAND (lvalue, 1));
12640         }
12641       else if (flag_bounds_check)
12642         {
12643           tree hook = lvalue;
12644           tree compound = TREE_OPERAND (lvalue, 0);
12645           tree bound_check, new_compound;
12646
12647           if (TREE_CODE (compound) == SAVE_EXPR)
12648             {
12649               compound = TREE_OPERAND (compound, 0);
12650               hook = TREE_OPERAND (hook, 0);
12651             }
12652
12653           /* Find the array bound check, hook the original array access. */
12654           bound_check = TREE_OPERAND (compound, 0);
12655           TREE_OPERAND (hook, 0) = TREE_OPERAND (compound, 1);
12656
12657           /* Make sure the bound check will happen before the store check */
12658           new_compound =
12659             build (COMPOUND_EXPR, void_type_node, bound_check, check);
12660
12661           /* Re-assemble the augmented array access. */
12662           lvalue = build (COMPOUND_EXPR, lhs_type, new_compound, lvalue);
12663         }
12664       else
12665         lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
12666     }
12667
12668   /* Final locals can be used as case values in switch
12669      statement. Prepare them for this eventuality. */
12670   if (TREE_CODE (lvalue) == VAR_DECL 
12671       && LOCAL_FINAL_P (lvalue)
12672       && TREE_CONSTANT (new_rhs)
12673       && IDENTIFIER_LOCAL_VALUE (DECL_NAME (lvalue))
12674       && JINTEGRAL_TYPE_P (TREE_TYPE (lvalue))
12675       )
12676     {
12677       TREE_CONSTANT (lvalue) = 1;
12678       DECL_INITIAL (lvalue) = new_rhs;
12679     }
12680
12681   TREE_OPERAND (node, 0) = lvalue;
12682   TREE_OPERAND (node, 1) = new_rhs;
12683   TREE_TYPE (node) = lhs_type;
12684   return node;
12685 }
12686
12687 /* Check that type SOURCE can be cast into type DEST. If the cast
12688    can't occur at all, return 0 otherwise 1. This function is used to
12689    produce accurate error messages on the reasons why an assignment
12690    failed. */
12691
12692 static tree
12693 try_reference_assignconv (lhs_type, rhs)
12694      tree lhs_type, rhs;
12695 {
12696   tree new_rhs = NULL_TREE;
12697   tree rhs_type = TREE_TYPE (rhs);
12698
12699   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
12700     {
12701       /* `null' may be assigned to any reference type */
12702       if (rhs == null_pointer_node)
12703         new_rhs = null_pointer_node;
12704       /* Try the reference assignment conversion */
12705       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
12706         new_rhs = rhs;
12707       /* This is a magic assignment that we process differently */
12708       else if (TREE_CODE (rhs) == JAVA_EXC_OBJ_EXPR)
12709         new_rhs = rhs;
12710     }
12711   return new_rhs;
12712 }
12713
12714 /* Check that RHS can be converted into LHS_TYPE by the assignment
12715    conversion (5.2), for the cases of RHS being a builtin type. Return
12716    NULL_TREE if the conversion fails or if because RHS isn't of a
12717    builtin type. Return a converted RHS if the conversion is possible.  */
12718
12719 static tree
12720 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
12721      tree wfl_op1, lhs_type, rhs;
12722 {
12723   tree new_rhs = NULL_TREE;
12724   tree rhs_type = TREE_TYPE (rhs);
12725
12726   /* Handle boolean specially.  */
12727   if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
12728       || TREE_CODE (lhs_type) == BOOLEAN_TYPE)
12729     {
12730       if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
12731           && TREE_CODE (lhs_type) == BOOLEAN_TYPE)
12732         new_rhs = rhs;
12733     }
12734
12735   /* Zero accepted everywhere */
12736   else if (TREE_CODE (rhs) == INTEGER_CST 
12737       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
12738       && JPRIMITIVE_TYPE_P (rhs_type))
12739     new_rhs = convert (lhs_type, rhs);
12740
12741   /* 5.1.1 Try Identity Conversion,
12742      5.1.2 Try Widening Primitive Conversion */
12743   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
12744     new_rhs = convert (lhs_type, rhs);
12745
12746   /* Try a narrowing primitive conversion (5.1.3): 
12747        - expression is a constant expression of type int AND
12748        - variable is byte, short or char AND
12749        - The value of the expression is representable in the type of the 
12750          variable */
12751   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
12752            && (lhs_type == byte_type_node || lhs_type == char_type_node
12753                || lhs_type == short_type_node))
12754     {
12755       if (int_fits_type_p (rhs, lhs_type))
12756         new_rhs = convert (lhs_type, rhs);
12757       else if (wfl_op1)         /* Might be called with a NULL */
12758         parse_warning_context 
12759           (wfl_op1, "Constant expression `%s' too wide for narrowing primitive conversion to `%s'", 
12760            print_int_node (rhs), lang_printable_name (lhs_type, 0));
12761       /* Reported a warning that will turn into an error further
12762          down, so we don't return */
12763     }
12764
12765   return new_rhs;
12766 }
12767
12768 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
12769    conversion (5.1.1) or widening primitive conversion (5.1.2).  Return
12770    0 is the conversion test fails.  This implements parts the method
12771    invocation convertion (5.3).  */
12772
12773 static int
12774 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
12775      tree lhs_type, rhs_type;
12776 {
12777   /* 5.1.1: This is the identity conversion part. */
12778   if (lhs_type == rhs_type)
12779     return 1;
12780
12781   /* Reject non primitive types and boolean conversions.  */
12782   if (!JNUMERIC_TYPE_P (lhs_type) || !JNUMERIC_TYPE_P (rhs_type))
12783     return 0;
12784
12785   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
12786      than a char can't be converted into a char. Short can't too, but
12787      the < test below takes care of that */
12788   if (lhs_type == char_type_node && rhs_type == byte_type_node)
12789     return 0;
12790
12791   /* Accept all promoted type here. Note, we can't use <= in the test
12792      below, because we still need to bounce out assignments of short
12793      to char and the likes */
12794   if (lhs_type == int_type_node
12795       && (rhs_type == promoted_byte_type_node
12796           || rhs_type == promoted_short_type_node
12797           || rhs_type == promoted_char_type_node
12798           || rhs_type == promoted_boolean_type_node))
12799     return 1;
12800
12801   /* From here, an integral is widened if its precision is smaller
12802      than the precision of the LHS or if the LHS is a floating point
12803      type, or the RHS is a float and the RHS a double. */
12804   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
12805        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
12806       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
12807       || (rhs_type == float_type_node && lhs_type == double_type_node))
12808     return 1;
12809
12810   return 0;
12811 }
12812
12813 /* Check that something of SOURCE type can be assigned or cast to
12814    something of DEST type at runtime. Return 1 if the operation is
12815    valid, 0 otherwise. If CAST is set to 1, we're treating the case
12816    were SOURCE is cast into DEST, which borrows a lot of the
12817    assignment check. */
12818
12819 static int
12820 valid_ref_assignconv_cast_p (source, dest, cast)
12821      tree source;
12822      tree dest;
12823      int cast;
12824 {
12825   /* SOURCE or DEST might be null if not from a declared entity. */
12826   if (!source || !dest)
12827     return 0;
12828   if (JNULLP_TYPE_P (source))
12829     return 1;
12830   if (TREE_CODE (source) == POINTER_TYPE)
12831     source = TREE_TYPE (source);
12832   if (TREE_CODE (dest) == POINTER_TYPE)
12833     dest = TREE_TYPE (dest);
12834
12835   /* If source and dest are being compiled from bytecode, they may need to
12836      be loaded. */
12837   if (CLASS_P (source) && !CLASS_LOADED_P (source))
12838     {
12839       load_class (source, 1);
12840       safe_layout_class (source);
12841     }
12842   if (CLASS_P (dest) && !CLASS_LOADED_P (dest))
12843     {
12844       load_class (dest, 1);
12845       safe_layout_class (dest);
12846     }
12847
12848   /* Case where SOURCE is a class type */
12849   if (TYPE_CLASS_P (source))
12850     {
12851       if (TYPE_CLASS_P (dest))
12852         return  (source == dest 
12853                  || inherits_from_p (source, dest)
12854                  || (cast && inherits_from_p (dest, source)));
12855       if (TYPE_INTERFACE_P (dest))
12856         {
12857           /* If doing a cast and SOURCE is final, the operation is
12858              always correct a compile time (because even if SOURCE
12859              does not implement DEST, a subclass of SOURCE might). */
12860           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
12861             return 1;
12862           /* Otherwise, SOURCE must implement DEST */
12863           return interface_of_p (dest, source);
12864         }
12865       /* DEST is an array, cast permited if SOURCE is of Object type */
12866       return (cast && source == object_type_node ? 1 : 0);
12867     }
12868   if (TYPE_INTERFACE_P (source))
12869     {
12870       if (TYPE_CLASS_P (dest))
12871         {
12872           /* If not casting, DEST must be the Object type */
12873           if (!cast)
12874             return dest == object_type_node;
12875           /* We're doing a cast. The cast is always valid is class
12876              DEST is not final, otherwise, DEST must implement SOURCE */
12877           else if (!CLASS_FINAL (TYPE_NAME (dest)))
12878             return 1;
12879           else
12880             return interface_of_p (source, dest);
12881         }
12882       if (TYPE_INTERFACE_P (dest))
12883         {
12884           /* If doing a cast, then if SOURCE and DEST contain method
12885              with the same signature but different return type, then
12886              this is a (compile time) error */
12887           if (cast)
12888             {
12889               tree method_source, method_dest;
12890               tree source_type;
12891               tree source_sig;
12892               tree source_name;
12893               for (method_source = TYPE_METHODS (source); method_source; 
12894                    method_source = TREE_CHAIN (method_source))
12895                 {
12896                   source_sig = 
12897                     build_java_argument_signature (TREE_TYPE (method_source));
12898                   source_type = TREE_TYPE (TREE_TYPE (method_source));
12899                   source_name = DECL_NAME (method_source);
12900                   for (method_dest = TYPE_METHODS (dest);
12901                        method_dest; method_dest = TREE_CHAIN (method_dest))
12902                     if (source_sig == 
12903                         build_java_argument_signature (TREE_TYPE (method_dest))
12904                         && source_name == DECL_NAME (method_dest)
12905                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
12906                       return 0;
12907                 }
12908               return 1;
12909             }
12910           else
12911             return source == dest || interface_of_p (dest, source);
12912         }
12913       else
12914         {
12915           /* Array */
12916           return (cast
12917                   && (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable
12918                       || (DECL_NAME (TYPE_NAME (source))
12919                           == java_io_serializable)));
12920         }
12921     }
12922   if (TYPE_ARRAY_P (source))
12923     {
12924       if (TYPE_CLASS_P (dest))
12925         return dest == object_type_node;
12926       /* Can't cast an array to an interface unless the interface is
12927          java.lang.Cloneable or java.io.Serializable.  */
12928       if (TYPE_INTERFACE_P (dest))
12929         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable
12930                 || DECL_NAME (TYPE_NAME (dest)) == java_io_serializable);
12931       else                      /* Arrays */
12932         {
12933           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
12934           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
12935           
12936           /* In case of severe errors, they turn out null */
12937           if (!dest_element_type || !source_element_type)
12938             return 0;
12939           if (source_element_type == dest_element_type)
12940             return 1;
12941           return valid_ref_assignconv_cast_p (source_element_type,
12942                                               dest_element_type, cast);
12943         }
12944       return 0;
12945     }
12946   return 0;
12947 }
12948
12949 static int
12950 valid_cast_to_p (source, dest)
12951      tree source;
12952      tree dest;
12953 {
12954   if (TREE_CODE (source) == POINTER_TYPE)
12955     source = TREE_TYPE (source);
12956   if (TREE_CODE (dest) == POINTER_TYPE)
12957     dest = TREE_TYPE (dest);
12958
12959   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
12960     return valid_ref_assignconv_cast_p (source, dest, 1);
12961
12962   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
12963     return 1;
12964
12965   else if (TREE_CODE (source) == BOOLEAN_TYPE
12966            && TREE_CODE (dest) == BOOLEAN_TYPE)
12967     return 1;
12968
12969   return 0;
12970 }
12971
12972 static tree
12973 do_unary_numeric_promotion (arg)
12974      tree arg;
12975 {
12976   tree type = TREE_TYPE (arg);
12977   if ((TREE_CODE (type) == INTEGER_TYPE && TYPE_PRECISION (type) < 32)
12978       || TREE_CODE (type) == CHAR_TYPE)
12979     arg = convert (int_type_node, arg);
12980   return arg;
12981 }
12982
12983 /* Return a non zero value if SOURCE can be converted into DEST using
12984    the method invocation conversion rule (5.3).  */
12985 static int
12986 valid_method_invocation_conversion_p (dest, source)
12987      tree dest, source;
12988 {
12989   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
12990            && valid_builtin_assignconv_identity_widening_p (dest, source))
12991           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
12992               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
12993               && valid_ref_assignconv_cast_p (source, dest, 0)));
12994 }
12995
12996 /* Build an incomplete binop expression. */
12997
12998 static tree
12999 build_binop (op, op_location, op1, op2)
13000      enum tree_code op;
13001      int op_location;
13002      tree op1, op2;
13003 {
13004   tree binop = build (op, NULL_TREE, op1, op2);
13005   TREE_SIDE_EFFECTS (binop) = 1;
13006   /* Store the location of the operator, for better error report. The
13007      string of the operator will be rebuild based on the OP value. */
13008   EXPR_WFL_LINECOL (binop) = op_location;
13009   return binop;
13010 }
13011
13012 /* Build the string of the operator retained by NODE. If NODE is part
13013    of a compound expression, add an '=' at the end of the string. This
13014    function is called when an error needs to be reported on an
13015    operator. The string is returned as a pointer to a static character
13016    buffer. */
13017
13018 static char *
13019 operator_string (node)
13020      tree node;
13021 {
13022 #define BUILD_OPERATOR_STRING(S)                                        \
13023   {                                                                     \
13024     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
13025     return buffer;                                                      \
13026   }
13027   
13028   static char buffer [10];
13029   switch (TREE_CODE (node))
13030     {
13031     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
13032     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
13033     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
13034     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
13035     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
13036     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
13037     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
13038     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
13039     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
13040     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
13041     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
13042     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
13043     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
13044     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
13045     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
13046     case GT_EXPR: BUILD_OPERATOR_STRING (">");
13047     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
13048     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
13049     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
13050     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
13051     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
13052     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
13053     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
13054     case PREINCREMENT_EXPR:     /* Fall through */
13055     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
13056     case PREDECREMENT_EXPR:     /* Fall through */
13057     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
13058     default:
13059       internal_error ("unregistered operator %s",
13060                       tree_code_name [TREE_CODE (node)]);
13061     }
13062   return NULL;
13063 #undef BUILD_OPERATOR_STRING
13064 }
13065
13066 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
13067
13068 static int
13069 java_decl_equiv (var_acc1, var_acc2)
13070      tree var_acc1, var_acc2;
13071 {
13072   if (JDECL_P (var_acc1))
13073     return (var_acc1 == var_acc2);
13074   
13075   return (TREE_CODE (var_acc1) == COMPONENT_REF
13076           && TREE_CODE (var_acc2) == COMPONENT_REF
13077           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
13078              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
13079           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
13080 }
13081
13082 /* Return a non zero value if CODE is one of the operators that can be
13083    used in conjunction with the `=' operator in a compound assignment.  */
13084
13085 static int
13086 binop_compound_p (code)
13087     enum tree_code code;
13088 {
13089   int i;
13090   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
13091     if (binop_lookup [i] == code)
13092       break;
13093
13094   return i < BINOP_COMPOUND_CANDIDATES;
13095 }
13096
13097 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
13098
13099 static tree
13100 java_refold (t)
13101      tree t;
13102 {
13103   tree c, b, ns, decl;
13104
13105   if (TREE_CODE (t) != MODIFY_EXPR)
13106     return t;
13107
13108   c = TREE_OPERAND (t, 1);
13109   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
13110          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
13111          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
13112     return t;
13113
13114   /* Now the left branch of the binary operator. */
13115   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
13116   if (! (b && TREE_CODE (b) == NOP_EXPR 
13117          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
13118     return t;
13119
13120   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
13121   if (! (ns && TREE_CODE (ns) == NOP_EXPR
13122          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
13123     return t;
13124
13125   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
13126   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
13127       /* It's got to be the an equivalent decl */
13128       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
13129     {
13130       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
13131       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
13132       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
13133       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
13134       /* Change the right part of the BINOP_EXPR */
13135       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
13136     }
13137
13138   return t;
13139 }
13140
13141 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
13142    errors but we modify NODE so that it contains the type computed
13143    according to the expression, when it's fixed. Otherwise, we write
13144    error_mark_node as the type. It allows us to further the analysis
13145    of remaining nodes and detects more errors in certain cases.  */
13146
13147 static tree
13148 patch_binop (node, wfl_op1, wfl_op2)
13149      tree node;
13150      tree wfl_op1;
13151      tree wfl_op2;
13152 {
13153   tree op1 = TREE_OPERAND (node, 0);
13154   tree op2 = TREE_OPERAND (node, 1);
13155   tree op1_type = TREE_TYPE (op1);
13156   tree op2_type = TREE_TYPE (op2);
13157   tree prom_type = NULL_TREE, cn;
13158   int code = TREE_CODE (node);
13159
13160   /* If 1, tell the routine that we have to return error_mark_node
13161      after checking for the initialization of the RHS */
13162   int error_found = 0;
13163
13164   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13165
13166   /* If either op<n>_type are NULL, this might be early signs of an
13167      error situation, unless it's too early to tell (in case we're
13168      handling a `+', `==', `!=' or `instanceof'.) We want to set op<n>_type
13169      correctly so the error can be later on reported accurately. */
13170   if (! (code == PLUS_EXPR || code == NE_EXPR 
13171          || code == EQ_EXPR || code == INSTANCEOF_EXPR))
13172     {
13173       tree n;
13174       if (! op1_type)
13175         {
13176           n = java_complete_tree (op1);
13177           op1_type = TREE_TYPE (n);
13178         }
13179       if (! op2_type)
13180         {
13181           n = java_complete_tree (op2);
13182           op2_type = TREE_TYPE (n);
13183         }
13184     }
13185
13186   switch (code)
13187     {
13188     /* 15.16 Multiplicative operators */
13189     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
13190     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
13191     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
13192     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
13193       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13194         {
13195           if (!JNUMERIC_TYPE_P (op1_type))
13196             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13197           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13198             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13199           TREE_TYPE (node) = error_mark_node;
13200           error_found = 1;
13201           break;
13202         }
13203       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13204       /* Change the division operator if necessary */
13205       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
13206         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
13207
13208       if (TREE_CODE (prom_type) == INTEGER_TYPE
13209           && flag_use_divide_subroutine
13210           && ! flag_emit_class_files
13211           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
13212         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
13213  
13214       /* This one is more complicated. FLOATs are processed by a
13215          function call to soft_fmod. Duplicate the value of the
13216          COMPOUND_ASSIGN_P flag. */
13217       if (code == TRUNC_MOD_EXPR)
13218         {
13219           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
13220           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
13221           TREE_SIDE_EFFECTS (mod)
13222             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13223           return mod;
13224         }
13225       break;
13226
13227     /* 15.17 Additive Operators */
13228     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
13229
13230       /* Operation is valid if either one argument is a string
13231          constant, a String object or a StringBuffer crafted for the
13232          purpose of the a previous usage of the String concatenation
13233          operator */
13234
13235       if (TREE_CODE (op1) == STRING_CST 
13236           || TREE_CODE (op2) == STRING_CST
13237           || JSTRING_TYPE_P (op1_type)
13238           || JSTRING_TYPE_P (op2_type)
13239           || IS_CRAFTED_STRING_BUFFER_P (op1)
13240           || IS_CRAFTED_STRING_BUFFER_P (op2))
13241         return build_string_concatenation (op1, op2);
13242
13243     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
13244                                    Numeric Types */
13245       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13246         {
13247           if (!JNUMERIC_TYPE_P (op1_type))
13248             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13249           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13250             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13251           TREE_TYPE (node) = error_mark_node;
13252           error_found = 1;
13253           break;
13254         }
13255       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13256       break;
13257
13258     /* 15.18 Shift Operators */
13259     case LSHIFT_EXPR:
13260     case RSHIFT_EXPR:
13261     case URSHIFT_EXPR:
13262       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
13263         {
13264           if (!JINTEGRAL_TYPE_P (op1_type))
13265             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13266           else
13267             {
13268               if (JNUMERIC_TYPE_P (op2_type))
13269                 parse_error_context (wfl_operator,
13270                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
13271                                      operator_string (node),
13272                                      lang_printable_name (op2_type, 0));
13273               else
13274                 parse_error_context (wfl_operator,
13275                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
13276                                      operator_string (node),
13277                                      lang_printable_name (op2_type, 0));
13278             }
13279           TREE_TYPE (node) = error_mark_node;
13280           error_found = 1;
13281           break;
13282         }
13283
13284       /* Unary numeric promotion (5.6.1) is performed on each operand
13285          separatly */
13286       op1 = do_unary_numeric_promotion (op1);
13287       op2 = do_unary_numeric_promotion (op2);
13288
13289       /* The type of the shift expression is the type of the promoted
13290          type of the left-hand operand */
13291       prom_type = TREE_TYPE (op1);
13292
13293       /* Shift int only up to 0x1f and long up to 0x3f */
13294       if (prom_type == int_type_node)
13295         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13296                            build_int_2 (0x1f, 0)));
13297       else
13298         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13299                            build_int_2 (0x3f, 0)));
13300
13301       /* The >>> operator is a >> operating on unsigned quantities */
13302       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
13303         {
13304           tree to_return;
13305           tree utype = unsigned_type (prom_type);
13306           op1 = convert (utype, op1);
13307           TREE_SET_CODE (node, RSHIFT_EXPR);
13308           TREE_OPERAND (node, 0) = op1;
13309           TREE_OPERAND (node, 1) = op2;
13310           TREE_TYPE (node) = utype;
13311           to_return = convert (prom_type, node);
13312           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
13313           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
13314           TREE_SIDE_EFFECTS (to_return)
13315             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13316           return to_return;
13317         }
13318       break;
13319
13320       /* 15.19.1 Type Comparison Operator instaceof */
13321     case INSTANCEOF_EXPR:
13322
13323       TREE_TYPE (node) = boolean_type_node;
13324
13325       if (!(op2_type = resolve_type_during_patch (op2)))
13326         return error_mark_node;
13327
13328       /* The first operand must be a reference type or the null type */
13329       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
13330         error_found = 1;        /* Error reported further below */
13331
13332       /* The second operand must be a reference type */
13333       if (!JREFERENCE_TYPE_P (op2_type))
13334         {
13335           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
13336           parse_error_context
13337             (wfl_operator, "Invalid argument `%s' for `instanceof'",
13338              lang_printable_name (op2_type, 0));
13339           error_found = 1;
13340         }
13341
13342       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
13343         {
13344           /* If the first operand is null, the result is always false */
13345           if (op1 == null_pointer_node)
13346             return boolean_false_node;
13347           else if (flag_emit_class_files)
13348             {
13349               TREE_OPERAND (node, 1) = op2_type;
13350               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
13351               return node;
13352             }
13353           /* Otherwise we have to invoke instance of to figure it out */
13354           else
13355             return build_instanceof (op1, op2_type);
13356         }
13357       /* There is no way the expression operand can be an instance of
13358          the type operand. This is a compile time error. */
13359       else
13360         {
13361           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
13362           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
13363           parse_error_context 
13364             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
13365              t1, lang_printable_name (op2_type, 0));
13366           free (t1);
13367           error_found = 1;
13368         }
13369       
13370       break;
13371
13372       /* 15.21 Bitwise and Logical Operators */
13373     case BIT_AND_EXPR:
13374     case BIT_XOR_EXPR:
13375     case BIT_IOR_EXPR:
13376       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
13377         /* Binary numeric promotion is performed on both operand and the
13378            expression retain that type */
13379         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13380
13381       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
13382                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
13383         /* The type of the bitwise operator expression is BOOLEAN */
13384         prom_type = boolean_type_node;
13385       else
13386         {
13387           if (!JINTEGRAL_TYPE_P (op1_type))
13388             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13389           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
13390             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
13391           TREE_TYPE (node) = error_mark_node;
13392           error_found = 1;
13393           /* Insert a break here if adding thing before the switch's
13394              break for this case */
13395         }
13396       break;
13397
13398       /* 15.22 Conditional-And Operator */
13399     case TRUTH_ANDIF_EXPR:
13400       /* 15.23 Conditional-Or Operator */
13401     case TRUTH_ORIF_EXPR:
13402       /* Operands must be of BOOLEAN type */
13403       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
13404           TREE_CODE (op2_type) != BOOLEAN_TYPE)
13405         {
13406           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
13407             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
13408           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
13409             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
13410           TREE_TYPE (node) = boolean_type_node;
13411           error_found = 1;
13412           break;
13413         }
13414       /* The type of the conditional operators is BOOLEAN */
13415       prom_type = boolean_type_node;
13416       break;
13417
13418       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
13419     case LT_EXPR:
13420     case GT_EXPR:
13421     case LE_EXPR:
13422     case GE_EXPR:
13423       /* The type of each of the operands must be a primitive numeric
13424          type */
13425       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
13426         {
13427           if (!JNUMERIC_TYPE_P (op1_type))
13428             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13429           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13430             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13431           TREE_TYPE (node) = boolean_type_node;
13432           error_found = 1;
13433           break;
13434         }
13435       /* Binary numeric promotion is performed on the operands */
13436       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13437       /* The type of the relation expression is always BOOLEAN */
13438       prom_type = boolean_type_node;
13439       break;
13440
13441       /* 15.20 Equality Operator */
13442     case EQ_EXPR:
13443     case NE_EXPR:
13444       /* It's time for us to patch the strings. */
13445       if ((cn = patch_string (op1))) 
13446        {
13447          op1 = cn;
13448          op1_type = TREE_TYPE (op1);
13449        }
13450       if ((cn = patch_string (op2))) 
13451        {
13452          op2 = cn;
13453          op2_type = TREE_TYPE (op2);
13454        }
13455       
13456       /* 15.20.1 Numerical Equality Operators == and != */
13457       /* Binary numeric promotion is performed on the operands */
13458       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
13459         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13460       
13461       /* 15.20.2 Boolean Equality Operators == and != */
13462       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
13463           TREE_CODE (op2_type) == BOOLEAN_TYPE)
13464         ;                       /* Nothing to do here */
13465       
13466       /* 15.20.3 Reference Equality Operators == and != */
13467       /* Types have to be either references or the null type. If
13468          they're references, it must be possible to convert either
13469          type to the other by casting conversion. */
13470       else if (op1 == null_pointer_node || op2 == null_pointer_node 
13471                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
13472                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
13473                        || valid_ref_assignconv_cast_p (op2_type, 
13474                                                        op1_type, 1))))
13475         ;                       /* Nothing to do here */
13476           
13477       /* Else we have an error figure what can't be converted into
13478          what and report the error */
13479       else
13480         {
13481           char *t1;
13482           t1 = xstrdup (lang_printable_name (op1_type, 0));
13483           parse_error_context 
13484             (wfl_operator,
13485              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
13486              operator_string (node), t1, 
13487              lang_printable_name (op2_type, 0));
13488           free (t1);
13489           TREE_TYPE (node) = boolean_type_node;
13490           error_found = 1;
13491           break;
13492         }
13493       prom_type = boolean_type_node;
13494       break;
13495     }
13496
13497   if (error_found)
13498     return error_mark_node;
13499
13500   TREE_OPERAND (node, 0) = op1;
13501   TREE_OPERAND (node, 1) = op2;
13502   TREE_TYPE (node) = prom_type;
13503   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13504   
13505   if (flag_emit_xref)
13506     return node;
13507
13508   /* fold does not respect side-effect order as required for Java but not C.
13509    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
13510    * bytecode.
13511    */
13512   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
13513       : ! TREE_SIDE_EFFECTS (node))
13514     node = fold (node);
13515   return node;
13516 }
13517
13518 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
13519    zero value, the value of CSTE comes after the valude of STRING */
13520
13521 static tree
13522 do_merge_string_cste (cste, string, string_len, after)
13523      tree cste;
13524      const char *string;
13525      int string_len, after;
13526 {
13527   const char *old = TREE_STRING_POINTER (cste);
13528   int old_len = TREE_STRING_LENGTH (cste);
13529   int len = old_len + string_len;
13530   char *new = alloca (len+1);
13531
13532   if (after)
13533     {
13534       memcpy (new, string, string_len);
13535       memcpy (&new [string_len], old, old_len);
13536     }
13537   else
13538     {
13539       memcpy (new, old, old_len);
13540       memcpy (&new [old_len], string, string_len);
13541     }
13542   new [len] = '\0';
13543   return build_string (len, new);
13544 }
13545
13546 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
13547    new STRING_CST on success, NULL_TREE on failure */
13548
13549 static tree
13550 merge_string_cste (op1, op2, after)
13551      tree op1, op2;
13552      int after;
13553 {
13554   /* Handle two string constants right away */
13555   if (TREE_CODE (op2) == STRING_CST)
13556     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
13557                                  TREE_STRING_LENGTH (op2), after);
13558   
13559   /* Reasonable integer constant can be treated right away */
13560   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
13561     {
13562       static const char *boolean_true = "true";
13563       static const char *boolean_false = "false";
13564       static const char *null_pointer = "null";
13565       char ch[3];
13566       const char *string;
13567       
13568       if (op2 == boolean_true_node)
13569         string = boolean_true;
13570       else if (op2 == boolean_false_node)
13571         string = boolean_false;
13572       else if (op2 == null_pointer_node)
13573         string = null_pointer;
13574       else if (TREE_TYPE (op2) == char_type_node)
13575         {
13576           ch[0] = (char )TREE_INT_CST_LOW (op2);
13577           ch[1] = '\0';
13578           string = ch;
13579         }
13580       else
13581           string = print_int_node (op2);
13582       
13583       return do_merge_string_cste (op1, string, strlen (string), after);
13584     }
13585   return NULL_TREE;
13586 }
13587
13588 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
13589    has to be a STRING_CST and the other part must be a STRING_CST or a
13590    INTEGRAL constant. Return a new STRING_CST if the operation
13591    succeed, NULL_TREE otherwise.
13592
13593    If the case we want to optimize for space, we might want to return
13594    NULL_TREE for each invocation of this routine. FIXME */
13595
13596 static tree
13597 string_constant_concatenation (op1, op2)
13598      tree op1, op2;
13599 {
13600   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
13601     {
13602       tree string, rest;
13603       int invert;
13604       
13605       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
13606       rest   = (string == op1 ? op2 : op1);
13607       invert = (string == op1 ? 0 : 1 );
13608       
13609       /* Walk REST, only if it looks reasonable */
13610       if (TREE_CODE (rest) != STRING_CST
13611           && !IS_CRAFTED_STRING_BUFFER_P (rest)
13612           && !JSTRING_TYPE_P (TREE_TYPE (rest))
13613           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
13614         {
13615           rest = java_complete_tree (rest);
13616           if (rest == error_mark_node)
13617             return error_mark_node;
13618           rest = fold (rest);
13619         }
13620       return merge_string_cste (string, rest, invert);
13621     }
13622   return NULL_TREE;
13623 }
13624
13625 /* Implement the `+' operator. Does static optimization if possible,
13626    otherwise create (if necessary) and append elements to a
13627    StringBuffer. The StringBuffer will be carried around until it is
13628    used for a function call or an assignment. Then toString() will be
13629    called on it to turn it into a String object. */
13630
13631 static tree
13632 build_string_concatenation (op1, op2)
13633      tree op1, op2;
13634 {
13635   tree result;
13636   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13637
13638   if (flag_emit_xref)
13639     return build (PLUS_EXPR, string_type_node, op1, op2);
13640   
13641   /* Try to do some static optimization */
13642   if ((result = string_constant_concatenation (op1, op2)))
13643     return result;
13644
13645   /* Discard empty strings on either side of the expression */
13646   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
13647     {
13648       op1 = op2;
13649       op2 = NULL_TREE;
13650     }
13651   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
13652     op2 = NULL_TREE;
13653
13654   /* If operands are string constant, turn then into object references */
13655   if (TREE_CODE (op1) == STRING_CST)
13656     op1 = patch_string_cst (op1);
13657   if (op2 && TREE_CODE (op2) == STRING_CST)
13658     op2 = patch_string_cst (op2);
13659
13660   /* If either one of the constant is null and the other non null
13661      operand is a String object, return it. */
13662   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
13663     return op1;
13664
13665   /* If OP1 isn't already a StringBuffer, create and
13666      initialize a new one */
13667   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
13668     {
13669       /* Two solutions here: 
13670          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
13671          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
13672       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
13673         op1 = BUILD_STRING_BUFFER (op1);
13674       else
13675         {
13676           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
13677           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
13678         }
13679     }
13680
13681   if (op2)
13682     {
13683       /* OP1 is no longer the last node holding a crafted StringBuffer */
13684       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
13685       /* Create a node for `{new...,xxx}.append (op2)' */
13686       if (op2)
13687         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
13688     }
13689
13690   /* Mark the last node holding a crafted StringBuffer */
13691   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
13692
13693   TREE_SIDE_EFFECTS (op1) = side_effects;
13694   return op1;
13695 }
13696
13697 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
13698    StringBuffer. If no string were found to be patched, return
13699    NULL. */
13700
13701 static tree
13702 patch_string (node)
13703     tree node;
13704 {
13705   if (node == error_mark_node)
13706     return error_mark_node;
13707   if (TREE_CODE (node) == STRING_CST)
13708     return patch_string_cst (node);
13709   else if (IS_CRAFTED_STRING_BUFFER_P (node))
13710     {
13711       int saved = ctxp->explicit_constructor_p;
13712       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
13713       tree ret;
13714       /* Temporary disable forbid the use of `this'. */
13715       ctxp->explicit_constructor_p = 0;
13716       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
13717       /* String concatenation arguments must be evaluated in order too. */
13718       ret = force_evaluation_order (ret);
13719       /* Restore it at its previous value */
13720       ctxp->explicit_constructor_p = saved;
13721       return ret;
13722     }
13723   return NULL_TREE;
13724 }
13725
13726 /* Build the internal representation of a string constant.  */
13727
13728 static tree
13729 patch_string_cst (node)
13730      tree node;
13731 {
13732   int location;
13733   if (! flag_emit_class_files)
13734     {
13735       node = get_identifier (TREE_STRING_POINTER (node));
13736       location = alloc_name_constant (CONSTANT_String, node);
13737       node = build_ref_from_constant_pool (location);
13738     }
13739   TREE_TYPE (node) = string_ptr_type_node;
13740   TREE_CONSTANT (node) = 1;
13741   return node;
13742 }
13743
13744 /* Build an incomplete unary operator expression. */
13745
13746 static tree
13747 build_unaryop (op_token, op_location, op1)
13748      int op_token, op_location;
13749      tree op1;
13750 {
13751   enum tree_code op;
13752   tree unaryop;
13753   switch (op_token)
13754     {
13755     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
13756     case MINUS_TK: op = NEGATE_EXPR; break;
13757     case NEG_TK: op = TRUTH_NOT_EXPR; break;
13758     case NOT_TK: op = BIT_NOT_EXPR; break;
13759     default: abort ();
13760     }
13761
13762   unaryop = build1 (op, NULL_TREE, op1);
13763   TREE_SIDE_EFFECTS (unaryop) = 1;
13764   /* Store the location of the operator, for better error report. The
13765      string of the operator will be rebuild based on the OP value. */
13766   EXPR_WFL_LINECOL (unaryop) = op_location;
13767   return unaryop;
13768 }
13769
13770 /* Special case for the ++/-- operators, since they require an extra
13771    argument to build, which is set to NULL and patched
13772    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
13773
13774 static tree
13775 build_incdec (op_token, op_location, op1, is_post_p)
13776      int op_token, op_location;
13777      tree op1;
13778      int is_post_p;
13779 {
13780   static enum tree_code lookup [2][2] = 
13781     {
13782       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
13783       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
13784     };
13785   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
13786                      NULL_TREE, op1, NULL_TREE);
13787   TREE_SIDE_EFFECTS (node) = 1;
13788   /* Store the location of the operator, for better error report. The
13789      string of the operator will be rebuild based on the OP value. */
13790   EXPR_WFL_LINECOL (node) = op_location;
13791   return node;
13792 }     
13793
13794 /* Build an incomplete cast operator, based on the use of the
13795    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
13796    set. java_complete_tree is trained to walk a CONVERT_EXPR even
13797    though its type is already set.  */
13798
13799 static tree
13800 build_cast (location, type, exp)
13801      int location;
13802      tree type, exp;
13803 {
13804   tree node = build1 (CONVERT_EXPR, type, exp);
13805   EXPR_WFL_LINECOL (node) = location;
13806   return node;
13807 }
13808
13809 /* Build an incomplete class reference operator.  */
13810 static tree
13811 build_incomplete_class_ref (location, class_name)
13812     int location;
13813     tree class_name;
13814 {
13815   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
13816   EXPR_WFL_LINECOL (node) = location;
13817   return node;
13818 }
13819
13820 /* Complete an incomplete class reference operator.  */
13821 static tree
13822 patch_incomplete_class_ref (node)
13823     tree node;
13824 {
13825   tree type = TREE_OPERAND (node, 0);
13826   tree ref_type;
13827
13828   if (!(ref_type = resolve_type_during_patch (type)))
13829     return error_mark_node;
13830
13831   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
13832     {
13833       tree dot = build_class_ref (ref_type);
13834       /* A class referenced by `foo.class' is initialized.  */
13835       if (!flag_emit_class_files)
13836        dot = build_class_init (ref_type, dot);
13837       return java_complete_tree (dot);
13838     }
13839
13840   /* If we're emitting class files and we have to deal with non
13841      primitive types, we invoke (and consider generating) the
13842      synthetic static method `class$'. */
13843   if (!TYPE_DOT_CLASS (current_class))
13844       build_dot_class_method (current_class);
13845   ref_type = build_dot_class_method_invocation (ref_type);
13846   return java_complete_tree (ref_type);
13847 }
13848
13849 /* 15.14 Unary operators. We return error_mark_node in case of error,
13850    but preserve the type of NODE if the type is fixed.  */
13851
13852 static tree
13853 patch_unaryop (node, wfl_op)
13854      tree node;
13855      tree wfl_op;
13856 {
13857   tree op = TREE_OPERAND (node, 0);
13858   tree op_type = TREE_TYPE (op);
13859   tree prom_type = NULL_TREE, value, decl;
13860   int outer_field_flag = 0;
13861   int code = TREE_CODE (node);
13862   int error_found = 0;
13863
13864   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13865
13866   switch (code)
13867     {
13868       /* 15.13.2 Postfix Increment Operator ++ */
13869     case POSTINCREMENT_EXPR:
13870       /* 15.13.3 Postfix Increment Operator -- */
13871     case POSTDECREMENT_EXPR:
13872       /* 15.14.1 Prefix Increment Operator ++ */
13873     case PREINCREMENT_EXPR:
13874       /* 15.14.2 Prefix Decrement Operator -- */
13875     case PREDECREMENT_EXPR:
13876       op = decl = strip_out_static_field_access_decl (op);
13877       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
13878       /* We might be trying to change an outer field accessed using
13879          access method. */
13880       if (outer_field_flag)
13881         {
13882           /* Retrieve the decl of the field we're trying to access. We
13883              do that by first retrieving the function we would call to
13884              access the field. It has been already verified that this
13885              field isn't final */
13886           if (flag_emit_class_files)
13887             decl = TREE_OPERAND (op, 0);
13888           else
13889             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
13890           decl = DECL_FUNCTION_ACCESS_DECL (decl);
13891         }
13892       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
13893       else if (!JDECL_P (decl) 
13894           && TREE_CODE (decl) != COMPONENT_REF
13895           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
13896           && TREE_CODE (decl) != INDIRECT_REF
13897           && !(TREE_CODE (decl) == COMPOUND_EXPR
13898                && TREE_OPERAND (decl, 1)
13899                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
13900         {
13901           tree lvalue;
13902           /* Before screaming, check that we're not in fact trying to
13903              increment a optimized static final access, in which case
13904              we issue an different error message. */
13905           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
13906                 && resolve_expression_name (wfl_op, &lvalue)
13907                 && check_final_assignment (lvalue, wfl_op)))
13908             parse_error_context (wfl_operator, "Invalid argument to `%s'",
13909                                  operator_string (node));
13910           TREE_TYPE (node) = error_mark_node;
13911           error_found = 1;
13912         }
13913       
13914       if (check_final_assignment (op, wfl_op))
13915         error_found = 1;
13916
13917       /* From now on, we know that op if a variable and that it has a
13918          valid wfl. We use wfl_op to locate errors related to the
13919          ++/-- operand. */
13920       else if (!JNUMERIC_TYPE_P (op_type))
13921         {
13922           parse_error_context
13923             (wfl_op, "Invalid argument type `%s' to `%s'",
13924              lang_printable_name (op_type, 0), operator_string (node));
13925           TREE_TYPE (node) = error_mark_node;
13926           error_found = 1;
13927         }
13928       else
13929         {
13930           /* Before the addition, binary numeric promotion is performed on
13931              both operands, if really necessary */
13932           if (JINTEGRAL_TYPE_P (op_type))
13933             {
13934               value = build_int_2 (1, 0);
13935               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
13936             }
13937           else
13938             {
13939               value = build_int_2 (1, 0);
13940               TREE_TYPE (node) = 
13941                 binary_numeric_promotion (op_type, 
13942                                           TREE_TYPE (value), &op, &value);
13943             }
13944
13945           /* We remember we might be accessing an outer field */
13946           if (outer_field_flag)
13947             {
13948               /* We re-generate an access to the field */
13949               value = build (PLUS_EXPR, TREE_TYPE (op), 
13950                              build_outer_field_access (wfl_op, decl), value);
13951                                                     
13952               /* And we patch the original access$() into a write 
13953                  with plus_op as a rhs */
13954               return outer_field_access_fix (node, op, value);
13955             }
13956
13957           /* And write back into the node. */
13958           TREE_OPERAND (node, 0) = op;
13959           TREE_OPERAND (node, 1) = value;
13960           /* Convert the overall back into its original type, if
13961              necessary, and return */
13962           if (JINTEGRAL_TYPE_P (op_type))
13963             return fold (node);
13964           else
13965             return fold (convert (op_type, node));
13966         }
13967       break;
13968
13969       /* 15.14.3 Unary Plus Operator + */
13970     case UNARY_PLUS_EXPR:
13971       /* 15.14.4 Unary Minus Operator - */
13972     case NEGATE_EXPR:
13973       if (!JNUMERIC_TYPE_P (op_type))
13974         {
13975           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
13976           TREE_TYPE (node) = error_mark_node;
13977           error_found = 1;
13978         }
13979       /* Unary numeric promotion is performed on operand */
13980       else
13981         {
13982           op = do_unary_numeric_promotion (op);
13983           prom_type = TREE_TYPE (op);
13984           if (code == UNARY_PLUS_EXPR)
13985             return fold (op);
13986         }
13987       break;
13988
13989       /* 15.14.5 Bitwise Complement Operator ~ */
13990     case BIT_NOT_EXPR:
13991       if (!JINTEGRAL_TYPE_P (op_type))
13992         {
13993           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
13994           TREE_TYPE (node) = error_mark_node;
13995           error_found = 1;
13996         }
13997       else
13998         {
13999           op = do_unary_numeric_promotion (op);
14000           prom_type = TREE_TYPE (op);
14001         }
14002       break;
14003
14004       /* 15.14.6 Logical Complement Operator ! */
14005     case TRUTH_NOT_EXPR:
14006       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
14007         {
14008           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
14009           /* But the type is known. We will report an error if further
14010              attempt of a assignment is made with this rhs */
14011           TREE_TYPE (node) = boolean_type_node;
14012           error_found = 1;
14013         }
14014       else
14015         prom_type = boolean_type_node;
14016       break;
14017
14018       /* 15.15 Cast Expression */
14019     case CONVERT_EXPR:
14020       value = patch_cast (node, wfl_operator);
14021       if (value == error_mark_node)
14022         {
14023           /* If this cast is part of an assignment, we tell the code
14024              that deals with it not to complain about a mismatch,
14025              because things have been cast, anyways */
14026           TREE_TYPE (node) = error_mark_node;
14027           error_found = 1;
14028         }
14029       else
14030         {
14031           value = fold (value);
14032           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
14033           return value;
14034         }
14035       break;
14036     }
14037   
14038   if (error_found)
14039     return error_mark_node;
14040
14041   /* There are cases where node has been replaced by something else
14042      and we don't end up returning here: UNARY_PLUS_EXPR,
14043      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
14044   TREE_OPERAND (node, 0) = fold (op);
14045   TREE_TYPE (node) = prom_type;
14046   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
14047   return fold (node);
14048 }
14049
14050 /* Generic type resolution that sometimes takes place during node
14051    patching. Returned the resolved type or generate an error
14052    message. Return the resolved type or NULL_TREE.  */
14053
14054 static tree
14055 resolve_type_during_patch (type)
14056      tree type;
14057 {
14058   if (unresolved_type_p (type, NULL))
14059     {
14060       tree type_decl = resolve_and_layout (EXPR_WFL_NODE (type), type);
14061       if (!type_decl)
14062         {
14063           parse_error_context (type, 
14064                                "Class `%s' not found in type declaration",
14065                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
14066           return NULL_TREE;
14067         }
14068       return TREE_TYPE (type_decl);
14069     }
14070   return type;
14071 }
14072 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
14073    found. Otherwise NODE or something meant to replace it is returned.  */
14074
14075 static tree
14076 patch_cast (node, wfl_op)
14077      tree node;
14078      tree wfl_op;
14079 {
14080   tree op = TREE_OPERAND (node, 0);
14081   tree op_type = TREE_TYPE (op);
14082   tree cast_type = TREE_TYPE (node);
14083   char *t1;
14084
14085   /* First resolve OP_TYPE if unresolved */
14086   if (!(cast_type = resolve_type_during_patch (cast_type)))
14087     return error_mark_node;
14088
14089   /* Check on cast that are proven correct at compile time */
14090   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
14091     {
14092       /* Same type */
14093       if (cast_type == op_type)
14094         return node;
14095
14096       /* float and double type are converted to the original type main
14097          variant and then to the target type. */
14098       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
14099         op = convert (integer_type_node, op);
14100
14101       /* Try widening/narowwing convertion. Potentially, things need
14102          to be worked out in gcc so we implement the extreme cases
14103          correctly. fold_convert() needs to be fixed. */
14104       return convert (cast_type, op);
14105     }
14106
14107   /* It's also valid to cast a boolean into a boolean */
14108   if (op_type == boolean_type_node && cast_type == boolean_type_node)
14109     return node;
14110
14111   /* null can be casted to references */
14112   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
14113     return build_null_of_type (cast_type);
14114
14115   /* The remaining legal casts involve conversion between reference
14116      types. Check for their compile time correctness. */
14117   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
14118       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
14119     {
14120       TREE_TYPE (node) = promote_type (cast_type);
14121       /* Now, the case can be determined correct at compile time if
14122          OP_TYPE can be converted into CAST_TYPE by assignment
14123          conversion (5.2) */
14124
14125       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
14126         {
14127           TREE_SET_CODE (node, NOP_EXPR);
14128           return node;
14129         }
14130
14131       if (flag_emit_class_files)
14132         {
14133           TREE_SET_CODE (node, CONVERT_EXPR);
14134           return node;
14135         }
14136
14137       /* The cast requires a run-time check */
14138       return build (CALL_EXPR, promote_type (cast_type),
14139                     build_address_of (soft_checkcast_node),
14140                     tree_cons (NULL_TREE, build_class_ref (cast_type),
14141                                build_tree_list (NULL_TREE, op)),
14142                     NULL_TREE);
14143     }
14144
14145   /* Any other casts are proven incorrect at compile time */
14146   t1 = xstrdup (lang_printable_name (op_type, 0));
14147   parse_error_context (wfl_op, "Invalid cast from `%s' to `%s'",
14148                        t1, lang_printable_name (cast_type, 0));
14149   free (t1);
14150   return error_mark_node;
14151 }
14152
14153 /* Build a null constant and give it the type TYPE.  */
14154
14155 static tree
14156 build_null_of_type (type)
14157      tree type;
14158 {
14159   tree node = build_int_2 (0, 0);
14160   TREE_TYPE (node) = promote_type (type);
14161   return node;
14162 }
14163
14164 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
14165    a list of indices. */
14166 static tree
14167 build_array_ref (location, array, index)
14168      int location;
14169      tree array, index;
14170 {
14171   tree node = build (ARRAY_REF, NULL_TREE, array, index);
14172   EXPR_WFL_LINECOL (node) = location;
14173   return node;
14174 }
14175
14176 /* 15.12 Array Access Expression */
14177
14178 static tree
14179 patch_array_ref (node)
14180      tree node;
14181 {
14182   tree array = TREE_OPERAND (node, 0);
14183   tree array_type  = TREE_TYPE (array);
14184   tree index = TREE_OPERAND (node, 1);
14185   tree index_type = TREE_TYPE (index);
14186   int error_found = 0;
14187
14188   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14189
14190   if (TREE_CODE (array_type) == POINTER_TYPE)
14191     array_type = TREE_TYPE (array_type);
14192
14193   /* The array reference must be an array */
14194   if (!TYPE_ARRAY_P (array_type))
14195     {
14196       parse_error_context 
14197         (wfl_operator,
14198          "`[]' can only be applied to arrays. It can't be applied to `%s'",
14199          lang_printable_name (array_type, 0));
14200       TREE_TYPE (node) = error_mark_node;
14201       error_found = 1;
14202     }
14203
14204   /* The array index undergoes unary numeric promotion. The promoted
14205      type must be int */
14206   index = do_unary_numeric_promotion (index);
14207   if (TREE_TYPE (index) != int_type_node)
14208     {
14209       if (valid_cast_to_p (index_type, int_type_node))
14210         parse_error_context (wfl_operator,
14211    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
14212                              lang_printable_name (index_type, 0));
14213       else
14214         parse_error_context (wfl_operator,
14215           "Incompatible type for `[]'. Can't convert `%s' to `int'",
14216                              lang_printable_name (index_type, 0));
14217       TREE_TYPE (node) = error_mark_node;
14218       error_found = 1;
14219     }
14220
14221   if (error_found)
14222     return error_mark_node;
14223
14224   array_type = TYPE_ARRAY_ELEMENT (array_type);
14225
14226   if (flag_emit_class_files || flag_emit_xref)
14227     {
14228       TREE_OPERAND (node, 0) = array;
14229       TREE_OPERAND (node, 1) = index;
14230     }
14231   else
14232     {
14233       /* The save_expr is for correct evaluation order.  It would be cleaner
14234          to use force_evaluation_order (see comment there), but that is
14235          difficult when we also have to deal with bounds checking. */
14236       if (TREE_SIDE_EFFECTS (index))
14237         array = save_expr (array);
14238       node = build_java_arrayaccess (array, array_type, index);
14239       if (TREE_SIDE_EFFECTS (index))
14240         node = build (COMPOUND_EXPR, array_type, array, node);
14241     }
14242   TREE_TYPE (node) = array_type;
14243   return node;
14244 }
14245
14246 /* 15.9 Array Creation Expressions */
14247
14248 static tree
14249 build_newarray_node (type, dims, extra_dims)
14250      tree type;
14251      tree dims;
14252      int extra_dims;
14253 {
14254   tree node =
14255     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
14256            build_int_2 (extra_dims, 0));
14257   return node;
14258 }
14259
14260 static tree
14261 patch_newarray (node)
14262      tree node;
14263 {
14264   tree type = TREE_OPERAND (node, 0);
14265   tree dims = TREE_OPERAND (node, 1);
14266   tree cdim, array_type;
14267   int error_found = 0;
14268   int ndims = 0;
14269   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
14270
14271   /* Dimension types are verified. It's better for the types to be
14272      verified in order. */
14273   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
14274     {
14275       int dim_error = 0;
14276       tree dim = TREE_VALUE (cdim);
14277
14278       /* Dim might have been saved during its evaluation */
14279       dim = (TREE_CODE (dim) == SAVE_EXPR ? TREE_OPERAND (dim, 0) : dim);
14280
14281       /* The type of each specified dimension must be an integral type. */
14282       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
14283         dim_error = 1;
14284
14285       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
14286          promoted type must be int. */
14287       else
14288         {
14289           dim = do_unary_numeric_promotion (dim);
14290           if (TREE_TYPE (dim) != int_type_node)
14291             dim_error = 1;
14292         }
14293
14294       /* Report errors on types here */
14295       if (dim_error)
14296         {
14297           parse_error_context 
14298             (TREE_PURPOSE (cdim), 
14299              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
14300              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
14301               "Explicit cast needed to" : "Can't"),
14302              lang_printable_name (TREE_TYPE (dim), 0));
14303           error_found = 1;
14304         }
14305
14306       TREE_PURPOSE (cdim) = NULL_TREE;
14307     }
14308
14309   /* Resolve array base type if unresolved */
14310   if (!(type = resolve_type_during_patch (type)))
14311     error_found = 1;
14312
14313   if (error_found)
14314     {
14315       /* We don't want further evaluation of this bogus array creation
14316          operation */
14317       TREE_TYPE (node) = error_mark_node;
14318       return error_mark_node;
14319     }
14320
14321   /* Set array_type to the actual (promoted) array type of the result. */
14322   if (TREE_CODE (type) == RECORD_TYPE)
14323     type = build_pointer_type (type);
14324   while (--xdims >= 0)
14325     {
14326       type = promote_type (build_java_array_type (type, -1));
14327     }
14328   dims = nreverse (dims);
14329   array_type = type;
14330   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
14331     {
14332       type = array_type;
14333       array_type
14334         = build_java_array_type (type,
14335                                  TREE_CODE (cdim) == INTEGER_CST
14336                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
14337                                  : -1);
14338       array_type = promote_type (array_type);
14339     }
14340   dims = nreverse (dims);
14341
14342   /* The node is transformed into a function call. Things are done
14343      differently according to the number of dimensions. If the number
14344      of dimension is equal to 1, then the nature of the base type
14345      (primitive or not) matters. */
14346   if (ndims == 1)
14347     return build_new_array (type, TREE_VALUE (dims));
14348   
14349   /* Can't reuse what's already written in expr.c because it uses the
14350      JVM stack representation. Provide a build_multianewarray. FIXME */
14351   return build (CALL_EXPR, array_type,
14352                 build_address_of (soft_multianewarray_node),
14353                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
14354                            tree_cons (NULL_TREE, 
14355                                       build_int_2 (ndims, 0), dims )),
14356                 NULL_TREE);
14357 }
14358
14359 /* 10.6 Array initializer.  */
14360
14361 /* Build a wfl for array element that don't have one, so we can
14362    pin-point errors.  */
14363
14364 static tree
14365 maybe_build_array_element_wfl (node)
14366      tree node;
14367 {
14368   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
14369     return build_expr_wfl (NULL_TREE, ctxp->filename,
14370                            ctxp->elc.line, ctxp->elc.prev_col);
14371   else
14372     return NULL_TREE;
14373 }
14374
14375 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
14376    identification of initialized arrays easier to detect during walk
14377    and expansion.  */
14378
14379 static tree
14380 build_new_array_init (location, values)
14381      int location;
14382      tree values;
14383 {
14384   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
14385   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
14386   EXPR_WFL_LINECOL (to_return) = location;
14387   return to_return;
14388 }
14389
14390 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
14391    occurred.  Otherwise return NODE after having set its type
14392    appropriately.  */
14393
14394 static tree
14395 patch_new_array_init (type, node)
14396      tree type, node;
14397 {
14398   int error_seen = 0;
14399   tree current, element_type;
14400   HOST_WIDE_INT length;
14401   int all_constant = 1;
14402   tree init = TREE_OPERAND (node, 0);
14403
14404   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
14405     {
14406       parse_error_context (node,
14407                            "Invalid array initializer for non-array type `%s'",
14408                            lang_printable_name (type, 1));
14409       return error_mark_node;
14410     }
14411   type = TREE_TYPE (type);
14412   element_type = TYPE_ARRAY_ELEMENT (type);
14413
14414   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
14415
14416   for (length = 0, current = CONSTRUCTOR_ELTS (init);
14417        current;  length++, current = TREE_CHAIN (current))
14418     {
14419       tree elt = TREE_VALUE (current);
14420       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
14421         {
14422           error_seen |= array_constructor_check_entry (element_type, current);
14423           elt = TREE_VALUE (current);
14424           /* When compiling to native code, STRING_CST is converted to
14425              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
14426           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
14427             all_constant = 0;
14428         }
14429       else
14430         {
14431           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
14432           TREE_PURPOSE (current) = NULL_TREE;
14433           all_constant = 0;
14434         }
14435       if (elt && TREE_CODE (elt) == TREE_LIST 
14436           && TREE_VALUE (elt) == error_mark_node)
14437         error_seen = 1;
14438     }
14439
14440   if (error_seen)
14441     return error_mark_node;
14442
14443   /* Create a new type. We can't reuse the one we have here by
14444      patching its dimension because it originally is of dimension -1
14445      hence reused by gcc. This would prevent triangular arrays. */
14446   type = build_java_array_type (element_type, length);
14447   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
14448   TREE_TYPE (node) = promote_type (type);
14449   TREE_CONSTANT (init) = all_constant;
14450   TREE_CONSTANT (node) = all_constant;
14451   return node;
14452 }
14453
14454 /* Verify that one entry of the initializer element list can be
14455    assigned to the array base type. Report 1 if an error occurred, 0
14456    otherwise.  */
14457
14458 static int
14459 array_constructor_check_entry (type, entry)
14460      tree type, entry;
14461 {
14462   char *array_type_string = NULL;       /* For error reports */
14463   tree value, type_value, new_value, wfl_value, patched;
14464   int error_seen = 0;
14465
14466   new_value = NULL_TREE;
14467   wfl_value = TREE_VALUE (entry);
14468
14469   value = java_complete_tree (TREE_VALUE (entry));
14470   /* patch_string return error_mark_node if arg is error_mark_node */
14471   if ((patched = patch_string (value)))
14472     value = patched;
14473   if (value == error_mark_node)
14474     return 1;
14475   
14476   type_value = TREE_TYPE (value);
14477   
14478   /* At anytime, try_builtin_assignconv can report a warning on
14479      constant overflow during narrowing. */
14480   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
14481   new_value = try_builtin_assignconv (wfl_operator, type, value);
14482   if (!new_value && (new_value = try_reference_assignconv (type, value)))
14483     type_value = promote_type (type);
14484
14485   /* Check and report errors */
14486   if (!new_value)
14487     {
14488       const char *msg = (!valid_cast_to_p (type_value, type) ?
14489                    "Can't" : "Explicit cast needed to");
14490       if (!array_type_string)
14491         array_type_string = xstrdup (lang_printable_name (type, 1));
14492       parse_error_context 
14493         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
14494          msg, lang_printable_name (type_value, 1), array_type_string);
14495       error_seen = 1;
14496     }
14497   
14498   if (new_value)
14499     {
14500       new_value = maybe_build_primttype_type_ref (new_value, wfl_value);
14501       TREE_VALUE (entry) = new_value;
14502     }
14503
14504   if (array_type_string)
14505     free (array_type_string);
14506
14507   TREE_PURPOSE (entry) = NULL_TREE;
14508   return error_seen;
14509 }
14510
14511 static tree
14512 build_this (location)
14513      int location;
14514 {
14515   tree node = build_wfl_node (this_identifier_node);
14516   TREE_SET_CODE (node, THIS_EXPR);
14517   EXPR_WFL_LINECOL (node) = location;
14518   return node;
14519 }
14520
14521 /* 14.15 The return statement. It builds a modify expression that
14522    assigns the returned value to the RESULT_DECL that hold the value
14523    to be returned. */
14524
14525 static tree
14526 build_return (location, op)
14527      int location;
14528      tree op;
14529 {
14530   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
14531   EXPR_WFL_LINECOL (node) = location;
14532   node = build_debugable_stmt (location, node);
14533   return node;
14534 }
14535
14536 static tree
14537 patch_return (node)
14538      tree node;
14539 {
14540   tree return_exp = TREE_OPERAND (node, 0);
14541   tree meth = current_function_decl;
14542   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
14543   int error_found = 0;
14544
14545   TREE_TYPE (node) = error_mark_node;
14546   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14547
14548   /* It's invalid to have a return value within a function that is
14549      declared with the keyword void or that is a constructor */
14550   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
14551     error_found = 1;
14552
14553   /* It's invalid to use a return statement in a static block */
14554   if (DECL_CLINIT_P (current_function_decl))
14555     error_found = 1;
14556
14557   /* It's invalid to have a no return value within a function that
14558      isn't declared with the keyword `void' */
14559   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
14560     error_found = 2;
14561   
14562   if (in_instance_initializer)
14563     error_found = 1;
14564
14565   if (error_found)
14566     {
14567       if (in_instance_initializer)
14568         parse_error_context (wfl_operator,
14569                              "`return' inside instance initializer");
14570         
14571       else if (DECL_CLINIT_P (current_function_decl))
14572         parse_error_context (wfl_operator,
14573                              "`return' inside static initializer");
14574
14575       else if (!DECL_CONSTRUCTOR_P (meth))
14576         {
14577           char *t = xstrdup (lang_printable_name (mtype, 0));
14578           parse_error_context (wfl_operator, 
14579                                "`return' with%s value from `%s %s'",
14580                                (error_found == 1 ? "" : "out"), 
14581                                t, lang_printable_name (meth, 0));
14582           free (t);
14583         }
14584       else
14585         parse_error_context (wfl_operator, 
14586                              "`return' with value from constructor `%s'",
14587                              lang_printable_name (meth, 0));
14588       return error_mark_node;
14589     }
14590
14591   /* If we have a return_exp, build a modify expression and expand
14592      it. Note: at that point, the assignment is declared valid, but we
14593      may want to carry some more hacks */
14594   if (return_exp)
14595     {
14596       tree exp = java_complete_tree (return_exp);
14597       tree modify, patched;
14598
14599       /* If the function returned value and EXP are booleans, EXP has
14600       to be converted into the type of DECL_RESULT, which is integer
14601       (see complete_start_java_method) */
14602       if (TREE_TYPE (exp) == boolean_type_node &&
14603           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
14604         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
14605
14606       /* `null' can be assigned to a function returning a reference */
14607       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
14608           exp == null_pointer_node)
14609         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
14610
14611       if ((patched = patch_string (exp)))
14612         exp = patched;
14613       
14614       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
14615       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
14616       modify = java_complete_tree (modify);
14617
14618       if (modify != error_mark_node)
14619         {
14620           TREE_SIDE_EFFECTS (modify) = 1;
14621           TREE_OPERAND (node, 0) = modify;
14622         }
14623       else
14624         return error_mark_node;
14625     }
14626   TREE_TYPE (node) = void_type_node;
14627   TREE_SIDE_EFFECTS (node) = 1;
14628   return node;
14629 }
14630
14631 /* 14.8 The if Statement */
14632
14633 static tree
14634 build_if_else_statement (location, expression, if_body, else_body)
14635      int location;
14636      tree expression, if_body, else_body;
14637 {
14638   tree node;
14639   if (!else_body)
14640     else_body = empty_stmt_node;
14641   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
14642   EXPR_WFL_LINECOL (node) = location;
14643   node = build_debugable_stmt (location, node);
14644   return node;
14645 }
14646
14647 static tree
14648 patch_if_else_statement (node)
14649      tree node;
14650 {
14651   tree expression = TREE_OPERAND (node, 0);
14652
14653   TREE_TYPE (node) = error_mark_node;
14654   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14655
14656   /* The type of expression must be boolean */
14657   if (TREE_TYPE (expression) != boolean_type_node
14658       && TREE_TYPE (expression) != promoted_boolean_type_node)
14659     {
14660       parse_error_context 
14661         (wfl_operator, 
14662          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
14663          lang_printable_name (TREE_TYPE (expression), 0));
14664       return error_mark_node;
14665     }
14666   
14667   TREE_TYPE (node) = void_type_node;
14668   TREE_SIDE_EFFECTS (node) = 1;
14669   CAN_COMPLETE_NORMALLY (node)
14670     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
14671     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
14672   return node;
14673 }
14674
14675 /* 14.6 Labeled Statements */
14676
14677 /* Action taken when a lableled statement is parsed. a new
14678    LABELED_BLOCK_EXPR is created. No statement is attached to the
14679    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
14680
14681 static tree
14682 build_labeled_block (location, label)
14683      int location;
14684      tree label;
14685 {
14686   tree label_name ;
14687   tree label_decl, node;
14688   if (label == NULL_TREE || label == continue_identifier_node)
14689     label_name = label;
14690   else
14691     {
14692       label_name = merge_qualified_name (label_id, label);
14693       /* Issue an error if we try to reuse a label that was previously
14694          declared */
14695       if (IDENTIFIER_LOCAL_VALUE (label_name))
14696         {
14697           EXPR_WFL_LINECOL (wfl_operator) = location;
14698           parse_error_context (wfl_operator,
14699             "Declaration of `%s' shadows a previous label declaration",
14700                                IDENTIFIER_POINTER (label));
14701           EXPR_WFL_LINECOL (wfl_operator) = 
14702             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
14703           parse_error_context (wfl_operator,
14704             "This is the location of the previous declaration of label `%s'",
14705                                IDENTIFIER_POINTER (label));
14706           java_error_count--;
14707         }
14708     }
14709
14710   label_decl = create_label_decl (label_name);
14711   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
14712   EXPR_WFL_LINECOL (node) = location;
14713   TREE_SIDE_EFFECTS (node) = 1;
14714   return node;
14715 }
14716
14717 /* A labeled statement LBE is attached a statement.  */
14718
14719 static tree
14720 finish_labeled_statement (lbe, statement)
14721      tree lbe;                  /* Labeled block expr */
14722      tree statement;
14723 {
14724   /* In anyways, tie the loop to its statement */
14725   LABELED_BLOCK_BODY (lbe) = statement;
14726   pop_labeled_block ();
14727   POP_LABELED_BLOCK ();
14728   return lbe;
14729 }
14730
14731 /* 14.10, 14.11, 14.12 Loop Statements */
14732
14733 /* Create an empty LOOP_EXPR and make it the last in the nested loop
14734    list. */
14735
14736 static tree
14737 build_new_loop (loop_body)
14738      tree loop_body;
14739 {
14740   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
14741   TREE_SIDE_EFFECTS (loop) = 1;
14742   PUSH_LOOP (loop);
14743   return loop;
14744 }
14745
14746 /* Create a loop body according to the following structure:
14747      COMPOUND_EXPR
14748        COMPOUND_EXPR            (loop main body)
14749          EXIT_EXPR              (this order is for while/for loops.
14750          LABELED_BLOCK_EXPR      the order is reversed for do loops)
14751            LABEL_DECL           (a continue occuring here branches at the 
14752            BODY                  end of this labeled block)
14753        INCREMENT                (if any)
14754
14755   REVERSED, if non zero, tells that the loop condition expr comes
14756   after the body, like in the do-while loop.
14757
14758   To obtain a loop, the loop body structure described above is
14759   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
14760
14761    LABELED_BLOCK_EXPR
14762      LABEL_DECL                   (use this label to exit the loop)
14763      LOOP_EXPR
14764        <structure described above> */
14765
14766 static tree
14767 build_loop_body (location, condition, reversed)
14768      int location;
14769      tree condition;
14770      int reversed;
14771 {
14772   tree first, second, body;
14773
14774   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
14775   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
14776   condition = build_debugable_stmt (location, condition);
14777   TREE_SIDE_EFFECTS (condition) = 1;
14778
14779   body = build_labeled_block (0, continue_identifier_node);
14780   first = (reversed ? body : condition);
14781   second = (reversed ? condition : body);
14782   return 
14783     build (COMPOUND_EXPR, NULL_TREE, 
14784            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
14785 }
14786
14787 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
14788    their order) on the current loop. Unlink the current loop from the
14789    loop list.  */
14790
14791 static tree
14792 finish_loop_body (location, condition, body, reversed)
14793      int location;
14794      tree condition, body;
14795      int reversed;
14796 {
14797   tree to_return = ctxp->current_loop;
14798   tree loop_body = LOOP_EXPR_BODY (to_return);
14799   if (condition)
14800     {
14801       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
14802       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
14803          The real EXIT_EXPR is one operand further. */
14804       EXPR_WFL_LINECOL (cnode) = location;
14805       /* This one is for accurate error reports */
14806       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
14807       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
14808     }
14809   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
14810   POP_LOOP ();
14811   return to_return;
14812 }
14813
14814 /* Tailored version of finish_loop_body for FOR loops, when FOR
14815    loops feature the condition part */
14816
14817 static tree
14818 finish_for_loop (location, condition, update, body)
14819     int location;
14820     tree condition, update, body;
14821 {
14822   /* Put the condition and the loop body in place */
14823   tree loop = finish_loop_body (location, condition, body, 0);
14824   /* LOOP is the current loop which has been now popped of the loop
14825      stack. Install the update block */
14826   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
14827   return loop;
14828 }
14829
14830 /* Try to find the loop a block might be related to. This comprises
14831    the case where the LOOP_EXPR is found as the second operand of a
14832    COMPOUND_EXPR, because the loop happens to have an initialization
14833    part, then expressed as the first operand of the COMPOUND_EXPR. If
14834    the search finds something, 1 is returned. Otherwise, 0 is
14835    returned. The search is assumed to start from a
14836    LABELED_BLOCK_EXPR's block.  */
14837
14838 static tree
14839 search_loop (statement)
14840     tree statement;
14841 {
14842   if (TREE_CODE (statement) == LOOP_EXPR)
14843     return statement;
14844
14845   if (TREE_CODE (statement) == BLOCK)
14846     statement = BLOCK_SUBBLOCKS (statement);
14847   else
14848     return NULL_TREE;
14849
14850   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14851     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14852       statement = TREE_OPERAND (statement, 1);
14853
14854   return (TREE_CODE (statement) == LOOP_EXPR
14855           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
14856 }
14857
14858 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
14859    returned otherwise.  */
14860
14861 static int
14862 labeled_block_contains_loop_p (block, loop)
14863     tree block, loop;
14864 {
14865   if (!block)
14866     return 0;
14867
14868   if (LABELED_BLOCK_BODY (block) == loop)
14869     return 1;
14870
14871   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
14872     return 1;
14873
14874   return 0;
14875 }
14876
14877 /* If the loop isn't surrounded by a labeled statement, create one and
14878    insert LOOP as its body.  */
14879
14880 static tree
14881 patch_loop_statement (loop)
14882      tree loop;
14883 {
14884   tree loop_label;
14885
14886   TREE_TYPE (loop) = void_type_node;
14887   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
14888     return loop;
14889
14890   loop_label = build_labeled_block (0, NULL_TREE);
14891   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
14892      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
14893   LABELED_BLOCK_BODY (loop_label) = loop;
14894   PUSH_LABELED_BLOCK (loop_label);
14895   return loop_label;
14896 }
14897
14898 /* 14.13, 14.14: break and continue Statements */
14899
14900 /* Build a break or a continue statement. a null NAME indicates an
14901    unlabeled break/continue statement.  */
14902
14903 static tree
14904 build_bc_statement (location, is_break, name)
14905      int location, is_break;
14906      tree name;
14907 {
14908   tree break_continue, label_block_expr = NULL_TREE;
14909
14910   if (name)
14911     {
14912       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
14913             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
14914         /* Null means that we don't have a target for this named
14915            break/continue. In this case, we make the target to be the
14916            label name, so that the error can be reported accuratly in
14917            patch_bc_statement. */
14918         label_block_expr = EXPR_WFL_NODE (name);
14919     }
14920   /* Unlabeled break/continue will be handled during the
14921      break/continue patch operation */
14922   break_continue 
14923     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
14924
14925   IS_BREAK_STMT_P (break_continue) = is_break;
14926   TREE_SIDE_EFFECTS (break_continue) = 1;
14927   EXPR_WFL_LINECOL (break_continue) = location;
14928   break_continue = build_debugable_stmt (location, break_continue);
14929   return break_continue;
14930 }
14931
14932 /* Verification of a break/continue statement. */
14933
14934 static tree
14935 patch_bc_statement (node)
14936      tree node;
14937 {
14938   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
14939   tree labeled_block = ctxp->current_labeled_block;
14940   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14941  
14942   /* Having an identifier here means that the target is unknown. */
14943   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
14944     {
14945       parse_error_context (wfl_operator, "No label definition found for `%s'",
14946                            IDENTIFIER_POINTER (bc_label));
14947       return error_mark_node;
14948     }
14949   if (! IS_BREAK_STMT_P (node))
14950     {
14951       /* It's a continue statement. */
14952       for (;; labeled_block = TREE_CHAIN (labeled_block))
14953         {
14954           if (labeled_block == NULL_TREE)
14955             {
14956               if (bc_label == NULL_TREE)
14957                 parse_error_context (wfl_operator,
14958                                      "`continue' must be in loop");
14959               else
14960                 parse_error_context 
14961                   (wfl_operator, "continue label `%s' does not name a loop",
14962                    IDENTIFIER_POINTER (bc_label));
14963               return error_mark_node;
14964             }
14965           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
14966                == continue_identifier_node)
14967               && (bc_label == NULL_TREE
14968                   || TREE_CHAIN (labeled_block) == bc_label))
14969             {
14970               bc_label = labeled_block;
14971               break;
14972             }
14973         }
14974     }
14975   else if (!bc_label)
14976     { 
14977       for (;; labeled_block = TREE_CHAIN (labeled_block))
14978         {
14979           if (labeled_block == NULL_TREE)
14980             {
14981               parse_error_context (wfl_operator,
14982                                      "`break' must be in loop or switch");
14983               return error_mark_node;
14984             }
14985           target_stmt = LABELED_BLOCK_BODY (labeled_block);
14986           if (TREE_CODE (target_stmt) == SWITCH_EXPR
14987               || search_loop (target_stmt))
14988             {
14989               bc_label = labeled_block;
14990               break;
14991             }
14992         }
14993     }
14994
14995   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
14996   CAN_COMPLETE_NORMALLY (bc_label) = 1;
14997
14998   /* Our break/continue don't return values. */
14999   TREE_TYPE (node) = void_type_node;
15000   /* Encapsulate the break within a compound statement so that it's
15001      expanded all the times by expand_expr (and not clobbered
15002      sometimes, like after a if statement) */
15003   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
15004   TREE_SIDE_EFFECTS (node) = 1;
15005   return node;
15006 }
15007
15008 /* Process the exit expression belonging to a loop. Its type must be
15009    boolean.  */
15010
15011 static tree
15012 patch_exit_expr (node)
15013      tree node;
15014 {
15015   tree expression = TREE_OPERAND (node, 0);
15016   TREE_TYPE (node) = error_mark_node;
15017   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15018
15019   /* The type of expression must be boolean */
15020   if (TREE_TYPE (expression) != boolean_type_node)
15021     {
15022       parse_error_context 
15023         (wfl_operator, 
15024     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
15025          lang_printable_name (TREE_TYPE (expression), 0));
15026       return error_mark_node;
15027     }
15028   /* Now we know things are allright, invert the condition, fold and
15029      return */
15030   TREE_OPERAND (node, 0) = 
15031     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
15032
15033   if (! integer_zerop (TREE_OPERAND (node, 0))
15034       && ctxp->current_loop != NULL_TREE
15035       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
15036     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
15037   if (! integer_onep (TREE_OPERAND (node, 0)))
15038     CAN_COMPLETE_NORMALLY (node) = 1;
15039
15040
15041   TREE_TYPE (node) = void_type_node;
15042   return node;
15043 }
15044
15045 /* 14.9 Switch statement */
15046
15047 static tree
15048 patch_switch_statement (node)
15049      tree node;
15050 {
15051   tree se = TREE_OPERAND (node, 0), se_type;
15052
15053   /* Complete the switch expression */
15054   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
15055   se_type = TREE_TYPE (se);
15056   /* The type of the switch expression must be char, byte, short or
15057      int */
15058   if (! JINTEGRAL_TYPE_P (se_type) || se_type == long_type_node)
15059     {
15060       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15061       parse_error_context (wfl_operator,
15062           "Incompatible type for `switch'. Can't convert `%s' to `int'",
15063                            lang_printable_name (se_type, 0));
15064       /* This is what java_complete_tree will check */
15065       TREE_OPERAND (node, 0) = error_mark_node;
15066       return error_mark_node;
15067     }
15068
15069   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
15070
15071   /* Ready to return */
15072   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
15073     {
15074       TREE_TYPE (node) = error_mark_node;
15075       return error_mark_node;
15076     }
15077   TREE_TYPE (node) = void_type_node;
15078   TREE_SIDE_EFFECTS (node) = 1;
15079   CAN_COMPLETE_NORMALLY (node)
15080     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
15081       || ! SWITCH_HAS_DEFAULT (node);
15082   return node;
15083 }
15084
15085 /* 14.18 The try/catch statements */
15086
15087 static tree
15088 build_try_statement (location, try_block, catches)
15089      int location;
15090      tree try_block, catches;
15091 {
15092   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
15093   EXPR_WFL_LINECOL (node) = location;
15094   return node;
15095 }
15096
15097 static tree
15098 build_try_finally_statement (location, try_block, finally)
15099      int location;
15100      tree try_block, finally;
15101 {
15102   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
15103   EXPR_WFL_LINECOL (node) = location;
15104   return node;
15105 }
15106
15107 static tree
15108 patch_try_statement (node)
15109      tree node;
15110 {
15111   int error_found = 0;
15112   tree try = TREE_OPERAND (node, 0);
15113   /* Exception handlers are considered in left to right order */
15114   tree catch = nreverse (TREE_OPERAND (node, 1));
15115   tree current, caught_type_list = NULL_TREE;
15116
15117   /* Check catch clauses, if any. Every time we find an error, we try
15118      to process the next catch clause. We process the catch clause before
15119      the try block so that when processing the try block we can check thrown
15120      exceptions againts the caught type list. */
15121   for (current = catch; current; current = TREE_CHAIN (current))
15122     {
15123       tree carg_decl, carg_type;
15124       tree sub_current, catch_block, catch_clause;
15125       int unreachable;
15126
15127       /* At this point, the structure of the catch clause is
15128            CATCH_EXPR           (catch node)
15129              BLOCK              (with the decl of the parameter)
15130                COMPOUND_EXPR
15131                  MODIFY_EXPR   (assignment of the catch parameter)
15132                  BLOCK          (catch clause block)
15133        */
15134       catch_clause = TREE_OPERAND (current, 0);
15135       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
15136       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
15137
15138       /* Catch clauses can't have more than one parameter declared,
15139          but it's already enforced by the grammar. Make sure that the
15140          only parameter of the clause statement in of class Throwable
15141          or a subclass of Throwable, but that was done earlier. The
15142          catch clause parameter type has also been resolved. */
15143       
15144       /* Just make sure that the catch clause parameter type inherits
15145          from java.lang.Throwable */
15146       if (!inherits_from_p (carg_type, throwable_type_node))
15147         {
15148           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15149           parse_error_context (wfl_operator,
15150                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
15151                                lang_printable_name (carg_type, 0));
15152           error_found = 1;
15153           continue;
15154         }
15155       
15156       /* Partial check for unreachable catch statement: The catch
15157          clause is reachable iff is no earlier catch block A in
15158          the try statement such that the type of the catch
15159          clause's parameter is the same as or a subclass of the
15160          type of A's parameter */
15161       unreachable = 0;
15162       for (sub_current = catch;
15163            sub_current != current; sub_current = TREE_CHAIN (sub_current))
15164         {
15165           tree sub_catch_clause, decl;
15166           sub_catch_clause = TREE_OPERAND (sub_current, 0);
15167           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
15168
15169           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
15170             {
15171               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15172               parse_error_context 
15173                 (wfl_operator,
15174                  "`catch' not reached because of the catch clause at line %d",
15175                  EXPR_WFL_LINENO (sub_current));
15176               unreachable = error_found = 1;
15177               break;
15178             }
15179         }
15180       /* Complete the catch clause block */
15181       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
15182       if (catch_block == error_mark_node)
15183         {
15184           error_found = 1;
15185           continue;
15186         }
15187       if (CAN_COMPLETE_NORMALLY (catch_block))
15188         CAN_COMPLETE_NORMALLY (node) = 1;
15189       TREE_OPERAND (current, 0) = catch_block;
15190
15191       if (unreachable)
15192         continue;
15193
15194       /* Things to do here: the exception must be thrown */
15195
15196       /* Link this type to the caught type list */
15197       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
15198     }
15199
15200   PUSH_EXCEPTIONS (caught_type_list);
15201   if ((try = java_complete_tree (try)) == error_mark_node)
15202     error_found = 1;
15203   if (CAN_COMPLETE_NORMALLY (try))
15204     CAN_COMPLETE_NORMALLY (node) = 1;
15205   POP_EXCEPTIONS ();
15206
15207   /* Verification ends here */
15208   if (error_found) 
15209     return error_mark_node;
15210
15211   TREE_OPERAND (node, 0) = try;
15212   TREE_OPERAND (node, 1) = catch;
15213   TREE_TYPE (node) = void_type_node;
15214   return node;
15215 }
15216
15217 /* 14.17 The synchronized Statement */
15218
15219 static tree
15220 patch_synchronized_statement (node, wfl_op1)
15221     tree node, wfl_op1;
15222 {
15223   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
15224   tree block = TREE_OPERAND (node, 1);
15225
15226   tree tmp, enter, exit, expr_decl, assignment;
15227
15228   if (expr == error_mark_node)
15229     {
15230       block = java_complete_tree (block);
15231       return expr;
15232     }
15233
15234   /* We might be trying to synchronize on a STRING_CST */
15235   if ((tmp = patch_string (expr)))
15236     expr = tmp;
15237
15238   /* The TYPE of expr must be a reference type */
15239   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
15240     {
15241       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15242       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
15243                            lang_printable_name (TREE_TYPE (expr), 0));
15244       return error_mark_node;
15245     }
15246
15247   if (flag_emit_xref)
15248     {
15249       TREE_OPERAND (node, 0) = expr;
15250       TREE_OPERAND (node, 1) = java_complete_tree (block);
15251       CAN_COMPLETE_NORMALLY (node) = 1;
15252       return node;
15253     }
15254
15255   /* Generate a try-finally for the synchronized statement, except
15256      that the handler that catches all throw exception calls
15257      _Jv_MonitorExit and then rethrow the exception.
15258      The synchronized statement is then implemented as:
15259      TRY 
15260        {
15261          _Jv_MonitorEnter (expression)
15262          synchronized_block
15263          _Jv_MonitorExit (expression)
15264        }
15265      CATCH_ALL
15266        {
15267          e = _Jv_exception_info ();
15268          _Jv_MonitorExit (expression)
15269          Throw (e);
15270        } */
15271
15272   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
15273   BUILD_MONITOR_ENTER (enter, expr_decl);
15274   BUILD_MONITOR_EXIT (exit, expr_decl);
15275   CAN_COMPLETE_NORMALLY (enter) = 1;
15276   CAN_COMPLETE_NORMALLY (exit) = 1;
15277   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
15278   TREE_SIDE_EFFECTS (assignment) = 1;
15279   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
15280                  build (COMPOUND_EXPR, NULL_TREE,
15281                         build (WITH_CLEANUP_EXPR, NULL_TREE,
15282                                build (COMPOUND_EXPR, NULL_TREE,
15283                                       assignment, enter),
15284                                NULL_TREE, exit),
15285                         block));
15286   node = build_expr_block (node, expr_decl);
15287
15288   return java_complete_tree (node);
15289 }
15290
15291 /* 14.16 The throw Statement */
15292
15293 static tree
15294 patch_throw_statement (node, wfl_op1)
15295     tree node, wfl_op1;
15296 {
15297   tree expr = TREE_OPERAND (node, 0);
15298   tree type = TREE_TYPE (expr);
15299   int unchecked_ok = 0, tryblock_throws_ok = 0;
15300
15301   /* Thrown expression must be assignable to java.lang.Throwable */
15302   if (!try_reference_assignconv (throwable_type_node, expr))
15303     {
15304       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15305       parse_error_context (wfl_operator,
15306     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
15307                            lang_printable_name (type, 0));
15308       /* If the thrown expression was a reference, we further the
15309          compile-time check. */
15310       if (!JREFERENCE_TYPE_P (type))
15311         return error_mark_node;
15312     }
15313
15314   /* At least one of the following must be true */
15315
15316   /* The type of the throw expression is a not checked exception,
15317      i.e. is a unchecked expression. */
15318   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
15319
15320   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15321   /* An instance can't throw a checked excetion unless that exception
15322      is explicitely declared in the `throws' clause of each
15323      constructor. This doesn't apply to anonymous classes, since they
15324      don't have declared constructors. */
15325   if (!unchecked_ok 
15326       && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
15327     {
15328       tree current;
15329       for (current = TYPE_METHODS (current_class); current; 
15330            current = TREE_CHAIN (current))
15331         if (DECL_CONSTRUCTOR_P (current) 
15332             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
15333           {
15334             parse_error_context (wfl_operator, "Checked exception `%s' can't be thrown in instance initializer (not all declared constructor are declaring it in their `throws' clause)", 
15335                                  lang_printable_name (TREE_TYPE (expr), 0));
15336             return error_mark_node;
15337           }
15338     }
15339
15340   /* Throw is contained in a try statement and at least one catch
15341      clause can receive the thrown expression or the current method is
15342      declared to throw such an exception. Or, the throw statement is
15343      contained in a method or constructor declaration and the type of
15344      the Expression is assignable to at least one type listed in the
15345      throws clause the declaration. */
15346   if (!unchecked_ok)
15347     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
15348   if (!(unchecked_ok || tryblock_throws_ok))
15349     {
15350       /* If there is a surrounding try block that has no matching
15351          clatch clause, report it first. A surrounding try block exits
15352          only if there is something after the list of checked
15353          exception thrown by the current function (if any). */
15354       if (IN_TRY_BLOCK_P ())
15355         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
15356                              lang_printable_name (type, 0));
15357       /* If we have no surrounding try statement and the method doesn't have
15358          any throws, report it now. FIXME */
15359
15360       /* We report that the exception can't be throw from a try block
15361          in all circumstances but when the `throw' is inside a static
15362          block. */
15363       else if (!EXCEPTIONS_P (currently_caught_type_list) 
15364                && !tryblock_throws_ok)
15365         {
15366           if (DECL_CLINIT_P (current_function_decl))
15367             parse_error_context (wfl_operator,
15368                    "Checked exception `%s' can't be thrown in initializer",
15369                                  lang_printable_name (type, 0));
15370           else
15371             parse_error_context (wfl_operator,
15372                    "Checked exception `%s' isn't thrown from a `try' block", 
15373                                  lang_printable_name (type, 0));
15374         }
15375       /* Otherwise, the current method doesn't have the appropriate
15376          throws declaration */
15377       else
15378         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
15379                              lang_printable_name (type, 0));
15380       return error_mark_node;
15381     }
15382
15383   if (! flag_emit_class_files && ! flag_emit_xref)
15384     BUILD_THROW (node, expr);
15385
15386   /* If doing xrefs, keep the location where the `throw' was seen. */
15387   if (flag_emit_xref)
15388     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
15389   return node;
15390 }
15391
15392 /* Check that exception said to be thrown by method DECL can be
15393    effectively caught from where DECL is invoked.  */
15394
15395 static void
15396 check_thrown_exceptions (location, decl)
15397      int location;
15398      tree decl;
15399 {
15400   tree throws;
15401   /* For all the unchecked exceptions thrown by DECL */
15402   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
15403        throws = TREE_CHAIN (throws)) 
15404     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
15405       {
15406 #if 1
15407         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
15408         if (DECL_NAME (decl) == get_identifier ("clone"))
15409           continue;
15410 #endif
15411         EXPR_WFL_LINECOL (wfl_operator) = location;
15412         if (DECL_FINIT_P (current_function_decl))
15413           parse_error_context
15414             (wfl_operator, "Exception `%s' can't be thrown in initializer",
15415              lang_printable_name (TREE_VALUE (throws), 0));
15416         else 
15417           {
15418             parse_error_context 
15419               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
15420                lang_printable_name (TREE_VALUE (throws), 0),
15421                (DECL_INIT_P (current_function_decl) ?
15422                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
15423                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
15424           }
15425       }
15426 }
15427
15428 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
15429    try-catch blocks, OR is listed in the `throws' clause of the
15430    current method.  */
15431
15432 static int
15433 check_thrown_exceptions_do (exception)
15434      tree exception;
15435 {
15436   tree list = currently_caught_type_list;
15437   resolve_and_layout (exception, NULL_TREE);
15438   /* First, all the nested try-catch-finally at that stage. The
15439      last element contains `throws' clause exceptions, if any. */
15440   if (IS_UNCHECKED_EXCEPTION_P (exception))
15441     return 1;
15442   while (list)
15443     {
15444       tree caught;
15445       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
15446         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
15447           return 1;
15448       list = TREE_CHAIN (list);
15449     }
15450   return 0;
15451 }
15452
15453 static void
15454 purge_unchecked_exceptions (mdecl)
15455      tree mdecl;
15456 {
15457   tree throws = DECL_FUNCTION_THROWS (mdecl);
15458   tree new = NULL_TREE;
15459
15460   while (throws)
15461     {
15462       tree next = TREE_CHAIN (throws);
15463       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
15464         {
15465           TREE_CHAIN (throws) = new;
15466           new = throws;
15467         }
15468       throws = next;
15469     }
15470   /* List is inverted here, but it doesn't matter */
15471   DECL_FUNCTION_THROWS (mdecl) = new;
15472 }
15473
15474 /* 15.24 Conditional Operator ?: */
15475
15476 static tree
15477 patch_conditional_expr (node, wfl_cond, wfl_op1)
15478      tree node, wfl_cond, wfl_op1;
15479 {
15480   tree cond = TREE_OPERAND (node, 0);
15481   tree op1 = TREE_OPERAND (node, 1);
15482   tree op2 = TREE_OPERAND (node, 2);
15483   tree resulting_type = NULL_TREE;
15484   tree t1, t2, patched;
15485   int error_found = 0;
15486
15487   /* Operands of ?: might be StringBuffers crafted as a result of a
15488      string concatenation. Obtain a descent operand here.  */
15489   if ((patched = patch_string (op1)))
15490     TREE_OPERAND (node, 1) = op1 = patched;
15491   if ((patched = patch_string (op2)))
15492     TREE_OPERAND (node, 2) = op2 = patched;
15493
15494   t1 = TREE_TYPE (op1);
15495   t2 = TREE_TYPE (op2);
15496
15497   /* The first expression must be a boolean */
15498   if (TREE_TYPE (cond) != boolean_type_node)
15499     {
15500       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
15501       parse_error_context (wfl_operator,
15502                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
15503                            lang_printable_name (TREE_TYPE (cond), 0));
15504       error_found = 1;
15505     }
15506
15507   /* Second and third can be numeric, boolean (i.e. primitive),
15508      references or null. Anything else results in an error */
15509   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
15510         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
15511             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
15512         || (t1 == boolean_type_node && t2 == boolean_type_node)))
15513     error_found = 1;
15514
15515   /* Determine the type of the conditional expression. Same types are
15516      easy to deal with */
15517   else if (t1 == t2)
15518     resulting_type = t1;
15519
15520   /* There are different rules for numeric types */
15521   else if (JNUMERIC_TYPE_P (t1))
15522     {
15523       /* if byte/short found, the resulting type is short */
15524       if ((t1 == byte_type_node && t2 == short_type_node)
15525           || (t1 == short_type_node && t2 == byte_type_node))
15526         resulting_type = short_type_node;
15527
15528       /* If t1 is a constant int and t2 is of type byte, short or char
15529          and t1's value fits in t2, then the resulting type is t2 */
15530       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
15531           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
15532         resulting_type = t2;
15533
15534       /* If t2 is a constant int and t1 is of type byte, short or char
15535          and t2's value fits in t1, then the resulting type is t1 */
15536       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
15537           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
15538         resulting_type = t1;
15539
15540       /* Otherwise, binary numeric promotion is applied and the
15541          resulting type is the promoted type of operand 1 and 2 */
15542       else 
15543         resulting_type = binary_numeric_promotion (t1, t2, 
15544                                                    &TREE_OPERAND (node, 1), 
15545                                                    &TREE_OPERAND (node, 2));
15546     }
15547
15548   /* Cases of a reference and a null type */
15549   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
15550     resulting_type = t1;
15551
15552   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
15553     resulting_type = t2;
15554
15555   /* Last case: different reference types. If a type can be converted
15556      into the other one by assignment conversion, the latter
15557      determines the type of the expression */
15558   else if ((resulting_type = try_reference_assignconv (t1, op2)))
15559     resulting_type = promote_type (t1);
15560
15561   else if ((resulting_type = try_reference_assignconv (t2, op1)))
15562     resulting_type = promote_type (t2);
15563
15564   /* If we don't have any resulting type, we're in trouble */
15565   if (!resulting_type)
15566     {
15567       char *t = xstrdup (lang_printable_name (t1, 0));
15568       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15569       parse_error_context (wfl_operator,
15570                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
15571                            t, lang_printable_name (t2, 0));
15572       free (t);
15573       error_found = 1;
15574     }
15575
15576   if (error_found)
15577     {
15578       TREE_TYPE (node) = error_mark_node;
15579       return error_mark_node;
15580     }
15581
15582   TREE_TYPE (node) = resulting_type;
15583   TREE_SET_CODE (node, COND_EXPR);
15584   CAN_COMPLETE_NORMALLY (node) = 1;
15585   return node;
15586 }
15587
15588 /* Wrap EXPR with code to initialize DECL's class, if appropriate. */
15589
15590 static tree
15591 maybe_build_class_init_for_field (decl, expr)
15592     tree decl, expr;
15593 {
15594   tree clas = DECL_CONTEXT (decl);
15595   if (flag_emit_class_files || flag_emit_xref)
15596     return expr;
15597
15598   if (TREE_CODE (decl) == VAR_DECL && FIELD_STATIC (decl)
15599       && FIELD_FINAL (decl))
15600     {
15601       tree init = DECL_INITIAL (decl);
15602       if (init != NULL_TREE)
15603         init = fold_constant_for_init (init, decl);
15604       if (init != NULL_TREE && CONSTANT_VALUE_P (init))
15605         return expr;
15606     }
15607
15608   return build_class_init (clas, expr);
15609 }
15610
15611 /* Try to constant fold NODE.
15612    If NODE is not a constant expression, return NULL_EXPR.
15613    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
15614
15615 static tree
15616 fold_constant_for_init (node, context)
15617      tree node;
15618      tree context;
15619 {
15620   tree op0, op1, val;
15621   enum tree_code code = TREE_CODE (node);
15622
15623   switch (code)
15624     {
15625     case STRING_CST:
15626     case INTEGER_CST:
15627     case REAL_CST:
15628       return node;
15629
15630     case PLUS_EXPR:
15631     case MINUS_EXPR:
15632     case MULT_EXPR:
15633     case TRUNC_MOD_EXPR:
15634     case RDIV_EXPR:
15635     case LSHIFT_EXPR:
15636     case RSHIFT_EXPR:
15637     case URSHIFT_EXPR:
15638     case BIT_AND_EXPR:
15639     case BIT_XOR_EXPR:
15640     case BIT_IOR_EXPR:
15641     case TRUTH_ANDIF_EXPR:
15642     case TRUTH_ORIF_EXPR:
15643     case EQ_EXPR: 
15644     case NE_EXPR:
15645     case GT_EXPR:
15646     case GE_EXPR:
15647     case LT_EXPR:
15648     case LE_EXPR:
15649       op0 = TREE_OPERAND (node, 0);
15650       op1 = TREE_OPERAND (node, 1);
15651       val = fold_constant_for_init (op0, context);
15652       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15653         return NULL_TREE;
15654       TREE_OPERAND (node, 0) = val;
15655       val = fold_constant_for_init (op1, context);
15656       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15657         return NULL_TREE;
15658       TREE_OPERAND (node, 1) = val;
15659       return patch_binop (node, op0, op1);
15660
15661     case UNARY_PLUS_EXPR:
15662     case NEGATE_EXPR:
15663     case TRUTH_NOT_EXPR:
15664     case BIT_NOT_EXPR:
15665     case CONVERT_EXPR:
15666       op0 = TREE_OPERAND (node, 0);
15667       val = fold_constant_for_init (op0, context);
15668       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15669         return NULL_TREE;
15670       TREE_OPERAND (node, 0) = val;
15671       return patch_unaryop (node, op0);
15672       break;
15673
15674     case COND_EXPR:
15675       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
15676       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15677         return NULL_TREE;
15678       TREE_OPERAND (node, 0) = val;
15679       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
15680       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15681         return NULL_TREE;
15682       TREE_OPERAND (node, 1) = val;
15683       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
15684       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15685         return NULL_TREE;
15686       TREE_OPERAND (node, 2) = val;
15687       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
15688         : TREE_OPERAND (node, 2);
15689
15690     case VAR_DECL:
15691     case FIELD_DECL:
15692       if (! FIELD_FINAL (node)
15693           || DECL_INITIAL (node) == NULL_TREE)
15694         return NULL_TREE;
15695       val = DECL_INITIAL (node);
15696       /* Guard against infinite recursion. */
15697       DECL_INITIAL (node) = NULL_TREE;
15698       val = fold_constant_for_init (val, node);
15699       DECL_INITIAL (node) = val;
15700       if (!val && CLASS_FINAL_VARIABLE_P (node))
15701         DECL_FIELD_FINAL_IUD (node) = 0;
15702       return val;
15703
15704     case EXPR_WITH_FILE_LOCATION:
15705       /* Compare java_complete_tree and resolve_expression_name. */
15706       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
15707           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
15708         {
15709           tree name = EXPR_WFL_NODE (node);
15710           tree decl;
15711           if (PRIMARY_P (node))
15712             return NULL_TREE;
15713           else if (! QUALIFIED_P (name))
15714             {
15715               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
15716               if (decl == NULL_TREE 
15717                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
15718                 return NULL_TREE;
15719               return fold_constant_for_init (decl, decl);
15720             }
15721           else
15722             {
15723               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
15724               qualify_ambiguous_name (node);
15725               if (resolve_field_access (node, &decl, NULL)
15726                   && decl != NULL_TREE)
15727                 return fold_constant_for_init (decl, decl);
15728               return NULL_TREE;
15729             }
15730         }
15731       else
15732         {
15733           op0 = TREE_OPERAND (node, 0);
15734           val = fold_constant_for_init (op0, context);
15735           if (val == NULL_TREE || ! TREE_CONSTANT (val))
15736             return NULL_TREE;
15737           TREE_OPERAND (node, 0) = val;
15738           return val;
15739         }
15740
15741 #ifdef USE_COMPONENT_REF
15742     case IDENTIFIER:
15743     case COMPONENT_REF:
15744       ?;
15745 #endif
15746
15747     default:
15748       return NULL_TREE;
15749     }
15750 }
15751
15752 #ifdef USE_COMPONENT_REF
15753 /* Context is 'T' for TypeName, 'P' for PackageName,
15754    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
15755
15756 tree
15757 resolve_simple_name (name, context)
15758      tree name;
15759      int context;
15760 {
15761 }
15762
15763 tree
15764 resolve_qualified_name (name, context)
15765      tree name;
15766      int context;
15767 {
15768 }
15769 #endif
15770
15771 /* Mark P, which is really a `struct parser_ctxt **' for GC.  */
15772
15773 static void
15774 mark_parser_ctxt (p)
15775      void *p;
15776 {
15777   struct parser_ctxt *pc = *((struct parser_ctxt **) p);
15778   int i;
15779
15780   if (!pc)
15781     return;
15782
15783 #ifndef JC1_LITE
15784   for (i = 0; i < 11; ++i)
15785     ggc_mark_tree (pc->modifier_ctx[i]);
15786   ggc_mark_tree (pc->class_type);
15787   ggc_mark_tree (pc->function_decl);
15788   ggc_mark_tree (pc->package);
15789   ggc_mark_tree (pc->class_list);
15790   ggc_mark_tree (pc->current_parsed_class);
15791   ggc_mark_tree (pc->current_parsed_class_un);
15792   ggc_mark_tree (pc->non_static_initialized);
15793   ggc_mark_tree (pc->static_initialized);
15794   ggc_mark_tree (pc->instance_initializers);
15795   ggc_mark_tree (pc->import_list);
15796   ggc_mark_tree (pc->import_demand_list);
15797   ggc_mark_tree (pc->current_loop);
15798   ggc_mark_tree (pc->current_labeled_block);
15799 #endif /* JC1_LITE */
15800
15801   if (pc->next)
15802     mark_parser_ctxt (&pc->next);
15803 }
15804
15805 void
15806 init_src_parse ()
15807 {
15808   /* Register roots with the garbage collector.  */
15809   ggc_add_tree_root (src_parse_roots, sizeof (src_parse_roots) / sizeof(tree));
15810 }