OSDN Git Service

3f1cfa7f3baa8f7b98c11eabc0b58948b5ce10b9
[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 check_inner_circular_reference PARAMS ((tree, tree));
145 static tree check_circular_reference PARAMS ((tree));
146 static tree obtain_incomplete_type PARAMS ((tree));
147 static tree java_complete_lhs PARAMS ((tree));
148 static tree java_complete_tree PARAMS ((tree));
149 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
150 static int analyze_clinit_body PARAMS ((tree));
151 static int maybe_yank_clinit PARAMS ((tree));
152 static void start_complete_expand_method PARAMS ((tree));
153 static void java_complete_expand_method PARAMS ((tree));
154 static void java_expand_method_bodies PARAMS ((tree));
155 static int  unresolved_type_p PARAMS ((tree, tree *));
156 static void create_jdep_list PARAMS ((struct parser_ctxt *));
157 static tree build_expr_block PARAMS ((tree, tree));
158 static tree enter_block PARAMS ((void));
159 static tree exit_block PARAMS ((void));
160 static tree lookup_name_in_blocks PARAMS ((tree));
161 static void maybe_absorb_scoping_blocks PARAMS ((void));
162 static tree build_method_invocation PARAMS ((tree, tree));
163 static tree build_new_invocation PARAMS ((tree, tree));
164 static tree build_assignment PARAMS ((int, int, tree, tree));
165 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
166 static int check_final_assignment PARAMS ((tree ,tree));
167 static tree patch_assignment PARAMS ((tree, tree, tree ));
168 static tree patch_binop PARAMS ((tree, tree, tree));
169 static tree build_unaryop PARAMS ((int, int, tree));
170 static tree build_incdec PARAMS ((int, int, tree, int));
171 static tree patch_unaryop PARAMS ((tree, tree));
172 static tree build_cast PARAMS ((int, tree, tree));
173 static tree build_null_of_type PARAMS ((tree));
174 static tree patch_cast PARAMS ((tree, tree));
175 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
176 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
177 static int valid_cast_to_p PARAMS ((tree, tree));
178 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
179 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
180 static tree try_reference_assignconv PARAMS ((tree, tree));
181 static tree build_unresolved_array_type PARAMS ((tree));
182 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
183 static tree build_array_ref PARAMS ((int, tree, tree));
184 static tree patch_array_ref PARAMS ((tree));
185 static tree make_qualified_name PARAMS ((tree, tree, int));
186 static tree merge_qualified_name PARAMS ((tree, tree));
187 static tree make_qualified_primary PARAMS ((tree, tree, int));
188 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
189                                                      tree *, tree *));
190 static void qualify_ambiguous_name PARAMS ((tree));
191 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
192 static tree build_newarray_node PARAMS ((tree, tree, int));
193 static tree patch_newarray PARAMS ((tree));
194 static tree resolve_type_during_patch PARAMS ((tree));
195 static tree build_this PARAMS ((int));
196 static tree build_wfl_wrap PARAMS ((tree, int));
197 static tree build_return PARAMS ((int, tree));
198 static tree patch_return PARAMS ((tree));
199 static tree maybe_access_field PARAMS ((tree, tree, tree));
200 static int complete_function_arguments PARAMS ((tree));
201 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
202                                                       tree, tree));
203 static int not_accessible_p PARAMS ((tree, tree, tree, int));
204 static void check_deprecation PARAMS ((tree, tree));
205 static int class_in_current_package PARAMS ((tree));
206 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
207 static tree patch_if_else_statement PARAMS ((tree));
208 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
209 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
210 static tree patch_exit_expr PARAMS ((tree));
211 static tree build_labeled_block PARAMS ((int, tree));
212 static tree finish_labeled_statement PARAMS ((tree, tree));
213 static tree build_bc_statement PARAMS ((int, int, tree));
214 static tree patch_bc_statement PARAMS ((tree));
215 static tree patch_loop_statement PARAMS ((tree));
216 static tree build_new_loop PARAMS ((tree));
217 static tree build_loop_body PARAMS ((int, tree, int));
218 static tree finish_loop_body PARAMS ((int, tree, tree, int));
219 static tree build_debugable_stmt PARAMS ((int, tree));
220 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
221 static tree patch_switch_statement PARAMS ((tree));
222 static tree string_constant_concatenation PARAMS ((tree, tree));
223 static tree build_string_concatenation PARAMS ((tree, tree));
224 static tree patch_string_cst PARAMS ((tree));
225 static tree patch_string PARAMS ((tree));
226 static tree encapsulate_with_try_catch PARAMS ((int, tree, tree, tree));
227 static tree build_try_statement PARAMS ((int, tree, tree));
228 static tree build_try_finally_statement PARAMS ((int, tree, tree));
229 static tree patch_try_statement PARAMS ((tree));
230 static tree patch_synchronized_statement PARAMS ((tree, tree));
231 static tree patch_throw_statement PARAMS ((tree, tree));
232 static void check_thrown_exceptions PARAMS ((int, tree));
233 static int check_thrown_exceptions_do PARAMS ((tree));
234 static void purge_unchecked_exceptions PARAMS ((tree));
235 static bool ctors_unchecked_throws_clause_p PARAMS ((tree));
236 static void check_throws_clauses PARAMS ((tree, tree, tree));
237 static void finish_method_declaration PARAMS ((tree));
238 static tree build_super_invocation PARAMS ((tree));
239 static int verify_constructor_circularity PARAMS ((tree, tree));
240 static char *constructor_circularity_msg PARAMS ((tree, tree));
241 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
242                                                           int, int));
243 static const char *get_printable_method_name PARAMS ((tree));
244 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
245 static tree generate_finit PARAMS ((tree));
246 static tree generate_instinit PARAMS ((tree));
247 static tree build_instinit_invocation PARAMS ((tree));
248 static void fix_constructors PARAMS ((tree));
249 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
250                                                             tree, int *));
251 static void craft_constructor PARAMS ((tree, tree));
252 static int verify_constructor_super PARAMS ((tree));
253 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
254 static void start_artificial_method_body PARAMS ((tree));
255 static void end_artificial_method_body PARAMS ((tree));
256 static int check_method_redefinition PARAMS ((tree, tree));
257 static int check_method_types_complete PARAMS ((tree));
258 static void java_check_regular_methods PARAMS ((tree));
259 static void java_check_abstract_methods PARAMS ((tree));
260 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
261 static void unreachable_stmt_error PARAMS ((tree));
262 static tree find_expr_with_wfl PARAMS ((tree));
263 static void missing_return_error PARAMS ((tree));
264 static tree build_new_array_init PARAMS ((int, tree));
265 static tree patch_new_array_init PARAMS ((tree, tree));
266 static tree maybe_build_array_element_wfl PARAMS ((tree));
267 static int array_constructor_check_entry PARAMS ((tree, tree));
268 static const char *purify_type_name PARAMS ((const char *));
269 static tree fold_constant_for_init PARAMS ((tree, tree));
270 static tree strip_out_static_field_access_decl PARAMS ((tree));
271 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
272 static void static_ref_err PARAMS ((tree, tree, tree));
273 static void parser_add_interface PARAMS ((tree, tree, tree));
274 static void add_superinterfaces PARAMS ((tree, tree));
275 static tree jdep_resolve_class PARAMS ((jdep *));
276 static int note_possible_classname PARAMS ((const char *, int));
277 static void java_complete_expand_classes PARAMS ((void));
278 static void java_complete_expand_class PARAMS ((tree));
279 static void java_complete_expand_methods PARAMS ((tree));
280 static tree cut_identifier_in_qualified PARAMS ((tree));
281 static tree java_stabilize_reference PARAMS ((tree));
282 static tree do_unary_numeric_promotion PARAMS ((tree));
283 static char * operator_string PARAMS ((tree));
284 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
285 static tree merge_string_cste PARAMS ((tree, tree, int));
286 static tree java_refold PARAMS ((tree));
287 static int java_decl_equiv PARAMS ((tree, tree));
288 static int binop_compound_p PARAMS ((enum tree_code));
289 static tree search_loop PARAMS ((tree));
290 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
291 static int check_abstract_method_definitions PARAMS ((int, tree, tree));
292 static void java_check_abstract_method_definitions PARAMS ((tree));
293 static void java_debug_context_do PARAMS ((int));
294 static void java_parser_context_push_initialized_field PARAMS ((void));
295 static void java_parser_context_pop_initialized_field PARAMS ((void));
296 static tree reorder_static_initialized PARAMS ((tree));
297 static void java_parser_context_suspend PARAMS ((void));
298 static void java_parser_context_resume PARAMS ((void));
299 static int pop_current_osb PARAMS ((struct parser_ctxt *));
300
301 /* JDK 1.1 work. FIXME */
302
303 static tree maybe_make_nested_class_name PARAMS ((tree));
304 static void make_nested_class_name PARAMS ((tree));
305 static void set_nested_class_simple_name_value PARAMS ((tree, int));
306 static void link_nested_class_to_enclosing PARAMS ((void));
307 static tree resolve_inner_class PARAMS ((struct hash_table *, tree, tree *,
308                                          tree *, tree));
309 static tree find_as_inner_class PARAMS ((tree, tree, tree));
310 static tree find_as_inner_class_do PARAMS ((tree, tree));
311 static int check_inner_class_redefinition PARAMS ((tree, tree));
312
313 static tree build_thisn_assign PARAMS ((void));
314 static tree build_current_thisn PARAMS ((tree));
315 static tree build_access_to_thisn PARAMS ((tree, tree, int));
316 static tree maybe_build_thisn_access_method PARAMS ((tree));
317
318 static tree build_outer_field_access PARAMS ((tree, tree));
319 static tree build_outer_field_access_methods PARAMS ((tree));
320 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
321                                                   tree, tree));
322 static tree build_outer_method_access_method PARAMS ((tree));
323 static tree build_new_access_id PARAMS ((void));
324 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
325                                                     tree, tree));
326
327 static int outer_field_access_p PARAMS ((tree, tree));
328 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
329                                                  tree *, tree *));
330 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
331 static tree build_incomplete_class_ref PARAMS ((int, tree));
332 static tree patch_incomplete_class_ref PARAMS ((tree));
333 static tree create_anonymous_class PARAMS ((int, tree));
334 static void patch_anonymous_class PARAMS ((tree, tree, tree));
335 static void add_inner_class_fields PARAMS ((tree, tree));
336
337 static tree build_dot_class_method PARAMS ((tree));
338 static tree build_dot_class_method_invocation PARAMS ((tree));
339 static void create_new_parser_context PARAMS ((int));
340 static void mark_parser_ctxt PARAMS ((void *));
341 static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
342
343 static bool attach_init_test_initialization_flags PARAMS ((struct hash_entry *,
344                                                           PTR));
345 static bool adjust_init_test_initialization PARAMS ((struct hash_entry *,
346                                                      PTR));
347 static bool emit_test_initialization PARAMS ((struct hash_entry *, PTR));
348
349 /* Number of error found so far. */
350 int java_error_count; 
351 /* Number of warning found so far. */
352 int java_warning_count;
353 /* Tell when not to fold, when doing xrefs */
354 int do_not_fold;
355 /* Cyclic inheritance report, as it can be set by layout_class */
356 const char *cyclic_inheritance_report;
357  
358 /* The current parser context */
359 struct parser_ctxt *ctxp;
360
361 /* List of things that were analyzed for which code will be generated */
362 struct parser_ctxt *ctxp_for_generation = NULL;
363
364 /* binop_lookup maps token to tree_code. It is used where binary
365    operations are involved and required by the parser. RDIV_EXPR
366    covers both integral/floating point division. The code is changed
367    once the type of both operator is worked out.  */
368
369 static enum tree_code binop_lookup[19] = 
370   { 
371     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
372     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
373     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
374     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
375     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
376    };
377 #define BINOP_LOOKUP(VALUE)                                             \
378   binop_lookup [((VALUE) - PLUS_TK) % ARRAY_SIZE (binop_lookup)]
379
380 /* This is the end index for binary operators that can also be used
381    in compound assignements. */
382 #define BINOP_COMPOUND_CANDIDATES 11
383
384 /* The "$L" identifier we use to create labels.  */
385 static tree label_id = NULL_TREE;
386
387 /* The "StringBuffer" identifier used for the String `+' operator. */
388 static tree wfl_string_buffer = NULL_TREE; 
389
390 /* The "append" identifier used for String `+' operator.  */
391 static tree wfl_append = NULL_TREE;
392
393 /* The "toString" identifier used for String `+' operator. */
394 static tree wfl_to_string = NULL_TREE;
395
396 /* The "java.lang" import qualified name.  */
397 static tree java_lang_id = NULL_TREE;
398
399 /* The generated `inst$' identifier used for generated enclosing
400    instance/field access functions.  */
401 static tree inst_id = NULL_TREE;
402
403 /* The "java.lang.Cloneable" qualified name.  */
404 static tree java_lang_cloneable = NULL_TREE;
405
406 /* The "java.io.Serializable" qualified name.  */
407 static tree java_io_serializable = NULL_TREE; 
408
409 /* Context and flag for static blocks */
410 static tree current_static_block = NULL_TREE;
411
412 /* The generated `write_parm_value$' identifier.  */
413 static tree wpv_id;
414
415 /* The list of all packages we've seen so far */
416 static tree package_list = NULL_TREE;
417  
418 /* Hold THIS for the scope of the current public method decl.  */
419 static tree current_this;
420
421 /* Hold a list of catch clauses list. The first element of this list is
422    the list of the catch clauses of the currently analysed try block. */
423 static tree currently_caught_type_list;
424
425 static tree src_parse_roots[1] = { NULL_TREE };
426
427 /* All classes seen from source code */
428 #define gclass_list src_parse_roots[0]
429
430 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
431    line and point it out.  */
432 /* Should point out the one that don't fit. ASCII/unicode, going
433    backward. FIXME */
434
435 #define check_modifiers(__message, __value, __mask) do {        \
436   if ((__value) & ~(__mask))                                    \
437     {                                                           \
438       int i, remainder = (__value) & ~(__mask);                 \
439       for (i = 0; i <= 10; i++)                                 \
440         if ((1 << i) & remainder)                               \
441           parse_error_context (ctxp->modifier_ctx [i], (__message), \
442                                java_accstring_lookup (1 << i)); \
443     }                                                           \
444 } while (0)
445
446 %}
447
448 %union {
449   tree node;
450   int sub_token;
451   struct {
452     int token;
453     int location;
454   } operator;
455   int value;
456 }
457
458 %{
459 #include "lex.c"
460 %}
461
462 %pure_parser
463
464 /* Things defined here have to match the order of what's in the
465    binop_lookup table.  */
466
467 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
468 %token   LS_TK           SRS_TK          ZRS_TK
469 %token   AND_TK          XOR_TK          OR_TK
470 %token   BOOL_AND_TK BOOL_OR_TK 
471 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
472
473 /* This maps to the same binop_lookup entry than the token above */
474
475 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
476 %token   REM_ASSIGN_TK   
477 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
478 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
479
480
481 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
482
483 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
484 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
485 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
486 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
487 %token   STRICT_TK
488
489 /* Keep those two in order, too */
490 %token   DECR_TK INCR_TK
491
492 /* From now one, things can be in any order */
493
494 %token   DEFAULT_TK      IF_TK              THROW_TK
495 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
496 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
497 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
498 %token   VOID_TK         CATCH_TK           INTERFACE_TK
499 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
500 %token   SUPER_TK        WHILE_TK           CLASS_TK
501 %token   SWITCH_TK       CONST_TK           TRY_TK
502 %token   FOR_TK          NEW_TK             CONTINUE_TK
503 %token   GOTO_TK         PACKAGE_TK         THIS_TK
504
505 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
506 %token   CHAR_TK         INTEGRAL_TK
507
508 %token   FLOAT_TK        DOUBLE_TK          FP_TK
509
510 %token   ID_TK
511
512 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
513
514 %token   ASSIGN_ANY_TK   ASSIGN_TK
515 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
516
517 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
518 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
519
520 %type    <value>        modifiers MODIFIER_TK final synchronized
521
522 %type    <node>         super ID_TK identifier
523 %type    <node>         name simple_name qualified_name
524 %type    <node>         type_declaration compilation_unit
525                         field_declaration method_declaration extends_interfaces
526                         interfaces interface_type_list
527                         class_member_declaration
528                         import_declarations package_declaration 
529                         type_declarations interface_body
530                         interface_member_declaration constant_declaration
531                         interface_member_declarations interface_type
532                         abstract_method_declaration interface_type_list
533 %type    <node>         class_body_declaration class_member_declaration
534                         static_initializer constructor_declaration block
535 %type    <node>         class_body_declarations constructor_header
536 %type    <node>         class_or_interface_type class_type class_type_list
537                         constructor_declarator explicit_constructor_invocation
538 %type    <node>         dim_expr dim_exprs this_or_super throws
539
540 %type    <node>         variable_declarator_id variable_declarator
541                         variable_declarators variable_initializer
542                         variable_initializers constructor_body
543                         array_initializer
544
545 %type    <node>         class_body block_end constructor_block_end
546 %type    <node>         statement statement_without_trailing_substatement
547                         labeled_statement if_then_statement label_decl
548                         if_then_else_statement while_statement for_statement
549                         statement_nsi labeled_statement_nsi do_statement
550                         if_then_else_statement_nsi while_statement_nsi
551                         for_statement_nsi statement_expression_list for_init
552                         for_update statement_expression expression_statement
553                         primary_no_new_array expression primary
554                         array_creation_expression array_type
555                         class_instance_creation_expression field_access
556                         method_invocation array_access something_dot_new
557                         argument_list postfix_expression while_expression 
558                         post_increment_expression post_decrement_expression
559                         unary_expression_not_plus_minus unary_expression
560                         pre_increment_expression pre_decrement_expression
561                         unary_expression_not_plus_minus cast_expression
562                         multiplicative_expression additive_expression
563                         shift_expression relational_expression 
564                         equality_expression and_expression 
565                         exclusive_or_expression inclusive_or_expression
566                         conditional_and_expression conditional_or_expression
567                         conditional_expression assignment_expression
568                         left_hand_side assignment for_header for_begin
569                         constant_expression do_statement_begin empty_statement
570                         switch_statement synchronized_statement throw_statement
571                         try_statement switch_expression switch_block
572                         catches catch_clause catch_clause_parameter finally
573                         anonymous_class_creation
574 %type    <node>         return_statement break_statement continue_statement
575
576 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
577 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
578 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
579 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
580 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
581 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
582 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
583 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
584 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
585 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
586 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
587 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
588 %type    <operator>     NEW_TK
589
590 %type    <node>         method_body 
591         
592 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
593                         STRING_LIT_TK NULL_TK VOID_TK
594
595 %type    <node>         IF_TK WHILE_TK FOR_TK
596
597 %type    <node>         formal_parameter_list formal_parameter
598                         method_declarator method_header
599
600 %type    <node>         primitive_type reference_type type 
601                         BOOLEAN_TK INTEGRAL_TK FP_TK
602
603 /* Added or modified JDK 1.1 rule types  */
604 %type    <node>         type_literals
605
606 %%
607 /* 19.2 Production from 2.3: The Syntactic Grammar  */
608 goal:
609                 {
610                   /* Register static variables with the garbage
611                      collector.  */
612                   ggc_add_tree_root (&label_id, 1);
613                   ggc_add_tree_root (&wfl_string_buffer, 1);
614                   ggc_add_tree_root (&wfl_append, 1);
615                   ggc_add_tree_root (&wfl_to_string, 1);
616                   ggc_add_tree_root (&java_lang_id, 1);
617                   ggc_add_tree_root (&inst_id, 1);
618                   ggc_add_tree_root (&java_lang_cloneable, 1);
619                   ggc_add_tree_root (&java_io_serializable, 1);
620                   ggc_add_tree_root (&current_static_block, 1);
621                   ggc_add_tree_root (&wpv_id, 1);
622                   ggc_add_tree_root (&package_list, 1);
623                   ggc_add_tree_root (&current_this, 1);
624                   ggc_add_tree_root (&currently_caught_type_list, 1);
625                   ggc_add_root (&ctxp, 1, 
626                                 sizeof (struct parser_ctxt *),
627                                 mark_parser_ctxt);
628                   ggc_add_root (&ctxp_for_generation, 1, 
629                                 sizeof (struct parser_ctxt *),
630                                 mark_parser_ctxt);
631                 }
632         compilation_unit
633                 {}
634 ;
635
636 /* 19.3 Productions from 3: Lexical structure  */
637 literal:
638         INT_LIT_TK
639 |       FP_LIT_TK
640 |       BOOL_LIT_TK
641 |       CHAR_LIT_TK
642 |       STRING_LIT_TK
643 |       NULL_TK
644 ;
645
646 /* 19.4 Productions from 4: Types, Values and Variables  */
647 type:
648         primitive_type
649 |       reference_type
650 ;
651
652 primitive_type:
653         INTEGRAL_TK
654 |       FP_TK
655 |       BOOLEAN_TK
656 ;
657
658 reference_type:
659         class_or_interface_type
660 |       array_type
661 ;
662
663 class_or_interface_type:
664         name
665 ;
666
667 class_type:
668         class_or_interface_type /* Default rule */
669 ;
670
671 interface_type:
672          class_or_interface_type
673 ;
674
675 array_type:
676         primitive_type dims
677                 { 
678                   int osb = pop_current_osb (ctxp);
679                   tree t = build_java_array_type (($1), -1);
680                   while (--osb)
681                     t = build_unresolved_array_type (t);
682                   $$ = t;
683                 }
684 |       name dims
685                 { 
686                   int osb = pop_current_osb (ctxp);
687                   tree t = $1;
688                   while (osb--)
689                     t = build_unresolved_array_type (t);
690                   $$ = t;
691                 }
692 ;
693
694 /* 19.5 Productions from 6: Names  */
695 name:
696         simple_name             /* Default rule */
697 |       qualified_name          /* Default rule */
698 ;
699
700 simple_name:
701         identifier              /* Default rule */
702 ;
703
704 qualified_name:
705         name DOT_TK identifier
706                 { $$ = make_qualified_name ($1, $3, $2.location); }
707 ;
708
709 identifier:
710         ID_TK
711 ;
712
713 /* 19.6: Production from 7: Packages  */
714 compilation_unit:
715                 {$$ = NULL;}
716 |       package_declaration
717 |       import_declarations
718 |       type_declarations
719 |       package_declaration import_declarations
720 |       package_declaration type_declarations
721 |       import_declarations type_declarations
722 |       package_declaration import_declarations type_declarations
723 ;
724
725 import_declarations:
726         import_declaration
727                 {
728                   $$ = NULL;
729                 }
730 |       import_declarations import_declaration
731                 {
732                   $$ = NULL;
733                 }
734 ;
735
736 type_declarations:
737         type_declaration
738 |       type_declarations type_declaration
739 ;
740
741 package_declaration:
742         PACKAGE_TK name SC_TK
743                 { 
744                   ctxp->package = EXPR_WFL_NODE ($2);
745                   register_package (ctxp->package);
746                 }
747 |       PACKAGE_TK error
748                 {yyerror ("Missing name"); RECOVER;}
749 |       PACKAGE_TK name error
750                 {yyerror ("';' expected"); RECOVER;}
751 ;
752
753 import_declaration:
754         single_type_import_declaration
755 |       type_import_on_demand_declaration
756 ;
757
758 single_type_import_declaration:
759         IMPORT_TK name SC_TK
760                 {
761                   tree name = EXPR_WFL_NODE ($2), last_name;
762                   int   i = IDENTIFIER_LENGTH (name)-1;
763                   const char *last = &IDENTIFIER_POINTER (name)[i];
764                   while (last != IDENTIFIER_POINTER (name))
765                     {
766                       if (last [0] == '.')
767                         break;
768                       last--;
769                     }
770                   last_name = get_identifier (++last);
771                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
772                     {
773                       tree err = find_name_in_single_imports (last_name);
774                       if (err && err != name)
775                         parse_error_context
776                           ($2, "Ambiguous class: `%s' and `%s'",
777                            IDENTIFIER_POINTER (name), 
778                            IDENTIFIER_POINTER (err));
779                       else
780                         REGISTER_IMPORT ($2, last_name);
781                     }
782                   else
783                     REGISTER_IMPORT ($2, last_name);
784                 }
785 |       IMPORT_TK error
786                 {yyerror ("Missing name"); RECOVER;}
787 |       IMPORT_TK name error
788                 {yyerror ("';' expected"); RECOVER;}
789 ;
790
791 type_import_on_demand_declaration:
792         IMPORT_TK name DOT_TK MULT_TK SC_TK
793                 {
794                   tree name = EXPR_WFL_NODE ($2);
795                   tree it;
796                   /* Search for duplicates. */
797                   for (it = ctxp->import_demand_list; it; it = TREE_CHAIN (it))
798                     if (EXPR_WFL_NODE (TREE_PURPOSE (it)) == name)
799                       break;
800                   /* Don't import the same thing more than once, just ignore
801                      duplicates (7.5.2) */
802                   if (! it)
803                     {
804                       read_import_dir ($2);
805                       ctxp->import_demand_list = 
806                         chainon (ctxp->import_demand_list,
807                                  build_tree_list ($2, NULL_TREE));
808                     }
809                 }
810 |       IMPORT_TK name DOT_TK error
811                 {yyerror ("'*' expected"); RECOVER;}
812 |       IMPORT_TK name DOT_TK MULT_TK error
813                 {yyerror ("';' expected"); RECOVER;}
814 ;
815
816 type_declaration:
817         class_declaration
818                 { end_class_declaration (0); }
819 |       interface_declaration
820                 { end_class_declaration (0); }
821 |       empty_statement
822 |       error
823                 {
824                   YYERROR_NOW;
825                   yyerror ("Class or interface declaration expected");
826                 }
827 ;
828
829 /* 19.7 Shortened from the original:
830    modifiers: modifier | modifiers modifier
831    modifier: any of public...  */
832 modifiers:
833         MODIFIER_TK
834                 {
835                   $$ = (1 << $1);
836                 }
837 |       modifiers MODIFIER_TK
838                 {
839                   int acc = (1 << $2);
840                   if ($$ & acc)
841                     parse_error_context 
842                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
843                        java_accstring_lookup (acc));
844                   else
845                     {
846                       $$ |= acc;
847                     }
848                 }
849 ;
850
851 /* 19.8.1 Production from $8.1: Class Declaration */
852 class_declaration:
853         modifiers CLASS_TK identifier super interfaces
854                 { create_class ($1, $3, $4, $5); }
855         class_body
856 |       CLASS_TK identifier super interfaces 
857                 { create_class (0, $2, $3, $4); }
858         class_body
859 |       modifiers CLASS_TK error
860                 {yyerror ("Missing class name"); RECOVER;}
861 |       CLASS_TK error
862                 {yyerror ("Missing class name"); RECOVER;}
863 |       CLASS_TK identifier error
864                 {
865                   if (!ctxp->class_err) yyerror ("'{' expected"); 
866                   DRECOVER(class1);
867                 }
868 |       modifiers CLASS_TK identifier error
869                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
870 ;
871
872 super:
873                 { $$ = NULL; }
874 |       EXTENDS_TK class_type
875                 { $$ = $2; }
876 |       EXTENDS_TK class_type error
877                 {yyerror ("'{' expected"); ctxp->class_err=1;}
878 |       EXTENDS_TK error
879                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
880 ;
881
882 interfaces:
883                 { $$ = NULL_TREE; }
884 |       IMPLEMENTS_TK interface_type_list
885                 { $$ = $2; }
886 |       IMPLEMENTS_TK error
887                 {
888                   ctxp->class_err=1;
889                   yyerror ("Missing interface name"); 
890                 }
891 ;
892
893 interface_type_list:
894         interface_type
895                 { 
896                   ctxp->interface_number = 1;
897                   $$ = build_tree_list ($1, NULL_TREE);
898                 }
899 |       interface_type_list C_TK interface_type
900                 { 
901                   ctxp->interface_number++;
902                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
903                 }
904 |       interface_type_list C_TK error
905                 {yyerror ("Missing interface name"); RECOVER;}
906 ;
907
908 class_body:
909         OCB_TK CCB_TK
910                 { 
911                   /* Store the location of the `}' when doing xrefs */
912                   if (flag_emit_xref)
913                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
914                       EXPR_WFL_ADD_COL ($2.location, 1);
915                   $$ = GET_CPC ();
916                 }
917 |       OCB_TK class_body_declarations CCB_TK
918                 { 
919                   /* Store the location of the `}' when doing xrefs */
920                   if (flag_emit_xref)
921                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
922                       EXPR_WFL_ADD_COL ($3.location, 1);
923                   $$ = GET_CPC ();
924                 }
925 ;
926
927 class_body_declarations:
928         class_body_declaration
929 |       class_body_declarations class_body_declaration
930 ;
931
932 class_body_declaration:
933         class_member_declaration
934 |       static_initializer
935 |       constructor_declaration
936 |       block                   /* Added, JDK1.1, instance initializer */
937                 {
938                   if ($1 != empty_stmt_node)
939                     {
940                       TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
941                       SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
942                     }
943                 }
944 ;
945
946 class_member_declaration:
947         field_declaration
948 |       method_declaration
949 |       class_declaration       /* Added, JDK1.1 inner classes */
950                 { end_class_declaration (1); }
951 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
952                 { end_class_declaration (1); }
953 |       empty_statement
954 ;
955
956 /* 19.8.2 Productions from 8.3: Field Declarations  */
957 field_declaration:
958         type variable_declarators SC_TK
959                 { register_fields (0, $1, $2); }
960 |       modifiers type variable_declarators SC_TK
961                 {
962                   check_modifiers 
963                     ("Illegal modifier `%s' for field declaration",
964                      $1, FIELD_MODIFIERS);
965                   check_modifiers_consistency ($1);
966                   register_fields ($1, $2, $3);
967                 }
968 ;
969
970 variable_declarators:
971         /* Should we use build_decl_list () instead ? FIXME */
972         variable_declarator     /* Default rule */
973 |       variable_declarators C_TK variable_declarator
974                 { $$ = chainon ($1, $3); }
975 |       variable_declarators C_TK error
976                 {yyerror ("Missing term"); RECOVER;}
977 ;
978
979 variable_declarator:
980         variable_declarator_id
981                 { $$ = build_tree_list ($1, NULL_TREE); }
982 |       variable_declarator_id ASSIGN_TK variable_initializer
983                 { 
984                   if (java_error_count)
985                     $3 = NULL_TREE;
986                   $$ = build_tree_list 
987                     ($1, build_assignment ($2.token, $2.location, $1, $3));
988                 }
989 |       variable_declarator_id ASSIGN_TK error
990                 {
991                   yyerror ("Missing variable initializer");
992                   $$ = build_tree_list ($1, NULL_TREE);
993                   RECOVER;
994                 }
995 |       variable_declarator_id ASSIGN_TK variable_initializer error
996                 {
997                   yyerror ("';' expected");
998                   $$ = build_tree_list ($1, NULL_TREE);
999                   RECOVER;
1000                 }
1001 ;
1002
1003 variable_declarator_id:
1004         identifier
1005 |       variable_declarator_id OSB_TK CSB_TK
1006                 { $$ = build_unresolved_array_type ($1); }
1007 |       identifier error
1008                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
1009 |       variable_declarator_id OSB_TK error
1010                 { 
1011                   tree node = java_lval.node;
1012                   if (node && (TREE_CODE (node) == INTEGER_CST
1013                                || TREE_CODE (node) == EXPR_WITH_FILE_LOCATION))
1014                     yyerror ("Can't specify array dimension in a declaration");
1015                   else
1016                     yyerror ("']' expected");
1017                   DRECOVER(vdi);
1018                 }
1019 |       variable_declarator_id CSB_TK error
1020                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
1021 ;
1022
1023 variable_initializer:
1024         expression
1025 |       array_initializer
1026 ;
1027
1028 /* 19.8.3 Productions from 8.4: Method Declarations  */
1029 method_declaration:
1030         method_header 
1031                 {
1032                   current_function_decl = $1;
1033                   if (current_function_decl
1034                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
1035                     source_start_java_method (current_function_decl);
1036                   else
1037                     current_function_decl = NULL_TREE;
1038                 }
1039         method_body
1040                 { finish_method_declaration ($3); }
1041 |       method_header error
1042                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
1043 ;
1044
1045 method_header:  
1046         type method_declarator throws
1047                 { $$ = method_header (0, $1, $2, $3); }
1048 |       VOID_TK method_declarator throws
1049                 { $$ = method_header (0, void_type_node, $2, $3); }
1050 |       modifiers type method_declarator throws
1051                 { $$ = method_header ($1, $2, $3, $4); }
1052 |       modifiers VOID_TK method_declarator throws
1053                 { $$ = method_header ($1, void_type_node, $3, $4); }
1054 |       type error
1055                 {
1056                   yyerror ("Invalid method declaration, method name required");
1057                   RECOVER;
1058                 }
1059 |       modifiers type error
1060                 {RECOVER;}
1061 |       VOID_TK error
1062                 {yyerror ("Identifier expected"); RECOVER;}
1063 |       modifiers VOID_TK error
1064                 {yyerror ("Identifier expected"); RECOVER;}
1065 |       modifiers error
1066                 {
1067                   yyerror ("Invalid method declaration, return type required");
1068                   RECOVER;
1069                 }
1070 ;
1071
1072 method_declarator:
1073         identifier OP_TK CP_TK
1074                 { 
1075                   ctxp->formal_parameter_number = 0;
1076                   $$ = method_declarator ($1, NULL_TREE);
1077                 }
1078 |       identifier OP_TK formal_parameter_list CP_TK
1079                 { $$ = method_declarator ($1, $3); }
1080 |       method_declarator OSB_TK CSB_TK
1081                 {
1082                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1083                   TREE_PURPOSE ($1) = 
1084                     build_unresolved_array_type (TREE_PURPOSE ($1));
1085                   parse_warning_context 
1086                     (wfl_operator, 
1087                      "Discouraged form of returned type specification");
1088                 }
1089 |       identifier OP_TK error
1090                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1091 |       method_declarator OSB_TK error
1092                 {yyerror ("']' expected"); RECOVER;}
1093 ;
1094
1095 formal_parameter_list:
1096         formal_parameter
1097                 {
1098                   ctxp->formal_parameter_number = 1;
1099                 }
1100 |       formal_parameter_list C_TK formal_parameter
1101                 {
1102                   ctxp->formal_parameter_number += 1;
1103                   $$ = chainon ($1, $3);
1104                 }
1105 |       formal_parameter_list C_TK error
1106                 { yyerror ("Missing formal parameter term"); RECOVER; }
1107 ;
1108
1109 formal_parameter:
1110         type variable_declarator_id
1111                 {
1112                   $$ = build_tree_list ($2, $1);
1113                 }
1114 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1115                 { 
1116                   $$ = build_tree_list ($3, $2);
1117                   ARG_FINAL_P ($$) = 1;
1118                 }
1119 |       type error
1120                 {
1121                   yyerror ("Missing identifier"); RECOVER;
1122                   $$ = NULL_TREE;
1123                 }
1124 |       final type error
1125                 {
1126                   yyerror ("Missing identifier"); RECOVER;
1127                   $$ = NULL_TREE;
1128                 }
1129 ;
1130
1131 final:
1132         modifiers
1133                 {
1134                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1135                                    $1, ACC_FINAL);
1136                   if ($1 != ACC_FINAL)
1137                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1138                 }
1139 ;
1140
1141 throws:
1142                 { $$ = NULL_TREE; }
1143 |       THROWS_TK class_type_list
1144                 { $$ = $2; }
1145 |       THROWS_TK error
1146                 {yyerror ("Missing class type term"); RECOVER;}
1147 ;
1148
1149 class_type_list:
1150         class_type
1151                 { $$ = build_tree_list ($1, $1); }
1152 |       class_type_list C_TK class_type
1153                 { $$ = tree_cons ($3, $3, $1); }
1154 |       class_type_list C_TK error
1155                 {yyerror ("Missing class type term"); RECOVER;}
1156 ;
1157
1158 method_body:
1159         block
1160 |       SC_TK { $$ = NULL_TREE; }
1161 ;
1162
1163 /* 19.8.4 Productions from 8.5: Static Initializers  */
1164 static_initializer:
1165         static block
1166                 {
1167                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1168                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1169                   current_static_block = NULL_TREE;
1170                 }
1171 ;
1172
1173 static:                         /* Test lval.sub_token here */
1174         modifiers
1175                 {
1176                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1177                   /* Can't have a static initializer in an innerclass */
1178                   if ($1 | ACC_STATIC &&
1179                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1180                     parse_error_context 
1181                       (MODIFIER_WFL (STATIC_TK),
1182                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1183                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1184                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1185                 }
1186 ;
1187
1188 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1189 constructor_declaration:
1190         constructor_header
1191                 {
1192                   current_function_decl = $1;
1193                   source_start_java_method (current_function_decl);
1194                 }
1195         constructor_body
1196                 { finish_method_declaration ($3); }
1197 ;
1198
1199 constructor_header:
1200         constructor_declarator throws
1201                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1202 |       modifiers constructor_declarator throws
1203                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1204 ;
1205
1206 constructor_declarator:
1207         simple_name OP_TK CP_TK
1208                 { 
1209                   ctxp->formal_parameter_number = 0;  
1210                   $$ = method_declarator ($1, NULL_TREE);
1211                 }
1212 |       simple_name OP_TK formal_parameter_list CP_TK
1213                 { $$ = method_declarator ($1, $3); }
1214 ;
1215
1216 constructor_body:
1217         /* Unlike regular method, we always need a complete (empty)
1218            body so we can safely perform all the required code
1219            addition (super invocation and field initialization) */
1220         block_begin constructor_block_end
1221                 { 
1222                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1223                   $$ = $2;
1224                 }
1225 |       block_begin explicit_constructor_invocation constructor_block_end
1226                 { $$ = $3; }
1227 |       block_begin block_statements constructor_block_end
1228                 { $$ = $3; }
1229 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1230                 { $$ = $4; }
1231 ;
1232
1233 constructor_block_end:
1234         block_end
1235 ;
1236
1237 /* Error recovery for that rule moved down expression_statement: rule.  */
1238 explicit_constructor_invocation:
1239         this_or_super OP_TK CP_TK SC_TK
1240                 { 
1241                   $$ = build_method_invocation ($1, NULL_TREE); 
1242                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1243                   $$ = java_method_add_stmt (current_function_decl, $$);
1244                 }
1245 |       this_or_super OP_TK argument_list CP_TK SC_TK
1246                 { 
1247                   $$ = build_method_invocation ($1, $3); 
1248                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1249                   $$ = java_method_add_stmt (current_function_decl, $$);
1250                 }
1251         /* Added, JDK1.1 inner classes. Modified because the rule
1252            'primary' couldn't work.  */
1253 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1254                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1255 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1256                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1257 ;
1258
1259 this_or_super:                  /* Added, simplifies error diagnostics */
1260         THIS_TK
1261                 {
1262                   tree wfl = build_wfl_node (this_identifier_node);
1263                   EXPR_WFL_LINECOL (wfl) = $1.location;
1264                   $$ = wfl;
1265                 }
1266 |       SUPER_TK
1267                 {
1268                   tree wfl = build_wfl_node (super_identifier_node);
1269                   EXPR_WFL_LINECOL (wfl) = $1.location;
1270                   $$ = wfl;
1271                 }
1272 ;
1273
1274 /* 19.9 Productions from 9: Interfaces  */
1275 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1276 interface_declaration:
1277         INTERFACE_TK identifier
1278                 { create_interface (0, $2, NULL_TREE); }
1279         interface_body
1280 |       modifiers INTERFACE_TK identifier
1281                 { create_interface ($1, $3, NULL_TREE); }
1282         interface_body
1283 |       INTERFACE_TK identifier extends_interfaces
1284                 { create_interface (0, $2, $3); }
1285         interface_body
1286 |       modifiers INTERFACE_TK identifier extends_interfaces
1287                 { create_interface ($1, $3, $4); }
1288         interface_body
1289 |       INTERFACE_TK identifier error
1290                 {yyerror ("'{' expected"); RECOVER;}
1291 |       modifiers INTERFACE_TK identifier error
1292                 {yyerror ("'{' expected"); RECOVER;}
1293 ;
1294
1295 extends_interfaces:
1296         EXTENDS_TK interface_type
1297                 { 
1298                   ctxp->interface_number = 1;
1299                   $$ = build_tree_list ($2, NULL_TREE);
1300                 }
1301 |       extends_interfaces C_TK interface_type
1302                 { 
1303                   ctxp->interface_number++;
1304                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1305                 }
1306 |       EXTENDS_TK error
1307                 {yyerror ("Invalid interface type"); RECOVER;}
1308 |       extends_interfaces C_TK error
1309                 {yyerror ("Missing term"); RECOVER;}
1310 ;
1311
1312 interface_body:
1313         OCB_TK CCB_TK
1314                 { $$ = NULL_TREE; }
1315 |       OCB_TK interface_member_declarations CCB_TK
1316                 { $$ = NULL_TREE; }
1317 ;
1318
1319 interface_member_declarations:
1320         interface_member_declaration
1321 |       interface_member_declarations interface_member_declaration
1322 ;
1323
1324 interface_member_declaration:
1325         constant_declaration
1326 |       abstract_method_declaration
1327 |       class_declaration       /* Added, JDK1.1 inner classes */
1328                 { end_class_declaration (1); }
1329 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1330                 { end_class_declaration (1); }
1331 ;
1332
1333 constant_declaration:
1334         field_declaration
1335 ;
1336
1337 abstract_method_declaration:
1338         method_header SC_TK
1339                 { 
1340                   check_abstract_method_header ($1);
1341                   current_function_decl = NULL_TREE; /* FIXME ? */
1342                 }
1343 |       method_header error
1344                 {yyerror ("';' expected"); RECOVER;}
1345 ;
1346
1347 /* 19.10 Productions from 10: Arrays  */
1348 array_initializer:
1349         OCB_TK CCB_TK
1350                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1351 |       OCB_TK C_TK CCB_TK
1352                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1353 |       OCB_TK variable_initializers CCB_TK
1354                 { $$ = build_new_array_init ($1.location, $2); }
1355 |       OCB_TK variable_initializers C_TK CCB_TK
1356                 { $$ = build_new_array_init ($1.location, $2); }
1357 ;
1358
1359 variable_initializers:
1360         variable_initializer
1361                 { 
1362                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1363                                   $1, NULL_TREE);
1364                 }
1365 |       variable_initializers C_TK variable_initializer
1366                 {
1367                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1368                 }
1369 |       variable_initializers C_TK error
1370                 {yyerror ("Missing term"); RECOVER;}
1371 ;
1372
1373 /* 19.11 Production from 14: Blocks and Statements  */
1374 block:
1375         OCB_TK CCB_TK
1376                 { 
1377                   /* Store the location of the `}' when doing xrefs */
1378                   if (current_function_decl && flag_emit_xref)
1379                     DECL_END_SOURCE_LINE (current_function_decl) = 
1380                       EXPR_WFL_ADD_COL ($2.location, 1);
1381                   $$ = empty_stmt_node; 
1382                 }
1383 |       block_begin block_statements block_end
1384                 { $$ = $3; }
1385 ;
1386
1387 block_begin:
1388         OCB_TK
1389                 { enter_block (); }
1390 ;
1391
1392 block_end:
1393         CCB_TK
1394                 { 
1395                   maybe_absorb_scoping_blocks ();
1396                   /* Store the location of the `}' when doing xrefs */
1397                   if (current_function_decl && flag_emit_xref)
1398                     DECL_END_SOURCE_LINE (current_function_decl) = 
1399                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1400                   $$ = exit_block ();
1401                   if (!BLOCK_SUBBLOCKS ($$))
1402                     BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
1403                 }
1404 ;
1405
1406 block_statements:
1407         block_statement
1408 |       block_statements block_statement
1409 ;
1410
1411 block_statement:
1412         local_variable_declaration_statement
1413 |       statement
1414                 { java_method_add_stmt (current_function_decl, $1); }
1415 |       class_declaration       /* Added, JDK1.1 local classes */
1416                 { 
1417                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1418                   end_class_declaration (1);
1419                 }
1420 ;
1421
1422 local_variable_declaration_statement:
1423         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1424 ;
1425
1426 local_variable_declaration:
1427         type variable_declarators
1428                 { declare_local_variables (0, $1, $2); }
1429 |       final type variable_declarators /* Added, JDK1.1 final locals */
1430                 { declare_local_variables ($1, $2, $3); }
1431 ;
1432
1433 statement:
1434         statement_without_trailing_substatement
1435 |       labeled_statement
1436 |       if_then_statement
1437 |       if_then_else_statement
1438 |       while_statement
1439 |       for_statement
1440                 { $$ = exit_block (); }
1441 ;
1442
1443 statement_nsi:
1444         statement_without_trailing_substatement
1445 |       labeled_statement_nsi
1446 |       if_then_else_statement_nsi
1447 |       while_statement_nsi
1448 |       for_statement_nsi
1449                 { $$ = exit_block (); }
1450 ;
1451
1452 statement_without_trailing_substatement:
1453         block
1454 |       empty_statement
1455 |       expression_statement
1456 |       switch_statement
1457 |       do_statement
1458 |       break_statement
1459 |       continue_statement
1460 |       return_statement
1461 |       synchronized_statement
1462 |       throw_statement
1463 |       try_statement
1464 ;
1465
1466 empty_statement:
1467         SC_TK
1468                 { 
1469                   if (flag_extraneous_semicolon 
1470                       && ! current_static_block 
1471                       && (! current_function_decl || 
1472                           /* Verify we're not in a inner class declaration */
1473                           (GET_CPC () != TYPE_NAME
1474                            (DECL_CONTEXT (current_function_decl)))))
1475                            
1476                     {
1477                       EXPR_WFL_SET_LINECOL (wfl_operator, lineno, -1);
1478                       parse_warning_context (wfl_operator, "An empty declaration is a deprecated feature that should not be used");
1479                     }
1480                   $$ = empty_stmt_node;
1481                 }
1482 ;
1483
1484 label_decl:
1485         identifier REL_CL_TK
1486                 {
1487                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1488                                             EXPR_WFL_NODE ($1));
1489                   pushlevel (2);
1490                   push_labeled_block ($$);
1491                   PUSH_LABELED_BLOCK ($$);
1492                 }
1493 ;
1494
1495 labeled_statement:
1496         label_decl statement
1497                 { $$ = finish_labeled_statement ($1, $2); }
1498 |       identifier error
1499                 {yyerror ("':' expected"); RECOVER;}
1500 ;
1501
1502 labeled_statement_nsi:
1503         label_decl statement_nsi
1504                 { $$ = finish_labeled_statement ($1, $2); }
1505 ;
1506
1507 /* We concentrate here a bunch of error handling rules that we couldn't write
1508    earlier, because expression_statement catches a missing ';'.  */
1509 expression_statement:
1510         statement_expression SC_TK
1511                 {
1512                   /* We have a statement. Generate a WFL around it so
1513                      we can debug it */
1514                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1515                   /* We know we have a statement, so set the debug
1516                      info to be eventually generate here. */
1517                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1518                 }
1519 |       error SC_TK 
1520                 {
1521                   YYNOT_TWICE yyerror ("Invalid expression statement");
1522                   DRECOVER (expr_stmt);
1523                 }
1524 |       error OCB_TK
1525                 {
1526                   YYNOT_TWICE yyerror ("Invalid expression statement");
1527                   DRECOVER (expr_stmt);
1528                 }
1529 |       error CCB_TK
1530                 {
1531                   YYNOT_TWICE yyerror ("Invalid expression statement");
1532                   DRECOVER (expr_stmt);
1533                 }
1534 |       this_or_super OP_TK error
1535                 {yyerror ("')' expected"); RECOVER;}
1536 |       this_or_super OP_TK CP_TK error
1537                 {
1538                   parse_ctor_invocation_error ();
1539                   RECOVER;
1540                 }
1541 |       this_or_super OP_TK argument_list error
1542                 {yyerror ("')' expected"); RECOVER;}
1543 |       this_or_super OP_TK argument_list CP_TK error
1544                 {
1545                   parse_ctor_invocation_error ();
1546                   RECOVER;
1547                 }
1548 |       name DOT_TK SUPER_TK error
1549                 {yyerror ("'(' expected"); RECOVER;}
1550 |       name DOT_TK SUPER_TK OP_TK error
1551                 {yyerror ("')' expected"); RECOVER;}
1552 |       name DOT_TK SUPER_TK OP_TK argument_list error
1553                 {yyerror ("')' expected"); RECOVER;}
1554 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1555                 {yyerror ("';' expected"); RECOVER;}
1556 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1557                 {yyerror ("';' expected"); RECOVER;}
1558 ;
1559
1560 statement_expression: 
1561         assignment
1562 |       pre_increment_expression
1563 |       pre_decrement_expression
1564 |       post_increment_expression
1565 |       post_decrement_expression
1566 |       method_invocation
1567 |       class_instance_creation_expression
1568 ;
1569
1570 if_then_statement:
1571         IF_TK OP_TK expression CP_TK statement
1572                 { 
1573                   $$ = build_if_else_statement ($2.location, $3, 
1574                                                 $5, NULL_TREE);
1575                 }
1576 |       IF_TK error
1577                 {yyerror ("'(' expected"); RECOVER;}
1578 |       IF_TK OP_TK error
1579                 {yyerror ("Missing term"); RECOVER;}
1580 |       IF_TK OP_TK expression error
1581                 {yyerror ("')' expected"); RECOVER;}
1582 ;
1583
1584 if_then_else_statement:
1585         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1586                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1587 ;
1588
1589 if_then_else_statement_nsi:
1590         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1591                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1592 ;
1593
1594 switch_statement:
1595         switch_expression
1596                 {
1597                   enter_block ();
1598                 }
1599         switch_block
1600                 { 
1601                   /* Make into "proper list" of COMPOUND_EXPRs.
1602                      I.e. make the last statment also have its own
1603                      COMPOUND_EXPR. */
1604                   maybe_absorb_scoping_blocks ();
1605                   TREE_OPERAND ($1, 1) = exit_block ();
1606                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1607                 }
1608 ;
1609
1610 switch_expression:
1611         SWITCH_TK OP_TK expression CP_TK
1612                 { 
1613                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1614                   EXPR_WFL_LINECOL ($$) = $2.location;
1615                 }
1616 |       SWITCH_TK error
1617                 {yyerror ("'(' expected"); RECOVER;}
1618 |       SWITCH_TK OP_TK error
1619                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1620 |       SWITCH_TK OP_TK expression CP_TK error
1621                 {yyerror ("'{' expected"); RECOVER;}
1622 ;
1623
1624 /* Default assignment is there to avoid type node on switch_block
1625    node. */
1626
1627 switch_block:
1628         OCB_TK CCB_TK
1629                 { $$ = NULL_TREE; }
1630 |       OCB_TK switch_labels CCB_TK
1631                 { $$ = NULL_TREE; }
1632 |       OCB_TK switch_block_statement_groups CCB_TK
1633                 { $$ = NULL_TREE; }
1634 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1635                 { $$ = NULL_TREE; }
1636 ;
1637
1638 switch_block_statement_groups: 
1639         switch_block_statement_group
1640 |       switch_block_statement_groups switch_block_statement_group
1641 ;
1642
1643 switch_block_statement_group:
1644         switch_labels block_statements
1645 ;
1646
1647 switch_labels:
1648         switch_label
1649 |       switch_labels switch_label
1650 ;
1651
1652 switch_label:
1653         CASE_TK constant_expression REL_CL_TK
1654                 { 
1655                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1656                   EXPR_WFL_LINECOL (lab) = $1.location;
1657                   java_method_add_stmt (current_function_decl, lab);
1658                 }
1659 |       DEFAULT_TK REL_CL_TK
1660                 { 
1661                   tree lab = build (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1662                   EXPR_WFL_LINECOL (lab) = $1.location;
1663                   java_method_add_stmt (current_function_decl, lab);
1664                 }
1665 |       CASE_TK error
1666                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1667 |       CASE_TK constant_expression error
1668                 {yyerror ("':' expected"); RECOVER;}
1669 |       DEFAULT_TK error
1670                 {yyerror ("':' expected"); RECOVER;}
1671 ;
1672
1673 while_expression:
1674         WHILE_TK OP_TK expression CP_TK
1675                 { 
1676                   tree body = build_loop_body ($2.location, $3, 0);
1677                   $$ = build_new_loop (body);
1678                 }
1679 ;
1680
1681 while_statement:
1682         while_expression statement
1683                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1684 |       WHILE_TK error
1685                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1686 |       WHILE_TK OP_TK error
1687                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1688 |       WHILE_TK OP_TK expression error
1689                 {yyerror ("')' expected"); RECOVER;}
1690 ;
1691
1692 while_statement_nsi:
1693         while_expression statement_nsi
1694                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1695 ;
1696
1697 do_statement_begin:
1698         DO_TK
1699                 { 
1700                   tree body = build_loop_body (0, NULL_TREE, 1);
1701                   $$ = build_new_loop (body);
1702                 }
1703         /* Need error handing here. FIXME */
1704 ;
1705
1706 do_statement: 
1707         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1708                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1709 ;
1710
1711 for_statement:
1712         for_begin SC_TK expression SC_TK for_update CP_TK statement
1713                 {
1714                   if (TREE_CODE_CLASS (TREE_CODE ($3)) == 'c')
1715                     $3 = build_wfl_node ($3);
1716                   $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);
1717                 }
1718 |       for_begin SC_TK SC_TK for_update CP_TK statement
1719                 { 
1720                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1721                   /* We have not condition, so we get rid of the EXIT_EXPR */
1722                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1723                     empty_stmt_node;
1724                 }
1725 |       for_begin SC_TK error
1726                 {yyerror ("Invalid control expression"); RECOVER;}
1727 |       for_begin SC_TK expression SC_TK error
1728                 {yyerror ("Invalid update expression"); RECOVER;}
1729 |       for_begin SC_TK SC_TK error
1730                 {yyerror ("Invalid update expression"); RECOVER;}
1731 ;
1732
1733 for_statement_nsi:
1734         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1735                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1736 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1737                 { 
1738                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1739                   /* We have not condition, so we get rid of the EXIT_EXPR */
1740                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1741                     empty_stmt_node;
1742                 }
1743 ;
1744
1745 for_header:
1746         FOR_TK OP_TK
1747                 { 
1748                   /* This scope defined for local variable that may be
1749                      defined within the scope of the for loop */
1750                   enter_block (); 
1751                 }
1752 |       FOR_TK error
1753                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1754 |       FOR_TK OP_TK error
1755                 {yyerror ("Invalid init statement"); RECOVER;}
1756 ;
1757
1758 for_begin:
1759         for_header for_init
1760                 { 
1761                   /* We now declare the loop body. The loop is
1762                      declared as a for loop. */
1763                   tree body = build_loop_body (0, NULL_TREE, 0);
1764                   $$ =  build_new_loop (body);
1765                   FOR_LOOP_P ($$) = 1;
1766                   /* The loop is added to the current block the for
1767                      statement is defined within */
1768                   java_method_add_stmt (current_function_decl, $$);
1769                 }
1770 ;
1771 for_init:                       /* Can be empty */
1772                 { $$ = empty_stmt_node; }
1773 |       statement_expression_list
1774                 { 
1775                   /* Init statement recorded within the previously
1776                      defined block scope */
1777                   $$ = java_method_add_stmt (current_function_decl, $1);
1778                 }
1779 |       local_variable_declaration
1780                 { 
1781                   /* Local variable are recorded within the previously
1782                      defined block scope */
1783                   $$ = NULL_TREE;
1784                 }
1785 |       statement_expression_list error
1786                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1787 ;
1788
1789 for_update:                     /* Can be empty */
1790                 {$$ = empty_stmt_node;}
1791 |       statement_expression_list
1792                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1793 ;
1794
1795 statement_expression_list:
1796         statement_expression
1797                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1798 |       statement_expression_list C_TK statement_expression
1799                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1800 |       statement_expression_list C_TK error
1801                 {yyerror ("Missing term"); RECOVER;}
1802 ;
1803
1804 break_statement:
1805         BREAK_TK SC_TK
1806                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1807 |       BREAK_TK identifier SC_TK
1808                 { $$ = build_bc_statement ($1.location, 1, $2); }
1809 |       BREAK_TK error
1810                 {yyerror ("Missing term"); RECOVER;}
1811 |       BREAK_TK identifier error
1812                 {yyerror ("';' expected"); RECOVER;}
1813 ;
1814
1815 continue_statement:
1816         CONTINUE_TK SC_TK
1817                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1818 |       CONTINUE_TK identifier SC_TK
1819                 { $$ = build_bc_statement ($1.location, 0, $2); }
1820 |       CONTINUE_TK error
1821                 {yyerror ("Missing term"); RECOVER;}
1822 |       CONTINUE_TK identifier error
1823                 {yyerror ("';' expected"); RECOVER;}
1824 ;
1825
1826 return_statement:
1827         RETURN_TK SC_TK
1828                 { $$ = build_return ($1.location, NULL_TREE); }
1829 |       RETURN_TK expression SC_TK
1830                 { $$ = build_return ($1.location, $2); }
1831 |       RETURN_TK error
1832                 {yyerror ("Missing term"); RECOVER;}
1833 |       RETURN_TK expression error
1834                 {yyerror ("';' expected"); RECOVER;}
1835 ;
1836
1837 throw_statement:
1838         THROW_TK expression SC_TK
1839                 { 
1840                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1841                   EXPR_WFL_LINECOL ($$) = $1.location;
1842                 }
1843 |       THROW_TK error
1844                 {yyerror ("Missing term"); RECOVER;}
1845 |       THROW_TK expression error
1846                 {yyerror ("';' expected"); RECOVER;}
1847 ;
1848
1849 synchronized_statement:
1850         synchronized OP_TK expression CP_TK block
1851                 { 
1852                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1853                   EXPR_WFL_LINECOL ($$) = 
1854                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1855                 }
1856 |       synchronized OP_TK expression CP_TK error
1857                 {yyerror ("'{' expected"); RECOVER;}
1858 |       synchronized error
1859                 {yyerror ("'(' expected"); RECOVER;}
1860 |       synchronized OP_TK error CP_TK
1861                 {yyerror ("Missing term"); RECOVER;}
1862 |       synchronized OP_TK error
1863                 {yyerror ("Missing term"); RECOVER;}
1864 ;
1865
1866 synchronized:
1867         modifiers
1868                 {
1869                   check_modifiers (
1870              "Illegal modifier `%s'. Only `synchronized' was expected here",
1871                                    $1, ACC_SYNCHRONIZED);
1872                   if ($1 != ACC_SYNCHRONIZED)
1873                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1874                       build_wfl_node (NULL_TREE);
1875                 }
1876 ;
1877
1878 try_statement:
1879         TRY_TK block catches
1880                 { $$ = build_try_statement ($1.location, $2, $3); }
1881 |       TRY_TK block finally
1882                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1883 |       TRY_TK block catches finally
1884                 { $$ = build_try_finally_statement 
1885                     ($1.location, build_try_statement ($1.location,
1886                                                        $2, $3), $4);
1887                 }
1888 |       TRY_TK error
1889                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1890 ;
1891
1892 catches:
1893         catch_clause
1894 |       catches catch_clause
1895                 { 
1896                   TREE_CHAIN ($2) = $1;
1897                   $$ = $2;
1898                 }
1899 ;
1900
1901 catch_clause:
1902         catch_clause_parameter block
1903                 { 
1904                   java_method_add_stmt (current_function_decl, $2);
1905                   exit_block ();
1906                   $$ = $1;
1907                 }
1908
1909 catch_clause_parameter:
1910         CATCH_TK OP_TK formal_parameter CP_TK
1911                 { 
1912                   /* We add a block to define a scope for
1913                      formal_parameter (CCBP). The formal parameter is
1914                      declared initialized by the appropriate function
1915                      call */
1916                   tree ccpb = enter_block ();
1917                   tree init = build_assignment
1918                     (ASSIGN_TK, $2.location, TREE_PURPOSE ($3), 
1919                      build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
1920                   declare_local_variables (0, TREE_VALUE ($3),
1921                                            build_tree_list (TREE_PURPOSE ($3),
1922                                                             init));
1923                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1924                   EXPR_WFL_LINECOL ($$) = $1.location;
1925                 }
1926 |       CATCH_TK error
1927                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1928 |       CATCH_TK OP_TK error 
1929                 {
1930                   yyerror ("Missing term or ')' expected"); 
1931                   RECOVER; $$ = NULL_TREE;
1932                 }
1933 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1934                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1935 ;
1936
1937 finally:
1938         FINALLY_TK block
1939                 { $$ = $2; }
1940 |       FINALLY_TK error
1941                 {yyerror ("'{' expected"); RECOVER; }
1942 ;
1943
1944 /* 19.12 Production from 15: Expressions  */
1945 primary:
1946         primary_no_new_array
1947 |       array_creation_expression
1948 ;
1949
1950 primary_no_new_array:
1951         literal
1952 |       THIS_TK
1953                 { $$ = build_this ($1.location); }
1954 |       OP_TK expression CP_TK
1955                 {$$ = $2;}
1956 |       class_instance_creation_expression
1957 |       field_access
1958 |       method_invocation
1959 |       array_access
1960 |       type_literals
1961         /* Added, JDK1.1 inner classes. Documentation is wrong
1962            refering to a 'ClassName' (class_name) rule that doesn't
1963            exist. Used name: instead.  */
1964 |       name DOT_TK THIS_TK
1965                 { 
1966                   tree wfl = build_wfl_node (this_identifier_node);
1967                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1968                 }
1969 |       OP_TK expression error 
1970                 {yyerror ("')' expected"); RECOVER;}
1971 |       name DOT_TK error
1972                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1973 |       primitive_type DOT_TK error
1974                 {yyerror ("'class' expected" ); RECOVER;}
1975 |       VOID_TK DOT_TK error
1976                 {yyerror ("'class' expected" ); RECOVER;}
1977 ;
1978
1979 type_literals:
1980         name DOT_TK CLASS_TK
1981                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1982 |       array_type DOT_TK CLASS_TK
1983                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1984 |       primitive_type DOT_TK CLASS_TK
1985                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1986 |       VOID_TK DOT_TK CLASS_TK
1987                 { 
1988                    $$ = build_incomplete_class_ref ($2.location,
1989                                                    void_type_node);
1990                 }
1991 ;
1992
1993 class_instance_creation_expression:
1994         NEW_TK class_type OP_TK argument_list CP_TK
1995                 { $$ = build_new_invocation ($2, $4); }
1996 |       NEW_TK class_type OP_TK CP_TK
1997                 { $$ = build_new_invocation ($2, NULL_TREE); }
1998 |       anonymous_class_creation
1999         /* Added, JDK1.1 inner classes, modified to use name or
2000            primary instead of primary solely which couldn't work in
2001            all situations.  */
2002 |       something_dot_new identifier OP_TK CP_TK
2003                 { 
2004                   tree ctor = build_new_invocation ($2, NULL_TREE);
2005                   $$ = make_qualified_primary ($1, ctor, 
2006                                                EXPR_WFL_LINECOL ($1));
2007                 }
2008 |       something_dot_new identifier OP_TK CP_TK class_body
2009 |       something_dot_new identifier OP_TK argument_list CP_TK
2010                 { 
2011                   tree ctor = build_new_invocation ($2, $4);
2012                   $$ = make_qualified_primary ($1, ctor, 
2013                                                EXPR_WFL_LINECOL ($1));
2014                 }
2015 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
2016 |       NEW_TK error SC_TK 
2017                 {yyerror ("'(' expected"); DRECOVER(new_1);}
2018 |       NEW_TK class_type error
2019                 {yyerror ("'(' expected"); RECOVER;}
2020 |       NEW_TK class_type OP_TK error
2021                 {yyerror ("')' or term expected"); RECOVER;}
2022 |       NEW_TK class_type OP_TK argument_list error
2023                 {yyerror ("')' expected"); RECOVER;}
2024 |       something_dot_new error
2025                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
2026 |       something_dot_new identifier error
2027                 {yyerror ("'(' expected"); RECOVER;}
2028 ;
2029
2030 /* Created after JDK1.1 rules originally added to
2031    class_instance_creation_expression, but modified to use
2032    'class_type' instead of 'TypeName' (type_name) which is mentionned
2033    in the documentation but doesn't exist. */
2034
2035 anonymous_class_creation:
2036         NEW_TK class_type OP_TK argument_list CP_TK 
2037                 { create_anonymous_class ($1.location, $2); }
2038         class_body
2039                 { 
2040                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2041                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2042
2043                   end_class_declaration (1);
2044
2045                   /* Now we can craft the new expression */
2046                   $$ = build_new_invocation (id, $4);
2047
2048                   /* Note that we can't possibly be here if
2049                      `class_type' is an interface (in which case the
2050                      anonymous class extends Object and implements
2051                      `class_type', hence its constructor can't have
2052                      arguments.) */
2053
2054                   /* Otherwise, the innerclass must feature a
2055                      constructor matching `argument_list'. Anonymous
2056                      classes are a bit special: it's impossible to
2057                      define constructor for them, hence constructors
2058                      must be generated following the hints provided by
2059                      the `new' expression. Whether a super constructor
2060                      of that nature exists or not is to be verified
2061                      later on in verify_constructor_super. 
2062
2063                      It's during the expansion of a `new' statement
2064                      refering to an anonymous class that a ctor will
2065                      be generated for the anonymous class, with the
2066                      right arguments. */
2067
2068                 }
2069 |       NEW_TK class_type OP_TK CP_TK 
2070                 { create_anonymous_class ($1.location, $2); }
2071         class_body         
2072                 { 
2073                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2074                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2075
2076                   end_class_declaration (1);
2077
2078                   /* Now we can craft the new expression. The
2079                      statement doesn't need to be remember so that a
2080                      constructor can be generated, since its signature
2081                      is already known. */
2082                   $$ = build_new_invocation (id, NULL_TREE);
2083                 }
2084 ;
2085
2086 something_dot_new:              /* Added, not part of the specs. */
2087         name DOT_TK NEW_TK
2088                 { $$ = $1; }
2089 |       primary DOT_TK NEW_TK
2090                 { $$ = $1; }
2091 ;
2092
2093 argument_list:
2094         expression
2095                 { 
2096                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2097                   ctxp->formal_parameter_number = 1; 
2098                 }
2099 |       argument_list C_TK expression
2100                 {
2101                   ctxp->formal_parameter_number += 1;
2102                   $$ = tree_cons (NULL_TREE, $3, $1);
2103                 }
2104 |       argument_list C_TK error
2105                 {yyerror ("Missing term"); RECOVER;}
2106 ;
2107
2108 array_creation_expression:
2109         NEW_TK primitive_type dim_exprs
2110                 { $$ = build_newarray_node ($2, $3, 0); }
2111 |       NEW_TK class_or_interface_type dim_exprs
2112                 { $$ = build_newarray_node ($2, $3, 0); }
2113 |       NEW_TK primitive_type dim_exprs dims
2114                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2115 |       NEW_TK class_or_interface_type dim_exprs dims
2116                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2117         /* Added, JDK1.1 anonymous array. Initial documentation rule
2118            modified */
2119 |       NEW_TK class_or_interface_type dims array_initializer
2120                 {
2121                   char *sig;
2122                   int osb = pop_current_osb (ctxp);
2123                   while (osb--)
2124                     obstack_1grow (&temporary_obstack, '[');
2125                   sig = obstack_finish (&temporary_obstack);
2126                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2127                               $2, get_identifier (sig), $4);
2128                 }
2129 |       NEW_TK primitive_type dims array_initializer
2130                 { 
2131                   int osb = pop_current_osb (ctxp);
2132                   tree type = $2;
2133                   while (osb--)
2134                     type = build_java_array_type (type, -1);
2135                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2136                               build_pointer_type (type), NULL_TREE, $4);
2137                 }
2138 |       NEW_TK error CSB_TK
2139                 {yyerror ("'[' expected"); DRECOVER ("]");}
2140 |       NEW_TK error OSB_TK
2141                 {yyerror ("']' expected"); RECOVER;}
2142 ;
2143
2144 dim_exprs:
2145         dim_expr
2146                 { $$ = build_tree_list (NULL_TREE, $1); }
2147 |       dim_exprs dim_expr
2148                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2149 ;
2150
2151 dim_expr:
2152         OSB_TK expression CSB_TK
2153                 { 
2154                   if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
2155                     {
2156                       $2 = build_wfl_node ($2);
2157                       TREE_TYPE ($2) = NULL_TREE;
2158                     }
2159                   EXPR_WFL_LINECOL ($2) = $1.location;
2160                   $$ = $2;
2161                 }
2162 |       OSB_TK expression error
2163                 {yyerror ("']' expected"); RECOVER;}
2164 |       OSB_TK error
2165                 {
2166                   yyerror ("Missing term");
2167                   yyerror ("']' expected");
2168                   RECOVER;
2169                 }
2170 ;
2171
2172 dims:                           
2173         OSB_TK CSB_TK
2174                 { 
2175                   int allocate = 0;
2176                   /* If not initialized, allocate memory for the osb
2177                      numbers stack */
2178                   if (!ctxp->osb_limit)
2179                     {
2180                       allocate = ctxp->osb_limit = 32;
2181                       ctxp->osb_depth = -1;
2182                     }
2183                   /* If capacity overflown, reallocate a bigger chunk */
2184                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2185                     allocate = ctxp->osb_limit << 1;
2186                   
2187                   if (allocate)
2188                     {
2189                       allocate *= sizeof (int);
2190                       if (ctxp->osb_number)
2191                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2192                                                             allocate);
2193                       else
2194                         ctxp->osb_number = (int *)xmalloc (allocate);
2195                     }
2196                   ctxp->osb_depth++;
2197                   CURRENT_OSB (ctxp) = 1;
2198                 }
2199 |       dims OSB_TK CSB_TK
2200                 { CURRENT_OSB (ctxp)++; }
2201 |       dims OSB_TK error
2202                 { yyerror ("']' expected"); RECOVER;}
2203 ;
2204
2205 field_access:
2206         primary DOT_TK identifier
2207                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2208                 /*  FIXME - REWRITE TO: 
2209                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2210 |       SUPER_TK DOT_TK identifier
2211                 {
2212                   tree super_wfl = build_wfl_node (super_identifier_node);
2213                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2214                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2215                 }
2216 |       SUPER_TK error
2217                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2218 ;
2219
2220 method_invocation:
2221         name OP_TK CP_TK
2222                 { $$ = build_method_invocation ($1, NULL_TREE); }
2223 |       name OP_TK argument_list CP_TK
2224                 { $$ = build_method_invocation ($1, $3); }
2225 |       primary DOT_TK identifier OP_TK CP_TK
2226                 { 
2227                   if (TREE_CODE ($1) == THIS_EXPR)
2228                     $$ = build_this_super_qualified_invocation 
2229                       (1, $3, NULL_TREE, 0, $2.location);
2230                   else
2231                     {
2232                       tree invok = build_method_invocation ($3, NULL_TREE);
2233                       $$ = make_qualified_primary ($1, invok, $2.location);
2234                     }
2235                 }
2236 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2237                 { 
2238                   if (TREE_CODE ($1) == THIS_EXPR)
2239                     $$ = build_this_super_qualified_invocation 
2240                       (1, $3, $5, 0, $2.location);
2241                   else
2242                     {
2243                       tree invok = build_method_invocation ($3, $5);
2244                       $$ = make_qualified_primary ($1, invok, $2.location);
2245                     }
2246                 }
2247 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2248                 { 
2249                   $$ = build_this_super_qualified_invocation 
2250                     (0, $3, NULL_TREE, $1.location, $2.location);
2251                 }
2252 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2253                 {
2254                   $$ = build_this_super_qualified_invocation 
2255                     (0, $3, $5, $1.location, $2.location);
2256                 }
2257         /* Screws up thing. I let it here until I'm convinced it can
2258            be removed. FIXME
2259 |       primary DOT_TK error
2260                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2261 |       SUPER_TK DOT_TK error CP_TK
2262                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2263 |       SUPER_TK DOT_TK error DOT_TK
2264                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2265 ;
2266
2267 array_access:
2268         name OSB_TK expression CSB_TK
2269                 { $$ = build_array_ref ($2.location, $1, $3); }
2270 |       primary_no_new_array OSB_TK expression CSB_TK
2271                 { $$ = build_array_ref ($2.location, $1, $3); }
2272 |       name OSB_TK error
2273                 {
2274                   yyerror ("Missing term and ']' expected");
2275                   DRECOVER(array_access);
2276                 }
2277 |       name OSB_TK expression error
2278                 {
2279                   yyerror ("']' expected");
2280                   DRECOVER(array_access);
2281                 }
2282 |       primary_no_new_array OSB_TK error
2283                 {
2284                   yyerror ("Missing term and ']' expected");
2285                   DRECOVER(array_access);
2286                 }
2287 |       primary_no_new_array OSB_TK expression error
2288                 {
2289                   yyerror ("']' expected");
2290                   DRECOVER(array_access);
2291                 }
2292 ;
2293
2294 postfix_expression:
2295         primary
2296 |       name
2297 |       post_increment_expression
2298 |       post_decrement_expression
2299 ;
2300
2301 post_increment_expression:
2302         postfix_expression INCR_TK
2303                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2304 ;
2305
2306 post_decrement_expression:
2307         postfix_expression DECR_TK
2308                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2309 ;
2310
2311 unary_expression:
2312         pre_increment_expression
2313 |       pre_decrement_expression
2314 |       PLUS_TK unary_expression
2315                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2316 |       MINUS_TK unary_expression
2317                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2318 |       unary_expression_not_plus_minus
2319 |       PLUS_TK error
2320                 {yyerror ("Missing term"); RECOVER}
2321 |       MINUS_TK error
2322                 {yyerror ("Missing term"); RECOVER}
2323 ;
2324
2325 pre_increment_expression:
2326         INCR_TK unary_expression
2327                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2328 |       INCR_TK error
2329                 {yyerror ("Missing term"); RECOVER}
2330 ;
2331
2332 pre_decrement_expression:
2333         DECR_TK unary_expression
2334                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2335 |       DECR_TK error
2336                 {yyerror ("Missing term"); RECOVER}
2337 ;
2338
2339 unary_expression_not_plus_minus:
2340         postfix_expression
2341 |       NOT_TK unary_expression
2342                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2343 |       NEG_TK unary_expression
2344                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2345 |       cast_expression
2346 |       NOT_TK error
2347                 {yyerror ("Missing term"); RECOVER}
2348 |       NEG_TK error
2349                 {yyerror ("Missing term"); RECOVER}
2350 ;
2351
2352 cast_expression:                /* Error handling here is potentially weak */
2353         OP_TK primitive_type dims CP_TK unary_expression
2354                 { 
2355                   tree type = $2;
2356                   int osb = pop_current_osb (ctxp);
2357                   while (osb--)
2358                     type = build_java_array_type (type, -1);
2359                   $$ = build_cast ($1.location, type, $5); 
2360                 }
2361 |       OP_TK primitive_type CP_TK unary_expression
2362                 { $$ = build_cast ($1.location, $2, $4); }
2363 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2364                 { $$ = build_cast ($1.location, $2, $4); }
2365 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2366                 { 
2367                   const char *ptr;
2368                   int osb = pop_current_osb (ctxp); 
2369                   while (osb--)
2370                     obstack_1grow (&temporary_obstack, '[');
2371                   obstack_grow0 (&temporary_obstack, 
2372                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2373                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2374                   ptr = obstack_finish (&temporary_obstack);
2375                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2376                   $$ = build_cast ($1.location, $2, $5);
2377                 }
2378 |       OP_TK primitive_type OSB_TK error
2379                 {yyerror ("']' expected, invalid type expression");}
2380 |       OP_TK error
2381                 {
2382                   YYNOT_TWICE yyerror ("Invalid type expression"); RECOVER;
2383                   RECOVER;
2384                 }
2385 |       OP_TK primitive_type dims CP_TK error
2386                 {yyerror ("Missing term"); RECOVER;}
2387 |       OP_TK primitive_type CP_TK error
2388                 {yyerror ("Missing term"); RECOVER;}
2389 |       OP_TK name dims CP_TK error
2390                 {yyerror ("Missing term"); RECOVER;}
2391 ;
2392
2393 multiplicative_expression:
2394         unary_expression
2395 |       multiplicative_expression MULT_TK unary_expression
2396                 { 
2397                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2398                                     $2.location, $1, $3);
2399                 }
2400 |       multiplicative_expression DIV_TK unary_expression
2401                 {
2402                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2403                                     $1, $3); 
2404                 }
2405 |       multiplicative_expression REM_TK unary_expression
2406                 {
2407                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2408                                     $1, $3); 
2409                 }
2410 |       multiplicative_expression MULT_TK error
2411                 {yyerror ("Missing term"); RECOVER;}
2412 |       multiplicative_expression DIV_TK error
2413                 {yyerror ("Missing term"); RECOVER;}
2414 |       multiplicative_expression REM_TK error
2415                 {yyerror ("Missing term"); RECOVER;}
2416 ;
2417
2418 additive_expression:
2419         multiplicative_expression
2420 |       additive_expression PLUS_TK multiplicative_expression
2421                 {
2422                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2423                                     $1, $3); 
2424                 }
2425 |       additive_expression MINUS_TK multiplicative_expression
2426                 {
2427                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2428                                     $1, $3); 
2429                 }
2430 |       additive_expression PLUS_TK error
2431                 {yyerror ("Missing term"); RECOVER;}
2432 |       additive_expression MINUS_TK error
2433                 {yyerror ("Missing term"); RECOVER;}
2434 ;
2435
2436 shift_expression:
2437         additive_expression
2438 |       shift_expression LS_TK additive_expression
2439                 {
2440                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2441                                     $1, $3); 
2442                 }
2443 |       shift_expression SRS_TK additive_expression
2444                 {
2445                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2446                                     $1, $3); 
2447                 }
2448 |       shift_expression ZRS_TK additive_expression
2449                 {
2450                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2451                                     $1, $3); 
2452                 }
2453 |       shift_expression LS_TK error
2454                 {yyerror ("Missing term"); RECOVER;}
2455 |       shift_expression SRS_TK error
2456                 {yyerror ("Missing term"); RECOVER;}
2457 |       shift_expression ZRS_TK error
2458                 {yyerror ("Missing term"); RECOVER;}
2459 ;
2460
2461 relational_expression:
2462         shift_expression
2463 |       relational_expression LT_TK shift_expression
2464                 {
2465                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2466                                     $1, $3); 
2467                 }
2468 |       relational_expression GT_TK shift_expression
2469                 {
2470                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2471                                     $1, $3); 
2472                 }
2473 |       relational_expression LTE_TK shift_expression
2474                 {
2475                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2476                                     $1, $3); 
2477                 }
2478 |       relational_expression GTE_TK shift_expression
2479                 {
2480                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2481                                     $1, $3); 
2482                 }
2483 |       relational_expression INSTANCEOF_TK reference_type
2484                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2485 |       relational_expression LT_TK error
2486                 {yyerror ("Missing term"); RECOVER;}
2487 |       relational_expression GT_TK error
2488                 {yyerror ("Missing term"); RECOVER;}
2489 |       relational_expression LTE_TK error
2490                 {yyerror ("Missing term"); RECOVER;}
2491 |       relational_expression GTE_TK error
2492                 {yyerror ("Missing term"); RECOVER;}
2493 |       relational_expression INSTANCEOF_TK error
2494                 {yyerror ("Invalid reference type"); RECOVER;}
2495 ;
2496
2497 equality_expression:
2498         relational_expression
2499 |       equality_expression EQ_TK relational_expression
2500                 {
2501                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2502                                     $1, $3); 
2503                 }
2504 |       equality_expression NEQ_TK relational_expression
2505                 {
2506                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2507                                     $1, $3); 
2508                 }
2509 |       equality_expression EQ_TK error
2510                 {yyerror ("Missing term"); RECOVER;}
2511 |       equality_expression NEQ_TK error
2512                 {yyerror ("Missing term"); RECOVER;}
2513 ;
2514
2515 and_expression:
2516         equality_expression
2517 |       and_expression AND_TK equality_expression
2518                 {
2519                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2520                                     $1, $3); 
2521                 }
2522 |       and_expression AND_TK error
2523                 {yyerror ("Missing term"); RECOVER;}
2524 ;
2525
2526 exclusive_or_expression:
2527         and_expression
2528 |       exclusive_or_expression XOR_TK and_expression
2529                 {
2530                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2531                                     $1, $3); 
2532                 }
2533 |       exclusive_or_expression XOR_TK error
2534                 {yyerror ("Missing term"); RECOVER;}
2535 ;
2536
2537 inclusive_or_expression:
2538         exclusive_or_expression
2539 |       inclusive_or_expression OR_TK exclusive_or_expression
2540                 {
2541                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2542                                     $1, $3); 
2543                 }
2544 |       inclusive_or_expression OR_TK error
2545                 {yyerror ("Missing term"); RECOVER;}
2546 ;
2547
2548 conditional_and_expression:
2549         inclusive_or_expression
2550 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2551                 {
2552                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2553                                     $1, $3); 
2554                 }
2555 |       conditional_and_expression BOOL_AND_TK error
2556                 {yyerror ("Missing term"); RECOVER;}
2557 ;
2558
2559 conditional_or_expression:
2560         conditional_and_expression
2561 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2562                 {
2563                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2564                                     $1, $3); 
2565                 }
2566 |       conditional_or_expression BOOL_OR_TK error
2567                 {yyerror ("Missing term"); RECOVER;}
2568 ;
2569
2570 conditional_expression:         /* Error handling here is weak */
2571         conditional_or_expression
2572 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2573                 {
2574                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2575                   EXPR_WFL_LINECOL ($$) = $2.location;
2576                 }
2577 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2578                 {
2579                   YYERROR_NOW;
2580                   yyerror ("Missing term");
2581                   DRECOVER (1);
2582                 }
2583 |       conditional_or_expression REL_QM_TK error
2584                 {yyerror ("Missing term"); DRECOVER (2);}
2585 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2586                 {yyerror ("Missing term"); DRECOVER (3);}
2587 ;
2588
2589 assignment_expression:
2590         conditional_expression
2591 |       assignment
2592 ;
2593
2594 assignment:
2595         left_hand_side assignment_operator assignment_expression
2596                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2597 |       left_hand_side assignment_operator error
2598                 {
2599                   YYNOT_TWICE yyerror ("Missing term");
2600                   DRECOVER (assign);
2601                 }
2602 ;
2603
2604 left_hand_side:
2605         name
2606 |       field_access
2607 |       array_access
2608 ;
2609
2610 assignment_operator:
2611         ASSIGN_ANY_TK
2612 |       ASSIGN_TK
2613 ;
2614
2615 expression:
2616         assignment_expression
2617 ;
2618
2619 constant_expression:
2620         expression
2621 ;
2622
2623 %%
2624
2625 /* Helper function to retrieve an OSB count. Should be used when the
2626    `dims:' rule is being used.  */
2627
2628 static int
2629 pop_current_osb (ctxp)
2630      struct parser_ctxt *ctxp;
2631 {
2632   int to_return;
2633
2634   if (ctxp->osb_depth < 0)
2635     abort ();
2636   
2637   to_return = CURRENT_OSB (ctxp);
2638   ctxp->osb_depth--;
2639   
2640   return to_return;
2641 }
2642
2643 \f
2644
2645 /* This section of the code deal with save/restoring parser contexts.
2646    Add mode documentation here. FIXME */
2647
2648 /* Helper function. Create a new parser context. With
2649    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2650    context is copied, otherwise, the new context is zeroed. The newly
2651    created context becomes the current one.  */
2652
2653 static void
2654 create_new_parser_context (copy_from_previous)
2655     int copy_from_previous;
2656 {
2657   struct parser_ctxt *new;
2658
2659   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2660   if (copy_from_previous)
2661     {
2662       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2663       new->saved_data_ctx = 1;
2664     }
2665   else
2666     memset ((PTR) new, 0, sizeof (struct parser_ctxt));
2667       
2668   new->next = ctxp;
2669   ctxp = new;
2670 }
2671
2672 /* Create a new parser context and make it the current one. */
2673
2674 void
2675 java_push_parser_context ()
2676 {
2677   create_new_parser_context (0);
2678 }  
2679
2680 void 
2681 java_pop_parser_context (generate)
2682      int generate;
2683 {
2684   tree current;
2685   struct parser_ctxt *toFree, *next;
2686
2687   if (!ctxp)
2688     return;
2689
2690   toFree = ctxp;
2691   next = ctxp->next;
2692   if (next)
2693     {
2694       lineno = ctxp->lineno;
2695       current_class = ctxp->class_type;
2696     }
2697
2698   /* If the old and new lexers differ, then free the old one.  */
2699   if (ctxp->lexer && next && ctxp->lexer != next->lexer)
2700     java_destroy_lexer (ctxp->lexer);
2701
2702   /* Set the single import class file flag to 0 for the current list
2703      of imported things */
2704   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2705     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 0;
2706
2707   /* And restore those of the previous context */
2708   if ((ctxp = next))            /* Assignment is really meant here */
2709     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2710       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1;
2711   
2712   /* If we pushed a context to parse a class intended to be generated,
2713      we keep it so we can remember the class. What we could actually
2714      do is to just update a list of class names.  */
2715   if (generate)
2716     {
2717       toFree->next = ctxp_for_generation;
2718       ctxp_for_generation = toFree;
2719     }
2720   else
2721     free (toFree);
2722 }
2723
2724 /* Create a parser context for the use of saving some global
2725    variables.  */
2726
2727 void
2728 java_parser_context_save_global ()
2729 {
2730   if (!ctxp)
2731     {
2732       java_push_parser_context ();
2733       ctxp->saved_data_ctx = 1;
2734     }
2735
2736   /* If this context already stores data, create a new one suitable
2737      for data storage. */
2738   else if (ctxp->saved_data)
2739     create_new_parser_context (1);
2740
2741   ctxp->lineno = lineno;
2742   ctxp->class_type = current_class;
2743   ctxp->filename = input_filename;
2744   ctxp->function_decl = current_function_decl;
2745   ctxp->saved_data = 1;
2746 }
2747
2748 /* Restore some global variables from the previous context. Make the
2749    previous context the current one.  */
2750
2751 void
2752 java_parser_context_restore_global ()
2753 {
2754   lineno = ctxp->lineno;
2755   current_class = ctxp->class_type;
2756   input_filename = ctxp->filename;
2757   if (wfl_operator)
2758     {
2759       tree s;
2760       BUILD_FILENAME_IDENTIFIER_NODE (s, input_filename);
2761       EXPR_WFL_FILENAME_NODE (wfl_operator) = s;
2762     }
2763   current_function_decl = ctxp->function_decl;
2764   ctxp->saved_data = 0;
2765   if (ctxp->saved_data_ctx)
2766     java_pop_parser_context (0);
2767 }
2768
2769 /* Suspend vital data for the current class/function being parsed so
2770    that an other class can be parsed. Used to let local/anonymous
2771    classes be parsed.  */
2772
2773 static void
2774 java_parser_context_suspend ()
2775 {
2776   /* This makes debugging through java_debug_context easier */
2777   static const char *name = "<inner buffer context>";
2778
2779   /* Duplicate the previous context, use it to save the globals we're
2780      interested in */
2781   create_new_parser_context (1);
2782   ctxp->function_decl = current_function_decl;
2783   ctxp->class_type = current_class;
2784
2785   /* Then create a new context which inherits all data from the
2786      previous one. This will be the new current context  */
2787   create_new_parser_context (1);
2788
2789   /* Help debugging */
2790   ctxp->next->filename = name;
2791 }
2792
2793 /* Resume vital data for the current class/function being parsed so
2794    that an other class can be parsed. Used to let local/anonymous
2795    classes be parsed.  The trick is the data storing file position
2796    informations must be restored to their current value, so parsing
2797    can resume as if no context was ever saved. */
2798
2799 static void
2800 java_parser_context_resume ()
2801 {
2802   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2803   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2804   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2805
2806   /* We need to inherit the list of classes to complete/generate */
2807   restored->classd_list = old->classd_list;
2808   restored->class_list = old->class_list;
2809
2810   /* Restore the current class and function from the saver */
2811   current_class = saver->class_type;
2812   current_function_decl = saver->function_decl;
2813
2814   /* Retrive the restored context */
2815   ctxp = restored;
2816
2817   /* Re-installed the data for the parsing to carry on */
2818   memcpy (&ctxp->marker_begining, &old->marker_begining, 
2819           (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2820
2821   /* Buffer context can now be discarded */
2822   free (saver);
2823   free (old);
2824 }
2825
2826 /* Add a new anchor node to which all statement(s) initializing static
2827    and non static initialized upon declaration field(s) will be
2828    linked.  */
2829
2830 static void
2831 java_parser_context_push_initialized_field ()
2832 {
2833   tree node;
2834
2835   node = build_tree_list (NULL_TREE, NULL_TREE);
2836   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2837   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2838
2839   node = build_tree_list (NULL_TREE, NULL_TREE);
2840   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2841   CPC_INITIALIZER_LIST (ctxp) = node;
2842
2843   node = build_tree_list (NULL_TREE, NULL_TREE);
2844   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2845   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2846 }
2847
2848 /* Pop the lists of initialized field. If this lists aren't empty,
2849    remember them so we can use it to create and populate the finit$
2850    or <clinit> functions. */
2851
2852 static void
2853 java_parser_context_pop_initialized_field ()
2854 {
2855   tree stmts;
2856   tree class_type = TREE_TYPE (GET_CPC ());
2857
2858   if (CPC_INITIALIZER_LIST (ctxp))
2859     {
2860       stmts = CPC_INITIALIZER_STMT (ctxp);
2861       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2862       if (stmts && !java_error_count)
2863         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2864     }
2865
2866   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2867     {
2868       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2869       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2870         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2871       /* Keep initialization in order to enforce 8.5 */
2872       if (stmts && !java_error_count)
2873         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2874     }
2875
2876   /* JDK 1.1 instance initializers */
2877   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2878     {
2879       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2880       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2881         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2882       if (stmts && !java_error_count)
2883         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2884     }
2885 }
2886
2887 static tree
2888 reorder_static_initialized (list)
2889      tree list;
2890 {
2891   /* We have to keep things in order. The alias initializer have to
2892      come first, then the initialized regular field, in reverse to
2893      keep them in lexical order. */
2894   tree marker, previous = NULL_TREE;
2895   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2896     if (TREE_CODE (marker) == TREE_LIST 
2897         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2898       break;
2899   
2900   /* No static initialized, the list is fine as is */
2901   if (!previous)
2902     list = TREE_CHAIN (marker);
2903
2904   /* No marker? reverse the whole list */
2905   else if (!marker)
2906     list = nreverse (list);
2907
2908   /* Otherwise, reverse what's after the marker and the new reordered
2909      sublist will replace the marker. */
2910   else
2911     {
2912       TREE_CHAIN (previous) = NULL_TREE;
2913       list = nreverse (list);
2914       list = chainon (TREE_CHAIN (marker), list);
2915     }
2916   return list;
2917 }
2918
2919 /* Helper functions to dump the parser context stack.  */
2920
2921 #define TAB_CONTEXT(C) \
2922   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2923
2924 static void
2925 java_debug_context_do (tab)
2926      int tab;
2927 {
2928   struct parser_ctxt *copy = ctxp;
2929   while (copy)
2930     {
2931       TAB_CONTEXT (tab);
2932       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2933       TAB_CONTEXT (tab);
2934       fprintf (stderr, "filename: %s\n", copy->filename);
2935       TAB_CONTEXT (tab);
2936       fprintf (stderr, "lineno: %d\n", copy->lineno);
2937       TAB_CONTEXT (tab);
2938       fprintf (stderr, "package: %s\n",
2939                (copy->package ? 
2940                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2941       TAB_CONTEXT (tab);
2942       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2943       TAB_CONTEXT (tab);
2944       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2945       copy = copy->next;
2946       tab += 2;
2947     }
2948 }
2949
2950 /* Dump the stacked up parser contexts. Intended to be called from a
2951    debugger.  */
2952
2953 void
2954 java_debug_context ()
2955 {
2956   java_debug_context_do (0);
2957 }
2958
2959 \f
2960
2961 /* Flag for the error report routine to issue the error the first time
2962    it's called (overriding the default behavior which is to drop the
2963    first invocation and honor the second one, taking advantage of a
2964    richer context.  */
2965 static int force_error = 0;
2966
2967 /* Reporting an constructor invocation error.  */
2968 static void
2969 parse_ctor_invocation_error ()
2970 {
2971   if (DECL_CONSTRUCTOR_P (current_function_decl))
2972     yyerror ("Constructor invocation must be first thing in a constructor"); 
2973   else
2974     yyerror ("Only constructors can invoke constructors");
2975 }
2976
2977 /* Reporting JDK1.1 features not implemented.  */
2978
2979 static tree
2980 parse_jdk1_1_error (msg)
2981     const char *msg;
2982 {
2983   sorry (": `%s' JDK1.1(TM) feature", msg);
2984   java_error_count++;
2985   return empty_stmt_node;
2986 }
2987
2988 static int do_warning = 0;
2989
2990 void
2991 yyerror (msg)
2992      const char *msg;
2993 {
2994   static java_lc elc;
2995   static int  prev_lineno;
2996   static const char *prev_msg;
2997
2998   int save_lineno;
2999   char *remainder, *code_from_source;
3000   
3001   if (!force_error && prev_lineno == lineno)
3002     return;
3003
3004   /* Save current error location but report latter, when the context is
3005      richer.  */
3006   if (ctxp->java_error_flag == 0)
3007     {
3008       ctxp->java_error_flag = 1;
3009       elc = ctxp->elc;
3010       /* Do something to use the previous line if we're reaching the
3011          end of the file... */
3012 #ifdef VERBOSE_SKELETON
3013       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
3014 #endif
3015       return;
3016     }
3017
3018   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
3019   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
3020     return;
3021
3022   ctxp->java_error_flag = 0;
3023   if (do_warning)
3024     java_warning_count++;
3025   else
3026     java_error_count++;
3027   
3028   if (elc.col == 0 && msg && msg[1] == ';')
3029     {
3030       elc.col  = ctxp->p_line->char_col-1;
3031       elc.line = ctxp->p_line->lineno;
3032     }
3033
3034   save_lineno = lineno;
3035   prev_lineno = lineno = elc.line;
3036   prev_msg = msg;
3037
3038   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
3039   obstack_grow0 (&temporary_obstack, 
3040                  code_from_source, strlen (code_from_source));
3041   remainder = obstack_finish (&temporary_obstack);
3042   if (do_warning)
3043     warning ("%s.\n%s", msg, remainder);
3044   else
3045     error ("%s.\n%s", msg, remainder);
3046
3047   /* This allow us to cheaply avoid an extra 'Invalid expression
3048      statement' error report when errors have been already reported on
3049      the same line. This occurs when we report an error but don't have
3050      a synchronization point other than ';', which
3051      expression_statement is the only one to take care of.  */
3052   ctxp->prevent_ese = lineno = save_lineno;
3053 }
3054
3055 static void
3056 issue_warning_error_from_context (cl, msg, ap)
3057      tree cl;
3058      const char *msg;
3059      va_list ap;
3060 {
3061   const char *saved, *saved_input_filename;
3062   char buffer [4096];
3063   vsprintf (buffer, msg, ap);
3064   force_error = 1;
3065
3066   ctxp->elc.line = EXPR_WFL_LINENO (cl);
3067   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
3068                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
3069
3070   /* We have a CL, that's a good reason for using it if it contains data */
3071   saved = ctxp->filename;
3072   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
3073     ctxp->filename = EXPR_WFL_FILENAME (cl);
3074   saved_input_filename = input_filename;
3075   input_filename = ctxp->filename;
3076   java_error (NULL);
3077   java_error (buffer);
3078   ctxp->filename = saved;
3079   input_filename = saved_input_filename;
3080   force_error = 0;
3081 }
3082
3083 /* Issue an error message at a current source line CL */
3084
3085 void
3086 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
3087 {
3088 #ifndef ANSI_PROTOTYPES
3089   tree cl;
3090   const char *msg;
3091 #endif
3092   va_list ap;
3093
3094   VA_START (ap, msg);
3095 #ifndef ANSI_PROTOTYPES
3096   cl = va_arg (ap, tree);
3097   msg = va_arg (ap, const char *);
3098 #endif
3099   issue_warning_error_from_context (cl, msg, ap);
3100   va_end (ap);
3101 }
3102
3103 /* Issue a warning at a current source line CL */
3104
3105 static void
3106 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3107 {
3108 #ifndef ANSI_PROTOTYPES
3109   tree cl;
3110   const char *msg;
3111 #endif
3112   va_list ap;
3113
3114   VA_START (ap, msg);
3115 #ifndef ANSI_PROTOTYPES
3116   cl = va_arg (ap, tree);
3117   msg = va_arg (ap, const char *);
3118 #endif
3119
3120   force_error = do_warning = 1;
3121   issue_warning_error_from_context (cl, msg, ap);
3122   do_warning = force_error = 0;
3123   va_end (ap);
3124 }
3125
3126 static tree
3127 find_expr_with_wfl (node)
3128      tree node;
3129 {
3130   while (node)
3131     {
3132       char code;
3133       tree to_return;
3134
3135       switch (TREE_CODE (node))
3136         {
3137         case BLOCK:
3138           node = BLOCK_EXPR_BODY (node);
3139           continue;
3140
3141         case COMPOUND_EXPR:
3142           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3143           if (to_return)
3144             return to_return;
3145           node = TREE_OPERAND (node, 1);
3146           continue;
3147
3148         case LOOP_EXPR:
3149           node = TREE_OPERAND (node, 0);
3150           continue;
3151           
3152         case LABELED_BLOCK_EXPR:
3153           node = TREE_OPERAND (node, 1);
3154           continue;
3155
3156         default:
3157           code = TREE_CODE_CLASS (TREE_CODE (node));
3158           if (((code == '1') || (code == '2') || (code == 'e'))
3159               && EXPR_WFL_LINECOL (node))
3160             return node;
3161           return NULL_TREE;
3162         }
3163     }
3164   return NULL_TREE;
3165 }
3166
3167 /* Issue a missing return statement error. Uses METHOD to figure the
3168    last line of the method the error occurs in.  */
3169
3170 static void
3171 missing_return_error (method)
3172      tree method;
3173 {
3174   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3175   parse_error_context (wfl_operator, "Missing return statement");
3176 }
3177
3178 /* Issue an unreachable statement error. From NODE, find the next
3179    statement to report appropriately.  */
3180 static void
3181 unreachable_stmt_error (node)
3182      tree node;
3183 {
3184   /* Browse node to find the next expression node that has a WFL. Use
3185      the location to report the error */
3186   if (TREE_CODE (node) == COMPOUND_EXPR)
3187     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3188   else
3189     node = find_expr_with_wfl (node);
3190
3191   if (node)
3192     {
3193       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3194       parse_error_context (wfl_operator, "Unreachable statement");
3195     }
3196   else
3197     abort ();
3198 }
3199
3200 int
3201 java_report_errors ()
3202 {
3203   if (java_error_count)
3204     fprintf (stderr, "%d error%s", 
3205              java_error_count, (java_error_count == 1 ? "" : "s"));
3206   if (java_warning_count)
3207     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3208              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3209   if (java_error_count || java_warning_count)
3210     putc ('\n', stderr);
3211   return java_error_count;
3212 }
3213
3214 static char *
3215 java_accstring_lookup (flags)
3216      int flags;
3217 {
3218   static char buffer [80];
3219 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3220
3221   /* Access modifier looked-up first for easier report on forbidden
3222      access. */
3223   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3224   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3225   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3226   if (flags & ACC_STATIC) COPY_RETURN ("static");
3227   if (flags & ACC_FINAL) COPY_RETURN ("final");
3228   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3229   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3230   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3231   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3232   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3233   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3234
3235   buffer [0] = '\0';
3236   return buffer;
3237 #undef COPY_RETURN
3238 }
3239
3240 /* Issuing error messages upon redefinition of classes, interfaces or
3241    variables. */
3242
3243 static void
3244 classitf_redefinition_error (context, id, decl, cl)
3245      const char *context;
3246      tree id, decl, cl;
3247 {
3248   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3249                        context, IDENTIFIER_POINTER (id), 
3250                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3251   /* Here we should point out where its redefined. It's a unicode. FIXME */
3252 }
3253
3254 static void
3255 variable_redefinition_error (context, name, type, line)
3256      tree context, name, type;
3257      int line;
3258 {
3259   const char *type_name;
3260
3261   /* Figure a proper name for type. We might haven't resolved it */
3262   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3263     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3264   else
3265     type_name = lang_printable_name (type, 0);
3266
3267   parse_error_context (context,
3268                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3269                        IDENTIFIER_POINTER (name),
3270                        type_name, IDENTIFIER_POINTER (name), line);
3271 }
3272
3273 static tree
3274 build_array_from_name (type, type_wfl, name, ret_name)
3275      tree type, type_wfl, name, *ret_name;
3276 {
3277   int more_dims = 0;
3278   const char *string;
3279
3280   /* Eventually get more dims */
3281   string = IDENTIFIER_POINTER (name);
3282   while (string [more_dims] == '[')
3283     more_dims++;
3284   
3285   /* If we have, then craft a new type for this variable */
3286   if (more_dims)
3287     {
3288       tree save = type;
3289
3290       name = get_identifier (&string [more_dims]);
3291
3292       /* If we have a pointer, use its type */
3293       if (TREE_CODE (type) == POINTER_TYPE)
3294         type = TREE_TYPE (type);
3295
3296       /* Building the first dimension of a primitive type uses this
3297          function */
3298       if (JPRIMITIVE_TYPE_P (type))
3299         {
3300           type = build_java_array_type (type, -1);
3301           more_dims--;
3302         }
3303       /* Otherwise, if we have a WFL for this type, use it (the type
3304          is already an array on an unresolved type, and we just keep
3305          on adding dimensions) */
3306       else if (type_wfl)
3307         {
3308           int i = 0;
3309           type = type_wfl;
3310           string = IDENTIFIER_POINTER (TYPE_NAME (save));
3311           while (string[i]  == '[')
3312             ++i;
3313           more_dims += i;
3314         }
3315
3316       /* Add all the dimensions */
3317       while (more_dims--)
3318         type = build_unresolved_array_type (type);
3319
3320       /* The type may have been incomplete in the first place */
3321       if (type_wfl)
3322         type = obtain_incomplete_type (type);
3323     }
3324
3325   if (ret_name)
3326     *ret_name = name;
3327   return type;
3328 }
3329
3330 /* Build something that the type identifier resolver will identify as
3331    being an array to an unresolved type. TYPE_WFL is a WFL on a
3332    identifier. */
3333
3334 static tree
3335 build_unresolved_array_type (type_or_wfl)
3336      tree type_or_wfl;
3337 {
3338   const char *ptr;
3339   tree wfl;
3340
3341   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3342      just create a array type */
3343   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3344     return build_java_array_type (type_or_wfl, -1);
3345
3346   obstack_1grow (&temporary_obstack, '[');
3347   obstack_grow0 (&temporary_obstack,
3348                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3349                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3350   ptr = obstack_finish (&temporary_obstack);
3351   wfl = build_expr_wfl (get_identifier (ptr),
3352                         EXPR_WFL_FILENAME (type_or_wfl),
3353                         EXPR_WFL_LINENO (type_or_wfl),
3354                         EXPR_WFL_COLNO (type_or_wfl));
3355   /* Re-install the existing qualifications so that the type can be
3356      resolved properly. */
3357   EXPR_WFL_QUALIFICATION (wfl) = EXPR_WFL_QUALIFICATION (type_or_wfl);
3358   return wfl;
3359 }
3360
3361 static void
3362 parser_add_interface (class_decl, interface_decl, wfl)
3363      tree class_decl, interface_decl, wfl;
3364 {
3365   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3366     parse_error_context (wfl, "Interface `%s' repeated",
3367                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3368 }
3369
3370 /* Bulk of common class/interface checks. Return 1 if an error was
3371    encountered. TAG is 0 for a class, 1 for an interface.  */
3372
3373 static int
3374 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3375      int is_interface, flags;
3376      tree raw_name, qualified_name, decl, cl;
3377 {
3378   tree node;
3379   int sca = 0;                  /* Static class allowed */
3380   int icaf = 0;                 /* Inner class allowed flags */
3381   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3382
3383   if (!quiet_flag)
3384     fprintf (stderr, " %s%s %s", 
3385              (CPC_INNER_P () ? "inner" : ""),
3386              (is_interface ? "interface" : "class"), 
3387              IDENTIFIER_POINTER (qualified_name));
3388
3389   /* Scope of an interface/class type name:
3390        - Can't be imported by a single type import
3391        - Can't already exists in the package */
3392   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3393       && (node = find_name_in_single_imports (raw_name))
3394       && !CPC_INNER_P ())
3395     {
3396       parse_error_context 
3397         (cl, "%s name `%s' clashes with imported type `%s'",
3398          (is_interface ? "Interface" : "Class"),
3399          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3400       return 1;
3401     }
3402   if (decl && CLASS_COMPLETE_P (decl))
3403     {
3404       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3405                                    qualified_name, decl, cl);
3406       return 1;
3407     }
3408
3409   if (check_inner_class_redefinition (raw_name, cl))
3410     return 1;
3411
3412   /* If public, file name should match class/interface name, except
3413      when dealing with an inner class */
3414   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3415     {
3416       const char *f;
3417
3418       /* Contains OS dependent assumption on path separator. FIXME */
3419       for (f = &input_filename [strlen (input_filename)]; 
3420            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3421            f--)
3422         ;
3423       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3424         f++;
3425       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3426                    f , IDENTIFIER_LENGTH (raw_name)) ||
3427           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3428         parse_error_context
3429           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3430                              (is_interface ? "interface" : "class"),
3431                              IDENTIFIER_POINTER (qualified_name),
3432                              IDENTIFIER_POINTER (raw_name));
3433     }
3434
3435   /* Static classes can be declared only in top level classes. Note:
3436      once static, a inner class is a top level class. */
3437   if (flags & ACC_STATIC)
3438     {
3439       /* Catch the specific error of declaring an class inner class
3440          with no toplevel enclosing class. Prevent check_modifiers from
3441          complaining a second time */
3442       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3443         {
3444           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3445                                IDENTIFIER_POINTER (qualified_name));
3446           sca = ACC_STATIC;
3447         }
3448       /* Else, in the context of a top-level class declaration, let
3449          `check_modifiers' do its job, otherwise, give it a go */
3450       else
3451         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3452     }
3453
3454   /* Inner classes can be declared private or protected
3455      within their enclosing classes. */
3456   if (CPC_INNER_P ())
3457     {
3458       /* A class which is local to a block can't be public, private,
3459          protected or static. But it is created final, so allow this
3460          one. */
3461       if (current_function_decl)
3462         icaf = sca = uaaf = ACC_FINAL;
3463       else
3464         {
3465           check_modifiers_consistency (flags);
3466           icaf = ACC_PROTECTED;
3467           if (! CLASS_INTERFACE (GET_CPC ()))
3468             icaf |= ACC_PRIVATE;
3469         }
3470     }
3471
3472   if (is_interface) 
3473     {
3474       if (CPC_INNER_P ())
3475         uaaf = INTERFACE_INNER_MODIFIERS;
3476       else
3477         uaaf = INTERFACE_MODIFIERS;
3478       
3479       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3480                        flags, uaaf);
3481     }
3482   else
3483     check_modifiers ((current_function_decl ?
3484                       "Illegal modifier `%s' for local class declaration" :
3485                       "Illegal modifier `%s' for class declaration"),
3486                      flags, uaaf|sca|icaf);
3487   return 0;
3488 }
3489
3490 static void
3491 make_nested_class_name (cpc_list)
3492      tree cpc_list;
3493 {
3494   tree name;
3495
3496   if (!cpc_list)
3497     return;
3498   else
3499     make_nested_class_name (TREE_CHAIN (cpc_list));
3500
3501   /* Pick the qualified name when dealing with the first upmost
3502      enclosing class */
3503   name = (TREE_CHAIN (cpc_list) ? 
3504           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3505   obstack_grow (&temporary_obstack,
3506                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3507   /* Why is NO_DOLLAR_IN_LABEL defined? */
3508 #if 0
3509 #ifdef NO_DOLLAR_IN_LABEL
3510   internal_error ("Can't use '$' as a separator for inner classes");
3511 #endif
3512 #endif
3513   obstack_1grow (&temporary_obstack, '$');
3514 }
3515
3516 /* Can't redefine a class already defined in an earlier scope. */
3517
3518 static int
3519 check_inner_class_redefinition (raw_name, cl)
3520      tree raw_name, cl;
3521 {
3522   tree scope_list;
3523
3524   for (scope_list = GET_CPC_LIST (); scope_list; 
3525        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3526     if (raw_name == GET_CPC_UN_NODE (scope_list))
3527       {
3528         parse_error_context 
3529           (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",
3530            IDENTIFIER_POINTER (raw_name));
3531         return 1;
3532       }
3533   return 0;
3534 }
3535
3536 /* Tries to find a decl for CLASS_TYPE within ENCLOSING. If we fail,
3537    we remember ENCLOSING and SUPER.  */
3538
3539 static tree
3540 resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
3541      struct hash_table *circularity_hash;
3542      tree cl, *enclosing, *super, class_type;
3543 {
3544   tree local_enclosing = *enclosing;
3545   tree local_super = NULL_TREE;
3546
3547   while (local_enclosing)
3548     {
3549       tree intermediate, decl;
3550
3551       hash_lookup (circularity_hash, 
3552                    (const  hash_table_key) local_enclosing, TRUE, NULL);
3553
3554       if ((decl = find_as_inner_class (local_enclosing, class_type, cl)))
3555         return decl;
3556
3557       intermediate = local_enclosing;
3558       /* Explore enclosing contexts. */
3559       while (INNER_CLASS_DECL_P (intermediate))
3560         {
3561           intermediate = DECL_CONTEXT (intermediate);
3562           if ((decl = find_as_inner_class (intermediate, class_type, cl)))
3563             return decl;
3564         }
3565
3566       /* Now go to the upper classes, bail out if necessary. We will
3567          analyze the returned SUPER and act accordingly (see
3568          do_resolve_class.) */
3569       local_super = CLASSTYPE_SUPER (TREE_TYPE (local_enclosing));
3570       if (!local_super || local_super == object_type_node)
3571         break;
3572
3573       if (TREE_CODE (local_super) == POINTER_TYPE)
3574         local_super = do_resolve_class (NULL, local_super, NULL, NULL);
3575       else
3576         local_super = TYPE_NAME (local_super);
3577
3578       /* We may not have checked for circular inheritance yet, so do so
3579          here to prevent an infinite loop. */
3580       if (hash_lookup (circularity_hash,
3581                        (const hash_table_key) local_super, FALSE, NULL))
3582         {
3583           if (!cl)
3584             cl = lookup_cl (local_enclosing);
3585           
3586           parse_error_context
3587             (cl, "Cyclic inheritance involving %s",
3588              IDENTIFIER_POINTER (DECL_NAME (local_enclosing)));
3589           local_enclosing = NULL_TREE;
3590         }
3591       else
3592         local_enclosing = local_super;
3593     }
3594
3595   /* We failed. Return LOCAL_SUPER and LOCAL_ENCLOSING. */
3596   *super = local_super;
3597   *enclosing = local_enclosing;
3598
3599   return NULL_TREE;
3600 }
3601
3602 /* Within ENCLOSING, find a decl for NAME and return it. NAME can be
3603    qualified. */
3604
3605 static tree
3606 find_as_inner_class (enclosing, name, cl)
3607      tree enclosing, name, cl;
3608 {
3609   tree qual, to_return;
3610   if (!enclosing)
3611     return NULL_TREE;
3612
3613   name = TYPE_NAME (name);
3614
3615   /* First search: within the scope of `enclosing', search for name */
3616   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3617     qual = EXPR_WFL_QUALIFICATION (cl);
3618   else if (cl)
3619     qual = build_tree_list (cl, NULL_TREE);
3620   else
3621     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3622   
3623   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3624     return to_return;
3625
3626   /* We're dealing with a qualified name. Try to resolve thing until
3627      we get something that is an enclosing class. */
3628   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3629     {
3630       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3631
3632       for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3633            qual = TREE_CHAIN (qual))
3634         {
3635           acc = merge_qualified_name (acc, 
3636                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3637           BUILD_PTR_FROM_NAME (ptr, acc);
3638
3639           /* Don't try to resolve ACC as a class name if it follows
3640              the current package name. We don't want to pick something
3641              that's accidentally there: for example `a.b.c' in package
3642              `a.b' shouldn't trigger loading `a' if it's there by
3643              itself. */
3644           if (ctxp->package
3645               && strstr (IDENTIFIER_POINTER (ctxp->package),
3646                          IDENTIFIER_POINTER (acc)))
3647             decl = NULL;
3648           else
3649             decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3650         }
3651
3652       /* A NULL qual and a decl means that the search ended
3653          successfully?!? We have to do something then. FIXME */
3654       
3655       if (decl)
3656         enclosing = decl;
3657       else
3658         qual = EXPR_WFL_QUALIFICATION (cl);
3659     }
3660   /* Otherwise, create a qual for the other part of the resolution. */
3661   else
3662     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3663
3664   return find_as_inner_class_do (qual, enclosing);
3665 }
3666
3667 /* We go inside the list of sub classes and try to find a way
3668    through. */
3669
3670 static tree
3671 find_as_inner_class_do (qual, enclosing)
3672      tree qual, enclosing;
3673 {
3674   if (!qual)
3675     return NULL_TREE;
3676
3677   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3678     {
3679       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3680       tree next_enclosing = NULL_TREE;
3681       tree inner_list;
3682
3683       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3684            inner_list; inner_list = TREE_CHAIN (inner_list))
3685         {
3686           if (TREE_VALUE (inner_list) == name_to_match)
3687             {
3688               next_enclosing = TREE_PURPOSE (inner_list);
3689               break;
3690             }
3691         }
3692       enclosing = next_enclosing;
3693     }
3694
3695   return (!qual && enclosing ? enclosing : NULL_TREE);
3696 }
3697
3698 /* Reach all inner classes and tie their unqualified name to a
3699    DECL. */
3700
3701 static void
3702 set_nested_class_simple_name_value (outer, set)
3703      tree outer;
3704      int set;
3705 {
3706   tree l;
3707
3708   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3709     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3710                                                 TREE_PURPOSE (l) : NULL_TREE);
3711 }
3712
3713 static void
3714 link_nested_class_to_enclosing ()
3715 {
3716   if (GET_ENCLOSING_CPC ())
3717     {
3718       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3719       DECL_INNER_CLASS_LIST (enclosing) = 
3720         tree_cons (GET_CPC (), GET_CPC_UN (),
3721                    DECL_INNER_CLASS_LIST (enclosing));
3722       enclosing = enclosing;
3723     }
3724 }
3725
3726 static tree
3727 maybe_make_nested_class_name (name)
3728      tree name;
3729 {
3730   tree id = NULL_TREE;
3731
3732   if (CPC_INNER_P ())
3733     {
3734       make_nested_class_name (GET_CPC_LIST ());
3735       obstack_grow0 (&temporary_obstack,
3736                      IDENTIFIER_POINTER (name), 
3737                      IDENTIFIER_LENGTH (name));
3738       id = get_identifier (obstack_finish (&temporary_obstack));
3739       if (ctxp->package)
3740         QUALIFIED_P (id) = 1;
3741     }
3742   return id;
3743 }
3744
3745 /* If DECL is NULL, create and push a new DECL, record the current
3746    line CL and do other maintenance things.  */
3747
3748 static tree
3749 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3750      tree decl, raw_name, qualified_name, cl;
3751 {
3752   if (!decl)
3753     decl = push_class (make_class (), qualified_name);
3754
3755   /* Take care of the file and line business */
3756   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3757   /* If we're emiting xrefs, store the line/col number information */
3758   if (flag_emit_xref)
3759     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3760   else
3761     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3762   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3763   CLASS_PARSED_P (TREE_TYPE (decl)) = 1;
3764   CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) =
3765     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3766
3767   PUSH_CPC (decl, raw_name);
3768   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3769
3770   /* Link the declaration to the already seen ones */
3771   TREE_CHAIN (decl) = ctxp->class_list;
3772   ctxp->class_list = decl;
3773
3774   /* Create a new nodes in the global lists */
3775   gclass_list = tree_cons (NULL_TREE, decl, gclass_list);
3776   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3777
3778   /* Install a new dependency list element */
3779   create_jdep_list (ctxp);
3780
3781   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3782                           IDENTIFIER_POINTER (qualified_name)));
3783   return decl;
3784 }
3785
3786 static void
3787 add_superinterfaces (decl, interface_list)
3788      tree decl, interface_list;
3789 {
3790   tree node;
3791   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3792      takes care of ensuring that:
3793        - This is an accessible interface type,
3794        - Circularity detection.
3795    parser_add_interface is then called. If present but not defined,
3796    the check operation is delayed until the super interface gets
3797    defined.  */
3798   for (node = interface_list; node; node = TREE_CHAIN (node))
3799     {
3800       tree current = TREE_PURPOSE (node);
3801       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3802       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3803         {
3804           if (!parser_check_super_interface (idecl, decl, current))
3805             parser_add_interface (decl, idecl, current);
3806         }
3807       else
3808         register_incomplete_type (JDEP_INTERFACE,
3809                                   current, decl, NULL_TREE);
3810     }
3811 }
3812
3813 /* Create an interface in pass1 and return its decl. Return the
3814    interface's decl in pass 2.  */
3815
3816 static tree
3817 create_interface (flags, id, super)
3818      int flags;
3819      tree id, super;
3820 {
3821   tree raw_name = EXPR_WFL_NODE (id);
3822   tree q_name = parser_qualified_classname (raw_name);
3823   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3824
3825   /* Certain syntax errors are making SUPER be like ID. Avoid this
3826      case. */
3827   if (ctxp->class_err && id == super)
3828     super = NULL;
3829
3830   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3831
3832   /* Basic checks: scope, redefinition, modifiers */ 
3833   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3834     {
3835       PUSH_ERROR ();
3836       return NULL_TREE;
3837     }
3838
3839   /* Suspend the current parsing context if we're parsing an inner
3840      interface */
3841   if (CPC_INNER_P ())
3842     {
3843       java_parser_context_suspend ();
3844       /* Interface members are public. */
3845       if (CLASS_INTERFACE (GET_CPC ()))
3846         flags |= ACC_PUBLIC;
3847     }
3848
3849   /* Push a new context for (static) initialized upon declaration fields */
3850   java_parser_context_push_initialized_field ();
3851
3852   /* Interface modifiers check
3853        - public/abstract allowed (already done at that point)
3854        - abstract is obsolete (comes first, it's a warning, or should be)
3855        - Can't use twice the same (checked in the modifier rule) */
3856   if ((flags & ACC_ABSTRACT) && flag_redundant)
3857     parse_warning_context 
3858       (MODIFIER_WFL (ABSTRACT_TK),
3859        "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3860
3861   /* Create a new decl if DECL is NULL, otherwise fix it */
3862   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3863
3864   /* Set super info and mark the class a complete */
3865   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3866                   object_type_node, ctxp->interface_number);
3867   ctxp->interface_number = 0;
3868   CLASS_COMPLETE_P (decl) = 1;
3869   add_superinterfaces (decl, super);
3870
3871   return decl;
3872 }
3873
3874 /* Anonymous class counter. Will be reset to 1 every time a non
3875    anonymous class gets created. */
3876 static int anonymous_class_counter = 1;
3877
3878 /* Patch anonymous class CLASS, by either extending or implementing
3879    DEP.  */
3880
3881 static void
3882 patch_anonymous_class (type_decl, class_decl, wfl)
3883     tree type_decl, class_decl, wfl;
3884 {
3885   tree class = TREE_TYPE (class_decl);
3886   tree type =  TREE_TYPE (type_decl);
3887   tree binfo = TYPE_BINFO (class);
3888
3889   /* If it's an interface, implement it */
3890   if (CLASS_INTERFACE (type_decl))
3891     {
3892       tree s_binfo;
3893       int length;
3894
3895       if (parser_check_super_interface (type_decl, class_decl, wfl))
3896         return;
3897
3898       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3899       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3900       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3901       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3902       /* And add the interface */
3903       parser_add_interface (class_decl, type_decl, wfl);
3904     }
3905   /* Otherwise, it's a type we want to extend */
3906   else
3907     {
3908       if (parser_check_super (type_decl, class_decl, wfl))
3909         return;
3910       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3911     }
3912 }
3913
3914 static tree
3915 create_anonymous_class (location, type_name)
3916     int location;
3917     tree type_name;
3918 {
3919   char buffer [80];
3920   tree super = NULL_TREE, itf = NULL_TREE;
3921   tree id, type_decl, class;
3922
3923   /* The unqualified name of the anonymous class. It's just a number. */
3924   sprintf (buffer, "%d", anonymous_class_counter++);
3925   id = build_wfl_node (get_identifier (buffer));
3926   EXPR_WFL_LINECOL (id) = location;
3927
3928   /* We know about the type to extend/implement. We go ahead */
3929   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3930     {
3931       /* Create a class which either implements on extends the designated
3932          class. The class bears an innacessible name. */
3933       if (CLASS_INTERFACE (type_decl))
3934         {
3935           /* It's OK to modify it here. It's been already used and
3936              shouldn't be reused */
3937           ctxp->interface_number = 1;
3938           /* Interfaces should presented as a list of WFLs */
3939           itf = build_tree_list (type_name, NULL_TREE);
3940         }
3941       else
3942         super = type_name;
3943     }
3944
3945   class = create_class (ACC_FINAL, id, super, itf);
3946
3947   /* We didn't know anything about the stuff. We register a dependence. */
3948   if (!type_decl)
3949     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3950
3951   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3952   return class;
3953 }
3954
3955 /* Create a class in pass1 and return its decl. Return class
3956    interface's decl in pass 2.  */
3957
3958 static tree
3959 create_class (flags, id, super, interfaces)
3960      int flags;
3961      tree id, super, interfaces;
3962 {
3963   tree raw_name = EXPR_WFL_NODE (id);
3964   tree class_id, decl;
3965   tree super_decl_type;
3966
3967   /* Certain syntax errors are making SUPER be like ID. Avoid this
3968      case. */
3969   if (ctxp->class_err && id == super)
3970     super = NULL;
3971
3972   class_id = parser_qualified_classname (raw_name);
3973   decl = IDENTIFIER_CLASS_VALUE (class_id);
3974   EXPR_WFL_NODE (id) = class_id;
3975
3976   /* Basic check: scope, redefinition, modifiers */
3977   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3978     {
3979       PUSH_ERROR ();
3980       return NULL_TREE;
3981     }
3982   
3983   /* Suspend the current parsing context if we're parsing an inner
3984      class or an anonymous class. */
3985   if (CPC_INNER_P ())
3986     {
3987       java_parser_context_suspend ();
3988       /* Interface members are public. */
3989       if (CLASS_INTERFACE (GET_CPC ()))
3990         flags |= ACC_PUBLIC;
3991     }
3992     
3993   /* Push a new context for (static) initialized upon declaration fields */
3994   java_parser_context_push_initialized_field ();
3995
3996   /* Class modifier check: 
3997        - Allowed modifier (already done at that point)
3998        - abstract AND final forbidden 
3999        - Public classes defined in the correct file */
4000   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
4001     parse_error_context
4002       (id, "Class `%s' can't be declared both abstract and final",
4003        IDENTIFIER_POINTER (raw_name));
4004
4005   /* Create a new decl if DECL is NULL, otherwise fix it */
4006   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
4007
4008   /* If SUPER exists, use it, otherwise use Object */
4009   if (super)
4010     {
4011       /* Can't extend java.lang.Object */
4012       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
4013         {
4014           parse_error_context (id, "Can't extend `java.lang.Object'");
4015           return NULL_TREE;
4016         }
4017
4018       super_decl_type = 
4019         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
4020     }
4021   else if (TREE_TYPE (decl) != object_type_node)
4022     super_decl_type = object_type_node;
4023   /* We're defining java.lang.Object */
4024   else
4025     super_decl_type = NULL_TREE;
4026
4027   /* A class nested in an interface is implicitly static. */
4028   if (INNER_CLASS_DECL_P (decl)
4029       && CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (DECL_CONTEXT (decl)))))
4030     {
4031       flags |= ACC_STATIC;
4032     }
4033
4034   /* Set super info and mark the class as complete. */
4035   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
4036                   ctxp->interface_number);
4037   ctxp->interface_number = 0;
4038   CLASS_COMPLETE_P (decl) = 1;
4039   add_superinterfaces (decl, interfaces);
4040
4041   /* Add the private this$<n> field, Replicate final locals still in
4042      scope as private final fields mangled like val$<local_name>.
4043      This doesn't not occur for top level (static) inner classes. */
4044   if (PURE_INNER_CLASS_DECL_P (decl))
4045     add_inner_class_fields (decl, current_function_decl);
4046
4047   /* If doing xref, store the location at which the inherited class
4048      (if any) was seen. */
4049   if (flag_emit_xref && super)
4050     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
4051
4052   /* Eventually sets the @deprecated tag flag */
4053   CHECK_DEPRECATED (decl);
4054
4055   /* Reset the anonymous class counter when declaring non inner classes */
4056   if (!INNER_CLASS_DECL_P (decl))
4057     anonymous_class_counter = 1;
4058
4059   return decl;
4060 }
4061
4062 /* End a class declaration: register the statements used to create
4063    finit$ and <clinit>, pop the current class and resume the prior
4064    parser context if necessary.  */
4065
4066 static void
4067 end_class_declaration (resume)
4068      int resume;
4069 {
4070   /* If an error occured, context weren't pushed and won't need to be
4071      popped by a resume. */
4072   int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
4073
4074   java_parser_context_pop_initialized_field ();
4075   POP_CPC ();
4076   if (resume && no_error_occured)
4077     java_parser_context_resume ();
4078
4079   /* We're ending a class declaration, this is a good time to reset
4080      the interface cout. Note that might have been already done in
4081      create_interface, but if at that time an inner class was being
4082      dealt with, the interface count was reset in a context created
4083      for the sake of handling inner classes declaration. */
4084   ctxp->interface_number = 0;
4085 }
4086
4087 static void
4088 add_inner_class_fields (class_decl, fct_decl)
4089      tree class_decl;
4090      tree fct_decl;
4091 {
4092   tree block, marker, f;
4093
4094   f = add_field (TREE_TYPE (class_decl),
4095                  build_current_thisn (TREE_TYPE (class_decl)),
4096                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
4097                  ACC_PRIVATE);
4098   FIELD_THISN (f) = 1;
4099
4100   if (!fct_decl)
4101     return;
4102     
4103   for (block = GET_CURRENT_BLOCK (fct_decl); 
4104        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
4105     {
4106       tree decl;
4107       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
4108         {
4109           tree name, pname;
4110           tree wfl, init, list;
4111           
4112           /* Avoid non final arguments. */
4113           if (!LOCAL_FINAL_P (decl))
4114             continue;
4115           
4116           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
4117           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
4118           wfl = build_wfl_node (name);
4119           init = build_wfl_node (pname);
4120           /* Build an initialization for the field: it will be
4121              initialized by a parameter added to finit$, bearing a
4122              mangled name of the field itself (param$<n>.) The
4123              parameter is provided to finit$ by the constructor
4124              invoking it (hence the constructor will also feature a
4125              hidden parameter, set to the value of the outer context
4126              local at the time the inner class is created.)
4127              
4128              Note: we take into account all possible locals that can
4129              be accessed by the inner class. It's actually not trivial
4130              to minimize these aliases down to the ones really
4131              used. One way to do that would be to expand all regular
4132              methods first, then finit$ to get a picture of what's
4133              used.  It works with the exception that we would have to
4134              go back on all constructor invoked in regular methods to
4135              have their invokation reworked (to include the right amount
4136              of alias initializer parameters.)
4137
4138              The only real way around, I think, is a first pass to
4139              identify locals really used in the inner class. We leave
4140              the flag FIELD_LOCAL_ALIAS_USED around for that future
4141              use.
4142              
4143              On the other hand, it only affect local inner classes,
4144              whose constructors (and finit$ call) will be featuring
4145              unecessary arguments. It's easy for a developper to keep
4146              this number of parameter down by using the `final'
4147              keyword only when necessary. For the time being, we can
4148              issue a warning on unecessary finals. FIXME */
4149           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
4150                                    wfl, init);
4151
4152           /* Register the field. The TREE_LIST holding the part
4153              initialized/initializer will be marked ARG_FINAL_P so
4154              that the created field can be marked
4155              FIELD_LOCAL_ALIAS. */
4156           list = build_tree_list (wfl, init);
4157           ARG_FINAL_P (list) = 1;
4158           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
4159         }
4160     }
4161
4162   if (!CPC_INITIALIZER_STMT (ctxp))
4163     return;
4164
4165   /* If we ever registered an alias field, insert and marker to
4166      remeber where the list ends. The second part of the list (the one
4167      featuring initialized fields) so it can be later reversed to
4168      enforce 8.5. The marker will be removed during that operation. */
4169   marker = build_tree_list (NULL_TREE, NULL_TREE);
4170   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
4171   SET_CPC_INITIALIZER_STMT (ctxp, marker);
4172 }
4173
4174 /* Can't use lookup_field () since we don't want to load the class and
4175    can't set the CLASS_LOADED_P flag */
4176
4177 static tree
4178 find_field (class, name)
4179      tree class;
4180      tree name;
4181 {
4182   tree decl;
4183   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
4184     {
4185       if (DECL_NAME (decl) == name)
4186         return decl;
4187     }
4188   return NULL_TREE;
4189 }
4190
4191 /* Wrap around lookup_field that doesn't potentially upset the value
4192    of CLASS */
4193
4194 static tree
4195 lookup_field_wrapper (class, name)
4196      tree class, name;
4197 {
4198   tree type = class;
4199   tree decl = NULL_TREE;
4200   java_parser_context_save_global ();
4201
4202   /* Last chance: if we're within the context of an inner class, we
4203      might be trying to access a local variable defined in an outer
4204      context. We try to look for it now. */
4205   if (INNER_CLASS_TYPE_P (class) && TREE_CODE (name) == IDENTIFIER_NODE)
4206     {
4207       tree new_name;
4208       MANGLE_OUTER_LOCAL_VARIABLE_NAME (new_name, name);
4209       decl = lookup_field (&type, new_name);
4210       if (decl && decl != error_mark_node)
4211         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4212     }
4213   if (!decl || decl == error_mark_node)
4214     {
4215       type = class;
4216       decl = lookup_field (&type, name);
4217     }
4218
4219   java_parser_context_restore_global ();
4220   return decl == error_mark_node ? NULL : decl;
4221 }
4222
4223 /* Find duplicate field within the same class declarations and report
4224    the error. Returns 1 if a duplicated field was found, 0
4225    otherwise.  */
4226
4227 static int
4228 duplicate_declaration_error_p (new_field_name, new_type, cl)
4229      tree new_field_name, new_type, cl;
4230 {
4231   /* This might be modified to work with method decl as well */
4232   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4233   if (decl)
4234     {
4235       char *t1 = xstrdup (purify_type_name
4236                          ((TREE_CODE (new_type) == POINTER_TYPE 
4237                            && TREE_TYPE (new_type) == NULL_TREE) ?
4238                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4239                           lang_printable_name (new_type, 1)));
4240       /* The type may not have been completed by the time we report
4241          the error */
4242       char *t2 = xstrdup (purify_type_name
4243                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4244                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4245                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4246                           lang_printable_name (TREE_TYPE (decl), 1)));
4247       parse_error_context 
4248         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4249          t1, IDENTIFIER_POINTER (new_field_name),
4250          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4251          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4252       free (t1);
4253       free (t2);
4254       return 1;
4255     }
4256   return 0;
4257 }
4258
4259 /* Field registration routine. If TYPE doesn't exist, field
4260    declarations are linked to the undefined TYPE dependency list, to
4261    be later resolved in java_complete_class () */
4262
4263 static void
4264 register_fields (flags, type, variable_list)
4265      int flags;
4266      tree type, variable_list;
4267 {
4268   tree current, saved_type;
4269   tree class_type = NULL_TREE;
4270   int saved_lineno = lineno;
4271   int must_chain = 0;
4272   tree wfl = NULL_TREE;
4273
4274   if (GET_CPC ())
4275     class_type = TREE_TYPE (GET_CPC ());
4276
4277   if (!class_type || class_type == error_mark_node)
4278     return;
4279
4280   /* If we're adding fields to interfaces, those fields are public,
4281      static, final */
4282   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4283     {
4284       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4285                                  flags, ACC_PUBLIC, "interface field(s)");
4286       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4287                                  flags, ACC_STATIC, "interface field(s)");
4288       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4289                                  flags, ACC_FINAL, "interface field(s)");
4290       check_modifiers ("Illegal interface member modifier `%s'", flags,
4291                        INTERFACE_FIELD_MODIFIERS);
4292       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4293     }
4294
4295   /* Obtain a suitable type for resolution, if necessary */
4296   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4297
4298   /* If TYPE is fully resolved and we don't have a reference, make one */
4299   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4300
4301   for (current = variable_list, saved_type = type; current; 
4302        current = TREE_CHAIN (current), type = saved_type)
4303     {
4304       tree real_type;
4305       tree field_decl;
4306       tree cl = TREE_PURPOSE (current);
4307       tree init = TREE_VALUE (current);
4308       tree current_name = EXPR_WFL_NODE (cl);
4309
4310       /* Can't declare non-final static fields in inner classes */
4311       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4312           && !(flags & ACC_FINAL))
4313         parse_error_context 
4314           (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
4315            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4316            lang_printable_name (class_type, 0));
4317
4318       /* Process NAME, as it may specify extra dimension(s) for it */
4319       type = build_array_from_name (type, wfl, current_name, &current_name);
4320
4321       /* Type adjustment. We may have just readjusted TYPE because
4322          the variable specified more dimensions. Make sure we have
4323          a reference if we can and don't have one already. Also
4324          change the name if we have an init. */
4325       if (type != saved_type)
4326         {
4327           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4328           if (init)
4329             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4330         }
4331
4332       real_type = GET_REAL_TYPE (type);
4333       /* Check for redeclarations */
4334       if (duplicate_declaration_error_p (current_name, real_type, cl))
4335         continue;
4336
4337       /* Set lineno to the line the field was found and create a
4338          declaration for it. Eventually sets the @deprecated tag flag. */
4339       if (flag_emit_xref)
4340         lineno = EXPR_WFL_LINECOL (cl);
4341       else
4342         lineno = EXPR_WFL_LINENO (cl);
4343       field_decl = add_field (class_type, current_name, real_type, flags);
4344       CHECK_DEPRECATED (field_decl);
4345
4346       /* If the field denotes a final instance variable, then we
4347          allocate a LANG_DECL_SPECIFIC part to keep track of its
4348          initialization. We also mark whether the field was
4349          initialized upon it's declaration. We don't do that if the
4350          created field is an alias to a final local. */
4351       if (!ARG_FINAL_P (current) && (flags & ACC_FINAL))
4352         {
4353           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field_decl);
4354           DECL_FIELD_FINAL_WFL (field_decl) = cl;
4355           if ((flags & ACC_STATIC) && init)
4356             DECL_FIELD_FINAL_IUD (field_decl) = 1;
4357         }
4358
4359       /* If the couple initializer/initialized is marked ARG_FINAL_P,
4360          we mark the created field FIELD_LOCAL_ALIAS, so that we can
4361          hide parameters to this inner class finit$ and
4362          constructors. It also means that the field isn't final per
4363          say. */
4364       if (ARG_FINAL_P (current))
4365         {
4366           FIELD_LOCAL_ALIAS (field_decl) = 1;
4367           FIELD_FINAL (field_decl) = 0;
4368         }
4369       
4370       /* Check if we must chain. */
4371       if (must_chain)
4372         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4373           
4374       /* If we have an initialization value tied to the field */
4375       if (init)
4376         {
4377           /* The field is declared static */
4378           if (flags & ACC_STATIC)
4379             {
4380               /* We include the field and its initialization part into
4381                  a list used to generate <clinit>. After <clinit> is
4382                  walked, field initializations will be processed and
4383                  fields initialized with known constants will be taken
4384                  out of <clinit> and have their DECL_INITIAL set
4385                  appropriately. */
4386               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4387               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4388               if (TREE_OPERAND (init, 1) 
4389                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4390                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4391             }
4392           /* A non-static field declared with an immediate initialization is
4393              to be initialized in <init>, if any.  This field is remembered
4394              to be processed at the time of the generation of <init>. */
4395           else
4396             {
4397               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4398               SET_CPC_INITIALIZER_STMT (ctxp, init);
4399             }
4400           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4401           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4402         }
4403     }
4404   lineno = saved_lineno;
4405 }
4406
4407 /* Generate finit$, using the list of initialized fields to populate
4408    its body. finit$'s parameter(s) list is adjusted to include the
4409    one(s) used to initialized the field(s) caching outer context
4410    local(s). */
4411
4412 static tree
4413 generate_finit (class_type)
4414      tree class_type;
4415 {
4416   int count = 0;
4417   tree list = TYPE_FINIT_STMT_LIST (class_type);
4418   tree mdecl, current, parms;
4419
4420   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4421                                                   class_type, NULL_TREE, 
4422                                                   &count);
4423   CRAFTED_PARAM_LIST_FIXUP (parms);
4424   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4425                                     finit_identifier_node, parms);
4426   fix_method_argument_names (parms, mdecl);
4427   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4428                        mdecl, NULL_TREE);
4429   DECL_FUNCTION_NAP (mdecl) = count;
4430   start_artificial_method_body (mdecl);
4431
4432   for (current = list; current; current = TREE_CHAIN (current))
4433     java_method_add_stmt (mdecl, 
4434                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4435                                                 current));
4436   end_artificial_method_body (mdecl);
4437   return mdecl;
4438 }
4439
4440 /* Generate a function to run the instance initialization code. The
4441    private method is called `instinit$'. Unless we're dealing with an
4442    anonymous class, we determine whether all ctors of CLASS_TYPE
4443    declare a checked exception in their `throws' clause in order to
4444    see whether it's necessary to encapsulate the instance initializer
4445    statements in a try/catch/rethrow sequence.  */
4446
4447 static tree
4448 generate_instinit (class_type)
4449      tree class_type;
4450 {
4451   tree current;
4452   tree compound = NULL_TREE;
4453   tree parms = tree_cons (this_identifier_node,
4454                           build_pointer_type (class_type), end_params_node);
4455   tree mdecl = create_artificial_method (class_type, ACC_PRIVATE,
4456                                          void_type_node,
4457                                          instinit_identifier_node, parms);
4458
4459   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4460                        mdecl, NULL_TREE);
4461
4462   /* Gather all the statements in a compound */
4463   for (current = TYPE_II_STMT_LIST (class_type); 
4464        current; current = TREE_CHAIN (current))
4465     compound = add_stmt_to_compound (compound, NULL_TREE, current);
4466
4467   /* We need to encapsulate COMPOUND by a try/catch statement to
4468      rethrow exceptions that might occur in the instance initializer.
4469      We do that only if all ctors of CLASS_TYPE are set to catch a
4470      checked exception. This doesn't apply to anonymous classes (since
4471      they don't have declared ctors.) */
4472   if (!ANONYMOUS_CLASS_P (class_type) && 
4473       ctors_unchecked_throws_clause_p (class_type))
4474     {
4475       compound = encapsulate_with_try_catch (0, exception_type_node, compound, 
4476                                              build1 (THROW_EXPR, NULL_TREE,
4477                                                      build_wfl_node (wpv_id)));
4478       DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
4479                                                       exception_type_node);
4480     }
4481
4482   start_artificial_method_body (mdecl);
4483   java_method_add_stmt (mdecl, compound);
4484   end_artificial_method_body (mdecl);
4485
4486   return mdecl;
4487 }
4488
4489 /* FIXME */
4490 static tree
4491 build_instinit_invocation (class_type)
4492      tree class_type;
4493 {
4494   tree to_return = NULL_TREE;
4495
4496   if (TYPE_II_STMT_LIST (class_type))
4497     {
4498       tree parm = build_tree_list (NULL_TREE,
4499                                    build_wfl_node (this_identifier_node));
4500       to_return =
4501         build_method_invocation (build_wfl_node (instinit_identifier_node),
4502                                  parm);
4503     }
4504   return to_return;
4505 }
4506
4507 /* Shared accros method_declarator and method_header to remember the
4508    patch stage that was reached during the declaration of the method.
4509    A method DECL is built differently is there is no patch
4510    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4511    pending on the currently defined method.  */
4512
4513 static int patch_stage;
4514
4515 /* Check the method declaration and add the method to its current
4516    class.  If the argument list is known to contain incomplete types,
4517    the method is partially added and the registration will be resume
4518    once the method arguments resolved. If TYPE is NULL, we're dealing
4519    with a constructor.  */
4520
4521 static tree
4522 method_header (flags, type, mdecl, throws)
4523      int flags;
4524      tree type, mdecl, throws;
4525 {
4526   tree type_wfl = NULL_TREE;
4527   tree meth_name = NULL_TREE;
4528   tree current, orig_arg, this_class = NULL;
4529   tree id, meth;
4530   int saved_lineno;
4531   int constructor_ok = 0, must_chain;
4532   int count;
4533
4534   if (mdecl == error_mark_node)
4535     return error_mark_node;
4536   meth = TREE_VALUE (mdecl);
4537   id = TREE_PURPOSE (mdecl);
4538   
4539   check_modifiers_consistency (flags);
4540
4541   if (GET_CPC ())
4542     this_class = TREE_TYPE (GET_CPC ());
4543
4544   if (!this_class || this_class == error_mark_node)
4545     return NULL_TREE;
4546   
4547   /* There are some forbidden modifiers for an abstract method and its
4548      class must be abstract as well.  */
4549   if (type && (flags & ACC_ABSTRACT))
4550     {
4551       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4552       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4553       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4554       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4555       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4556       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4557           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4558         parse_error_context 
4559           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4560            IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())),
4561            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4562     }
4563
4564   /* Things to be checked when declaring a constructor */
4565   if (!type)
4566     {
4567       int ec = java_error_count;
4568       /* 8.6: Constructor declarations: we might be trying to define a
4569          method without specifying a return type. */
4570       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4571         parse_error_context 
4572           (id, "Invalid method declaration, return type required");
4573       /* 8.6.3: Constructor modifiers */
4574       else
4575         {
4576           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4577           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4578           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4579           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4580           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4581         }
4582       /* If we found error here, we don't consider it's OK to tread
4583          the method definition as a constructor, for the rest of this
4584          function */
4585       if (ec == java_error_count)
4586         constructor_ok = 1;
4587     }
4588
4589   /* Method declared within the scope of an interface are implicitly
4590      abstract and public. Conflicts with other erroneously provided
4591      modifiers are checked right after. */
4592
4593   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4594     {
4595       /* If FLAGS isn't set because of a modifier, turn the
4596          corresponding modifier WFL to NULL so we issue a warning on
4597          the obsolete use of the modifier */
4598       if (!(flags & ACC_PUBLIC))
4599         MODIFIER_WFL (PUBLIC_TK) = NULL;
4600       if (!(flags & ACC_ABSTRACT))
4601         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4602       flags |= ACC_PUBLIC;
4603       flags |= ACC_ABSTRACT;
4604     }
4605
4606   /* Inner class can't declare static methods */
4607   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4608     {
4609       parse_error_context 
4610         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4611          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4612          lang_printable_name (this_class, 0));
4613     }
4614
4615   /* Modifiers context reset moved up, so abstract method declaration
4616      modifiers can be later checked.  */
4617
4618   /* Set constructor returned type to void and method name to <init>,
4619      unless we found an error identifier the constructor (in which
4620      case we retain the original name) */
4621   if (!type)
4622     {
4623       type = void_type_node;
4624       if (constructor_ok)
4625         meth_name = init_identifier_node;
4626     }
4627   else
4628     meth_name = EXPR_WFL_NODE (id);
4629
4630   /* Do the returned type resolution and registration if necessary */
4631   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4632
4633   if (meth_name)
4634     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4635   EXPR_WFL_NODE (id) = meth_name;
4636   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4637
4638   if (must_chain)
4639     {
4640       patch_stage = JDEP_METHOD_RETURN;
4641       register_incomplete_type (patch_stage, type_wfl, id, type);
4642       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4643     }
4644   else
4645     TREE_TYPE (meth) = type;
4646
4647   saved_lineno = lineno;
4648   /* When defining an abstract or interface method, the curly
4649      bracket at level 1 doesn't exist because there is no function
4650      body */
4651   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4652             EXPR_WFL_LINENO (id));
4653
4654   /* Remember the original argument list */
4655   orig_arg = TYPE_ARG_TYPES (meth);
4656
4657   if (patch_stage)              /* includes ret type and/or all args */
4658     {
4659       jdep *jdep;
4660       meth = add_method_1 (this_class, flags, meth_name, meth);
4661       /* Patch for the return type */
4662       if (patch_stage == JDEP_METHOD_RETURN)
4663         {
4664           jdep = CLASSD_LAST (ctxp->classd_list);
4665           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4666         }
4667       /* This is the stop JDEP. METH allows the function's signature
4668          to be computed. */
4669       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4670     }
4671   else
4672     meth = add_method (this_class, flags, meth_name, 
4673                        build_java_signature (meth));
4674
4675   /* Remember final parameters */
4676   MARK_FINAL_PARMS (meth, orig_arg);
4677
4678   /* Fix the method argument list so we have the argument name
4679      information */
4680   fix_method_argument_names (orig_arg, meth);
4681
4682   /* Register the parameter number and re-install the current line
4683      number */
4684   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4685   lineno = saved_lineno;
4686
4687   /* Register exception specified by the `throws' keyword for
4688      resolution and set the method decl appropriate field to the list.
4689      Note: the grammar ensures that what we get here are class
4690      types. */
4691   if (throws)
4692     {
4693       throws = nreverse (throws);
4694       for (current = throws; current; current = TREE_CHAIN (current))
4695         {
4696           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4697                                     NULL_TREE, NULL_TREE);
4698           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4699             &TREE_VALUE (current);
4700         }
4701       DECL_FUNCTION_THROWS (meth) = throws;
4702     }
4703
4704   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4705     DECL_FUNCTION_WFL (meth) = id;
4706
4707   /* Set the flag if we correctly processed a constructor */
4708   if (constructor_ok)
4709     {
4710       DECL_CONSTRUCTOR_P (meth) = 1;
4711       /* Compute and store the number of artificial parameters declared
4712          for this constructor */
4713       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4714            current = TREE_CHAIN (current))
4715         if (FIELD_LOCAL_ALIAS (current))
4716           count++;
4717       DECL_FUNCTION_NAP (meth) = count;
4718     }
4719
4720   /* Eventually set the @deprecated tag flag */
4721   CHECK_DEPRECATED (meth);
4722
4723   /* If doing xref, store column and line number information instead
4724      of the line number only. */
4725   if (flag_emit_xref)
4726     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4727
4728   return meth;
4729 }
4730
4731 static void
4732 fix_method_argument_names (orig_arg, meth)
4733     tree orig_arg, meth;
4734 {
4735   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4736   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4737     {
4738       TREE_PURPOSE (arg) = this_identifier_node;
4739       arg = TREE_CHAIN (arg);
4740     }
4741   while (orig_arg != end_params_node)
4742     {
4743       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4744       orig_arg = TREE_CHAIN (orig_arg);
4745       arg = TREE_CHAIN (arg);
4746     }
4747 }
4748
4749 /* Complete the method declaration with METHOD_BODY.  */
4750
4751 static void
4752 finish_method_declaration (method_body)
4753      tree method_body;
4754 {
4755   int flags;
4756
4757   if (!current_function_decl)
4758     return;
4759
4760   flags = get_access_flags_from_decl (current_function_decl);
4761
4762   /* 8.4.5 Method Body */
4763   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4764     {
4765       tree name = DECL_NAME (current_function_decl);
4766       parse_error_context (DECL_FUNCTION_WFL (current_function_decl), 
4767                            "%s method `%s' can't have a body defined",
4768                            (METHOD_NATIVE (current_function_decl) ?
4769                             "Native" : "Abstract"),
4770                            IDENTIFIER_POINTER (name));
4771       method_body = NULL_TREE;
4772     }
4773   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4774     {
4775       tree name = DECL_NAME (current_function_decl);
4776       parse_error_context
4777         (DECL_FUNCTION_WFL (current_function_decl), 
4778          "Non native and non abstract method `%s' must have a body defined",
4779          IDENTIFIER_POINTER (name));
4780       method_body = NULL_TREE;
4781     }
4782
4783   if (flag_emit_class_files && method_body 
4784       && TREE_CODE (method_body) == NOP_EXPR 
4785       && TREE_TYPE (current_function_decl) 
4786       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4787     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4788
4789   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4790   maybe_absorb_scoping_blocks ();
4791   /* Exit function's body */
4792   exit_block ();
4793   /* Merge last line of the function with first line, directly in the
4794      function decl. It will be used to emit correct debug info. */
4795   if (!flag_emit_xref)
4796     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4797
4798   /* Since function's argument's list are shared, reset the
4799      ARG_FINAL_P parameter that might have been set on some of this
4800      function parameters. */
4801   UNMARK_FINAL_PARMS (current_function_decl);
4802   
4803   /* So we don't have an irrelevant function declaration context for
4804      the next static block we'll see. */
4805   current_function_decl = NULL_TREE;
4806 }
4807
4808 /* Build a an error message for constructor circularity errors.  */
4809
4810 static char *
4811 constructor_circularity_msg (from, to)
4812      tree from, to;
4813 {
4814   static char string [4096];
4815   char *t = xstrdup (lang_printable_name (from, 0));
4816   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4817   free (t);
4818   return string;
4819 }
4820
4821 /* Verify a circular call to METH. Return 1 if an error is found, 0
4822    otherwise.  */
4823
4824 static int
4825 verify_constructor_circularity (meth, current)
4826      tree meth, current;
4827 {
4828   static tree list = NULL_TREE;
4829   static int initialized_p;
4830   tree c;
4831
4832   /* If we haven't already registered LIST with the garbage collector,
4833      do so now.  */
4834   if (!initialized_p)
4835     {
4836       ggc_add_tree_root (&list, 1);
4837       initialized_p = 1;
4838     }
4839
4840   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4841     {
4842       if (TREE_VALUE (c) == meth)
4843         {
4844           char *t;
4845           if (list)
4846             {
4847               tree liste;
4848               list = nreverse (list);
4849               for (liste = list; liste; liste = TREE_CHAIN (liste))
4850                 {
4851                   parse_error_context 
4852                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4853                      constructor_circularity_msg
4854                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4855                   java_error_count--;
4856                 }
4857             }
4858           t = xstrdup (lang_printable_name (meth, 0));
4859           parse_error_context (TREE_PURPOSE (c), 
4860                                "%s: recursive invocation of constructor `%s'",
4861                                constructor_circularity_msg (current, meth), t);
4862           free (t);
4863           list = NULL_TREE;
4864           return 1;
4865         }
4866     }
4867   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4868     {
4869       list = tree_cons (c, current, list);
4870       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4871         return 1;
4872       list = TREE_CHAIN (list);
4873     }
4874   return 0;
4875 }
4876
4877 /* Check modifiers that can be declared but exclusively */
4878
4879 static void
4880 check_modifiers_consistency (flags)
4881      int flags;
4882 {
4883   int acc_count = 0;
4884   tree cl = NULL_TREE;
4885
4886   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4887   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4888   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4889   if (acc_count > 1)
4890     parse_error_context
4891       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4892
4893   acc_count = 0;
4894   cl = NULL_TREE;
4895   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
4896   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
4897   if (acc_count > 1)
4898     parse_error_context (cl,
4899                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4900 }
4901
4902 /* Check the methode header METH for abstract specifics features */
4903
4904 static void
4905 check_abstract_method_header (meth)
4906      tree meth;
4907 {
4908   int flags = get_access_flags_from_decl (meth);
4909
4910   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4911                               ACC_ABSTRACT, "abstract method",
4912                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4913   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4914                               ACC_PUBLIC, "abstract method",
4915                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4916
4917   check_modifiers ("Illegal modifier `%s' for interface method",
4918                   flags, INTERFACE_METHOD_MODIFIERS);
4919 }
4920
4921 /* Create a FUNCTION_TYPE node and start augmenting it with the
4922    declared function arguments. Arguments type that can't be resolved
4923    are left as they are, but the returned node is marked as containing
4924    incomplete types.  */
4925
4926 static tree
4927 method_declarator (id, list)
4928      tree id, list;
4929 {
4930   tree arg_types = NULL_TREE, current, node;
4931   tree meth = make_node (FUNCTION_TYPE);
4932   jdep *jdep;
4933
4934   patch_stage = JDEP_NO_PATCH;
4935
4936   if (GET_CPC () == error_mark_node)
4937     return error_mark_node;
4938
4939   /* If we're dealing with an inner class constructor, we hide the
4940      this$<n> decl in the name field of its parameter declaration.  We
4941      also might have to hide the outer context local alias
4942      initializers. Not done when the class is a toplevel class. */
4943   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4944       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4945     {
4946       tree aliases_list, type, thisn;
4947       /* First the aliases, linked to the regular parameters */
4948       aliases_list =
4949         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4950                                                 TREE_TYPE (GET_CPC ()),
4951                                                 NULL_TREE, NULL);
4952       list = chainon (nreverse (aliases_list), list);
4953
4954       /* Then this$<n> */
4955       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4956       thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
4957       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4958                         list);
4959     }
4960   
4961   for (current = list; current; current = TREE_CHAIN (current))
4962     {
4963       int must_chain = 0;
4964       tree wfl_name = TREE_PURPOSE (current);
4965       tree type = TREE_VALUE (current);
4966       tree name = EXPR_WFL_NODE (wfl_name);
4967       tree already, arg_node;
4968       tree type_wfl = NULL_TREE;
4969       tree real_type;
4970
4971       /* Obtain a suitable type for resolution, if necessary */
4972       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4973
4974       /* Process NAME, as it may specify extra dimension(s) for it */
4975       type = build_array_from_name (type, type_wfl, name, &name);
4976       EXPR_WFL_NODE (wfl_name) = name;
4977
4978       real_type = GET_REAL_TYPE (type);
4979       if (TREE_CODE (real_type) == RECORD_TYPE)
4980         {
4981           real_type = promote_type (real_type);
4982           if (TREE_CODE (type) == TREE_LIST)
4983             TREE_PURPOSE (type) = real_type;
4984         }
4985
4986       /* Check redefinition */
4987       for (already = arg_types; already; already = TREE_CHAIN (already))
4988         if (TREE_PURPOSE (already) == name)
4989           {
4990             parse_error_context
4991               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4992                IDENTIFIER_POINTER (name),
4993                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4994             break;
4995           }
4996
4997       /* If we've an incomplete argument type, we know there is a location
4998          to patch when the type get resolved, later.  */
4999       jdep = NULL;
5000       if (must_chain)
5001         {
5002           patch_stage = JDEP_METHOD;
5003           type = register_incomplete_type (patch_stage, 
5004                                            type_wfl, wfl_name, type);
5005           jdep = CLASSD_LAST (ctxp->classd_list);
5006           JDEP_MISC (jdep) = id;
5007         }
5008
5009       /* The argument node: a name and a (possibly) incomplete type.  */
5010       arg_node = build_tree_list (name, real_type);
5011       /* Remeber arguments declared final. */
5012       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
5013       
5014       if (jdep)
5015         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
5016       TREE_CHAIN (arg_node) = arg_types;
5017       arg_types = arg_node;
5018     }
5019   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
5020   node = build_tree_list (id, meth);
5021   return node;
5022 }
5023
5024 static int
5025 unresolved_type_p (wfl, returned)
5026      tree wfl;
5027      tree *returned;
5028      
5029 {
5030   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
5031     {
5032       if (returned)
5033         {
5034           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
5035           if (decl && current_class && (decl == TYPE_NAME (current_class)))
5036             *returned = TREE_TYPE (decl);
5037           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
5038             *returned = TREE_TYPE (GET_CPC ());
5039           else
5040             *returned = NULL_TREE;
5041         }
5042       return 1;
5043     }
5044   if (returned)
5045     *returned = wfl;
5046   return 0;
5047 }
5048
5049 /* From NAME, build a qualified identifier node using the
5050    qualification from the current package definition. */
5051
5052 static tree
5053 parser_qualified_classname (name)
5054      tree name;
5055 {
5056   tree nested_class_name;
5057
5058   if ((nested_class_name = maybe_make_nested_class_name (name)))
5059     return nested_class_name;
5060
5061   if (ctxp->package)
5062     return merge_qualified_name (ctxp->package, name);
5063   else 
5064     return name;
5065 }
5066
5067 /* Called once the type a interface extends is resolved. Returns 0 if
5068    everything is OK.  */
5069
5070 static int
5071 parser_check_super_interface (super_decl, this_decl, this_wfl)
5072      tree super_decl, this_decl, this_wfl;
5073 {
5074   tree super_type = TREE_TYPE (super_decl);
5075
5076   /* Has to be an interface */
5077   if (!CLASS_INTERFACE (super_decl))
5078     {
5079       parse_error_context 
5080         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
5081          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
5082          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
5083          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
5084           "interface" : "class"),
5085          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
5086       return 1;
5087     }
5088
5089   /* Check top-level interface access. Inner classes are subject to member 
5090      access rules (6.6.1). */
5091   if (! INNER_CLASS_P (super_type)
5092       && check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
5093     return 1;
5094
5095   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
5096                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5097                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
5098   return 0;
5099 }
5100
5101 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
5102    0 if everthing is OK.  */
5103
5104 static int
5105 parser_check_super (super_decl, this_decl, wfl)
5106      tree super_decl, this_decl, wfl;
5107 {
5108   tree super_type = TREE_TYPE (super_decl);
5109
5110   /* SUPER should be a CLASS (neither an array nor an interface) */
5111   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
5112     {
5113       parse_error_context 
5114         (wfl, "Class `%s' can't subclass %s `%s'",
5115          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5116          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
5117          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
5118       return 1;
5119     }
5120
5121   if (CLASS_FINAL (TYPE_NAME (super_type)))
5122     {
5123       parse_error_context (wfl, "Can't subclass final classes: %s",
5124                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
5125       return 1;
5126     }
5127
5128   /* Check top-level class scope. Inner classes are subject to member access
5129      rules (6.6.1). */
5130   if (! INNER_CLASS_P (super_type)
5131       && (check_pkg_class_access (DECL_NAME (super_decl), wfl)))
5132     return 1;
5133   
5134   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
5135                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5136                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
5137   return 0;
5138 }
5139
5140 /* Create a new dependency list and link it (in a LIFO manner) to the
5141    CTXP list of type dependency list.  */
5142
5143 static void
5144 create_jdep_list (ctxp)
5145      struct parser_ctxt *ctxp;
5146 {
5147   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
5148   new->first = new->last = NULL;
5149   new->next = ctxp->classd_list;
5150   ctxp->classd_list = new;
5151 }
5152
5153 static jdeplist *
5154 reverse_jdep_list (ctxp)
5155      struct parser_ctxt *ctxp;
5156 {
5157   register jdeplist *prev = NULL, *current, *next;
5158   for (current = ctxp->classd_list; current; current = next)
5159     {
5160       next = current->next;
5161       current->next = prev;
5162       prev = current;
5163     }
5164   return prev;
5165 }
5166
5167 /* Create a fake pointer based on the ID stored in
5168    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
5169    registered again. */
5170
5171 static tree
5172 obtain_incomplete_type (type_name)
5173      tree type_name;
5174 {
5175   tree ptr = NULL_TREE, name;
5176
5177   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
5178     name = EXPR_WFL_NODE (type_name);
5179   else if (INCOMPLETE_TYPE_P (type_name))
5180     name = TYPE_NAME (type_name);
5181   else
5182     abort ();
5183
5184   BUILD_PTR_FROM_NAME (ptr, name);
5185   layout_type (ptr);
5186
5187   return ptr;
5188 }
5189
5190 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
5191    non NULL instead of computing a new fake type based on WFL. The new
5192    dependency is inserted in the current type dependency list, in FIFO
5193    manner.  */
5194
5195 static tree
5196 register_incomplete_type (kind, wfl, decl, ptr)
5197      int kind;
5198      tree wfl, decl, ptr;
5199 {
5200   jdep *new = (jdep *)xmalloc (sizeof (jdep));
5201
5202   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
5203     ptr = obtain_incomplete_type (wfl);
5204
5205   JDEP_KIND (new) = kind;
5206   JDEP_DECL (new) = decl;
5207   JDEP_TO_RESOLVE (new) = ptr;
5208   JDEP_WFL (new) = wfl;
5209   JDEP_CHAIN (new) = NULL;
5210   JDEP_MISC (new) = NULL_TREE;
5211   /* For some dependencies, set the enclosing class of the current
5212      class to be the enclosing context */
5213   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE 
5214        || kind == JDEP_ANONYMOUS)
5215       && GET_ENCLOSING_CPC ())
5216     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
5217   else
5218     JDEP_ENCLOSING (new) = GET_CPC ();
5219   JDEP_GET_PATCH (new) = (tree *)NULL;
5220
5221   JDEP_INSERT (ctxp->classd_list, new);
5222
5223   return ptr;
5224 }
5225
5226 /* This checks for circular references with innerclasses. We start
5227    from SOURCE and should never reach TARGET. Extended/implemented
5228    types in SOURCE have their enclosing context checked not to reach
5229    TARGET. When the last enclosing context of SOURCE is reached, its
5230    extended/implemented types are also checked not to reach TARGET.
5231    In case of error, WFL of the offending type is returned; NULL_TREE
5232    otherwise.  */
5233
5234 static tree
5235 check_inner_circular_reference (source, target)
5236      tree source;
5237      tree target;
5238 {
5239   tree basetype_vec = TYPE_BINFO_BASETYPES (source);
5240   tree ctx, cl;
5241   int i;
5242
5243   if (!basetype_vec)
5244     return NULL_TREE;
5245   
5246   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
5247     {
5248       tree su = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
5249
5250       if (inherits_from_p (su, target))
5251         return lookup_cl (TYPE_NAME (su));
5252       
5253       for (ctx = DECL_CONTEXT (TYPE_NAME (su)); ctx; ctx = DECL_CONTEXT (ctx))
5254         {
5255           /* An enclosing context shouldn't be TARGET */
5256           if (ctx == TYPE_NAME (target))
5257             return lookup_cl (TYPE_NAME (su));
5258
5259           /* When we reach the enclosing last context, start a check
5260              on it, with the same target */
5261           if (! DECL_CONTEXT (ctx) &&
5262               (cl = check_inner_circular_reference (TREE_TYPE (ctx), target)))
5263             return cl;
5264         }
5265     }
5266   return NULL_TREE;
5267 }
5268
5269 /* Explore TYPE's `extends' clause member(s) and return the WFL of the
5270    offending type if a circularity is detected. NULL_TREE is returned
5271    otherwise. TYPE can be an interface or a class.   */
5272
5273 static tree
5274 check_circular_reference (type)
5275      tree type;
5276 {
5277   tree basetype_vec = TYPE_BINFO_BASETYPES (type);
5278   int i;
5279
5280   if (!basetype_vec)
5281     return NULL_TREE;
5282
5283   if (! CLASS_INTERFACE (TYPE_NAME (type)))
5284     {
5285       if (inherits_from_p (CLASSTYPE_SUPER (type), type))
5286         return lookup_cl (TYPE_NAME (type));
5287       return NULL_TREE;
5288     }
5289     
5290   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
5291     {
5292       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
5293       if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node
5294           && interface_of_p (type, BINFO_TYPE (vec_elt)))
5295         return lookup_cl (TYPE_NAME (BINFO_TYPE (vec_elt)));
5296     }
5297   return NULL_TREE;
5298 }
5299
5300 void
5301 java_check_circular_reference ()
5302 {
5303   tree current;
5304   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5305     {
5306       tree type = TREE_TYPE (current);
5307       tree cl;
5308
5309       cl = check_circular_reference (type);
5310       if (! cl)
5311         cl = check_inner_circular_reference (type, type);
5312       if (cl)
5313         parse_error_context (cl, "Cyclic class inheritance%s",
5314                              (cyclic_inheritance_report ?
5315                               cyclic_inheritance_report : ""));
5316     }
5317 }
5318
5319 /* Augment the parameter list PARM with parameters crafted to
5320    initialize outer context locals aliases. Through ARTIFICIAL, a
5321    count is kept of the number of crafted parameters. MODE governs
5322    what eventually gets created: something suitable for a function
5323    creation or a function invocation, either the constructor or
5324    finit$.  */
5325
5326 static tree
5327 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
5328     int mode;
5329     tree class_type, parm;
5330     int *artificial;
5331 {
5332   tree field;
5333   tree additional_parms = NULL_TREE;
5334
5335   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5336     if (FIELD_LOCAL_ALIAS (field))
5337       {
5338         const char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5339         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5340         tree mangled_id;
5341
5342         switch (mode)
5343           {
5344           case AIPL_FUNCTION_DECLARATION:
5345             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5346                                                          &buffer [4]);
5347             purpose = build_wfl_node (mangled_id);
5348             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5349               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5350             else
5351               value = TREE_TYPE (field);
5352             break;
5353
5354           case AIPL_FUNCTION_CREATION:
5355             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (purpose,
5356                                                          &buffer [4]);
5357             value = TREE_TYPE (field);
5358             break;
5359
5360           case AIPL_FUNCTION_FINIT_INVOCATION:
5361             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5362                                                          &buffer [4]);
5363             /* Now, this is wrong. purpose should always be the NAME
5364                of something and value its matching value (decl, type,
5365                etc...) FIXME -- but there is a lot to fix. */
5366
5367             /* When invoked for this kind of operation, we already
5368                know whether a field is used or not. */
5369             purpose = TREE_TYPE (field);
5370             value = build_wfl_node (mangled_id);
5371             break;
5372
5373           case AIPL_FUNCTION_CTOR_INVOCATION:
5374             /* There are two case: the constructor invokation happends
5375                outside the local inner, in which case, locales from the outer
5376                context are directly used.
5377
5378                Otherwise, we fold to using the alias directly. */
5379             if (class_type == current_class)
5380               value = field;
5381             else
5382               {
5383                 name = get_identifier (&buffer[4]);
5384                 value = IDENTIFIER_LOCAL_VALUE (name);
5385               }
5386             break;
5387           }
5388         additional_parms = tree_cons (purpose, value, additional_parms);
5389         if (artificial)
5390           *artificial +=1;
5391       }
5392   if (additional_parms)
5393     {
5394       if (ANONYMOUS_CLASS_P (class_type) 
5395           && mode == AIPL_FUNCTION_CTOR_INVOCATION)
5396         additional_parms = nreverse (additional_parms);
5397       parm = chainon (additional_parms, parm);
5398     }
5399
5400    return parm;
5401 }
5402
5403 /* Craft a constructor for CLASS_DECL -- what we should do when none
5404    where found. ARGS is non NULL when a special signature must be
5405    enforced. This is the case for anonymous classes.  */
5406
5407 static void
5408 craft_constructor (class_decl, args)
5409      tree class_decl, args;
5410 {
5411   tree class_type = TREE_TYPE (class_decl);
5412   tree parm = NULL_TREE;
5413   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5414                ACC_PUBLIC : 0);
5415   int i = 0, artificial = 0;
5416   tree decl, ctor_name;
5417   char buffer [80];
5418   
5419   /* The constructor name is <init> unless we're dealing with an
5420      anonymous class, in which case the name will be fixed after having
5421      be expanded. */
5422   if (ANONYMOUS_CLASS_P (class_type))
5423     ctor_name = DECL_NAME (class_decl);
5424   else
5425     ctor_name = init_identifier_node;
5426
5427   /* If we're dealing with an inner class constructor, we hide the
5428      this$<n> decl in the name field of its parameter declaration. */
5429   if (PURE_INNER_CLASS_TYPE_P (class_type))
5430     {
5431       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5432       parm = tree_cons (build_current_thisn (class_type),
5433                         build_pointer_type (type), parm);
5434
5435       /* Some more arguments to be hidden here. The values of the local
5436          variables of the outer context that the inner class needs to see. */
5437       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5438                                                      class_type, parm, 
5439                                                      &artificial);
5440     }
5441
5442   /* Then if there are any args to be enforced, enforce them now */
5443   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5444     {
5445       sprintf (buffer, "parm%d", i++);
5446       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5447     }
5448
5449   CRAFTED_PARAM_LIST_FIXUP (parm);
5450   decl = create_artificial_method (class_type, flags, void_type_node, 
5451                                    ctor_name, parm);
5452   fix_method_argument_names (parm, decl);
5453   /* Now, mark the artificial parameters. */
5454   DECL_FUNCTION_NAP (decl) = artificial;
5455   DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
5456 }
5457
5458
5459 /* Fix the constructors. This will be called right after circular
5460    references have been checked. It is necessary to fix constructors
5461    early even if no code generation will take place for that class:
5462    some generated constructor might be required by the class whose
5463    compilation triggered this one to be simply loaded.  */
5464
5465 void
5466 java_fix_constructors ()
5467 {
5468   tree current;
5469
5470   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5471     {
5472       tree class_type = TREE_TYPE (current);
5473       int saw_ctor = 0;
5474       tree decl;
5475
5476       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5477         continue;
5478
5479       current_class = class_type;
5480       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5481         {
5482           if (DECL_CONSTRUCTOR_P (decl))
5483             {
5484               fix_constructors (decl);
5485               saw_ctor = 1;
5486             }
5487         }
5488
5489       /* Anonymous class constructor can't be generated that early. */
5490       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5491         craft_constructor (current, NULL_TREE);
5492     }
5493 }
5494
5495 /* safe_layout_class just makes sure that we can load a class without
5496    disrupting the current_class, input_file, lineno, etc, information
5497    about the class processed currently.  */
5498
5499 void
5500 safe_layout_class (class)
5501      tree class;
5502 {
5503   tree save_current_class = current_class;
5504   const char *save_input_filename = input_filename;
5505   int save_lineno = lineno;
5506
5507   layout_class (class);
5508
5509   current_class = save_current_class;
5510   input_filename = save_input_filename;
5511   lineno = save_lineno;
5512 }
5513
5514 static tree
5515 jdep_resolve_class (dep)
5516      jdep *dep;
5517 {
5518   tree decl;
5519
5520   if (JDEP_RESOLVED_P (dep))
5521     decl = JDEP_RESOLVED_DECL (dep);
5522   else
5523     {
5524       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5525                             JDEP_DECL (dep), JDEP_WFL (dep));
5526       JDEP_RESOLVED (dep, decl);
5527     }
5528     
5529   if (!decl)
5530     complete_class_report_errors (dep);
5531   else if (PURE_INNER_CLASS_DECL_P (decl))
5532     {
5533       tree inner = TREE_TYPE (decl);
5534       if (! CLASS_LOADED_P (inner))
5535         {
5536           safe_layout_class (inner);
5537           if (TYPE_SIZE (inner) == error_mark_node)
5538             TYPE_SIZE (inner) = NULL_TREE;
5539         }
5540       check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
5541     }
5542   return decl;
5543 }
5544
5545 /* Complete unsatisfied class declaration and their dependencies */
5546
5547 void
5548 java_complete_class ()
5549 {
5550   tree cclass;
5551   jdeplist *cclassd;
5552   int error_found;
5553   tree type;
5554
5555   /* Process imports */
5556   process_imports ();
5557
5558   /* Rever things so we have the right order */
5559   ctxp->class_list = nreverse (ctxp->class_list);
5560   ctxp->classd_list = reverse_jdep_list (ctxp);
5561
5562   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5563        cclass && cclassd; 
5564        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5565     {
5566       jdep *dep;
5567       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5568         {
5569           tree decl;
5570           if (!(decl = jdep_resolve_class (dep)))
5571             continue;
5572
5573           /* Now it's time to patch */
5574           switch (JDEP_KIND (dep))
5575             {
5576             case JDEP_SUPER:
5577               /* Simply patch super */
5578               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5579                 continue;
5580               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5581                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5582               break;
5583
5584             case JDEP_FIELD:
5585               {
5586                 /* We do part of the job done in add_field */
5587                 tree field_decl = JDEP_DECL (dep);
5588                 tree field_type = TREE_TYPE (decl);
5589                 if (TREE_CODE (field_type) == RECORD_TYPE)
5590                   field_type = promote_type (field_type);
5591                 TREE_TYPE (field_decl) = field_type;
5592                 DECL_ALIGN (field_decl) = 0;
5593                 DECL_USER_ALIGN (field_decl) = 0;
5594                 layout_decl (field_decl, 0);
5595                 SOURCE_FRONTEND_DEBUG 
5596                   (("Completed field/var decl `%s' with `%s'",
5597                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5598                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5599                 break;
5600               }
5601             case JDEP_METHOD:   /* We start patching a method */
5602             case JDEP_METHOD_RETURN:
5603               error_found = 0;
5604               while (1)
5605                 {
5606                   if (decl)
5607                     {
5608                       type = TREE_TYPE(decl);
5609                       if (TREE_CODE (type) == RECORD_TYPE)
5610                         type = promote_type (type);
5611                       JDEP_APPLY_PATCH (dep, type);
5612                       SOURCE_FRONTEND_DEBUG 
5613                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5614                            "Completing fct `%s' with ret type `%s'":
5615                            "Completing arg `%s' with type `%s'"),
5616                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5617                                               (JDEP_DECL_WFL (dep))),
5618                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5619                     }
5620                   else
5621                     error_found = 1;
5622                   dep = JDEP_CHAIN (dep);
5623                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5624                     break;
5625                   else
5626                     decl = jdep_resolve_class (dep);
5627                 }
5628               if (!error_found)
5629                 {
5630                   tree mdecl = JDEP_DECL (dep), signature;
5631                   /* Recompute and reset the signature, check first that
5632                      all types are now defined. If they're not,
5633                      dont build the signature. */
5634                   if (check_method_types_complete (mdecl))
5635                     {
5636                       signature = build_java_signature (TREE_TYPE (mdecl));
5637                       set_java_signature (TREE_TYPE (mdecl), signature);
5638                     }
5639                 }
5640               else
5641                 continue;
5642               break;
5643
5644             case JDEP_INTERFACE:
5645               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5646                                                 JDEP_WFL (dep)))
5647                 continue;
5648               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5649               break;
5650
5651             case JDEP_PARM:
5652             case JDEP_VARIABLE:
5653               type = TREE_TYPE(decl);
5654               if (TREE_CODE (type) == RECORD_TYPE)
5655                 type = promote_type (type);
5656               JDEP_APPLY_PATCH (dep, type);
5657               break;
5658
5659             case JDEP_TYPE:
5660               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5661               SOURCE_FRONTEND_DEBUG 
5662                 (("Completing a random type dependency on a '%s' node",
5663                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5664               break;
5665
5666             case JDEP_EXCEPTION:
5667               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5668               SOURCE_FRONTEND_DEBUG 
5669                 (("Completing `%s' `throws' argument node",
5670                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5671               break;
5672
5673             case JDEP_ANONYMOUS:
5674               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5675               break;
5676
5677             default:
5678               abort ();
5679             }
5680         }
5681     }
5682   return;
5683 }
5684
5685 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5686    array.  */
5687
5688 static tree
5689 resolve_class (enclosing, class_type, decl, cl)
5690      tree enclosing, class_type, decl, cl;
5691 {
5692   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5693   const char *base = name;
5694   tree resolved_type = TREE_TYPE (class_type);
5695   tree resolved_type_decl;
5696   
5697   if (resolved_type != NULL_TREE)
5698     {
5699       tree resolved_type_decl = TYPE_NAME (resolved_type);
5700       if (resolved_type_decl == NULL_TREE
5701           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5702         {
5703           resolved_type_decl = build_decl (TYPE_DECL,
5704                                            TYPE_NAME (class_type),
5705                                            resolved_type);
5706         }
5707       return resolved_type_decl;
5708     }
5709
5710   /* 1- Check to see if we have an array. If true, find what we really
5711      want to resolve  */
5712   while (name[0] == '[')
5713     name++;
5714   if (base != name)
5715     {
5716       TYPE_NAME (class_type) = get_identifier (name);
5717       WFL_STRIP_BRACKET (cl, cl);
5718     }
5719
5720   /* 2- Resolve the bare type */
5721   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5722                                                decl, cl)))
5723     return NULL_TREE;
5724   resolved_type = TREE_TYPE (resolved_type_decl);
5725
5726   /* 3- If we have and array, reconstruct the array down to its nesting */
5727   if (base != name)
5728     {
5729       while (base != name)
5730         {
5731           resolved_type = build_java_array_type (resolved_type, -1);
5732           name--;
5733         }
5734       /* A TYPE_NAME that is a TYPE_DECL was set in
5735          build_java_array_type, return it. */
5736       resolved_type_decl = TYPE_NAME (resolved_type);
5737     }
5738   TREE_TYPE (class_type) = resolved_type;
5739   return resolved_type_decl;
5740 }
5741
5742 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5743    are used to report error messages. Do not try to replace TYPE_NAME
5744    (class_type) by a variable, since it is changed by
5745    find_in_imports{_on_demand} and (but it doesn't really matter)
5746    qualify_and_find.  */
5747
5748 tree
5749 do_resolve_class (enclosing, class_type, decl, cl)
5750      tree enclosing, class_type, decl, cl;
5751 {
5752   tree new_class_decl = NULL_TREE, super = NULL_TREE;
5753   struct hash_table _ht, *circularity_hash = &_ht;
5754
5755   /* This hash table is used to register the classes we're going
5756      through when searching the current class as an inner class, in
5757      order to detect circular references. Remember to free it before
5758      returning the section 0- of this function. */
5759   hash_table_init (circularity_hash, hash_newfunc,
5760                    java_hash_hash_tree_node, java_hash_compare_tree_node);
5761
5762   /* 0- Search in the current class as an inner class.
5763      Maybe some code here should be added to load the class or
5764      something, at least if the class isn't an inner class and ended
5765      being loaded from class file. FIXME. */
5766   while (enclosing)
5767     {
5768       new_class_decl = resolve_inner_class (circularity_hash, cl, &enclosing,
5769                                             &super, class_type);
5770       if (new_class_decl)
5771         break;
5772
5773       /* If we haven't found anything because SUPER reached Object and
5774          ENCLOSING happens to be an innerclass, try the enclosing context. */
5775       if ((!super || super == object_type_node) && 
5776           enclosing && INNER_CLASS_DECL_P (enclosing))
5777         enclosing = DECL_CONTEXT (enclosing);
5778       else
5779         enclosing = NULL_TREE;
5780     }
5781
5782   hash_table_free (circularity_hash);
5783
5784   if (new_class_decl)
5785     return new_class_decl;
5786
5787   /* 1- Check for the type in single imports. This will change
5788      TYPE_NAME() if something relevant is found */
5789   find_in_imports (class_type);
5790
5791   /* 2- And check for the type in the current compilation unit */
5792   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5793     {
5794       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5795           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5796         load_class (TYPE_NAME (class_type), 0);
5797       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5798     }
5799
5800   /* 3- Search according to the current package definition */
5801   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5802     {
5803       if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
5804                                              TYPE_NAME (class_type))))
5805         return new_class_decl;
5806     }
5807
5808   /* 4- Check the import on demands. Don't allow bar.baz to be
5809      imported from foo.* */
5810   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5811     if (find_in_imports_on_demand (class_type))
5812       return NULL_TREE;
5813
5814   /* If found in find_in_imports_on_demant, the type has already been
5815      loaded. */
5816   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5817     return new_class_decl;
5818
5819   /* 5- Try with a name qualified with the package name we've seen so far */
5820   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5821     {
5822       tree package;
5823
5824       /* If there is a current package (ctxp->package), it's the first
5825          element of package_list and we can skip it. */
5826       for (package = (ctxp->package ? 
5827                       TREE_CHAIN (package_list) : package_list);
5828            package; package = TREE_CHAIN (package))
5829         if ((new_class_decl = qualify_and_find (class_type,
5830                                                TREE_PURPOSE (package), 
5831                                                TYPE_NAME (class_type))))
5832           return new_class_decl;
5833     }
5834
5835   /* 5- Check an other compilation unit that bears the name of type */
5836   load_class (TYPE_NAME (class_type), 0);
5837   
5838   if (!cl)
5839     cl = lookup_cl (decl);
5840   
5841   /* If we don't have a value for CL, then we're being called recursively. 
5842      We can't check package access just yet, but it will be taken care of
5843      by the caller. */
5844   if (cl)
5845     {
5846       if (check_pkg_class_access (TYPE_NAME (class_type), cl))
5847         return NULL_TREE;
5848     }
5849   
5850   /* 6- Last call for a resolution */
5851   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5852 }
5853
5854 static tree
5855 qualify_and_find (class_type, package, name)
5856      tree class_type, package, name;
5857 {
5858   tree new_qualified = merge_qualified_name (package, name);
5859   tree new_class_decl;
5860
5861   if (!IDENTIFIER_CLASS_VALUE (new_qualified))
5862     load_class (new_qualified, 0);
5863   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
5864     {
5865       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5866           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5867         load_class (new_qualified, 0);
5868       TYPE_NAME (class_type) = new_qualified;
5869       return IDENTIFIER_CLASS_VALUE (new_qualified);
5870     }
5871   return NULL_TREE;
5872 }
5873
5874 /* Resolve NAME and lay it out (if not done and if not the current
5875    parsed class). Return a decl node. This function is meant to be
5876    called when type resolution is necessary during the walk pass.  */
5877
5878 static tree
5879 resolve_and_layout (something, cl)
5880      tree something;
5881      tree cl;
5882 {
5883   tree decl, decl_type;
5884
5885   /* Don't do that on the current class */
5886   if (something == current_class)
5887     return TYPE_NAME (current_class);
5888
5889   /* Don't do anything for void and other primitive types */
5890   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5891     return NULL_TREE;
5892
5893   /* Pointer types can be reall pointer types or fake pointers. When
5894      finding a real pointer, recheck for primitive types */
5895   if (TREE_CODE (something) == POINTER_TYPE)
5896     {
5897       if (TREE_TYPE (something))
5898         {
5899           something = TREE_TYPE (something);
5900           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5901             return NULL_TREE;
5902         }
5903       else
5904         something = TYPE_NAME (something);
5905     }
5906
5907   /* Don't do anything for arrays of primitive types */
5908   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5909       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5910     return NULL_TREE;
5911
5912   /* Something might be a WFL */
5913   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5914     something = EXPR_WFL_NODE (something);
5915
5916   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5917      TYPE_DECL or a real TYPE */
5918   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5919     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5920             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5921
5922   if (!(decl = resolve_no_layout (something, cl)))
5923     return NULL_TREE;
5924
5925   /* Resolve and layout if necessary */
5926   decl_type = TREE_TYPE (decl);
5927   layout_class_methods (decl_type);
5928   /* Check methods */
5929   if (CLASS_FROM_SOURCE_P (decl_type))
5930     java_check_methods (decl);
5931   /* Layout the type if necessary */ 
5932   if (decl_type != current_class && !CLASS_LOADED_P (decl_type))
5933     safe_layout_class (decl_type);
5934
5935   return decl;
5936 }
5937
5938 /* Resolve a class, returns its decl but doesn't perform any
5939    layout. The current parsing context is saved and restored */
5940
5941 static tree
5942 resolve_no_layout (name, cl)
5943      tree name, cl;
5944 {
5945   tree ptr, decl;
5946   BUILD_PTR_FROM_NAME (ptr, name);
5947   java_parser_context_save_global ();
5948   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5949   java_parser_context_restore_global ();
5950   
5951   return decl;
5952 }
5953
5954 /* Called when reporting errors. Skip leader '[' in a complex array
5955    type description that failed to be resolved.  */
5956
5957 static const char *
5958 purify_type_name (name)
5959      const char *name;
5960 {
5961   while (*name && *name == '[')
5962     name++;
5963   return name;
5964 }
5965
5966 /* The type CURRENT refers to can't be found. We print error messages.  */
5967
5968 static void
5969 complete_class_report_errors (dep)
5970      jdep *dep;
5971 {
5972   const char *name;
5973
5974   if (!JDEP_WFL (dep))
5975     return;
5976
5977   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5978   switch (JDEP_KIND (dep))
5979     {
5980     case JDEP_SUPER:
5981       parse_error_context  
5982         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5983          purify_type_name (name),
5984          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5985       break;
5986     case JDEP_FIELD:
5987       parse_error_context
5988         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5989          purify_type_name (name),
5990          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5991       break;
5992     case JDEP_METHOD:           /* Covers arguments */
5993       parse_error_context
5994         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5995          purify_type_name (name),
5996          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5997          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5998       break;
5999     case JDEP_METHOD_RETURN:    /* Covers return type */
6000       parse_error_context
6001         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
6002          purify_type_name (name),
6003          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
6004       break;
6005     case JDEP_INTERFACE:
6006       parse_error_context
6007         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
6008          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
6009          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
6010          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6011       break;
6012     case JDEP_VARIABLE:
6013       parse_error_context
6014         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
6015          purify_type_name (IDENTIFIER_POINTER 
6016                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
6017          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6018       break;
6019     case JDEP_EXCEPTION:        /* As specified by `throws' */
6020       parse_error_context 
6021           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
6022          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
6023       break;
6024     default:
6025       /* Fix for -Wall. Just break doing nothing. The error will be
6026          caught later */
6027       break;
6028     }
6029 }
6030
6031 /* Return a static string containing the DECL prototype string. If
6032    DECL is a constructor, use the class name instead of the form
6033    <init> */
6034
6035 static const char *
6036 get_printable_method_name (decl)
6037      tree decl;
6038 {
6039   const char *to_return;
6040   tree name = NULL_TREE;
6041
6042   if (DECL_CONSTRUCTOR_P (decl))
6043     {
6044       name = DECL_NAME (decl);
6045       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
6046     }
6047       
6048   to_return = lang_printable_name (decl, 0);
6049   if (DECL_CONSTRUCTOR_P (decl))
6050     DECL_NAME (decl) = name;
6051   
6052   return to_return;
6053 }
6054
6055 /* Track method being redefined inside the same class. As a side
6056    effect, set DECL_NAME to an IDENTIFIER (prior entering this
6057    function it's a FWL, so we can track errors more accurately.)  */
6058
6059 static int
6060 check_method_redefinition (class, method)
6061      tree class, method;
6062 {
6063   tree redef, sig;
6064
6065   /* There's no need to verify <clinit> and finit$ and instinit$ */
6066   if (DECL_CLINIT_P (method)
6067       || DECL_FINIT_P (method) || DECL_INSTINIT_P (method))
6068     return 0;
6069
6070   sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
6071   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
6072     {
6073       if (redef == method)
6074         break;
6075       if (DECL_NAME (redef) == DECL_NAME (method)
6076           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef))
6077           && !DECL_ARTIFICIAL (method))
6078         {
6079           parse_error_context 
6080             (DECL_FUNCTION_WFL (method), "Duplicate %s declaration `%s'",
6081              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
6082              get_printable_method_name (redef));
6083           return 1;
6084         }
6085     }
6086   return 0;
6087 }
6088
6089 /* Return 1 if check went ok, 0 otherwise.  */
6090 static int
6091 check_abstract_method_definitions (do_interface, class_decl, type)
6092      int do_interface;
6093      tree class_decl, type;
6094 {
6095   tree class = TREE_TYPE (class_decl);
6096   tree method, end_type;
6097   int ok = 1;
6098
6099   end_type = (do_interface ? object_type_node : type);
6100   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
6101     {
6102       tree other_super, other_method, method_sig, method_name;
6103       int found = 0;
6104       int end_type_reached = 0;
6105       
6106       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
6107         continue;
6108       
6109       /* Now verify that somewhere in between TYPE and CLASS,
6110          abstract method METHOD gets a non abstract definition
6111          that is inherited by CLASS.  */
6112       
6113       method_sig = build_java_signature (TREE_TYPE (method));
6114       method_name = DECL_NAME (method);
6115       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
6116         method_name = EXPR_WFL_NODE (method_name);
6117
6118       other_super = class;
6119       do {
6120         if (other_super == end_type)
6121           end_type_reached = 1;
6122         
6123         /* Method search */
6124         for (other_method = TYPE_METHODS (other_super); other_method;
6125             other_method = TREE_CHAIN (other_method))
6126           {
6127             tree s = build_java_signature (TREE_TYPE (other_method));
6128             tree other_name = DECL_NAME (other_method);
6129             
6130             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
6131               other_name = EXPR_WFL_NODE (other_name);
6132             if (!DECL_CLINIT_P (other_method)
6133                 && !DECL_CONSTRUCTOR_P (other_method)
6134                 && method_name == other_name
6135                 && method_sig == s
6136                 && !METHOD_ABSTRACT (other_method))
6137              {
6138                found = 1;
6139                break;
6140              }
6141           }
6142         other_super = CLASSTYPE_SUPER (other_super);
6143       } while (!end_type_reached);
6144  
6145       /* Report that abstract METHOD didn't find an implementation
6146          that CLASS can use. */
6147       if (!found)
6148         {
6149           char *t = xstrdup (lang_printable_name 
6150                             (TREE_TYPE (TREE_TYPE (method)), 0));
6151           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
6152           
6153           parse_error_context 
6154             (lookup_cl (class_decl),
6155              "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",
6156              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6157              t, lang_printable_name (method, 0), 
6158              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
6159               "interface" : "class"),
6160              IDENTIFIER_POINTER (ccn),
6161              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
6162              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
6163           ok = 0;
6164           free (t);
6165         }
6166     }
6167
6168   if (ok && do_interface)
6169     {
6170       /* Check for implemented interfaces. */
6171       int i;
6172       tree vector = TYPE_BINFO_BASETYPES (type);
6173       for (i = 1; ok && vector && i < TREE_VEC_LENGTH (vector); i++)
6174         {
6175           tree super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
6176           ok = check_abstract_method_definitions (1, class_decl, super);
6177         }
6178     }
6179
6180   return ok;
6181 }
6182
6183 /* Check that CLASS_DECL somehow implements all inherited abstract
6184    methods.  */
6185
6186 static void
6187 java_check_abstract_method_definitions (class_decl)
6188      tree class_decl;
6189 {
6190   tree class = TREE_TYPE (class_decl);
6191   tree super, vector;
6192   int i;
6193
6194   if (CLASS_ABSTRACT (class_decl))
6195     return;
6196
6197   /* Check for inherited types */
6198   super = class;
6199   do {
6200     super = CLASSTYPE_SUPER (super);
6201     check_abstract_method_definitions (0, class_decl, super);
6202   } while (super != object_type_node);
6203
6204   /* Check for implemented interfaces. */
6205   vector = TYPE_BINFO_BASETYPES (class);
6206   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
6207     {
6208       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
6209       check_abstract_method_definitions (1, class_decl, super);
6210     }
6211 }
6212
6213 /* Check all the types method DECL uses and return 1 if all of them
6214    are now complete, 0 otherwise. This is used to check whether its
6215    safe to build a method signature or not.  */
6216
6217 static int
6218 check_method_types_complete (decl)
6219      tree decl;
6220 {
6221   tree type = TREE_TYPE (decl);
6222   tree args;
6223
6224   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
6225     return 0;
6226   
6227   args = TYPE_ARG_TYPES (type);
6228   if (TREE_CODE (type) == METHOD_TYPE)
6229     args = TREE_CHAIN (args);
6230   for (; args != end_params_node; args = TREE_CHAIN (args))
6231     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
6232       return 0;
6233
6234   return 1;
6235 }
6236
6237 /* Visible interface to check methods contained in CLASS_DECL */
6238
6239 void
6240 java_check_methods (class_decl)
6241      tree class_decl;
6242 {
6243   if (CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)))
6244     return;
6245
6246   if (CLASS_INTERFACE (class_decl))
6247     java_check_abstract_methods (class_decl);
6248   else
6249     java_check_regular_methods (class_decl);
6250   
6251   CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)) = 1;
6252 }
6253
6254 /* Check all the methods of CLASS_DECL. Methods are first completed
6255    then checked according to regular method existance rules.  If no
6256    constructor for CLASS_DECL were encountered, then build its
6257    declaration.  */
6258
6259 static void
6260 java_check_regular_methods (class_decl)
6261      tree class_decl;
6262 {
6263   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
6264   tree method;
6265   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
6266   tree found = NULL_TREE;
6267   tree mthrows;
6268
6269   /* It is not necessary to check methods defined in java.lang.Object */
6270   if (class == object_type_node)
6271     return;
6272
6273   if (!TYPE_NVIRTUALS (class))
6274     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6275
6276   /* Should take interfaces into account. FIXME */
6277   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
6278     {
6279       tree sig;
6280       tree method_wfl = DECL_FUNCTION_WFL (method);
6281       int aflags;
6282
6283       /* Check for redefinitions */
6284       if (check_method_redefinition (class, method))
6285         continue;
6286
6287       /* If we see one constructor a mark so we don't generate the
6288          default one. Also skip other verifications: constructors
6289          can't be inherited hence hiden or overriden */
6290      if (DECL_CONSTRUCTOR_P (method))
6291        {
6292          saw_constructor = 1;
6293          continue;
6294        }
6295
6296       /* We verify things thrown by the method. They must inherits from
6297          java.lang.Throwable */
6298       for (mthrows = DECL_FUNCTION_THROWS (method);
6299            mthrows; mthrows = TREE_CHAIN (mthrows))
6300         {
6301           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
6302             parse_error_context 
6303               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
6304                IDENTIFIER_POINTER 
6305                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
6306         }
6307
6308       sig = build_java_argument_signature (TREE_TYPE (method));
6309       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
6310
6311       /* Inner class can't declare static methods */
6312       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
6313         {
6314           char *t = xstrdup (lang_printable_name (class, 0));
6315           parse_error_context 
6316             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
6317              lang_printable_name (method, 0), t);
6318           free (t);
6319         }
6320
6321       /* Nothing overrides or it's a private method. */
6322       if (!found)
6323         continue;
6324       if (METHOD_PRIVATE (found))
6325         {
6326           found = NULL_TREE;
6327           continue;
6328         }
6329
6330       /* If `found' is declared in an interface, make sure the
6331          modifier matches. */
6332       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6333           && clinit_identifier_node != DECL_NAME (found)
6334           && !METHOD_PUBLIC (method))
6335         {
6336           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6337           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6338                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6339                                lang_printable_name (method, 0),
6340                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6341         }
6342
6343       /* Can't override a method with the same name and different return
6344          types. */
6345       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6346         {
6347           char *t = xstrdup 
6348             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6349           parse_error_context 
6350             (method_wfl,
6351              "Method `%s' was defined with return type `%s' in class `%s'", 
6352              lang_printable_name (found, 0), t,
6353              IDENTIFIER_POINTER 
6354                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6355           free (t);
6356         }
6357
6358       aflags = get_access_flags_from_decl (found);
6359
6360       /* Can't override final. Can't override static. */
6361       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6362         {
6363           /* Static *can* override static */
6364           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6365             continue;
6366           parse_error_context 
6367             (method_wfl,
6368              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6369              (METHOD_FINAL (found) ? "Final" : "Static"),
6370              lang_printable_name (found, 0),
6371              (METHOD_FINAL (found) ? "final" : "static"),
6372              IDENTIFIER_POINTER
6373                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6374           continue;
6375         }
6376
6377       /* Static method can't override instance method. */
6378       if (METHOD_STATIC (method))
6379         {
6380           parse_error_context 
6381             (method_wfl,
6382              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6383              lang_printable_name (found, 0),
6384              IDENTIFIER_POINTER
6385                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6386           continue;
6387         }
6388
6389       /* - Overriding/hiding public must be public
6390          - Overriding/hiding protected must be protected or public
6391          - If the overriden or hidden method has default (package)
6392            access, then the overriding or hiding method must not be
6393            private; otherwise, a compile-time error occurs.  If
6394            `found' belongs to an interface, things have been already
6395            taken care of.  */
6396       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6397           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6398               || (METHOD_PROTECTED (found) 
6399                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6400               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6401                   && METHOD_PRIVATE (method))))
6402         {
6403           parse_error_context 
6404             (method_wfl,
6405              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6406              (METHOD_PUBLIC (method) ? "public" : 
6407               (METHOD_PRIVATE (method) ? "private" : "protected")),
6408              IDENTIFIER_POINTER (DECL_NAME 
6409                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6410           continue;
6411         }
6412
6413       /* Overriding methods must have compatible `throws' clauses on checked
6414          exceptions, if any */
6415       check_throws_clauses (method, method_wfl, found);
6416
6417       /* Inheriting multiple methods with the same signature. FIXME */
6418     }
6419   
6420   if (!TYPE_NVIRTUALS (class))
6421     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6422
6423   /* Search for inherited abstract method not yet implemented in this
6424      class.  */
6425   java_check_abstract_method_definitions (class_decl);
6426
6427   if (!saw_constructor)
6428     abort ();
6429 }
6430
6431 /* Return a non zero value if the `throws' clause of METHOD (if any)
6432    is incompatible with the `throws' clause of FOUND (if any).  */
6433
6434 static void
6435 check_throws_clauses (method, method_wfl, found)
6436      tree method, method_wfl, found;
6437 {
6438   tree mthrows, fthrows;
6439
6440   /* Can't check these things with class loaded from bytecode. FIXME */
6441   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6442     return;
6443
6444   for (mthrows = DECL_FUNCTION_THROWS (method);
6445        mthrows; mthrows = TREE_CHAIN (mthrows))
6446     {
6447       /* We don't verify unchecked expressions */
6448       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6449         continue;
6450       /* Checked expression must be compatible */
6451       for (fthrows = DECL_FUNCTION_THROWS (found); 
6452            fthrows; fthrows = TREE_CHAIN (fthrows))
6453         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6454           break;
6455       if (!fthrows)
6456         {
6457           parse_error_context 
6458             (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'",
6459              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6460              lang_printable_name (found, 0),
6461              IDENTIFIER_POINTER 
6462                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6463         }
6464     }
6465 }
6466
6467 /* Check abstract method of interface INTERFACE */
6468
6469 static void
6470 java_check_abstract_methods (interface_decl)
6471      tree interface_decl;
6472 {
6473   int i, n;
6474   tree method, basetype_vec, found;
6475   tree interface = TREE_TYPE (interface_decl);
6476
6477   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6478     {
6479       /* 2- Check for double definition inside the defining interface */
6480       if (check_method_redefinition (interface, method))
6481         continue;
6482
6483       /* 3- Overriding is OK as far as we preserve the return type and
6484          the thrown exceptions (FIXME) */
6485       found = lookup_java_interface_method2 (interface, method);
6486       if (found)
6487         {
6488           char *t;
6489           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6490           parse_error_context 
6491             (DECL_FUNCTION_WFL (found),
6492              "Method `%s' was defined with return type `%s' in class `%s'",
6493              lang_printable_name (found, 0), t,
6494              IDENTIFIER_POINTER 
6495                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6496           free (t);
6497           continue;
6498         }
6499     }
6500
6501   /* 4- Inherited methods can't differ by their returned types */
6502   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6503     return;
6504   n = TREE_VEC_LENGTH (basetype_vec);
6505   for (i = 0; i < n; i++)
6506     {
6507       tree sub_interface_method, sub_interface;
6508       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6509       if (!vec_elt)
6510         continue;
6511       sub_interface = BINFO_TYPE (vec_elt);
6512       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6513            sub_interface_method;
6514            sub_interface_method = TREE_CHAIN (sub_interface_method))
6515         {
6516           found = lookup_java_interface_method2 (interface, 
6517                                                  sub_interface_method);
6518           if (found && (found != sub_interface_method))
6519             {
6520               parse_error_context 
6521                 (lookup_cl (sub_interface_method),
6522                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6523                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6524                  lang_printable_name (found, 0),
6525                  IDENTIFIER_POINTER 
6526                    (DECL_NAME (TYPE_NAME 
6527                                (DECL_CONTEXT (sub_interface_method)))),
6528                  IDENTIFIER_POINTER 
6529                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6530             }
6531         }
6532     }
6533 }
6534
6535 /* Lookup methods in interfaces using their name and partial
6536    signature. Return a matching method only if their types differ.  */
6537
6538 static tree
6539 lookup_java_interface_method2 (class, method_decl)
6540      tree class, method_decl;
6541 {
6542   int i, n;
6543   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6544
6545   if (!basetype_vec)
6546     return NULL_TREE;
6547
6548   n = TREE_VEC_LENGTH (basetype_vec);
6549   for (i = 0; i < n; i++)
6550     {
6551       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6552       if ((BINFO_TYPE (vec_elt) != object_type_node)
6553           && (to_return = 
6554               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6555         return to_return;
6556     }
6557   for (i = 0; i < n; i++)
6558     {
6559       to_return = lookup_java_interface_method2 
6560         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6561       if (to_return)
6562         return to_return;
6563     }
6564
6565   return NULL_TREE;
6566 }
6567
6568 /* Lookup method using their name and partial signature. Return a
6569    matching method only if their types differ.  */
6570
6571 static tree
6572 lookup_java_method2 (clas, method_decl, do_interface)
6573      tree clas, method_decl;
6574      int do_interface;
6575 {
6576   tree method, method_signature, method_name, method_type, name;
6577
6578   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6579   name = DECL_NAME (method_decl);
6580   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6581                  EXPR_WFL_NODE (name) : name);
6582   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6583
6584   while (clas != NULL_TREE)
6585     {
6586       for (method = TYPE_METHODS (clas);
6587            method != NULL_TREE;  method = TREE_CHAIN (method))
6588         {
6589           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6590           tree name = DECL_NAME (method);
6591           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6592                EXPR_WFL_NODE (name) : name) == method_name
6593               && method_sig == method_signature 
6594               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6595             return method;
6596         }
6597       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6598     }
6599   return NULL_TREE;
6600 }
6601
6602 /* Return the line that matches DECL line number, and try its best to
6603    position the column number. Used during error reports.  */
6604
6605 static tree
6606 lookup_cl (decl)
6607      tree decl;
6608 {
6609   static tree cl = NULL_TREE;
6610   char *line, *found;
6611   
6612   if (!decl)
6613     return NULL_TREE;
6614
6615   if (cl == NULL_TREE)
6616     {
6617       cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6618       ggc_add_tree_root (&cl, 1);
6619     }
6620
6621   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6622   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6623
6624   line = java_get_line_col (EXPR_WFL_FILENAME (cl), 
6625                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6626
6627   found = strstr ((const char *)line, 
6628                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6629   if (found)
6630     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6631
6632   return cl;
6633 }
6634
6635 /* Look for a simple name in the single-type import list */
6636
6637 static tree
6638 find_name_in_single_imports (name)
6639      tree name;
6640 {
6641   tree node;
6642
6643   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6644     if (TREE_VALUE (node) == name)
6645       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6646
6647   return NULL_TREE;
6648 }
6649
6650 /* Process all single-type import. */
6651
6652 static int
6653 process_imports ()
6654 {
6655   tree import;
6656   int error_found;
6657
6658   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6659     {
6660       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6661       char *original_name;
6662
6663       obstack_grow0 (&temporary_obstack,
6664                      IDENTIFIER_POINTER (to_be_found),
6665                      IDENTIFIER_LENGTH (to_be_found));
6666       original_name = obstack_finish (&temporary_obstack);
6667
6668       /* Don't load twice something already defined. */
6669       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6670         continue;
6671       
6672       while (1)
6673         {
6674           tree left;
6675
6676           QUALIFIED_P (to_be_found) = 1;
6677           load_class (to_be_found, 0);
6678           error_found =
6679             check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6680           
6681           /* We found it, we can bail out */
6682           if (IDENTIFIER_CLASS_VALUE (to_be_found))
6683             break;
6684
6685           /* We haven't found it. Maybe we're trying to access an
6686              inner class.  The only way for us to know is to try again
6687              after having dropped a qualifier. If we can't break it further,
6688              we have an error. */
6689           if (breakdown_qualified (&left, NULL, to_be_found))
6690             break;
6691
6692           to_be_found = left;
6693         }
6694       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6695         {
6696           parse_error_context (TREE_PURPOSE (import),
6697                                "Class or interface `%s' not found in import",
6698                                original_name);
6699           error_found = 1;
6700         }
6701
6702       obstack_free (&temporary_obstack, original_name);
6703       if (error_found)
6704         return 1;
6705     }
6706   return 0;
6707 }
6708
6709 /* Possibly find and mark a class imported by a single-type import
6710    statement.  */
6711
6712 static void
6713 find_in_imports (class_type)
6714      tree class_type;
6715 {
6716   tree import;
6717
6718   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6719     if (TREE_VALUE (import) == TYPE_NAME (class_type))
6720       {
6721         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6722         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6723       }
6724 }
6725
6726 static int
6727 note_possible_classname (name, len)
6728      const char *name;
6729      int len;
6730 {
6731   tree node;
6732   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6733     len = len - 5;
6734   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6735     len = len - 6;
6736   else
6737     return 0;
6738   node = ident_subst (name, len, "", '/', '.', "");
6739   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6740   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6741   return 1;
6742 }
6743
6744 /* Read a import directory, gathering potential match for further type
6745    references. Indifferently reads a filesystem or a ZIP archive
6746    directory.  */
6747
6748 static void
6749 read_import_dir (wfl)
6750      tree wfl;
6751 {
6752   tree package_id = EXPR_WFL_NODE (wfl);
6753   const char *package_name = IDENTIFIER_POINTER (package_id);
6754   int package_length = IDENTIFIER_LENGTH (package_id);
6755   DIR *dirp = NULL;
6756   JCF *saved_jcf = current_jcf;
6757
6758   int found = 0;
6759   int k;
6760   void *entry;
6761   struct buffer filename[1];
6762
6763
6764   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6765     return;
6766   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6767
6768   BUFFER_INIT (filename);
6769   buffer_grow (filename, package_length + 100);
6770
6771   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6772     {
6773       const char *entry_name = jcf_path_name (entry);
6774       int entry_length = strlen (entry_name);
6775       if (jcf_path_is_zipfile (entry))
6776         {
6777           ZipFile *zipf;
6778           buffer_grow (filename, entry_length);
6779           memcpy (filename->data, entry_name, entry_length - 1);
6780           filename->data[entry_length-1] = '\0';
6781           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6782           if (zipf == NULL)
6783             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6784           else
6785             {
6786               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6787               BUFFER_RESET (filename);
6788               for (k = 0; k < package_length; k++)
6789                 {
6790                   char ch = package_name[k];
6791                   *filename->ptr++ = ch == '.' ? '/' : ch;
6792                 }
6793               *filename->ptr++ = '/';
6794
6795               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6796                 {
6797                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6798                   int current_entry_len = zipd->filename_length;
6799
6800                   if (current_entry_len >= BUFFER_LENGTH (filename)
6801                       && strncmp (filename->data, current_entry, 
6802                                   BUFFER_LENGTH (filename)) != 0)
6803                     continue;
6804                   found |= note_possible_classname (current_entry,
6805                                                     current_entry_len);
6806                 }
6807             }
6808         }
6809       else
6810         {
6811           BUFFER_RESET (filename);
6812           buffer_grow (filename, entry_length + package_length + 4);
6813           strcpy (filename->data, entry_name);
6814           filename->ptr = filename->data + entry_length;
6815           for (k = 0; k < package_length; k++)
6816             {
6817               char ch = package_name[k];
6818               *filename->ptr++ = ch == '.' ? '/' : ch;
6819             }
6820           *filename->ptr = '\0';
6821
6822           dirp = opendir (filename->data);
6823           if (dirp == NULL)
6824             continue;
6825           *filename->ptr++ = '/';
6826           for (;;)
6827             {
6828               int len; 
6829               const char *d_name;
6830               struct dirent *direntp = readdir (dirp);
6831               if (!direntp)
6832                 break;
6833               d_name = direntp->d_name;
6834               len = strlen (direntp->d_name);
6835               buffer_grow (filename, len+1);
6836               strcpy (filename->ptr, d_name);
6837               found |= note_possible_classname (filename->data + entry_length,
6838                                                 package_length+len+1);
6839             }
6840           if (dirp)
6841             closedir (dirp);
6842         }
6843     }
6844
6845   free (filename->data);
6846
6847   /* Here we should have a unified way of retrieving an entry, to be
6848      indexed. */
6849   if (!found)
6850     {
6851       static int first = 1;
6852       if (first)
6853         {
6854           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6855           java_error_count++;
6856           first = 0;
6857         }
6858       else
6859         parse_error_context (wfl, "Package `%s' not found in import",
6860                              package_name);
6861       current_jcf = saved_jcf;
6862       return;
6863     }
6864   current_jcf = saved_jcf;
6865 }
6866
6867 /* Possibly find a type in the import on demands specified
6868    types. Returns 1 if an error occured, 0 otherwise. Run throught the
6869    entire list, to detected potential double definitions.  */
6870                  
6871 static int
6872 find_in_imports_on_demand (class_type)
6873      tree class_type;
6874 {
6875   tree node, import, node_to_use = NULL_TREE;
6876   int seen_once = -1;
6877   tree cl = NULL_TREE;
6878
6879   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6880     {
6881       const char *id_name;
6882       obstack_grow (&temporary_obstack, 
6883                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6884                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6885       obstack_1grow (&temporary_obstack, '.');
6886       obstack_grow0 (&temporary_obstack, 
6887                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6888                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6889       id_name = obstack_finish (&temporary_obstack);
6890               
6891       node = maybe_get_identifier (id_name);
6892       if (node && IS_A_CLASSFILE_NAME (node))
6893         {
6894           if (seen_once < 0)
6895             {
6896               cl = TREE_PURPOSE (import);
6897               seen_once = 1;
6898               node_to_use = node;
6899             }
6900           else
6901             {
6902               seen_once++;
6903               parse_error_context 
6904                 (TREE_PURPOSE (import), 
6905                  "Type `%s' also potentially defined in package `%s'",
6906                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6907                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6908             }
6909         }
6910     }
6911
6912   if (seen_once == 1)
6913     {
6914       /* Setup lineno so that it refers to the line of the import (in
6915          case we parse a class file and encounter errors */
6916       tree decl;
6917       int saved_lineno = lineno;
6918       lineno = EXPR_WFL_LINENO (cl);
6919       TYPE_NAME (class_type) = node_to_use;
6920       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6921       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6922       /* If there is no DECL set for the class or if the class isn't
6923          loaded and not seen in source yet, the load */
6924       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6925                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6926         {
6927           load_class (node_to_use, 0);
6928           decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6929         }
6930       lineno = saved_lineno;
6931       if (! INNER_CLASS_P (TREE_TYPE (decl)))
6932         return check_pkg_class_access (TYPE_NAME (class_type), cl);
6933       else
6934         /* 6.6.1: Inner classes are subject to member access rules. */
6935         return 0;
6936     }
6937   else
6938     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6939 }
6940
6941 /* Add package NAME to the list of package encountered so far. To
6942    speed up class lookup in do_resolve_class, we make sure a
6943    particular package is added only once.  */
6944
6945 static void
6946 register_package (name)
6947      tree name;
6948 {
6949   static struct hash_table _pht, *pht = NULL;
6950
6951   if (!pht)
6952     {
6953       hash_table_init (&_pht, hash_newfunc, 
6954                        java_hash_hash_tree_node, java_hash_compare_tree_node);
6955       pht = &_pht;
6956     }
6957   
6958   if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
6959     {
6960       package_list = chainon (package_list, build_tree_list (name, NULL));
6961       hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
6962     }
6963 }
6964
6965 static tree
6966 resolve_package (pkg, next)
6967      tree pkg, *next;
6968 {
6969   tree current, acc;
6970   tree type_name = NULL_TREE;
6971   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6972
6973   /* The trick is to determine when the package name stops and were
6974      the name of something contained in the package starts. Then we
6975      return a fully qualified name of what we want to get. */
6976
6977   /* Do a quick search on well known package names */
6978   if (!strncmp (name, "java.lang.reflect", 17))
6979     {
6980       *next = 
6981         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6982       type_name = lookup_package_type (name, 17);
6983     }
6984   else if (!strncmp (name, "java.lang", 9))
6985     {
6986       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6987       type_name = lookup_package_type (name, 9);
6988     }
6989
6990   /* If we found something here, return */
6991   if (type_name)
6992     return type_name; 
6993
6994   *next = EXPR_WFL_QUALIFICATION (pkg);
6995
6996   /* Try to progressively construct a type name */
6997   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6998     for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
6999          current; current = TREE_CHAIN (current))
7000       {
7001         /* If we don't have what we're expecting, exit now. TYPE_NAME
7002            will be null and the error caught later. */
7003         if (TREE_CODE (QUAL_WFL (current)) != EXPR_WITH_FILE_LOCATION)
7004           break;
7005         acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
7006         if ((type_name = resolve_no_layout (acc, NULL_TREE)))
7007           {
7008             type_name = acc;
7009             /* resolve_package should be used in a loop, hence we
7010                point at this one to naturally process the next one at
7011                the next iteration. */
7012             *next = current;
7013             break;
7014           }
7015       }
7016   return type_name;
7017 }
7018
7019 static tree
7020 lookup_package_type (name, from)
7021      const char *name;
7022      int from;
7023 {
7024   char subname [128];
7025   const char *sub = &name[from+1];
7026   while (*sub != '.' && *sub)
7027     sub++;
7028   strncpy (subname, name, sub-name);
7029   subname [sub-name] = '\0';
7030   return get_identifier (subname);
7031 }
7032
7033 /* Check accessibility of inner classes according to member access rules. 
7034    DECL is the inner class, ENCLOSING_DECL is the class from which the
7035    access is being attempted. */
7036
7037 static void
7038 check_inner_class_access (decl, enclosing_decl, cl)
7039      tree decl, enclosing_decl, cl;
7040 {
7041   const char *access;
7042   tree enclosing_decl_type;
7043
7044   /* We don't issue an error message when CL is null. CL can be null
7045      as a result of processing a JDEP crafted by source_start_java_method
7046      for the purpose of patching its parm decl. But the error would
7047      have been already trapped when fixing the method's signature.
7048      DECL can also be NULL in case of earlier errors. */
7049   if (!decl || !cl)
7050     return;
7051
7052   enclosing_decl_type = TREE_TYPE (enclosing_decl);
7053
7054   if (CLASS_PRIVATE (decl))
7055     {
7056       /* Access is permitted only within the body of the top-level
7057          class in which DECL is declared. */
7058       tree top_level = decl;
7059       while (DECL_CONTEXT (top_level))
7060         top_level = DECL_CONTEXT (top_level);      
7061       while (DECL_CONTEXT (enclosing_decl))
7062         enclosing_decl = DECL_CONTEXT (enclosing_decl);
7063       if (top_level == enclosing_decl)
7064         return;      
7065       access = "private";
7066     }
7067   else if (CLASS_PROTECTED (decl))
7068     {
7069       tree decl_context;
7070       /* Access is permitted from within the same package... */
7071       if (in_same_package (decl, enclosing_decl))
7072         return;
7073       
7074       /* ... or from within the body of a subtype of the context in which
7075          DECL is declared. */
7076       decl_context = DECL_CONTEXT (decl);
7077       while (enclosing_decl)
7078         {
7079           if (CLASS_INTERFACE (decl))
7080             {
7081               if (interface_of_p (TREE_TYPE (decl_context), 
7082                                   enclosing_decl_type))
7083                 return;
7084             }
7085           else
7086             {
7087               /* Eww. The order of the arguments is different!! */
7088               if (inherits_from_p (enclosing_decl_type, 
7089                                    TREE_TYPE (decl_context)))
7090                 return;
7091             }
7092           enclosing_decl = DECL_CONTEXT (enclosing_decl);
7093         }      
7094       access = "protected";
7095     }
7096   else if (! CLASS_PUBLIC (decl))
7097     {
7098       /* Access is permitted only from within the same package as DECL. */
7099       if (in_same_package (decl, enclosing_decl))
7100         return;
7101       access = "non-public";
7102     }
7103   else
7104     /* Class is public. */
7105     return;
7106
7107   parse_error_context (cl, "Nested %s %s is %s; cannot be accessed from here",
7108                        (CLASS_INTERFACE (decl) ? "interface" : "class"),
7109                        lang_printable_name (decl, 0), access);
7110 }
7111
7112 /* Accessibility check for top-level classes. If CLASS_NAME is in a foreign 
7113    package, it must be PUBLIC. Return 0 if no access violations were found, 
7114    1 otherwise.  */
7115
7116 static int
7117 check_pkg_class_access (class_name, cl)
7118      tree class_name;
7119      tree cl;
7120 {
7121   tree type;
7122
7123   if (!IDENTIFIER_CLASS_VALUE (class_name))
7124     return 0;
7125
7126   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
7127     return 0;
7128
7129   if (!CLASS_PUBLIC (TYPE_NAME (type)))
7130     {
7131       /* Access to a private class within the same package is
7132          allowed. */
7133       tree l, r;
7134       breakdown_qualified (&l, &r, class_name);
7135       if (!QUALIFIED_P (class_name) && !ctxp->package)
7136         /* Both in the empty package. */
7137         return 0;
7138       if (l == ctxp->package)
7139         /* Both in the same package. */
7140         return 0;
7141
7142       parse_error_context 
7143         (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
7144          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
7145          IDENTIFIER_POINTER (class_name));
7146       return 1;
7147     }
7148   return 0;
7149 }
7150
7151 /* Local variable declaration. */
7152
7153 static void
7154 declare_local_variables (modifier, type, vlist)
7155      int modifier;
7156      tree type;
7157      tree vlist;
7158 {
7159   tree decl, current, saved_type;
7160   tree type_wfl = NULL_TREE;
7161   int must_chain = 0;
7162   int final_p = 0;
7163
7164   /* Push a new block if statements were seen between the last time we
7165      pushed a block and now. Keep a count of blocks to close */
7166   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
7167     {
7168       tree b = enter_block ();
7169       BLOCK_IS_IMPLICIT (b) = 1;
7170     }
7171
7172   if (modifier)
7173     {
7174       int i;
7175       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
7176       if (modifier == ACC_FINAL)
7177         final_p = 1;
7178       else 
7179         {
7180           parse_error_context 
7181             (ctxp->modifier_ctx [i], 
7182              "Only `final' is allowed as a local variables modifier");
7183           return;
7184         }
7185     }
7186
7187   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
7188      hold the TYPE value if a new incomplete has to be created (as
7189      opposed to being found already existing and reused). */
7190   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
7191
7192   /* If TYPE is fully resolved and we don't have a reference, make one */
7193   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
7194
7195   /* Go through all the declared variables */
7196   for (current = vlist, saved_type = type; current;
7197        current = TREE_CHAIN (current), type = saved_type)
7198     {
7199       tree other, real_type;
7200       tree wfl  = TREE_PURPOSE (current);
7201       tree name = EXPR_WFL_NODE (wfl);
7202       tree init = TREE_VALUE (current);
7203
7204       /* Process NAME, as it may specify extra dimension(s) for it */
7205       type = build_array_from_name (type, type_wfl, name, &name);
7206
7207       /* Variable redefinition check */
7208       if ((other = lookup_name_in_blocks (name)))
7209         {
7210           variable_redefinition_error (wfl, name, TREE_TYPE (other),
7211                                        DECL_SOURCE_LINE (other));
7212           continue;
7213         }
7214
7215       /* Type adjustment. We may have just readjusted TYPE because
7216          the variable specified more dimensions. Make sure we have
7217          a reference if we can and don't have one already. */
7218       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
7219
7220       real_type = GET_REAL_TYPE (type);
7221       /* Never layout this decl. This will be done when its scope
7222          will be entered */
7223       decl = build_decl (VAR_DECL, name, real_type);
7224       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
7225       LOCAL_FINAL (decl) = final_p;
7226       BLOCK_CHAIN_DECL (decl);
7227       
7228       /* If doing xreferencing, replace the line number with the WFL
7229          compound value */
7230       if (flag_emit_xref)
7231         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
7232       
7233       /* Don't try to use an INIT statement when an error was found */
7234       if (init && java_error_count)
7235         init = NULL_TREE;
7236       
7237       /* Add the initialization function to the current function's code */
7238       if (init)
7239         {
7240           /* Name might have been readjusted */
7241           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
7242           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
7243           java_method_add_stmt (current_function_decl,
7244                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
7245                                                       init));
7246         }
7247     
7248       /* Setup dependency the type of the decl */
7249       if (must_chain)
7250         {
7251           jdep *dep;
7252           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
7253           dep = CLASSD_LAST (ctxp->classd_list);
7254           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
7255         }
7256     }
7257   SOURCE_FRONTEND_DEBUG (("Defined locals"));
7258 }
7259
7260 /* Called during parsing. Build decls from argument list.  */
7261
7262 static void
7263 source_start_java_method (fndecl)
7264      tree fndecl;
7265 {
7266   tree tem;
7267   tree parm_decl;
7268   int i;
7269
7270   if (!fndecl)
7271     return;
7272
7273   current_function_decl = fndecl;
7274
7275   /* New scope for the function */
7276   enter_block ();
7277   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
7278        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
7279     {
7280       tree type = TREE_VALUE (tem);
7281       tree name = TREE_PURPOSE (tem);
7282       
7283       /* If type is incomplete. Create an incomplete decl and ask for
7284          the decl to be patched later */
7285       if (INCOMPLETE_TYPE_P (type))
7286         {
7287           jdep *jdep;
7288           tree real_type = GET_REAL_TYPE (type);
7289           parm_decl = build_decl (PARM_DECL, name, real_type);
7290           type = obtain_incomplete_type (type);
7291           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
7292           jdep = CLASSD_LAST (ctxp->classd_list);
7293           JDEP_MISC (jdep) = name;
7294           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
7295         }
7296       else
7297         parm_decl = build_decl (PARM_DECL, name, type);
7298
7299       /* Remember if a local variable was declared final (via its
7300          TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
7301       if (ARG_FINAL_P (tem))
7302         {
7303           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (parm_decl);
7304           LOCAL_FINAL (parm_decl) = 1;
7305         }
7306
7307       BLOCK_CHAIN_DECL (parm_decl);
7308     }
7309   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7310   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
7311     nreverse (tem);
7312   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
7313   DECL_MAX_LOCALS (current_function_decl) = i;
7314 }
7315
7316 /* Called during parsing. Creates an artificial method declaration.  */
7317
7318 static tree
7319 create_artificial_method (class, flags, type, name, args)
7320      tree class;
7321      int flags;
7322      tree type, name, args;
7323 {
7324   tree mdecl;
7325
7326   java_parser_context_save_global ();
7327   lineno = 0;                                                               
7328   mdecl = make_node (FUNCTION_TYPE);                                
7329   TREE_TYPE (mdecl) = type;
7330   TYPE_ARG_TYPES (mdecl) = args;
7331   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
7332   java_parser_context_restore_global ();
7333   DECL_ARTIFICIAL (mdecl) = 1;                                      
7334   return mdecl;
7335 }
7336
7337 /* Starts the body if an artifical method.  */
7338
7339 static void
7340 start_artificial_method_body (mdecl)
7341      tree mdecl;
7342 {
7343   DECL_SOURCE_LINE (mdecl) = 1;
7344   DECL_SOURCE_LINE_MERGE (mdecl, 1);
7345   source_start_java_method (mdecl);
7346   enter_block ();
7347 }
7348
7349 static void
7350 end_artificial_method_body (mdecl)
7351      tree mdecl;
7352 {
7353   /* exit_block modifies DECL_FUNCTION_BODY (current_function_decl).
7354      It has to be evaluated first. (if mdecl is current_function_decl,
7355      we have an undefined behavior if no temporary variable is used.) */
7356   tree b = exit_block ();
7357   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = b;
7358   exit_block ();
7359 }
7360
7361 /* Terminate a function and expand its body.  */
7362
7363 static void
7364 source_end_java_method ()
7365 {
7366   tree fndecl = current_function_decl;
7367
7368   if (!fndecl)
7369     return;
7370
7371   java_parser_context_save_global ();
7372   lineno = ctxp->last_ccb_indent1;
7373
7374   /* Turn function bodies with only a NOP expr null, so they don't get
7375      generated at all and we won't get warnings when using the -W
7376      -Wall flags. */
7377   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7378     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7379
7380   /* Generate function's code */
7381   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7382       && ! flag_emit_class_files
7383       && ! flag_emit_xref)
7384     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7385
7386   /* pop out of its parameters */
7387   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7388   poplevel (1, 0, 1);
7389   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7390
7391   /* Generate rtl for function exit.  */
7392   if (! flag_emit_class_files && ! flag_emit_xref)
7393     {
7394       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7395       expand_function_end (input_filename, lineno, 0);
7396
7397       /* Run the optimizers and output assembler code for this function. */
7398       rest_of_compilation (fndecl);
7399     }
7400
7401   current_function_decl = NULL_TREE;
7402   java_parser_context_restore_global ();
7403 }
7404
7405 /* Record EXPR in the current function block. Complements compound
7406    expression second operand if necessary.  */
7407
7408 tree
7409 java_method_add_stmt (fndecl, expr)
7410      tree fndecl, expr;
7411 {
7412   if (!GET_CURRENT_BLOCK (fndecl))
7413     return NULL_TREE;
7414   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7415 }
7416
7417 static tree
7418 add_stmt_to_block (b, type, stmt)
7419      tree b, type, stmt;
7420 {
7421   tree body = BLOCK_EXPR_BODY (b), c;
7422   
7423   if (java_error_count)
7424     return body;
7425     
7426   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7427     return body;
7428
7429   BLOCK_EXPR_BODY (b) = c;
7430   TREE_SIDE_EFFECTS (c) = 1;
7431   return c;
7432 }
7433
7434 /* Add STMT to EXISTING if possible, otherwise create a new
7435    COMPOUND_EXPR and add STMT to it. */
7436
7437 static tree
7438 add_stmt_to_compound (existing, type, stmt)
7439      tree existing, type, stmt;
7440 {
7441   if (existing)
7442     return build (COMPOUND_EXPR, type, existing, stmt);
7443   else
7444     return stmt;
7445 }
7446
7447 void java_layout_seen_class_methods ()
7448 {
7449   tree previous_list = all_class_list;
7450   tree end = NULL_TREE;
7451   tree current;
7452
7453   while (1)
7454     {
7455       for (current = previous_list; 
7456            current != end; current = TREE_CHAIN (current))
7457         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7458       
7459       if (previous_list != all_class_list)
7460         {
7461           end = previous_list;
7462           previous_list = all_class_list;
7463         }
7464       else
7465         break;
7466     }
7467 }
7468
7469 void
7470 java_reorder_fields ()
7471 {
7472   static tree stop_reordering = NULL_TREE;
7473   static int initialized_p;
7474   tree current;
7475
7476   /* Register STOP_REORDERING with the garbage collector.  */
7477   if (!initialized_p)
7478     {
7479       ggc_add_tree_root (&stop_reordering, 1);
7480       initialized_p = 1;
7481     }
7482
7483   for (current = gclass_list; current; current = TREE_CHAIN (current))
7484     {
7485       current_class = TREE_TYPE (TREE_VALUE (current));
7486
7487       if (current_class == stop_reordering)
7488         break;
7489
7490       /* Reverse the fields, but leave the dummy field in front.
7491          Fields are already ordered for Object and Class */
7492       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7493           && current_class != class_type_node)
7494       {
7495         /* If the dummy field is there, reverse the right fields and
7496            just layout the type for proper fields offset */
7497         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7498           {
7499             tree fields = TYPE_FIELDS (current_class);
7500             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7501             TYPE_SIZE (current_class) = NULL_TREE;
7502           }
7503         /* We don't have a dummy field, we need to layout the class,
7504            after having reversed the fields */
7505         else
7506           {
7507             TYPE_FIELDS (current_class) = 
7508               nreverse (TYPE_FIELDS (current_class));
7509             TYPE_SIZE (current_class) = NULL_TREE;
7510           }
7511       }
7512     }
7513   /* There are cases were gclass_list will be empty. */
7514   if (gclass_list)
7515     stop_reordering = TREE_TYPE (TREE_VALUE (gclass_list));
7516 }
7517
7518 /* Layout the methods of all classes loaded in one way or another.
7519    Check methods of source parsed classes. Then reorder the
7520    fields and layout the classes or the type of all source parsed
7521    classes */
7522
7523 void
7524 java_layout_classes ()
7525 {
7526   tree current;
7527   int save_error_count = java_error_count;
7528
7529   /* Layout the methods of all classes seen so far */
7530   java_layout_seen_class_methods ();
7531   java_parse_abort_on_error ();
7532   all_class_list = NULL_TREE;
7533
7534   /* Then check the methods of all parsed classes */
7535   for (current = gclass_list; current; current = TREE_CHAIN (current))
7536     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7537       java_check_methods (TREE_VALUE (current));
7538   java_parse_abort_on_error ();
7539
7540   for (current = gclass_list; current; current = TREE_CHAIN (current))
7541     {
7542       current_class = TREE_TYPE (TREE_VALUE (current));
7543       layout_class (current_class);
7544
7545       /* Error reported by the caller */
7546       if (java_error_count)
7547         return;
7548     }
7549
7550   /* We might have reloaded classes durign the process of laying out
7551      classes for code generation. We must layout the methods of those
7552      late additions, as constructor checks might use them */
7553   java_layout_seen_class_methods ();
7554   java_parse_abort_on_error ();
7555 }
7556
7557 /* Expand methods in the current set of classes rememebered for
7558    generation.  */
7559
7560 static void
7561 java_complete_expand_classes ()
7562 {
7563   tree current;
7564
7565   do_not_fold = flag_emit_xref;
7566
7567   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7568     if (!INNER_CLASS_DECL_P (current))
7569       java_complete_expand_class (current);
7570 }
7571
7572 /* Expand the methods found in OUTER, starting first by OUTER's inner
7573    classes, if any.  */
7574
7575 static void
7576 java_complete_expand_class (outer)
7577      tree outer;
7578 {
7579   tree inner_list;
7580
7581   set_nested_class_simple_name_value (outer, 1); /* Set */
7582
7583   /* We need to go after all inner classes and start expanding them,
7584      starting with most nested ones. We have to do that because nested
7585      classes might add functions to outer classes */
7586
7587   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7588        inner_list; inner_list = TREE_CHAIN (inner_list))
7589     java_complete_expand_class (TREE_PURPOSE (inner_list));
7590
7591   java_complete_expand_methods (outer);
7592   set_nested_class_simple_name_value (outer, 0); /* Reset */
7593 }
7594
7595 /* Expand methods registered in CLASS_DECL. The general idea is that
7596    we expand regular methods first. This allows us get an estimate on
7597    how outer context local alias fields are really used so we can add
7598    to the constructor just enough code to initialize them properly (it
7599    also lets us generate finit$ correctly.) Then we expand the
7600    constructors and then <clinit>.  */
7601
7602 static void
7603 java_complete_expand_methods (class_decl)
7604      tree class_decl;
7605 {
7606   tree clinit, decl, first_decl;
7607
7608   current_class = TREE_TYPE (class_decl);
7609
7610   /* Find whether the class has final variables */
7611   for (decl = TYPE_FIELDS (current_class); decl; decl = TREE_CHAIN (decl))
7612     if (FIELD_FINAL (decl))
7613       {
7614         TYPE_HAS_FINAL_VARIABLE (current_class) = 1;
7615         break;
7616       }
7617
7618   /* Initialize a new constant pool */
7619   init_outgoing_cpool ();
7620
7621   /* Pre-expand <clinit> to figure whether we really need it or
7622      not. If we do need it, we pre-expand the static fields so they're
7623      ready to be used somewhere else. <clinit> will be fully expanded
7624      after we processed the constructors. */
7625   first_decl = TYPE_METHODS (current_class);
7626   clinit = maybe_generate_pre_expand_clinit (current_class);
7627
7628   /* Then generate finit$ (if we need to) because constructors will
7629    try to use it.*/
7630   if (TYPE_FINIT_STMT_LIST (current_class))
7631     java_complete_expand_method (generate_finit (current_class));
7632
7633   /* Then generate instinit$ (if we need to) because constructors will
7634      try to use it. */
7635   if (TYPE_II_STMT_LIST (current_class))
7636     java_complete_expand_method (generate_instinit (current_class));
7637
7638   /* Now do the constructors */
7639   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7640     {
7641       int no_body;
7642
7643       if (!DECL_CONSTRUCTOR_P (decl))
7644         continue;
7645       
7646       no_body = !DECL_FUNCTION_BODY (decl);
7647       /* Don't generate debug info on line zero when expanding a
7648          generated constructor. */
7649       if (no_body)
7650         restore_line_number_status (1);
7651
7652       /* Reset the final local variable assignment flags */
7653       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7654         reset_final_variable_local_assignment_flag (current_class);
7655
7656       java_complete_expand_method (decl);
7657
7658       /* Check for missed out final variable assignment */
7659       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7660         check_final_variable_local_assignment_flag (current_class, decl);
7661       
7662       if (no_body)
7663         restore_line_number_status (0);
7664     }
7665
7666   /* First, do the ordinary methods. */
7667   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7668     {
7669       /* Ctors aren't part of this batch. */
7670       if (DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7671         continue;
7672       
7673       /* Skip abstract or native methods -- but do handle native
7674          methods when generating JNI stubs.  */
7675       if (METHOD_ABSTRACT (decl) || (! flag_jni && METHOD_NATIVE (decl)))
7676         {
7677           DECL_FUNCTION_BODY (decl) = NULL_TREE;
7678           continue;
7679         }
7680
7681       if (METHOD_NATIVE (decl))
7682         {
7683           tree body = build_jni_stub (decl);
7684           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7685         }
7686
7687       java_complete_expand_method (decl);
7688     }
7689
7690   /* If there is indeed a <clinit>, fully expand it now */
7691   if (clinit)
7692     {
7693       /* Reset the final local variable assignment flags */
7694       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7695         reset_static_final_variable_assignment_flag (current_class);
7696       /* Prevent the use of `this' inside <clinit> */
7697       ctxp->explicit_constructor_p = 1;
7698       java_complete_expand_method (clinit);
7699       ctxp->explicit_constructor_p = 0;
7700       /* Check for missed out static final variable assignment */
7701       if (TYPE_HAS_FINAL_VARIABLE (current_class)
7702           && !CLASS_INTERFACE (class_decl))
7703         check_static_final_variable_assignment_flag (current_class);
7704     }
7705   
7706   /* We might have generated a class$ that we now want to expand */
7707   if (TYPE_DOT_CLASS (current_class))
7708     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7709
7710   /* Now verify constructor circularity (stop after the first one we
7711      prove wrong.) */
7712   if (!CLASS_INTERFACE (class_decl))
7713     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7714       if (DECL_CONSTRUCTOR_P (decl) 
7715           && verify_constructor_circularity (decl, decl))
7716         break;
7717
7718   /* Final check on the initialization of final variables. */
7719   if (TYPE_HAS_FINAL_VARIABLE (current_class))
7720     {
7721       check_final_variable_global_assignment_flag (current_class);
7722       /* If we have an interface, check for uninitialized fields. */
7723       if (CLASS_INTERFACE (class_decl))
7724         check_static_final_variable_assignment_flag (current_class);
7725     }
7726
7727   /* Save the constant pool. We'll need to restore it later. */
7728   TYPE_CPOOL (current_class) = outgoing_cpool;
7729 }
7730
7731 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7732    safely used in some other methods/constructors.  */
7733
7734 static tree
7735 maybe_generate_pre_expand_clinit (class_type)
7736      tree class_type;
7737 {
7738   tree current, mdecl;
7739
7740   if (!TYPE_CLINIT_STMT_LIST (class_type))
7741     return NULL_TREE;
7742
7743   /* Go through all static fields and pre expand them */
7744   for (current = TYPE_FIELDS (class_type); current; 
7745        current = TREE_CHAIN (current))
7746     if (FIELD_STATIC (current))
7747       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7748
7749   /* Then build the <clinit> method */
7750   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7751                                     clinit_identifier_node, end_params_node);
7752   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7753                        mdecl, NULL_TREE);
7754   start_artificial_method_body (mdecl);
7755
7756   /* We process the list of assignment we produced as the result of
7757      the declaration of initialized static field and add them as
7758      statement to the <clinit> method. */
7759   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7760        current = TREE_CHAIN (current))
7761     {
7762       tree stmt = current;
7763       /* We build the assignment expression that will initialize the
7764          field to its value. There are strict rules on static
7765          initializers (8.5). FIXME */
7766       if (TREE_CODE (stmt) != BLOCK && stmt != empty_stmt_node)
7767         stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
7768       java_method_add_stmt (mdecl, stmt);
7769     }
7770
7771   end_artificial_method_body (mdecl);
7772
7773   /* Now we want to place <clinit> as the last method (because we need
7774      it at least for interface so that it doesn't interfere with the
7775      dispatch table based lookup. */
7776   if (TREE_CHAIN (TYPE_METHODS (class_type)))
7777     {
7778       current = TREE_CHAIN (TYPE_METHODS (class_type));
7779       TYPE_METHODS (class_type) = current;
7780
7781       while (TREE_CHAIN (current))
7782         current = TREE_CHAIN (current);
7783
7784       TREE_CHAIN (current) = mdecl;
7785       TREE_CHAIN (mdecl) = NULL_TREE;
7786     }
7787
7788   return mdecl;
7789 }
7790
7791 /* Analyzes a method body and look for something that isn't a
7792    MODIFY_EXPR with a constant value.  */
7793
7794 static int
7795 analyze_clinit_body (bbody)
7796      tree bbody;
7797 {
7798   while (bbody)
7799     switch (TREE_CODE (bbody))
7800       {
7801       case BLOCK:
7802         bbody = BLOCK_EXPR_BODY (bbody);
7803         break;
7804         
7805       case EXPR_WITH_FILE_LOCATION:
7806         bbody = EXPR_WFL_NODE (bbody);
7807         break;
7808         
7809       case COMPOUND_EXPR:
7810         if (analyze_clinit_body (TREE_OPERAND (bbody, 0)))
7811           return 1;
7812         bbody = TREE_OPERAND (bbody, 1);
7813         break;
7814         
7815       case MODIFY_EXPR:
7816         /* Return 0 if the operand is constant, 1 otherwise.  */
7817         return ! TREE_CONSTANT (TREE_OPERAND (bbody, 1));
7818
7819       default:
7820         return 1;
7821       }
7822   return 0;
7823 }
7824
7825
7826 /* See whether we could get rid of <clinit>. Criteria are: all static
7827    final fields have constant initial values and the body of <clinit>
7828    is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
7829
7830 static int
7831 maybe_yank_clinit (mdecl)
7832      tree mdecl;
7833 {
7834   tree type, current;
7835   tree fbody, bbody;
7836   int found = 0;
7837   
7838   if (!DECL_CLINIT_P (mdecl))
7839     return 0;
7840
7841   /* If the body isn't empty, then we keep <clinit>. Note that if
7842      we're emitting classfiles, this isn't enough not to rule it
7843      out. */
7844   fbody = DECL_FUNCTION_BODY (mdecl);
7845   bbody = BLOCK_EXPR_BODY (fbody);
7846   if (bbody && bbody != error_mark_node)
7847     bbody = BLOCK_EXPR_BODY (bbody);
7848   else
7849     return 0;
7850   if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
7851     return 0;
7852   
7853   type = DECL_CONTEXT (mdecl);
7854   current = TYPE_FIELDS (type);
7855
7856   for (current = (current ? TREE_CHAIN (current) : current); 
7857        current; current = TREE_CHAIN (current))
7858     {
7859       tree f_init;
7860
7861       /* We're not interested in non static field */
7862       if (!FIELD_STATIC (current))
7863         continue;
7864
7865       /* Anything that isn't String or a basic type is ruled out -- or
7866          if we know how to deal with it (when doing things natively) we
7867          should generated an empty <clinit> so that SUID are computed
7868          correctly. */
7869       if (! JSTRING_TYPE_P (TREE_TYPE (current))
7870           && ! JNUMERIC_TYPE_P (TREE_TYPE (current)))
7871         break;
7872           
7873       f_init = DECL_INITIAL (current);
7874       /* If we're emitting native code, we want static final fields to
7875          have constant initializers. If we don't meet these
7876          conditions, we keep <clinit> */
7877       if (!flag_emit_class_files
7878           && !(FIELD_FINAL (current) && f_init && TREE_CONSTANT (f_init)))
7879         break;
7880       /* If we're emitting bytecode, we want static fields to have
7881          constant initializers or no initializer. If we don't meet
7882          these conditions, we keep <clinit> */
7883       if (flag_emit_class_files && f_init && !TREE_CONSTANT (f_init))
7884         break;
7885     }
7886
7887   /* Now we analyze the method body and look for something that
7888      isn't a MODIFY_EXPR */
7889   if (bbody == empty_stmt_node)
7890     found = 0;
7891   else
7892     found = analyze_clinit_body (bbody);
7893
7894   if (current || found)
7895     return 0;
7896
7897   /* Get rid of <clinit> in the class' list of methods */
7898   if (TYPE_METHODS (type) == mdecl)
7899     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
7900   else
7901     for (current = TYPE_METHODS (type); current; 
7902          current = TREE_CHAIN (current))
7903       if (TREE_CHAIN (current) == mdecl)
7904         {
7905           TREE_CHAIN (current) = TREE_CHAIN (mdecl);
7906           break;
7907         }
7908
7909   return 1;
7910 }
7911
7912 /* Install the argument from MDECL. Suitable to completion and
7913    expansion of mdecl's body.  */
7914
7915 static void
7916 start_complete_expand_method (mdecl)
7917      tree mdecl;
7918 {
7919   tree tem, *ptr;
7920
7921   pushlevel (1);                /* Prepare for a parameter push */
7922   ptr = &DECL_ARGUMENTS (mdecl);
7923   tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7924
7925   while (tem)
7926     {
7927       tree next = TREE_CHAIN (tem);
7928       tree type = TREE_TYPE (tem);
7929       if (PROMOTE_PROTOTYPES
7930           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
7931           && INTEGRAL_TYPE_P (type))
7932         type = integer_type_node;
7933       DECL_ARG_TYPE (tem) = type;
7934       layout_decl (tem, 0);
7935       pushdecl (tem);
7936       *ptr = tem;
7937       ptr = &TREE_CHAIN (tem);
7938       tem = next;
7939     }
7940   *ptr = NULL_TREE;
7941   pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7942   lineno = DECL_SOURCE_LINE_FIRST (mdecl);
7943   build_result_decl (mdecl);
7944 }
7945
7946
7947 /* Complete and expand a method.  */
7948
7949 static void
7950 java_complete_expand_method (mdecl)
7951      tree mdecl;
7952 {
7953   tree fbody, block_body, exception_copy;
7954
7955   current_function_decl = mdecl;
7956   /* Fix constructors before expanding them */
7957   if (DECL_CONSTRUCTOR_P (mdecl))
7958     fix_constructors (mdecl);
7959   
7960   /* Expand functions that have a body */
7961   if (!DECL_FUNCTION_BODY (mdecl))
7962     return;
7963
7964   fbody = DECL_FUNCTION_BODY (mdecl);
7965   block_body = BLOCK_EXPR_BODY (fbody);
7966   exception_copy = NULL_TREE;
7967
7968   current_function_decl = mdecl;
7969
7970   if (! quiet_flag)
7971     fprintf (stderr, " [%s.",
7972              lang_printable_name (DECL_CONTEXT (mdecl), 0));
7973   announce_function (mdecl);
7974   if (! quiet_flag)
7975     fprintf (stderr, "]");
7976   
7977   /* Prepare the function for tree completion */
7978   start_complete_expand_method (mdecl);
7979
7980   /* Install the current this */
7981   current_this = (!METHOD_STATIC (mdecl) ? 
7982                   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7983
7984   /* Purge the `throws' list of unchecked exceptions (we save a copy
7985      of the list and re-install it later.) */
7986   exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7987   purge_unchecked_exceptions (mdecl);
7988   
7989   /* Install exceptions thrown with `throws' */
7990   PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7991   
7992   if (block_body != NULL_TREE)
7993     {
7994       block_body = java_complete_tree (block_body);
7995       
7996       /* Before we check initialization, attached all class initialization
7997          variable to the block_body */
7998       hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
7999                      attach_init_test_initialization_flags, block_body);
8000       
8001       if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
8002         {
8003           unsigned int state = check_for_initialization (block_body);
8004           
8005           /* Go through all the flags marking the initialization of
8006              static variables and see whether they're definitively
8007              assigned, in which case the type is remembered as
8008              definitively initialized in MDECL. */
8009           if (STATIC_CLASS_INIT_OPT_P ())
8010             {
8011               hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
8012                              attach_initialized_static_class, (PTR)&state);
8013
8014               /* Always register the context as properly initialized in
8015                  MDECL. This used with caution helps removing extra
8016                  initialization of self. */
8017               if (METHOD_STATIC (mdecl))
8018                 hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (mdecl),
8019                              (hash_table_key) DECL_CONTEXT (mdecl),
8020                              TRUE, NULL);
8021             }
8022         }
8023       ctxp->explicit_constructor_p = 0;
8024     }
8025   
8026   BLOCK_EXPR_BODY (fbody) = block_body;
8027   
8028   /* If we saw a return but couldn't evaluate it properly, we'll have
8029      an error_mark_node here. */
8030   if (block_body != error_mark_node
8031       && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
8032       && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
8033       && !flag_emit_xref)
8034     missing_return_error (current_function_decl);
8035
8036   /* See if we can get rid of <clinit> if MDECL happens to be <clinit> */
8037   maybe_yank_clinit (mdecl);
8038
8039   /* Pop the current level, with special measures if we found errors. */
8040   if (java_error_count)
8041     pushdecl_force_head (DECL_ARGUMENTS (mdecl));
8042   poplevel (1, 0, 1);
8043
8044   /* Pop the exceptions and sanity check */
8045   POP_EXCEPTIONS();
8046   if (currently_caught_type_list)
8047     abort ();
8048
8049   /* Restore the copy of the list of exceptions if emitting xrefs. */
8050   DECL_FUNCTION_THROWS (mdecl) = exception_copy;
8051 }
8052
8053 /* For with each class for which there's code to generate. */
8054
8055 static void
8056 java_expand_method_bodies (class)
8057      tree class;
8058 {
8059   tree decl;
8060   for (decl = TYPE_METHODS (class); decl; decl = TREE_CHAIN (decl))
8061     {
8062       if (!DECL_FUNCTION_BODY (decl))
8063         continue;
8064
8065       current_function_decl = decl;
8066
8067       /* It's time to assign the variable flagging static class
8068          initialization based on which classes invoked static methods
8069          are definitely initializing. This should be flagged. */
8070       if (STATIC_CLASS_INIT_OPT_P ())
8071         hash_traverse (&DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (decl),
8072                        adjust_init_test_initialization, NULL);
8073
8074       /* Prepare the function for RTL expansion */  
8075       start_complete_expand_method (decl);
8076
8077       /* Expand function start, generate initialization flag
8078          assignment, and handle synchronized methods. */
8079       complete_start_java_method (decl);
8080
8081       /* Expand the rest of the function body and terminate
8082          expansion. */
8083       source_end_java_method ();
8084     }
8085 }
8086
8087 \f
8088
8089 /* This section of the code deals with accessing enclosing context
8090    fields either directly by using the relevant access to this$<n> or
8091    by invoking an access method crafted for that purpose.  */
8092
8093 /* Build the necessary access from an inner class to an outer
8094    class. This routine could be optimized to cache previous result
8095    (decl, current_class and returned access).  When an access method
8096    needs to be generated, it always takes the form of a read. It might
8097    be later turned into a write by calling outer_field_access_fix.  */
8098
8099 static tree
8100 build_outer_field_access (id, decl)
8101      tree id, decl;
8102 {
8103   tree access = NULL_TREE;
8104   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
8105   tree decl_ctx = DECL_CONTEXT (decl);
8106
8107   /* If the immediate enclosing context of the current class is the
8108      field decl's class or inherits from it; build the access as
8109      `this$<n>.<field>'. Note that we will break the `private' barrier
8110      if we're not emitting bytecodes. */
8111   if ((ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
8112       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
8113     {
8114       tree thisn = build_current_thisn (current_class);
8115       access = make_qualified_primary (build_wfl_node (thisn), 
8116                                        id, EXPR_WFL_LINECOL (id));
8117     }
8118   /* Otherwise, generate access methods to outer this and access the
8119      field (either using an access method or by direct access.) */
8120   else
8121     {
8122       int lc = EXPR_WFL_LINECOL (id);
8123
8124       /* Now we chain the required number of calls to the access$0 to
8125          get a hold to the enclosing instance we need, and then we
8126          build the field access. */
8127       access = build_access_to_thisn (current_class, decl_ctx, lc);
8128
8129       /* If the field is private and we're generating bytecode, then
8130          we generate an access method */
8131       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
8132         {
8133           tree name = build_outer_field_access_methods (decl);
8134           access = build_outer_field_access_expr (lc, decl_ctx,
8135                                                   name, access, NULL_TREE);
8136         }
8137       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
8138          Once again we break the `private' access rule from a foreign
8139          class. */
8140       else
8141         access = make_qualified_primary (access, id, lc);
8142     }
8143   return resolve_expression_name (access, NULL);
8144 }
8145
8146 /* Return a non zero value if NODE describes an outer field inner
8147    access.  */
8148
8149 static int
8150 outer_field_access_p (type, decl)
8151     tree type, decl;
8152 {
8153   if (!INNER_CLASS_TYPE_P (type) 
8154       || TREE_CODE (decl) != FIELD_DECL
8155       || DECL_CONTEXT (decl) == type)
8156     return 0;
8157   
8158   /* If the inner class extends the declaration context of the field
8159      we're try to acces, then this isn't an outer field access */
8160   if (inherits_from_p (type, DECL_CONTEXT (decl)))
8161     return 0;
8162
8163   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
8164        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
8165     {
8166       if (type == DECL_CONTEXT (decl))
8167         return 1;
8168
8169       if (!DECL_CONTEXT (TYPE_NAME (type)))
8170         {
8171           /* Before we give up, see whether the field is inherited from
8172              the enclosing context we're considering. */
8173           if (inherits_from_p (type, DECL_CONTEXT (decl)))
8174             return 1;
8175           break;
8176         }
8177     }
8178
8179   return 0;
8180 }
8181
8182 /* Return a non zero value if NODE represents an outer field inner
8183    access that was been already expanded. As a side effect, it returns
8184    the name of the field being accessed and the argument passed to the
8185    access function, suitable for a regeneration of the access method
8186    call if necessary. */
8187
8188 static int
8189 outer_field_expanded_access_p (node, name, arg_type, arg)
8190     tree node, *name, *arg_type, *arg;
8191 {
8192   int identified = 0;
8193
8194   if (TREE_CODE (node) != CALL_EXPR)
8195     return 0;
8196
8197   /* Well, gcj generates slightly different tree nodes when compiling
8198      to native or bytecodes. It's the case for function calls. */
8199
8200   if (flag_emit_class_files 
8201       && TREE_CODE (node) == CALL_EXPR
8202       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
8203     identified = 1;
8204   else if (!flag_emit_class_files)
8205     {
8206       node = TREE_OPERAND (node, 0);
8207       
8208       if (node && TREE_OPERAND (node, 0)
8209           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
8210         {
8211           node = TREE_OPERAND (node, 0);
8212           if (TREE_OPERAND (node, 0)
8213               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
8214               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
8215                   (DECL_NAME (TREE_OPERAND (node, 0)))))
8216             identified = 1;
8217         }
8218     }
8219
8220   if (identified && name && arg_type && arg)
8221     {
8222       tree argument = TREE_OPERAND (node, 1);
8223       *name = DECL_NAME (TREE_OPERAND (node, 0));
8224       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
8225       *arg = TREE_VALUE (argument);
8226     }
8227   return identified;
8228 }
8229
8230 /* Detect in NODE an outer field read access from an inner class and
8231    transform it into a write with RHS as an argument. This function is
8232    called from the java_complete_lhs when an assignment to a LHS can
8233    be identified. */
8234
8235 static tree
8236 outer_field_access_fix (wfl, node, rhs)
8237     tree wfl, node, rhs;
8238 {
8239   tree name, arg_type, arg;
8240   
8241   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
8242     {
8243       /* At any rate, check whether we're trying to assign a value to
8244          a final. */
8245       tree accessed = (JDECL_P (node) ? node : 
8246                        (TREE_CODE (node) == COMPONENT_REF ? 
8247                         TREE_OPERAND (node, 1) : node));
8248       if (check_final_assignment (accessed, wfl))
8249         return error_mark_node;
8250   
8251       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
8252                                             arg_type, name, arg, rhs);
8253       return java_complete_tree (node);
8254     }
8255   return NULL_TREE;
8256 }
8257
8258 /* Construct the expression that calls an access method:
8259      <type>.access$<n>(<arg1> [, <arg2>]); 
8260
8261    ARG2 can be NULL and will be omitted in that case. It will denote a
8262    read access.  */
8263
8264 static tree
8265 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
8266     int lc;
8267     tree type, access_method_name, arg1, arg2;
8268 {
8269   tree args, cn, access;
8270
8271   args = arg1 ? arg1 : 
8272     build_wfl_node (build_current_thisn (current_class));
8273   args = build_tree_list (NULL_TREE, args);
8274
8275   if (arg2)
8276     args = tree_cons (NULL_TREE, arg2, args);
8277
8278   access = build_method_invocation (build_wfl_node (access_method_name), args);
8279   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
8280   return make_qualified_primary (cn, access, lc);
8281 }
8282
8283 static tree
8284 build_new_access_id ()
8285 {
8286   static int access_n_counter = 1;
8287   char buffer [128];
8288
8289   sprintf (buffer, "access$%d", access_n_counter++);
8290   return get_identifier (buffer);
8291 }
8292
8293 /* Create the static access functions for the outer field DECL. We define a
8294    read:
8295      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
8296        return inst$.field;
8297      }
8298    and a write access:
8299      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
8300                                      TREE_TYPE (<field>) value$) {
8301        return inst$.field = value$;
8302      }
8303    We should have a usage flags on the DECL so we can lazily turn the ones
8304    we're using for code generation. FIXME.
8305 */
8306
8307 static tree
8308 build_outer_field_access_methods (decl)
8309     tree decl;
8310 {
8311   tree id, args, stmt, mdecl;
8312   
8313   if (FIELD_INNER_ACCESS_P (decl))
8314     return FIELD_INNER_ACCESS (decl);
8315
8316   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
8317  
8318   /* Create the identifier and a function named after it. */
8319   id = build_new_access_id ();
8320
8321   /* The identifier is marked as bearing the name of a generated write
8322      access function for outer field accessed from inner classes. */
8323   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8324
8325   /* Create the read access */
8326   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
8327   TREE_CHAIN (args) = end_params_node;
8328   stmt = make_qualified_primary (build_wfl_node (inst_id),
8329                                  build_wfl_node (DECL_NAME (decl)), 0);
8330   stmt = build_return (0, stmt);
8331   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8332                                            TREE_TYPE (decl), id, args, stmt);
8333   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8334
8335   /* Create the write access method. No write access for final variable */
8336   if (!FIELD_FINAL (decl))
8337     {
8338       args = build_tree_list (inst_id, 
8339                               build_pointer_type (DECL_CONTEXT (decl)));
8340       TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
8341       TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
8342       stmt = make_qualified_primary (build_wfl_node (inst_id),
8343                                      build_wfl_node (DECL_NAME (decl)), 0);
8344       stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
8345                                                 build_wfl_node (wpv_id)));
8346       mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8347                                                TREE_TYPE (decl), id, 
8348                                                args, stmt);
8349     }
8350   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8351
8352   /* Return the access name */
8353   return FIELD_INNER_ACCESS (decl) = id;
8354 }
8355
8356 /* Build an field access method NAME.  */
8357
8358 static tree 
8359 build_outer_field_access_method (class, type, name, args, body)
8360     tree class, type, name, args, body;
8361 {
8362   tree saved_current_function_decl, mdecl;
8363
8364   /* Create the method */
8365   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
8366   fix_method_argument_names (args, mdecl);
8367   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8368
8369   /* Attach the method body. */
8370   saved_current_function_decl = current_function_decl;
8371   start_artificial_method_body (mdecl);
8372   java_method_add_stmt (mdecl, body);
8373   end_artificial_method_body (mdecl);
8374   current_function_decl = saved_current_function_decl;
8375
8376   return mdecl;
8377 }
8378
8379 \f
8380 /* This section deals with building access function necessary for
8381    certain kinds of method invocation from inner classes.  */
8382
8383 static tree
8384 build_outer_method_access_method (decl)
8385     tree decl;
8386 {
8387   tree saved_current_function_decl, mdecl;
8388   tree args = NULL_TREE, call_args = NULL_TREE;
8389   tree carg, id, body, class;
8390   char buffer [80];
8391   int parm_id_count = 0;
8392
8393   /* Test this abort with an access to a private field */
8394   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
8395     abort ();
8396
8397   /* Check the cache first */
8398   if (DECL_FUNCTION_INNER_ACCESS (decl))
8399     return DECL_FUNCTION_INNER_ACCESS (decl);
8400
8401   class = DECL_CONTEXT (decl);
8402
8403   /* Obtain an access identifier and mark it */
8404   id = build_new_access_id ();
8405   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8406
8407   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
8408   /* Create the arguments, as much as the original */
8409   for (; carg && carg != end_params_node; 
8410        carg = TREE_CHAIN (carg))
8411     {
8412       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
8413       args = chainon (args, build_tree_list (get_identifier (buffer), 
8414                                              TREE_VALUE (carg)));
8415     }
8416   args = chainon (args, end_params_node);
8417
8418   /* Create the method */
8419   mdecl = create_artificial_method (class, ACC_STATIC, 
8420                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
8421   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8422   /* There is a potential bug here. We should be able to use
8423      fix_method_argument_names, but then arg names get mixed up and
8424      eventually a constructor will have its this$0 altered and the
8425      outer context won't be assignment properly. The test case is
8426      stub.java FIXME */
8427   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
8428
8429   /* Attach the method body. */
8430   saved_current_function_decl = current_function_decl;
8431   start_artificial_method_body (mdecl);
8432
8433   /* The actual method invocation uses the same args. When invoking a
8434      static methods that way, we don't want to skip the first
8435      argument. */
8436   carg = args;
8437   if (!METHOD_STATIC (decl))
8438     carg = TREE_CHAIN (carg);
8439   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
8440     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
8441                            call_args);
8442
8443   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
8444                                   call_args);
8445   if (!METHOD_STATIC (decl))
8446     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
8447                                    body, 0);
8448   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
8449     body = build_return (0, body);
8450   java_method_add_stmt (mdecl,body);
8451   end_artificial_method_body (mdecl);
8452   current_function_decl = saved_current_function_decl;
8453
8454   /* Back tag the access function so it know what it accesses */
8455   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
8456
8457   /* Tag the current method so it knows it has an access generated */
8458   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
8459 }
8460
8461 \f
8462 /* This section of the code deals with building expressions to access
8463    the enclosing instance of an inner class. The enclosing instance is
8464    kept in a generated field called this$<n>, with <n> being the
8465    inner class nesting level (starting from 0.)  */
8466     
8467 /* Build an access to a given this$<n>, always chaining access call to
8468    others. Access methods to this$<n> are build on the fly if
8469    necessary. This CAN'T be used to solely access this$<n-1> from
8470    this$<n> (which alway yield to special cases and optimization, see
8471    for example build_outer_field_access).  */
8472
8473 static tree
8474 build_access_to_thisn (from, to, lc)
8475      tree from, to;
8476      int lc;
8477 {
8478   tree access = NULL_TREE;
8479
8480   while (from != to)
8481     {
8482       if (!access)
8483         {
8484           access = build_current_thisn (from);
8485           access = build_wfl_node (access);
8486         }
8487       else
8488         {
8489           tree access0_wfl, cn;
8490
8491           maybe_build_thisn_access_method (from);
8492           access0_wfl = build_wfl_node (access0_identifier_node);
8493           cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
8494           EXPR_WFL_LINECOL (access0_wfl) = lc;
8495           access = build_tree_list (NULL_TREE, access);
8496           access = build_method_invocation (access0_wfl, access);
8497           access = make_qualified_primary (cn, access, lc);
8498         }
8499
8500       /* if FROM isn't an inter class, that's fine, we've done
8501          enough. What we're looking for can be accessed from there. */
8502       from = DECL_CONTEXT (TYPE_NAME (from));
8503       if (!from)
8504         break;
8505       from = TREE_TYPE (from);
8506     }
8507   return access;
8508 }
8509
8510 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
8511    is returned if nothing needs to be generated. Otherwise, the method
8512    generated and a method decl is returned.  
8513
8514    NOTE: These generated methods should be declared in a class file
8515    attribute so that they can't be referred to directly.  */
8516
8517 static tree
8518 maybe_build_thisn_access_method (type)
8519     tree type;
8520 {
8521   tree mdecl, args, stmt, rtype;
8522   tree saved_current_function_decl;
8523
8524   /* If TYPE is a top-level class, no access method is required.
8525      If there already is such an access method, bail out. */
8526   if (CLASS_ACCESS0_GENERATED_P (type) || !PURE_INNER_CLASS_TYPE_P (type))
8527     return NULL_TREE;
8528
8529   /* We generate the method. The method looks like:
8530      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
8531   */
8532   args = build_tree_list (inst_id, build_pointer_type (type));
8533   TREE_CHAIN (args) = end_params_node;
8534   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
8535   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
8536                                     access0_identifier_node, args);
8537   fix_method_argument_names (args, mdecl);
8538   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
8539   stmt = build_current_thisn (type);
8540   stmt = make_qualified_primary (build_wfl_node (inst_id), 
8541                                  build_wfl_node (stmt), 0);
8542   stmt = build_return (0, stmt);
8543
8544   saved_current_function_decl = current_function_decl;
8545   start_artificial_method_body (mdecl);
8546   java_method_add_stmt (mdecl, stmt);
8547   end_artificial_method_body (mdecl);
8548   current_function_decl = saved_current_function_decl;
8549
8550   CLASS_ACCESS0_GENERATED_P (type) = 1;
8551
8552   return mdecl;
8553 }
8554
8555 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
8556    the first level of innerclassing. this$1 for the next one, etc...
8557    This function can be invoked with TYPE to NULL, available and then
8558    has to count the parser context.  */
8559
8560 static tree
8561 build_current_thisn (type)
8562     tree type;
8563 {
8564   static int saved_i = -1;
8565   static tree saved_thisn = NULL_TREE;
8566   static tree saved_type = NULL_TREE;
8567   static int saved_type_i = 0;
8568   static int initialized_p;
8569   tree decl;
8570   char buffer [80];
8571   int i = 0;
8572
8573   /* Register SAVED_THISN and SAVED_TYPE with the garbage collector.  */
8574   if (!initialized_p)
8575     {
8576       ggc_add_tree_root (&saved_thisn, 1);
8577       ggc_add_tree_root (&saved_type, 1);
8578       initialized_p = 1;
8579     }
8580
8581   if (type)
8582     {
8583       if (type == saved_type)
8584         i = saved_type_i;
8585       else
8586         {
8587           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
8588                decl; decl = DECL_CONTEXT (decl), i++)
8589             ;
8590       
8591           saved_type = type;
8592           saved_type_i = i;
8593         }
8594     }
8595   else
8596     i = list_length (GET_CPC_LIST ())-2;
8597
8598   if (i == saved_i)
8599     return saved_thisn;
8600     
8601   sprintf (buffer, "this$%d", i);
8602   saved_i = i;
8603   saved_thisn = get_identifier (buffer);
8604   return saved_thisn;
8605 }
8606
8607 /* Return the assignement to the hidden enclosing context `this$<n>'
8608    by the second incoming parameter to the innerclass constructor. The
8609    form used is `this.this$<n> = this$<n>;'.  */
8610
8611 static tree
8612 build_thisn_assign ()
8613 {
8614   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
8615     {
8616       tree thisn = build_current_thisn (current_class);
8617       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
8618                                          build_wfl_node (thisn), 0);
8619       tree rhs = build_wfl_node (thisn);
8620       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
8621       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
8622     }
8623   return NULL_TREE;
8624 }
8625
8626 \f
8627 /* Building the synthetic `class$' used to implement the `.class' 1.1
8628    extension for non primitive types. This method looks like:
8629
8630     static Class class$(String type) throws NoClassDefFoundError
8631     {
8632       try {return (java.lang.Class.forName (String));}
8633       catch (ClassNotFoundException e) {
8634         throw new NoClassDefFoundError(e.getMessage());}
8635     } */
8636
8637 static tree
8638 build_dot_class_method (class)
8639      tree class;
8640 {
8641 #define BWF(S) build_wfl_node (get_identifier ((S)))
8642 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8643   tree args, tmp, saved_current_function_decl, mdecl;
8644   tree stmt, throw_stmt;
8645
8646   static tree get_message_wfl, type_parm_wfl;
8647
8648   if (!get_message_wfl)
8649     {
8650       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8651       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8652       ggc_add_tree_root (&get_message_wfl, 1);
8653       ggc_add_tree_root (&type_parm_wfl, 1);
8654     }
8655
8656   /* Build the arguments */
8657   args = build_tree_list (get_identifier ("type$"),
8658                           build_pointer_type (string_type_node));
8659   TREE_CHAIN (args) = end_params_node;
8660
8661   /* Build the qualified name java.lang.Class.forName */
8662   tmp = MQN (MQN (MQN (BWF ("java"), 
8663                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8664   load_class (class_not_found_type_node, 1);
8665   load_class (no_class_def_found_type_node, 1);
8666   
8667   /* Create the "class$" function */
8668   mdecl = create_artificial_method (class, ACC_STATIC, 
8669                                     build_pointer_type (class_type_node),
8670                                     classdollar_identifier_node, args);
8671   DECL_FUNCTION_THROWS (mdecl) = 
8672     build_tree_list (NULL_TREE, no_class_def_found_type_node);
8673
8674   /* We start by building the try block. We need to build:
8675        return (java.lang.Class.forName (type)); */
8676   stmt = build_method_invocation (tmp, 
8677                                   build_tree_list (NULL_TREE, type_parm_wfl));
8678   stmt = build_return (0, stmt);
8679
8680   /* Now onto the catch block. We start by building the expression
8681      throwing a new exception: throw new NoClassDefFoundError (_.getMessage) */
8682   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8683                                     get_message_wfl, 0);
8684   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8685   
8686   /* Build new NoClassDefFoundError (_.getMessage) */
8687   throw_stmt = build_new_invocation 
8688     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8689      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8690
8691   /* Build the throw, (it's too early to use BUILD_THROW) */
8692   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8693
8694   /* Encapsulate STMT in a try block. The catch clause executes THROW_STMT */
8695   stmt = encapsulate_with_try_catch (0, class_not_found_type_node,
8696                                      stmt, throw_stmt);
8697
8698   fix_method_argument_names (args, mdecl);
8699   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8700   saved_current_function_decl = current_function_decl;
8701   start_artificial_method_body (mdecl);
8702   java_method_add_stmt (mdecl, stmt);
8703   end_artificial_method_body (mdecl);
8704   current_function_decl = saved_current_function_decl;
8705   TYPE_DOT_CLASS (class) = mdecl;
8706
8707   return mdecl;
8708 }
8709
8710 static tree
8711 build_dot_class_method_invocation (type)
8712      tree type;
8713 {
8714   tree sig_id, s;
8715
8716   if (TYPE_ARRAY_P (type))
8717     sig_id = build_java_signature (type);
8718   else
8719     sig_id = DECL_NAME (TYPE_NAME (type));
8720
8721   /* Ensure that the proper name separator is used */
8722   sig_id = unmangle_classname (IDENTIFIER_POINTER (sig_id),
8723                                IDENTIFIER_LENGTH (sig_id));
8724
8725   s = build_string (IDENTIFIER_LENGTH (sig_id), 
8726                     IDENTIFIER_POINTER (sig_id));
8727   return build_method_invocation (build_wfl_node (classdollar_identifier_node),
8728                                   build_tree_list (NULL_TREE, s));
8729 }
8730
8731 /* This section of the code deals with constructor.  */
8732
8733 /* Craft a body for default constructor. Patch existing constructor
8734    bodies with call to super() and field initialization statements if
8735    necessary.  */
8736
8737 static void
8738 fix_constructors (mdecl)
8739      tree mdecl;
8740 {
8741   tree iii;                     /* Instance Initializer Invocation */
8742   tree body = DECL_FUNCTION_BODY (mdecl);
8743   tree thisn_assign, compound = NULL_TREE;
8744   tree class_type = DECL_CONTEXT (mdecl);
8745
8746   if (DECL_FIXED_CONSTRUCTOR_P (mdecl))
8747     return;
8748   DECL_FIXED_CONSTRUCTOR_P (mdecl) = 1;
8749
8750   if (!body)
8751     {
8752       /* It is an error for the compiler to generate a default
8753          constructor if the superclass doesn't have a constructor that
8754          takes no argument, or the same args for an anonymous class */
8755       if (verify_constructor_super (mdecl))
8756         {
8757           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8758           tree save = DECL_NAME (mdecl);
8759           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8760           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8761           parse_error_context
8762             (lookup_cl (TYPE_NAME (class_type)), 
8763              "No constructor matching `%s' found in class `%s'",
8764              lang_printable_name (mdecl, 0), n);
8765           DECL_NAME (mdecl) = save;
8766         }
8767       
8768       /* The constructor body must be crafted by hand. It's the
8769          constructor we defined when we realize we didn't have the
8770          CLASSNAME() constructor */
8771       start_artificial_method_body (mdecl);
8772       
8773       /* Insert an assignment to the this$<n> hidden field, if
8774          necessary */
8775       if ((thisn_assign = build_thisn_assign ()))
8776         java_method_add_stmt (mdecl, thisn_assign);
8777
8778       /* We don't generate a super constructor invocation if we're
8779          compiling java.lang.Object. build_super_invocation takes care
8780          of that. */
8781       java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8782
8783       /* FIXME */
8784       if ((iii = build_instinit_invocation (class_type)))
8785         java_method_add_stmt (mdecl, iii);
8786
8787       end_artificial_method_body (mdecl);
8788     }
8789   /* Search for an explicit constructor invocation */
8790   else 
8791     {
8792       int found = 0;
8793       int invokes_this = 0;
8794       tree found_call = NULL_TREE;
8795       tree main_block = BLOCK_EXPR_BODY (body);
8796       
8797       while (body)
8798         switch (TREE_CODE (body))
8799           {
8800           case CALL_EXPR:
8801             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8802             if (CALL_THIS_CONSTRUCTOR_P (body))
8803               invokes_this = 1;
8804             body = NULL_TREE;
8805             break;
8806           case COMPOUND_EXPR:
8807           case EXPR_WITH_FILE_LOCATION:
8808             found_call = body;
8809             body = TREE_OPERAND (body, 0);
8810             break;
8811           case BLOCK:
8812             found_call = body;
8813             body = BLOCK_EXPR_BODY (body);
8814             break;
8815           default:
8816             found = 0;
8817             body = NULL_TREE;
8818           }
8819
8820       /* Generate the assignment to this$<n>, if necessary */
8821       if ((thisn_assign = build_thisn_assign ()))
8822         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8823
8824       /* The constructor is missing an invocation of super() */
8825       if (!found)
8826         compound = add_stmt_to_compound (compound, NULL_TREE,
8827                                          build_super_invocation (mdecl));
8828       /* Explicit super() invokation should take place before the
8829          instance initializer blocks. */
8830       else
8831         {
8832           compound = add_stmt_to_compound (compound, NULL_TREE,
8833                                            TREE_OPERAND (found_call, 0));
8834           TREE_OPERAND (found_call, 0) = empty_stmt_node;
8835         }
8836       
8837       /* Insert the instance initializer block right after. */
8838       if (!invokes_this && (iii = build_instinit_invocation (class_type)))
8839         compound = add_stmt_to_compound (compound, NULL_TREE, iii);
8840
8841       /* Fix the constructor main block if we're adding extra stmts */
8842       if (compound)
8843         {
8844           compound = add_stmt_to_compound (compound, NULL_TREE,
8845                                            BLOCK_EXPR_BODY (main_block));
8846           BLOCK_EXPR_BODY (main_block) = compound;
8847         }
8848     }
8849 }
8850
8851 /* Browse constructors in the super class, searching for a constructor
8852    that doesn't take any argument. Return 0 if one is found, 1
8853    otherwise.  If the current class is an anonymous inner class, look
8854    for something that has the same signature. */
8855
8856 static int
8857 verify_constructor_super (mdecl)
8858      tree mdecl;
8859 {
8860   tree class = CLASSTYPE_SUPER (current_class);
8861   int super_inner = PURE_INNER_CLASS_TYPE_P (class);
8862   tree sdecl;
8863
8864   if (!class)
8865     return 0;
8866
8867   if (ANONYMOUS_CLASS_P (current_class))
8868     {
8869       tree mdecl_arg_type;
8870       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8871       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8872         if (DECL_CONSTRUCTOR_P (sdecl))
8873           {
8874             tree m_arg_type;
8875             tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8876             if (super_inner)
8877               arg_type = TREE_CHAIN (arg_type);
8878             for (m_arg_type = mdecl_arg_type; 
8879                  (arg_type != end_params_node 
8880                   && m_arg_type != end_params_node);
8881                  arg_type = TREE_CHAIN (arg_type), 
8882                    m_arg_type = TREE_CHAIN (m_arg_type))
8883               if (!valid_method_invocation_conversion_p 
8884                      (TREE_VALUE (arg_type),
8885                       TREE_VALUE (m_arg_type)))
8886                 break;
8887
8888             if (arg_type == end_params_node && m_arg_type == end_params_node)
8889               return 0;
8890           }
8891     }
8892   else
8893     {
8894       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8895         {
8896           tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8897           if (super_inner)
8898             arg = TREE_CHAIN (arg);
8899           if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
8900             return 0;
8901         }
8902     }
8903   return 1;
8904 }
8905
8906 /* Generate code for all context remembered for code generation.  */
8907
8908 void
8909 java_expand_classes ()
8910 {
8911   int save_error_count = 0;
8912   static struct parser_ctxt *cur_ctxp = NULL;
8913
8914   java_parse_abort_on_error ();
8915   if (!(ctxp = ctxp_for_generation))
8916     return;
8917   java_layout_classes ();
8918   java_parse_abort_on_error ();
8919
8920   cur_ctxp = ctxp_for_generation;
8921   for (; cur_ctxp; cur_ctxp = cur_ctxp->next)
8922     {
8923       ctxp = cur_ctxp;
8924       input_filename = ctxp->filename;
8925       lang_init_source (2);            /* Error msgs have method prototypes */
8926       java_complete_expand_classes (); /* Complete and expand classes */
8927       java_parse_abort_on_error ();
8928     }
8929   input_filename = main_input_filename;
8930
8931   /* Find anonymous classes and expand their constructor, now they
8932      have been fixed. */
8933   for (cur_ctxp = ctxp_for_generation;  cur_ctxp;  cur_ctxp = cur_ctxp->next)
8934     {
8935       tree current;
8936       ctxp = cur_ctxp;
8937       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8938         {
8939           current_class = TREE_TYPE (current);
8940           if (ANONYMOUS_CLASS_P (current_class))
8941             {
8942               tree d;
8943               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8944                 {
8945                   if (DECL_CONSTRUCTOR_P (d))
8946                     {
8947                       restore_line_number_status (1);
8948                       java_complete_expand_method (d);
8949                       restore_line_number_status (0);
8950                       break;    /* We now there are no other ones */
8951                     }
8952                 }
8953             }
8954         }
8955     }
8956
8957   /* If we've found error at that stage, don't try to generate
8958      anything, unless we're emitting xrefs or checking the syntax only
8959      (but not using -fsyntax-only for the purpose of generating
8960      bytecode. */
8961   if (java_error_count && !flag_emit_xref 
8962       && (!flag_syntax_only && !flag_emit_class_files))
8963     return;
8964
8965   /* Now things are stable, go for generation of the class data. */
8966   for (cur_ctxp = ctxp_for_generation;  cur_ctxp;  cur_ctxp = cur_ctxp->next)
8967     {
8968       tree current;
8969       ctxp = cur_ctxp;
8970       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8971         {
8972           current_class = TREE_TYPE (current);
8973           outgoing_cpool = TYPE_CPOOL (current_class);
8974           if (flag_emit_class_files)
8975             write_classfile (current_class);
8976           if (flag_emit_xref)
8977             expand_xref (current_class);
8978           else if (! flag_syntax_only)
8979             {
8980               java_expand_method_bodies (current_class);
8981               finish_class ();
8982             }
8983         }
8984     }
8985 }
8986
8987 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8988    a tree list node containing RIGHT. Fore coming RIGHTs will be
8989    chained to this hook. LOCATION contains the location of the
8990    separating `.' operator.  */
8991
8992 static tree
8993 make_qualified_primary (primary, right, location)
8994      tree primary, right;
8995      int location;
8996 {
8997   tree wfl;
8998
8999   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
9000     wfl = build_wfl_wrap (primary, location);
9001   else
9002     {
9003       wfl = primary;
9004       /* If wfl wasn't qualified, we build a first anchor */
9005       if (!EXPR_WFL_QUALIFICATION (wfl))
9006         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
9007     }
9008
9009   /* And chain them */
9010   EXPR_WFL_LINECOL (right) = location;
9011   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
9012   PRIMARY_P (wfl) =  1;
9013   return wfl;
9014 }
9015
9016 /* Simple merge of two name separated by a `.' */
9017
9018 static tree
9019 merge_qualified_name (left, right)
9020      tree left, right;
9021 {
9022   tree node;
9023   if (!left && !right)
9024     return NULL_TREE;
9025
9026   if (!left)
9027     return right;
9028
9029   if (!right)
9030     return left;
9031
9032   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
9033                 IDENTIFIER_LENGTH (left));
9034   obstack_1grow (&temporary_obstack, '.');
9035   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
9036                  IDENTIFIER_LENGTH (right));
9037   node =  get_identifier (obstack_base (&temporary_obstack));
9038   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
9039   QUALIFIED_P (node) = 1;
9040   return node;
9041 }
9042
9043 /* Merge the two parts of a qualified name into LEFT.  Set the
9044    location information of the resulting node to LOCATION, usually
9045    inherited from the location information of the `.' operator. */
9046
9047 static tree
9048 make_qualified_name (left, right, location)
9049      tree left, right;
9050      int location;
9051 {
9052 #ifdef USE_COMPONENT_REF
9053   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
9054   EXPR_WFL_LINECOL (node) = location;
9055   return node;
9056 #else
9057   tree left_id = EXPR_WFL_NODE (left);
9058   tree right_id = EXPR_WFL_NODE (right);
9059   tree wfl, merge;
9060
9061   merge = merge_qualified_name (left_id, right_id);
9062
9063   /* Left wasn't qualified and is now qualified */
9064   if (!QUALIFIED_P (left_id))
9065     {
9066       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
9067       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
9068       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
9069     }
9070   
9071   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
9072   EXPR_WFL_LINECOL (wfl) = location;
9073   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
9074
9075   EXPR_WFL_NODE (left) = merge;
9076   return left;
9077 #endif
9078 }
9079
9080 /* Extract the last identifier component of the qualified in WFL. The
9081    last identifier is removed from the linked list */
9082
9083 static tree
9084 cut_identifier_in_qualified (wfl)
9085      tree wfl;
9086 {
9087   tree q;
9088   tree previous = NULL_TREE;
9089   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
9090     if (!TREE_CHAIN (q))
9091       {
9092         if (!previous)
9093           /* Operating on a non qualified qualified WFL.  */
9094           abort ();
9095
9096         TREE_CHAIN (previous) = NULL_TREE;
9097         return TREE_PURPOSE (q);
9098       }
9099 }
9100
9101 /* Resolve the expression name NAME. Return its decl.  */
9102
9103 static tree
9104 resolve_expression_name (id, orig)
9105      tree id;
9106      tree *orig;
9107 {
9108   tree name = EXPR_WFL_NODE (id);
9109   tree decl;
9110
9111   /* 6.5.5.1: Simple expression names */
9112   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
9113     {
9114       /* 15.13.1: NAME can appear within the scope of a local variable
9115          declaration */
9116       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
9117         return decl;
9118
9119       /* 15.13.1: NAME can appear within a class declaration */
9120       else 
9121         {
9122           decl = lookup_field_wrapper (current_class, name);
9123           if (decl)
9124             {
9125               tree access = NULL_TREE;
9126               int fs = FIELD_STATIC (decl);
9127
9128               /* If we're accessing an outer scope local alias, make
9129                  sure we change the name of the field we're going to
9130                  build access to. */
9131               if (FIELD_LOCAL_ALIAS_USED (decl))
9132                 name = DECL_NAME (decl);
9133
9134               /* Instance variable (8.3.1.1) can't appear within
9135                  static method, static initializer or initializer for
9136                  a static variable. */
9137               if (!fs && METHOD_STATIC (current_function_decl))
9138                 {
9139                   static_ref_err (id, name, current_class);
9140                   return error_mark_node;
9141                 }
9142               /* Instance variables can't appear as an argument of
9143                  an explicit constructor invocation */
9144               if (!fs && ctxp->explicit_constructor_p
9145                   && !enclosing_context_p (DECL_CONTEXT (decl), current_class))
9146                 {
9147                   parse_error_context
9148                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
9149                   return error_mark_node;
9150                 }
9151
9152               /* If we're processing an inner class and we're trying
9153                  to access a field belonging to an outer class, build
9154                  the access to the field */
9155               if (!fs && outer_field_access_p (current_class, decl))
9156                 {
9157                   if (CLASS_STATIC (TYPE_NAME (current_class)))
9158                     {
9159                       static_ref_err (id, DECL_NAME (decl), current_class);
9160                       return error_mark_node;
9161                     }
9162                   access = build_outer_field_access (id, decl);
9163                   if (orig)
9164                     *orig = access;
9165                   return access;
9166                 }
9167
9168               /* Otherwise build what it takes to access the field */
9169               access = build_field_ref ((fs ? NULL_TREE : current_this),
9170                                         DECL_CONTEXT (decl), name);
9171               if (fs)
9172                 access = maybe_build_class_init_for_field (decl, access);
9173               /* We may be asked to save the real field access node */
9174               if (orig)
9175                 *orig = access;
9176               /* And we return what we got */
9177               return access;
9178             }
9179           /* Fall down to error report on undefined variable */
9180         }
9181     }
9182   /* 6.5.5.2 Qualified Expression Names */
9183   else
9184     {
9185       if (orig)
9186         *orig = NULL_TREE;
9187       qualify_ambiguous_name (id);
9188       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
9189       /* 15.10.2: Accessing Superclass Members using super */
9190       return resolve_field_access (id, orig, NULL);
9191     }
9192
9193   /* We've got an error here */
9194   if (INNER_CLASS_TYPE_P (current_class))
9195     parse_error_context (id, 
9196                          "Local variable `%s' can't be accessed from within the inner class `%s' unless it is declared final",
9197                          IDENTIFIER_POINTER (name),
9198                          IDENTIFIER_POINTER (DECL_NAME
9199                                              (TYPE_NAME (current_class))));
9200   else
9201     parse_error_context (id, "Undefined variable `%s'", 
9202                          IDENTIFIER_POINTER (name));
9203
9204   return error_mark_node;
9205 }
9206
9207 static void
9208 static_ref_err (wfl, field_id, class_type)
9209     tree wfl, field_id, class_type;
9210 {
9211   parse_error_context 
9212     (wfl, 
9213      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
9214      IDENTIFIER_POINTER (field_id), 
9215      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
9216 }
9217
9218 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
9219    We return something suitable to generate the field access. We also
9220    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
9221    recipient's address can be null. */
9222
9223 static tree
9224 resolve_field_access (qual_wfl, field_decl, field_type)
9225      tree qual_wfl;
9226      tree *field_decl, *field_type;
9227 {
9228   int is_static = 0;
9229   tree field_ref;
9230   tree decl, where_found, type_found;
9231
9232   if (resolve_qualified_expression_name (qual_wfl, &decl,
9233                                          &where_found, &type_found))
9234     return error_mark_node;
9235
9236   /* Resolve the LENGTH field of an array here */
9237   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
9238       && type_found && TYPE_ARRAY_P (type_found) 
9239       && ! flag_emit_class_files && ! flag_emit_xref)
9240     {
9241       tree length = build_java_array_length_access (where_found);
9242       field_ref = length;
9243
9244       /* In case we're dealing with a static array, we need to
9245          initialize its class before the array length can be fetched.
9246          It's also a good time to create a DECL_RTL for the field if
9247          none already exists, otherwise if the field was declared in a
9248          class found in an external file and hasn't been (and won't
9249          be) accessed for its value, none will be created. */
9250       if (TREE_CODE (where_found) == VAR_DECL && FIELD_STATIC (where_found))
9251         {
9252           build_static_field_ref (where_found);
9253           field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
9254         }
9255     }
9256   /* We might have been trying to resolve field.method(). In which
9257      case, the resolution is over and decl is the answer */
9258   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
9259     field_ref = decl;
9260   else if (JDECL_P (decl))
9261     {
9262       if (!type_found)
9263         type_found = DECL_CONTEXT (decl);
9264       is_static = FIELD_STATIC (decl);
9265       field_ref = build_field_ref ((is_static && !flag_emit_xref? 
9266                                     NULL_TREE : where_found), 
9267                                    type_found, DECL_NAME (decl));
9268       if (field_ref == error_mark_node)
9269         return error_mark_node;
9270       if (is_static)
9271         field_ref = maybe_build_class_init_for_field (decl, field_ref);
9272     }
9273   else
9274     field_ref = decl;
9275
9276   if (field_decl)
9277     *field_decl = decl;
9278   if (field_type)
9279     *field_type = (QUAL_DECL_TYPE (decl) ? 
9280                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
9281   return field_ref;
9282 }
9283
9284 /* If NODE is an access to f static field, strip out the class
9285    initialization part and return the field decl, otherwise, return
9286    NODE. */
9287
9288 static tree
9289 strip_out_static_field_access_decl (node)
9290     tree node;
9291 {
9292   if (TREE_CODE (node) == COMPOUND_EXPR)
9293     {
9294       tree op1 = TREE_OPERAND (node, 1);
9295       if (TREE_CODE (op1) == COMPOUND_EXPR)
9296          {
9297            tree call = TREE_OPERAND (op1, 0);
9298            if (TREE_CODE (call) == CALL_EXPR
9299                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
9300                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
9301                == soft_initclass_node)
9302              return TREE_OPERAND (op1, 1);
9303          }
9304       else if (JDECL_P (op1))
9305         return op1;
9306     }
9307   return node;
9308 }
9309
9310 /* 6.5.5.2: Qualified Expression Names */
9311
9312 static int
9313 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
9314      tree wfl;
9315      tree *found_decl, *type_found, *where_found;
9316 {
9317   int from_type = 0;            /* Field search initiated from a type */
9318   int from_super = 0, from_cast = 0, from_qualified_this = 0;
9319   int previous_call_static = 0;
9320   int is_static;
9321   tree decl = NULL_TREE, type = NULL_TREE, q;
9322   /* For certain for of inner class instantiation */
9323   tree saved_current, saved_this;               
9324 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
9325   { current_class = saved_current; current_this = saved_this;}
9326
9327   *type_found = *where_found = NULL_TREE;
9328
9329   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
9330     {
9331       tree qual_wfl = QUAL_WFL (q);
9332       tree ret_decl;            /* for EH checking */
9333       int location;             /* for EH checking */
9334
9335       /* 15.10.1 Field Access Using a Primary */
9336       switch (TREE_CODE (qual_wfl))
9337         {
9338         case CALL_EXPR:
9339         case NEW_CLASS_EXPR:
9340           /* If the access to the function call is a non static field,
9341              build the code to access it. */
9342           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9343             {
9344               decl = maybe_access_field (decl, *where_found, 
9345                                          DECL_CONTEXT (decl));
9346               if (decl == error_mark_node)
9347                 return 1;
9348             }
9349
9350           /* And code for the function call */
9351           if (complete_function_arguments (qual_wfl))
9352             return 1;
9353
9354           /* We might have to setup a new current class and a new this
9355              for the search of an inner class, relative to the type of
9356              a expression resolved as `decl'. The current values are
9357              saved and restored shortly after */
9358           saved_current = current_class;
9359           saved_this = current_this;
9360           if (decl 
9361               && (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9362                   || from_qualified_this))
9363             {
9364               /* If we still have `from_qualified_this', we have the form
9365                  <T>.this.f() and we need to build <T>.this */
9366               if (from_qualified_this)
9367                 {
9368                   decl = build_access_to_thisn (current_class, type, 0);
9369                   decl = java_complete_tree (decl);
9370                   type = TREE_TYPE (TREE_TYPE (decl));
9371                 }
9372               current_class = type;
9373               current_this = decl;
9374               from_qualified_this = 0;
9375             }
9376
9377           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
9378             CALL_USING_SUPER (qual_wfl) = 1;
9379           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
9380                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
9381           *where_found = patch_method_invocation (qual_wfl, decl, type,
9382                                                   from_super,
9383                                                   &is_static, &ret_decl);
9384           if (*where_found == error_mark_node)
9385             {
9386               RESTORE_THIS_AND_CURRENT_CLASS;
9387               return 1;
9388             }
9389           *type_found = type = QUAL_DECL_TYPE (*where_found);
9390
9391           /* If we're creating an inner class instance, check for that
9392              an enclosing instance is in scope */
9393           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9394               && INNER_ENCLOSING_SCOPE_CHECK (type))
9395             {
9396               parse_error_context 
9397                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
9398                  lang_printable_name (type, 0),
9399                  (!current_this ? "" :
9400                   "; an explicit one must be provided when creating this inner class"));
9401               RESTORE_THIS_AND_CURRENT_CLASS;
9402               return 1;
9403             }
9404
9405           /* In case we had to change then to resolve a inner class
9406              instantiation using a primary qualified by a `new' */
9407           RESTORE_THIS_AND_CURRENT_CLASS;
9408
9409           /* EH check. No check on access$<n> functions */
9410           if (location 
9411               && !OUTER_FIELD_ACCESS_IDENTIFIER_P 
9412                     (DECL_NAME (current_function_decl)))
9413             check_thrown_exceptions (location, ret_decl);
9414
9415           /* If the previous call was static and this one is too,
9416              build a compound expression to hold the two (because in
9417              that case, previous function calls aren't transported as
9418              forcoming function's argument. */
9419           if (previous_call_static && is_static)
9420             {
9421               decl = build (COMPOUND_EXPR, TREE_TYPE (*where_found),
9422                             decl, *where_found);
9423               TREE_SIDE_EFFECTS (decl) = 1;
9424             }
9425           else
9426             {
9427               previous_call_static = is_static;
9428               decl = *where_found;
9429             }
9430           from_type = 0;
9431           continue;
9432
9433         case NEW_ARRAY_EXPR:
9434         case NEW_ANONYMOUS_ARRAY_EXPR:
9435           *where_found = decl = java_complete_tree (qual_wfl);
9436           if (decl == error_mark_node)
9437             return 1;
9438           *type_found = type = QUAL_DECL_TYPE (decl);
9439           continue;
9440
9441         case CONVERT_EXPR:
9442           *where_found = decl = java_complete_tree (qual_wfl);
9443           if (decl == error_mark_node)
9444             return 1;
9445           *type_found = type = QUAL_DECL_TYPE (decl);
9446           from_cast = 1;
9447           continue;
9448
9449         case CONDITIONAL_EXPR:
9450         case STRING_CST:
9451         case MODIFY_EXPR:
9452           *where_found = decl = java_complete_tree (qual_wfl);
9453           if (decl == error_mark_node)
9454             return 1;
9455           *type_found = type = QUAL_DECL_TYPE (decl);
9456           continue;
9457
9458         case ARRAY_REF:
9459           /* If the access to the function call is a non static field,
9460              build the code to access it. */
9461           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9462             {
9463               decl = maybe_access_field (decl, *where_found, type);
9464               if (decl == error_mark_node)
9465                 return 1;
9466             }
9467           /* And code for the array reference expression */
9468           decl = java_complete_tree (qual_wfl);
9469           if (decl == error_mark_node)
9470             return 1;
9471           type = QUAL_DECL_TYPE (decl);
9472           continue;
9473
9474         case PLUS_EXPR:
9475           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9476             return 1;
9477           if ((type = patch_string (decl)))
9478             decl = type;
9479           *where_found = QUAL_RESOLUTION (q) = decl;
9480           *type_found = type = TREE_TYPE (decl);
9481           break;
9482
9483         case CLASS_LITERAL:
9484           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9485             return 1;
9486           *where_found = QUAL_RESOLUTION (q) = decl;
9487           *type_found = type = TREE_TYPE (decl);
9488           break;
9489
9490         default:
9491           /* Fix for -Wall Just go to the next statement. Don't
9492              continue */
9493           break;
9494         }
9495
9496       /* If we fall here, we weren't processing a (static) function call. */
9497       previous_call_static = 0;
9498
9499       /* It can be the keyword THIS */
9500       if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION
9501           && EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
9502         {
9503           if (!current_this)
9504             {
9505               parse_error_context 
9506                 (wfl, "Keyword `this' used outside allowed context");
9507               return 1;
9508             }
9509           if (ctxp->explicit_constructor_p
9510               && type == current_class)
9511             {
9512               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9513               return 1;
9514             }
9515           /* We have to generate code for intermediate acess */
9516           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
9517             {
9518               *where_found = decl = current_this;
9519               *type_found = type = QUAL_DECL_TYPE (decl);
9520             }
9521           /* We're trying to access the this from somewhere else. Make sure
9522              it's allowed before doing so. */
9523           else
9524             {
9525               if (!enclosing_context_p (type, current_class))
9526                 {
9527                   char *p  = xstrdup (lang_printable_name (type, 0));
9528                   parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'", 
9529                                        p, p, 
9530                                        lang_printable_name (current_class, 0));
9531                   free (p);
9532                   return 1;
9533                 }
9534               from_qualified_this = 1;
9535               /* If there's nothing else after that, we need to
9536                  produce something now, otherwise, the section of the
9537                  code that needs to produce <T>.this will generate
9538                  what is necessary. */
9539               if (!TREE_CHAIN (q))
9540                 {
9541                   decl = build_access_to_thisn (current_class, type, 0);
9542                   *where_found = decl = java_complete_tree (decl);
9543                   *type_found = type = TREE_TYPE (decl);
9544                 }
9545             }
9546
9547           from_type = 0;
9548           continue;
9549         }
9550
9551       /* 15.10.2 Accessing Superclass Members using SUPER */
9552       if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION
9553           && EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
9554         {
9555           tree node;
9556           /* Check on the restricted use of SUPER */
9557           if (METHOD_STATIC (current_function_decl)
9558               || current_class == object_type_node)
9559             {
9560               parse_error_context 
9561                 (wfl, "Keyword `super' used outside allowed context");
9562               return 1;
9563             }
9564           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
9565           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
9566                              CLASSTYPE_SUPER (current_class),
9567                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
9568           *where_found = decl = java_complete_tree (node);
9569           if (decl == error_mark_node)
9570             return 1;
9571           *type_found = type = QUAL_DECL_TYPE (decl);
9572           from_super = from_type = 1;
9573           continue;
9574         }
9575
9576       /* 15.13.1: Can't search for field name in packages, so we
9577          assume a variable/class name was meant. */
9578       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
9579         {
9580           tree name = resolve_package (wfl, &q);
9581           if (name)
9582             {
9583               tree list;
9584               *where_found = decl = resolve_no_layout (name, qual_wfl);
9585               /* We want to be absolutely sure that the class is laid
9586                  out. We're going to search something inside it. */
9587               *type_found = type = TREE_TYPE (decl);
9588               layout_class (type);
9589               from_type = 1;
9590
9591               /* Fix them all the way down, if any are left. */
9592               if (q)
9593                 {
9594                   list = TREE_CHAIN (q);
9595                   while (list)
9596                     {
9597                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
9598                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
9599                       list = TREE_CHAIN (list);
9600                     }
9601                 }
9602             }
9603           else
9604             {
9605               if (from_super || from_cast)
9606                 parse_error_context 
9607                   ((from_cast ? qual_wfl : wfl),
9608                    "No variable `%s' defined in class `%s'",
9609                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9610                    lang_printable_name (type, 0));
9611               else
9612                 parse_error_context
9613                   (qual_wfl, "Undefined variable or class name: `%s'",
9614                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
9615               return 1;
9616             }
9617         }
9618
9619       /* We have a type name. It's been already resolved when the
9620          expression was qualified. */
9621       else if (RESOLVE_TYPE_NAME_P (qual_wfl) && QUAL_RESOLUTION (q))
9622         {
9623           decl = QUAL_RESOLUTION (q);
9624
9625           /* Sneak preview. If next we see a `new', we're facing a
9626              qualification with resulted in a type being selected
9627              instead of a field.  Report the error */
9628           if(TREE_CHAIN (q) 
9629              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
9630             {
9631               parse_error_context (qual_wfl, "Undefined variable `%s'",
9632                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9633               return 1;
9634             }
9635
9636           if (not_accessible_p (TREE_TYPE (decl), decl, type, 0))
9637             {
9638               parse_error_context 
9639                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
9640                  java_accstring_lookup (get_access_flags_from_decl (decl)),
9641                  GET_TYPE_NAME (type),
9642                  IDENTIFIER_POINTER (DECL_NAME (decl)),
9643                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9644               return 1;
9645             }
9646           check_deprecation (qual_wfl, decl);
9647
9648           type = TREE_TYPE (decl);
9649           from_type = 1;
9650         }
9651       /* We resolve an expression name */
9652       else 
9653         {
9654           tree field_decl = NULL_TREE;
9655
9656           /* If there exists an early resolution, use it. That occurs
9657              only once and we know that there are more things to
9658              come. Don't do that when processing something after SUPER
9659              (we need more thing to be put in place below */
9660           if (!from_super && QUAL_RESOLUTION (q))
9661             {
9662               decl = QUAL_RESOLUTION (q);
9663               if (!type)
9664                 {
9665                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
9666                     {
9667                       if (current_this)
9668                         *where_found = current_this;
9669                       else
9670                         {
9671                           static_ref_err (qual_wfl, DECL_NAME (decl),
9672                                           current_class);
9673                           return 1;
9674                         }
9675                       if (outer_field_access_p (current_class, decl))
9676                         decl = build_outer_field_access (qual_wfl, decl);
9677                     }
9678                   else
9679                     {
9680                       *where_found = TREE_TYPE (decl);
9681                       if (TREE_CODE (*where_found) == POINTER_TYPE)
9682                         *where_found = TREE_TYPE (*where_found);
9683                     }
9684                 }
9685             }
9686
9687           /* Report and error if we're using a numerical litteral as a
9688              qualifier. It can only be an INTEGER_CST. */
9689           else if (TREE_CODE (qual_wfl) == INTEGER_CST)
9690             {
9691               parse_error_context
9692                 (wfl, "Can't use type `%s' as a qualifier",
9693                  lang_printable_name (TREE_TYPE (qual_wfl), 0));
9694               return 1;
9695             }
9696
9697           /* We have to search for a field, knowing the type of its
9698              container. The flag FROM_TYPE indicates that we resolved
9699              the last member of the expression as a type name, which
9700              means that for the resolution of this field, we'll look
9701              for other errors than if it was resolved as a member of
9702              an other field. */
9703           else
9704             {
9705               int is_static;
9706               tree field_decl_type; /* For layout */
9707
9708               if (!from_type && !JREFERENCE_TYPE_P (type))
9709                 {
9710                   parse_error_context 
9711                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9712                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9713                      lang_printable_name (type, 0),
9714                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9715                   return 1;
9716                 }
9717               
9718               field_decl = lookup_field_wrapper (type,
9719                                                  EXPR_WFL_NODE (qual_wfl));
9720
9721               /* Maybe what we're trying to access to is an inner
9722                  class, only if decl is a TYPE_DECL. */
9723               if (!field_decl && TREE_CODE (decl) == TYPE_DECL)
9724                 {
9725                   tree ptr, inner_decl;
9726
9727                   BUILD_PTR_FROM_NAME (ptr, EXPR_WFL_NODE (qual_wfl));
9728                   inner_decl = resolve_class (decl, ptr, NULL_TREE, qual_wfl);
9729                   if (inner_decl)
9730                     {
9731                       check_inner_class_access (inner_decl, decl, qual_wfl); 
9732                       type = TREE_TYPE (inner_decl);
9733                       decl = inner_decl;
9734                       from_type = 1;
9735                       continue;
9736                     }
9737                 }
9738
9739               if (field_decl == NULL_TREE)
9740                 {
9741                   parse_error_context 
9742                     (qual_wfl, "No variable `%s' defined in type `%s'",
9743                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9744                      GET_TYPE_NAME (type));
9745                   return 1;
9746                 }
9747               if (field_decl == error_mark_node)
9748                 return 1;
9749
9750               /* Layout the type of field_decl, since we may need
9751                  it. Don't do primitive types or loaded classes. The
9752                  situation of non primitive arrays may not handled
9753                  properly here. FIXME */
9754               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9755                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9756               else
9757                 field_decl_type = TREE_TYPE (field_decl);
9758               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9759                   && !CLASS_LOADED_P (field_decl_type)
9760                   && !TYPE_ARRAY_P (field_decl_type))
9761                 resolve_and_layout (field_decl_type, NULL_TREE);
9762               
9763               /* Check on accessibility here */
9764               if (not_accessible_p (current_class, field_decl,
9765                                     DECL_CONTEXT (field_decl), from_super))
9766                 {
9767                   parse_error_context 
9768                     (qual_wfl,
9769                      "Can't access %s field `%s.%s' from `%s'",
9770                      java_accstring_lookup 
9771                        (get_access_flags_from_decl (field_decl)),
9772                      GET_TYPE_NAME (type),
9773                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9774                      IDENTIFIER_POINTER 
9775                        (DECL_NAME (TYPE_NAME (current_class))));
9776                   return 1;
9777                 }
9778               check_deprecation (qual_wfl, field_decl);
9779               
9780               /* There are things to check when fields are accessed
9781                  from type. There are no restrictions on a static
9782                  declaration of the field when it is accessed from an
9783                  interface */
9784               is_static = FIELD_STATIC (field_decl);
9785               if (!from_super && from_type 
9786                   && !TYPE_INTERFACE_P (type) 
9787                   && !is_static 
9788                   && (current_function_decl 
9789                       && METHOD_STATIC (current_function_decl)))
9790                 {
9791                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9792                   return 1;
9793                 }
9794               from_cast = from_super = 0;
9795
9796               /* It's an access from a type but it isn't static, we
9797                  make it relative to `this'. */
9798               if (!is_static && from_type)
9799                 decl = current_this;
9800
9801               /* If we need to generate something to get a proper
9802                  handle on what this field is accessed from, do it
9803                  now. */
9804               if (!is_static)
9805                 {
9806                   decl = maybe_access_field (decl, *where_found, *type_found);
9807                   if (decl == error_mark_node)
9808                     return 1;
9809                 }
9810
9811               /* We want to keep the location were found it, and the type
9812                  we found. */
9813               *where_found = decl;
9814               *type_found = type;
9815
9816               /* Generate the correct expression for field access from
9817                  qualified this */
9818               if (from_qualified_this)
9819                 {
9820                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9821                   from_qualified_this = 0;
9822                 }
9823
9824               /* This is the decl found and eventually the next one to
9825                  search from */
9826               decl = field_decl;
9827             }
9828           from_type = 0;
9829           type = QUAL_DECL_TYPE (decl);
9830
9831           /* Sneak preview. If decl is qualified by a `new', report
9832              the error here to be accurate on the peculiar construct */
9833           if (TREE_CHAIN (q) 
9834               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9835               && !JREFERENCE_TYPE_P (type))
9836             {
9837               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9838                                    lang_printable_name (type, 0));
9839               return 1;
9840             }
9841         }
9842       /* `q' might have changed due to a after package resolution
9843          re-qualification */
9844       if (!q)
9845         break;
9846     }
9847   *found_decl = decl;
9848   return 0;
9849 }
9850
9851 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9852    can't be accessed from REFERENCE (a record type). If MEMBER
9853    features a protected access, we then use WHERE which, if non null,
9854    holds the type of MEMBER's access that is checked against
9855    6.6.2.1. This function should be used when decl is a field or a
9856    method.  */
9857
9858 static int
9859 not_accessible_p (reference, member, where, from_super)
9860      tree reference, member;
9861      tree where;
9862      int from_super;
9863 {
9864   int access_flag = get_access_flags_from_decl (member);
9865
9866   /* Inner classes are processed by check_inner_class_access */
9867   if (INNER_CLASS_TYPE_P (reference))
9868     return 0;
9869
9870   /* Access always granted for members declared public */
9871   if (access_flag & ACC_PUBLIC)
9872     return 0;
9873   
9874   /* Check access on protected members */
9875   if (access_flag & ACC_PROTECTED)
9876     {
9877       /* Access granted if it occurs from within the package
9878          containing the class in which the protected member is
9879          declared */
9880       if (class_in_current_package (DECL_CONTEXT (member)))
9881         return 0;
9882
9883       /* If accessed with the form `super.member', then access is granted */
9884       if (from_super)
9885         return 0;
9886
9887       /* If where is active, access was made through a
9888          qualifier. Access is granted if the type of the qualifier is
9889          or is a sublass of the type the access made from (6.6.2.1.)  */
9890       if (where && !inherits_from_p (reference, where))
9891         return 1;
9892
9893       /* Otherwise, access is granted if occuring from the class where
9894          member is declared or a subclass of it. Find the right
9895          context to perform the check */
9896       if (PURE_INNER_CLASS_TYPE_P (reference))
9897         {
9898           while (INNER_CLASS_TYPE_P (reference))
9899             {
9900               if (inherits_from_p (reference, DECL_CONTEXT (member)))
9901                 return 0;
9902               reference = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (reference)));
9903             }
9904         }
9905       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9906         return 0;
9907       return 1;
9908     }
9909
9910   /* Check access on private members. Access is granted only if it
9911      occurs from within the class in which it is declared -- that does
9912      it for innerclasses too. */
9913   if (access_flag & ACC_PRIVATE)
9914     {
9915       if (reference == DECL_CONTEXT (member))
9916         return 0;
9917       if (enclosing_context_p (reference, DECL_CONTEXT (member)))
9918         return 0;
9919       return 1;
9920     }
9921
9922   /* Default access are permitted only when occuring within the
9923      package in which the type (REFERENCE) is declared. In other words,
9924      REFERENCE is defined in the current package */
9925   if (ctxp->package)
9926     return !class_in_current_package (reference);
9927
9928   /* Otherwise, access is granted */
9929   return 0;
9930 }
9931
9932 /* Test deprecated decl access.  */
9933 static void
9934 check_deprecation (wfl, decl)
9935      tree wfl, decl;
9936 {
9937   const char *file = DECL_SOURCE_FILE (decl);
9938   /* Complain if the field is deprecated and the file it was defined
9939      in isn't compiled at the same time the file which contains its
9940      use is */
9941   if (DECL_DEPRECATED (decl) 
9942       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9943     {
9944       char the [20];
9945       switch (TREE_CODE (decl))
9946         {
9947         case FUNCTION_DECL:
9948           strcpy (the, "method");
9949           break;
9950         case FIELD_DECL:
9951         case VAR_DECL:
9952           strcpy (the, "field");
9953           break;
9954         case TYPE_DECL:
9955           parse_warning_context (wfl, "The class `%s' has been deprecated",
9956                                  IDENTIFIER_POINTER (DECL_NAME (decl)));
9957           return;
9958         default:
9959           abort ();
9960         }
9961       /* Don't issue a message if the context as been deprecated as a
9962          whole. */
9963       if (! CLASS_DEPRECATED (TYPE_NAME (DECL_CONTEXT (decl))))
9964         parse_warning_context 
9965           (wfl, "The %s `%s' in class `%s' has been deprecated", 
9966            the, lang_printable_name (decl, 0),
9967            IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9968     }
9969 }
9970
9971 /* Returns 1 if class was declared in the current package, 0 otherwise */
9972
9973 static int
9974 class_in_current_package (class)
9975      tree class;
9976 {
9977   static tree cache = NULL_TREE;
9978   int qualified_flag;
9979   tree left;
9980
9981   if (cache == class)
9982     return 1;
9983
9984   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9985
9986   /* If the current package is empty and the name of CLASS is
9987      qualified, class isn't in the current package.  If there is a
9988      current package and the name of the CLASS is not qualified, class
9989      isn't in the current package */
9990   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9991     return 0;
9992
9993   /* If there is not package and the name of CLASS isn't qualified,
9994      they belong to the same unnamed package */
9995   if (!ctxp->package && !qualified_flag)
9996     return 1;
9997
9998   /* Compare the left part of the name of CLASS with the package name */
9999   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
10000   if (ctxp->package == left)
10001     {
10002       static int initialized_p;
10003       /* Register CACHE with the garbage collector.  */
10004       if (!initialized_p)
10005         {
10006           ggc_add_tree_root (&cache, 1);
10007           initialized_p = 1;
10008         }
10009
10010       cache = class;
10011       return 1;
10012     }
10013   return 0;
10014 }
10015
10016 /* This function may generate code to access DECL from WHERE. This is
10017    done only if certain conditions meet.  */
10018
10019 static tree
10020 maybe_access_field (decl, where, type)
10021   tree decl, where, type;
10022 {
10023   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
10024       && !FIELD_STATIC (decl))
10025     decl = build_field_ref (where ? where : current_this, 
10026                             (type ? type : DECL_CONTEXT (decl)),
10027                             DECL_NAME (decl));
10028   return decl;
10029 }
10030
10031 /* Build a method invocation, by patching PATCH. If non NULL
10032    and according to the situation, PRIMARY and WHERE may be
10033    used. IS_STATIC is set to 1 if the invoked function is static. */
10034
10035 static tree
10036 patch_method_invocation (patch, primary, where, from_super,
10037                         is_static, ret_decl)
10038      tree patch, primary, where;
10039      int from_super;
10040      int *is_static;
10041      tree *ret_decl;
10042 {
10043   tree wfl = TREE_OPERAND (patch, 0);
10044   tree args = TREE_OPERAND (patch, 1);
10045   tree name = EXPR_WFL_NODE (wfl);
10046   tree list;
10047   int is_static_flag = 0;
10048   int is_super_init = 0;
10049   tree this_arg = NULL_TREE;
10050   int is_array_clone_call = 0;
10051   
10052   /* Should be overriden if everything goes well. Otherwise, if
10053      something fails, it should keep this value. It stop the
10054      evaluation of a bogus assignment. See java_complete_tree,
10055      MODIFY_EXPR: for the reasons why we sometimes want to keep on
10056      evaluating an assignment */
10057   TREE_TYPE (patch) = error_mark_node;
10058
10059   /* Since lookup functions are messing with line numbers, save the
10060      context now.  */
10061   java_parser_context_save_global ();
10062
10063   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
10064
10065   /* Resolution of qualified name, excluding constructors */
10066   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
10067     {
10068       tree identifier, identifier_wfl, type, resolved;
10069       /* Extract the last IDENTIFIER of the qualified
10070          expression. This is a wfl and we will use it's location
10071          data during error report. */
10072       identifier_wfl = cut_identifier_in_qualified (wfl);
10073       identifier = EXPR_WFL_NODE (identifier_wfl);
10074       
10075       /* Given the context, IDENTIFIER is syntactically qualified
10076          as a MethodName. We need to qualify what's before */
10077       qualify_ambiguous_name (wfl);
10078       resolved = resolve_field_access (wfl, NULL, NULL);
10079
10080       if (resolved == error_mark_node)
10081         PATCH_METHOD_RETURN_ERROR ();
10082
10083       type = GET_SKIP_TYPE (resolved);
10084       resolve_and_layout (type, NULL_TREE);
10085       
10086       if (JPRIMITIVE_TYPE_P (type))
10087         {
10088           parse_error_context
10089             (identifier_wfl,
10090              "Can't invoke a method on primitive type `%s'",
10091              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
10092           PATCH_METHOD_RETURN_ERROR ();         
10093         }
10094
10095       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
10096       args = nreverse (args);
10097
10098       /* We're resolving a call from a type */
10099       if (TREE_CODE (resolved) == TYPE_DECL)
10100         {
10101           if (CLASS_INTERFACE (resolved))
10102             {
10103               parse_error_context
10104                 (identifier_wfl,
10105                 "Can't make static reference to method `%s' in interface `%s'",
10106                  IDENTIFIER_POINTER (identifier), 
10107                  IDENTIFIER_POINTER (name));
10108               PATCH_METHOD_RETURN_ERROR ();
10109             }
10110           if (list && !METHOD_STATIC (list))
10111             {
10112               char *fct_name = xstrdup (lang_printable_name (list, 0));
10113               parse_error_context 
10114                 (identifier_wfl,
10115                  "Can't make static reference to method `%s %s' in class `%s'",
10116                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
10117                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
10118               free (fct_name);
10119               PATCH_METHOD_RETURN_ERROR ();
10120             }
10121         }
10122       else
10123         this_arg = primary = resolved;
10124       
10125       if (TYPE_ARRAY_P (type) && identifier == get_identifier ("clone"))
10126         is_array_clone_call = 1;
10127       
10128       /* IDENTIFIER_WFL will be used to report any problem further */
10129       wfl = identifier_wfl;
10130     }
10131   /* Resolution of simple names, names generated after a primary: or
10132      constructors */
10133   else
10134     {
10135       tree class_to_search = NULL_TREE;
10136       int lc;                   /* Looking for Constructor */
10137       
10138       /* We search constructor in their target class */
10139       if (CALL_CONSTRUCTOR_P (patch))
10140         {
10141           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10142             class_to_search = EXPR_WFL_NODE (wfl);
10143           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
10144                    this_identifier_node)
10145             class_to_search = NULL_TREE;
10146           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
10147                    super_identifier_node)
10148             {
10149               is_super_init = 1;
10150               if (CLASSTYPE_SUPER (current_class))
10151                 class_to_search = 
10152                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
10153               else
10154                 {
10155                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
10156                   PATCH_METHOD_RETURN_ERROR ();
10157                 }
10158             }
10159
10160           /* Class to search is NULL if we're searching the current one */
10161           if (class_to_search)
10162             {
10163               class_to_search = resolve_and_layout (class_to_search, wfl);
10164
10165               if (!class_to_search)
10166                 {
10167                   parse_error_context 
10168                     (wfl, "Class `%s' not found in type declaration",
10169                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
10170                   PATCH_METHOD_RETURN_ERROR ();
10171                 }
10172               
10173               /* Can't instantiate an abstract class, but we can
10174                  invoke it's constructor. It's use within the `new'
10175                  context is denied here. */
10176               if (CLASS_ABSTRACT (class_to_search) 
10177                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
10178                 {
10179                   parse_error_context 
10180                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
10181                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
10182                   PATCH_METHOD_RETURN_ERROR ();
10183                 }
10184
10185               class_to_search = TREE_TYPE (class_to_search);
10186             }
10187           else
10188             class_to_search = current_class;
10189           lc = 1;
10190         }
10191       /* This is a regular search in the local class, unless an
10192          alternate class is specified. */
10193       else
10194         {
10195           if (where != NULL_TREE)
10196             class_to_search = where;
10197           else if (QUALIFIED_P (name))
10198             class_to_search = current_class;
10199           else
10200             {
10201               class_to_search = current_class;
10202
10203               for (;;)
10204                 {
10205                   if (has_method (class_to_search, name))
10206                     break;
10207                   if (! INNER_CLASS_TYPE_P (class_to_search))
10208                     {
10209                       parse_error_context (wfl,
10210                                            "No method named `%s' in scope",
10211                                            IDENTIFIER_POINTER (name));
10212                       PATCH_METHOD_RETURN_ERROR ();
10213                     }
10214                   class_to_search
10215                     = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_to_search)));
10216                 }
10217             }
10218           lc = 0;
10219         }
10220
10221       /* NAME is a simple identifier or comes from a primary. Search
10222          in the class whose declaration contain the method being
10223          invoked. */
10224       resolve_and_layout (class_to_search, NULL_TREE);
10225
10226       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
10227       /* Don't continue if no method were found, as the next statement
10228          can't be executed then. */
10229       if (!list)
10230         PATCH_METHOD_RETURN_ERROR ();
10231       
10232       if (TYPE_ARRAY_P (class_to_search)
10233           && DECL_NAME (list) == get_identifier ("clone"))
10234         is_array_clone_call = 1;
10235
10236       /* Check for static reference if non static methods */
10237       if (check_for_static_method_reference (wfl, patch, list, 
10238                                              class_to_search, primary))
10239         PATCH_METHOD_RETURN_ERROR ();
10240
10241       /* Check for inner classes creation from illegal contexts */
10242       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
10243                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
10244           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
10245         {
10246           parse_error_context 
10247             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
10248              lang_printable_name (class_to_search, 0),
10249              (!current_this ? "" :
10250               "; an explicit one must be provided when creating this inner class"));
10251           PATCH_METHOD_RETURN_ERROR ();
10252         }
10253
10254       /* Non static methods are called with the current object extra
10255          argument. If patch a `new TYPE()', the argument is the value
10256          returned by the object allocator. If method is resolved as a
10257          primary, use the primary otherwise use the current THIS. */
10258       args = nreverse (args);
10259       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
10260         {
10261           this_arg = primary ? primary : current_this;
10262
10263           /* If we're using an access method, things are different.
10264              There are two familly of cases:
10265
10266              1) We're not generating bytecodes:
10267
10268              - LIST is non static. It's invocation is transformed from
10269                x(a1,...,an) into this$<n>.x(a1,....an).
10270              - LIST is static. It's invocation is transformed from
10271                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
10272
10273              2) We're generating bytecodes:
10274              
10275              - LIST is non static. It's invocation is transformed from
10276                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
10277              - LIST is static. It's invocation is transformed from
10278                x(a1,....,an) into TYPE_OF(this$<n>).x(a1,....an).
10279
10280              Of course, this$<n> can be abitrary complex, ranging from
10281              this$0 (the immediate outer context) to 
10282              access$0(access$0(...(this$0))). 
10283              
10284              maybe_use_access_method returns a non zero value if the
10285              this_arg has to be moved into the (then generated) stub
10286              argument list. In the meantime, the selected function
10287              might have be replaced by a generated stub. */
10288           if (!primary &&
10289               maybe_use_access_method (is_super_init, &list, &this_arg))
10290             {
10291               args = tree_cons (NULL_TREE, this_arg, args);
10292               this_arg = NULL_TREE; /* So it doesn't get chained twice */
10293             }
10294         }
10295     }
10296
10297   /* Merge point of all resolution schemes. If we have nothing, this
10298      is an error, already signaled */
10299   if (!list) 
10300     PATCH_METHOD_RETURN_ERROR ();
10301
10302   /* Check accessibility, position the is_static flag, build and
10303      return the call */
10304   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list,
10305                         (primary ? TREE_TYPE (TREE_TYPE (primary)) : 
10306                          NULL_TREE), from_super)
10307       /* Calls to clone() on array types are permitted as a special-case. */
10308       && !is_array_clone_call)
10309     {
10310       const char *fct_name = IDENTIFIER_POINTER (DECL_NAME (list));
10311       const char *access =
10312         java_accstring_lookup (get_access_flags_from_decl (list));
10313       const char *klass =
10314         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list))));
10315       const char *refklass =
10316         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
10317       const char *what = (DECL_CONSTRUCTOR_P (list)
10318                           ? "constructor" : "method");
10319       /* FIXME: WFL yields the wrong message here but I don't know
10320          what else to use.  */
10321       parse_error_context (wfl,
10322                            "Can't access %s %s `%s.%s' from `%s'",
10323                            access, what, klass, fct_name, refklass);
10324       PATCH_METHOD_RETURN_ERROR ();
10325     }
10326
10327   /* Deprecation check: check whether the method being invoked or the
10328      instance-being-created's type are deprecated. */
10329   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10330     check_deprecation (wfl, TYPE_NAME (DECL_CONTEXT (list)));
10331   else
10332     check_deprecation (wfl, list);
10333
10334   /* If invoking a innerclass constructor, there are hidden parameters
10335      to pass */
10336   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
10337       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10338     {
10339       /* And make sure we add the accessed local variables to be saved
10340          in field aliases. */
10341       args = build_alias_initializer_parameter_list
10342         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
10343
10344       /* Secretly pass the current_this/primary as a second argument */
10345       if (primary || current_this)
10346         {
10347           tree extra_arg;
10348           tree this_type = (current_this ?
10349                             TREE_TYPE (TREE_TYPE (current_this)) : NULL_TREE);
10350           /* Method's (list) enclosing context */
10351           tree mec = DECL_CONTEXT (TYPE_NAME (DECL_CONTEXT (list)));
10352           /* If we have a primary, use it. */
10353           if (primary)
10354             extra_arg = primary;
10355           /* The current `this' is an inner class but isn't a direct
10356              enclosing context for the inner class we're trying to
10357              create. Build an access to the proper enclosing context
10358              and use it. */
10359           else if (current_this && PURE_INNER_CLASS_TYPE_P (this_type)
10360                    && this_type != TREE_TYPE (mec))
10361             {
10362
10363               extra_arg = build_access_to_thisn (current_class,
10364                                                  TREE_TYPE (mec), 0);
10365               extra_arg = java_complete_tree (extra_arg);
10366             }
10367           /* Otherwise, just use the current `this' as an enclosing
10368              context. */
10369           else
10370             extra_arg = current_this;
10371           args = tree_cons (NULL_TREE, extra_arg, args);
10372         }
10373       else
10374         args = tree_cons (NULL_TREE, integer_zero_node, args);
10375     }
10376
10377   /* This handles the situation where a constructor invocation needs
10378      to have an enclosing context passed as a second parameter (the
10379      constructor is one of an inner class. We extract it from the
10380      current function.  */
10381   if ((is_super_init || 
10382        (TREE_CODE (patch) == CALL_EXPR && name == this_identifier_node))
10383       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10384     {
10385       tree enclosing_decl = DECL_CONTEXT (TYPE_NAME (current_class));
10386       tree extra_arg;
10387
10388       if (ANONYMOUS_CLASS_P (current_class) || !DECL_CONTEXT (enclosing_decl))
10389         {
10390           extra_arg = DECL_FUNCTION_BODY (current_function_decl);
10391           extra_arg = TREE_CHAIN (BLOCK_EXPR_DECLS (extra_arg));
10392         }
10393       else
10394         {
10395           tree dest = TREE_TYPE (DECL_CONTEXT (enclosing_decl));
10396           extra_arg = 
10397             build_access_to_thisn (TREE_TYPE (enclosing_decl), dest, 0);
10398           extra_arg = java_complete_tree (extra_arg);
10399         }
10400       args = tree_cons (NULL_TREE, extra_arg, args);
10401     }
10402
10403   is_static_flag = METHOD_STATIC (list);
10404   if (! is_static_flag && this_arg != NULL_TREE)
10405     args = tree_cons (NULL_TREE, this_arg, args);
10406
10407   /* In the context of an explicit constructor invocation, we can't
10408      invoke any method relying on `this'. Exceptions are: we're
10409      invoking a static function, primary exists and is not the current
10410      this, we're creating a new object. */
10411   if (ctxp->explicit_constructor_p 
10412       && !is_static_flag 
10413       && (!primary || primary == current_this)
10414       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
10415     {
10416       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
10417       PATCH_METHOD_RETURN_ERROR ();
10418     }
10419   java_parser_context_restore_global ();
10420   if (is_static) 
10421     *is_static = is_static_flag;
10422   /* Sometimes, we want the decl of the selected method. Such as for
10423      EH checking */
10424   if (ret_decl)
10425     *ret_decl = list;
10426   patch = patch_invoke (patch, list, args);
10427
10428   /* Now is a good time to insert the call to finit$ */
10429   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
10430     {
10431       tree finit_parms, finit_call;
10432       
10433       /* Prepare to pass hidden parameters to finit$, if any. */
10434       finit_parms = build_alias_initializer_parameter_list 
10435         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
10436       
10437       finit_call = 
10438         build_method_invocation (build_wfl_node (finit_identifier_node),
10439                                  finit_parms);
10440
10441       /* Generate the code used to initialize fields declared with an
10442          initialization statement and build a compound statement along
10443          with the super constructor invocation. */
10444       patch = build (COMPOUND_EXPR, void_type_node, patch,
10445                      java_complete_tree (finit_call));
10446       CAN_COMPLETE_NORMALLY (patch) = 1;
10447     }
10448   return patch;
10449 }
10450
10451 /* Check that we're not trying to do a static reference to a method in
10452    non static method. Return 1 if it's the case, 0 otherwise. */
10453
10454 static int
10455 check_for_static_method_reference (wfl, node, method, where, primary)
10456      tree wfl, node, method, where, primary;
10457 {
10458   if (METHOD_STATIC (current_function_decl) 
10459       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
10460     {
10461       char *fct_name = xstrdup (lang_printable_name (method, 0));
10462       parse_error_context 
10463         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
10464          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
10465          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
10466       free (fct_name);
10467       return 1;
10468     }
10469   return 0;
10470 }
10471
10472 /* Fix the invocation of *MDECL if necessary in the case of a
10473    invocation from an inner class. *THIS_ARG might be modified
10474    appropriately and an alternative access to *MDECL might be
10475    returned.  */
10476
10477 static int
10478 maybe_use_access_method (is_super_init, mdecl, this_arg)
10479      int is_super_init;
10480      tree *mdecl, *this_arg;
10481 {
10482   tree ctx;
10483   tree md = *mdecl, ta = *this_arg;
10484   int to_return = 0;
10485   int non_static_context = !METHOD_STATIC (md);
10486
10487   if (is_super_init 
10488       || DECL_CONTEXT (md) == current_class
10489       || !PURE_INNER_CLASS_TYPE_P (current_class) 
10490       || DECL_FINIT_P (md)
10491       || DECL_INSTINIT_P (md))
10492     return 0;
10493   
10494   /* If we're calling a method found in an enclosing class, generate
10495      what it takes to retrieve the right this. Don't do that if we're
10496      invoking a static method. Note that if MD's type is unrelated to
10497      CURRENT_CLASS, then the current this can be used. */
10498
10499   if (non_static_context && DECL_CONTEXT (md) != object_type_node)
10500     {
10501       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
10502       if (inherits_from_p (ctx, DECL_CONTEXT (md)))
10503         {
10504           ta = build_current_thisn (current_class);
10505           ta = build_wfl_node (ta);
10506         }
10507       else
10508         {
10509           tree type = ctx;
10510           while (type)
10511             {
10512               maybe_build_thisn_access_method (type);
10513               if (inherits_from_p (type, DECL_CONTEXT (md)))
10514                 {
10515                   ta = build_access_to_thisn (ctx, type, 0);
10516                   break;
10517                 }
10518               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
10519                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
10520             }
10521         }
10522       ta = java_complete_tree (ta);
10523     }
10524
10525   /* We might have to use an access method to get to MD. We can
10526      break the method access rule as far as we're not generating
10527      bytecode */
10528   if (METHOD_PRIVATE (md) && flag_emit_class_files)
10529     {
10530       md = build_outer_method_access_method (md);
10531       to_return = 1;
10532     }
10533
10534   *mdecl = md;
10535   *this_arg = ta;
10536
10537   /* Returnin a non zero value indicates we were doing a non static
10538      method invokation that is now a static invocation. It will have
10539      callee displace `this' to insert it in the regular argument
10540      list. */
10541   return (non_static_context && to_return);
10542 }
10543
10544 /* Patch an invoke expression METHOD and ARGS, based on its invocation
10545    mode.  */
10546
10547 static tree
10548 patch_invoke (patch, method, args)
10549      tree patch, method, args;
10550 {
10551   tree dtable, func;
10552   tree original_call, t, ta;
10553   tree check = NULL_TREE;
10554
10555   /* Last step for args: convert build-in types. If we're dealing with
10556      a new TYPE() type call, the first argument to the constructor
10557      isn't found in the incoming argument list, but delivered by
10558      `new' */
10559   t = TYPE_ARG_TYPES (TREE_TYPE (method));
10560   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10561     t = TREE_CHAIN (t);
10562   for (ta = args; t != end_params_node && ta; 
10563        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
10564     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
10565         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
10566       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
10567
10568   /* Resolve unresolved returned type isses */
10569   t = TREE_TYPE (TREE_TYPE (method));
10570   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
10571     resolve_and_layout (TREE_TYPE (t), NULL);
10572
10573   if (flag_emit_class_files || flag_emit_xref)
10574     func = method;
10575   else
10576     {
10577       tree signature = build_java_signature (TREE_TYPE (method));
10578       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
10579         {
10580         case INVOKE_VIRTUAL:
10581           dtable = invoke_build_dtable (0, args);
10582           func = build_invokevirtual (dtable, method);
10583           break;
10584
10585         case INVOKE_NONVIRTUAL:
10586           /* If the object for the method call is null, we throw an
10587              exception.  We don't do this if the object is the current
10588              method's `this'.  In other cases we just rely on an
10589              optimization pass to eliminate redundant checks.  */
10590           if (TREE_VALUE (args) != current_this)
10591             {
10592               /* We use a save_expr here to make sure we only evaluate
10593                  the new `self' expression once.  */
10594               tree save_arg = save_expr (TREE_VALUE (args));
10595               TREE_VALUE (args) = save_arg;
10596               check = java_check_reference (save_arg, 1);
10597             }
10598           /* Fall through.  */
10599
10600         case INVOKE_SUPER:
10601         case INVOKE_STATIC:
10602           func = build_known_method_ref (method, TREE_TYPE (method),
10603                                          DECL_CONTEXT (method),
10604                                          signature, args);
10605           break;
10606
10607         case INVOKE_INTERFACE:
10608           dtable = invoke_build_dtable (1, args);
10609           func = build_invokeinterface (dtable, method);
10610           break;
10611
10612         default:
10613           abort ();
10614         }
10615
10616       /* Ensure self_type is initialized, (invokestatic). FIXME */
10617       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
10618     }
10619
10620   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
10621   TREE_OPERAND (patch, 0) = func;
10622   TREE_OPERAND (patch, 1) = args;
10623   original_call = patch;
10624
10625   /* We're processing a `new TYPE ()' form. New is called and its
10626      returned value is the first argument to the constructor. We build
10627      a COMPOUND_EXPR and use saved expression so that the overall NEW
10628      expression value is a pointer to a newly created and initialized
10629      class. */
10630   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
10631     {
10632       tree class = DECL_CONTEXT (method);
10633       tree c1, saved_new, size, new;
10634       if (flag_emit_class_files || flag_emit_xref)
10635         {
10636           TREE_TYPE (patch) = build_pointer_type (class);
10637           return patch;
10638         }
10639       if (!TYPE_SIZE (class))
10640         safe_layout_class (class);
10641       size = size_in_bytes (class);
10642       new = build (CALL_EXPR, promote_type (class),
10643                    build_address_of (alloc_object_node),
10644                    tree_cons (NULL_TREE, build_class_ref (class),
10645                               build_tree_list (NULL_TREE, 
10646                                                size_in_bytes (class))),
10647                    NULL_TREE);
10648       saved_new = save_expr (new);
10649       c1 = build_tree_list (NULL_TREE, saved_new);
10650       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
10651       TREE_OPERAND (original_call, 1) = c1;
10652       TREE_SET_CODE (original_call, CALL_EXPR);
10653       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
10654     }
10655
10656   /* If CHECK is set, then we are building a check to see if the object
10657      is NULL.  */
10658   if (check != NULL_TREE)
10659     {
10660       patch = build (COMPOUND_EXPR, TREE_TYPE (patch), check, patch);
10661       TREE_SIDE_EFFECTS (patch) = 1;
10662     }
10663
10664   /* In order to be able to modify PATCH later, we SAVE_EXPR it and
10665      put it as the first expression of a COMPOUND_EXPR. The second
10666      expression being an empty statement to be later patched if
10667      necessary. We remember a TREE_LIST (the PURPOSE is the method,
10668      the VALUE is the compound) in a hashtable and return a
10669      COMPOUND_EXPR built so that the result of the evaluation of the
10670      original PATCH node is returned. */
10671   if (STATIC_CLASS_INIT_OPT_P ()
10672       && current_function_decl && METHOD_STATIC (method))
10673     {
10674       tree list;
10675       tree fndecl = current_function_decl;
10676       tree save = save_expr (patch);
10677       tree type = TREE_TYPE (patch);
10678
10679       patch = build (COMPOUND_EXPR, type, save, empty_stmt_node);
10680       list = build_tree_list (method, patch);
10681
10682       hash_lookup (&DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl),
10683                    (const hash_table_key) list, TRUE, NULL);
10684
10685       patch = build (COMPOUND_EXPR, type, patch, save);
10686     }
10687
10688   return patch;
10689 }
10690
10691 static int
10692 invocation_mode (method, super)
10693      tree method;
10694      int super;
10695 {
10696   int access = get_access_flags_from_decl (method);
10697
10698   if (super)
10699     return INVOKE_SUPER;
10700
10701   if (access & ACC_STATIC)
10702     return INVOKE_STATIC;
10703
10704   /* We have to look for a constructor before we handle nonvirtual
10705      calls; otherwise the constructor will look nonvirtual.  */
10706   if (DECL_CONSTRUCTOR_P (method))
10707     return INVOKE_STATIC;
10708
10709   if (access & ACC_FINAL || access & ACC_PRIVATE)
10710     return INVOKE_NONVIRTUAL;
10711
10712   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
10713     return INVOKE_NONVIRTUAL;
10714
10715   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
10716     return INVOKE_INTERFACE;
10717
10718   return INVOKE_VIRTUAL;
10719 }
10720
10721 /* Retrieve a refined list of matching methods. It covers the step
10722    15.11.2 (Compile-Time Step 2) */
10723
10724 static tree
10725 lookup_method_invoke (lc, cl, class, name, arg_list)
10726      int lc;
10727      tree cl;
10728      tree class, name, arg_list;
10729 {
10730   tree atl = end_params_node;           /* Arg Type List */
10731   tree method, signature, list, node;
10732   const char *candidates;               /* Used for error report */
10733   char *dup;
10734
10735   /* Fix the arguments */
10736   for (node = arg_list; node; node = TREE_CHAIN (node))
10737     {
10738       tree current_arg = TREE_TYPE (TREE_VALUE (node));
10739       /* Non primitive type may have to be resolved */
10740       if (!JPRIMITIVE_TYPE_P (current_arg))
10741         resolve_and_layout (current_arg, NULL_TREE);
10742       /* And promoted */
10743       if (TREE_CODE (current_arg) == RECORD_TYPE)
10744         current_arg = promote_type (current_arg);
10745       atl = tree_cons (NULL_TREE, current_arg, atl);
10746     }
10747
10748   /* Presto. If we're dealing with an anonymous class and a
10749      constructor call, generate the right constructor now, since we
10750      know the arguments' types. */
10751
10752   if (lc && ANONYMOUS_CLASS_P (class))
10753     craft_constructor (TYPE_NAME (class), atl);
10754
10755   /* Find all candidates and then refine the list, searching for the
10756      most specific method. */
10757   list = find_applicable_accessible_methods_list (lc, class, name, atl);
10758   list = find_most_specific_methods_list (list);
10759   if (list && !TREE_CHAIN (list))
10760     return TREE_VALUE (list);
10761
10762   /* Issue an error. List candidates if any. Candidates are listed
10763      only if accessible (non accessible methods may end-up here for
10764      the sake of a better error report). */
10765   candidates = NULL;
10766   if (list)
10767     {
10768       tree current;
10769       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
10770       for (current = list; current; current = TREE_CHAIN (current))
10771         {
10772           tree cm = TREE_VALUE (current);
10773           char string [4096];
10774           if (!cm || not_accessible_p (class, cm, NULL_TREE, 0))
10775             continue;
10776           sprintf 
10777             (string, "  `%s' in `%s'%s",
10778              get_printable_method_name (cm),
10779              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
10780              (TREE_CHAIN (current) ? "\n" : ""));
10781           obstack_grow (&temporary_obstack, string, strlen (string));
10782         }
10783       obstack_1grow (&temporary_obstack, '\0');
10784       candidates = obstack_finish (&temporary_obstack);
10785     }
10786   /* Issue the error message */
10787   method = make_node (FUNCTION_TYPE);
10788   TYPE_ARG_TYPES (method) = atl;
10789   signature = build_java_argument_signature (method);
10790   dup = xstrdup (lang_printable_name (class, 0));
10791   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
10792                        (lc ? "constructor" : "method"),
10793                        (lc ? dup : IDENTIFIER_POINTER (name)),
10794                        IDENTIFIER_POINTER (signature), dup,
10795                        (candidates ? candidates : ""));
10796   free (dup);
10797   return NULL_TREE;
10798 }
10799
10800 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
10801    when we're looking for a constructor. */
10802
10803 static tree
10804 find_applicable_accessible_methods_list (lc, class, name, arglist)
10805      int lc;
10806      tree class, name, arglist;
10807 {
10808   static struct hash_table t, *searched_classes = NULL;
10809   static int search_not_done = 0;
10810   tree list = NULL_TREE, all_list = NULL_TREE;
10811
10812   /* Check the hash table to determine if this class has been searched 
10813      already. */
10814   if (searched_classes)
10815     {
10816       if (hash_lookup (searched_classes, 
10817                       (const hash_table_key) class, FALSE, NULL))
10818        return NULL;
10819     }
10820   else
10821     {
10822       hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
10823                       java_hash_compare_tree_node);
10824       searched_classes = &t;
10825     }
10826     
10827   search_not_done++;
10828   hash_lookup (searched_classes, 
10829                (const hash_table_key) class, TRUE, NULL);
10830
10831   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
10832     {
10833       load_class (class, 1);
10834       safe_layout_class (class);
10835     }
10836
10837   /* Search interfaces */
10838   if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
10839       && CLASS_INTERFACE (TYPE_NAME (class)))
10840     {
10841       int i, n;
10842       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10843       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10844                                       name, arglist, &list, &all_list);
10845       n = TREE_VEC_LENGTH (basetype_vec);
10846       for (i = 1; i < n; i++)
10847         {
10848           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10849           tree rlist;
10850
10851           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
10852                                                            arglist);
10853           list = chainon (rlist, list);
10854         }
10855     }
10856   /* Search classes */
10857   else
10858     {
10859       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10860                                       name, arglist, &list, &all_list);
10861
10862       /* When looking finit$, class$ or instinit$, we turn LC to 1 so
10863          that we only search in class. Note that we should have found
10864          something at this point. */
10865       if (ID_FINIT_P (name) || ID_CLASSDOLLAR_P (name) || ID_INSTINIT_P (name))
10866         {
10867           lc = 1;
10868           if (!list)
10869             abort ();
10870         }
10871
10872       /* We must search all interfaces of this class */
10873       if (!lc)
10874       {
10875         tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10876         int n = TREE_VEC_LENGTH (basetype_vec), i;
10877         for (i = 1; i < n; i++)
10878           {
10879             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10880             if (t != object_type_node)
10881               {
10882                 tree rlist
10883                   = find_applicable_accessible_methods_list (lc, t,
10884                                                              name, arglist);
10885                 list = chainon (rlist, list);
10886               }
10887           }
10888       }
10889
10890       /* Search superclass */
10891       if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
10892         {
10893           tree rlist;
10894           class = CLASSTYPE_SUPER (class);
10895           rlist = find_applicable_accessible_methods_list (lc, class, 
10896                                                            name, arglist);
10897           list = chainon (rlist, list);
10898         }
10899     }
10900
10901   search_not_done--;
10902
10903   /* We're done. Reset the searched classes list and finally search
10904      java.lang.Object if it wasn't searched already. */
10905   if (!search_not_done)
10906     {
10907       if (!lc
10908           && TYPE_METHODS (object_type_node)
10909           && !hash_lookup (searched_classes, 
10910                            (const hash_table_key) object_type_node, 
10911                            FALSE, NULL))
10912         {
10913           search_applicable_methods_list (lc, 
10914                                           TYPE_METHODS (object_type_node),
10915                                           name, arglist, &list, &all_list);
10916         }
10917       hash_table_free (searched_classes);
10918       searched_classes = NULL;
10919     }
10920
10921   /* Either return the list obtained or all selected (but
10922      inaccessible) methods for better error report. */
10923   return (!list ? all_list : list);
10924 }
10925
10926 /* Effectively search for the appropriate method in method */
10927
10928 static void 
10929 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10930      int lc;
10931      tree method, name, arglist;
10932      tree *list, *all_list;
10933 {
10934   for (; method; method = TREE_CHAIN (method))
10935     {
10936       /* When dealing with constructor, stop here, otherwise search
10937          other classes */
10938       if (lc && !DECL_CONSTRUCTOR_P (method))
10939         continue;
10940       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10941                        || (DECL_NAME (method) != name)))
10942         continue;
10943
10944       if (argument_types_convertible (method, arglist))
10945         {
10946           /* Retain accessible methods only */
10947           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10948                                  method, NULL_TREE, 0))
10949             *list = tree_cons (NULL_TREE, method, *list);
10950           else
10951             /* Also retain all selected method here */
10952             *all_list = tree_cons (NULL_TREE, method, *list);
10953         }
10954     }
10955 }
10956
10957 /* 15.11.2.2 Choose the Most Specific Method */
10958
10959 static tree
10960 find_most_specific_methods_list (list)
10961      tree list;
10962 {
10963   int max = 0;
10964   int abstract, candidates;
10965   tree current, new_list = NULL_TREE;
10966   for (current = list; current; current = TREE_CHAIN (current))
10967     {
10968       tree method;
10969       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10970
10971       for (method = list; method; method = TREE_CHAIN (method))
10972         {
10973           tree method_v, current_v;
10974           /* Don't test a method against itself */
10975           if (method == current)
10976             continue;
10977
10978           method_v = TREE_VALUE (method);
10979           current_v = TREE_VALUE (current);
10980
10981           /* Compare arguments and location where methods where declared */
10982           if (argument_types_convertible (method_v, current_v))
10983             {
10984               if (valid_method_invocation_conversion_p 
10985                   (DECL_CONTEXT (method_v), DECL_CONTEXT (current_v))
10986                   || (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v))
10987                       && enclosing_context_p (DECL_CONTEXT (method_v),
10988                                               DECL_CONTEXT (current_v))))
10989                 {
10990                   int v = (DECL_SPECIFIC_COUNT (current_v) += 
10991                     (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v)) ? 2 : 1));
10992                   max = (v > max ? v : max);
10993                 }
10994             }
10995         }
10996     }
10997
10998   /* Review the list and select the maximally specific methods */
10999   for (current = list, abstract = -1, candidates = -1;
11000        current; current = TREE_CHAIN (current))
11001     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
11002       {
11003         new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
11004         abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
11005         candidates++;
11006       }
11007
11008   /* If we have several and they're all abstract, just pick the
11009      closest one. */
11010   if (candidates > 0 && (candidates == abstract))
11011     {
11012       new_list = nreverse (new_list);
11013       TREE_CHAIN (new_list) = NULL_TREE;
11014     }
11015
11016   /* We have several (we couldn't find a most specific), all but one
11017      are abstract, we pick the only non abstract one. */
11018   if (candidates > 0 && (candidates == abstract+1))
11019     {
11020       for (current = new_list; current; current = TREE_CHAIN (current))
11021         if (!METHOD_ABSTRACT (TREE_VALUE (current)))
11022           {
11023             TREE_CHAIN (current) = NULL_TREE;
11024             new_list = current;
11025           }
11026     }
11027
11028   /* If we can't find one, lower expectations and try to gather multiple
11029      maximally specific methods */
11030   while (!new_list && max)
11031     {
11032       while (--max > 0)
11033         {
11034           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
11035             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
11036         }
11037     }
11038
11039   return new_list;
11040 }
11041
11042 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
11043    converted by method invocation conversion (5.3) to the type of the
11044    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
11045    to change less often than M1. */
11046
11047 static int
11048 argument_types_convertible (m1, m2_or_arglist)
11049     tree m1, m2_or_arglist;
11050 {
11051   static tree m2_arg_value = NULL_TREE;
11052   static tree m2_arg_cache = NULL_TREE;
11053   static int initialized_p;
11054
11055   register tree m1_arg, m2_arg;
11056
11057   /* Register M2_ARG_VALUE and M2_ARG_CACHE with the garbage
11058      collector.  */
11059   if (!initialized_p)
11060     {
11061       ggc_add_tree_root (&m2_arg_value, 1);
11062       ggc_add_tree_root (&m2_arg_cache, 1);
11063       initialized_p = 1;
11064     }
11065
11066   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
11067
11068   if (m2_arg_value == m2_or_arglist)
11069     m2_arg = m2_arg_cache;
11070   else
11071     {
11072       /* M2_OR_ARGLIST can be a function DECL or a raw list of
11073          argument types */
11074       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
11075         {
11076           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
11077           if (!METHOD_STATIC (m2_or_arglist))
11078             m2_arg = TREE_CHAIN (m2_arg);
11079         }
11080       else
11081         m2_arg = m2_or_arglist;
11082
11083       m2_arg_value = m2_or_arglist;
11084       m2_arg_cache = m2_arg;
11085     }
11086
11087   while (m1_arg != end_params_node && m2_arg != end_params_node)
11088     {
11089       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
11090       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
11091                                                  TREE_VALUE (m2_arg)))
11092         break;
11093       m1_arg = TREE_CHAIN (m1_arg);
11094       m2_arg = TREE_CHAIN (m2_arg);
11095     }
11096   return m1_arg == end_params_node && m2_arg == end_params_node;
11097 }
11098
11099 /* Qualification routines */
11100
11101 static void
11102 qualify_ambiguous_name (id)
11103      tree id;
11104 {
11105   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
11106     saved_current_class;
11107   int again, super_found = 0, this_found = 0, new_array_found = 0;
11108   int code;
11109
11110   /* We first qualify the first element, then derive qualification of
11111      others based on the first one. If the first element is qualified
11112      by a resolution (field or type), this resolution is stored in the
11113      QUAL_RESOLUTION of the qual element being examined. We need to
11114      save the current_class since the use of SUPER might change the
11115      its value. */
11116   saved_current_class = current_class;
11117   qual = EXPR_WFL_QUALIFICATION (id);
11118   do {
11119
11120     /* Simple qualified expression feature a qual_wfl that is a
11121        WFL. Expression derived from a primary feature more complicated
11122        things like a CALL_EXPR. Expression from primary need to be
11123        worked out to extract the part on which the qualification will
11124        take place. */
11125     qual_wfl = QUAL_WFL (qual);
11126     switch (TREE_CODE (qual_wfl))
11127       {
11128       case CALL_EXPR:
11129         qual_wfl = TREE_OPERAND (qual_wfl, 0);
11130         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
11131           {
11132             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
11133             qual_wfl = QUAL_WFL (qual);
11134           }
11135         break;
11136       case NEW_ARRAY_EXPR:
11137       case NEW_ANONYMOUS_ARRAY_EXPR:
11138         qual = TREE_CHAIN (qual);
11139         again = new_array_found = 1;
11140         continue;
11141       case CONVERT_EXPR:
11142         break;
11143       case NEW_CLASS_EXPR:
11144         qual_wfl = TREE_OPERAND (qual_wfl, 0);
11145         break;
11146       case ARRAY_REF:
11147         while (TREE_CODE (qual_wfl) == ARRAY_REF)
11148           qual_wfl = TREE_OPERAND (qual_wfl, 0);
11149         break;
11150       case STRING_CST:
11151         qual = TREE_CHAIN (qual);
11152         qual_wfl = QUAL_WFL (qual);
11153         break;
11154       case CLASS_LITERAL:
11155         qual = TREE_CHAIN (qual);
11156         qual_wfl = QUAL_WFL (qual);
11157       break;
11158       default:
11159         /* Fix for -Wall. Just break doing nothing */
11160         break;
11161       }
11162
11163     ptr_type = current_class;
11164     again = 0;
11165     code = TREE_CODE (qual_wfl);
11166
11167     /* Pos evaluation: non WFL leading expression nodes */
11168     if (code == CONVERT_EXPR
11169         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
11170       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
11171
11172     else if (code == INTEGER_CST)
11173       name = qual_wfl;
11174     
11175     else if (code == CONVERT_EXPR &&
11176              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
11177       name = TREE_OPERAND (qual_wfl, 0);
11178     
11179     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
11180              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
11181       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
11182
11183     else if (code == TREE_LIST)
11184       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
11185
11186     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
11187              || code == PLUS_EXPR)
11188       {
11189         qual = TREE_CHAIN (qual);
11190         qual_wfl = QUAL_WFL (qual);
11191         again = 1;
11192       }
11193     else
11194       {
11195         name = EXPR_WFL_NODE (qual_wfl);
11196         if (!name)
11197           {
11198             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
11199             again = 1;
11200           }
11201       }
11202
11203     /* If we have a THIS (from a primary), we set the context accordingly */
11204     if (name == this_identifier_node)
11205       {
11206         /* This isn't really elegant. One more added irregularity
11207            before I start using COMPONENT_REF (hopefully very soon.)  */
11208         if (TREE_CODE (TREE_PURPOSE (qual)) == ARRAY_REF
11209             && TREE_CODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
11210                EXPR_WITH_FILE_LOCATION
11211             && EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) == 
11212                this_identifier_node)
11213             {
11214               qual = TREE_OPERAND (TREE_PURPOSE (qual), 0);
11215               qual = EXPR_WFL_QUALIFICATION (qual);
11216             }
11217         qual = TREE_CHAIN (qual);
11218         qual_wfl = QUAL_WFL (qual);
11219         if (TREE_CODE (qual_wfl) == CALL_EXPR)
11220           again = 1;
11221         else if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION)
11222           name = EXPR_WFL_NODE (qual_wfl);
11223         else if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
11224           name = TREE_OPERAND (qual_wfl, 0);
11225         this_found = 1;
11226       }
11227     /* If we have a SUPER, we set the context accordingly */
11228     if (name == super_identifier_node)
11229       {
11230         current_class = CLASSTYPE_SUPER (ptr_type);
11231         /* Check that there is such a thing as a super class. If not,
11232            return.  The error will be caught later on, during the
11233            resolution */
11234         if (!current_class)
11235           {
11236             current_class = saved_current_class;
11237             return;
11238           }
11239         qual = TREE_CHAIN (qual);
11240         /* Do one more interation to set things up */
11241         super_found = again = 1;
11242       }
11243   } while (again);
11244   
11245   /* If name appears within the scope of a local variable declaration
11246      or parameter declaration, then it is an expression name. We don't
11247      carry this test out if we're in the context of the use of SUPER
11248      or THIS */
11249   if (!this_found && !super_found 
11250       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
11251       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
11252     {
11253       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11254       QUAL_RESOLUTION (qual) = decl;
11255     }
11256
11257   /* If within the class/interface NAME was found to be used there
11258      exists a (possibly inherited) field named NAME, then this is an
11259      expression name. If we saw a NEW_ARRAY_EXPR before and want to
11260      address length, it is OK. */
11261   else if ((decl = lookup_field_wrapper (ptr_type, name))
11262            || name == length_identifier_node)
11263     {
11264       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11265       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
11266     }
11267
11268   /* We reclassify NAME as yielding to a type name resolution if:
11269      - NAME is a class/interface declared within the compilation
11270        unit containing NAME,
11271      - NAME is imported via a single-type-import declaration,
11272      - NAME is declared in an another compilation unit of the package
11273        of the compilation unit containing NAME,
11274      - NAME is declared by exactly on type-import-on-demand declaration
11275      of the compilation unit containing NAME. 
11276      - NAME is actually a STRING_CST.
11277      This can't happen if the expression was qualified by `this.' */
11278   else if (! this_found &&
11279            (TREE_CODE (name) == STRING_CST ||
11280             TREE_CODE (name) == INTEGER_CST ||
11281             (decl = resolve_and_layout (name, NULL_TREE))))
11282     {
11283       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
11284       QUAL_RESOLUTION (qual) = decl;
11285     }
11286
11287   /* Method call, array references and cast are expression name */
11288   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
11289            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
11290            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR
11291            || TREE_CODE (QUAL_WFL (qual)) == MODIFY_EXPR)
11292     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11293
11294   /* Check here that NAME isn't declared by more than one
11295      type-import-on-demand declaration of the compilation unit
11296      containing NAME. FIXME */
11297
11298   /* Otherwise, NAME is reclassified as a package name */
11299   else 
11300     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
11301
11302   /* Propagate the qualification accross other components of the
11303      qualified name */
11304   for (qual = TREE_CHAIN (qual); qual;
11305        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
11306     {
11307       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
11308         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
11309       else 
11310         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
11311     }
11312
11313   /* Store the global qualification for the ambiguous part of ID back
11314      into ID fields */
11315   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
11316     RESOLVE_EXPRESSION_NAME_P (id) = 1;
11317   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
11318     RESOLVE_TYPE_NAME_P (id) = 1;
11319   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
11320     RESOLVE_PACKAGE_NAME_P (id) = 1;
11321
11322   /* Restore the current class */
11323   current_class = saved_current_class;
11324 }
11325
11326 static int
11327 breakdown_qualified (left, right, source)
11328     tree *left, *right, source;
11329 {
11330   char *p, *base;
11331   int   l = IDENTIFIER_LENGTH (source);
11332
11333   base = alloca (l + 1);
11334   memcpy (base, IDENTIFIER_POINTER (source), l + 1);
11335
11336   /* Breakdown NAME into REMAINDER . IDENTIFIER */
11337   p = base + l - 1;
11338   while (*p != '.' && p != base)
11339     p--;
11340
11341   /* We didn't find a '.'. Return an error */
11342   if (p == base)
11343     return 1;
11344
11345   *p = '\0';
11346   if (right)
11347     *right = get_identifier (p+1);
11348   *left = get_identifier (base);
11349   
11350   return 0;
11351 }
11352
11353 /* Return TRUE if two classes are from the same package. */
11354
11355 static int
11356 in_same_package (name1, name2)
11357   tree name1, name2;
11358 {
11359   tree tmp;
11360   tree pkg1;
11361   tree pkg2;
11362   
11363   if (TREE_CODE (name1) == TYPE_DECL)
11364     name1 = DECL_NAME (name1);
11365   if (TREE_CODE (name2) == TYPE_DECL)
11366     name2 = DECL_NAME (name2);
11367
11368   if (QUALIFIED_P (name1) != QUALIFIED_P (name2))
11369     /* One in empty package. */
11370     return 0;
11371
11372   if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0)
11373     /* Both in empty package. */
11374     return 1;
11375
11376   breakdown_qualified (&pkg1, &tmp, name1);
11377   breakdown_qualified (&pkg2, &tmp, name2);
11378   
11379   return (pkg1 == pkg2);
11380 }
11381
11382 /* Patch tree nodes in a function body. When a BLOCK is found, push
11383    local variable decls if present.
11384    Same as java_complete_lhs, but does resolve static finals to values. */
11385
11386 static tree
11387 java_complete_tree (node)
11388      tree node;
11389 {
11390   node = java_complete_lhs (node);
11391   if (JDECL_P (node) && CLASS_FINAL_VARIABLE_P (node)
11392       && DECL_INITIAL (node) != NULL_TREE
11393       && !flag_emit_xref)
11394     {
11395       tree value = DECL_INITIAL (node);
11396       DECL_INITIAL (node) = NULL_TREE;
11397       value = fold_constant_for_init (value, node);
11398       DECL_INITIAL (node) = value;
11399       if (value != NULL_TREE)
11400         {
11401           /* fold_constant_for_init sometimes widen the original type
11402              of the constant (i.e. byte to int.) It's not desirable,
11403              especially if NODE is a function argument. */
11404           if (TREE_CODE (value) == INTEGER_CST
11405               && TREE_TYPE (node) != TREE_TYPE (value))
11406             return convert (TREE_TYPE (node), value);
11407           else
11408             return value;
11409         }
11410       else
11411         DECL_FIELD_FINAL_IUD (node) = 0;
11412     }
11413   return node;
11414 }
11415
11416 static tree
11417 java_stabilize_reference (node)
11418      tree node;
11419 {
11420   if (TREE_CODE (node) == COMPOUND_EXPR)
11421     {
11422       tree op0 = TREE_OPERAND (node, 0);
11423       tree op1 = TREE_OPERAND (node, 1);
11424       TREE_OPERAND (node, 0) = save_expr (op0);
11425       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
11426       return node;
11427     }
11428   return stabilize_reference (node);
11429 }
11430
11431 /* Patch tree nodes in a function body. When a BLOCK is found, push
11432    local variable decls if present.
11433    Same as java_complete_tree, but does not resolve static finals to values. */
11434
11435 static tree
11436 java_complete_lhs (node)
11437      tree node;
11438 {
11439   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
11440   int flag;
11441
11442   /* CONVERT_EXPR always has its type set, even though it needs to be
11443      worked out. */
11444   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
11445     return node;
11446
11447   /* The switch block implements cases processing container nodes
11448      first.  Contained nodes are always written back. Leaves come
11449      next and return a value. */
11450   switch (TREE_CODE (node))
11451     {
11452     case BLOCK:
11453
11454       /* 1- Block section.
11455          Set the local values on decl names so we can identify them
11456          faster when they're referenced. At that stage, identifiers
11457          are legal so we don't check for declaration errors. */
11458       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11459         {
11460           DECL_CONTEXT (cn) = current_function_decl;
11461           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
11462         }
11463       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
11464           CAN_COMPLETE_NORMALLY (node) = 1;
11465       else
11466         {
11467           tree stmt = BLOCK_EXPR_BODY (node);
11468           tree *ptr;
11469           int error_seen = 0;
11470           if (TREE_CODE (stmt) == COMPOUND_EXPR)
11471             {
11472               /* Re-order from (((A; B); C); ...; Z) to 
11473                  (A; (B; (C ; (...; Z)))).
11474                  This makes it easier to scan the statements left-to-right
11475                  without using recursion (which might overflow the stack
11476                  if the block has many statements. */
11477               for (;;)
11478                 {
11479                   tree left = TREE_OPERAND (stmt, 0);
11480                   if (TREE_CODE (left) != COMPOUND_EXPR)
11481                     break;
11482                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
11483                   TREE_OPERAND (left, 1) = stmt;
11484                   stmt = left;
11485                 }
11486               BLOCK_EXPR_BODY (node) = stmt;
11487             }
11488
11489           /* Now do the actual complete, without deep recursion for
11490              long blocks. */
11491           ptr = &BLOCK_EXPR_BODY (node);
11492           while (TREE_CODE (*ptr) == COMPOUND_EXPR
11493                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
11494             {
11495               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
11496               tree *next = &TREE_OPERAND (*ptr, 1);
11497               TREE_OPERAND (*ptr, 0) = cur;
11498               if (cur == empty_stmt_node)
11499                 {
11500                   /* Optimization;  makes it easier to detect empty bodies.
11501                      Most useful for <clinit> with all-constant initializer. */
11502                   *ptr = *next;
11503                   continue;
11504                 }
11505               if (TREE_CODE (cur) == ERROR_MARK)
11506                 error_seen++;
11507               else if (! CAN_COMPLETE_NORMALLY (cur))
11508                 {
11509                   wfl_op2 = *next;
11510                   for (;;)
11511                     {
11512                       if (TREE_CODE (wfl_op2) == BLOCK)
11513                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
11514                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
11515                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
11516                       else
11517                         break;
11518                     }
11519                   if (TREE_CODE (wfl_op2) != CASE_EXPR
11520                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
11521                     unreachable_stmt_error (*ptr);
11522                 }
11523               ptr = next;
11524             }
11525           *ptr = java_complete_tree (*ptr);
11526
11527           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
11528             return error_mark_node;
11529           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
11530         }
11531       /* Turn local bindings to null */
11532       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11533         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
11534
11535       TREE_TYPE (node) = void_type_node;
11536       break;
11537
11538       /* 2- They are expressions but ultimately deal with statements */
11539
11540     case THROW_EXPR:
11541       wfl_op1 = TREE_OPERAND (node, 0);
11542       COMPLETE_CHECK_OP_0 (node);
11543       /* 14.19 A throw statement cannot complete normally. */
11544       CAN_COMPLETE_NORMALLY (node) = 0;
11545       return patch_throw_statement (node, wfl_op1);
11546
11547     case SYNCHRONIZED_EXPR:
11548       wfl_op1 = TREE_OPERAND (node, 0);
11549       return patch_synchronized_statement (node, wfl_op1);
11550
11551     case TRY_EXPR:
11552       return patch_try_statement (node);
11553
11554     case TRY_FINALLY_EXPR:
11555       COMPLETE_CHECK_OP_0 (node);
11556       COMPLETE_CHECK_OP_1 (node);
11557       if (TREE_OPERAND (node, 0) == empty_stmt_node)
11558         return TREE_OPERAND (node, 1);
11559       if (TREE_OPERAND (node, 1) == empty_stmt_node)
11560         return TREE_OPERAND (node, 0);
11561       CAN_COMPLETE_NORMALLY (node)
11562         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
11563            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
11564       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
11565       return node;
11566
11567     case CLEANUP_POINT_EXPR:
11568       COMPLETE_CHECK_OP_0 (node);
11569       TREE_TYPE (node) = void_type_node;
11570       CAN_COMPLETE_NORMALLY (node) = 
11571         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
11572       return node;
11573
11574     case WITH_CLEANUP_EXPR:
11575       COMPLETE_CHECK_OP_0 (node);
11576       COMPLETE_CHECK_OP_1 (node);
11577       CAN_COMPLETE_NORMALLY (node) = 
11578         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
11579       TREE_TYPE (node) = void_type_node;
11580       return node;
11581
11582     case LABELED_BLOCK_EXPR:
11583       PUSH_LABELED_BLOCK (node);
11584       if (LABELED_BLOCK_BODY (node))
11585         COMPLETE_CHECK_OP_1 (node);
11586       TREE_TYPE (node) = void_type_node;
11587       POP_LABELED_BLOCK ();
11588
11589       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
11590         {
11591           LABELED_BLOCK_BODY (node) = NULL_TREE;
11592           CAN_COMPLETE_NORMALLY (node) = 1;
11593         }
11594       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
11595         CAN_COMPLETE_NORMALLY (node) = 1;
11596       return node;
11597
11598     case EXIT_BLOCK_EXPR:
11599       /* We don't complete operand 1, because it's the return value of
11600          the EXIT_BLOCK_EXPR which doesn't exist it Java */
11601       return patch_bc_statement (node);
11602
11603     case CASE_EXPR:
11604       cn = java_complete_tree (TREE_OPERAND (node, 0));
11605       if (cn == error_mark_node)
11606         return cn;
11607
11608       /* First, the case expression must be constant. Values of final
11609          fields are accepted. */
11610       cn = fold (cn);
11611       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
11612           && JDECL_P (TREE_OPERAND (cn, 1))
11613           && FIELD_FINAL (TREE_OPERAND (cn, 1))
11614           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
11615         {
11616           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
11617                                        TREE_OPERAND (cn, 1));
11618         }
11619
11620       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
11621         {
11622           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11623           parse_error_context (node, "Constant expression required");
11624           return error_mark_node;
11625         }
11626
11627       nn = ctxp->current_loop;
11628
11629       /* It must be assignable to the type of the switch expression. */
11630       if (!try_builtin_assignconv (NULL_TREE, 
11631                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
11632         {
11633           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11634           parse_error_context 
11635             (wfl_operator,
11636              "Incompatible type for case. Can't convert `%s' to `int'",
11637              lang_printable_name (TREE_TYPE (cn), 0));
11638           return error_mark_node;
11639         }
11640
11641       cn = fold (convert (int_type_node, cn));
11642       TREE_CONSTANT_OVERFLOW (cn) = 0;
11643       CAN_COMPLETE_NORMALLY (cn) = 1;
11644
11645       /* Multiple instance of a case label bearing the same
11646          value is checked during code generation. The case
11647          expression is allright so far. */
11648       if (TREE_CODE (cn) == VAR_DECL)
11649         cn = DECL_INITIAL (cn);
11650       TREE_OPERAND (node, 0) = cn;
11651       TREE_TYPE (node) = void_type_node;
11652       CAN_COMPLETE_NORMALLY (node) = 1;
11653       TREE_SIDE_EFFECTS (node) = 1;
11654       break;
11655
11656     case DEFAULT_EXPR:
11657       nn = ctxp->current_loop;
11658       /* Only one default label is allowed per switch statement */
11659       if (SWITCH_HAS_DEFAULT (nn))
11660         {
11661           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11662           parse_error_context (wfl_operator, 
11663                                "Duplicate case label: `default'");
11664           return error_mark_node;
11665         }
11666       else
11667         SWITCH_HAS_DEFAULT (nn) = 1;
11668       TREE_TYPE (node) = void_type_node;
11669       TREE_SIDE_EFFECTS (node) = 1;
11670       CAN_COMPLETE_NORMALLY (node) = 1;
11671       break;
11672
11673     case SWITCH_EXPR:
11674     case LOOP_EXPR:
11675       PUSH_LOOP (node);
11676       /* Check whether the loop was enclosed in a labeled
11677          statement. If not, create one, insert the loop in it and
11678          return the node */
11679       nn = patch_loop_statement (node);
11680
11681       /* Anyways, walk the body of the loop */
11682       if (TREE_CODE (node) == LOOP_EXPR)
11683         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11684       /* Switch statement: walk the switch expression and the cases */
11685       else
11686         node = patch_switch_statement (node);
11687
11688       if (node == error_mark_node || TREE_OPERAND (node, 0) == error_mark_node)
11689         nn = error_mark_node;
11690       else
11691         {
11692           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
11693           /* If we returned something different, that's because we
11694              inserted a label. Pop the label too. */
11695           if (nn != node)
11696             {
11697               if (CAN_COMPLETE_NORMALLY (node))
11698                 CAN_COMPLETE_NORMALLY (nn) = 1;
11699               POP_LABELED_BLOCK ();
11700             }
11701         }
11702       POP_LOOP ();
11703       return nn;
11704
11705     case EXIT_EXPR:
11706       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11707       return patch_exit_expr (node);
11708
11709     case COND_EXPR:
11710       /* Condition */
11711       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11712       if (TREE_OPERAND (node, 0) == error_mark_node)
11713         return error_mark_node;
11714       /* then-else branches */
11715       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11716       if (TREE_OPERAND (node, 1) == error_mark_node)
11717         return error_mark_node;
11718       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
11719       if (TREE_OPERAND (node, 2) == error_mark_node)
11720         return error_mark_node;
11721       return patch_if_else_statement (node);
11722       break;
11723
11724     case CONDITIONAL_EXPR:
11725       /* Condition */
11726       wfl_op1 = TREE_OPERAND (node, 0);
11727       COMPLETE_CHECK_OP_0 (node);
11728       wfl_op2 = TREE_OPERAND (node, 1);
11729       COMPLETE_CHECK_OP_1 (node);
11730       wfl_op3 = TREE_OPERAND (node, 2);
11731       COMPLETE_CHECK_OP_2 (node);
11732       return patch_conditional_expr (node, wfl_op1, wfl_op2);
11733
11734       /* 3- Expression section */
11735     case COMPOUND_EXPR:
11736       wfl_op2 = TREE_OPERAND (node, 1);
11737       TREE_OPERAND (node, 0) = nn = 
11738         java_complete_tree (TREE_OPERAND (node, 0));
11739       if (wfl_op2 == empty_stmt_node)
11740         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
11741       else
11742         {
11743           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
11744             {
11745               /* An unreachable condition in a do-while statement
11746                  is *not* (technically) an unreachable statement. */
11747               nn = wfl_op2;
11748               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
11749                 nn = EXPR_WFL_NODE (nn);
11750               if (TREE_CODE (nn) != EXIT_EXPR)
11751                 {
11752                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
11753                   parse_error_context (wfl_operator, "Unreachable statement");
11754                 }
11755             }
11756           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11757           if (TREE_OPERAND (node, 1) == error_mark_node)
11758             return error_mark_node;
11759           CAN_COMPLETE_NORMALLY (node)
11760             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
11761         }
11762       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
11763       break;
11764
11765     case RETURN_EXPR:
11766       /* CAN_COMPLETE_NORMALLY (node) = 0; */
11767       return patch_return (node);
11768
11769     case EXPR_WITH_FILE_LOCATION:
11770       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11771           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11772         {
11773           tree wfl = node;
11774           node = resolve_expression_name (node, NULL);
11775           if (node == error_mark_node)
11776             return node;
11777           /* Keep line number information somewhere were it doesn't
11778              disrupt the completion process. */
11779           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
11780             {
11781               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
11782               TREE_OPERAND (node, 1) = wfl;
11783             }
11784           CAN_COMPLETE_NORMALLY (node) = 1;
11785         }
11786       else
11787         {
11788           tree body;
11789           int save_lineno = lineno;
11790           lineno = EXPR_WFL_LINENO (node);
11791           body = java_complete_tree (EXPR_WFL_NODE (node));
11792           lineno = save_lineno;
11793           EXPR_WFL_NODE (node) = body;
11794           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
11795           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
11796           if (body == empty_stmt_node || TREE_CONSTANT (body))
11797             {
11798               /* Makes it easier to constant fold, detect empty bodies. */
11799               return body;
11800             }
11801           if (body == error_mark_node)
11802             {
11803               /* Its important for the evaluation of assignment that
11804                  this mark on the TREE_TYPE is propagated. */
11805               TREE_TYPE (node) = error_mark_node;
11806               return error_mark_node;
11807             }
11808           else
11809             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
11810           
11811         }
11812       break;
11813
11814     case NEW_ARRAY_EXPR:
11815       /* Patch all the dimensions */
11816       flag = 0;
11817       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11818         {
11819           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
11820           tree dim = convert (int_type_node, 
11821                               java_complete_tree (TREE_VALUE (cn)));
11822           if (dim == error_mark_node)
11823             {
11824               flag = 1;
11825               continue;
11826             }
11827           else
11828             {
11829               TREE_VALUE (cn) = dim;
11830               /* Setup the location of the current dimension, for
11831                  later error report. */
11832               TREE_PURPOSE (cn) = 
11833                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
11834               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
11835             }
11836         }
11837       /* They complete the array creation expression, if no errors
11838          were found. */
11839       CAN_COMPLETE_NORMALLY (node) = 1;
11840       return (flag ? error_mark_node
11841               : force_evaluation_order (patch_newarray (node)));
11842
11843     case NEW_ANONYMOUS_ARRAY_EXPR:
11844       /* Create the array type if necessary. */
11845       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
11846         {
11847           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
11848           if (!(type = resolve_type_during_patch (type)))
11849             return error_mark_node;
11850           type = build_array_from_name (type, NULL_TREE,
11851                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
11852           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
11853         }
11854       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
11855                                    ANONYMOUS_ARRAY_INITIALIZER (node));
11856       if (node == error_mark_node)
11857         return error_mark_node;
11858       CAN_COMPLETE_NORMALLY (node) = 1;
11859       return node;
11860
11861     case NEW_CLASS_EXPR:
11862     case CALL_EXPR:
11863       /* Complete function's argument(s) first */
11864       if (complete_function_arguments (node))
11865         return error_mark_node;
11866       else
11867         {
11868           tree decl, wfl = TREE_OPERAND (node, 0);
11869           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
11870           int from_super = (EXPR_WFL_NODE (TREE_OPERAND (node, 0)) ==
11871                            super_identifier_node);
11872
11873           node = patch_method_invocation (node, NULL_TREE, NULL_TREE,
11874                                           from_super, 0, &decl);
11875           if (node == error_mark_node)
11876             return error_mark_node;
11877
11878           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
11879           /* If we call this(...), register signature and positions */
11880           if (in_this)
11881             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
11882               tree_cons (wfl, decl, 
11883                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
11884           CAN_COMPLETE_NORMALLY (node) = 1;
11885           return force_evaluation_order (node);
11886         }
11887
11888     case MODIFY_EXPR:
11889       /* Save potential wfls */
11890       wfl_op1 = TREE_OPERAND (node, 0);
11891       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
11892       
11893       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
11894           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
11895           && DECL_INITIAL (nn) != NULL_TREE)
11896         {
11897           tree value;
11898           
11899           value = fold_constant_for_init (nn, nn);
11900
11901           if (value != NULL_TREE)
11902             {
11903               tree type = TREE_TYPE (value);
11904               if (JPRIMITIVE_TYPE_P (type) || 
11905                   (type == string_ptr_type_node && ! flag_emit_class_files))
11906                 return empty_stmt_node;
11907             }
11908           if (! flag_emit_class_files)
11909             DECL_INITIAL (nn) = NULL_TREE;
11910           if (CLASS_FINAL_VARIABLE_P (nn))
11911             DECL_FIELD_FINAL_IUD (nn) = 0;
11912         }
11913       wfl_op2 = TREE_OPERAND (node, 1);
11914
11915       if (TREE_OPERAND (node, 0) == error_mark_node)
11916         return error_mark_node;
11917
11918       flag = COMPOUND_ASSIGN_P (wfl_op2);
11919       if (flag)
11920         {
11921           /* This might break when accessing outer field from inner
11922              class. TESTME, FIXME */
11923           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
11924
11925           /* Hand stabilize the lhs on both places */
11926           TREE_OPERAND (node, 0) = lvalue;
11927           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
11928             (flag_emit_class_files ? lvalue : save_expr (lvalue));
11929
11930           /* 15.25.2.a: Left hand is not an array access. FIXME */
11931           /* Now complete the RHS. We write it back later on. */
11932           nn = java_complete_tree (TREE_OPERAND (node, 1));
11933
11934           if ((cn = patch_string (nn)))
11935             nn = cn;
11936
11937           /* The last part of the rewrite for E1 op= E2 is to have 
11938              E1 = (T)(E1 op E2), with T being the type of E1. */
11939           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
11940                                                TREE_TYPE (lvalue), nn));
11941
11942           /* If the assignment is compound and has reference type,
11943              then ensure the LHS has type String and nothing else.  */
11944           if (JREFERENCE_TYPE_P (TREE_TYPE (lvalue))
11945               && ! JSTRING_TYPE_P (TREE_TYPE (lvalue)))
11946             parse_error_context (wfl_op2,
11947                                  "Incompatible type for `+='. Can't convert `%s' to `java.lang.String'",
11948                                  lang_printable_name (TREE_TYPE (lvalue), 0));
11949
11950           /* 15.25.2.b: Left hand is an array access. FIXME */
11951         }
11952
11953       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
11954          function to complete this RHS. Note that a NEW_ARRAY_INIT
11955          might have been already fully expanded if created as a result
11956          of processing an anonymous array initializer. We avoid doing
11957          the operation twice by testing whether the node already bears
11958          a type. */
11959       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
11960         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
11961                                    TREE_OPERAND (node, 1));
11962       /* Otherwise we simply complete the RHS */
11963       else
11964         nn = java_complete_tree (TREE_OPERAND (node, 1));
11965
11966       if (nn == error_mark_node)
11967         return error_mark_node;
11968
11969       /* Write back the RHS as we evaluated it. */
11970       TREE_OPERAND (node, 1) = nn;
11971
11972       /* In case we're handling = with a String as a RHS, we need to
11973          produce a String out of the RHS (it might still be a
11974          STRING_CST or a StringBuffer at this stage */
11975       if ((nn = patch_string (TREE_OPERAND (node, 1))))
11976         TREE_OPERAND (node, 1) = nn;
11977
11978       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
11979                                         TREE_OPERAND (node, 1))))
11980         {
11981           /* We return error_mark_node if outer_field_access_fix
11982              detects we write into a final. */
11983           if (nn == error_mark_node)
11984             return error_mark_node;
11985           node = nn;
11986         }
11987       else
11988         {
11989           node = patch_assignment (node, wfl_op1, wfl_op2);
11990           /* Reorganize the tree if necessary. */
11991           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
11992                        || JSTRING_P (TREE_TYPE (node))))
11993             node = java_refold (node);
11994         }
11995       
11996       CAN_COMPLETE_NORMALLY (node) = 1;
11997       return node;
11998
11999     case MULT_EXPR:
12000     case PLUS_EXPR:
12001     case MINUS_EXPR:
12002     case LSHIFT_EXPR:
12003     case RSHIFT_EXPR:
12004     case URSHIFT_EXPR:
12005     case BIT_AND_EXPR:
12006     case BIT_XOR_EXPR:
12007     case BIT_IOR_EXPR:
12008     case TRUNC_MOD_EXPR:
12009     case TRUNC_DIV_EXPR:
12010     case RDIV_EXPR:
12011     case TRUTH_ANDIF_EXPR:
12012     case TRUTH_ORIF_EXPR:
12013     case EQ_EXPR: 
12014     case NE_EXPR:
12015     case GT_EXPR:
12016     case GE_EXPR:
12017     case LT_EXPR:
12018     case LE_EXPR:
12019       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
12020          knows how to handle those cases. */
12021       wfl_op1 = TREE_OPERAND (node, 0);
12022       wfl_op2 = TREE_OPERAND (node, 1);
12023
12024       CAN_COMPLETE_NORMALLY (node) = 1;
12025       /* Don't complete string nodes if dealing with the PLUS operand. */
12026       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
12027         {
12028           nn = java_complete_tree (wfl_op1);
12029           if (nn == error_mark_node)
12030             return error_mark_node;
12031
12032           TREE_OPERAND (node, 0) = nn;
12033         }
12034       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
12035         {
12036           nn = java_complete_tree (wfl_op2);
12037           if (nn == error_mark_node)
12038             return error_mark_node;
12039
12040           TREE_OPERAND (node, 1) = nn;
12041         }
12042       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
12043
12044     case INSTANCEOF_EXPR:
12045       wfl_op1 = TREE_OPERAND (node, 0);
12046       COMPLETE_CHECK_OP_0 (node);
12047       if (flag_emit_xref)
12048         {
12049           TREE_TYPE (node) = boolean_type_node;
12050           return node;
12051         }
12052       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
12053
12054     case UNARY_PLUS_EXPR:
12055     case NEGATE_EXPR:
12056     case TRUTH_NOT_EXPR:
12057     case BIT_NOT_EXPR:
12058     case PREDECREMENT_EXPR:
12059     case PREINCREMENT_EXPR:
12060     case POSTDECREMENT_EXPR:
12061     case POSTINCREMENT_EXPR:
12062     case CONVERT_EXPR:
12063       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
12064          how to handle those cases. */
12065       wfl_op1 = TREE_OPERAND (node, 0);
12066       CAN_COMPLETE_NORMALLY (node) = 1;
12067       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
12068       if (TREE_OPERAND (node, 0) == error_mark_node)
12069         return error_mark_node;
12070       node = patch_unaryop (node, wfl_op1);
12071       CAN_COMPLETE_NORMALLY (node) = 1;
12072       break;
12073
12074     case ARRAY_REF:
12075       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
12076          how to handle those cases. */
12077       wfl_op1 = TREE_OPERAND (node, 0);
12078       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
12079       if (TREE_OPERAND (node, 0) == error_mark_node)
12080         return error_mark_node;
12081       if (!flag_emit_class_files && !flag_emit_xref)
12082         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
12083       /* The same applies to wfl_op2 */
12084       wfl_op2 = TREE_OPERAND (node, 1);
12085       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
12086       if (TREE_OPERAND (node, 1) == error_mark_node)
12087         return error_mark_node;
12088       if (!flag_emit_class_files && !flag_emit_xref)
12089         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
12090       return patch_array_ref (node);
12091
12092     case RECORD_TYPE:
12093       return node;;
12094
12095     case COMPONENT_REF:
12096       /* The first step in the re-write of qualified name handling.  FIXME.
12097          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
12098       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
12099       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
12100         {
12101           tree name = TREE_OPERAND (node, 1);
12102           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
12103           if (field == NULL_TREE)
12104             {
12105               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
12106               return error_mark_node;
12107             }
12108           if (! FIELD_STATIC (field))
12109             {
12110               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
12111               return error_mark_node;
12112             }
12113           return field;
12114         }
12115       else
12116         abort ();
12117       break;
12118
12119     case THIS_EXPR:
12120       /* Can't use THIS in a static environment */
12121       if (!current_this)
12122         {
12123           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12124           parse_error_context (wfl_operator,
12125                                "Keyword `this' used outside allowed context");
12126           TREE_TYPE (node) = error_mark_node;
12127           return error_mark_node;
12128         }
12129       if (ctxp->explicit_constructor_p)
12130         {
12131           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12132           parse_error_context 
12133             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
12134           TREE_TYPE (node) = error_mark_node;
12135           return error_mark_node;
12136         }
12137       return current_this;
12138       
12139     case CLASS_LITERAL:
12140       CAN_COMPLETE_NORMALLY (node) = 1;
12141       node = patch_incomplete_class_ref (node);
12142       if (node == error_mark_node)
12143         return error_mark_node;
12144       break;
12145
12146     default:
12147       CAN_COMPLETE_NORMALLY (node) = 1;
12148       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
12149          and it's time to turn it into the appropriate String object */
12150       if ((nn = patch_string (node)))
12151         node = nn;
12152       else
12153         internal_error ("No case for %s", tree_code_name [TREE_CODE (node)]);
12154     }
12155   return node;
12156 }
12157
12158 /* Complete function call's argument. Return a non zero value is an
12159    error was found.  */
12160
12161 static int
12162 complete_function_arguments (node)
12163      tree node;
12164 {
12165   int flag = 0;
12166   tree cn;
12167
12168   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
12169   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
12170     {
12171       tree wfl = TREE_VALUE (cn), parm, temp;
12172       parm = java_complete_tree (wfl);
12173
12174       if (parm == error_mark_node)
12175         {
12176           flag = 1;
12177           continue;
12178         }
12179       /* If have a string literal that we haven't transformed yet or a
12180          crafted string buffer, as a result of use of the the String
12181          `+' operator. Build `parm.toString()' and expand it. */
12182       if ((temp = patch_string (parm)))
12183         parm = temp;
12184       /* Inline PRIMTYPE.TYPE read access */
12185       parm = maybe_build_primttype_type_ref (parm, wfl);
12186
12187       TREE_VALUE (cn) = parm;
12188     }
12189   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
12190   return flag;
12191 }
12192
12193 /* Sometimes (for loops and variable initialized during their
12194    declaration), we want to wrap a statement around a WFL and turn it
12195    debugable.  */
12196
12197 static tree
12198 build_debugable_stmt (location, stmt)
12199     int location;
12200     tree stmt;
12201 {
12202   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
12203     {
12204       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
12205       EXPR_WFL_LINECOL (stmt) = location;
12206     }
12207   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
12208   return stmt;
12209 }
12210
12211 static tree
12212 build_expr_block (body, decls)
12213      tree body, decls;
12214 {
12215   tree node = make_node (BLOCK);
12216   BLOCK_EXPR_DECLS (node) = decls;
12217   BLOCK_EXPR_BODY (node) = body;
12218   if (body)
12219     TREE_TYPE (node) = TREE_TYPE (body);
12220   TREE_SIDE_EFFECTS (node) = 1;
12221   return node;
12222 }
12223
12224 /* Create a new function block and link it approriately to current
12225    function block chain */
12226
12227 static tree
12228 enter_block ()
12229 {
12230   tree b = build_expr_block (NULL_TREE, NULL_TREE);
12231
12232   /* Link block B supercontext to the previous block. The current
12233      function DECL is used as supercontext when enter_a_block is called
12234      for the first time for a given function. The current function body
12235      (DECL_FUNCTION_BODY) is set to be block B.  */
12236
12237   tree fndecl = current_function_decl; 
12238
12239   if (!fndecl) {
12240     BLOCK_SUPERCONTEXT (b) = current_static_block;
12241     current_static_block = b;
12242   }
12243
12244   else if (!DECL_FUNCTION_BODY (fndecl))
12245     {
12246       BLOCK_SUPERCONTEXT (b) = fndecl;
12247       DECL_FUNCTION_BODY (fndecl) = b;
12248     }
12249   else
12250     {
12251       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
12252       DECL_FUNCTION_BODY (fndecl) = b;
12253     }
12254   return b;
12255 }
12256
12257 /* Exit a block by changing the current function body
12258    (DECL_FUNCTION_BODY) to the current block super context, only if
12259    the block being exited isn't the method's top level one.  */
12260
12261 static tree
12262 exit_block ()
12263 {
12264   tree b;
12265   if (current_function_decl)
12266     {
12267       b = DECL_FUNCTION_BODY (current_function_decl);
12268       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
12269         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
12270     }
12271   else
12272     {
12273       b = current_static_block;
12274
12275       if (BLOCK_SUPERCONTEXT (b))
12276         current_static_block = BLOCK_SUPERCONTEXT (b);
12277     }
12278   return b;
12279 }
12280
12281 /* Lookup for NAME in the nested function's blocks, all the way up to
12282    the current toplevel one. It complies with Java's local variable
12283    scoping rules.  */
12284
12285 static tree
12286 lookup_name_in_blocks (name)
12287      tree name;
12288 {
12289   tree b = GET_CURRENT_BLOCK (current_function_decl);
12290
12291   while (b != current_function_decl)
12292     {
12293       tree current;
12294
12295       /* Paranoid sanity check. To be removed */
12296       if (TREE_CODE (b) != BLOCK)
12297         abort ();
12298
12299       for (current = BLOCK_EXPR_DECLS (b); current; 
12300            current = TREE_CHAIN (current))
12301         if (DECL_NAME (current) == name)
12302           return current;
12303       b = BLOCK_SUPERCONTEXT (b);
12304     }
12305   return NULL_TREE;
12306 }
12307
12308 static void
12309 maybe_absorb_scoping_blocks ()
12310 {
12311   while (BLOCK_IS_IMPLICIT (GET_CURRENT_BLOCK (current_function_decl)))
12312     {
12313       tree b = exit_block ();
12314       java_method_add_stmt (current_function_decl, b);
12315       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
12316     }
12317 }
12318
12319 \f
12320 /* This section of the source is reserved to build_* functions that
12321    are building incomplete tree nodes and the patch_* functions that
12322    are completing them.  */
12323
12324 /* Wrap a non WFL node around a WFL.  */
12325
12326 static tree
12327 build_wfl_wrap (node, location)
12328     tree node;
12329     int location;
12330 {
12331   tree wfl, node_to_insert = node;
12332   
12333   /* We want to process THIS . xxx symbolicaly, to keep it consistent
12334      with the way we're processing SUPER. A THIS from a primary as a
12335      different form than a SUPER. Turn THIS into something symbolic */
12336   if (TREE_CODE (node) == THIS_EXPR)
12337     node_to_insert = wfl = build_wfl_node (this_identifier_node);
12338   else
12339     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
12340
12341   EXPR_WFL_LINECOL (wfl) = location;
12342   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
12343   return wfl;
12344 }
12345
12346 /* Build a super() constructor invocation. Returns empty_stmt_node if
12347    we're currently dealing with the class java.lang.Object. */
12348
12349 static tree
12350 build_super_invocation (mdecl)
12351      tree mdecl;
12352 {
12353   if (DECL_CONTEXT (mdecl) == object_type_node)
12354     return empty_stmt_node;
12355   else
12356     {
12357       tree super_wfl = build_wfl_node (super_identifier_node);
12358       tree a = NULL_TREE, t;
12359       /* If we're dealing with an anonymous class, pass the arguments
12360          of the crafted constructor along. */
12361       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
12362         {
12363           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
12364           for (; t != end_params_node; t = TREE_CHAIN (t))
12365             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
12366         }
12367       return build_method_invocation (super_wfl, a);
12368     }
12369 }
12370
12371 /* Build a SUPER/THIS qualified method invocation.  */
12372
12373 static tree
12374 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
12375      int use_this;
12376      tree name, args;
12377      int lloc, rloc;
12378 {
12379   tree invok;
12380   tree wfl = 
12381     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
12382   EXPR_WFL_LINECOL (wfl) = lloc;
12383   invok = build_method_invocation (name, args);
12384   return make_qualified_primary (wfl, invok, rloc);
12385 }
12386
12387 /* Build an incomplete CALL_EXPR node. */
12388
12389 static tree
12390 build_method_invocation (name, args)
12391     tree name;
12392     tree args;
12393 {
12394   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
12395   TREE_SIDE_EFFECTS (call) = 1;
12396   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12397   return call;
12398 }
12399
12400 /* Build an incomplete new xxx(...) node. */
12401
12402 static tree
12403 build_new_invocation (name, args)
12404     tree name, args;
12405 {
12406   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
12407   TREE_SIDE_EFFECTS (call) = 1;
12408   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12409   return call;
12410 }
12411
12412 /* Build an incomplete assignment expression. */
12413
12414 static tree
12415 build_assignment (op, op_location, lhs, rhs)
12416      int op, op_location;
12417      tree lhs, rhs;
12418 {
12419   tree assignment;
12420   /* Build the corresponding binop if we deal with a Compound
12421      Assignment operator. Mark the binop sub-tree as part of a
12422      Compound Assignment expression */
12423   if (op != ASSIGN_TK)
12424     {
12425       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
12426       COMPOUND_ASSIGN_P (rhs) = 1;
12427     }
12428   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
12429   TREE_SIDE_EFFECTS (assignment) = 1;
12430   EXPR_WFL_LINECOL (assignment) = op_location;
12431   return assignment;
12432 }
12433
12434 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
12435
12436 char *
12437 print_int_node (node)
12438     tree node;
12439 {
12440   static char buffer [80];
12441   if (TREE_CONSTANT_OVERFLOW (node))
12442     sprintf (buffer, "<overflow>");
12443     
12444   if (TREE_INT_CST_HIGH (node) == 0)
12445     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
12446              TREE_INT_CST_LOW (node));
12447   else if (TREE_INT_CST_HIGH (node) == -1
12448            && TREE_INT_CST_LOW (node) != 0)
12449     {
12450       buffer [0] = '-';
12451       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
12452                -TREE_INT_CST_LOW (node));
12453     }
12454   else
12455     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
12456              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
12457
12458   return buffer;
12459 }
12460
12461 \f
12462
12463 /* This section of the code handle assignment check with FINAL
12464    variables.  */
12465
12466 static void
12467 reset_static_final_variable_assignment_flag (class)
12468      tree class;
12469 {
12470   tree field;
12471   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12472     if (CLASS_FINAL_VARIABLE_P (field))
12473       DECL_FIELD_FINAL_LIIC (field) = 0;
12474 }
12475
12476 /* Figure whether all final static variable have been initialized.  */
12477
12478 static void
12479 check_static_final_variable_assignment_flag (class)
12480      tree class;
12481 {
12482   tree field;
12483
12484   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12485     if (CLASS_FINAL_VARIABLE_P (field)
12486         && !DECL_FIELD_FINAL_IUD (field) && !DECL_FIELD_FINAL_LIIC (field))
12487       parse_error_context
12488         (DECL_FIELD_FINAL_WFL (field),
12489          "Blank static final variable `%s' may not have been initialized",
12490          IDENTIFIER_POINTER (DECL_NAME (field)));
12491 }
12492
12493 /* This function marks all final variable locally unassigned.  */
12494
12495 static void
12496 reset_final_variable_local_assignment_flag (class)
12497      tree class;
12498 {
12499   tree field;
12500   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12501     if (FINAL_VARIABLE_P (field))
12502       DECL_FIELD_FINAL_LIIC (field) = 0;
12503 }
12504
12505 /* Figure whether all final variables have beem initialized in MDECL
12506    and mark MDECL accordingly.  */
12507
12508 static void
12509 check_final_variable_local_assignment_flag (class, mdecl)
12510      tree class;
12511      tree mdecl;
12512 {
12513   tree field;
12514   int initialized = 0;
12515   int non_initialized = 0; 
12516
12517   if (DECL_FUNCTION_SYNTHETIC_CTOR (mdecl))
12518     return;
12519
12520   /* First find out whether all final variables or no final variable
12521      are initialized in this ctor. We don't take into account final
12522      variable that have been initialized upon declaration.  */
12523   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12524     if (FINAL_VARIABLE_P (field) && !DECL_FIELD_FINAL_IUD (field))
12525       {
12526         if (DECL_FIELD_FINAL_LIIC (field))
12527           initialized++;
12528         else
12529           non_initialized++;
12530       }
12531
12532   /* There were no non initialized variable and no initialized variable.
12533      This ctor is fine. */
12534   if (!non_initialized && !initialized)
12535     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12536   /* If no variables have been initialized, that fine. We'll check
12537      later whether this ctor calls a constructor which initializes
12538      them. We mark the ctor as not initializing all its finals. */
12539   else if (initialized == 0)
12540     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 0;
12541   /* If we have a mixed bag, then we have a problem. We need to report
12542      all the variables we're not initializing.  */
12543   else if (initialized && non_initialized)
12544     {
12545       DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 0;
12546       for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12547         if (FIELD_FINAL (field)
12548             && !DECL_FIELD_FINAL_IUD (field) && !DECL_FIELD_FINAL_LIIC (field))
12549           {
12550             parse_error_context 
12551               (lookup_cl (mdecl),
12552                "Blank final variable `%s' may not have been initialized in this constructor",
12553                IDENTIFIER_POINTER (DECL_NAME (field)));
12554             DECL_FIELD_FINAL_IERR (field) = 1;
12555           }
12556     }
12557   /* Otherwise we know this ctor is initializing all its final
12558      variable. We mark it so. */
12559   else
12560     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12561 }
12562
12563 /* This function recurses in a simple what through STMT and stops when
12564    it finds a constructor call. It then verifies that the called
12565    constructor initialized its final properly. Return 1 upon success,
12566    0 or -1 otherwise.  */
12567
12568 static int
12569 check_final_variable_indirect_assignment (stmt)
12570      tree stmt;
12571 {
12572   int res;
12573   switch (TREE_CODE (stmt))
12574     {
12575     case EXPR_WITH_FILE_LOCATION:
12576       return check_final_variable_indirect_assignment (EXPR_WFL_NODE (stmt));
12577     case COMPOUND_EXPR:
12578       res = check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 0));
12579       if (res)
12580         return res;
12581       return check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 1));
12582     case SAVE_EXPR:
12583       return check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 0));
12584     case CALL_EXPR:
12585       {
12586         tree decl = TREE_OPERAND (stmt, 0);
12587         tree fbody;
12588
12589         if (TREE_CODE (decl) != FUNCTION_DECL)
12590           decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
12591         if (TREE_CODE (decl) != FUNCTION_DECL)
12592           abort ();
12593         if (DECL_FUNCTION_ALL_FINAL_INITIALIZED (decl))
12594           return 1;
12595         if (DECL_FINIT_P (decl) || DECL_CONTEXT (decl) != current_class)
12596           return -1;
12597         fbody = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
12598         if (fbody == error_mark_node)
12599           return -1;
12600         fbody = BLOCK_EXPR_BODY (fbody);
12601         return check_final_variable_indirect_assignment (fbody);
12602       }
12603     default:
12604       break;
12605     }
12606   return 0;
12607 }
12608
12609 /* This is the last chance to catch a final variable initialization
12610    problem. This routine will report an error if a final variable was
12611    never (globally) initialized and never reported as not having been
12612    initialized properly. */
12613
12614 static void
12615 check_final_variable_global_assignment_flag (class)
12616      tree class;
12617 {
12618   tree field, mdecl;
12619   int nnctor = 0;
12620
12621   /* We go through all natural ctors and see whether they're
12622      initializing all their final variables or not. */
12623   current_function_decl = NULL_TREE; /* For the error report. */
12624   for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
12625     if (DECL_CONSTRUCTOR_P (mdecl) && ! DECL_FUNCTION_SYNTHETIC_CTOR (mdecl))
12626       {
12627         if (!DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl))
12628           {
12629             /* It doesn't. Maybe it calls a constructor that initializes
12630                them.  find out. */
12631             tree fbody = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl));
12632             if (fbody == error_mark_node)
12633               continue;
12634             fbody = BLOCK_EXPR_BODY (fbody);
12635             if (check_final_variable_indirect_assignment (fbody) == 1)
12636               {
12637                 DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12638                 nnctor++;
12639               }
12640             else
12641               parse_error_context
12642                 (lookup_cl (mdecl),
12643                  "Final variable initialization error in this constructor");
12644           }
12645         else
12646           nnctor++;
12647       }
12648
12649   /* Finally we catch final variables that never were initialized */
12650   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12651     if (FINAL_VARIABLE_P (field)
12652         /* If the field wasn't initialized upon declaration */
12653         && !DECL_FIELD_FINAL_IUD (field)
12654         /* There wasn't natural ctor in which the field could have been
12655            initialized */
12656         && !nnctor
12657         /* If we never reported a problem with this field */
12658         && !DECL_FIELD_FINAL_IERR (field))
12659       {
12660         current_function_decl = NULL;
12661         parse_error_context
12662           (DECL_FIELD_FINAL_WFL (field),
12663            "Final variable `%s' hasn't been initialized upon its declaration",
12664            IDENTIFIER_POINTER (DECL_NAME (field)));
12665       }
12666
12667 }
12668
12669 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
12670    context.  */
12671
12672 static int
12673 check_final_assignment (lvalue, wfl)
12674      tree lvalue, wfl;
12675 {
12676   if (TREE_CODE (lvalue) != COMPONENT_REF && !JDECL_P (lvalue))
12677     return 0;
12678
12679   if (TREE_CODE (lvalue) == COMPONENT_REF
12680       && JDECL_P (TREE_OPERAND (lvalue, 1)))
12681     lvalue = TREE_OPERAND (lvalue, 1);
12682
12683   if (!FIELD_FINAL (lvalue))
12684     return 0;
12685
12686   /* Now the logic. We can modify a final VARIABLE:
12687      1) in finit$, (its declaration was followed by an initialization,)
12688      2) consistently in each natural ctor, if it wasn't initialized in
12689         finit$ or once in <clinit>.  In any other cases, an error should be
12690         reported. */
12691   if (DECL_FINIT_P (current_function_decl))
12692     {
12693       DECL_FIELD_FINAL_IUD (lvalue) = 1;
12694       return 0;
12695     }
12696
12697   if (!DECL_FUNCTION_SYNTHETIC_CTOR (current_function_decl)
12698       /* Only if it wasn't given a value upon initialization */
12699       && DECL_LANG_SPECIFIC (lvalue) && !DECL_FIELD_FINAL_IUD (lvalue)
12700       /* If it was never assigned a value in this constructor */
12701       && !DECL_FIELD_FINAL_LIIC (lvalue))
12702     {
12703       /* Turn the locally assigned flag on, it will be checked later
12704          on to point out at discrepancies. */
12705       DECL_FIELD_FINAL_LIIC (lvalue) = 1;
12706       if (DECL_CLINIT_P (current_function_decl))
12707         DECL_FIELD_FINAL_IUD (lvalue) = 1;
12708       return 0;
12709     }
12710
12711   /* Other problems should be reported right away. */
12712   parse_error_context 
12713     (wfl, "Can't %sassign a value to the final variable `%s'",
12714      (FIELD_STATIC (lvalue) ? "re" : ""),
12715      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
12716
12717   /* Note that static field can be initialized once and only once. */
12718   if (FIELD_STATIC (lvalue))
12719     DECL_FIELD_FINAL_IERR (lvalue) = 1;
12720
12721   return 1;
12722 }
12723
12724 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
12725    read. This is needed to avoid circularities in the implementation
12726    of these fields in libjava. */
12727
12728 static tree
12729 maybe_build_primttype_type_ref (rhs, wfl)
12730     tree rhs, wfl;
12731 {
12732   tree to_return = NULL_TREE;
12733   tree rhs_type = TREE_TYPE (rhs);
12734   if (TREE_CODE (rhs) == COMPOUND_EXPR)
12735     {
12736       tree n = TREE_OPERAND (rhs, 1);
12737       if (TREE_CODE (n) == VAR_DECL 
12738           && DECL_NAME (n) == TYPE_identifier_node
12739           && rhs_type == class_ptr_type
12740           && TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION
12741           && TREE_CODE (EXPR_WFL_NODE (wfl)) == IDENTIFIER_NODE)
12742         {
12743           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
12744           if (!strncmp (self_name, "java.lang.", 10))
12745             to_return = build_primtype_type_ref (self_name);
12746         }
12747     }
12748   return (to_return ? to_return : rhs );
12749 }
12750
12751 /* 15.25 Assignment operators. */
12752
12753 static tree
12754 patch_assignment (node, wfl_op1, wfl_op2)
12755      tree node;
12756      tree wfl_op1;
12757      tree wfl_op2;
12758 {
12759   tree rhs = TREE_OPERAND (node, 1);
12760   tree lvalue = TREE_OPERAND (node, 0), llvalue;
12761   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
12762   int error_found = 0;
12763   int lvalue_from_array = 0;
12764
12765   /* Can't assign to a (blank) final. */
12766   if (check_final_assignment (lvalue, wfl_op1))
12767     error_found = 1;
12768
12769   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12770
12771   /* Lhs can be a named variable */
12772   if (JDECL_P (lvalue))
12773     {
12774       lhs_type = TREE_TYPE (lvalue);
12775     }
12776   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
12777      comment on reason why */
12778   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
12779     {
12780       lhs_type = TREE_TYPE (lvalue);
12781       lvalue_from_array = 1;
12782     }
12783   /* Or a field access */
12784   else if (TREE_CODE (lvalue) == COMPONENT_REF)
12785     lhs_type = TREE_TYPE (lvalue);
12786   /* Or a function return slot */
12787   else if (TREE_CODE (lvalue) == RESULT_DECL)
12788     lhs_type = TREE_TYPE (lvalue);
12789   /* Otherwise, we might want to try to write into an optimized static
12790      final, this is an of a different nature, reported further on. */
12791   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
12792            && resolve_expression_name (wfl_op1, &llvalue))
12793     {
12794       if (!error_found && check_final_assignment (llvalue, wfl_op1))
12795         {
12796           /* What we should do instead is resetting the all the flags
12797              previously set, exchange lvalue for llvalue and continue. */
12798           error_found = 1;
12799           return error_mark_node;
12800         }
12801       else 
12802         lhs_type = TREE_TYPE (lvalue);
12803     }
12804   else 
12805     {
12806       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
12807       error_found = 1;
12808     }
12809
12810   rhs_type = TREE_TYPE (rhs);
12811   /* 5.1 Try the assignment conversion for builtin type. */
12812   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
12813
12814   /* 5.2 If it failed, try a reference conversion */
12815   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
12816     lhs_type = promote_type (rhs_type);
12817
12818   /* 15.25.2 If we have a compound assignment, convert RHS into the
12819      type of the LHS */
12820   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12821     new_rhs = convert (lhs_type, rhs);
12822
12823   /* Explicit cast required. This is an error */
12824   if (!new_rhs)
12825     {
12826       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
12827       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
12828       tree wfl;
12829       char operation [32];      /* Max size known */
12830
12831       /* If the assignment is part of a declaration, we use the WFL of
12832          the declared variable to point out the error and call it a
12833          declaration problem. If the assignment is a genuine =
12834          operator, we call is a operator `=' problem, otherwise we
12835          call it an assignment problem. In both of these last cases,
12836          we use the WFL of the operator to indicate the error. */
12837
12838       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
12839         {
12840           wfl = wfl_op1;
12841           strcpy (operation, "declaration");
12842         }
12843       else
12844         {
12845           wfl = wfl_operator;
12846           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12847             strcpy (operation, "assignment");
12848           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
12849             strcpy (operation, "`return'");
12850           else
12851             strcpy (operation, "`='");
12852         }
12853
12854       if (!valid_cast_to_p (rhs_type, lhs_type))
12855         parse_error_context
12856           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
12857            operation, t1, t2);
12858       else
12859         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
12860                              operation, t1, t2);
12861       free (t1); free (t2);
12862       error_found = 1;
12863     }
12864
12865   /* Inline read access to java.lang.PRIMTYPE.TYPE */
12866   if (new_rhs)
12867     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
12868
12869   if (error_found)
12870     return error_mark_node;
12871
12872   /* 10.10: Array Store Exception runtime check */
12873   if (!flag_emit_class_files
12874       && !flag_emit_xref
12875       && lvalue_from_array 
12876       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
12877     {
12878       tree check;
12879       tree base = lvalue;
12880
12881       /* We need to retrieve the right argument for
12882          _Jv_CheckArrayStore.  This is somewhat complicated by bounds
12883          and null pointer checks, both of which wrap the operand in
12884          one layer of COMPOUND_EXPR.  */
12885       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
12886         base = TREE_OPERAND (lvalue, 0);
12887       else
12888         {
12889           tree op = TREE_OPERAND (base, 0);
12890           
12891           /* We can have a SAVE_EXPR here when doing String +=.  */
12892           if (TREE_CODE (op) == SAVE_EXPR)
12893             op = TREE_OPERAND (op, 0);
12894           if (flag_bounds_check)
12895             base = TREE_OPERAND (TREE_OPERAND (op, 1), 0);
12896           else
12897             base = TREE_OPERAND (op, 0);
12898         }
12899
12900       /* Build the invocation of _Jv_CheckArrayStore */
12901       new_rhs = save_expr (new_rhs);
12902       check = build (CALL_EXPR, void_type_node,
12903                      build_address_of (soft_checkarraystore_node),
12904                      tree_cons (NULL_TREE, base,
12905                                 build_tree_list (NULL_TREE, new_rhs)),
12906                      NULL_TREE);
12907       TREE_SIDE_EFFECTS (check) = 1;
12908
12909       /* We have to decide on an insertion point */
12910       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
12911         {
12912           tree t;
12913           if (flag_bounds_check)
12914             {
12915               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
12916               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
12917                 build (COMPOUND_EXPR, void_type_node, t, check);
12918             }
12919           else
12920             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
12921                                               check, TREE_OPERAND (lvalue, 1));
12922         }
12923       else if (flag_bounds_check)
12924         {
12925           tree hook = lvalue;
12926           tree compound = TREE_OPERAND (lvalue, 0);
12927           tree bound_check, new_compound;
12928
12929           if (TREE_CODE (compound) == SAVE_EXPR)
12930             {
12931               compound = TREE_OPERAND (compound, 0);
12932               hook = TREE_OPERAND (hook, 0);
12933             }
12934
12935           /* Find the array bound check, hook the original array access. */
12936           bound_check = TREE_OPERAND (compound, 0);
12937           TREE_OPERAND (hook, 0) = TREE_OPERAND (compound, 1);
12938
12939           /* Make sure the bound check will happen before the store check */
12940           new_compound =
12941             build (COMPOUND_EXPR, void_type_node, bound_check, check);
12942
12943           /* Re-assemble the augmented array access. */
12944           lvalue = build (COMPOUND_EXPR, lhs_type, new_compound, lvalue);
12945         }
12946       else
12947         lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
12948     }
12949
12950   /* Final locals can be used as case values in switch
12951      statement. Prepare them for this eventuality. */
12952   if (TREE_CODE (lvalue) == VAR_DECL 
12953       && LOCAL_FINAL_P (lvalue)
12954       && TREE_CONSTANT (new_rhs)
12955       && IDENTIFIER_LOCAL_VALUE (DECL_NAME (lvalue))
12956       && JINTEGRAL_TYPE_P (TREE_TYPE (lvalue))
12957       )
12958     {
12959       TREE_CONSTANT (lvalue) = 1;
12960       DECL_INITIAL (lvalue) = new_rhs;
12961     }
12962
12963   TREE_OPERAND (node, 0) = lvalue;
12964   TREE_OPERAND (node, 1) = new_rhs;
12965   TREE_TYPE (node) = lhs_type;
12966   return node;
12967 }
12968
12969 /* Check that type SOURCE can be cast into type DEST. If the cast
12970    can't occur at all, return 0 otherwise 1. This function is used to
12971    produce accurate error messages on the reasons why an assignment
12972    failed. */
12973
12974 static tree
12975 try_reference_assignconv (lhs_type, rhs)
12976      tree lhs_type, rhs;
12977 {
12978   tree new_rhs = NULL_TREE;
12979   tree rhs_type = TREE_TYPE (rhs);
12980
12981   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
12982     {
12983       /* `null' may be assigned to any reference type */
12984       if (rhs == null_pointer_node)
12985         new_rhs = null_pointer_node;
12986       /* Try the reference assignment conversion */
12987       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
12988         new_rhs = rhs;
12989       /* This is a magic assignment that we process differently */
12990       else if (TREE_CODE (rhs) == JAVA_EXC_OBJ_EXPR)
12991         new_rhs = rhs;
12992     }
12993   return new_rhs;
12994 }
12995
12996 /* Check that RHS can be converted into LHS_TYPE by the assignment
12997    conversion (5.2), for the cases of RHS being a builtin type. Return
12998    NULL_TREE if the conversion fails or if because RHS isn't of a
12999    builtin type. Return a converted RHS if the conversion is possible.  */
13000
13001 static tree
13002 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
13003      tree wfl_op1, lhs_type, rhs;
13004 {
13005   tree new_rhs = NULL_TREE;
13006   tree rhs_type = TREE_TYPE (rhs);
13007
13008   /* Handle boolean specially.  */
13009   if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
13010       || TREE_CODE (lhs_type) == BOOLEAN_TYPE)
13011     {
13012       if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
13013           && TREE_CODE (lhs_type) == BOOLEAN_TYPE)
13014         new_rhs = rhs;
13015     }
13016
13017   /* Zero accepted everywhere */
13018   else if (TREE_CODE (rhs) == INTEGER_CST 
13019       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
13020       && JPRIMITIVE_TYPE_P (rhs_type))
13021     new_rhs = convert (lhs_type, rhs);
13022
13023   /* 5.1.1 Try Identity Conversion,
13024      5.1.2 Try Widening Primitive Conversion */
13025   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
13026     new_rhs = convert (lhs_type, rhs);
13027
13028   /* Try a narrowing primitive conversion (5.1.3): 
13029        - expression is a constant expression of type int AND
13030        - variable is byte, short or char AND
13031        - The value of the expression is representable in the type of the 
13032          variable */
13033   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
13034            && (lhs_type == byte_type_node || lhs_type == char_type_node
13035                || lhs_type == short_type_node))
13036     {
13037       if (int_fits_type_p (rhs, lhs_type))
13038         new_rhs = convert (lhs_type, rhs);
13039       else if (wfl_op1)         /* Might be called with a NULL */
13040         parse_warning_context 
13041           (wfl_op1, "Constant expression `%s' too wide for narrowing primitive conversion to `%s'", 
13042            print_int_node (rhs), lang_printable_name (lhs_type, 0));
13043       /* Reported a warning that will turn into an error further
13044          down, so we don't return */
13045     }
13046
13047   return new_rhs;
13048 }
13049
13050 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
13051    conversion (5.1.1) or widening primitive conversion (5.1.2).  Return
13052    0 is the conversion test fails.  This implements parts the method
13053    invocation convertion (5.3).  */
13054
13055 static int
13056 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
13057      tree lhs_type, rhs_type;
13058 {
13059   /* 5.1.1: This is the identity conversion part. */
13060   if (lhs_type == rhs_type)
13061     return 1;
13062
13063   /* Reject non primitive types and boolean conversions.  */
13064   if (!JNUMERIC_TYPE_P (lhs_type) || !JNUMERIC_TYPE_P (rhs_type))
13065     return 0;
13066
13067   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
13068      than a char can't be converted into a char. Short can't too, but
13069      the < test below takes care of that */
13070   if (lhs_type == char_type_node && rhs_type == byte_type_node)
13071     return 0;
13072
13073   /* Accept all promoted type here. Note, we can't use <= in the test
13074      below, because we still need to bounce out assignments of short
13075      to char and the likes */
13076   if (lhs_type == int_type_node
13077       && (rhs_type == promoted_byte_type_node
13078           || rhs_type == promoted_short_type_node
13079           || rhs_type == promoted_char_type_node
13080           || rhs_type == promoted_boolean_type_node))
13081     return 1;
13082
13083   /* From here, an integral is widened if its precision is smaller
13084      than the precision of the LHS or if the LHS is a floating point
13085      type, or the RHS is a float and the RHS a double. */
13086   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
13087        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
13088       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
13089       || (rhs_type == float_type_node && lhs_type == double_type_node))
13090     return 1;
13091
13092   return 0;
13093 }
13094
13095 /* Check that something of SOURCE type can be assigned or cast to
13096    something of DEST type at runtime. Return 1 if the operation is
13097    valid, 0 otherwise. If CAST is set to 1, we're treating the case
13098    were SOURCE is cast into DEST, which borrows a lot of the
13099    assignment check. */
13100
13101 static int
13102 valid_ref_assignconv_cast_p (source, dest, cast)
13103      tree source;
13104      tree dest;
13105      int cast;
13106 {
13107   /* SOURCE or DEST might be null if not from a declared entity. */
13108   if (!source || !dest)
13109     return 0;
13110   if (JNULLP_TYPE_P (source))
13111     return 1;
13112   if (TREE_CODE (source) == POINTER_TYPE)
13113     source = TREE_TYPE (source);
13114   if (TREE_CODE (dest) == POINTER_TYPE)
13115     dest = TREE_TYPE (dest);
13116
13117   /* If source and dest are being compiled from bytecode, they may need to
13118      be loaded. */
13119   if (CLASS_P (source) && !CLASS_LOADED_P (source))
13120     {
13121       load_class (source, 1);
13122       safe_layout_class (source);
13123     }
13124   if (CLASS_P (dest) && !CLASS_LOADED_P (dest))
13125     {
13126       load_class (dest, 1);
13127       safe_layout_class (dest);
13128     }
13129
13130   /* Case where SOURCE is a class type */
13131   if (TYPE_CLASS_P (source))
13132     {
13133       if (TYPE_CLASS_P (dest))
13134         return  (source == dest 
13135                  || inherits_from_p (source, dest)
13136                  || (cast && inherits_from_p (dest, source)));
13137       if (TYPE_INTERFACE_P (dest))
13138         {
13139           /* If doing a cast and SOURCE is final, the operation is
13140              always correct a compile time (because even if SOURCE
13141              does not implement DEST, a subclass of SOURCE might). */
13142           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
13143             return 1;
13144           /* Otherwise, SOURCE must implement DEST */
13145           return interface_of_p (dest, source);
13146         }
13147       /* DEST is an array, cast permited if SOURCE is of Object type */
13148       return (cast && source == object_type_node ? 1 : 0);
13149     }
13150   if (TYPE_INTERFACE_P (source))
13151     {
13152       if (TYPE_CLASS_P (dest))
13153         {
13154           /* If not casting, DEST must be the Object type */
13155           if (!cast)
13156             return dest == object_type_node;
13157           /* We're doing a cast. The cast is always valid is class
13158              DEST is not final, otherwise, DEST must implement SOURCE */
13159           else if (!CLASS_FINAL (TYPE_NAME (dest)))
13160             return 1;
13161           else
13162             return interface_of_p (source, dest);
13163         }
13164       if (TYPE_INTERFACE_P (dest))
13165         {
13166           /* If doing a cast, then if SOURCE and DEST contain method
13167              with the same signature but different return type, then
13168              this is a (compile time) error */
13169           if (cast)
13170             {
13171               tree method_source, method_dest;
13172               tree source_type;
13173               tree source_sig;
13174               tree source_name;
13175               for (method_source = TYPE_METHODS (source); method_source; 
13176                    method_source = TREE_CHAIN (method_source))
13177                 {
13178                   source_sig = 
13179                     build_java_argument_signature (TREE_TYPE (method_source));
13180                   source_type = TREE_TYPE (TREE_TYPE (method_source));
13181                   source_name = DECL_NAME (method_source);
13182                   for (method_dest = TYPE_METHODS (dest);
13183                        method_dest; method_dest = TREE_CHAIN (method_dest))
13184                     if (source_sig == 
13185                         build_java_argument_signature (TREE_TYPE (method_dest))
13186                         && source_name == DECL_NAME (method_dest)
13187                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
13188                       return 0;
13189                 }
13190               return 1;
13191             }
13192           else
13193             return source == dest || interface_of_p (dest, source);
13194         }
13195       else
13196         {
13197           /* Array */
13198           return (cast
13199                   && (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable
13200                       || (DECL_NAME (TYPE_NAME (source))
13201                           == java_io_serializable)));
13202         }
13203     }
13204   if (TYPE_ARRAY_P (source))
13205     {
13206       if (TYPE_CLASS_P (dest))
13207         return dest == object_type_node;
13208       /* Can't cast an array to an interface unless the interface is
13209          java.lang.Cloneable or java.io.Serializable.  */
13210       if (TYPE_INTERFACE_P (dest))
13211         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable
13212                 || DECL_NAME (TYPE_NAME (dest)) == java_io_serializable);
13213       else                      /* Arrays */
13214         {
13215           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
13216           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
13217           
13218           /* In case of severe errors, they turn out null */
13219           if (!dest_element_type || !source_element_type)
13220             return 0;
13221           if (source_element_type == dest_element_type)
13222             return 1;
13223           return valid_ref_assignconv_cast_p (source_element_type,
13224                                               dest_element_type, cast);
13225         }
13226       return 0;
13227     }
13228   return 0;
13229 }
13230
13231 static int
13232 valid_cast_to_p (source, dest)
13233      tree source;
13234      tree dest;
13235 {
13236   if (TREE_CODE (source) == POINTER_TYPE)
13237     source = TREE_TYPE (source);
13238   if (TREE_CODE (dest) == POINTER_TYPE)
13239     dest = TREE_TYPE (dest);
13240
13241   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
13242     return valid_ref_assignconv_cast_p (source, dest, 1);
13243
13244   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
13245     return 1;
13246
13247   else if (TREE_CODE (source) == BOOLEAN_TYPE
13248            && TREE_CODE (dest) == BOOLEAN_TYPE)
13249     return 1;
13250
13251   return 0;
13252 }
13253
13254 static tree
13255 do_unary_numeric_promotion (arg)
13256      tree arg;
13257 {
13258   tree type = TREE_TYPE (arg);
13259   if ((TREE_CODE (type) == INTEGER_TYPE && TYPE_PRECISION (type) < 32)
13260       || TREE_CODE (type) == CHAR_TYPE)
13261     arg = convert (int_type_node, arg);
13262   return arg;
13263 }
13264
13265 /* Return a non zero value if SOURCE can be converted into DEST using
13266    the method invocation conversion rule (5.3).  */
13267 static int
13268 valid_method_invocation_conversion_p (dest, source)
13269      tree dest, source;
13270 {
13271   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
13272            && valid_builtin_assignconv_identity_widening_p (dest, source))
13273           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
13274               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
13275               && valid_ref_assignconv_cast_p (source, dest, 0)));
13276 }
13277
13278 /* Build an incomplete binop expression. */
13279
13280 static tree
13281 build_binop (op, op_location, op1, op2)
13282      enum tree_code op;
13283      int op_location;
13284      tree op1, op2;
13285 {
13286   tree binop = build (op, NULL_TREE, op1, op2);
13287   TREE_SIDE_EFFECTS (binop) = 1;
13288   /* Store the location of the operator, for better error report. The
13289      string of the operator will be rebuild based on the OP value. */
13290   EXPR_WFL_LINECOL (binop) = op_location;
13291   return binop;
13292 }
13293
13294 /* Build the string of the operator retained by NODE. If NODE is part
13295    of a compound expression, add an '=' at the end of the string. This
13296    function is called when an error needs to be reported on an
13297    operator. The string is returned as a pointer to a static character
13298    buffer. */
13299
13300 static char *
13301 operator_string (node)
13302      tree node;
13303 {
13304 #define BUILD_OPERATOR_STRING(S)                                        \
13305   {                                                                     \
13306     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
13307     return buffer;                                                      \
13308   }
13309   
13310   static char buffer [10];
13311   switch (TREE_CODE (node))
13312     {
13313     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
13314     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
13315     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
13316     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
13317     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
13318     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
13319     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
13320     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
13321     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
13322     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
13323     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
13324     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
13325     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
13326     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
13327     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
13328     case GT_EXPR: BUILD_OPERATOR_STRING (">");
13329     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
13330     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
13331     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
13332     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
13333     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
13334     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
13335     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
13336     case PREINCREMENT_EXPR:     /* Fall through */
13337     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
13338     case PREDECREMENT_EXPR:     /* Fall through */
13339     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
13340     default:
13341       internal_error ("unregistered operator %s",
13342                       tree_code_name [TREE_CODE (node)]);
13343     }
13344   return NULL;
13345 #undef BUILD_OPERATOR_STRING
13346 }
13347
13348 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
13349
13350 static int
13351 java_decl_equiv (var_acc1, var_acc2)
13352      tree var_acc1, var_acc2;
13353 {
13354   if (JDECL_P (var_acc1))
13355     return (var_acc1 == var_acc2);
13356   
13357   return (TREE_CODE (var_acc1) == COMPONENT_REF
13358           && TREE_CODE (var_acc2) == COMPONENT_REF
13359           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
13360              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
13361           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
13362 }
13363
13364 /* Return a non zero value if CODE is one of the operators that can be
13365    used in conjunction with the `=' operator in a compound assignment.  */
13366
13367 static int
13368 binop_compound_p (code)
13369     enum tree_code code;
13370 {
13371   int i;
13372   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
13373     if (binop_lookup [i] == code)
13374       break;
13375
13376   return i < BINOP_COMPOUND_CANDIDATES;
13377 }
13378
13379 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
13380
13381 static tree
13382 java_refold (t)
13383      tree t;
13384 {
13385   tree c, b, ns, decl;
13386
13387   if (TREE_CODE (t) != MODIFY_EXPR)
13388     return t;
13389
13390   c = TREE_OPERAND (t, 1);
13391   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
13392          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
13393          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
13394     return t;
13395
13396   /* Now the left branch of the binary operator. */
13397   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
13398   if (! (b && TREE_CODE (b) == NOP_EXPR 
13399          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
13400     return t;
13401
13402   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
13403   if (! (ns && TREE_CODE (ns) == NOP_EXPR
13404          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
13405     return t;
13406
13407   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
13408   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
13409       /* It's got to be the an equivalent decl */
13410       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
13411     {
13412       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
13413       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
13414       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
13415       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
13416       /* Change the right part of the BINOP_EXPR */
13417       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
13418     }
13419
13420   return t;
13421 }
13422
13423 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
13424    errors but we modify NODE so that it contains the type computed
13425    according to the expression, when it's fixed. Otherwise, we write
13426    error_mark_node as the type. It allows us to further the analysis
13427    of remaining nodes and detects more errors in certain cases.  */
13428
13429 static tree
13430 patch_binop (node, wfl_op1, wfl_op2)
13431      tree node;
13432      tree wfl_op1;
13433      tree wfl_op2;
13434 {
13435   tree op1 = TREE_OPERAND (node, 0);
13436   tree op2 = TREE_OPERAND (node, 1);
13437   tree op1_type = TREE_TYPE (op1);
13438   tree op2_type = TREE_TYPE (op2);
13439   tree prom_type = NULL_TREE, cn;
13440   enum tree_code code = TREE_CODE (node);
13441
13442   /* If 1, tell the routine that we have to return error_mark_node
13443      after checking for the initialization of the RHS */
13444   int error_found = 0;
13445
13446   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13447
13448   /* If either op<n>_type are NULL, this might be early signs of an
13449      error situation, unless it's too early to tell (in case we're
13450      handling a `+', `==', `!=' or `instanceof'.) We want to set op<n>_type
13451      correctly so the error can be later on reported accurately. */
13452   if (! (code == PLUS_EXPR || code == NE_EXPR 
13453          || code == EQ_EXPR || code == INSTANCEOF_EXPR))
13454     {
13455       tree n;
13456       if (! op1_type)
13457         {
13458           n = java_complete_tree (op1);
13459           op1_type = TREE_TYPE (n);
13460         }
13461       if (! op2_type)
13462         {
13463           n = java_complete_tree (op2);
13464           op2_type = TREE_TYPE (n);
13465         }
13466     }
13467
13468   switch (code)
13469     {
13470     /* 15.16 Multiplicative operators */
13471     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
13472     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
13473     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
13474     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
13475       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13476         {
13477           if (!JNUMERIC_TYPE_P (op1_type))
13478             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13479           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13480             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13481           TREE_TYPE (node) = error_mark_node;
13482           error_found = 1;
13483           break;
13484         }
13485       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13486
13487       /* Detect integral division by zero */
13488       if ((code == RDIV_EXPR || code == TRUNC_MOD_EXPR)
13489           && TREE_CODE (prom_type) == INTEGER_TYPE
13490           && (op2 == integer_zero_node || op2 == long_zero_node ||
13491               (TREE_CODE (op2) == INTEGER_CST &&
13492                ! TREE_INT_CST_LOW (op2)  && ! TREE_INT_CST_HIGH (op2))))
13493         {
13494           parse_error_context (wfl_operator, "Arithmetic exception");
13495           error_found = 1;
13496         }
13497           
13498       /* Change the division operator if necessary */
13499       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
13500         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
13501
13502       /* Before divisions as is disapear, try to simplify and bail if
13503          applicable, otherwise we won't perform even simple simplifications
13504          like (1-1)/3. */
13505       if (code == RDIV_EXPR && TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
13506         {
13507           TREE_TYPE (node) = prom_type;
13508           node = fold (node);
13509           if (TREE_CODE (node) != code)
13510             return node;
13511         }
13512
13513       if (TREE_CODE (prom_type) == INTEGER_TYPE
13514           && flag_use_divide_subroutine
13515           && ! flag_emit_class_files
13516           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
13517         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
13518  
13519       /* This one is more complicated. FLOATs are processed by a
13520          function call to soft_fmod. Duplicate the value of the
13521          COMPOUND_ASSIGN_P flag. */
13522       if (code == TRUNC_MOD_EXPR)
13523         {
13524           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
13525           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
13526           TREE_SIDE_EFFECTS (mod)
13527             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13528           return mod;
13529         }
13530       break;
13531
13532     /* 15.17 Additive Operators */
13533     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
13534
13535       /* Operation is valid if either one argument is a string
13536          constant, a String object or a StringBuffer crafted for the
13537          purpose of the a previous usage of the String concatenation
13538          operator */
13539
13540       if (TREE_CODE (op1) == STRING_CST 
13541           || TREE_CODE (op2) == STRING_CST
13542           || JSTRING_TYPE_P (op1_type)
13543           || JSTRING_TYPE_P (op2_type)
13544           || IS_CRAFTED_STRING_BUFFER_P (op1)
13545           || IS_CRAFTED_STRING_BUFFER_P (op2))
13546         return build_string_concatenation (op1, op2);
13547
13548     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
13549                                    Numeric Types */
13550       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13551         {
13552           if (!JNUMERIC_TYPE_P (op1_type))
13553             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13554           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13555             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13556           TREE_TYPE (node) = error_mark_node;
13557           error_found = 1;
13558           break;
13559         }
13560       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13561       break;
13562
13563     /* 15.18 Shift Operators */
13564     case LSHIFT_EXPR:
13565     case RSHIFT_EXPR:
13566     case URSHIFT_EXPR:
13567       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
13568         {
13569           if (!JINTEGRAL_TYPE_P (op1_type))
13570             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13571           else
13572             {
13573               if (JNUMERIC_TYPE_P (op2_type))
13574                 parse_error_context (wfl_operator,
13575                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
13576                                      operator_string (node),
13577                                      lang_printable_name (op2_type, 0));
13578               else
13579                 parse_error_context (wfl_operator,
13580                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
13581                                      operator_string (node),
13582                                      lang_printable_name (op2_type, 0));
13583             }
13584           TREE_TYPE (node) = error_mark_node;
13585           error_found = 1;
13586           break;
13587         }
13588
13589       /* Unary numeric promotion (5.6.1) is performed on each operand
13590          separatly */
13591       op1 = do_unary_numeric_promotion (op1);
13592       op2 = do_unary_numeric_promotion (op2);
13593
13594       /* The type of the shift expression is the type of the promoted
13595          type of the left-hand operand */
13596       prom_type = TREE_TYPE (op1);
13597
13598       /* Shift int only up to 0x1f and long up to 0x3f */
13599       if (prom_type == int_type_node)
13600         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13601                            build_int_2 (0x1f, 0)));
13602       else
13603         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13604                            build_int_2 (0x3f, 0)));
13605
13606       /* The >>> operator is a >> operating on unsigned quantities */
13607       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
13608         {
13609           tree to_return;
13610           tree utype = unsigned_type (prom_type);
13611           op1 = convert (utype, op1);
13612           TREE_SET_CODE (node, RSHIFT_EXPR);
13613           TREE_OPERAND (node, 0) = op1;
13614           TREE_OPERAND (node, 1) = op2;
13615           TREE_TYPE (node) = utype;
13616           to_return = convert (prom_type, node);
13617           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
13618           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
13619           TREE_SIDE_EFFECTS (to_return)
13620             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13621           return to_return;
13622         }
13623       break;
13624
13625       /* 15.19.1 Type Comparison Operator instaceof */
13626     case INSTANCEOF_EXPR:
13627
13628       TREE_TYPE (node) = boolean_type_node;
13629
13630       if (!(op2_type = resolve_type_during_patch (op2)))
13631         return error_mark_node;
13632
13633       /* The first operand must be a reference type or the null type */
13634       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
13635         error_found = 1;        /* Error reported further below */
13636
13637       /* The second operand must be a reference type */
13638       if (!JREFERENCE_TYPE_P (op2_type))
13639         {
13640           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
13641           parse_error_context
13642             (wfl_operator, "Invalid argument `%s' for `instanceof'",
13643              lang_printable_name (op2_type, 0));
13644           error_found = 1;
13645         }
13646
13647       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
13648         {
13649           /* If the first operand is null, the result is always false */
13650           if (op1 == null_pointer_node)
13651             return boolean_false_node;
13652           else if (flag_emit_class_files)
13653             {
13654               TREE_OPERAND (node, 1) = op2_type;
13655               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
13656               return node;
13657             }
13658           /* Otherwise we have to invoke instance of to figure it out */
13659           else
13660             return build_instanceof (op1, op2_type);
13661         }
13662       /* There is no way the expression operand can be an instance of
13663          the type operand. This is a compile time error. */
13664       else
13665         {
13666           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
13667           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
13668           parse_error_context 
13669             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
13670              t1, lang_printable_name (op2_type, 0));
13671           free (t1);
13672           error_found = 1;
13673         }
13674       
13675       break;
13676
13677       /* 15.21 Bitwise and Logical Operators */
13678     case BIT_AND_EXPR:
13679     case BIT_XOR_EXPR:
13680     case BIT_IOR_EXPR:
13681       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
13682         /* Binary numeric promotion is performed on both operand and the
13683            expression retain that type */
13684         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13685
13686       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
13687                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
13688         /* The type of the bitwise operator expression is BOOLEAN */
13689         prom_type = boolean_type_node;
13690       else
13691         {
13692           if (!JINTEGRAL_TYPE_P (op1_type))
13693             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13694           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
13695             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
13696           TREE_TYPE (node) = error_mark_node;
13697           error_found = 1;
13698           /* Insert a break here if adding thing before the switch's
13699              break for this case */
13700         }
13701       break;
13702
13703       /* 15.22 Conditional-And Operator */
13704     case TRUTH_ANDIF_EXPR:
13705       /* 15.23 Conditional-Or Operator */
13706     case TRUTH_ORIF_EXPR:
13707       /* Operands must be of BOOLEAN type */
13708       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
13709           TREE_CODE (op2_type) != BOOLEAN_TYPE)
13710         {
13711           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
13712             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
13713           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
13714             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
13715           TREE_TYPE (node) = boolean_type_node;
13716           error_found = 1;
13717           break;
13718         }
13719       /* The type of the conditional operators is BOOLEAN */
13720       prom_type = boolean_type_node;
13721       break;
13722
13723       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
13724     case LT_EXPR:
13725     case GT_EXPR:
13726     case LE_EXPR:
13727     case GE_EXPR:
13728       /* The type of each of the operands must be a primitive numeric
13729          type */
13730       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
13731         {
13732           if (!JNUMERIC_TYPE_P (op1_type))
13733             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13734           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13735             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13736           TREE_TYPE (node) = boolean_type_node;
13737           error_found = 1;
13738           break;
13739         }
13740       /* Binary numeric promotion is performed on the operands */
13741       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13742       /* The type of the relation expression is always BOOLEAN */
13743       prom_type = boolean_type_node;
13744       break;
13745
13746       /* 15.20 Equality Operator */
13747     case EQ_EXPR:
13748     case NE_EXPR:
13749       /* It's time for us to patch the strings. */
13750       if ((cn = patch_string (op1))) 
13751        {
13752          op1 = cn;
13753          op1_type = TREE_TYPE (op1);
13754        }
13755       if ((cn = patch_string (op2))) 
13756        {
13757          op2 = cn;
13758          op2_type = TREE_TYPE (op2);
13759        }
13760       
13761       /* 15.20.1 Numerical Equality Operators == and != */
13762       /* Binary numeric promotion is performed on the operands */
13763       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
13764         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13765       
13766       /* 15.20.2 Boolean Equality Operators == and != */
13767       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
13768           TREE_CODE (op2_type) == BOOLEAN_TYPE)
13769         ;                       /* Nothing to do here */
13770       
13771       /* 15.20.3 Reference Equality Operators == and != */
13772       /* Types have to be either references or the null type. If
13773          they're references, it must be possible to convert either
13774          type to the other by casting conversion. */
13775       else if (op1 == null_pointer_node || op2 == null_pointer_node 
13776                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
13777                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
13778                        || valid_ref_assignconv_cast_p (op2_type, 
13779                                                        op1_type, 1))))
13780         ;                       /* Nothing to do here */
13781           
13782       /* Else we have an error figure what can't be converted into
13783          what and report the error */
13784       else
13785         {
13786           char *t1;
13787           t1 = xstrdup (lang_printable_name (op1_type, 0));
13788           parse_error_context 
13789             (wfl_operator,
13790              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
13791              operator_string (node), t1, 
13792              lang_printable_name (op2_type, 0));
13793           free (t1);
13794           TREE_TYPE (node) = boolean_type_node;
13795           error_found = 1;
13796           break;
13797         }
13798       prom_type = boolean_type_node;
13799       break;
13800     default:
13801       abort ();
13802     }
13803
13804   if (error_found)
13805     return error_mark_node;
13806
13807   TREE_OPERAND (node, 0) = op1;
13808   TREE_OPERAND (node, 1) = op2;
13809   TREE_TYPE (node) = prom_type;
13810   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13811   
13812   if (flag_emit_xref)
13813     return node;
13814
13815   /* fold does not respect side-effect order as required for Java but not C.
13816    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
13817    * bytecode.
13818    */
13819   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
13820       : ! TREE_SIDE_EFFECTS (node))
13821     node = fold (node);
13822   return node;
13823 }
13824
13825 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
13826    zero value, the value of CSTE comes after the valude of STRING */
13827
13828 static tree
13829 do_merge_string_cste (cste, string, string_len, after)
13830      tree cste;
13831      const char *string;
13832      int string_len, after;
13833 {
13834   const char *old = TREE_STRING_POINTER (cste);
13835   int old_len = TREE_STRING_LENGTH (cste);
13836   int len = old_len + string_len;
13837   char *new = alloca (len+1);
13838
13839   if (after)
13840     {
13841       memcpy (new, string, string_len);
13842       memcpy (&new [string_len], old, old_len);
13843     }
13844   else
13845     {
13846       memcpy (new, old, old_len);
13847       memcpy (&new [old_len], string, string_len);
13848     }
13849   new [len] = '\0';
13850   return build_string (len, new);
13851 }
13852
13853 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
13854    new STRING_CST on success, NULL_TREE on failure */
13855
13856 static tree
13857 merge_string_cste (op1, op2, after)
13858      tree op1, op2;
13859      int after;
13860 {
13861   /* Handle two string constants right away */
13862   if (TREE_CODE (op2) == STRING_CST)
13863     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
13864                                  TREE_STRING_LENGTH (op2), after);
13865   
13866   /* Reasonable integer constant can be treated right away */
13867   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
13868     {
13869       static const char *boolean_true = "true";
13870       static const char *boolean_false = "false";
13871       static const char *null_pointer = "null";
13872       char ch[3];
13873       const char *string;
13874       
13875       if (op2 == boolean_true_node)
13876         string = boolean_true;
13877       else if (op2 == boolean_false_node)
13878         string = boolean_false;
13879       else if (op2 == null_pointer_node)
13880         string = null_pointer;
13881       else if (TREE_TYPE (op2) == char_type_node)
13882         {
13883           ch[0] = (char )TREE_INT_CST_LOW (op2);
13884           ch[1] = '\0';
13885           string = ch;
13886         }
13887       else
13888           string = print_int_node (op2);
13889       
13890       return do_merge_string_cste (op1, string, strlen (string), after);
13891     }
13892   return NULL_TREE;
13893 }
13894
13895 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
13896    has to be a STRING_CST and the other part must be a STRING_CST or a
13897    INTEGRAL constant. Return a new STRING_CST if the operation
13898    succeed, NULL_TREE otherwise.
13899
13900    If the case we want to optimize for space, we might want to return
13901    NULL_TREE for each invocation of this routine. FIXME */
13902
13903 static tree
13904 string_constant_concatenation (op1, op2)
13905      tree op1, op2;
13906 {
13907   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
13908     {
13909       tree string, rest;
13910       int invert;
13911       
13912       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
13913       rest   = (string == op1 ? op2 : op1);
13914       invert = (string == op1 ? 0 : 1 );
13915       
13916       /* Walk REST, only if it looks reasonable */
13917       if (TREE_CODE (rest) != STRING_CST
13918           && !IS_CRAFTED_STRING_BUFFER_P (rest)
13919           && !JSTRING_TYPE_P (TREE_TYPE (rest))
13920           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
13921         {
13922           rest = java_complete_tree (rest);
13923           if (rest == error_mark_node)
13924             return error_mark_node;
13925           rest = fold (rest);
13926         }
13927       return merge_string_cste (string, rest, invert);
13928     }
13929   return NULL_TREE;
13930 }
13931
13932 /* Implement the `+' operator. Does static optimization if possible,
13933    otherwise create (if necessary) and append elements to a
13934    StringBuffer. The StringBuffer will be carried around until it is
13935    used for a function call or an assignment. Then toString() will be
13936    called on it to turn it into a String object. */
13937
13938 static tree
13939 build_string_concatenation (op1, op2)
13940      tree op1, op2;
13941 {
13942   tree result;
13943   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13944
13945   if (flag_emit_xref)
13946     return build (PLUS_EXPR, string_type_node, op1, op2);
13947   
13948   /* Try to do some static optimization */
13949   if ((result = string_constant_concatenation (op1, op2)))
13950     return result;
13951
13952   /* Discard empty strings on either side of the expression */
13953   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
13954     {
13955       op1 = op2;
13956       op2 = NULL_TREE;
13957     }
13958   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
13959     op2 = NULL_TREE;
13960
13961   /* If operands are string constant, turn then into object references */
13962   if (TREE_CODE (op1) == STRING_CST)
13963     op1 = patch_string_cst (op1);
13964   if (op2 && TREE_CODE (op2) == STRING_CST)
13965     op2 = patch_string_cst (op2);
13966
13967   /* If either one of the constant is null and the other non null
13968      operand is a String object, return it. */
13969   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
13970     return op1;
13971
13972   /* If OP1 isn't already a StringBuffer, create and
13973      initialize a new one */
13974   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
13975     {
13976       /* Two solutions here: 
13977          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
13978          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
13979       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
13980         op1 = BUILD_STRING_BUFFER (op1);
13981       else
13982         {
13983           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
13984           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
13985         }
13986     }
13987
13988   if (op2)
13989     {
13990       /* OP1 is no longer the last node holding a crafted StringBuffer */
13991       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
13992       /* Create a node for `{new...,xxx}.append (op2)' */
13993       if (op2)
13994         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
13995     }
13996
13997   /* Mark the last node holding a crafted StringBuffer */
13998   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
13999
14000   TREE_SIDE_EFFECTS (op1) = side_effects;
14001   return op1;
14002 }
14003
14004 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
14005    StringBuffer. If no string were found to be patched, return
14006    NULL. */
14007
14008 static tree
14009 patch_string (node)
14010     tree node;
14011 {
14012   if (node == error_mark_node)
14013     return error_mark_node;
14014   if (TREE_CODE (node) == STRING_CST)
14015     return patch_string_cst (node);
14016   else if (IS_CRAFTED_STRING_BUFFER_P (node))
14017     {
14018       int saved = ctxp->explicit_constructor_p;
14019       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
14020       tree ret;
14021       /* Temporary disable forbid the use of `this'. */
14022       ctxp->explicit_constructor_p = 0;
14023       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
14024       /* String concatenation arguments must be evaluated in order too. */
14025       ret = force_evaluation_order (ret);
14026       /* Restore it at its previous value */
14027       ctxp->explicit_constructor_p = saved;
14028       return ret;
14029     }
14030   return NULL_TREE;
14031 }
14032
14033 /* Build the internal representation of a string constant.  */
14034
14035 static tree
14036 patch_string_cst (node)
14037      tree node;
14038 {
14039   int location;
14040   if (! flag_emit_class_files)
14041     {
14042       node = get_identifier (TREE_STRING_POINTER (node));
14043       location = alloc_name_constant (CONSTANT_String, node);
14044       node = build_ref_from_constant_pool (location);
14045     }
14046   TREE_TYPE (node) = string_ptr_type_node;
14047   TREE_CONSTANT (node) = 1;
14048   return node;
14049 }
14050
14051 /* Build an incomplete unary operator expression. */
14052
14053 static tree
14054 build_unaryop (op_token, op_location, op1)
14055      int op_token, op_location;
14056      tree op1;
14057 {
14058   enum tree_code op;
14059   tree unaryop;
14060   switch (op_token)
14061     {
14062     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
14063     case MINUS_TK: op = NEGATE_EXPR; break;
14064     case NEG_TK: op = TRUTH_NOT_EXPR; break;
14065     case NOT_TK: op = BIT_NOT_EXPR; break;
14066     default: abort ();
14067     }
14068
14069   unaryop = build1 (op, NULL_TREE, op1);
14070   TREE_SIDE_EFFECTS (unaryop) = 1;
14071   /* Store the location of the operator, for better error report. The
14072      string of the operator will be rebuild based on the OP value. */
14073   EXPR_WFL_LINECOL (unaryop) = op_location;
14074   return unaryop;
14075 }
14076
14077 /* Special case for the ++/-- operators, since they require an extra
14078    argument to build, which is set to NULL and patched
14079    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
14080
14081 static tree
14082 build_incdec (op_token, op_location, op1, is_post_p)
14083      int op_token, op_location;
14084      tree op1;
14085      int is_post_p;
14086 {
14087   static enum tree_code lookup [2][2] = 
14088     {
14089       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
14090       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
14091     };
14092   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
14093                      NULL_TREE, op1, NULL_TREE);
14094   TREE_SIDE_EFFECTS (node) = 1;
14095   /* Store the location of the operator, for better error report. The
14096      string of the operator will be rebuild based on the OP value. */
14097   EXPR_WFL_LINECOL (node) = op_location;
14098   return node;
14099 }     
14100
14101 /* Build an incomplete cast operator, based on the use of the
14102    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
14103    set. java_complete_tree is trained to walk a CONVERT_EXPR even
14104    though its type is already set.  */
14105
14106 static tree
14107 build_cast (location, type, exp)
14108      int location;
14109      tree type, exp;
14110 {
14111   tree node = build1 (CONVERT_EXPR, type, exp);
14112   EXPR_WFL_LINECOL (node) = location;
14113   return node;
14114 }
14115
14116 /* Build an incomplete class reference operator.  */
14117 static tree
14118 build_incomplete_class_ref (location, class_name)
14119     int location;
14120     tree class_name;
14121 {
14122   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
14123   EXPR_WFL_LINECOL (node) = location;
14124   return node;
14125 }
14126
14127 /* Complete an incomplete class reference operator.  */
14128 static tree
14129 patch_incomplete_class_ref (node)
14130     tree node;
14131 {
14132   tree type = TREE_OPERAND (node, 0);
14133   tree ref_type;
14134
14135   if (!(ref_type = resolve_type_during_patch (type)))
14136     return error_mark_node;
14137
14138   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
14139     {
14140       tree dot = build_class_ref (ref_type);
14141       /* A class referenced by `foo.class' is initialized.  */
14142       if (!flag_emit_class_files)
14143        dot = build_class_init (ref_type, dot);
14144       return java_complete_tree (dot);
14145     }
14146
14147   /* If we're emitting class files and we have to deal with non
14148      primitive types, we invoke (and consider generating) the
14149      synthetic static method `class$'. */
14150   if (!TYPE_DOT_CLASS (current_class))
14151       build_dot_class_method (current_class);
14152   ref_type = build_dot_class_method_invocation (ref_type);
14153   return java_complete_tree (ref_type);
14154 }
14155
14156 /* 15.14 Unary operators. We return error_mark_node in case of error,
14157    but preserve the type of NODE if the type is fixed.  */
14158
14159 static tree
14160 patch_unaryop (node, wfl_op)
14161      tree node;
14162      tree wfl_op;
14163 {
14164   tree op = TREE_OPERAND (node, 0);
14165   tree op_type = TREE_TYPE (op);
14166   tree prom_type = NULL_TREE, value, decl;
14167   int outer_field_flag = 0;
14168   int code = TREE_CODE (node);
14169   int error_found = 0;
14170
14171   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14172
14173   switch (code)
14174     {
14175       /* 15.13.2 Postfix Increment Operator ++ */
14176     case POSTINCREMENT_EXPR:
14177       /* 15.13.3 Postfix Increment Operator -- */
14178     case POSTDECREMENT_EXPR:
14179       /* 15.14.1 Prefix Increment Operator ++ */
14180     case PREINCREMENT_EXPR:
14181       /* 15.14.2 Prefix Decrement Operator -- */
14182     case PREDECREMENT_EXPR:
14183       op = decl = strip_out_static_field_access_decl (op);
14184       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
14185       /* We might be trying to change an outer field accessed using
14186          access method. */
14187       if (outer_field_flag)
14188         {
14189           /* Retrieve the decl of the field we're trying to access. We
14190              do that by first retrieving the function we would call to
14191              access the field. It has been already verified that this
14192              field isn't final */
14193           if (flag_emit_class_files)
14194             decl = TREE_OPERAND (op, 0);
14195           else
14196             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
14197           decl = DECL_FUNCTION_ACCESS_DECL (decl);
14198         }
14199       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
14200       else if (!JDECL_P (decl) 
14201           && TREE_CODE (decl) != COMPONENT_REF
14202           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
14203           && TREE_CODE (decl) != INDIRECT_REF
14204           && !(TREE_CODE (decl) == COMPOUND_EXPR
14205                && TREE_OPERAND (decl, 1)
14206                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
14207         {
14208           tree lvalue;
14209           /* Before screaming, check that we're not in fact trying to
14210              increment a optimized static final access, in which case
14211              we issue an different error message. */
14212           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
14213                 && resolve_expression_name (wfl_op, &lvalue)
14214                 && check_final_assignment (lvalue, wfl_op)))
14215             parse_error_context (wfl_operator, "Invalid argument to `%s'",
14216                                  operator_string (node));
14217           TREE_TYPE (node) = error_mark_node;
14218           error_found = 1;
14219         }
14220       
14221       if (check_final_assignment (op, wfl_op))
14222         error_found = 1;
14223
14224       /* From now on, we know that op if a variable and that it has a
14225          valid wfl. We use wfl_op to locate errors related to the
14226          ++/-- operand. */
14227       else if (!JNUMERIC_TYPE_P (op_type))
14228         {
14229           parse_error_context
14230             (wfl_op, "Invalid argument type `%s' to `%s'",
14231              lang_printable_name (op_type, 0), operator_string (node));
14232           TREE_TYPE (node) = error_mark_node;
14233           error_found = 1;
14234         }
14235       else
14236         {
14237           /* Before the addition, binary numeric promotion is performed on
14238              both operands, if really necessary */
14239           if (JINTEGRAL_TYPE_P (op_type))
14240             {
14241               value = build_int_2 (1, 0);
14242               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
14243             }
14244           else
14245             {
14246               value = build_int_2 (1, 0);
14247               TREE_TYPE (node) = 
14248                 binary_numeric_promotion (op_type, 
14249                                           TREE_TYPE (value), &op, &value);
14250             }
14251
14252           /* We remember we might be accessing an outer field */
14253           if (outer_field_flag)
14254             {
14255               /* We re-generate an access to the field */
14256               value = build (PLUS_EXPR, TREE_TYPE (op), 
14257                              build_outer_field_access (wfl_op, decl), value);
14258                                                     
14259               /* And we patch the original access$() into a write 
14260                  with plus_op as a rhs */
14261               return outer_field_access_fix (node, op, value);
14262             }
14263
14264           /* And write back into the node. */
14265           TREE_OPERAND (node, 0) = op;
14266           TREE_OPERAND (node, 1) = value;
14267           /* Convert the overall back into its original type, if
14268              necessary, and return */
14269           if (JINTEGRAL_TYPE_P (op_type))
14270             return fold (node);
14271           else
14272             return fold (convert (op_type, node));
14273         }
14274       break;
14275
14276       /* 15.14.3 Unary Plus Operator + */
14277     case UNARY_PLUS_EXPR:
14278       /* 15.14.4 Unary Minus Operator - */
14279     case NEGATE_EXPR:
14280       if (!JNUMERIC_TYPE_P (op_type))
14281         {
14282           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
14283           TREE_TYPE (node) = error_mark_node;
14284           error_found = 1;
14285         }
14286       /* Unary numeric promotion is performed on operand */
14287       else
14288         {
14289           op = do_unary_numeric_promotion (op);
14290           prom_type = TREE_TYPE (op);
14291           if (code == UNARY_PLUS_EXPR)
14292             return fold (op);
14293         }
14294       break;
14295
14296       /* 15.14.5 Bitwise Complement Operator ~ */
14297     case BIT_NOT_EXPR:
14298       if (!JINTEGRAL_TYPE_P (op_type))
14299         {
14300           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
14301           TREE_TYPE (node) = error_mark_node;
14302           error_found = 1;
14303         }
14304       else
14305         {
14306           op = do_unary_numeric_promotion (op);
14307           prom_type = TREE_TYPE (op);
14308         }
14309       break;
14310
14311       /* 15.14.6 Logical Complement Operator ! */
14312     case TRUTH_NOT_EXPR:
14313       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
14314         {
14315           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
14316           /* But the type is known. We will report an error if further
14317              attempt of a assignment is made with this rhs */
14318           TREE_TYPE (node) = boolean_type_node;
14319           error_found = 1;
14320         }
14321       else
14322         prom_type = boolean_type_node;
14323       break;
14324
14325       /* 15.15 Cast Expression */
14326     case CONVERT_EXPR:
14327       value = patch_cast (node, wfl_operator);
14328       if (value == error_mark_node)
14329         {
14330           /* If this cast is part of an assignment, we tell the code
14331              that deals with it not to complain about a mismatch,
14332              because things have been cast, anyways */
14333           TREE_TYPE (node) = error_mark_node;
14334           error_found = 1;
14335         }
14336       else
14337         {
14338           value = fold (value);
14339           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
14340           return value;
14341         }
14342       break;
14343     }
14344   
14345   if (error_found)
14346     return error_mark_node;
14347
14348   /* There are cases where node has been replaced by something else
14349      and we don't end up returning here: UNARY_PLUS_EXPR,
14350      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
14351   TREE_OPERAND (node, 0) = fold (op);
14352   TREE_TYPE (node) = prom_type;
14353   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
14354   return fold (node);
14355 }
14356
14357 /* Generic type resolution that sometimes takes place during node
14358    patching. Returned the resolved type or generate an error
14359    message. Return the resolved type or NULL_TREE.  */
14360
14361 static tree
14362 resolve_type_during_patch (type)
14363      tree type;
14364 {
14365   if (unresolved_type_p (type, NULL))
14366     {
14367       tree type_decl = resolve_and_layout (EXPR_WFL_NODE (type), type);
14368       if (!type_decl)
14369         {
14370           parse_error_context (type, 
14371                                "Class `%s' not found in type declaration",
14372                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
14373           return NULL_TREE;
14374         }
14375       return TREE_TYPE (type_decl);
14376     }
14377   return type;
14378 }
14379 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
14380    found. Otherwise NODE or something meant to replace it is returned.  */
14381
14382 static tree
14383 patch_cast (node, wfl_op)
14384      tree node;
14385      tree wfl_op;
14386 {
14387   tree op = TREE_OPERAND (node, 0);
14388   tree op_type = TREE_TYPE (op);
14389   tree cast_type = TREE_TYPE (node);
14390   char *t1;
14391
14392   /* First resolve OP_TYPE if unresolved */
14393   if (!(cast_type = resolve_type_during_patch (cast_type)))
14394     return error_mark_node;
14395
14396   /* Check on cast that are proven correct at compile time */
14397   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
14398     {
14399       /* Same type */
14400       if (cast_type == op_type)
14401         return node;
14402
14403       /* float and double type are converted to the original type main
14404          variant and then to the target type. */
14405       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
14406         op = convert (integer_type_node, op);
14407
14408       /* Try widening/narowwing convertion. Potentially, things need
14409          to be worked out in gcc so we implement the extreme cases
14410          correctly. fold_convert() needs to be fixed. */
14411       return convert (cast_type, op);
14412     }
14413
14414   /* It's also valid to cast a boolean into a boolean */
14415   if (op_type == boolean_type_node && cast_type == boolean_type_node)
14416     return node;
14417
14418   /* null can be casted to references */
14419   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
14420     return build_null_of_type (cast_type);
14421
14422   /* The remaining legal casts involve conversion between reference
14423      types. Check for their compile time correctness. */
14424   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
14425       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
14426     {
14427       TREE_TYPE (node) = promote_type (cast_type);
14428       /* Now, the case can be determined correct at compile time if
14429          OP_TYPE can be converted into CAST_TYPE by assignment
14430          conversion (5.2) */
14431
14432       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
14433         {
14434           TREE_SET_CODE (node, NOP_EXPR);
14435           return node;
14436         }
14437
14438       if (flag_emit_class_files)
14439         {
14440           TREE_SET_CODE (node, CONVERT_EXPR);
14441           return node;
14442         }
14443
14444       /* The cast requires a run-time check */
14445       return build (CALL_EXPR, promote_type (cast_type),
14446                     build_address_of (soft_checkcast_node),
14447                     tree_cons (NULL_TREE, build_class_ref (cast_type),
14448                                build_tree_list (NULL_TREE, op)),
14449                     NULL_TREE);
14450     }
14451
14452   /* Any other casts are proven incorrect at compile time */
14453   t1 = xstrdup (lang_printable_name (op_type, 0));
14454   parse_error_context (wfl_op, "Invalid cast from `%s' to `%s'",
14455                        t1, lang_printable_name (cast_type, 0));
14456   free (t1);
14457   return error_mark_node;
14458 }
14459
14460 /* Build a null constant and give it the type TYPE.  */
14461
14462 static tree
14463 build_null_of_type (type)
14464      tree type;
14465 {
14466   tree node = build_int_2 (0, 0);
14467   TREE_TYPE (node) = promote_type (type);
14468   return node;
14469 }
14470
14471 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
14472    a list of indices. */
14473 static tree
14474 build_array_ref (location, array, index)
14475      int location;
14476      tree array, index;
14477 {
14478   tree node = build (ARRAY_REF, NULL_TREE, array, index);
14479   EXPR_WFL_LINECOL (node) = location;
14480   return node;
14481 }
14482
14483 /* 15.12 Array Access Expression */
14484
14485 static tree
14486 patch_array_ref (node)
14487      tree node;
14488 {
14489   tree array = TREE_OPERAND (node, 0);
14490   tree array_type  = TREE_TYPE (array);
14491   tree index = TREE_OPERAND (node, 1);
14492   tree index_type = TREE_TYPE (index);
14493   int error_found = 0;
14494
14495   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14496
14497   if (TREE_CODE (array_type) == POINTER_TYPE)
14498     array_type = TREE_TYPE (array_type);
14499
14500   /* The array reference must be an array */
14501   if (!TYPE_ARRAY_P (array_type))
14502     {
14503       parse_error_context 
14504         (wfl_operator,
14505          "`[]' can only be applied to arrays. It can't be applied to `%s'",
14506          lang_printable_name (array_type, 0));
14507       TREE_TYPE (node) = error_mark_node;
14508       error_found = 1;
14509     }
14510
14511   /* The array index undergoes unary numeric promotion. The promoted
14512      type must be int */
14513   index = do_unary_numeric_promotion (index);
14514   if (TREE_TYPE (index) != int_type_node)
14515     {
14516       if (valid_cast_to_p (index_type, int_type_node))
14517         parse_error_context (wfl_operator,
14518    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
14519                              lang_printable_name (index_type, 0));
14520       else
14521         parse_error_context (wfl_operator,
14522           "Incompatible type for `[]'. Can't convert `%s' to `int'",
14523                              lang_printable_name (index_type, 0));
14524       TREE_TYPE (node) = error_mark_node;
14525       error_found = 1;
14526     }
14527
14528   if (error_found)
14529     return error_mark_node;
14530
14531   array_type = TYPE_ARRAY_ELEMENT (array_type);
14532
14533   if (flag_emit_class_files || flag_emit_xref)
14534     {
14535       TREE_OPERAND (node, 0) = array;
14536       TREE_OPERAND (node, 1) = index;
14537     }
14538   else
14539     {
14540       /* The save_expr is for correct evaluation order.  It would be cleaner
14541          to use force_evaluation_order (see comment there), but that is
14542          difficult when we also have to deal with bounds checking. */
14543       if (TREE_SIDE_EFFECTS (index))
14544         array = save_expr (array);
14545       node = build_java_arrayaccess (array, array_type, index);
14546       if (TREE_SIDE_EFFECTS (index))
14547         node = build (COMPOUND_EXPR, array_type, array, node);
14548     }
14549   TREE_TYPE (node) = array_type;
14550   return node;
14551 }
14552
14553 /* 15.9 Array Creation Expressions */
14554
14555 static tree
14556 build_newarray_node (type, dims, extra_dims)
14557      tree type;
14558      tree dims;
14559      int extra_dims;
14560 {
14561   tree node =
14562     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
14563            build_int_2 (extra_dims, 0));
14564   return node;
14565 }
14566
14567 static tree
14568 patch_newarray (node)
14569      tree node;
14570 {
14571   tree type = TREE_OPERAND (node, 0);
14572   tree dims = TREE_OPERAND (node, 1);
14573   tree cdim, array_type;
14574   int error_found = 0;
14575   int ndims = 0;
14576   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
14577
14578   /* Dimension types are verified. It's better for the types to be
14579      verified in order. */
14580   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
14581     {
14582       int dim_error = 0;
14583       tree dim = TREE_VALUE (cdim);
14584
14585       /* Dim might have been saved during its evaluation */
14586       dim = (TREE_CODE (dim) == SAVE_EXPR ? TREE_OPERAND (dim, 0) : dim);
14587
14588       /* The type of each specified dimension must be an integral type. */
14589       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
14590         dim_error = 1;
14591
14592       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
14593          promoted type must be int. */
14594       else
14595         {
14596           dim = do_unary_numeric_promotion (dim);
14597           if (TREE_TYPE (dim) != int_type_node)
14598             dim_error = 1;
14599         }
14600
14601       /* Report errors on types here */
14602       if (dim_error)
14603         {
14604           parse_error_context 
14605             (TREE_PURPOSE (cdim), 
14606              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
14607              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
14608               "Explicit cast needed to" : "Can't"),
14609              lang_printable_name (TREE_TYPE (dim), 0));
14610           error_found = 1;
14611         }
14612
14613       TREE_PURPOSE (cdim) = NULL_TREE;
14614     }
14615
14616   /* Resolve array base type if unresolved */
14617   if (!(type = resolve_type_during_patch (type)))
14618     error_found = 1;
14619
14620   if (error_found)
14621     {
14622       /* We don't want further evaluation of this bogus array creation
14623          operation */
14624       TREE_TYPE (node) = error_mark_node;
14625       return error_mark_node;
14626     }
14627
14628   /* Set array_type to the actual (promoted) array type of the result. */
14629   if (TREE_CODE (type) == RECORD_TYPE)
14630     type = build_pointer_type (type);
14631   while (--xdims >= 0)
14632     {
14633       type = promote_type (build_java_array_type (type, -1));
14634     }
14635   dims = nreverse (dims);
14636   array_type = type;
14637   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
14638     {
14639       type = array_type;
14640       array_type
14641         = build_java_array_type (type,
14642                                  TREE_CODE (cdim) == INTEGER_CST
14643                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
14644                                  : -1);
14645       array_type = promote_type (array_type);
14646     }
14647   dims = nreverse (dims);
14648
14649   /* The node is transformed into a function call. Things are done
14650      differently according to the number of dimensions. If the number
14651      of dimension is equal to 1, then the nature of the base type
14652      (primitive or not) matters. */
14653   if (ndims == 1)
14654     return build_new_array (type, TREE_VALUE (dims));
14655   
14656   /* Can't reuse what's already written in expr.c because it uses the
14657      JVM stack representation. Provide a build_multianewarray. FIXME */
14658   return build (CALL_EXPR, array_type,
14659                 build_address_of (soft_multianewarray_node),
14660                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
14661                            tree_cons (NULL_TREE, 
14662                                       build_int_2 (ndims, 0), dims )),
14663                 NULL_TREE);
14664 }
14665
14666 /* 10.6 Array initializer.  */
14667
14668 /* Build a wfl for array element that don't have one, so we can
14669    pin-point errors.  */
14670
14671 static tree
14672 maybe_build_array_element_wfl (node)
14673      tree node;
14674 {
14675   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
14676     return build_expr_wfl (NULL_TREE, ctxp->filename,
14677                            ctxp->elc.line, ctxp->elc.prev_col);
14678   else
14679     return NULL_TREE;
14680 }
14681
14682 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
14683    identification of initialized arrays easier to detect during walk
14684    and expansion.  */
14685
14686 static tree
14687 build_new_array_init (location, values)
14688      int location;
14689      tree values;
14690 {
14691   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
14692   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
14693   EXPR_WFL_LINECOL (to_return) = location;
14694   return to_return;
14695 }
14696
14697 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
14698    occurred.  Otherwise return NODE after having set its type
14699    appropriately.  */
14700
14701 static tree
14702 patch_new_array_init (type, node)
14703      tree type, node;
14704 {
14705   int error_seen = 0;
14706   tree current, element_type;
14707   HOST_WIDE_INT length;
14708   int all_constant = 1;
14709   tree init = TREE_OPERAND (node, 0);
14710
14711   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
14712     {
14713       parse_error_context (node,
14714                            "Invalid array initializer for non-array type `%s'",
14715                            lang_printable_name (type, 1));
14716       return error_mark_node;
14717     }
14718   type = TREE_TYPE (type);
14719   element_type = TYPE_ARRAY_ELEMENT (type);
14720
14721   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
14722
14723   for (length = 0, current = CONSTRUCTOR_ELTS (init);
14724        current;  length++, current = TREE_CHAIN (current))
14725     {
14726       tree elt = TREE_VALUE (current);
14727       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
14728         {
14729           error_seen |= array_constructor_check_entry (element_type, current);
14730           elt = TREE_VALUE (current);
14731           /* When compiling to native code, STRING_CST is converted to
14732              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
14733           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
14734             all_constant = 0;
14735         }
14736       else
14737         {
14738           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
14739           TREE_PURPOSE (current) = NULL_TREE;
14740           all_constant = 0;
14741         }
14742       if (elt && TREE_CODE (elt) == TREE_LIST 
14743           && TREE_VALUE (elt) == error_mark_node)
14744         error_seen = 1;
14745     }
14746
14747   if (error_seen)
14748     return error_mark_node;
14749
14750   /* Create a new type. We can't reuse the one we have here by
14751      patching its dimension because it originally is of dimension -1
14752      hence reused by gcc. This would prevent triangular arrays. */
14753   type = build_java_array_type (element_type, length);
14754   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
14755   TREE_TYPE (node) = promote_type (type);
14756   TREE_CONSTANT (init) = all_constant;
14757   TREE_CONSTANT (node) = all_constant;
14758   return node;
14759 }
14760
14761 /* Verify that one entry of the initializer element list can be
14762    assigned to the array base type. Report 1 if an error occurred, 0
14763    otherwise.  */
14764
14765 static int
14766 array_constructor_check_entry (type, entry)
14767      tree type, entry;
14768 {
14769   char *array_type_string = NULL;       /* For error reports */
14770   tree value, type_value, new_value, wfl_value, patched;
14771   int error_seen = 0;
14772
14773   new_value = NULL_TREE;
14774   wfl_value = TREE_VALUE (entry);
14775
14776   value = java_complete_tree (TREE_VALUE (entry));
14777   /* patch_string return error_mark_node if arg is error_mark_node */
14778   if ((patched = patch_string (value)))
14779     value = patched;
14780   if (value == error_mark_node)
14781     return 1;
14782   
14783   type_value = TREE_TYPE (value);
14784   
14785   /* At anytime, try_builtin_assignconv can report a warning on
14786      constant overflow during narrowing. */
14787   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
14788   new_value = try_builtin_assignconv (wfl_operator, type, value);
14789   if (!new_value && (new_value = try_reference_assignconv (type, value)))
14790     type_value = promote_type (type);
14791
14792   /* Check and report errors */
14793   if (!new_value)
14794     {
14795       const char *msg = (!valid_cast_to_p (type_value, type) ?
14796                    "Can't" : "Explicit cast needed to");
14797       if (!array_type_string)
14798         array_type_string = xstrdup (lang_printable_name (type, 1));
14799       parse_error_context 
14800         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
14801          msg, lang_printable_name (type_value, 1), array_type_string);
14802       error_seen = 1;
14803     }
14804   
14805   if (new_value)
14806     {
14807       new_value = maybe_build_primttype_type_ref (new_value, wfl_value);
14808       TREE_VALUE (entry) = new_value;
14809     }
14810
14811   if (array_type_string)
14812     free (array_type_string);
14813
14814   TREE_PURPOSE (entry) = NULL_TREE;
14815   return error_seen;
14816 }
14817
14818 static tree
14819 build_this (location)
14820      int location;
14821 {
14822   tree node = build_wfl_node (this_identifier_node);
14823   TREE_SET_CODE (node, THIS_EXPR);
14824   EXPR_WFL_LINECOL (node) = location;
14825   return node;
14826 }
14827
14828 /* 14.15 The return statement. It builds a modify expression that
14829    assigns the returned value to the RESULT_DECL that hold the value
14830    to be returned. */
14831
14832 static tree
14833 build_return (location, op)
14834      int location;
14835      tree op;
14836 {
14837   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
14838   EXPR_WFL_LINECOL (node) = location;
14839   node = build_debugable_stmt (location, node);
14840   return node;
14841 }
14842
14843 static tree
14844 patch_return (node)
14845      tree node;
14846 {
14847   tree return_exp = TREE_OPERAND (node, 0);
14848   tree meth = current_function_decl;
14849   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
14850   int error_found = 0;
14851
14852   TREE_TYPE (node) = error_mark_node;
14853   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14854
14855   /* It's invalid to have a return value within a function that is
14856      declared with the keyword void or that is a constructor */
14857   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
14858     error_found = 1;
14859
14860   /* It's invalid to use a return statement in a static block */
14861   if (DECL_CLINIT_P (current_function_decl))
14862     error_found = 1;
14863
14864   /* It's invalid to have a no return value within a function that
14865      isn't declared with the keyword `void' */
14866   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
14867     error_found = 2;
14868   
14869   if (DECL_INSTINIT_P (current_function_decl))
14870     error_found = 1;
14871
14872   if (error_found)
14873     {
14874       if (DECL_INSTINIT_P (current_function_decl))
14875         parse_error_context (wfl_operator,
14876                              "`return' inside instance initializer");
14877         
14878       else if (DECL_CLINIT_P (current_function_decl))
14879         parse_error_context (wfl_operator,
14880                              "`return' inside static initializer");
14881
14882       else if (!DECL_CONSTRUCTOR_P (meth))
14883         {
14884           char *t = xstrdup (lang_printable_name (mtype, 0));
14885           parse_error_context (wfl_operator, 
14886                                "`return' with%s value from `%s %s'",
14887                                (error_found == 1 ? "" : "out"), 
14888                                t, lang_printable_name (meth, 0));
14889           free (t);
14890         }
14891       else
14892         parse_error_context (wfl_operator, 
14893                              "`return' with value from constructor `%s'",
14894                              lang_printable_name (meth, 0));
14895       return error_mark_node;
14896     }
14897
14898   /* If we have a return_exp, build a modify expression and expand
14899      it. Note: at that point, the assignment is declared valid, but we
14900      may want to carry some more hacks */
14901   if (return_exp)
14902     {
14903       tree exp = java_complete_tree (return_exp);
14904       tree modify, patched;
14905
14906       /* If the function returned value and EXP are booleans, EXP has
14907       to be converted into the type of DECL_RESULT, which is integer
14908       (see complete_start_java_method) */
14909       if (TREE_TYPE (exp) == boolean_type_node &&
14910           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
14911         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
14912
14913       /* `null' can be assigned to a function returning a reference */
14914       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
14915           exp == null_pointer_node)
14916         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
14917
14918       if ((patched = patch_string (exp)))
14919         exp = patched;
14920       
14921       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
14922       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
14923       modify = java_complete_tree (modify);
14924
14925       if (modify != error_mark_node)
14926         {
14927           TREE_SIDE_EFFECTS (modify) = 1;
14928           TREE_OPERAND (node, 0) = modify;
14929         }
14930       else
14931         return error_mark_node;
14932     }
14933   TREE_TYPE (node) = void_type_node;
14934   TREE_SIDE_EFFECTS (node) = 1;
14935   return node;
14936 }
14937
14938 /* 14.8 The if Statement */
14939
14940 static tree
14941 build_if_else_statement (location, expression, if_body, else_body)
14942      int location;
14943      tree expression, if_body, else_body;
14944 {
14945   tree node;
14946   if (!else_body)
14947     else_body = empty_stmt_node;
14948   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
14949   EXPR_WFL_LINECOL (node) = location;
14950   node = build_debugable_stmt (location, node);
14951   return node;
14952 }
14953
14954 static tree
14955 patch_if_else_statement (node)
14956      tree node;
14957 {
14958   tree expression = TREE_OPERAND (node, 0);
14959
14960   TREE_TYPE (node) = error_mark_node;
14961   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14962
14963   /* The type of expression must be boolean */
14964   if (TREE_TYPE (expression) != boolean_type_node
14965       && TREE_TYPE (expression) != promoted_boolean_type_node)
14966     {
14967       parse_error_context 
14968         (wfl_operator, 
14969          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
14970          lang_printable_name (TREE_TYPE (expression), 0));
14971       return error_mark_node;
14972     }
14973   
14974   TREE_TYPE (node) = void_type_node;
14975   TREE_SIDE_EFFECTS (node) = 1;
14976   CAN_COMPLETE_NORMALLY (node)
14977     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
14978     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
14979   return node;
14980 }
14981
14982 /* 14.6 Labeled Statements */
14983
14984 /* Action taken when a lableled statement is parsed. a new
14985    LABELED_BLOCK_EXPR is created. No statement is attached to the
14986    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
14987
14988 static tree
14989 build_labeled_block (location, label)
14990      int location;
14991      tree label;
14992 {
14993   tree label_name ;
14994   tree label_decl, node;
14995   if (label == NULL_TREE || label == continue_identifier_node)
14996     label_name = label;
14997   else
14998     {
14999       label_name = merge_qualified_name (label_id, label);
15000       /* Issue an error if we try to reuse a label that was previously
15001          declared */
15002       if (IDENTIFIER_LOCAL_VALUE (label_name))
15003         {
15004           EXPR_WFL_LINECOL (wfl_operator) = location;
15005           parse_error_context (wfl_operator,
15006             "Declaration of `%s' shadows a previous label declaration",
15007                                IDENTIFIER_POINTER (label));
15008           EXPR_WFL_LINECOL (wfl_operator) = 
15009             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
15010           parse_error_context (wfl_operator,
15011             "This is the location of the previous declaration of label `%s'",
15012                                IDENTIFIER_POINTER (label));
15013           java_error_count--;
15014         }
15015     }
15016
15017   label_decl = create_label_decl (label_name);
15018   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
15019   EXPR_WFL_LINECOL (node) = location;
15020   TREE_SIDE_EFFECTS (node) = 1;
15021   return node;
15022 }
15023
15024 /* A labeled statement LBE is attached a statement.  */
15025
15026 static tree
15027 finish_labeled_statement (lbe, statement)
15028      tree lbe;                  /* Labeled block expr */
15029      tree statement;
15030 {
15031   /* In anyways, tie the loop to its statement */
15032   LABELED_BLOCK_BODY (lbe) = statement;
15033   pop_labeled_block ();
15034   POP_LABELED_BLOCK ();
15035   return lbe;
15036 }
15037
15038 /* 14.10, 14.11, 14.12 Loop Statements */
15039
15040 /* Create an empty LOOP_EXPR and make it the last in the nested loop
15041    list. */
15042
15043 static tree
15044 build_new_loop (loop_body)
15045      tree loop_body;
15046 {
15047   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
15048   TREE_SIDE_EFFECTS (loop) = 1;
15049   PUSH_LOOP (loop);
15050   return loop;
15051 }
15052
15053 /* Create a loop body according to the following structure:
15054      COMPOUND_EXPR
15055        COMPOUND_EXPR            (loop main body)
15056          EXIT_EXPR              (this order is for while/for loops.
15057          LABELED_BLOCK_EXPR      the order is reversed for do loops)
15058            LABEL_DECL           (a continue occuring here branches at the 
15059            BODY                  end of this labeled block)
15060        INCREMENT                (if any)
15061
15062   REVERSED, if non zero, tells that the loop condition expr comes
15063   after the body, like in the do-while loop.
15064
15065   To obtain a loop, the loop body structure described above is
15066   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
15067
15068    LABELED_BLOCK_EXPR
15069      LABEL_DECL                   (use this label to exit the loop)
15070      LOOP_EXPR
15071        <structure described above> */
15072
15073 static tree
15074 build_loop_body (location, condition, reversed)
15075      int location;
15076      tree condition;
15077      int reversed;
15078 {
15079   tree first, second, body;
15080
15081   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
15082   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
15083   condition = build_debugable_stmt (location, condition);
15084   TREE_SIDE_EFFECTS (condition) = 1;
15085
15086   body = build_labeled_block (0, continue_identifier_node);
15087   first = (reversed ? body : condition);
15088   second = (reversed ? condition : body);
15089   return 
15090     build (COMPOUND_EXPR, NULL_TREE, 
15091            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
15092 }
15093
15094 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
15095    their order) on the current loop. Unlink the current loop from the
15096    loop list.  */
15097
15098 static tree
15099 finish_loop_body (location, condition, body, reversed)
15100      int location;
15101      tree condition, body;
15102      int reversed;
15103 {
15104   tree to_return = ctxp->current_loop;
15105   tree loop_body = LOOP_EXPR_BODY (to_return);
15106   if (condition)
15107     {
15108       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
15109       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
15110          The real EXIT_EXPR is one operand further. */
15111       EXPR_WFL_LINECOL (cnode) = location;
15112       /* This one is for accurate error reports */
15113       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
15114       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
15115     }
15116   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
15117   POP_LOOP ();
15118   return to_return;
15119 }
15120
15121 /* Tailored version of finish_loop_body for FOR loops, when FOR
15122    loops feature the condition part */
15123
15124 static tree
15125 finish_for_loop (location, condition, update, body)
15126     int location;
15127     tree condition, update, body;
15128 {
15129   /* Put the condition and the loop body in place */
15130   tree loop = finish_loop_body (location, condition, body, 0);
15131   /* LOOP is the current loop which has been now popped of the loop
15132      stack. Install the update block */
15133   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
15134   return loop;
15135 }
15136
15137 /* Try to find the loop a block might be related to. This comprises
15138    the case where the LOOP_EXPR is found as the second operand of a
15139    COMPOUND_EXPR, because the loop happens to have an initialization
15140    part, then expressed as the first operand of the COMPOUND_EXPR. If
15141    the search finds something, 1 is returned. Otherwise, 0 is
15142    returned. The search is assumed to start from a
15143    LABELED_BLOCK_EXPR's block.  */
15144
15145 static tree
15146 search_loop (statement)
15147     tree statement;
15148 {
15149   if (TREE_CODE (statement) == LOOP_EXPR)
15150     return statement;
15151
15152   if (TREE_CODE (statement) == BLOCK)
15153     statement = BLOCK_SUBBLOCKS (statement);
15154   else
15155     return NULL_TREE;
15156
15157   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
15158     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
15159       statement = TREE_OPERAND (statement, 1);
15160
15161   return (TREE_CODE (statement) == LOOP_EXPR
15162           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
15163 }
15164
15165 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
15166    returned otherwise.  */
15167
15168 static int
15169 labeled_block_contains_loop_p (block, loop)
15170     tree block, loop;
15171 {
15172   if (!block)
15173     return 0;
15174
15175   if (LABELED_BLOCK_BODY (block) == loop)
15176     return 1;
15177
15178   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
15179     return 1;
15180
15181   return 0;
15182 }
15183
15184 /* If the loop isn't surrounded by a labeled statement, create one and
15185    insert LOOP as its body.  */
15186
15187 static tree
15188 patch_loop_statement (loop)
15189      tree loop;
15190 {
15191   tree loop_label;
15192
15193   TREE_TYPE (loop) = void_type_node;
15194   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
15195     return loop;
15196
15197   loop_label = build_labeled_block (0, NULL_TREE);
15198   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
15199      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
15200   LABELED_BLOCK_BODY (loop_label) = loop;
15201   PUSH_LABELED_BLOCK (loop_label);
15202   return loop_label;
15203 }
15204
15205 /* 14.13, 14.14: break and continue Statements */
15206
15207 /* Build a break or a continue statement. a null NAME indicates an
15208    unlabeled break/continue statement.  */
15209
15210 static tree
15211 build_bc_statement (location, is_break, name)
15212      int location, is_break;
15213      tree name;
15214 {
15215   tree break_continue, label_block_expr = NULL_TREE;
15216
15217   if (name)
15218     {
15219       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
15220             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
15221         /* Null means that we don't have a target for this named
15222            break/continue. In this case, we make the target to be the
15223            label name, so that the error can be reported accuratly in
15224            patch_bc_statement. */
15225         label_block_expr = EXPR_WFL_NODE (name);
15226     }
15227   /* Unlabeled break/continue will be handled during the
15228      break/continue patch operation */
15229   break_continue 
15230     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
15231
15232   IS_BREAK_STMT_P (break_continue) = is_break;
15233   TREE_SIDE_EFFECTS (break_continue) = 1;
15234   EXPR_WFL_LINECOL (break_continue) = location;
15235   break_continue = build_debugable_stmt (location, break_continue);
15236   return break_continue;
15237 }
15238
15239 /* Verification of a break/continue statement. */
15240
15241 static tree
15242 patch_bc_statement (node)
15243      tree node;
15244 {
15245   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
15246   tree labeled_block = ctxp->current_labeled_block;
15247   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15248  
15249   /* Having an identifier here means that the target is unknown. */
15250   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
15251     {
15252       parse_error_context (wfl_operator, "No label definition found for `%s'",
15253                            IDENTIFIER_POINTER (bc_label));
15254       return error_mark_node;
15255     }
15256   if (! IS_BREAK_STMT_P (node))
15257     {
15258       /* It's a continue statement. */
15259       for (;; labeled_block = TREE_CHAIN (labeled_block))
15260         {
15261           if (labeled_block == NULL_TREE)
15262             {
15263               if (bc_label == NULL_TREE)
15264                 parse_error_context (wfl_operator,
15265                                      "`continue' must be in loop");
15266               else
15267                 parse_error_context 
15268                   (wfl_operator, "continue label `%s' does not name a loop",
15269                    IDENTIFIER_POINTER (bc_label));
15270               return error_mark_node;
15271             }
15272           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
15273                == continue_identifier_node)
15274               && (bc_label == NULL_TREE
15275                   || TREE_CHAIN (labeled_block) == bc_label))
15276             {
15277               bc_label = labeled_block;
15278               break;
15279             }
15280         }
15281     }
15282   else if (!bc_label)
15283     { 
15284       for (;; labeled_block = TREE_CHAIN (labeled_block))
15285         {
15286           if (labeled_block == NULL_TREE)
15287             {
15288               parse_error_context (wfl_operator,
15289                                      "`break' must be in loop or switch");
15290               return error_mark_node;
15291             }
15292           target_stmt = LABELED_BLOCK_BODY (labeled_block);
15293           if (TREE_CODE (target_stmt) == SWITCH_EXPR
15294               || search_loop (target_stmt))
15295             {
15296               bc_label = labeled_block;
15297               break;
15298             }
15299         }
15300     }
15301
15302   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
15303   CAN_COMPLETE_NORMALLY (bc_label) = 1;
15304
15305   /* Our break/continue don't return values. */
15306   TREE_TYPE (node) = void_type_node;
15307   /* Encapsulate the break within a compound statement so that it's
15308      expanded all the times by expand_expr (and not clobbered
15309      sometimes, like after a if statement) */
15310   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
15311   TREE_SIDE_EFFECTS (node) = 1;
15312   return node;
15313 }
15314
15315 /* Process the exit expression belonging to a loop. Its type must be
15316    boolean.  */
15317
15318 static tree
15319 patch_exit_expr (node)
15320      tree node;
15321 {
15322   tree expression = TREE_OPERAND (node, 0);
15323   TREE_TYPE (node) = error_mark_node;
15324   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15325
15326   /* The type of expression must be boolean */
15327   if (TREE_TYPE (expression) != boolean_type_node)
15328     {
15329       parse_error_context 
15330         (wfl_operator, 
15331     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
15332          lang_printable_name (TREE_TYPE (expression), 0));
15333       return error_mark_node;
15334     }
15335   /* Now we know things are allright, invert the condition, fold and
15336      return */
15337   TREE_OPERAND (node, 0) = 
15338     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
15339
15340   if (! integer_zerop (TREE_OPERAND (node, 0))
15341       && ctxp->current_loop != NULL_TREE
15342       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
15343     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
15344   if (! integer_onep (TREE_OPERAND (node, 0)))
15345     CAN_COMPLETE_NORMALLY (node) = 1;
15346
15347
15348   TREE_TYPE (node) = void_type_node;
15349   return node;
15350 }
15351
15352 /* 14.9 Switch statement */
15353
15354 static tree
15355 patch_switch_statement (node)
15356      tree node;
15357 {
15358   tree se = TREE_OPERAND (node, 0), se_type;
15359
15360   /* Complete the switch expression */
15361   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
15362   se_type = TREE_TYPE (se);
15363   /* The type of the switch expression must be char, byte, short or
15364      int */
15365   if (! JINTEGRAL_TYPE_P (se_type) || se_type == long_type_node)
15366     {
15367       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15368       parse_error_context (wfl_operator,
15369           "Incompatible type for `switch'. Can't convert `%s' to `int'",
15370                            lang_printable_name (se_type, 0));
15371       /* This is what java_complete_tree will check */
15372       TREE_OPERAND (node, 0) = error_mark_node;
15373       return error_mark_node;
15374     }
15375
15376   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
15377
15378   /* Ready to return */
15379   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
15380     {
15381       TREE_TYPE (node) = error_mark_node;
15382       return error_mark_node;
15383     }
15384   TREE_TYPE (node) = void_type_node;
15385   TREE_SIDE_EFFECTS (node) = 1;
15386   CAN_COMPLETE_NORMALLY (node)
15387     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
15388       || ! SWITCH_HAS_DEFAULT (node);
15389   return node;
15390 }
15391
15392 /* 14.18 The try/catch statements */
15393
15394 /* Encapsulate TRY_STMTS' in a try catch sequence. The catch clause
15395    catches TYPE and executes CATCH_STMTS.  */
15396
15397 static tree
15398 encapsulate_with_try_catch (location, type, try_stmts, catch_stmts)
15399      int location;
15400      tree type, try_stmts, catch_stmts;
15401 {
15402   tree try_block, catch_clause_param, catch_block, catch;
15403
15404   /* First build a try block */
15405   try_block = build_expr_block (try_stmts, NULL_TREE);
15406
15407   /* Build a catch block: we need a catch clause parameter */
15408   catch_clause_param = build_decl (VAR_DECL, 
15409                                    wpv_id, build_pointer_type (type));
15410   /* And a block */
15411   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
15412   
15413   /* Initialize the variable and store in the block */
15414   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
15415                  build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
15416   add_stmt_to_block (catch_block, NULL_TREE, catch);
15417
15418   /* Add the catch statements */
15419   add_stmt_to_block (catch_block, NULL_TREE, catch_stmts);
15420
15421   /* Now we can build a CATCH_EXPR */
15422   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
15423
15424   return build_try_statement (location, try_block, catch_block);
15425 }
15426
15427 static tree
15428 build_try_statement (location, try_block, catches)
15429      int location;
15430      tree try_block, catches;
15431 {
15432   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
15433   EXPR_WFL_LINECOL (node) = location;
15434   return node;
15435 }
15436
15437 static tree
15438 build_try_finally_statement (location, try_block, finally)
15439      int location;
15440      tree try_block, finally;
15441 {
15442   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
15443   EXPR_WFL_LINECOL (node) = location;
15444   return node;
15445 }
15446
15447 static tree
15448 patch_try_statement (node)
15449      tree node;
15450 {
15451   int error_found = 0;
15452   tree try = TREE_OPERAND (node, 0);
15453   /* Exception handlers are considered in left to right order */
15454   tree catch = nreverse (TREE_OPERAND (node, 1));
15455   tree current, caught_type_list = NULL_TREE;
15456
15457   /* Check catch clauses, if any. Every time we find an error, we try
15458      to process the next catch clause. We process the catch clause before
15459      the try block so that when processing the try block we can check thrown
15460      exceptions againts the caught type list. */
15461   for (current = catch; current; current = TREE_CHAIN (current))
15462     {
15463       tree carg_decl, carg_type;
15464       tree sub_current, catch_block, catch_clause;
15465       int unreachable;
15466
15467       /* At this point, the structure of the catch clause is
15468            CATCH_EXPR           (catch node)
15469              BLOCK              (with the decl of the parameter)
15470                COMPOUND_EXPR
15471                  MODIFY_EXPR   (assignment of the catch parameter)
15472                  BLOCK          (catch clause block)
15473        */
15474       catch_clause = TREE_OPERAND (current, 0);
15475       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
15476       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
15477
15478       /* Catch clauses can't have more than one parameter declared,
15479          but it's already enforced by the grammar. Make sure that the
15480          only parameter of the clause statement in of class Throwable
15481          or a subclass of Throwable, but that was done earlier. The
15482          catch clause parameter type has also been resolved. */
15483       
15484       /* Just make sure that the catch clause parameter type inherits
15485          from java.lang.Throwable */
15486       if (!inherits_from_p (carg_type, throwable_type_node))
15487         {
15488           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15489           parse_error_context (wfl_operator,
15490                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
15491                                lang_printable_name (carg_type, 0));
15492           error_found = 1;
15493           continue;
15494         }
15495       
15496       /* Partial check for unreachable catch statement: The catch
15497          clause is reachable iff is no earlier catch block A in
15498          the try statement such that the type of the catch
15499          clause's parameter is the same as or a subclass of the
15500          type of A's parameter */
15501       unreachable = 0;
15502       for (sub_current = catch;
15503            sub_current != current; sub_current = TREE_CHAIN (sub_current))
15504         {
15505           tree sub_catch_clause, decl;
15506           sub_catch_clause = TREE_OPERAND (sub_current, 0);
15507           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
15508
15509           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
15510             {
15511               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15512               parse_error_context 
15513                 (wfl_operator,
15514                  "`catch' not reached because of the catch clause at line %d",
15515                  EXPR_WFL_LINENO (sub_current));
15516               unreachable = error_found = 1;
15517               break;
15518             }
15519         }
15520       /* Complete the catch clause block */
15521       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
15522       if (catch_block == error_mark_node)
15523         {
15524           error_found = 1;
15525           continue;
15526         }
15527       if (CAN_COMPLETE_NORMALLY (catch_block))
15528         CAN_COMPLETE_NORMALLY (node) = 1;
15529       TREE_OPERAND (current, 0) = catch_block;
15530
15531       if (unreachable)
15532         continue;
15533
15534       /* Things to do here: the exception must be thrown */
15535
15536       /* Link this type to the caught type list */
15537       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
15538     }
15539
15540   PUSH_EXCEPTIONS (caught_type_list);
15541   if ((try = java_complete_tree (try)) == error_mark_node)
15542     error_found = 1;
15543   if (CAN_COMPLETE_NORMALLY (try))
15544     CAN_COMPLETE_NORMALLY (node) = 1;
15545   POP_EXCEPTIONS ();
15546
15547   /* Verification ends here */
15548   if (error_found) 
15549     return error_mark_node;
15550
15551   TREE_OPERAND (node, 0) = try;
15552   TREE_OPERAND (node, 1) = catch;
15553   TREE_TYPE (node) = void_type_node;
15554   return node;
15555 }
15556
15557 /* 14.17 The synchronized Statement */
15558
15559 static tree
15560 patch_synchronized_statement (node, wfl_op1)
15561     tree node, wfl_op1;
15562 {
15563   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
15564   tree block = TREE_OPERAND (node, 1);
15565
15566   tree tmp, enter, exit, expr_decl, assignment;
15567
15568   if (expr == error_mark_node)
15569     {
15570       block = java_complete_tree (block);
15571       return expr;
15572     }
15573
15574   /* We might be trying to synchronize on a STRING_CST */
15575   if ((tmp = patch_string (expr)))
15576     expr = tmp;
15577
15578   /* The TYPE of expr must be a reference type */
15579   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
15580     {
15581       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15582       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
15583                            lang_printable_name (TREE_TYPE (expr), 0));
15584       return error_mark_node;
15585     }
15586
15587   if (flag_emit_xref)
15588     {
15589       TREE_OPERAND (node, 0) = expr;
15590       TREE_OPERAND (node, 1) = java_complete_tree (block);
15591       CAN_COMPLETE_NORMALLY (node) = 1;
15592       return node;
15593     }
15594
15595   /* Generate a try-finally for the synchronized statement, except
15596      that the handler that catches all throw exception calls
15597      _Jv_MonitorExit and then rethrow the exception.
15598      The synchronized statement is then implemented as:
15599      TRY 
15600        {
15601          _Jv_MonitorEnter (expression)
15602          synchronized_block
15603          _Jv_MonitorExit (expression)
15604        }
15605      CATCH_ALL
15606        {
15607          e = _Jv_exception_info ();
15608          _Jv_MonitorExit (expression)
15609          Throw (e);
15610        } */
15611
15612   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
15613   BUILD_MONITOR_ENTER (enter, expr_decl);
15614   BUILD_MONITOR_EXIT (exit, expr_decl);
15615   CAN_COMPLETE_NORMALLY (enter) = 1;
15616   CAN_COMPLETE_NORMALLY (exit) = 1;
15617   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
15618   TREE_SIDE_EFFECTS (assignment) = 1;
15619   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
15620                  build (COMPOUND_EXPR, NULL_TREE,
15621                         build (WITH_CLEANUP_EXPR, NULL_TREE,
15622                                build (COMPOUND_EXPR, NULL_TREE,
15623                                       assignment, enter),
15624                                exit, NULL_TREE),
15625                         block));
15626   node = build_expr_block (node, expr_decl);
15627
15628   return java_complete_tree (node);
15629 }
15630
15631 /* 14.16 The throw Statement */
15632
15633 static tree
15634 patch_throw_statement (node, wfl_op1)
15635     tree node, wfl_op1;
15636 {
15637   tree expr = TREE_OPERAND (node, 0);
15638   tree type = TREE_TYPE (expr);
15639   int unchecked_ok = 0, tryblock_throws_ok = 0;
15640
15641   /* Thrown expression must be assignable to java.lang.Throwable */
15642   if (!try_reference_assignconv (throwable_type_node, expr))
15643     {
15644       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15645       parse_error_context (wfl_operator,
15646     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
15647                            lang_printable_name (type, 0));
15648       /* If the thrown expression was a reference, we further the
15649          compile-time check. */
15650       if (!JREFERENCE_TYPE_P (type))
15651         return error_mark_node;
15652     }
15653
15654   /* At least one of the following must be true */
15655
15656   /* The type of the throw expression is a not checked exception,
15657      i.e. is a unchecked expression. */
15658   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
15659
15660   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15661   /* An instance can't throw a checked exception unless that exception
15662      is explicitely declared in the `throws' clause of each
15663      constructor. This doesn't apply to anonymous classes, since they
15664      don't have declared constructors. */
15665   if (!unchecked_ok 
15666       && DECL_INSTINIT_P (current_function_decl)
15667       && !ANONYMOUS_CLASS_P (current_class))
15668     {
15669       tree current;
15670       for (current = TYPE_METHODS (current_class); current; 
15671            current = TREE_CHAIN (current))
15672         if (DECL_CONSTRUCTOR_P (current) 
15673             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
15674           {
15675             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)", 
15676                                  lang_printable_name (TREE_TYPE (expr), 0));
15677             return error_mark_node;
15678           }
15679     }
15680
15681   /* Throw is contained in a try statement and at least one catch
15682      clause can receive the thrown expression or the current method is
15683      declared to throw such an exception. Or, the throw statement is
15684      contained in a method or constructor declaration and the type of
15685      the Expression is assignable to at least one type listed in the
15686      throws clause the declaration. */
15687   if (!unchecked_ok)
15688     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
15689   if (!(unchecked_ok || tryblock_throws_ok))
15690     {
15691       /* If there is a surrounding try block that has no matching
15692          clatch clause, report it first. A surrounding try block exits
15693          only if there is something after the list of checked
15694          exception thrown by the current function (if any). */
15695       if (IN_TRY_BLOCK_P ())
15696         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
15697                              lang_printable_name (type, 0));
15698       /* If we have no surrounding try statement and the method doesn't have
15699          any throws, report it now. FIXME */
15700
15701       /* We report that the exception can't be throw from a try block
15702          in all circumstances but when the `throw' is inside a static
15703          block. */
15704       else if (!EXCEPTIONS_P (currently_caught_type_list) 
15705                && !tryblock_throws_ok)
15706         {
15707           if (DECL_CLINIT_P (current_function_decl))
15708             parse_error_context (wfl_operator,
15709                    "Checked exception `%s' can't be thrown in initializer",
15710                                  lang_printable_name (type, 0));
15711           else
15712             parse_error_context (wfl_operator,
15713                    "Checked exception `%s' isn't thrown from a `try' block", 
15714                                  lang_printable_name (type, 0));
15715         }
15716       /* Otherwise, the current method doesn't have the appropriate
15717          throws declaration */
15718       else
15719         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
15720                              lang_printable_name (type, 0));
15721       return error_mark_node;
15722     }
15723
15724   if (! flag_emit_class_files && ! flag_emit_xref)
15725     BUILD_THROW (node, expr);
15726
15727   /* If doing xrefs, keep the location where the `throw' was seen. */
15728   if (flag_emit_xref)
15729     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
15730   return node;
15731 }
15732
15733 /* Check that exception said to be thrown by method DECL can be
15734    effectively caught from where DECL is invoked.  */
15735
15736 static void
15737 check_thrown_exceptions (location, decl)
15738      int location;
15739      tree decl;
15740 {
15741   tree throws;
15742   /* For all the unchecked exceptions thrown by DECL */
15743   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
15744        throws = TREE_CHAIN (throws)) 
15745     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
15746       {
15747 #if 1
15748         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
15749         if (DECL_NAME (decl) == get_identifier ("clone"))
15750           continue;
15751 #endif
15752         EXPR_WFL_LINECOL (wfl_operator) = location;
15753         if (DECL_FINIT_P (current_function_decl))
15754           parse_error_context
15755             (wfl_operator, "Exception `%s' can't be thrown in initializer",
15756              lang_printable_name (TREE_VALUE (throws), 0));
15757         else 
15758           {
15759             parse_error_context 
15760               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
15761                lang_printable_name (TREE_VALUE (throws), 0),
15762                (DECL_INIT_P (current_function_decl) ?
15763                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
15764                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
15765           }
15766       }
15767 }
15768
15769 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
15770    try-catch blocks, OR is listed in the `throws' clause of the
15771    current method.  */
15772
15773 static int
15774 check_thrown_exceptions_do (exception)
15775      tree exception;
15776 {
15777   tree list = currently_caught_type_list;
15778   resolve_and_layout (exception, NULL_TREE);
15779   /* First, all the nested try-catch-finally at that stage. The
15780      last element contains `throws' clause exceptions, if any. */
15781   if (IS_UNCHECKED_EXCEPTION_P (exception))
15782     return 1;
15783   while (list)
15784     {
15785       tree caught;
15786       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
15787         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
15788           return 1;
15789       list = TREE_CHAIN (list);
15790     }
15791   return 0;
15792 }
15793
15794 static void
15795 purge_unchecked_exceptions (mdecl)
15796      tree mdecl;
15797 {
15798   tree throws = DECL_FUNCTION_THROWS (mdecl);
15799   tree new = NULL_TREE;
15800
15801   while (throws)
15802     {
15803       tree next = TREE_CHAIN (throws);
15804       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
15805         {
15806           TREE_CHAIN (throws) = new;
15807           new = throws;
15808         }
15809       throws = next;
15810     }
15811   /* List is inverted here, but it doesn't matter */
15812   DECL_FUNCTION_THROWS (mdecl) = new;
15813 }
15814
15815 /* This function goes over all of CLASS_TYPE ctors and checks whether
15816    each of them features at least one unchecked exception in its
15817    `throws' clause. If it's the case, it returns `true', `false'
15818    otherwise.  */
15819
15820 static bool
15821 ctors_unchecked_throws_clause_p (class_type)
15822      tree class_type;
15823 {
15824   tree current;
15825
15826   for (current = TYPE_METHODS (class_type); current;
15827        current = TREE_CHAIN (current))
15828     {
15829       bool ctu = false; /* Ctor Throws Unchecked */
15830       if (DECL_CONSTRUCTOR_P (current))
15831         {
15832           tree throws;
15833           for (throws = DECL_FUNCTION_THROWS (current); throws && !ctu;
15834                throws = TREE_CHAIN (throws))
15835             if (inherits_from_p (TREE_VALUE (throws), exception_type_node))
15836               ctu = true;
15837         }
15838       /* We return false as we found one ctor that is unfit. */
15839       if (!ctu && DECL_CONSTRUCTOR_P (current))
15840         return false;
15841     }
15842   /* All ctors feature at least one unchecked exception in their
15843      `throws' clause. */
15844   return true;
15845 }
15846
15847 /* 15.24 Conditional Operator ?: */
15848
15849 static tree
15850 patch_conditional_expr (node, wfl_cond, wfl_op1)
15851      tree node, wfl_cond, wfl_op1;
15852 {
15853   tree cond = TREE_OPERAND (node, 0);
15854   tree op1 = TREE_OPERAND (node, 1);
15855   tree op2 = TREE_OPERAND (node, 2);
15856   tree resulting_type = NULL_TREE;
15857   tree t1, t2, patched;
15858   int error_found = 0;
15859
15860   /* Operands of ?: might be StringBuffers crafted as a result of a
15861      string concatenation. Obtain a descent operand here.  */
15862   if ((patched = patch_string (op1)))
15863     TREE_OPERAND (node, 1) = op1 = patched;
15864   if ((patched = patch_string (op2)))
15865     TREE_OPERAND (node, 2) = op2 = patched;
15866
15867   t1 = TREE_TYPE (op1);
15868   t2 = TREE_TYPE (op2);
15869
15870   /* The first expression must be a boolean */
15871   if (TREE_TYPE (cond) != boolean_type_node)
15872     {
15873       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
15874       parse_error_context (wfl_operator,
15875                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
15876                            lang_printable_name (TREE_TYPE (cond), 0));
15877       error_found = 1;
15878     }
15879
15880   /* Second and third can be numeric, boolean (i.e. primitive),
15881      references or null. Anything else results in an error */
15882   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
15883         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
15884             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
15885         || (t1 == boolean_type_node && t2 == boolean_type_node)))
15886     error_found = 1;
15887
15888   /* Determine the type of the conditional expression. Same types are
15889      easy to deal with */
15890   else if (t1 == t2)
15891     resulting_type = t1;
15892
15893   /* There are different rules for numeric types */
15894   else if (JNUMERIC_TYPE_P (t1))
15895     {
15896       /* if byte/short found, the resulting type is short */
15897       if ((t1 == byte_type_node && t2 == short_type_node)
15898           || (t1 == short_type_node && t2 == byte_type_node))
15899         resulting_type = short_type_node;
15900
15901       /* If t1 is a constant int and t2 is of type byte, short or char
15902          and t1's value fits in t2, then the resulting type is t2 */
15903       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
15904           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
15905         resulting_type = t2;
15906
15907       /* If t2 is a constant int and t1 is of type byte, short or char
15908          and t2's value fits in t1, then the resulting type is t1 */
15909       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
15910           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
15911         resulting_type = t1;
15912
15913       /* Otherwise, binary numeric promotion is applied and the
15914          resulting type is the promoted type of operand 1 and 2 */
15915       else 
15916         resulting_type = binary_numeric_promotion (t1, t2, 
15917                                                    &TREE_OPERAND (node, 1), 
15918                                                    &TREE_OPERAND (node, 2));
15919     }
15920
15921   /* Cases of a reference and a null type */
15922   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
15923     resulting_type = t1;
15924
15925   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
15926     resulting_type = t2;
15927
15928   /* Last case: different reference types. If a type can be converted
15929      into the other one by assignment conversion, the latter
15930      determines the type of the expression */
15931   else if ((resulting_type = try_reference_assignconv (t1, op2)))
15932     resulting_type = promote_type (t1);
15933
15934   else if ((resulting_type = try_reference_assignconv (t2, op1)))
15935     resulting_type = promote_type (t2);
15936
15937   /* If we don't have any resulting type, we're in trouble */
15938   if (!resulting_type)
15939     {
15940       char *t = xstrdup (lang_printable_name (t1, 0));
15941       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15942       parse_error_context (wfl_operator,
15943                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
15944                            t, lang_printable_name (t2, 0));
15945       free (t);
15946       error_found = 1;
15947     }
15948
15949   if (error_found)
15950     {
15951       TREE_TYPE (node) = error_mark_node;
15952       return error_mark_node;
15953     }
15954
15955   TREE_TYPE (node) = resulting_type;
15956   TREE_SET_CODE (node, COND_EXPR);
15957   CAN_COMPLETE_NORMALLY (node) = 1;
15958   return node;
15959 }
15960
15961 /* Wrap EXPR with code to initialize DECL's class, if appropriate. */
15962
15963 static tree
15964 maybe_build_class_init_for_field (decl, expr)
15965     tree decl, expr;
15966 {
15967   tree clas = DECL_CONTEXT (decl);
15968   if (flag_emit_class_files || flag_emit_xref)
15969     return expr;
15970
15971   if (TREE_CODE (decl) == VAR_DECL && FIELD_STATIC (decl)
15972       && FIELD_FINAL (decl))
15973     {
15974       tree init = DECL_INITIAL (decl);
15975       if (init != NULL_TREE)
15976         init = fold_constant_for_init (init, decl);
15977       if (init != NULL_TREE && CONSTANT_VALUE_P (init))
15978         return expr;
15979     }
15980
15981   return build_class_init (clas, expr);
15982 }
15983
15984 /* Try to constant fold NODE.
15985    If NODE is not a constant expression, return NULL_EXPR.
15986    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
15987
15988 static tree
15989 fold_constant_for_init (node, context)
15990      tree node;
15991      tree context;
15992 {
15993   tree op0, op1, val;
15994   enum tree_code code = TREE_CODE (node);
15995
15996   switch (code)
15997     {
15998     case STRING_CST:
15999     case INTEGER_CST:
16000     case REAL_CST:
16001       return node;
16002
16003     case PLUS_EXPR:
16004     case MINUS_EXPR:
16005     case MULT_EXPR:
16006     case TRUNC_MOD_EXPR:
16007     case RDIV_EXPR:
16008     case LSHIFT_EXPR:
16009     case RSHIFT_EXPR:
16010     case URSHIFT_EXPR:
16011     case BIT_AND_EXPR:
16012     case BIT_XOR_EXPR:
16013     case BIT_IOR_EXPR:
16014     case TRUTH_ANDIF_EXPR:
16015     case TRUTH_ORIF_EXPR:
16016     case EQ_EXPR: 
16017     case NE_EXPR:
16018     case GT_EXPR:
16019     case GE_EXPR:
16020     case LT_EXPR:
16021     case LE_EXPR:
16022       op0 = TREE_OPERAND (node, 0);
16023       op1 = TREE_OPERAND (node, 1);
16024       val = fold_constant_for_init (op0, context);
16025       if (val == NULL_TREE || ! TREE_CONSTANT (val))
16026         return NULL_TREE;
16027       TREE_OPERAND (node, 0) = val;
16028       val = fold_constant_for_init (op1, context);
16029       if (val == NULL_TREE || ! TREE_CONSTANT (val))
16030         return NULL_TREE;
16031       TREE_OPERAND (node, 1) = val;
16032       return patch_binop (node, op0, op1);
16033
16034     case UNARY_PLUS_EXPR:
16035     case NEGATE_EXPR:
16036     case TRUTH_NOT_EXPR:
16037     case BIT_NOT_EXPR:
16038     case CONVERT_EXPR:
16039       op0 = TREE_OPERAND (node, 0);
16040       val = fold_constant_for_init (op0, context);
16041       if (val == NULL_TREE || ! TREE_CONSTANT (val))
16042         return NULL_TREE;
16043       TREE_OPERAND (node, 0) = val;
16044       return patch_unaryop (node, op0);
16045       break;
16046
16047     case COND_EXPR:
16048       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
16049       if (val == NULL_TREE || ! TREE_CONSTANT (val))
16050         return NULL_TREE;
16051       TREE_OPERAND (node, 0) = val;
16052       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
16053       if (val == NULL_TREE || ! TREE_CONSTANT (val))
16054         return NULL_TREE;
16055       TREE_OPERAND (node, 1) = val;
16056       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
16057       if (val == NULL_TREE || ! TREE_CONSTANT (val))
16058         return NULL_TREE;
16059       TREE_OPERAND (node, 2) = val;
16060       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
16061         : TREE_OPERAND (node, 2);
16062
16063     case VAR_DECL:
16064     case FIELD_DECL:
16065       if (! FIELD_FINAL (node)
16066           || DECL_INITIAL (node) == NULL_TREE)
16067         return NULL_TREE;
16068       val = DECL_INITIAL (node);
16069       /* Guard against infinite recursion. */
16070       DECL_INITIAL (node) = NULL_TREE;
16071       val = fold_constant_for_init (val, node);
16072       DECL_INITIAL (node) = val;
16073       if (!val && CLASS_FINAL_VARIABLE_P (node))
16074         DECL_FIELD_FINAL_IUD (node) = 0;
16075       return val;
16076
16077     case EXPR_WITH_FILE_LOCATION:
16078       /* Compare java_complete_tree and resolve_expression_name. */
16079       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
16080           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
16081         {
16082           tree name = EXPR_WFL_NODE (node);
16083           tree decl;
16084           if (PRIMARY_P (node))
16085             return NULL_TREE;
16086           else if (! QUALIFIED_P (name))
16087             {
16088               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
16089               if (decl == NULL_TREE 
16090                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
16091                 return NULL_TREE;
16092               return fold_constant_for_init (decl, decl);
16093             }
16094           else
16095             {
16096               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
16097               qualify_ambiguous_name (node);
16098               if (resolve_field_access (node, &decl, NULL)
16099                   && decl != NULL_TREE)
16100                 return fold_constant_for_init (decl, decl);
16101               return NULL_TREE;
16102             }
16103         }
16104       else
16105         {
16106           op0 = TREE_OPERAND (node, 0);
16107           val = fold_constant_for_init (op0, context);
16108           if (val == NULL_TREE || ! TREE_CONSTANT (val))
16109             return NULL_TREE;
16110           TREE_OPERAND (node, 0) = val;
16111           return val;
16112         }
16113
16114 #ifdef USE_COMPONENT_REF
16115     case IDENTIFIER:
16116     case COMPONENT_REF:
16117       ?;
16118 #endif
16119
16120     default:
16121       return NULL_TREE;
16122     }
16123 }
16124
16125 #ifdef USE_COMPONENT_REF
16126 /* Context is 'T' for TypeName, 'P' for PackageName,
16127    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
16128
16129 tree
16130 resolve_simple_name (name, context)
16131      tree name;
16132      int context;
16133 {
16134 }
16135
16136 tree
16137 resolve_qualified_name (name, context)
16138      tree name;
16139      int context;
16140 {
16141 }
16142 #endif
16143
16144 /* Mark P, which is really a `struct parser_ctxt **' for GC.  */
16145
16146 static void
16147 mark_parser_ctxt (p)
16148      void *p;
16149 {
16150   struct parser_ctxt *pc = *((struct parser_ctxt **) p);
16151   int i;
16152
16153   if (!pc)
16154     return;
16155
16156 #ifndef JC1_LITE
16157   for (i = 0; i < 11; ++i)
16158     ggc_mark_tree (pc->modifier_ctx[i]);
16159   ggc_mark_tree (pc->class_type);
16160   ggc_mark_tree (pc->function_decl);
16161   ggc_mark_tree (pc->package);
16162   ggc_mark_tree (pc->class_list);
16163   ggc_mark_tree (pc->current_parsed_class);
16164   ggc_mark_tree (pc->current_parsed_class_un);
16165   ggc_mark_tree (pc->non_static_initialized);
16166   ggc_mark_tree (pc->static_initialized);
16167   ggc_mark_tree (pc->instance_initializers);
16168   ggc_mark_tree (pc->import_list);
16169   ggc_mark_tree (pc->import_demand_list);
16170   ggc_mark_tree (pc->current_loop);
16171   ggc_mark_tree (pc->current_labeled_block);
16172 #endif /* JC1_LITE */
16173
16174   if (pc->next)
16175     mark_parser_ctxt (&pc->next);
16176 }
16177
16178 void
16179 init_src_parse ()
16180 {
16181   /* Register roots with the garbage collector.  */
16182   ggc_add_tree_root (src_parse_roots, sizeof (src_parse_roots) / sizeof(tree));
16183 }
16184
16185 \f
16186
16187 /* This section deals with the functions that are called when tables
16188    recording class initialization information are traversed.  */
16189
16190 /* Attach to PTR (a block) the declaration found in ENTRY. */
16191
16192 static bool
16193 attach_init_test_initialization_flags (entry, ptr)
16194      struct hash_entry *entry;
16195      PTR ptr;
16196 {
16197   tree block = (tree)ptr;
16198   struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
16199   
16200   TREE_CHAIN (ite->init_test_decl) = BLOCK_EXPR_DECLS (block);
16201   BLOCK_EXPR_DECLS (block) = ite->init_test_decl;
16202   return true;
16203 }
16204
16205 /* This function is called for each statement calling a static
16206    function.  ENTRY is a TREE_LIST whose PURPOSE is the called
16207    function and VALUE is a compound whose second operand can be
16208    patched with static class initialization flag assignments.  */
16209
16210 static bool
16211 adjust_init_test_initialization (entry, info)
16212      struct hash_entry *entry;
16213      PTR info ATTRIBUTE_UNUSED;
16214 {
16215   tree list = (tree)(entry->key);
16216   tree called_method = TREE_PURPOSE (list);
16217   tree compound = TREE_VALUE (list);
16218   tree assignment_compound_list = build_tree_list (called_method, NULL);
16219
16220   /* For each class definitely initialized in CALLED_METHOD, fill
16221      ASSIGNMENT_COMPOUND with assignment to the class initialization flag. */
16222   hash_traverse (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method),
16223                  emit_test_initialization, assignment_compound_list);
16224
16225   if (TREE_VALUE (assignment_compound_list))
16226     TREE_OPERAND (compound, 1) = TREE_VALUE (assignment_compound_list);
16227
16228   return true;
16229 }
16230
16231 /* This function is called for each classes that is known definitely
16232    assigned when a given static method was called. This function
16233    augments a compound expression (INFO) storing all assignment to
16234    initialized static class flags if a flag already existed, otherwise
16235    a new one is created.  */
16236
16237 static bool
16238 emit_test_initialization (entry, info)
16239      struct hash_entry *entry;
16240      PTR info;
16241 {
16242   tree l = (tree) info;
16243   tree decl, init;
16244
16245   struct init_test_hash_entry *ite = (struct init_test_hash_entry *)
16246     hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
16247                  entry->key, FALSE, NULL);
16248
16249   /* If we haven't found a flag and we're dealing with self registered
16250      with current_function_decl, then don't do anything. Self is
16251      always added as definitely initialized but this information is
16252      valid only if used outside the current function. */
16253   if (! ite)
16254     {
16255       if (current_function_decl != TREE_PURPOSE (l))
16256         ite = (struct init_test_hash_entry *)
16257           hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
16258                        entry->key, TRUE, NULL);
16259       else
16260         return true;
16261     }
16262
16263   /* If we don't have a variable, create one and install it. */
16264   if (! ite->init_test_decl)
16265     {
16266       tree block;
16267       
16268       decl = build_decl (VAR_DECL, NULL_TREE, boolean_type_node);
16269       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
16270       LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
16271       DECL_CONTEXT (decl) = current_function_decl;
16272       DECL_INITIAL (decl) = boolean_true_node;
16273
16274       /* The trick is to find the right context for it. */
16275       block = BLOCK_SUBBLOCKS (GET_CURRENT_BLOCK (current_function_decl));
16276       TREE_CHAIN (decl) = BLOCK_EXPR_DECLS (block);
16277       BLOCK_EXPR_DECLS (block) = decl;
16278       ite->init_test_decl = decl;
16279     }
16280   else
16281     decl = ite->init_test_decl;
16282
16283   /* Now simply augment the compound that holds all the assignments
16284      pertaining to this method invocation. */
16285   init = build (MODIFY_EXPR, boolean_type_node, decl, boolean_true_node);
16286   TREE_SIDE_EFFECTS (init) = 1;
16287   TREE_VALUE (l) = add_stmt_to_compound (TREE_VALUE (l), void_type_node, init);
16288   TREE_SIDE_EFFECTS (TREE_VALUE (l)) = 1;
16289
16290   return true;
16291 }