OSDN Git Service

960bd9075da7e2d4c3fc5d5ec4d1e117b1957539
[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, 2002 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 "real.h"
55 #include "obstack.h"
56 #include "toplev.h"
57 #include "flags.h"
58 #include "java-tree.h"
59 #include "jcf.h"
60 #include "lex.h"
61 #include "parse.h"
62 #include "zipfile.h"
63 #include "convert.h"
64 #include "buffer.h"
65 #include "xref.h"
66 #include "function.h"
67 #include "except.h"
68 #include "ggc.h"
69 #include "debug.h"
70
71 #ifndef DIR_SEPARATOR
72 #define DIR_SEPARATOR '/'
73 #endif
74
75 /* Local function prototypes */
76 static char *java_accstring_lookup PARAMS ((int));
77 static void  classitf_redefinition_error PARAMS ((const char *,tree, tree, tree));
78 static void  variable_redefinition_error PARAMS ((tree, tree, tree, int));
79 static tree  create_class PARAMS ((int, tree, tree, tree));
80 static tree  create_interface PARAMS ((int, tree, tree));
81 static void  end_class_declaration PARAMS ((int));
82 static tree  find_field PARAMS ((tree, tree));
83 static tree lookup_field_wrapper PARAMS ((tree, tree));
84 static int   duplicate_declaration_error_p PARAMS ((tree, tree, tree));
85 static void  register_fields PARAMS ((int, tree, tree));
86 static tree parser_qualified_classname PARAMS ((tree));
87 static int  parser_check_super PARAMS ((tree, tree, tree));
88 static int  parser_check_super_interface PARAMS ((tree, tree, tree));
89 static void check_modifiers_consistency PARAMS ((int));
90 static tree lookup_cl PARAMS ((tree));
91 static tree lookup_java_method2 PARAMS ((tree, tree, int));
92 static tree method_header PARAMS ((int, tree, tree, tree));
93 static void fix_method_argument_names PARAMS ((tree ,tree));
94 static tree method_declarator PARAMS ((tree, tree));
95 static void parse_warning_context PARAMS ((tree cl, const char *msg, ...))
96   ATTRIBUTE_PRINTF_2;
97 static void issue_warning_error_from_context PARAMS ((tree, const char *msg, va_list))
98   ATTRIBUTE_PRINTF (2, 0);
99 static void parse_ctor_invocation_error PARAMS ((void));
100 static tree parse_jdk1_1_error PARAMS ((const char *));
101 static void complete_class_report_errors PARAMS ((jdep *));
102 static int process_imports PARAMS ((void));
103 static void read_import_dir PARAMS ((tree));
104 static int find_in_imports_on_demand PARAMS ((tree, tree));
105 static void find_in_imports PARAMS ((tree, tree));
106 static void check_inner_class_access PARAMS ((tree, tree, tree));
107 static int check_pkg_class_access PARAMS ((tree, tree, bool));
108 static void register_package PARAMS ((tree));
109 static tree resolve_package PARAMS ((tree, tree *, tree *));
110 static tree resolve_class PARAMS ((tree, tree, tree, tree));
111 static void declare_local_variables PARAMS ((int, tree, tree));
112 static void dump_java_tree PARAMS ((enum tree_dump_index, tree));
113 static void source_start_java_method PARAMS ((tree));
114 static void source_end_java_method PARAMS ((void));
115 static tree find_name_in_single_imports PARAMS ((tree));
116 static void check_abstract_method_header PARAMS ((tree));
117 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
118 static tree resolve_expression_name PARAMS ((tree, tree *));
119 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
120 static int check_class_interface_creation PARAMS ((int, int, tree, 
121                                                   tree, tree, tree));
122 static tree patch_method_invocation PARAMS ((tree, tree, tree, int,
123                                             int *, tree *));
124 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
125 static int in_same_package PARAMS ((tree, tree));
126 static tree resolve_and_layout PARAMS ((tree, tree));
127 static tree qualify_and_find PARAMS ((tree, tree, tree));
128 static tree resolve_no_layout PARAMS ((tree, tree));
129 static int invocation_mode PARAMS ((tree, int));
130 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
131                                                             tree, tree));
132 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
133                                                    tree *, tree *));
134 static tree find_most_specific_methods_list PARAMS ((tree));
135 static int argument_types_convertible PARAMS ((tree, tree));
136 static tree patch_invoke PARAMS ((tree, tree, tree));
137 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
138 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
139 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
140 static tree check_inner_circular_reference PARAMS ((tree, tree));
141 static tree check_circular_reference PARAMS ((tree));
142 static tree obtain_incomplete_type PARAMS ((tree));
143 static tree java_complete_lhs PARAMS ((tree));
144 static tree java_complete_tree PARAMS ((tree));
145 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
146 static int analyze_clinit_body PARAMS ((tree, tree));
147 static int maybe_yank_clinit PARAMS ((tree));
148 static void start_complete_expand_method PARAMS ((tree));
149 static void java_complete_expand_method PARAMS ((tree));
150 static void java_expand_method_bodies PARAMS ((tree));
151 static int  unresolved_type_p PARAMS ((tree, tree *));
152 static void create_jdep_list PARAMS ((struct parser_ctxt *));
153 static tree build_expr_block PARAMS ((tree, tree));
154 static tree enter_block PARAMS ((void));
155 static tree exit_block PARAMS ((void));
156 static tree lookup_name_in_blocks PARAMS ((tree));
157 static void maybe_absorb_scoping_blocks PARAMS ((void));
158 static tree build_method_invocation PARAMS ((tree, tree));
159 static tree build_new_invocation PARAMS ((tree, tree));
160 static tree build_assignment PARAMS ((int, int, tree, tree));
161 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
162 static tree patch_assignment PARAMS ((tree, tree));
163 static tree patch_binop PARAMS ((tree, tree, tree));
164 static tree build_unaryop PARAMS ((int, int, tree));
165 static tree build_incdec PARAMS ((int, int, tree, int));
166 static tree patch_unaryop PARAMS ((tree, tree));
167 static tree build_cast PARAMS ((int, tree, tree));
168 static tree build_null_of_type PARAMS ((tree));
169 static tree patch_cast PARAMS ((tree, tree));
170 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
171 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
172 static int valid_cast_to_p PARAMS ((tree, tree));
173 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
174 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
175 static tree try_reference_assignconv PARAMS ((tree, tree));
176 static tree build_unresolved_array_type PARAMS ((tree));
177 static int build_type_name_from_array_name PARAMS ((tree, tree *));
178 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
179 static tree build_array_ref PARAMS ((int, tree, tree));
180 static tree patch_array_ref PARAMS ((tree));
181 static tree make_qualified_name PARAMS ((tree, tree, int));
182 static tree merge_qualified_name PARAMS ((tree, tree));
183 static tree make_qualified_primary PARAMS ((tree, tree, int));
184 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
185                                                      tree *, tree *));
186 static void qualify_ambiguous_name PARAMS ((tree));
187 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
188 static tree build_newarray_node PARAMS ((tree, tree, int));
189 static tree patch_newarray PARAMS ((tree));
190 static tree resolve_type_during_patch PARAMS ((tree));
191 static tree build_this PARAMS ((int));
192 static tree build_wfl_wrap PARAMS ((tree, int));
193 static tree build_return PARAMS ((int, tree));
194 static tree patch_return PARAMS ((tree));
195 static tree maybe_access_field PARAMS ((tree, tree, tree));
196 static int complete_function_arguments PARAMS ((tree));
197 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
198                                                       tree, tree));
199 static int not_accessible_p PARAMS ((tree, tree, tree, int));
200 static void check_deprecation PARAMS ((tree, tree));
201 static int class_in_current_package PARAMS ((tree));
202 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
203 static tree patch_if_else_statement PARAMS ((tree));
204 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
205 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
206 static tree patch_exit_expr PARAMS ((tree));
207 static tree build_labeled_block PARAMS ((int, tree));
208 static tree finish_labeled_statement PARAMS ((tree, tree));
209 static tree build_bc_statement PARAMS ((int, int, tree));
210 static tree patch_bc_statement PARAMS ((tree));
211 static tree patch_loop_statement PARAMS ((tree));
212 static tree build_new_loop PARAMS ((tree));
213 static tree build_loop_body PARAMS ((int, tree, int));
214 static tree finish_loop_body PARAMS ((int, tree, tree, int));
215 static tree build_debugable_stmt PARAMS ((int, tree));
216 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
217 static tree patch_switch_statement PARAMS ((tree));
218 static tree string_constant_concatenation PARAMS ((tree, tree));
219 static tree build_string_concatenation PARAMS ((tree, tree));
220 static tree patch_string_cst PARAMS ((tree));
221 static tree patch_string PARAMS ((tree));
222 static tree encapsulate_with_try_catch PARAMS ((int, tree, tree, tree));
223 static tree build_try_statement PARAMS ((int, tree, tree));
224 static tree build_try_finally_statement PARAMS ((int, tree, tree));
225 static tree patch_try_statement PARAMS ((tree));
226 static tree patch_synchronized_statement PARAMS ((tree, tree));
227 static tree patch_throw_statement PARAMS ((tree, tree));
228 static void check_thrown_exceptions PARAMS ((int, tree));
229 static int check_thrown_exceptions_do PARAMS ((tree));
230 static void purge_unchecked_exceptions PARAMS ((tree));
231 static bool ctors_unchecked_throws_clause_p PARAMS ((tree));
232 static void check_throws_clauses PARAMS ((tree, tree, tree));
233 static void finish_method_declaration PARAMS ((tree));
234 static tree build_super_invocation PARAMS ((tree));
235 static int verify_constructor_circularity PARAMS ((tree, tree));
236 static char *constructor_circularity_msg PARAMS ((tree, tree));
237 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
238                                                           int, int));
239 static const char *get_printable_method_name PARAMS ((tree));
240 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
241 static tree generate_finit PARAMS ((tree));
242 static tree generate_instinit PARAMS ((tree));
243 static tree build_instinit_invocation PARAMS ((tree));
244 static void fix_constructors PARAMS ((tree));
245 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
246                                                             tree, int *));
247 static tree craft_constructor PARAMS ((tree, tree));
248 static int verify_constructor_super PARAMS ((tree));
249 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
250 static void start_artificial_method_body PARAMS ((tree));
251 static void end_artificial_method_body PARAMS ((tree));
252 static int check_method_redefinition PARAMS ((tree, tree));
253 static int check_method_types_complete PARAMS ((tree));
254 static void java_check_regular_methods PARAMS ((tree));
255 static void java_check_abstract_methods PARAMS ((tree));
256 static void unreachable_stmt_error PARAMS ((tree));
257 static tree find_expr_with_wfl PARAMS ((tree));
258 static void missing_return_error PARAMS ((tree));
259 static tree build_new_array_init PARAMS ((int, tree));
260 static tree patch_new_array_init PARAMS ((tree, tree));
261 static tree maybe_build_array_element_wfl PARAMS ((tree));
262 static int array_constructor_check_entry PARAMS ((tree, tree));
263 static const char *purify_type_name PARAMS ((const char *));
264 static tree fold_constant_for_init PARAMS ((tree, tree));
265 static tree strip_out_static_field_access_decl PARAMS ((tree));
266 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
267 static void static_ref_err PARAMS ((tree, tree, tree));
268 static void parser_add_interface PARAMS ((tree, tree, tree));
269 static void add_superinterfaces PARAMS ((tree, tree));
270 static tree jdep_resolve_class PARAMS ((jdep *));
271 static int note_possible_classname PARAMS ((const char *, int));
272 static void java_complete_expand_classes PARAMS ((void));
273 static void java_complete_expand_class PARAMS ((tree));
274 static void java_complete_expand_methods PARAMS ((tree));
275 static tree cut_identifier_in_qualified PARAMS ((tree));
276 static tree java_stabilize_reference PARAMS ((tree));
277 static tree do_unary_numeric_promotion PARAMS ((tree));
278 static char * operator_string PARAMS ((tree));
279 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
280 static tree merge_string_cste PARAMS ((tree, tree, int));
281 static tree java_refold PARAMS ((tree));
282 static int java_decl_equiv PARAMS ((tree, tree));
283 static int binop_compound_p PARAMS ((enum tree_code));
284 static tree search_loop PARAMS ((tree));
285 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
286 static int check_abstract_method_definitions PARAMS ((int, tree, tree));
287 static void java_check_abstract_method_definitions PARAMS ((tree));
288 static void java_debug_context_do PARAMS ((int));
289 static void java_parser_context_push_initialized_field PARAMS ((void));
290 static void java_parser_context_pop_initialized_field PARAMS ((void));
291 static tree reorder_static_initialized PARAMS ((tree));
292 static void java_parser_context_suspend PARAMS ((void));
293 static void java_parser_context_resume PARAMS ((void));
294 static int pop_current_osb PARAMS ((struct parser_ctxt *));
295
296 /* JDK 1.1 work. FIXME */
297
298 static tree maybe_make_nested_class_name PARAMS ((tree));
299 static int make_nested_class_name PARAMS ((tree));
300 static void set_nested_class_simple_name_value PARAMS ((tree, int));
301 static void link_nested_class_to_enclosing PARAMS ((void));
302 static tree resolve_inner_class PARAMS ((htab_t, tree, tree *, tree *, tree));
303 static tree find_as_inner_class PARAMS ((tree, tree, tree));
304 static tree find_as_inner_class_do PARAMS ((tree, tree));
305 static int check_inner_class_redefinition PARAMS ((tree, tree));
306
307 static tree build_thisn_assign PARAMS ((void));
308 static tree build_current_thisn PARAMS ((tree));
309 static tree build_access_to_thisn PARAMS ((tree, tree, int));
310 static tree maybe_build_thisn_access_method PARAMS ((tree));
311
312 static tree build_outer_field_access PARAMS ((tree, tree));
313 static tree build_outer_field_access_methods PARAMS ((tree));
314 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
315                                                   tree, tree));
316 static tree build_outer_method_access_method PARAMS ((tree));
317 static tree build_new_access_id PARAMS ((void));
318 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
319                                                     tree, tree));
320
321 static int outer_field_access_p PARAMS ((tree, tree));
322 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
323                                                  tree *, tree *));
324 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
325 static tree build_incomplete_class_ref PARAMS ((int, tree));
326 static tree patch_incomplete_class_ref PARAMS ((tree));
327 static tree create_anonymous_class PARAMS ((int, tree));
328 static void patch_anonymous_class PARAMS ((tree, tree, tree));
329 static void add_inner_class_fields PARAMS ((tree, tree));
330
331 static tree build_dot_class_method PARAMS ((tree));
332 static tree build_dot_class_method_invocation PARAMS ((tree));
333 static void create_new_parser_context PARAMS ((int));
334 static void mark_parser_ctxt PARAMS ((void *));
335 static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
336
337 static int attach_init_test_initialization_flags PARAMS ((PTR *, PTR));
338 static int emit_test_initialization PARAMS ((PTR *, PTR));
339
340 static char *string_convert_int_cst PARAMS ((tree));
341
342 /* Number of error found so far. */
343 int java_error_count; 
344 /* Number of warning found so far. */
345 int java_warning_count;
346 /* Tell when not to fold, when doing xrefs */
347 int do_not_fold;
348 /* Cyclic inheritance report, as it can be set by layout_class */
349 const char *cyclic_inheritance_report;
350  
351 /* The current parser context */
352 struct parser_ctxt *ctxp;
353
354 /* List of things that were analyzed for which code will be generated */
355 struct parser_ctxt *ctxp_for_generation = NULL;
356
357 /* binop_lookup maps token to tree_code. It is used where binary
358    operations are involved and required by the parser. RDIV_EXPR
359    covers both integral/floating point division. The code is changed
360    once the type of both operator is worked out.  */
361
362 static const enum tree_code binop_lookup[19] = 
363   { 
364     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
365     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
366     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
367     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
368     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
369    };
370 #define BINOP_LOOKUP(VALUE)                                             \
371   binop_lookup [((VALUE) - PLUS_TK) % ARRAY_SIZE (binop_lookup)]
372
373 /* This is the end index for binary operators that can also be used
374    in compound assignements. */
375 #define BINOP_COMPOUND_CANDIDATES 11
376
377 /* The "$L" identifier we use to create labels.  */
378 static GTY(()) tree label_id;
379
380 /* The "StringBuffer" identifier used for the String `+' operator. */
381 static GTY(()) tree wfl_string_buffer; 
382
383 /* The "append" identifier used for String `+' operator.  */
384 static GTY(()) tree wfl_append;
385
386 /* The "toString" identifier used for String `+' operator. */
387 static GTY(()) tree wfl_to_string;
388
389 /* The "java.lang" import qualified name.  */
390 static GTY(()) tree java_lang_id;
391
392 /* The generated `inst$' identifier used for generated enclosing
393    instance/field access functions.  */
394 static GTY(()) tree inst_id;
395
396 /* The "java.lang.Cloneable" qualified name.  */
397 static GTY(()) tree java_lang_cloneable;
398
399 /* The "java.io.Serializable" qualified name.  */
400 static GTY(()) tree java_io_serializable; 
401
402 /* Context and flag for static blocks */
403 static GTY(()) tree current_static_block;
404
405 /* The generated `write_parm_value$' identifier.  */
406 static GTY(()) tree wpv_id;
407
408 /* The list of all packages we've seen so far */
409 static GTY(()) tree package_list;
410  
411 /* Hold THIS for the scope of the current method decl.  */
412 static GTY(()) tree current_this;
413
414 /* Hold a list of catch clauses list. The first element of this list is
415    the list of the catch clauses of the currently analysed try block. */
416 static GTY(()) tree currently_caught_type_list;
417
418 /* This holds a linked list of all the case labels for the current
419    switch statement.  It is only used when checking to see if there
420    are duplicate labels.  FIXME: probably this should just be attached
421    to the switch itself; then it could be referenced via
422    `ctxp->current_loop'.  */
423 static GTY(()) tree case_label_list; 
424
425 /* Anonymous class counter. Will be reset to 1 every time a non
426    anonymous class gets created. */
427 static int anonymous_class_counter = 1;
428
429 static GTY(()) tree src_parse_roots[1];
430
431 /* All classes seen from source code */
432 #define gclass_list src_parse_roots[0]
433
434 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
435    line and point it out.  */
436 /* Should point out the one that don't fit. ASCII/unicode, going
437    backward. FIXME */
438
439 #define check_modifiers(__message, __value, __mask) do {        \
440   if ((__value) & ~(__mask))                                    \
441     {                                                           \
442       int i, remainder = (__value) & ~(__mask);                 \
443       for (i = 0; i <= 10; i++)                                 \
444         if ((1 << i) & remainder)                               \
445           parse_error_context (ctxp->modifier_ctx [i], (__message), \
446                                java_accstring_lookup (1 << i)); \
447     }                                                           \
448 } while (0)
449
450 %}
451
452 %union {
453   tree node;
454   int sub_token;
455   struct {
456     int token;
457     int location;
458   } operator;
459   int value;
460 }
461
462 %{
463 #include "lex.c"
464 %}
465
466 %pure_parser
467
468 /* Things defined here have to match the order of what's in the
469    binop_lookup table.  */
470
471 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
472 %token   LS_TK           SRS_TK          ZRS_TK
473 %token   AND_TK          XOR_TK          OR_TK
474 %token   BOOL_AND_TK BOOL_OR_TK 
475 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
476
477 /* This maps to the same binop_lookup entry than the token above */
478
479 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
480 %token   REM_ASSIGN_TK   
481 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
482 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
483
484
485 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
486
487 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
488 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
489 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
490 %token   PAD_TK          ABSTRACT_TK        STRICT_TK
491 %token   MODIFIER_TK
492
493 /* Keep those two in order, too */
494 %token   DECR_TK INCR_TK
495
496 /* From now one, things can be in any order */
497
498 %token   DEFAULT_TK      IF_TK              THROW_TK
499 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
500 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
501 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
502 %token   VOID_TK         CATCH_TK           INTERFACE_TK
503 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
504 %token   SUPER_TK        WHILE_TK           CLASS_TK
505 %token   SWITCH_TK       CONST_TK           TRY_TK
506 %token   FOR_TK          NEW_TK             CONTINUE_TK
507 %token   GOTO_TK         PACKAGE_TK         THIS_TK
508
509 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
510 %token   CHAR_TK         INTEGRAL_TK
511
512 %token   FLOAT_TK        DOUBLE_TK          FP_TK
513
514 %token   ID_TK
515
516 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
517
518 %token   ASSIGN_ANY_TK   ASSIGN_TK
519 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
520
521 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
522 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
523
524 %type    <value>        modifiers MODIFIER_TK final synchronized
525
526 %type    <node>         super ID_TK identifier
527 %type    <node>         name simple_name qualified_name
528 %type    <node>         type_declaration compilation_unit
529                         field_declaration method_declaration extends_interfaces
530                         interfaces interface_type_list
531                         class_member_declaration
532                         import_declarations package_declaration 
533                         type_declarations interface_body
534                         interface_member_declaration constant_declaration
535                         interface_member_declarations interface_type
536                         abstract_method_declaration interface_type_list
537 %type    <node>         class_body_declaration class_member_declaration
538                         static_initializer constructor_declaration block
539 %type    <node>         class_body_declarations constructor_header
540 %type    <node>         class_or_interface_type class_type class_type_list
541                         constructor_declarator explicit_constructor_invocation
542 %type    <node>         dim_expr dim_exprs this_or_super throws
543
544 %type    <node>         variable_declarator_id variable_declarator
545                         variable_declarators variable_initializer
546                         variable_initializers constructor_body
547                         array_initializer
548
549 %type    <node>         class_body block_end constructor_block_end
550 %type    <node>         statement statement_without_trailing_substatement
551                         labeled_statement if_then_statement label_decl
552                         if_then_else_statement while_statement for_statement
553                         statement_nsi labeled_statement_nsi do_statement
554                         if_then_else_statement_nsi while_statement_nsi
555                         for_statement_nsi statement_expression_list for_init
556                         for_update statement_expression expression_statement
557                         primary_no_new_array expression primary
558                         array_creation_expression array_type
559                         class_instance_creation_expression field_access
560                         method_invocation array_access something_dot_new
561                         argument_list postfix_expression while_expression 
562                         post_increment_expression post_decrement_expression
563                         unary_expression_not_plus_minus unary_expression
564                         pre_increment_expression pre_decrement_expression
565                         unary_expression_not_plus_minus cast_expression
566                         multiplicative_expression additive_expression
567                         shift_expression relational_expression 
568                         equality_expression and_expression 
569                         exclusive_or_expression inclusive_or_expression
570                         conditional_and_expression conditional_or_expression
571                         conditional_expression assignment_expression
572                         left_hand_side assignment for_header for_begin
573                         constant_expression do_statement_begin empty_statement
574                         switch_statement synchronized_statement throw_statement
575                         try_statement switch_expression switch_block
576                         catches catch_clause catch_clause_parameter finally
577                         anonymous_class_creation trap_overflow_corner_case
578 %type    <node>         return_statement break_statement continue_statement
579
580 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
581 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
582 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
583 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
584 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
585 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
586 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
587 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
588 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
589 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
590 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
591 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
592 %type    <operator>     NEW_TK
593
594 %type    <node>         method_body 
595         
596 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
597                         STRING_LIT_TK NULL_TK VOID_TK
598
599 %type    <node>         IF_TK WHILE_TK FOR_TK
600
601 %type    <node>         formal_parameter_list formal_parameter
602                         method_declarator method_header
603
604 %type    <node>         primitive_type reference_type type 
605                         BOOLEAN_TK INTEGRAL_TK FP_TK
606
607 /* Added or modified JDK 1.1 rule types  */
608 %type    <node>         type_literals
609
610 %%
611 /* 19.2 Production from 2.3: The Syntactic Grammar  */
612 goal:
613                 {
614                   /* Register static variables with the garbage
615                      collector.  */
616                   ggc_add_root (&ctxp, 1, 
617                                 sizeof (struct parser_ctxt *),
618                                 mark_parser_ctxt);
619                   ggc_add_root (&ctxp_for_generation, 1, 
620                                 sizeof (struct parser_ctxt *),
621                                 mark_parser_ctxt);
622                 }
623         compilation_unit
624                 {}
625 ;
626
627 /* 19.3 Productions from 3: Lexical structure  */
628 literal:
629         INT_LIT_TK
630 |       FP_LIT_TK
631 |       BOOL_LIT_TK
632 |       CHAR_LIT_TK
633 |       STRING_LIT_TK
634 |       NULL_TK
635 ;
636
637 /* 19.4 Productions from 4: Types, Values and Variables  */
638 type:
639         primitive_type
640 |       reference_type
641 ;
642
643 primitive_type:
644         INTEGRAL_TK
645 |       FP_TK
646 |       BOOLEAN_TK
647 ;
648
649 reference_type:
650         class_or_interface_type
651 |       array_type
652 ;
653
654 class_or_interface_type:
655         name
656 ;
657
658 class_type:
659         class_or_interface_type /* Default rule */
660 ;
661
662 interface_type:
663          class_or_interface_type
664 ;
665
666 array_type:
667         primitive_type dims
668                 { 
669                   int osb = pop_current_osb (ctxp);
670                   tree t = build_java_array_type (($1), -1);
671                   while (--osb)
672                     t = build_unresolved_array_type (t);
673                   $$ = t;
674                 }
675 |       name dims
676                 { 
677                   int osb = pop_current_osb (ctxp);
678                   tree t = $1;
679                   while (osb--)
680                     t = build_unresolved_array_type (t);
681                   $$ = t;
682                 }
683 ;
684
685 /* 19.5 Productions from 6: Names  */
686 name:
687         simple_name             /* Default rule */
688 |       qualified_name          /* Default rule */
689 ;
690
691 simple_name:
692         identifier              /* Default rule */
693 ;
694
695 qualified_name:
696         name DOT_TK identifier
697                 { $$ = make_qualified_name ($1, $3, $2.location); }
698 ;
699
700 identifier:
701         ID_TK
702 ;
703
704 /* 19.6: Production from 7: Packages  */
705 compilation_unit:
706                 {$$ = NULL;}
707 |       package_declaration
708 |       import_declarations
709 |       type_declarations
710 |       package_declaration import_declarations
711 |       package_declaration type_declarations
712 |       import_declarations type_declarations
713 |       package_declaration import_declarations type_declarations
714 ;
715
716 import_declarations:
717         import_declaration
718                 {
719                   $$ = NULL;
720                 }
721 |       import_declarations import_declaration
722                 {
723                   $$ = NULL;
724                 }
725 ;
726
727 type_declarations:
728         type_declaration
729 |       type_declarations type_declaration
730 ;
731
732 package_declaration:
733         PACKAGE_TK name SC_TK
734                 { 
735                   ctxp->package = EXPR_WFL_NODE ($2);
736                   register_package (ctxp->package);
737                 }
738 |       PACKAGE_TK error
739                 {yyerror ("Missing name"); RECOVER;}
740 |       PACKAGE_TK name error
741                 {yyerror ("';' expected"); RECOVER;}
742 ;
743
744 import_declaration:
745         single_type_import_declaration
746 |       type_import_on_demand_declaration
747 ;
748
749 single_type_import_declaration:
750         IMPORT_TK name SC_TK
751                 {
752                   tree name = EXPR_WFL_NODE ($2), last_name;
753                   int   i = IDENTIFIER_LENGTH (name)-1;
754                   const char *last = &IDENTIFIER_POINTER (name)[i];
755                   while (last != IDENTIFIER_POINTER (name))
756                     {
757                       if (last [0] == '.')
758                         break;
759                       last--;
760                     }
761                   last_name = get_identifier (++last);
762                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
763                     {
764                       tree err = find_name_in_single_imports (last_name);
765                       if (err && err != name)
766                         parse_error_context
767                           ($2, "Ambiguous class: `%s' and `%s'",
768                            IDENTIFIER_POINTER (name), 
769                            IDENTIFIER_POINTER (err));
770                       else
771                         REGISTER_IMPORT ($2, last_name);
772                     }
773                   else
774                     REGISTER_IMPORT ($2, last_name);
775                 }
776 |       IMPORT_TK error
777                 {yyerror ("Missing name"); RECOVER;}
778 |       IMPORT_TK name error
779                 {yyerror ("';' expected"); RECOVER;}
780 ;
781
782 type_import_on_demand_declaration:
783         IMPORT_TK name DOT_TK MULT_TK SC_TK
784                 {
785                   tree name = EXPR_WFL_NODE ($2);
786                   tree it;
787                   /* Search for duplicates. */
788                   for (it = ctxp->import_demand_list; it; it = TREE_CHAIN (it))
789                     if (EXPR_WFL_NODE (TREE_PURPOSE (it)) == name)
790                       break;
791                   /* Don't import the same thing more than once, just ignore
792                      duplicates (7.5.2) */
793                   if (! it)
794                     {
795                       read_import_dir ($2);
796                       ctxp->import_demand_list = 
797                         chainon (ctxp->import_demand_list,
798                                  build_tree_list ($2, NULL_TREE));
799                     }
800                 }
801 |       IMPORT_TK name DOT_TK error
802                 {yyerror ("'*' expected"); RECOVER;}
803 |       IMPORT_TK name DOT_TK MULT_TK error
804                 {yyerror ("';' expected"); RECOVER;}
805 ;
806
807 type_declaration:
808         class_declaration
809                 { end_class_declaration (0); }
810 |       interface_declaration
811                 { end_class_declaration (0); }
812 |       empty_statement
813 |       error
814                 {
815                   YYERROR_NOW;
816                   yyerror ("Class or interface declaration expected");
817                 }
818 ;
819
820 /* 19.7 Shortened from the original:
821    modifiers: modifier | modifiers modifier
822    modifier: any of public...  */
823 modifiers:
824         MODIFIER_TK
825                 {
826                   $$ = (1 << $1);
827                 }
828 |       modifiers MODIFIER_TK
829                 {
830                   int acc = (1 << $2);
831                   if ($$ & acc)
832                     parse_error_context 
833                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
834                        java_accstring_lookup (acc));
835                   else
836                     {
837                       $$ |= acc;
838                     }
839                 }
840 ;
841
842 /* 19.8.1 Production from $8.1: Class Declaration */
843 class_declaration:
844         modifiers CLASS_TK identifier super interfaces
845                 { create_class ($1, $3, $4, $5); }
846         class_body
847 |       CLASS_TK identifier super interfaces 
848                 { create_class (0, $2, $3, $4); }
849         class_body
850 |       modifiers CLASS_TK error
851                 {yyerror ("Missing class name"); RECOVER;}
852 |       CLASS_TK error
853                 {yyerror ("Missing class name"); RECOVER;}
854 |       CLASS_TK identifier error
855                 {
856                   if (!ctxp->class_err) yyerror ("'{' expected"); 
857                   DRECOVER(class1);
858                 }
859 |       modifiers CLASS_TK identifier error
860                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
861 ;
862
863 super:
864                 { $$ = NULL; }
865 |       EXTENDS_TK class_type
866                 { $$ = $2; }
867 |       EXTENDS_TK class_type error
868                 {yyerror ("'{' expected"); ctxp->class_err=1;}
869 |       EXTENDS_TK error
870                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
871 ;
872
873 interfaces:
874                 { $$ = NULL_TREE; }
875 |       IMPLEMENTS_TK interface_type_list
876                 { $$ = $2; }
877 |       IMPLEMENTS_TK error
878                 {
879                   ctxp->class_err=1;
880                   yyerror ("Missing interface name"); 
881                 }
882 ;
883
884 interface_type_list:
885         interface_type
886                 { 
887                   ctxp->interface_number = 1;
888                   $$ = build_tree_list ($1, NULL_TREE);
889                 }
890 |       interface_type_list C_TK interface_type
891                 { 
892                   ctxp->interface_number++;
893                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
894                 }
895 |       interface_type_list C_TK error
896                 {yyerror ("Missing interface name"); RECOVER;}
897 ;
898
899 class_body:
900         OCB_TK CCB_TK
901                 { 
902                   /* Store the location of the `}' when doing xrefs */
903                   if (flag_emit_xref)
904                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
905                       EXPR_WFL_ADD_COL ($2.location, 1);
906                   $$ = GET_CPC ();
907                 }
908 |       OCB_TK class_body_declarations CCB_TK
909                 { 
910                   /* Store the location of the `}' when doing xrefs */
911                   if (flag_emit_xref)
912                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
913                       EXPR_WFL_ADD_COL ($3.location, 1);
914                   $$ = GET_CPC ();
915                 }
916 ;
917
918 class_body_declarations:
919         class_body_declaration
920 |       class_body_declarations class_body_declaration
921 ;
922
923 class_body_declaration:
924         class_member_declaration
925 |       static_initializer
926 |       constructor_declaration
927 |       block                   /* Added, JDK1.1, instance initializer */
928                 {
929                   if ($1 != empty_stmt_node)
930                     {
931                       TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
932                       SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
933                     }
934                 }
935 ;
936
937 class_member_declaration:
938         field_declaration
939 |       method_declaration
940 |       class_declaration       /* Added, JDK1.1 inner classes */
941                 { end_class_declaration (1); }
942 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
943                 { end_class_declaration (1); }
944 |       empty_statement
945 ;
946
947 /* 19.8.2 Productions from 8.3: Field Declarations  */
948 field_declaration:
949         type variable_declarators SC_TK
950                 { register_fields (0, $1, $2); }
951 |       modifiers type variable_declarators SC_TK
952                 {
953                   check_modifiers 
954                     ("Illegal modifier `%s' for field declaration",
955                      $1, FIELD_MODIFIERS);
956                   check_modifiers_consistency ($1);
957                   register_fields ($1, $2, $3);
958                 }
959 ;
960
961 variable_declarators:
962         /* Should we use build_decl_list () instead ? FIXME */
963         variable_declarator     /* Default rule */
964 |       variable_declarators C_TK variable_declarator
965                 { $$ = chainon ($1, $3); }
966 |       variable_declarators C_TK error
967                 {yyerror ("Missing term"); RECOVER;}
968 ;
969
970 variable_declarator:
971         variable_declarator_id
972                 { $$ = build_tree_list ($1, NULL_TREE); }
973 |       variable_declarator_id ASSIGN_TK variable_initializer
974                 { 
975                   if (java_error_count)
976                     $3 = NULL_TREE;
977                   $$ = build_tree_list 
978                     ($1, build_assignment ($2.token, $2.location, $1, $3));
979                 }
980 |       variable_declarator_id ASSIGN_TK error
981                 {
982                   yyerror ("Missing variable initializer");
983                   $$ = build_tree_list ($1, NULL_TREE);
984                   RECOVER;
985                 }
986 |       variable_declarator_id ASSIGN_TK variable_initializer error
987                 {
988                   yyerror ("';' expected");
989                   $$ = build_tree_list ($1, NULL_TREE);
990                   RECOVER;
991                 }
992 ;
993
994 variable_declarator_id:
995         identifier
996 |       variable_declarator_id OSB_TK CSB_TK
997                 { $$ = build_unresolved_array_type ($1); }
998 |       identifier error
999                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
1000 |       variable_declarator_id OSB_TK error
1001                 { 
1002                   tree node = java_lval.node;
1003                   if (node && (TREE_CODE (node) == INTEGER_CST
1004                                || TREE_CODE (node) == EXPR_WITH_FILE_LOCATION))
1005                     yyerror ("Can't specify array dimension in a declaration");
1006                   else
1007                     yyerror ("']' expected");
1008                   DRECOVER(vdi);
1009                 }
1010 |       variable_declarator_id CSB_TK error
1011                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
1012 ;
1013
1014 variable_initializer:
1015         expression
1016 |       array_initializer
1017 ;
1018
1019 /* 19.8.3 Productions from 8.4: Method Declarations  */
1020 method_declaration:
1021         method_header 
1022                 {
1023                   current_function_decl = $1;
1024                   if (current_function_decl
1025                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
1026                     source_start_java_method (current_function_decl);
1027                   else
1028                     current_function_decl = NULL_TREE;
1029                 }
1030         method_body
1031                 { finish_method_declaration ($3); }
1032 |       method_header error
1033                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
1034 ;
1035
1036 method_header:  
1037         type method_declarator throws
1038                 { $$ = method_header (0, $1, $2, $3); }
1039 |       VOID_TK method_declarator throws
1040                 { $$ = method_header (0, void_type_node, $2, $3); }
1041 |       modifiers type method_declarator throws
1042                 { $$ = method_header ($1, $2, $3, $4); }
1043 |       modifiers VOID_TK method_declarator throws
1044                 { $$ = method_header ($1, void_type_node, $3, $4); }
1045 |       type error
1046                 {
1047                   yyerror ("Invalid method declaration, method name required");
1048                   RECOVER;
1049                 }
1050 |       modifiers type error
1051                 {RECOVER;}
1052 |       VOID_TK error
1053                 {yyerror ("Identifier expected"); RECOVER;}
1054 |       modifiers VOID_TK error
1055                 {yyerror ("Identifier expected"); RECOVER;}
1056 |       modifiers error
1057                 {
1058                   yyerror ("Invalid method declaration, return type required");
1059                   RECOVER;
1060                 }
1061 ;
1062
1063 method_declarator:
1064         identifier OP_TK CP_TK
1065                 { 
1066                   ctxp->formal_parameter_number = 0;
1067                   $$ = method_declarator ($1, NULL_TREE);
1068                 }
1069 |       identifier OP_TK formal_parameter_list CP_TK
1070                 { $$ = method_declarator ($1, $3); }
1071 |       method_declarator OSB_TK CSB_TK
1072                 {
1073                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1074                   TREE_PURPOSE ($1) = 
1075                     build_unresolved_array_type (TREE_PURPOSE ($1));
1076                   parse_warning_context 
1077                     (wfl_operator, 
1078                      "Discouraged form of returned type specification");
1079                 }
1080 |       identifier OP_TK error
1081                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1082 |       method_declarator OSB_TK error
1083                 {yyerror ("']' expected"); RECOVER;}
1084 ;
1085
1086 formal_parameter_list:
1087         formal_parameter
1088                 {
1089                   ctxp->formal_parameter_number = 1;
1090                 }
1091 |       formal_parameter_list C_TK formal_parameter
1092                 {
1093                   ctxp->formal_parameter_number += 1;
1094                   $$ = chainon ($1, $3);
1095                 }
1096 |       formal_parameter_list C_TK error
1097                 { yyerror ("Missing formal parameter term"); RECOVER; }
1098 ;
1099
1100 formal_parameter:
1101         type variable_declarator_id
1102                 {
1103                   $$ = build_tree_list ($2, $1);
1104                 }
1105 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1106                 { 
1107                   $$ = build_tree_list ($3, $2);
1108                   ARG_FINAL_P ($$) = 1;
1109                 }
1110 |       type error
1111                 {
1112                   yyerror ("Missing identifier"); RECOVER;
1113                   $$ = NULL_TREE;
1114                 }
1115 |       final type error
1116                 {
1117                   yyerror ("Missing identifier"); RECOVER;
1118                   $$ = NULL_TREE;
1119                 }
1120 ;
1121
1122 final:
1123         modifiers
1124                 {
1125                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1126                                    $1, ACC_FINAL);
1127                   if ($1 != ACC_FINAL)
1128                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1129                 }
1130 ;
1131
1132 throws:
1133                 { $$ = NULL_TREE; }
1134 |       THROWS_TK class_type_list
1135                 { $$ = $2; }
1136 |       THROWS_TK error
1137                 {yyerror ("Missing class type term"); RECOVER;}
1138 ;
1139
1140 class_type_list:
1141         class_type
1142                 { $$ = build_tree_list ($1, $1); }
1143 |       class_type_list C_TK class_type
1144                 { $$ = tree_cons ($3, $3, $1); }
1145 |       class_type_list C_TK error
1146                 {yyerror ("Missing class type term"); RECOVER;}
1147 ;
1148
1149 method_body:
1150         block
1151 |       SC_TK { $$ = NULL_TREE; }
1152 ;
1153
1154 /* 19.8.4 Productions from 8.5: Static Initializers  */
1155 static_initializer:
1156         static block
1157                 {
1158                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1159                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1160                   current_static_block = NULL_TREE;
1161                 }
1162 ;
1163
1164 static:                         /* Test lval.sub_token here */
1165         modifiers
1166                 {
1167                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1168                   /* Can't have a static initializer in an innerclass */
1169                   if ($1 | ACC_STATIC &&
1170                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1171                     parse_error_context 
1172                       (MODIFIER_WFL (STATIC_TK),
1173                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1174                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1175                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1176                 }
1177 ;
1178
1179 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1180 constructor_declaration:
1181         constructor_header
1182                 {
1183                   current_function_decl = $1;
1184                   source_start_java_method (current_function_decl);
1185                 }
1186         constructor_body
1187                 { finish_method_declaration ($3); }
1188 ;
1189
1190 constructor_header:
1191         constructor_declarator throws
1192                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1193 |       modifiers constructor_declarator throws
1194                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1195 ;
1196
1197 constructor_declarator:
1198         simple_name OP_TK CP_TK
1199                 { 
1200                   ctxp->formal_parameter_number = 0;  
1201                   $$ = method_declarator ($1, NULL_TREE);
1202                 }
1203 |       simple_name OP_TK formal_parameter_list CP_TK
1204                 { $$ = method_declarator ($1, $3); }
1205 ;
1206
1207 constructor_body:
1208         /* Unlike regular method, we always need a complete (empty)
1209            body so we can safely perform all the required code
1210            addition (super invocation and field initialization) */
1211         block_begin constructor_block_end
1212                 { 
1213                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1214                   $$ = $2;
1215                 }
1216 |       block_begin explicit_constructor_invocation constructor_block_end
1217                 { $$ = $3; }
1218 |       block_begin block_statements constructor_block_end
1219                 { $$ = $3; }
1220 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1221                 { $$ = $4; }
1222 ;
1223
1224 constructor_block_end:
1225         block_end
1226 ;
1227
1228 /* Error recovery for that rule moved down expression_statement: rule.  */
1229 explicit_constructor_invocation:
1230         this_or_super OP_TK CP_TK SC_TK
1231                 { 
1232                   $$ = build_method_invocation ($1, NULL_TREE); 
1233                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1234                   $$ = java_method_add_stmt (current_function_decl, $$);
1235                 }
1236 |       this_or_super OP_TK argument_list CP_TK SC_TK
1237                 { 
1238                   $$ = build_method_invocation ($1, $3); 
1239                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1240                   $$ = java_method_add_stmt (current_function_decl, $$);
1241                 }
1242         /* Added, JDK1.1 inner classes. Modified because the rule
1243            'primary' couldn't work.  */
1244 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1245                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1246 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1247                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1248 ;
1249
1250 this_or_super:                  /* Added, simplifies error diagnostics */
1251         THIS_TK
1252                 {
1253                   tree wfl = build_wfl_node (this_identifier_node);
1254                   EXPR_WFL_LINECOL (wfl) = $1.location;
1255                   $$ = wfl;
1256                 }
1257 |       SUPER_TK
1258                 {
1259                   tree wfl = build_wfl_node (super_identifier_node);
1260                   EXPR_WFL_LINECOL (wfl) = $1.location;
1261                   $$ = wfl;
1262                 }
1263 ;
1264
1265 /* 19.9 Productions from 9: Interfaces  */
1266 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1267 interface_declaration:
1268         INTERFACE_TK identifier
1269                 { create_interface (0, $2, NULL_TREE); }
1270         interface_body
1271 |       modifiers INTERFACE_TK identifier
1272                 { create_interface ($1, $3, NULL_TREE); }
1273         interface_body
1274 |       INTERFACE_TK identifier extends_interfaces
1275                 { create_interface (0, $2, $3); }
1276         interface_body
1277 |       modifiers INTERFACE_TK identifier extends_interfaces
1278                 { create_interface ($1, $3, $4); }
1279         interface_body
1280 |       INTERFACE_TK identifier error
1281                 {yyerror ("'{' expected"); RECOVER;}
1282 |       modifiers INTERFACE_TK identifier error
1283                 {yyerror ("'{' expected"); RECOVER;}
1284 ;
1285
1286 extends_interfaces:
1287         EXTENDS_TK interface_type
1288                 { 
1289                   ctxp->interface_number = 1;
1290                   $$ = build_tree_list ($2, NULL_TREE);
1291                 }
1292 |       extends_interfaces C_TK interface_type
1293                 { 
1294                   ctxp->interface_number++;
1295                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1296                 }
1297 |       EXTENDS_TK error
1298                 {yyerror ("Invalid interface type"); RECOVER;}
1299 |       extends_interfaces C_TK error
1300                 {yyerror ("Missing term"); RECOVER;}
1301 ;
1302
1303 interface_body:
1304         OCB_TK CCB_TK
1305                 { $$ = NULL_TREE; }
1306 |       OCB_TK interface_member_declarations CCB_TK
1307                 { $$ = NULL_TREE; }
1308 ;
1309
1310 interface_member_declarations:
1311         interface_member_declaration
1312 |       interface_member_declarations interface_member_declaration
1313 ;
1314
1315 interface_member_declaration:
1316         constant_declaration
1317 |       abstract_method_declaration
1318 |       class_declaration       /* Added, JDK1.1 inner classes */
1319                 { end_class_declaration (1); }
1320 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1321                 { end_class_declaration (1); }
1322 ;
1323
1324 constant_declaration:
1325         field_declaration
1326 ;
1327
1328 abstract_method_declaration:
1329         method_header SC_TK
1330                 { 
1331                   check_abstract_method_header ($1);
1332                   current_function_decl = NULL_TREE; /* FIXME ? */
1333                 }
1334 |       method_header error
1335                 {yyerror ("';' expected"); RECOVER;}
1336 ;
1337
1338 /* 19.10 Productions from 10: Arrays  */
1339 array_initializer:
1340         OCB_TK CCB_TK
1341                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1342 |       OCB_TK C_TK CCB_TK
1343                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1344 |       OCB_TK variable_initializers CCB_TK
1345                 { $$ = build_new_array_init ($1.location, $2); }
1346 |       OCB_TK variable_initializers C_TK CCB_TK
1347                 { $$ = build_new_array_init ($1.location, $2); }
1348 ;
1349
1350 variable_initializers:
1351         variable_initializer
1352                 { 
1353                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1354                                   $1, NULL_TREE);
1355                 }
1356 |       variable_initializers C_TK variable_initializer
1357                 {
1358                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1359                 }
1360 |       variable_initializers C_TK error
1361                 {yyerror ("Missing term"); RECOVER;}
1362 ;
1363
1364 /* 19.11 Production from 14: Blocks and Statements  */
1365 block:
1366         OCB_TK CCB_TK
1367                 { 
1368                   /* Store the location of the `}' when doing xrefs */
1369                   if (current_function_decl && flag_emit_xref)
1370                     DECL_END_SOURCE_LINE (current_function_decl) = 
1371                       EXPR_WFL_ADD_COL ($2.location, 1);
1372                   $$ = empty_stmt_node; 
1373                 }
1374 |       block_begin block_statements block_end
1375                 { $$ = $3; }
1376 ;
1377
1378 block_begin:
1379         OCB_TK
1380                 { enter_block (); }
1381 ;
1382
1383 block_end:
1384         CCB_TK
1385                 { 
1386                   maybe_absorb_scoping_blocks ();
1387                   /* Store the location of the `}' when doing xrefs */
1388                   if (current_function_decl && flag_emit_xref)
1389                     DECL_END_SOURCE_LINE (current_function_decl) = 
1390                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1391                   $$ = exit_block ();
1392                   if (!BLOCK_SUBBLOCKS ($$))
1393                     BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
1394                 }
1395 ;
1396
1397 block_statements:
1398         block_statement
1399 |       block_statements block_statement
1400 ;
1401
1402 block_statement:
1403         local_variable_declaration_statement
1404 |       statement
1405                 { java_method_add_stmt (current_function_decl, $1); }
1406 |       class_declaration       /* Added, JDK1.1 local classes */
1407                 { 
1408                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1409                   end_class_declaration (1);
1410                 }
1411 ;
1412
1413 local_variable_declaration_statement:
1414         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1415 ;
1416
1417 local_variable_declaration:
1418         type variable_declarators
1419                 { declare_local_variables (0, $1, $2); }
1420 |       final type variable_declarators /* Added, JDK1.1 final locals */
1421                 { declare_local_variables ($1, $2, $3); }
1422 ;
1423
1424 statement:
1425         statement_without_trailing_substatement
1426 |       labeled_statement
1427 |       if_then_statement
1428 |       if_then_else_statement
1429 |       while_statement
1430 |       for_statement
1431                 { $$ = exit_block (); }
1432 ;
1433
1434 statement_nsi:
1435         statement_without_trailing_substatement
1436 |       labeled_statement_nsi
1437 |       if_then_else_statement_nsi
1438 |       while_statement_nsi
1439 |       for_statement_nsi
1440                 { $$ = exit_block (); }
1441 ;
1442
1443 statement_without_trailing_substatement:
1444         block
1445 |       empty_statement
1446 |       expression_statement
1447 |       switch_statement
1448 |       do_statement
1449 |       break_statement
1450 |       continue_statement
1451 |       return_statement
1452 |       synchronized_statement
1453 |       throw_statement
1454 |       try_statement
1455 ;
1456
1457 empty_statement:
1458         SC_TK
1459                 { 
1460                   if (flag_extraneous_semicolon 
1461                       && ! current_static_block 
1462                       && (! current_function_decl || 
1463                           /* Verify we're not in a inner class declaration */
1464                           (GET_CPC () != TYPE_NAME
1465                            (DECL_CONTEXT (current_function_decl)))))
1466                            
1467                     {
1468                       EXPR_WFL_SET_LINECOL (wfl_operator, lineno, -1);
1469                       parse_warning_context (wfl_operator, "An empty declaration is a deprecated feature that should not be used");
1470                     }
1471                   $$ = empty_stmt_node;
1472                 }
1473 ;
1474
1475 label_decl:
1476         identifier REL_CL_TK
1477                 {
1478                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1479                                             EXPR_WFL_NODE ($1));
1480                   pushlevel (2);
1481                   push_labeled_block ($$);
1482                   PUSH_LABELED_BLOCK ($$);
1483                 }
1484 ;
1485
1486 labeled_statement:
1487         label_decl statement
1488                 { $$ = finish_labeled_statement ($1, $2); }
1489 |       identifier error
1490                 {yyerror ("':' expected"); RECOVER;}
1491 ;
1492
1493 labeled_statement_nsi:
1494         label_decl statement_nsi
1495                 { $$ = finish_labeled_statement ($1, $2); }
1496 ;
1497
1498 /* We concentrate here a bunch of error handling rules that we couldn't write
1499    earlier, because expression_statement catches a missing ';'.  */
1500 expression_statement:
1501         statement_expression SC_TK
1502                 {
1503                   /* We have a statement. Generate a WFL around it so
1504                      we can debug it */
1505                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1506                   /* We know we have a statement, so set the debug
1507                      info to be eventually generate here. */
1508                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1509                 }
1510 |       error SC_TK 
1511                 {
1512                   YYNOT_TWICE yyerror ("Invalid expression statement");
1513                   DRECOVER (expr_stmt);
1514                 }
1515 |       error OCB_TK
1516                 {
1517                   YYNOT_TWICE yyerror ("Invalid expression statement");
1518                   DRECOVER (expr_stmt);
1519                 }
1520 |       error CCB_TK
1521                 {
1522                   YYNOT_TWICE yyerror ("Invalid expression statement");
1523                   DRECOVER (expr_stmt);
1524                 }
1525 |       this_or_super OP_TK error
1526                 {yyerror ("')' expected"); RECOVER;}
1527 |       this_or_super OP_TK CP_TK error
1528                 {
1529                   parse_ctor_invocation_error ();
1530                   RECOVER;
1531                 }
1532 |       this_or_super OP_TK argument_list error
1533                 {yyerror ("')' expected"); RECOVER;}
1534 |       this_or_super OP_TK argument_list CP_TK error
1535                 {
1536                   parse_ctor_invocation_error ();
1537                   RECOVER;
1538                 }
1539 |       name DOT_TK SUPER_TK error
1540                 {yyerror ("'(' expected"); RECOVER;}
1541 |       name DOT_TK SUPER_TK OP_TK error
1542                 {yyerror ("')' expected"); RECOVER;}
1543 |       name DOT_TK SUPER_TK OP_TK argument_list error
1544                 {yyerror ("')' expected"); RECOVER;}
1545 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1546                 {yyerror ("';' expected"); RECOVER;}
1547 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1548                 {yyerror ("';' expected"); RECOVER;}
1549 ;
1550
1551 statement_expression: 
1552         assignment
1553 |       pre_increment_expression
1554 |       pre_decrement_expression
1555 |       post_increment_expression
1556 |       post_decrement_expression
1557 |       method_invocation
1558 |       class_instance_creation_expression
1559 ;
1560
1561 if_then_statement:
1562         IF_TK OP_TK expression CP_TK statement
1563                 { 
1564                   $$ = build_if_else_statement ($2.location, $3, 
1565                                                 $5, NULL_TREE);
1566                 }
1567 |       IF_TK error
1568                 {yyerror ("'(' expected"); RECOVER;}
1569 |       IF_TK OP_TK error
1570                 {yyerror ("Missing term"); RECOVER;}
1571 |       IF_TK OP_TK expression error
1572                 {yyerror ("')' expected"); RECOVER;}
1573 ;
1574
1575 if_then_else_statement:
1576         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1577                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1578 ;
1579
1580 if_then_else_statement_nsi:
1581         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1582                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1583 ;
1584
1585 switch_statement:
1586         switch_expression
1587                 {
1588                   enter_block ();
1589                 }
1590         switch_block
1591                 { 
1592                   /* Make into "proper list" of COMPOUND_EXPRs.
1593                      I.e. make the last statement also have its own
1594                      COMPOUND_EXPR. */
1595                   maybe_absorb_scoping_blocks ();
1596                   TREE_OPERAND ($1, 1) = exit_block ();
1597                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1598                 }
1599 ;
1600
1601 switch_expression:
1602         SWITCH_TK OP_TK expression CP_TK
1603                 { 
1604                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1605                   EXPR_WFL_LINECOL ($$) = $2.location;
1606                 }
1607 |       SWITCH_TK error
1608                 {yyerror ("'(' expected"); RECOVER;}
1609 |       SWITCH_TK OP_TK error
1610                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1611 |       SWITCH_TK OP_TK expression CP_TK error
1612                 {yyerror ("'{' expected"); RECOVER;}
1613 ;
1614
1615 /* Default assignment is there to avoid type node on switch_block
1616    node. */
1617
1618 switch_block:
1619         OCB_TK CCB_TK
1620                 { $$ = NULL_TREE; }
1621 |       OCB_TK switch_labels CCB_TK
1622                 { $$ = NULL_TREE; }
1623 |       OCB_TK switch_block_statement_groups CCB_TK
1624                 { $$ = NULL_TREE; }
1625 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1626                 { $$ = NULL_TREE; }
1627 ;
1628
1629 switch_block_statement_groups: 
1630         switch_block_statement_group
1631 |       switch_block_statement_groups switch_block_statement_group
1632 ;
1633
1634 switch_block_statement_group:
1635         switch_labels block_statements
1636 ;
1637
1638 switch_labels:
1639         switch_label
1640 |       switch_labels switch_label
1641 ;
1642
1643 switch_label:
1644         CASE_TK constant_expression REL_CL_TK
1645                 { 
1646                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1647                   EXPR_WFL_LINECOL (lab) = $1.location;
1648                   java_method_add_stmt (current_function_decl, lab);
1649                 }
1650 |       DEFAULT_TK REL_CL_TK
1651                 { 
1652                   tree lab = build (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1653                   EXPR_WFL_LINECOL (lab) = $1.location;
1654                   java_method_add_stmt (current_function_decl, lab);
1655                 }
1656 |       CASE_TK error
1657                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1658 |       CASE_TK constant_expression error
1659                 {yyerror ("':' expected"); RECOVER;}
1660 |       DEFAULT_TK error
1661                 {yyerror ("':' expected"); RECOVER;}
1662 ;
1663
1664 while_expression:
1665         WHILE_TK OP_TK expression CP_TK
1666                 { 
1667                   tree body = build_loop_body ($2.location, $3, 0);
1668                   $$ = build_new_loop (body);
1669                 }
1670 ;
1671
1672 while_statement:
1673         while_expression statement
1674                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1675 |       WHILE_TK error
1676                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1677 |       WHILE_TK OP_TK error
1678                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1679 |       WHILE_TK OP_TK expression error
1680                 {yyerror ("')' expected"); RECOVER;}
1681 ;
1682
1683 while_statement_nsi:
1684         while_expression statement_nsi
1685                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1686 ;
1687
1688 do_statement_begin:
1689         DO_TK
1690                 { 
1691                   tree body = build_loop_body (0, NULL_TREE, 1);
1692                   $$ = build_new_loop (body);
1693                 }
1694         /* Need error handing here. FIXME */
1695 ;
1696
1697 do_statement: 
1698         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1699                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1700 ;
1701
1702 for_statement:
1703         for_begin SC_TK expression SC_TK for_update CP_TK statement
1704                 {
1705                   if (TREE_CODE_CLASS (TREE_CODE ($3)) == 'c')
1706                     $3 = build_wfl_node ($3);
1707                   $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);
1708                 }
1709 |       for_begin SC_TK SC_TK for_update CP_TK statement
1710                 { 
1711                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1712                   /* We have not condition, so we get rid of the EXIT_EXPR */
1713                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1714                     empty_stmt_node;
1715                 }
1716 |       for_begin SC_TK error
1717                 {yyerror ("Invalid control expression"); RECOVER;}
1718 |       for_begin SC_TK expression SC_TK error
1719                 {yyerror ("Invalid update expression"); RECOVER;}
1720 |       for_begin SC_TK SC_TK error
1721                 {yyerror ("Invalid update expression"); RECOVER;}
1722 ;
1723
1724 for_statement_nsi:
1725         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1726                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1727 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1728                 { 
1729                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1730                   /* We have not condition, so we get rid of the EXIT_EXPR */
1731                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1732                     empty_stmt_node;
1733                 }
1734 ;
1735
1736 for_header:
1737         FOR_TK OP_TK
1738                 { 
1739                   /* This scope defined for local variable that may be
1740                      defined within the scope of the for loop */
1741                   enter_block (); 
1742                 }
1743 |       FOR_TK error
1744                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1745 |       FOR_TK OP_TK error
1746                 {yyerror ("Invalid init statement"); RECOVER;}
1747 ;
1748
1749 for_begin:
1750         for_header for_init
1751                 { 
1752                   /* We now declare the loop body. The loop is
1753                      declared as a for loop. */
1754                   tree body = build_loop_body (0, NULL_TREE, 0);
1755                   $$ =  build_new_loop (body);
1756                   FOR_LOOP_P ($$) = 1;
1757                   /* The loop is added to the current block the for
1758                      statement is defined within */
1759                   java_method_add_stmt (current_function_decl, $$);
1760                 }
1761 ;
1762 for_init:                       /* Can be empty */
1763                 { $$ = empty_stmt_node; }
1764 |       statement_expression_list
1765                 { 
1766                   /* Init statement recorded within the previously
1767                      defined block scope */
1768                   $$ = java_method_add_stmt (current_function_decl, $1);
1769                 }
1770 |       local_variable_declaration
1771                 { 
1772                   /* Local variable are recorded within the previously
1773                      defined block scope */
1774                   $$ = NULL_TREE;
1775                 }
1776 |       statement_expression_list error
1777                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1778 ;
1779
1780 for_update:                     /* Can be empty */
1781                 {$$ = empty_stmt_node;}
1782 |       statement_expression_list
1783                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1784 ;
1785
1786 statement_expression_list:
1787         statement_expression
1788                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1789 |       statement_expression_list C_TK statement_expression
1790                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1791 |       statement_expression_list C_TK error
1792                 {yyerror ("Missing term"); RECOVER;}
1793 ;
1794
1795 break_statement:
1796         BREAK_TK SC_TK
1797                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1798 |       BREAK_TK identifier SC_TK
1799                 { $$ = build_bc_statement ($1.location, 1, $2); }
1800 |       BREAK_TK error
1801                 {yyerror ("Missing term"); RECOVER;}
1802 |       BREAK_TK identifier error
1803                 {yyerror ("';' expected"); RECOVER;}
1804 ;
1805
1806 continue_statement:
1807         CONTINUE_TK SC_TK
1808                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1809 |       CONTINUE_TK identifier SC_TK
1810                 { $$ = build_bc_statement ($1.location, 0, $2); }
1811 |       CONTINUE_TK error
1812                 {yyerror ("Missing term"); RECOVER;}
1813 |       CONTINUE_TK identifier error
1814                 {yyerror ("';' expected"); RECOVER;}
1815 ;
1816
1817 return_statement:
1818         RETURN_TK SC_TK
1819                 { $$ = build_return ($1.location, NULL_TREE); }
1820 |       RETURN_TK expression SC_TK
1821                 { $$ = build_return ($1.location, $2); }
1822 |       RETURN_TK error
1823                 {yyerror ("Missing term"); RECOVER;}
1824 |       RETURN_TK expression error
1825                 {yyerror ("';' expected"); RECOVER;}
1826 ;
1827
1828 throw_statement:
1829         THROW_TK expression SC_TK
1830                 { 
1831                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1832                   EXPR_WFL_LINECOL ($$) = $1.location;
1833                 }
1834 |       THROW_TK error
1835                 {yyerror ("Missing term"); RECOVER;}
1836 |       THROW_TK expression error
1837                 {yyerror ("';' expected"); RECOVER;}
1838 ;
1839
1840 synchronized_statement:
1841         synchronized OP_TK expression CP_TK block
1842                 { 
1843                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1844                   EXPR_WFL_LINECOL ($$) = 
1845                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1846                 }
1847 |       synchronized OP_TK expression CP_TK error
1848                 {yyerror ("'{' expected"); RECOVER;}
1849 |       synchronized error
1850                 {yyerror ("'(' expected"); RECOVER;}
1851 |       synchronized OP_TK error CP_TK
1852                 {yyerror ("Missing term"); RECOVER;}
1853 |       synchronized OP_TK error
1854                 {yyerror ("Missing term"); RECOVER;}
1855 ;
1856
1857 synchronized:
1858         modifiers
1859                 {
1860                   check_modifiers (
1861              "Illegal modifier `%s'. Only `synchronized' was expected here",
1862                                    $1, ACC_SYNCHRONIZED);
1863                   if ($1 != ACC_SYNCHRONIZED)
1864                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1865                       build_wfl_node (NULL_TREE);
1866                 }
1867 ;
1868
1869 try_statement:
1870         TRY_TK block catches
1871                 { $$ = build_try_statement ($1.location, $2, $3); }
1872 |       TRY_TK block finally
1873                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1874 |       TRY_TK block catches finally
1875                 { $$ = build_try_finally_statement 
1876                     ($1.location, build_try_statement ($1.location,
1877                                                        $2, $3), $4);
1878                 }
1879 |       TRY_TK error
1880                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1881 ;
1882
1883 catches:
1884         catch_clause
1885 |       catches catch_clause
1886                 { 
1887                   TREE_CHAIN ($2) = $1;
1888                   $$ = $2;
1889                 }
1890 ;
1891
1892 catch_clause:
1893         catch_clause_parameter block
1894                 { 
1895                   java_method_add_stmt (current_function_decl, $2);
1896                   exit_block ();
1897                   $$ = $1;
1898                 }
1899
1900 catch_clause_parameter:
1901         CATCH_TK OP_TK formal_parameter CP_TK
1902                 { 
1903                   /* We add a block to define a scope for
1904                      formal_parameter (CCBP). The formal parameter is
1905                      declared initialized by the appropriate function
1906                      call */
1907                   tree ccpb = enter_block ();
1908                   tree init = build_assignment
1909                     (ASSIGN_TK, $2.location, TREE_PURPOSE ($3), 
1910                      build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
1911                   declare_local_variables (0, TREE_VALUE ($3),
1912                                            build_tree_list (TREE_PURPOSE ($3),
1913                                                             init));
1914                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1915                   EXPR_WFL_LINECOL ($$) = $1.location;
1916                 }
1917 |       CATCH_TK error
1918                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1919 |       CATCH_TK OP_TK error 
1920                 {
1921                   yyerror ("Missing term or ')' expected"); 
1922                   RECOVER; $$ = NULL_TREE;
1923                 }
1924 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1925                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1926 ;
1927
1928 finally:
1929         FINALLY_TK block
1930                 { $$ = $2; }
1931 |       FINALLY_TK error
1932                 {yyerror ("'{' expected"); RECOVER; }
1933 ;
1934
1935 /* 19.12 Production from 15: Expressions  */
1936 primary:
1937         primary_no_new_array
1938 |       array_creation_expression
1939 ;
1940
1941 primary_no_new_array:
1942         literal
1943 |       THIS_TK
1944                 { $$ = build_this ($1.location); }
1945 |       OP_TK expression CP_TK
1946                 {$$ = $2;}
1947 |       class_instance_creation_expression
1948 |       field_access
1949 |       method_invocation
1950 |       array_access
1951 |       type_literals
1952         /* Added, JDK1.1 inner classes. Documentation is wrong
1953            refering to a 'ClassName' (class_name) rule that doesn't
1954            exist. Used name: instead.  */
1955 |       name DOT_TK THIS_TK
1956                 { 
1957                   tree wfl = build_wfl_node (this_identifier_node);
1958                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1959                 }
1960 |       OP_TK expression error 
1961                 {yyerror ("')' expected"); RECOVER;}
1962 |       name DOT_TK error
1963                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1964 |       primitive_type DOT_TK error
1965                 {yyerror ("'class' expected" ); RECOVER;}
1966 |       VOID_TK DOT_TK error
1967                 {yyerror ("'class' expected" ); RECOVER;}
1968 ;
1969
1970 type_literals:
1971         name DOT_TK CLASS_TK
1972                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1973 |       array_type DOT_TK CLASS_TK
1974                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1975 |       primitive_type DOT_TK CLASS_TK
1976                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1977 |       VOID_TK DOT_TK CLASS_TK
1978                 { 
1979                    $$ = build_incomplete_class_ref ($2.location,
1980                                                    void_type_node);
1981                 }
1982 ;
1983
1984 class_instance_creation_expression:
1985         NEW_TK class_type OP_TK argument_list CP_TK
1986                 { $$ = build_new_invocation ($2, $4); }
1987 |       NEW_TK class_type OP_TK CP_TK
1988                 { $$ = build_new_invocation ($2, NULL_TREE); }
1989 |       anonymous_class_creation
1990         /* Added, JDK1.1 inner classes, modified to use name or
1991            primary instead of primary solely which couldn't work in
1992            all situations.  */
1993 |       something_dot_new identifier OP_TK CP_TK
1994                 { 
1995                   tree ctor = build_new_invocation ($2, NULL_TREE);
1996                   $$ = make_qualified_primary ($1, ctor, 
1997                                                EXPR_WFL_LINECOL ($1));
1998                 }
1999 |       something_dot_new identifier OP_TK CP_TK class_body
2000 |       something_dot_new identifier OP_TK argument_list CP_TK
2001                 { 
2002                   tree ctor = build_new_invocation ($2, $4);
2003                   $$ = make_qualified_primary ($1, ctor, 
2004                                                EXPR_WFL_LINECOL ($1));
2005                 }
2006 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
2007 |       NEW_TK error SC_TK 
2008                 {yyerror ("'(' expected"); DRECOVER(new_1);}
2009 |       NEW_TK class_type error
2010                 {yyerror ("'(' expected"); RECOVER;}
2011 |       NEW_TK class_type OP_TK error
2012                 {yyerror ("')' or term expected"); RECOVER;}
2013 |       NEW_TK class_type OP_TK argument_list error
2014                 {yyerror ("')' expected"); RECOVER;}
2015 |       something_dot_new error
2016                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
2017 |       something_dot_new identifier error
2018                 {yyerror ("'(' expected"); RECOVER;}
2019 ;
2020
2021 /* Created after JDK1.1 rules originally added to
2022    class_instance_creation_expression, but modified to use
2023    'class_type' instead of 'TypeName' (type_name) which is mentionned
2024    in the documentation but doesn't exist. */
2025
2026 anonymous_class_creation:
2027         NEW_TK class_type OP_TK argument_list CP_TK 
2028                 { create_anonymous_class ($1.location, $2); }
2029         class_body
2030                 { 
2031                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2032                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2033
2034                   end_class_declaration (1);
2035
2036                   /* Now we can craft the new expression */
2037                   $$ = build_new_invocation (id, $4);
2038
2039                   /* Note that we can't possibly be here if
2040                      `class_type' is an interface (in which case the
2041                      anonymous class extends Object and implements
2042                      `class_type', hence its constructor can't have
2043                      arguments.) */
2044
2045                   /* Otherwise, the innerclass must feature a
2046                      constructor matching `argument_list'. Anonymous
2047                      classes are a bit special: it's impossible to
2048                      define constructor for them, hence constructors
2049                      must be generated following the hints provided by
2050                      the `new' expression. Whether a super constructor
2051                      of that nature exists or not is to be verified
2052                      later on in verify_constructor_super. 
2053
2054                      It's during the expansion of a `new' statement
2055                      refering to an anonymous class that a ctor will
2056                      be generated for the anonymous class, with the
2057                      right arguments. */
2058
2059                 }
2060 |       NEW_TK class_type OP_TK CP_TK 
2061                 { create_anonymous_class ($1.location, $2); }
2062         class_body         
2063                 { 
2064                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2065                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2066
2067                   end_class_declaration (1);
2068
2069                   /* Now we can craft the new expression. The
2070                      statement doesn't need to be remember so that a
2071                      constructor can be generated, since its signature
2072                      is already known. */
2073                   $$ = build_new_invocation (id, NULL_TREE);
2074                 }
2075 ;
2076
2077 something_dot_new:              /* Added, not part of the specs. */
2078         name DOT_TK NEW_TK
2079                 { $$ = $1; }
2080 |       primary DOT_TK NEW_TK
2081                 { $$ = $1; }
2082 ;
2083
2084 argument_list:
2085         expression
2086                 { 
2087                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2088                   ctxp->formal_parameter_number = 1; 
2089                 }
2090 |       argument_list C_TK expression
2091                 {
2092                   ctxp->formal_parameter_number += 1;
2093                   $$ = tree_cons (NULL_TREE, $3, $1);
2094                 }
2095 |       argument_list C_TK error
2096                 {yyerror ("Missing term"); RECOVER;}
2097 ;
2098
2099 array_creation_expression:
2100         NEW_TK primitive_type dim_exprs
2101                 { $$ = build_newarray_node ($2, $3, 0); }
2102 |       NEW_TK class_or_interface_type dim_exprs
2103                 { $$ = build_newarray_node ($2, $3, 0); }
2104 |       NEW_TK primitive_type dim_exprs dims
2105                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2106 |       NEW_TK class_or_interface_type dim_exprs dims
2107                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2108         /* Added, JDK1.1 anonymous array. Initial documentation rule
2109            modified */
2110 |       NEW_TK class_or_interface_type dims array_initializer
2111                 {
2112                   char *sig;
2113                   int osb = pop_current_osb (ctxp);
2114                   while (osb--)
2115                     obstack_grow (&temporary_obstack, "[]", 2);
2116                   obstack_1grow (&temporary_obstack, '\0');
2117                   sig = obstack_finish (&temporary_obstack);
2118                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2119                               $2, get_identifier (sig), $4);
2120                 }
2121 |       NEW_TK primitive_type dims array_initializer
2122                 { 
2123                   int osb = pop_current_osb (ctxp);
2124                   tree type = $2;
2125                   while (osb--)
2126                     type = build_java_array_type (type, -1);
2127                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2128                               build_pointer_type (type), NULL_TREE, $4);
2129                 }
2130 |       NEW_TK error CSB_TK
2131                 {yyerror ("'[' expected"); DRECOVER ("]");}
2132 |       NEW_TK error OSB_TK
2133                 {yyerror ("']' expected"); RECOVER;}
2134 ;
2135
2136 dim_exprs:
2137         dim_expr
2138                 { $$ = build_tree_list (NULL_TREE, $1); }
2139 |       dim_exprs dim_expr
2140                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2141 ;
2142
2143 dim_expr:
2144         OSB_TK expression CSB_TK
2145                 { 
2146                   if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
2147                     {
2148                       $2 = build_wfl_node ($2);
2149                       TREE_TYPE ($2) = NULL_TREE;
2150                     }
2151                   EXPR_WFL_LINECOL ($2) = $1.location;
2152                   $$ = $2;
2153                 }
2154 |       OSB_TK expression error
2155                 {yyerror ("']' expected"); RECOVER;}
2156 |       OSB_TK error
2157                 {
2158                   yyerror ("Missing term");
2159                   yyerror ("']' expected");
2160                   RECOVER;
2161                 }
2162 ;
2163
2164 dims:                           
2165         OSB_TK CSB_TK
2166                 { 
2167                   int allocate = 0;
2168                   /* If not initialized, allocate memory for the osb
2169                      numbers stack */
2170                   if (!ctxp->osb_limit)
2171                     {
2172                       allocate = ctxp->osb_limit = 32;
2173                       ctxp->osb_depth = -1;
2174                     }
2175                   /* If capacity overflown, reallocate a bigger chunk */
2176                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2177                     allocate = ctxp->osb_limit << 1;
2178                   
2179                   if (allocate)
2180                     {
2181                       allocate *= sizeof (int);
2182                       if (ctxp->osb_number)
2183                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2184                                                             allocate);
2185                       else
2186                         ctxp->osb_number = (int *)xmalloc (allocate);
2187                     }
2188                   ctxp->osb_depth++;
2189                   CURRENT_OSB (ctxp) = 1;
2190                 }
2191 |       dims OSB_TK CSB_TK
2192                 { CURRENT_OSB (ctxp)++; }
2193 |       dims OSB_TK error
2194                 { yyerror ("']' expected"); RECOVER;}
2195 ;
2196
2197 field_access:
2198         primary DOT_TK identifier
2199                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2200                 /*  FIXME - REWRITE TO: 
2201                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2202 |       SUPER_TK DOT_TK identifier
2203                 {
2204                   tree super_wfl = build_wfl_node (super_identifier_node);
2205                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2206                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2207                 }
2208 |       SUPER_TK error
2209                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2210 ;
2211
2212 method_invocation:
2213         name OP_TK CP_TK
2214                 { $$ = build_method_invocation ($1, NULL_TREE); }
2215 |       name OP_TK argument_list CP_TK
2216                 { $$ = build_method_invocation ($1, $3); }
2217 |       primary DOT_TK identifier OP_TK CP_TK
2218                 { 
2219                   if (TREE_CODE ($1) == THIS_EXPR)
2220                     $$ = build_this_super_qualified_invocation 
2221                       (1, $3, NULL_TREE, 0, $2.location);
2222                   else
2223                     {
2224                       tree invok = build_method_invocation ($3, NULL_TREE);
2225                       $$ = make_qualified_primary ($1, invok, $2.location);
2226                     }
2227                 }
2228 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2229                 { 
2230                   if (TREE_CODE ($1) == THIS_EXPR)
2231                     $$ = build_this_super_qualified_invocation 
2232                       (1, $3, $5, 0, $2.location);
2233                   else
2234                     {
2235                       tree invok = build_method_invocation ($3, $5);
2236                       $$ = make_qualified_primary ($1, invok, $2.location);
2237                     }
2238                 }
2239 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2240                 { 
2241                   $$ = build_this_super_qualified_invocation 
2242                     (0, $3, NULL_TREE, $1.location, $2.location);
2243                 }
2244 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2245                 {
2246                   $$ = build_this_super_qualified_invocation 
2247                     (0, $3, $5, $1.location, $2.location);
2248                 }
2249         /* Screws up thing. I let it here until I'm convinced it can
2250            be removed. FIXME
2251 |       primary DOT_TK error
2252                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2253 |       SUPER_TK DOT_TK error CP_TK
2254                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2255 |       SUPER_TK DOT_TK error DOT_TK
2256                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2257 ;
2258
2259 array_access:
2260         name OSB_TK expression CSB_TK
2261                 { $$ = build_array_ref ($2.location, $1, $3); }
2262 |       primary_no_new_array OSB_TK expression CSB_TK
2263                 { $$ = build_array_ref ($2.location, $1, $3); }
2264 |       name OSB_TK error
2265                 {
2266                   yyerror ("Missing term and ']' expected");
2267                   DRECOVER(array_access);
2268                 }
2269 |       name OSB_TK expression error
2270                 {
2271                   yyerror ("']' expected");
2272                   DRECOVER(array_access);
2273                 }
2274 |       primary_no_new_array OSB_TK error
2275                 {
2276                   yyerror ("Missing term and ']' expected");
2277                   DRECOVER(array_access);
2278                 }
2279 |       primary_no_new_array OSB_TK expression error
2280                 {
2281                   yyerror ("']' expected");
2282                   DRECOVER(array_access);
2283                 }
2284 ;
2285
2286 postfix_expression:
2287         primary
2288 |       name
2289 |       post_increment_expression
2290 |       post_decrement_expression
2291 ;
2292
2293 post_increment_expression:
2294         postfix_expression INCR_TK
2295                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2296 ;
2297
2298 post_decrement_expression:
2299         postfix_expression DECR_TK
2300                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2301 ;
2302
2303 trap_overflow_corner_case:
2304         pre_increment_expression
2305 |       pre_decrement_expression
2306 |       PLUS_TK unary_expression
2307                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2308 |       unary_expression_not_plus_minus
2309 |       PLUS_TK error
2310                 {yyerror ("Missing term"); RECOVER}
2311 ;
2312
2313 unary_expression:
2314         trap_overflow_corner_case
2315                 {
2316                   error_if_numeric_overflow ($1);
2317                   $$ = $1;
2318                 }
2319 |       MINUS_TK trap_overflow_corner_case
2320                 {$$ = build_unaryop ($1.token, $1.location, $2); }
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                   obstack_grow (&temporary_obstack, 
2370                                 IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2371                                 IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2372                   while (osb--)
2373                     obstack_grow (&temporary_obstack, "[]", 2);
2374                   obstack_1grow (&temporary_obstack, '\0');
2375                   ptr = obstack_finish (&temporary_obstack);
2376                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2377                   $$ = build_cast ($1.location, $2, $5);
2378                 }
2379 |       OP_TK primitive_type OSB_TK error
2380                 {yyerror ("']' expected, invalid type expression");}
2381 |       OP_TK error
2382                 {
2383                   YYNOT_TWICE yyerror ("Invalid type expression"); RECOVER;
2384                   RECOVER;
2385                 }
2386 |       OP_TK primitive_type dims CP_TK error
2387                 {yyerror ("Missing term"); RECOVER;}
2388 |       OP_TK primitive_type CP_TK error
2389                 {yyerror ("Missing term"); RECOVER;}
2390 |       OP_TK name dims CP_TK error
2391                 {yyerror ("Missing term"); RECOVER;}
2392 ;
2393
2394 multiplicative_expression:
2395         unary_expression
2396 |       multiplicative_expression MULT_TK unary_expression
2397                 { 
2398                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2399                                     $2.location, $1, $3);
2400                 }
2401 |       multiplicative_expression DIV_TK unary_expression
2402                 {
2403                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2404                                     $1, $3); 
2405                 }
2406 |       multiplicative_expression REM_TK unary_expression
2407                 {
2408                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2409                                     $1, $3); 
2410                 }
2411 |       multiplicative_expression MULT_TK error
2412                 {yyerror ("Missing term"); RECOVER;}
2413 |       multiplicative_expression DIV_TK error
2414                 {yyerror ("Missing term"); RECOVER;}
2415 |       multiplicative_expression REM_TK error
2416                 {yyerror ("Missing term"); RECOVER;}
2417 ;
2418
2419 additive_expression:
2420         multiplicative_expression
2421 |       additive_expression PLUS_TK multiplicative_expression
2422                 {
2423                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2424                                     $1, $3); 
2425                 }
2426 |       additive_expression MINUS_TK multiplicative_expression
2427                 {
2428                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2429                                     $1, $3); 
2430                 }
2431 |       additive_expression PLUS_TK error
2432                 {yyerror ("Missing term"); RECOVER;}
2433 |       additive_expression MINUS_TK error
2434                 {yyerror ("Missing term"); RECOVER;}
2435 ;
2436
2437 shift_expression:
2438         additive_expression
2439 |       shift_expression LS_TK additive_expression
2440                 {
2441                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2442                                     $1, $3); 
2443                 }
2444 |       shift_expression SRS_TK additive_expression
2445                 {
2446                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2447                                     $1, $3); 
2448                 }
2449 |       shift_expression ZRS_TK additive_expression
2450                 {
2451                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2452                                     $1, $3); 
2453                 }
2454 |       shift_expression LS_TK error
2455                 {yyerror ("Missing term"); RECOVER;}
2456 |       shift_expression SRS_TK error
2457                 {yyerror ("Missing term"); RECOVER;}
2458 |       shift_expression ZRS_TK error
2459                 {yyerror ("Missing term"); RECOVER;}
2460 ;
2461
2462 relational_expression:
2463         shift_expression
2464 |       relational_expression LT_TK shift_expression
2465                 {
2466                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2467                                     $1, $3); 
2468                 }
2469 |       relational_expression GT_TK shift_expression
2470                 {
2471                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2472                                     $1, $3); 
2473                 }
2474 |       relational_expression LTE_TK shift_expression
2475                 {
2476                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2477                                     $1, $3); 
2478                 }
2479 |       relational_expression GTE_TK shift_expression
2480                 {
2481                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2482                                     $1, $3); 
2483                 }
2484 |       relational_expression INSTANCEOF_TK reference_type
2485                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2486 |       relational_expression LT_TK error
2487                 {yyerror ("Missing term"); RECOVER;}
2488 |       relational_expression GT_TK error
2489                 {yyerror ("Missing term"); RECOVER;}
2490 |       relational_expression LTE_TK error
2491                 {yyerror ("Missing term"); RECOVER;}
2492 |       relational_expression GTE_TK error
2493                 {yyerror ("Missing term"); RECOVER;}
2494 |       relational_expression INSTANCEOF_TK error
2495                 {yyerror ("Invalid reference type"); RECOVER;}
2496 ;
2497
2498 equality_expression:
2499         relational_expression
2500 |       equality_expression EQ_TK relational_expression
2501                 {
2502                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2503                                     $1, $3); 
2504                 }
2505 |       equality_expression NEQ_TK relational_expression
2506                 {
2507                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2508                                     $1, $3); 
2509                 }
2510 |       equality_expression EQ_TK error
2511                 {yyerror ("Missing term"); RECOVER;}
2512 |       equality_expression NEQ_TK error
2513                 {yyerror ("Missing term"); RECOVER;}
2514 ;
2515
2516 and_expression:
2517         equality_expression
2518 |       and_expression AND_TK equality_expression
2519                 {
2520                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2521                                     $1, $3); 
2522                 }
2523 |       and_expression AND_TK error
2524                 {yyerror ("Missing term"); RECOVER;}
2525 ;
2526
2527 exclusive_or_expression:
2528         and_expression
2529 |       exclusive_or_expression XOR_TK and_expression
2530                 {
2531                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2532                                     $1, $3); 
2533                 }
2534 |       exclusive_or_expression XOR_TK error
2535                 {yyerror ("Missing term"); RECOVER;}
2536 ;
2537
2538 inclusive_or_expression:
2539         exclusive_or_expression
2540 |       inclusive_or_expression OR_TK exclusive_or_expression
2541                 {
2542                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2543                                     $1, $3); 
2544                 }
2545 |       inclusive_or_expression OR_TK error
2546                 {yyerror ("Missing term"); RECOVER;}
2547 ;
2548
2549 conditional_and_expression:
2550         inclusive_or_expression
2551 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2552                 {
2553                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2554                                     $1, $3); 
2555                 }
2556 |       conditional_and_expression BOOL_AND_TK error
2557                 {yyerror ("Missing term"); RECOVER;}
2558 ;
2559
2560 conditional_or_expression:
2561         conditional_and_expression
2562 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2563                 {
2564                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2565                                     $1, $3); 
2566                 }
2567 |       conditional_or_expression BOOL_OR_TK error
2568                 {yyerror ("Missing term"); RECOVER;}
2569 ;
2570
2571 conditional_expression:         /* Error handling here is weak */
2572         conditional_or_expression
2573 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2574                 {
2575                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2576                   EXPR_WFL_LINECOL ($$) = $2.location;
2577                 }
2578 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2579                 {
2580                   YYERROR_NOW;
2581                   yyerror ("Missing term");
2582                   DRECOVER (1);
2583                 }
2584 |       conditional_or_expression REL_QM_TK error
2585                 {yyerror ("Missing term"); DRECOVER (2);}
2586 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2587                 {yyerror ("Missing term"); DRECOVER (3);}
2588 ;
2589
2590 assignment_expression:
2591         conditional_expression
2592 |       assignment
2593 ;
2594
2595 assignment:
2596         left_hand_side assignment_operator assignment_expression
2597                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2598 |       left_hand_side assignment_operator error
2599                 {
2600                   YYNOT_TWICE yyerror ("Missing term");
2601                   DRECOVER (assign);
2602                 }
2603 ;
2604
2605 left_hand_side:
2606         name
2607 |       field_access
2608 |       array_access
2609 ;
2610
2611 assignment_operator:
2612         ASSIGN_ANY_TK
2613 |       ASSIGN_TK
2614 ;
2615
2616 expression:
2617         assignment_expression
2618 ;
2619
2620 constant_expression:
2621         expression
2622 ;
2623
2624 %%
2625
2626 /* Helper function to retrieve an OSB count. Should be used when the
2627    `dims:' rule is being used.  */
2628
2629 static int
2630 pop_current_osb (ctxp)
2631      struct parser_ctxt *ctxp;
2632 {
2633   int to_return;
2634
2635   if (ctxp->osb_depth < 0)
2636     abort ();
2637   
2638   to_return = CURRENT_OSB (ctxp);
2639   ctxp->osb_depth--;
2640   
2641   return to_return;
2642 }
2643
2644 \f
2645
2646 /* This section of the code deal with save/restoring parser contexts.
2647    Add mode documentation here. FIXME */
2648
2649 /* Helper function. Create a new parser context. With
2650    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2651    context is copied, otherwise, the new context is zeroed. The newly
2652    created context becomes the current one.  */
2653
2654 static void
2655 create_new_parser_context (copy_from_previous)
2656     int copy_from_previous;
2657 {
2658   struct parser_ctxt *new;
2659
2660   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2661   if (copy_from_previous)
2662     {
2663       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2664       new->saved_data_ctx = 1;
2665     }
2666   else
2667     memset ((PTR) new, 0, sizeof (struct parser_ctxt));
2668       
2669   new->next = ctxp;
2670   ctxp = new;
2671 }
2672
2673 /* Create a new parser context and make it the current one. */
2674
2675 void
2676 java_push_parser_context ()
2677 {
2678   create_new_parser_context (0);
2679 }  
2680
2681 void 
2682 java_pop_parser_context (generate)
2683      int generate;
2684 {
2685   tree current;
2686   struct parser_ctxt *toFree, *next;
2687
2688   if (!ctxp)
2689     return;
2690
2691   toFree = ctxp;
2692   next = ctxp->next;
2693   if (next)
2694     {
2695       lineno = ctxp->lineno;
2696       current_class = ctxp->class_type;
2697     }
2698
2699   /* If the old and new lexers differ, then free the old one.  */
2700   if (ctxp->lexer && next && ctxp->lexer != next->lexer)
2701     java_destroy_lexer (ctxp->lexer);
2702
2703   /* Set the single import class file flag to 0 for the current list
2704      of imported things */
2705   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2706     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 0;
2707
2708   /* And restore those of the previous context */
2709   if ((ctxp = next))            /* Assignment is really meant here */
2710     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2711       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1;
2712   
2713   /* If we pushed a context to parse a class intended to be generated,
2714      we keep it so we can remember the class. What we could actually
2715      do is to just update a list of class names.  */
2716   if (generate)
2717     {
2718       toFree->next = ctxp_for_generation;
2719       ctxp_for_generation = toFree;
2720     }
2721   else
2722     free (toFree);
2723 }
2724
2725 /* Create a parser context for the use of saving some global
2726    variables.  */
2727
2728 void
2729 java_parser_context_save_global ()
2730 {
2731   if (!ctxp)
2732     {
2733       java_push_parser_context ();
2734       ctxp->saved_data_ctx = 1;
2735     }
2736
2737   /* If this context already stores data, create a new one suitable
2738      for data storage. */
2739   else if (ctxp->saved_data)
2740     create_new_parser_context (1);
2741
2742   ctxp->lineno = lineno;
2743   ctxp->class_type = current_class;
2744   ctxp->filename = input_filename;
2745   ctxp->function_decl = current_function_decl;
2746   ctxp->saved_data = 1;
2747 }
2748
2749 /* Restore some global variables from the previous context. Make the
2750    previous context the current one.  */
2751
2752 void
2753 java_parser_context_restore_global ()
2754 {
2755   lineno = ctxp->lineno;
2756   current_class = ctxp->class_type;
2757   input_filename = ctxp->filename;
2758   if (wfl_operator)
2759     {
2760       tree s;
2761       BUILD_FILENAME_IDENTIFIER_NODE (s, input_filename);
2762       EXPR_WFL_FILENAME_NODE (wfl_operator) = s;
2763     }
2764   current_function_decl = ctxp->function_decl;
2765   ctxp->saved_data = 0;
2766   if (ctxp->saved_data_ctx)
2767     java_pop_parser_context (0);
2768 }
2769
2770 /* Suspend vital data for the current class/function being parsed so
2771    that an other class can be parsed. Used to let local/anonymous
2772    classes be parsed.  */
2773
2774 static void
2775 java_parser_context_suspend ()
2776 {
2777   /* This makes debugging through java_debug_context easier */
2778   static const char *const name = "<inner buffer context>";
2779
2780   /* Duplicate the previous context, use it to save the globals we're
2781      interested in */
2782   create_new_parser_context (1);
2783   ctxp->function_decl = current_function_decl;
2784   ctxp->class_type = current_class;
2785
2786   /* Then create a new context which inherits all data from the
2787      previous one. This will be the new current context  */
2788   create_new_parser_context (1);
2789
2790   /* Help debugging */
2791   ctxp->next->filename = name;
2792 }
2793
2794 /* Resume vital data for the current class/function being parsed so
2795    that an other class can be parsed. Used to let local/anonymous
2796    classes be parsed.  The trick is the data storing file position
2797    informations must be restored to their current value, so parsing
2798    can resume as if no context was ever saved. */
2799
2800 static void
2801 java_parser_context_resume ()
2802 {
2803   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2804   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2805   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2806
2807   /* We need to inherit the list of classes to complete/generate */
2808   restored->classd_list = old->classd_list;
2809   restored->class_list = old->class_list;
2810
2811   /* Restore the current class and function from the saver */
2812   current_class = saver->class_type;
2813   current_function_decl = saver->function_decl;
2814
2815   /* Retrive the restored context */
2816   ctxp = restored;
2817
2818   /* Re-installed the data for the parsing to carry on */
2819   memcpy (&ctxp->marker_begining, &old->marker_begining, 
2820           (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2821
2822   /* Buffer context can now be discarded */
2823   free (saver);
2824   free (old);
2825 }
2826
2827 /* Add a new anchor node to which all statement(s) initializing static
2828    and non static initialized upon declaration field(s) will be
2829    linked.  */
2830
2831 static void
2832 java_parser_context_push_initialized_field ()
2833 {
2834   tree node;
2835
2836   node = build_tree_list (NULL_TREE, NULL_TREE);
2837   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2838   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2839
2840   node = build_tree_list (NULL_TREE, NULL_TREE);
2841   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2842   CPC_INITIALIZER_LIST (ctxp) = node;
2843
2844   node = build_tree_list (NULL_TREE, NULL_TREE);
2845   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2846   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2847 }
2848
2849 /* Pop the lists of initialized field. If this lists aren't empty,
2850    remember them so we can use it to create and populate the finit$
2851    or <clinit> functions. */
2852
2853 static void
2854 java_parser_context_pop_initialized_field ()
2855 {
2856   tree stmts;
2857   tree class_type = TREE_TYPE (GET_CPC ());
2858
2859   if (CPC_INITIALIZER_LIST (ctxp))
2860     {
2861       stmts = CPC_INITIALIZER_STMT (ctxp);
2862       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2863       if (stmts && !java_error_count)
2864         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2865     }
2866
2867   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2868     {
2869       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2870       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2871         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2872       /* Keep initialization in order to enforce 8.5 */
2873       if (stmts && !java_error_count)
2874         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2875     }
2876
2877   /* JDK 1.1 instance initializers */
2878   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2879     {
2880       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2881       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2882         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2883       if (stmts && !java_error_count)
2884         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2885     }
2886 }
2887
2888 static tree
2889 reorder_static_initialized (list)
2890      tree list;
2891 {
2892   /* We have to keep things in order. The alias initializer have to
2893      come first, then the initialized regular field, in reverse to
2894      keep them in lexical order. */
2895   tree marker, previous = NULL_TREE;
2896   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2897     if (TREE_CODE (marker) == TREE_LIST 
2898         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2899       break;
2900   
2901   /* No static initialized, the list is fine as is */
2902   if (!previous)
2903     list = TREE_CHAIN (marker);
2904
2905   /* No marker? reverse the whole list */
2906   else if (!marker)
2907     list = nreverse (list);
2908
2909   /* Otherwise, reverse what's after the marker and the new reordered
2910      sublist will replace the marker. */
2911   else
2912     {
2913       TREE_CHAIN (previous) = NULL_TREE;
2914       list = nreverse (list);
2915       list = chainon (TREE_CHAIN (marker), list);
2916     }
2917   return list;
2918 }
2919
2920 /* Helper functions to dump the parser context stack.  */
2921
2922 #define TAB_CONTEXT(C) \
2923   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2924
2925 static void
2926 java_debug_context_do (tab)
2927      int tab;
2928 {
2929   struct parser_ctxt *copy = ctxp;
2930   while (copy)
2931     {
2932       TAB_CONTEXT (tab);
2933       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2934       TAB_CONTEXT (tab);
2935       fprintf (stderr, "filename: %s\n", copy->filename);
2936       TAB_CONTEXT (tab);
2937       fprintf (stderr, "lineno: %d\n", copy->lineno);
2938       TAB_CONTEXT (tab);
2939       fprintf (stderr, "package: %s\n",
2940                (copy->package ? 
2941                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2942       TAB_CONTEXT (tab);
2943       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2944       TAB_CONTEXT (tab);
2945       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2946       copy = copy->next;
2947       tab += 2;
2948     }
2949 }
2950
2951 /* Dump the stacked up parser contexts. Intended to be called from a
2952    debugger.  */
2953
2954 void
2955 java_debug_context ()
2956 {
2957   java_debug_context_do (0);
2958 }
2959
2960 \f
2961
2962 /* Flag for the error report routine to issue the error the first time
2963    it's called (overriding the default behavior which is to drop the
2964    first invocation and honor the second one, taking advantage of a
2965    richer context.  */
2966 static int force_error = 0;
2967
2968 /* Reporting an constructor invocation error.  */
2969 static void
2970 parse_ctor_invocation_error ()
2971 {
2972   if (DECL_CONSTRUCTOR_P (current_function_decl))
2973     yyerror ("Constructor invocation must be first thing in a constructor"); 
2974   else
2975     yyerror ("Only constructors can invoke constructors");
2976 }
2977
2978 /* Reporting JDK1.1 features not implemented.  */
2979
2980 static tree
2981 parse_jdk1_1_error (msg)
2982     const char *msg;
2983 {
2984   sorry (": `%s' JDK1.1(TM) feature", msg);
2985   java_error_count++;
2986   return empty_stmt_node;
2987 }
2988
2989 static int do_warning = 0;
2990
2991 void
2992 yyerror (msg)
2993      const char *msg;
2994 {
2995   static java_lc elc;
2996   static int  prev_lineno;
2997   static const char *prev_msg;
2998
2999   int save_lineno;
3000   char *remainder, *code_from_source;
3001   
3002   if (!force_error && prev_lineno == lineno)
3003     return;
3004
3005   /* Save current error location but report latter, when the context is
3006      richer.  */
3007   if (ctxp->java_error_flag == 0)
3008     {
3009       ctxp->java_error_flag = 1;
3010       elc = ctxp->elc;
3011       /* Do something to use the previous line if we're reaching the
3012          end of the file... */
3013 #ifdef VERBOSE_SKELETON
3014       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
3015 #endif
3016       return;
3017     }
3018
3019   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
3020   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
3021     return;
3022
3023   ctxp->java_error_flag = 0;
3024   if (do_warning)
3025     java_warning_count++;
3026   else
3027     java_error_count++;
3028   
3029   if (elc.col == 0 && msg && msg[1] == ';')
3030     {
3031       elc.col  = ctxp->p_line->char_col-1;
3032       elc.line = ctxp->p_line->lineno;
3033     }
3034
3035   save_lineno = lineno;
3036   prev_lineno = lineno = elc.line;
3037   prev_msg = msg;
3038
3039   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
3040   obstack_grow0 (&temporary_obstack, 
3041                  code_from_source, strlen (code_from_source));
3042   remainder = obstack_finish (&temporary_obstack);
3043   if (do_warning)
3044     warning ("%s.\n%s", msg, remainder);
3045   else
3046     error ("%s.\n%s", msg, remainder);
3047
3048   /* This allow us to cheaply avoid an extra 'Invalid expression
3049      statement' error report when errors have been already reported on
3050      the same line. This occurs when we report an error but don't have
3051      a synchronization point other than ';', which
3052      expression_statement is the only one to take care of.  */
3053   ctxp->prevent_ese = lineno = save_lineno;
3054 }
3055
3056 static void
3057 issue_warning_error_from_context (cl, msg, ap)
3058      tree cl;
3059      const char *msg;
3060      va_list ap;
3061 {
3062   const char *saved, *saved_input_filename;
3063   char buffer [4096];
3064   vsprintf (buffer, msg, ap);
3065   force_error = 1;
3066
3067   ctxp->elc.line = EXPR_WFL_LINENO (cl);
3068   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
3069                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
3070
3071   /* We have a CL, that's a good reason for using it if it contains data */
3072   saved = ctxp->filename;
3073   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
3074     ctxp->filename = EXPR_WFL_FILENAME (cl);
3075   saved_input_filename = input_filename;
3076   input_filename = ctxp->filename;
3077   java_error (NULL);
3078   java_error (buffer);
3079   ctxp->filename = saved;
3080   input_filename = saved_input_filename;
3081   force_error = 0;
3082 }
3083
3084 /* Issue an error message at a current source line CL */
3085
3086 void
3087 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
3088 {
3089   VA_OPEN (ap, msg);
3090   VA_FIXEDARG (ap, tree, cl);
3091   VA_FIXEDARG (ap, const char *, msg);
3092   issue_warning_error_from_context (cl, msg, ap);
3093   VA_CLOSE (ap);
3094 }
3095
3096 /* Issue a warning at a current source line CL */
3097
3098 static void
3099 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3100 {
3101   VA_OPEN (ap, msg);
3102   VA_FIXEDARG (ap, tree, cl);
3103   VA_FIXEDARG (ap, const char *, msg);
3104
3105   force_error = do_warning = 1;
3106   issue_warning_error_from_context (cl, msg, ap);
3107   do_warning = force_error = 0;
3108   VA_CLOSE (ap);
3109 }
3110
3111 static tree
3112 find_expr_with_wfl (node)
3113      tree node;
3114 {
3115   while (node)
3116     {
3117       char code;
3118       tree to_return;
3119
3120       switch (TREE_CODE (node))
3121         {
3122         case BLOCK:
3123           node = BLOCK_EXPR_BODY (node);
3124           continue;
3125
3126         case COMPOUND_EXPR:
3127           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3128           if (to_return)
3129             return to_return;
3130           node = TREE_OPERAND (node, 1);
3131           continue;
3132
3133         case LOOP_EXPR:
3134           node = TREE_OPERAND (node, 0);
3135           continue;
3136           
3137         case LABELED_BLOCK_EXPR:
3138           node = TREE_OPERAND (node, 1);
3139           continue;
3140
3141         default:
3142           code = TREE_CODE_CLASS (TREE_CODE (node));
3143           if (((code == '1') || (code == '2') || (code == 'e'))
3144               && EXPR_WFL_LINECOL (node))
3145             return node;
3146           return NULL_TREE;
3147         }
3148     }
3149   return NULL_TREE;
3150 }
3151
3152 /* Issue a missing return statement error. Uses METHOD to figure the
3153    last line of the method the error occurs in.  */
3154
3155 static void
3156 missing_return_error (method)
3157      tree method;
3158 {
3159   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3160   parse_error_context (wfl_operator, "Missing return statement");
3161 }
3162
3163 /* Issue an unreachable statement error. From NODE, find the next
3164    statement to report appropriately.  */
3165 static void
3166 unreachable_stmt_error (node)
3167      tree node;
3168 {
3169   /* Browse node to find the next expression node that has a WFL. Use
3170      the location to report the error */
3171   if (TREE_CODE (node) == COMPOUND_EXPR)
3172     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3173   else
3174     node = find_expr_with_wfl (node);
3175
3176   if (node)
3177     {
3178       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3179       parse_error_context (wfl_operator, "Unreachable statement");
3180     }
3181   else
3182     abort ();
3183 }
3184
3185 int
3186 java_report_errors ()
3187 {
3188   if (java_error_count)
3189     fprintf (stderr, "%d error%s", 
3190              java_error_count, (java_error_count == 1 ? "" : "s"));
3191   if (java_warning_count)
3192     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3193              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3194   if (java_error_count || java_warning_count)
3195     putc ('\n', stderr);
3196   return java_error_count;
3197 }
3198
3199 static char *
3200 java_accstring_lookup (flags)
3201      int flags;
3202 {
3203   static char buffer [80];
3204 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3205
3206   /* Access modifier looked-up first for easier report on forbidden
3207      access. */
3208   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3209   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3210   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3211   if (flags & ACC_STATIC) COPY_RETURN ("static");
3212   if (flags & ACC_FINAL) COPY_RETURN ("final");
3213   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3214   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3215   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3216   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3217   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3218   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3219
3220   buffer [0] = '\0';
3221   return buffer;
3222 #undef COPY_RETURN
3223 }
3224
3225 /* Issuing error messages upon redefinition of classes, interfaces or
3226    variables. */
3227
3228 static void
3229 classitf_redefinition_error (context, id, decl, cl)
3230      const char *context;
3231      tree id, decl, cl;
3232 {
3233   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3234                        context, IDENTIFIER_POINTER (id), 
3235                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3236   /* Here we should point out where its redefined. It's a unicode. FIXME */
3237 }
3238
3239 static void
3240 variable_redefinition_error (context, name, type, line)
3241      tree context, name, type;
3242      int line;
3243 {
3244   const char *type_name;
3245
3246   /* Figure a proper name for type. We might haven't resolved it */
3247   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3248     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3249   else
3250     type_name = lang_printable_name (type, 0);
3251
3252   parse_error_context (context,
3253                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3254                        IDENTIFIER_POINTER (name),
3255                        type_name, IDENTIFIER_POINTER (name), line);
3256 }
3257
3258 /* If ANAME is terminated with `[]', it indicates an array. This
3259    function returns the number of `[]' found and if this number is
3260    greater than zero, it extracts the array type name and places it in
3261    the node pointed to by TRIMMED unless TRIMMED is null.  */
3262
3263 static int
3264 build_type_name_from_array_name (aname, trimmed)
3265      tree aname;
3266      tree *trimmed;
3267 {
3268   const char *name = IDENTIFIER_POINTER (aname);
3269   int len = IDENTIFIER_LENGTH (aname);
3270   int array_dims;
3271
3272   STRING_STRIP_BRACKETS (name, len, array_dims);
3273
3274   if (array_dims && trimmed)
3275     *trimmed = get_identifier_with_length (name, len);
3276
3277   return array_dims;
3278 }
3279
3280 static tree
3281 build_array_from_name (type, type_wfl, name, ret_name)
3282      tree type, type_wfl, name, *ret_name;
3283 {
3284   int more_dims = 0;
3285
3286   /* Eventually get more dims */
3287   more_dims = build_type_name_from_array_name (name, &name);
3288   
3289   /* If we have, then craft a new type for this variable */
3290   if (more_dims)
3291     {
3292       tree save = type;
3293
3294       /* If we have a pointer, use its type */
3295       if (TREE_CODE (type) == POINTER_TYPE)
3296         type = TREE_TYPE (type);
3297
3298       /* Building the first dimension of a primitive type uses this
3299          function */
3300       if (JPRIMITIVE_TYPE_P (type))
3301         {
3302           type = build_java_array_type (type, -1);
3303           more_dims--;
3304         }
3305       /* Otherwise, if we have a WFL for this type, use it (the type
3306          is already an array on an unresolved type, and we just keep
3307          on adding dimensions) */
3308       else if (type_wfl)
3309         {
3310           type = type_wfl;
3311           more_dims += build_type_name_from_array_name (TYPE_NAME (save),
3312                                                         NULL);
3313         }
3314
3315       /* Add all the dimensions */
3316       while (more_dims--)
3317         type = build_unresolved_array_type (type);
3318
3319       /* The type may have been incomplete in the first place */
3320       if (type_wfl)
3321         type = obtain_incomplete_type (type);
3322     }
3323
3324   if (ret_name)
3325     *ret_name = name;
3326   return type;
3327 }
3328
3329 /* Build something that the type identifier resolver will identify as
3330    being an array to an unresolved type. TYPE_WFL is a WFL on a
3331    identifier. */
3332
3333 static tree
3334 build_unresolved_array_type (type_or_wfl)
3335      tree type_or_wfl;
3336 {
3337   const char *ptr;
3338   tree wfl;
3339
3340   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3341      just create a array type */
3342   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3343     return build_java_array_type (type_or_wfl, -1);
3344
3345   obstack_grow (&temporary_obstack,
3346                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3347                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3348   obstack_grow0 (&temporary_obstack, "[]", 2);
3349   ptr = obstack_finish (&temporary_obstack);
3350   wfl = build_expr_wfl (get_identifier (ptr),
3351                         EXPR_WFL_FILENAME (type_or_wfl),
3352                         EXPR_WFL_LINENO (type_or_wfl),
3353                         EXPR_WFL_COLNO (type_or_wfl));
3354   /* Re-install the existing qualifications so that the type can be
3355      resolved properly. */
3356   EXPR_WFL_QUALIFICATION (wfl) = EXPR_WFL_QUALIFICATION (type_or_wfl);
3357   return wfl;
3358 }
3359
3360 static void
3361 parser_add_interface (class_decl, interface_decl, wfl)
3362      tree class_decl, interface_decl, wfl;
3363 {
3364   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3365     parse_error_context (wfl, "Interface `%s' repeated",
3366                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3367 }
3368
3369 /* Bulk of common class/interface checks. Return 1 if an error was
3370    encountered. TAG is 0 for a class, 1 for an interface.  */
3371
3372 static int
3373 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3374      int is_interface, flags;
3375      tree raw_name, qualified_name, decl, cl;
3376 {
3377   tree node;
3378   int sca = 0;                  /* Static class allowed */
3379   int icaf = 0;                 /* Inner class allowed flags */
3380   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3381
3382   if (!quiet_flag)
3383     fprintf (stderr, " %s%s %s", 
3384              (CPC_INNER_P () ? "inner" : ""),
3385              (is_interface ? "interface" : "class"), 
3386              IDENTIFIER_POINTER (qualified_name));
3387
3388   /* Scope of an interface/class type name:
3389        - Can't be imported by a single type import
3390        - Can't already exists in the package */
3391   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3392       && (node = find_name_in_single_imports (raw_name))
3393       && !CPC_INNER_P ())
3394     {
3395       parse_error_context 
3396         (cl, "%s name `%s' clashes with imported type `%s'",
3397          (is_interface ? "Interface" : "Class"),
3398          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3399       return 1;
3400     }
3401   if (decl && CLASS_COMPLETE_P (decl))
3402     {
3403       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3404                                    qualified_name, decl, cl);
3405       return 1;
3406     }
3407
3408   if (check_inner_class_redefinition (raw_name, cl))
3409     return 1;
3410
3411   /* If public, file name should match class/interface name, except
3412      when dealing with an inner class */
3413   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3414     {
3415       const char *f;
3416
3417       /* Contains OS dependent assumption on path separator. FIXME */
3418       for (f = &input_filename [strlen (input_filename)]; 
3419            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3420            f--)
3421         ;
3422       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3423         f++;
3424       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3425                    f , IDENTIFIER_LENGTH (raw_name)) ||
3426           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3427         parse_error_context
3428           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3429                              (is_interface ? "interface" : "class"),
3430                              IDENTIFIER_POINTER (qualified_name),
3431                              IDENTIFIER_POINTER (raw_name));
3432     }
3433
3434   /* Static classes can be declared only in top level classes. Note:
3435      once static, a inner class is a top level class. */
3436   if (flags & ACC_STATIC)
3437     {
3438       /* Catch the specific error of declaring an class inner class
3439          with no toplevel enclosing class. Prevent check_modifiers from
3440          complaining a second time */
3441       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3442         {
3443           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3444                                IDENTIFIER_POINTER (qualified_name));
3445           sca = ACC_STATIC;
3446         }
3447       /* Else, in the context of a top-level class declaration, let
3448          `check_modifiers' do its job, otherwise, give it a go */
3449       else
3450         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3451     }
3452
3453   /* Inner classes can be declared private or protected
3454      within their enclosing classes. */
3455   if (CPC_INNER_P ())
3456     {
3457       /* A class which is local to a block can't be public, private,
3458          protected or static. But it is created final, so allow this
3459          one. */
3460       if (current_function_decl)
3461         icaf = sca = uaaf = ACC_FINAL;
3462       else
3463         {
3464           check_modifiers_consistency (flags);
3465           icaf = ACC_PROTECTED;
3466           if (! CLASS_INTERFACE (GET_CPC ()))
3467             icaf |= ACC_PRIVATE;
3468         }
3469     }
3470
3471   if (is_interface) 
3472     {
3473       if (CPC_INNER_P ())
3474         uaaf = INTERFACE_INNER_MODIFIERS;
3475       else
3476         uaaf = INTERFACE_MODIFIERS;
3477       
3478       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3479                        flags, uaaf);
3480     }
3481   else
3482     check_modifiers ((current_function_decl ?
3483                       "Illegal modifier `%s' for local class declaration" :
3484                       "Illegal modifier `%s' for class declaration"),
3485                      flags, uaaf|sca|icaf);
3486   return 0;
3487 }
3488
3489 /* Construct a nested class name.  If the final component starts with
3490    a digit, return true.  Otherwise return false.  */
3491 static int
3492 make_nested_class_name (cpc_list)
3493      tree cpc_list;
3494 {
3495   tree name;
3496
3497   if (!cpc_list)
3498     return 0;
3499
3500   make_nested_class_name (TREE_CHAIN (cpc_list));
3501
3502   /* Pick the qualified name when dealing with the first upmost
3503      enclosing class */
3504   name = (TREE_CHAIN (cpc_list)
3505           ? TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3506   obstack_grow (&temporary_obstack,
3507                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3508   obstack_1grow (&temporary_obstack, '$');
3509
3510   return ISDIGIT (IDENTIFIER_POINTER (name)[0]);
3511 }
3512
3513 /* Can't redefine a class already defined in an earlier scope. */
3514
3515 static int
3516 check_inner_class_redefinition (raw_name, cl)
3517      tree raw_name, cl;
3518 {
3519   tree scope_list;
3520
3521   for (scope_list = GET_CPC_LIST (); scope_list; 
3522        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3523     if (raw_name == GET_CPC_UN_NODE (scope_list))
3524       {
3525         parse_error_context 
3526           (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",
3527            IDENTIFIER_POINTER (raw_name));
3528         return 1;
3529       }
3530   return 0;
3531 }
3532
3533 /* Tries to find a decl for CLASS_TYPE within ENCLOSING. If we fail,
3534    we remember ENCLOSING and SUPER.  */
3535
3536 static tree
3537 resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
3538      htab_t circularity_hash;
3539      tree cl, *enclosing, *super, class_type;
3540 {
3541   tree local_enclosing = *enclosing;
3542   tree local_super = NULL_TREE;
3543
3544   while (local_enclosing)
3545     {
3546       tree intermediate, decl;
3547
3548       *htab_find_slot (circularity_hash, local_enclosing, INSERT) =
3549         local_enclosing;
3550
3551       if ((decl = find_as_inner_class (local_enclosing, class_type, cl)))
3552         return decl;
3553
3554       intermediate = local_enclosing;
3555       /* Explore enclosing contexts. */
3556       while (INNER_CLASS_DECL_P (intermediate))
3557         {
3558           intermediate = DECL_CONTEXT (intermediate);
3559           if ((decl = find_as_inner_class (intermediate, class_type, cl)))
3560             return decl;
3561         }
3562
3563       /* Now go to the upper classes, bail out if necessary. We will
3564          analyze the returned SUPER and act accordingly (see
3565          do_resolve_class.) */
3566       local_super = CLASSTYPE_SUPER (TREE_TYPE (local_enclosing));
3567       if (!local_super || local_super == object_type_node)
3568         break;
3569
3570       if (TREE_CODE (local_super) == POINTER_TYPE)
3571         local_super = do_resolve_class (NULL, local_super, NULL, NULL);
3572       else
3573         local_super = TYPE_NAME (local_super);
3574
3575       /* We may not have checked for circular inheritance yet, so do so
3576          here to prevent an infinite loop. */
3577       if (htab_find (circularity_hash, local_super) != NULL)
3578         {
3579           if (!cl)
3580             cl = lookup_cl (local_enclosing);
3581           
3582           parse_error_context
3583             (cl, "Cyclic inheritance involving %s",
3584              IDENTIFIER_POINTER (DECL_NAME (local_enclosing)));
3585           local_enclosing = NULL_TREE;
3586         }
3587       else
3588         local_enclosing = local_super;
3589     }
3590
3591   /* We failed. Return LOCAL_SUPER and LOCAL_ENCLOSING. */
3592   *super = local_super;
3593   *enclosing = local_enclosing;
3594
3595   return NULL_TREE;
3596 }
3597
3598 /* Within ENCLOSING, find a decl for NAME and return it. NAME can be
3599    qualified. */
3600
3601 static tree
3602 find_as_inner_class (enclosing, name, cl)
3603      tree enclosing, name, cl;
3604 {
3605   tree qual, to_return;
3606   if (!enclosing)
3607     return NULL_TREE;
3608
3609   name = TYPE_NAME (name);
3610
3611   /* First search: within the scope of `enclosing', search for name */
3612   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3613     qual = EXPR_WFL_QUALIFICATION (cl);
3614   else if (cl)
3615     qual = build_tree_list (cl, NULL_TREE);
3616   else
3617     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3618   
3619   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3620     return to_return;
3621
3622   /* We're dealing with a qualified name. Try to resolve thing until
3623      we get something that is an enclosing class. */
3624   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3625     {
3626       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3627
3628       for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3629            qual = TREE_CHAIN (qual))
3630         {
3631           acc = merge_qualified_name (acc, 
3632                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3633           BUILD_PTR_FROM_NAME (ptr, acc);
3634           decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3635         }
3636
3637       /* A NULL qual and a decl means that the search ended
3638          successfully?!? We have to do something then. FIXME */
3639       
3640       if (decl)
3641         enclosing = decl;
3642       else
3643         qual = EXPR_WFL_QUALIFICATION (cl);
3644     }
3645   /* Otherwise, create a qual for the other part of the resolution. */
3646   else
3647     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3648   
3649   return find_as_inner_class_do (qual, enclosing);
3650 }
3651
3652 /* We go inside the list of sub classes and try to find a way
3653    through. */
3654
3655 static tree
3656 find_as_inner_class_do (qual, enclosing)
3657      tree qual, enclosing;
3658 {
3659   if (!qual)
3660     return NULL_TREE;
3661
3662   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3663     {
3664       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3665       tree next_enclosing = NULL_TREE;
3666       tree inner_list;
3667
3668       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3669            inner_list; inner_list = TREE_CHAIN (inner_list))
3670         {
3671           if (TREE_VALUE (inner_list) == name_to_match)
3672             {
3673               next_enclosing = TREE_PURPOSE (inner_list);
3674               break;
3675             }
3676         }
3677       enclosing = next_enclosing;
3678     }
3679
3680   return (!qual && enclosing ? enclosing : NULL_TREE);
3681 }
3682
3683 /* Reach all inner classes and tie their unqualified name to a
3684    DECL. */
3685
3686 static void
3687 set_nested_class_simple_name_value (outer, set)
3688      tree outer;
3689      int set;
3690 {
3691   tree l;
3692
3693   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3694     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3695                                                 TREE_PURPOSE (l) : NULL_TREE);
3696 }
3697
3698 static void
3699 link_nested_class_to_enclosing ()
3700 {
3701   if (GET_ENCLOSING_CPC ())
3702     {
3703       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3704       DECL_INNER_CLASS_LIST (enclosing) = 
3705         tree_cons (GET_CPC (), GET_CPC_UN (),
3706                    DECL_INNER_CLASS_LIST (enclosing));
3707     }
3708 }
3709
3710 static tree
3711 maybe_make_nested_class_name (name)
3712      tree name;
3713 {
3714   tree id = NULL_TREE;
3715
3716   if (CPC_INNER_P ())
3717     {
3718       /* If we're in a function, we must append a number to create the
3719          nested class name.  However, we don't do this if the class we
3720          are constructing is anonymous, because in that case we'll
3721          already have a number as the class name.  */
3722       if (! make_nested_class_name (GET_CPC_LIST ())
3723           && current_function_decl != NULL_TREE
3724           && ! ISDIGIT (IDENTIFIER_POINTER (name)[0]))
3725         {
3726           char buf[10];
3727           sprintf (buf, "%d", anonymous_class_counter);
3728           ++anonymous_class_counter;
3729           obstack_grow (&temporary_obstack, buf, strlen (buf));
3730           obstack_1grow (&temporary_obstack, '$');
3731         }
3732       obstack_grow0 (&temporary_obstack,
3733                      IDENTIFIER_POINTER (name), 
3734                      IDENTIFIER_LENGTH (name));
3735       id = get_identifier (obstack_finish (&temporary_obstack));
3736       if (ctxp->package)
3737         QUALIFIED_P (id) = 1;
3738     }
3739   return id;
3740 }
3741
3742 /* If DECL is NULL, create and push a new DECL, record the current
3743    line CL and do other maintenance things.  */
3744
3745 static tree
3746 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3747      tree decl, raw_name, qualified_name, cl;
3748 {
3749   if (!decl)
3750     decl = push_class (make_class (), qualified_name);
3751
3752   /* Take care of the file and line business */
3753   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3754   /* If we're emiting xrefs, store the line/col number information */
3755   if (flag_emit_xref)
3756     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3757   else
3758     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3759   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3760   CLASS_PARSED_P (TREE_TYPE (decl)) = 1;
3761   CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) =
3762     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3763
3764   PUSH_CPC (decl, raw_name);
3765   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3766
3767   /* Link the declaration to the already seen ones */
3768   TREE_CHAIN (decl) = ctxp->class_list;
3769   ctxp->class_list = decl;
3770
3771   /* Create a new nodes in the global lists */
3772   gclass_list = tree_cons (NULL_TREE, decl, gclass_list);
3773   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3774
3775   /* Install a new dependency list element */
3776   create_jdep_list (ctxp);
3777
3778   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3779                           IDENTIFIER_POINTER (qualified_name)));
3780   return decl;
3781 }
3782
3783 static void
3784 add_superinterfaces (decl, interface_list)
3785      tree decl, interface_list;
3786 {
3787   tree node;
3788   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3789      takes care of ensuring that:
3790        - This is an accessible interface type,
3791        - Circularity detection.
3792    parser_add_interface is then called. If present but not defined,
3793    the check operation is delayed until the super interface gets
3794    defined.  */
3795   for (node = interface_list; node; node = TREE_CHAIN (node))
3796     {
3797       tree current = TREE_PURPOSE (node);
3798       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3799       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3800         {
3801           if (!parser_check_super_interface (idecl, decl, current))
3802             parser_add_interface (decl, idecl, current);
3803         }
3804       else
3805         register_incomplete_type (JDEP_INTERFACE,
3806                                   current, decl, NULL_TREE);
3807     }
3808 }
3809
3810 /* Create an interface in pass1 and return its decl. Return the
3811    interface's decl in pass 2.  */
3812
3813 static tree
3814 create_interface (flags, id, super)
3815      int flags;
3816      tree id, super;
3817 {
3818   tree raw_name = EXPR_WFL_NODE (id);
3819   tree q_name = parser_qualified_classname (raw_name);
3820   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3821
3822   /* Certain syntax errors are making SUPER be like ID. Avoid this
3823      case. */
3824   if (ctxp->class_err && id == super)
3825     super = NULL;
3826
3827   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3828
3829   /* Basic checks: scope, redefinition, modifiers */ 
3830   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3831     {
3832       PUSH_ERROR ();
3833       return NULL_TREE;
3834     }
3835
3836   /* Suspend the current parsing context if we're parsing an inner
3837      interface */
3838   if (CPC_INNER_P ())
3839     {
3840       java_parser_context_suspend ();
3841       /* Interface members are public. */
3842       if (CLASS_INTERFACE (GET_CPC ()))
3843         flags |= ACC_PUBLIC;
3844     }
3845
3846   /* Push a new context for (static) initialized upon declaration fields */
3847   java_parser_context_push_initialized_field ();
3848
3849   /* Interface modifiers check
3850        - public/abstract allowed (already done at that point)
3851        - abstract is obsolete (comes first, it's a warning, or should be)
3852        - Can't use twice the same (checked in the modifier rule) */
3853   if ((flags & ACC_ABSTRACT) && flag_redundant)
3854     parse_warning_context 
3855       (MODIFIER_WFL (ABSTRACT_TK),
3856        "Redundant use of `abstract' modifier. Interface `%s' is implicitly abstract", IDENTIFIER_POINTER (raw_name));
3857
3858   /* Create a new decl if DECL is NULL, otherwise fix it */
3859   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3860
3861   /* Set super info and mark the class a complete */
3862   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3863                   object_type_node, ctxp->interface_number);
3864   ctxp->interface_number = 0;
3865   CLASS_COMPLETE_P (decl) = 1;
3866   add_superinterfaces (decl, super);
3867
3868   return decl;
3869 }
3870
3871 /* Patch anonymous class CLASS, by either extending or implementing
3872    DEP.  */
3873
3874 static void
3875 patch_anonymous_class (type_decl, class_decl, wfl)
3876     tree type_decl, class_decl, wfl;
3877 {
3878   tree class = TREE_TYPE (class_decl);
3879   tree type =  TREE_TYPE (type_decl);
3880   tree binfo = TYPE_BINFO (class);
3881
3882   /* If it's an interface, implement it */
3883   if (CLASS_INTERFACE (type_decl))
3884     {
3885       tree s_binfo;
3886       int length;
3887
3888       if (parser_check_super_interface (type_decl, class_decl, wfl))
3889         return;
3890
3891       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3892       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3893       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3894       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3895       /* And add the interface */
3896       parser_add_interface (class_decl, type_decl, wfl);
3897     }
3898   /* Otherwise, it's a type we want to extend */
3899   else
3900     {
3901       if (parser_check_super (type_decl, class_decl, wfl))
3902         return;
3903       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3904     }
3905 }
3906
3907 static tree
3908 create_anonymous_class (location, type_name)
3909     int location;
3910     tree type_name;
3911 {
3912   char buffer [80];
3913   tree super = NULL_TREE, itf = NULL_TREE;
3914   tree id, type_decl, class;
3915
3916   /* The unqualified name of the anonymous class. It's just a number. */
3917   sprintf (buffer, "%d", anonymous_class_counter++);
3918   id = build_wfl_node (get_identifier (buffer));
3919   EXPR_WFL_LINECOL (id) = location;
3920
3921   /* We know about the type to extend/implement. We go ahead */
3922   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3923     {
3924       /* Create a class which either implements on extends the designated
3925          class. The class bears an innacessible name. */
3926       if (CLASS_INTERFACE (type_decl))
3927         {
3928           /* It's OK to modify it here. It's been already used and
3929              shouldn't be reused */
3930           ctxp->interface_number = 1;
3931           /* Interfaces should presented as a list of WFLs */
3932           itf = build_tree_list (type_name, NULL_TREE);
3933         }
3934       else
3935         super = type_name;
3936     }
3937
3938   class = create_class (ACC_FINAL, id, super, itf);
3939
3940   /* We didn't know anything about the stuff. We register a dependence. */
3941   if (!type_decl)
3942     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3943
3944   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3945   return class;
3946 }
3947
3948 /* Create a class in pass1 and return its decl. Return class
3949    interface's decl in pass 2.  */
3950
3951 static tree
3952 create_class (flags, id, super, interfaces)
3953      int flags;
3954      tree id, super, interfaces;
3955 {
3956   tree raw_name = EXPR_WFL_NODE (id);
3957   tree class_id, decl;
3958   tree super_decl_type;
3959
3960   /* Certain syntax errors are making SUPER be like ID. Avoid this
3961      case. */
3962   if (ctxp->class_err && id == super)
3963     super = NULL;
3964
3965   class_id = parser_qualified_classname (raw_name);
3966   decl = IDENTIFIER_CLASS_VALUE (class_id);
3967   EXPR_WFL_NODE (id) = class_id;
3968
3969   /* Basic check: scope, redefinition, modifiers */
3970   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3971     {
3972       PUSH_ERROR ();
3973       return NULL_TREE;
3974     }
3975   
3976   /* Suspend the current parsing context if we're parsing an inner
3977      class or an anonymous class. */
3978   if (CPC_INNER_P ())
3979     {
3980       java_parser_context_suspend ();
3981       /* Interface members are public. */
3982       if (CLASS_INTERFACE (GET_CPC ()))
3983         flags |= ACC_PUBLIC;
3984     }
3985     
3986   /* Push a new context for (static) initialized upon declaration fields */
3987   java_parser_context_push_initialized_field ();
3988
3989   /* Class modifier check: 
3990        - Allowed modifier (already done at that point)
3991        - abstract AND final forbidden 
3992        - Public classes defined in the correct file */
3993   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3994     parse_error_context
3995       (id, "Class `%s' can't be declared both abstract and final",
3996        IDENTIFIER_POINTER (raw_name));
3997
3998   /* Create a new decl if DECL is NULL, otherwise fix it */
3999   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
4000
4001   /* If SUPER exists, use it, otherwise use Object */
4002   if (super)
4003     {
4004       /* Can't extend java.lang.Object */
4005       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
4006         {
4007           parse_error_context (id, "Can't extend `java.lang.Object'");
4008           return NULL_TREE;
4009         }
4010
4011       super_decl_type = 
4012         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
4013     }
4014   else if (TREE_TYPE (decl) != object_type_node)
4015     super_decl_type = object_type_node;
4016   /* We're defining java.lang.Object */
4017   else
4018     super_decl_type = NULL_TREE;
4019
4020   /* A class nested in an interface is implicitly static. */
4021   if (INNER_CLASS_DECL_P (decl)
4022       && CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (DECL_CONTEXT (decl)))))
4023     {
4024       flags |= ACC_STATIC;
4025     }
4026
4027   /* Set super info and mark the class as complete. */
4028   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
4029                   ctxp->interface_number);
4030   ctxp->interface_number = 0;
4031   CLASS_COMPLETE_P (decl) = 1;
4032   add_superinterfaces (decl, interfaces);
4033
4034   /* Add the private this$<n> field, Replicate final locals still in
4035      scope as private final fields mangled like val$<local_name>.
4036      This doesn't not occur for top level (static) inner classes. */
4037   if (PURE_INNER_CLASS_DECL_P (decl))
4038     add_inner_class_fields (decl, current_function_decl);
4039
4040   /* If doing xref, store the location at which the inherited class
4041      (if any) was seen. */
4042   if (flag_emit_xref && super)
4043     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
4044
4045   /* Eventually sets the @deprecated tag flag */
4046   CHECK_DEPRECATED (decl);
4047
4048   /* Reset the anonymous class counter when declaring non inner classes */
4049   if (!INNER_CLASS_DECL_P (decl))
4050     anonymous_class_counter = 1;
4051
4052   return decl;
4053 }
4054
4055 /* End a class declaration: register the statements used to create
4056    finit$ and <clinit>, pop the current class and resume the prior
4057    parser context if necessary.  */
4058
4059 static void
4060 end_class_declaration (resume)
4061      int resume;
4062 {
4063   /* If an error occurred, context weren't pushed and won't need to be
4064      popped by a resume. */
4065   int no_error_occurred = ctxp->next && GET_CPC () != error_mark_node;
4066
4067   if (GET_CPC () != error_mark_node)
4068     dump_java_tree (TDI_class, GET_CPC ());
4069
4070   java_parser_context_pop_initialized_field ();
4071   POP_CPC ();
4072   if (resume && no_error_occurred)
4073     java_parser_context_resume ();
4074
4075   /* We're ending a class declaration, this is a good time to reset
4076      the interface cout. Note that might have been already done in
4077      create_interface, but if at that time an inner class was being
4078      dealt with, the interface count was reset in a context created
4079      for the sake of handling inner classes declaration. */
4080   ctxp->interface_number = 0;
4081 }
4082
4083 static void
4084 add_inner_class_fields (class_decl, fct_decl)
4085      tree class_decl;
4086      tree fct_decl;
4087 {
4088   tree block, marker, f;
4089
4090   f = add_field (TREE_TYPE (class_decl),
4091                  build_current_thisn (TREE_TYPE (class_decl)),
4092                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
4093                  ACC_PRIVATE);
4094   FIELD_THISN (f) = 1;
4095
4096   if (!fct_decl)
4097     return;
4098     
4099   for (block = GET_CURRENT_BLOCK (fct_decl); 
4100        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
4101     {
4102       tree decl;
4103       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
4104         {
4105           tree name, pname;
4106           tree wfl, init, list;
4107           
4108           /* Avoid non final arguments. */
4109           if (!LOCAL_FINAL_P (decl))
4110             continue;
4111           
4112           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
4113           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
4114           wfl = build_wfl_node (name);
4115           init = build_wfl_node (pname);
4116           /* Build an initialization for the field: it will be
4117              initialized by a parameter added to finit$, bearing a
4118              mangled name of the field itself (param$<n>.) The
4119              parameter is provided to finit$ by the constructor
4120              invoking it (hence the constructor will also feature a
4121              hidden parameter, set to the value of the outer context
4122              local at the time the inner class is created.)
4123              
4124              Note: we take into account all possible locals that can
4125              be accessed by the inner class. It's actually not trivial
4126              to minimize these aliases down to the ones really
4127              used. One way to do that would be to expand all regular
4128              methods first, then finit$ to get a picture of what's
4129              used.  It works with the exception that we would have to
4130              go back on all constructor invoked in regular methods to
4131              have their invokation reworked (to include the right amount
4132              of alias initializer parameters.)
4133
4134              The only real way around, I think, is a first pass to
4135              identify locals really used in the inner class. We leave
4136              the flag FIELD_LOCAL_ALIAS_USED around for that future
4137              use.
4138              
4139              On the other hand, it only affect local inner classes,
4140              whose constructors (and finit$ call) will be featuring
4141              unecessary arguments. It's easy for a developper to keep
4142              this number of parameter down by using the `final'
4143              keyword only when necessary. For the time being, we can
4144              issue a warning on unecessary finals. FIXME */
4145           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
4146                                    wfl, init);
4147
4148           /* Register the field. The TREE_LIST holding the part
4149              initialized/initializer will be marked ARG_FINAL_P so
4150              that the created field can be marked
4151              FIELD_LOCAL_ALIAS. */
4152           list = build_tree_list (wfl, init);
4153           ARG_FINAL_P (list) = 1;
4154           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
4155         }
4156     }
4157
4158   if (!CPC_INITIALIZER_STMT (ctxp))
4159     return;
4160
4161   /* If we ever registered an alias field, insert and marker to
4162      remeber where the list ends. The second part of the list (the one
4163      featuring initialized fields) so it can be later reversed to
4164      enforce 8.5. The marker will be removed during that operation. */
4165   marker = build_tree_list (NULL_TREE, NULL_TREE);
4166   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
4167   SET_CPC_INITIALIZER_STMT (ctxp, marker);
4168 }
4169
4170 /* Can't use lookup_field () since we don't want to load the class and
4171    can't set the CLASS_LOADED_P flag */
4172
4173 static tree
4174 find_field (class, name)
4175      tree class;
4176      tree name;
4177 {
4178   tree decl;
4179   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
4180     {
4181       if (DECL_NAME (decl) == name)
4182         return decl;
4183     }
4184   return NULL_TREE;
4185 }
4186
4187 /* Wrap around lookup_field that doesn't potentially upset the value
4188    of CLASS */
4189
4190 static tree
4191 lookup_field_wrapper (class, name)
4192      tree class, name;
4193 {
4194   tree type = class;
4195   tree decl = NULL_TREE;
4196   java_parser_context_save_global ();
4197
4198   /* Last chance: if we're within the context of an inner class, we
4199      might be trying to access a local variable defined in an outer
4200      context. We try to look for it now. */
4201   if (INNER_CLASS_TYPE_P (class) && TREE_CODE (name) == IDENTIFIER_NODE)
4202     {
4203       tree new_name;
4204       MANGLE_OUTER_LOCAL_VARIABLE_NAME (new_name, name);
4205       decl = lookup_field (&type, new_name);
4206       if (decl && decl != error_mark_node)
4207         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4208     }
4209   if (!decl || decl == error_mark_node)
4210     {
4211       type = class;
4212       decl = lookup_field (&type, name);
4213     }
4214
4215   /* If the field still hasn't been found, try the next enclosing context. */
4216   if (!decl && INNER_CLASS_TYPE_P (class))
4217     {
4218       tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
4219       decl = lookup_field_wrapper (outer_type, name);
4220     }
4221
4222   java_parser_context_restore_global ();
4223   return decl == error_mark_node ? NULL : decl;
4224 }
4225
4226 /* Find duplicate field within the same class declarations and report
4227    the error. Returns 1 if a duplicated field was found, 0
4228    otherwise.  */
4229
4230 static int
4231 duplicate_declaration_error_p (new_field_name, new_type, cl)
4232      tree new_field_name, new_type, cl;
4233 {
4234   /* This might be modified to work with method decl as well */
4235   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4236   if (decl)
4237     {
4238       char *t1 = xstrdup (purify_type_name
4239                          ((TREE_CODE (new_type) == POINTER_TYPE 
4240                            && TREE_TYPE (new_type) == NULL_TREE) ?
4241                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4242                           lang_printable_name (new_type, 1)));
4243       /* The type may not have been completed by the time we report
4244          the error */
4245       char *t2 = xstrdup (purify_type_name
4246                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4247                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4248                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4249                           lang_printable_name (TREE_TYPE (decl), 1)));
4250       parse_error_context 
4251         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4252          t1, IDENTIFIER_POINTER (new_field_name),
4253          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4254          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4255       free (t1);
4256       free (t2);
4257       return 1;
4258     }
4259   return 0;
4260 }
4261
4262 /* Field registration routine. If TYPE doesn't exist, field
4263    declarations are linked to the undefined TYPE dependency list, to
4264    be later resolved in java_complete_class () */
4265
4266 static void
4267 register_fields (flags, type, variable_list)
4268      int flags;
4269      tree type, variable_list;
4270 {
4271   tree current, saved_type;
4272   tree class_type = NULL_TREE;
4273   int saved_lineno = lineno;
4274   int must_chain = 0;
4275   tree wfl = NULL_TREE;
4276
4277   if (GET_CPC ())
4278     class_type = TREE_TYPE (GET_CPC ());
4279
4280   if (!class_type || class_type == error_mark_node)
4281     return;
4282
4283   /* If we're adding fields to interfaces, those fields are public,
4284      static, final */
4285   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4286     {
4287       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4288                                  flags, ACC_PUBLIC, "interface field(s)");
4289       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4290                                  flags, ACC_STATIC, "interface field(s)");
4291       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4292                                  flags, ACC_FINAL, "interface field(s)");
4293       check_modifiers ("Illegal interface member modifier `%s'", flags,
4294                        INTERFACE_FIELD_MODIFIERS);
4295       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4296     }
4297
4298   /* Obtain a suitable type for resolution, if necessary */
4299   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4300
4301   /* If TYPE is fully resolved and we don't have a reference, make one */
4302   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4303
4304   for (current = variable_list, saved_type = type; current; 
4305        current = TREE_CHAIN (current), type = saved_type)
4306     {
4307       tree real_type;
4308       tree field_decl;
4309       tree cl = TREE_PURPOSE (current);
4310       tree init = TREE_VALUE (current);
4311       tree current_name = EXPR_WFL_NODE (cl);
4312
4313       /* Can't declare non-final static fields in inner classes */
4314       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4315           && !(flags & ACC_FINAL))
4316         parse_error_context 
4317           (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
4318            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4319            lang_printable_name (class_type, 0));
4320
4321       /* Process NAME, as it may specify extra dimension(s) for it */
4322       type = build_array_from_name (type, wfl, current_name, &current_name);
4323
4324       /* Type adjustment. We may have just readjusted TYPE because
4325          the variable specified more dimensions. Make sure we have
4326          a reference if we can and don't have one already. Also
4327          change the name if we have an init. */
4328       if (type != saved_type)
4329         {
4330           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4331           if (init)
4332             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4333         }
4334
4335       real_type = GET_REAL_TYPE (type);
4336       /* Check for redeclarations */
4337       if (duplicate_declaration_error_p (current_name, real_type, cl))
4338         continue;
4339
4340       /* Set lineno to the line the field was found and create a
4341          declaration for it. Eventually sets the @deprecated tag flag. */
4342       if (flag_emit_xref)
4343         lineno = EXPR_WFL_LINECOL (cl);
4344       else
4345         lineno = EXPR_WFL_LINENO (cl);
4346       field_decl = add_field (class_type, current_name, real_type, flags);
4347       CHECK_DEPRECATED (field_decl);
4348
4349       /* If the field denotes a final instance variable, then we
4350          allocate a LANG_DECL_SPECIFIC part to keep track of its
4351          initialization. We also mark whether the field was
4352          initialized upon its declaration. We don't do that if the
4353          created field is an alias to a final local. */
4354       if (!ARG_FINAL_P (current) && (flags & ACC_FINAL))
4355         {
4356           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field_decl);
4357           DECL_FIELD_FINAL_WFL (field_decl) = cl;
4358         }
4359
4360       /* If the couple initializer/initialized is marked ARG_FINAL_P,
4361          we mark the created field FIELD_LOCAL_ALIAS, so that we can
4362          hide parameters to this inner class finit$ and
4363          constructors. It also means that the field isn't final per
4364          say. */
4365       if (ARG_FINAL_P (current))
4366         {
4367           FIELD_LOCAL_ALIAS (field_decl) = 1;
4368           FIELD_FINAL (field_decl) = 0;
4369         }
4370       
4371       /* Check if we must chain. */
4372       if (must_chain)
4373         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4374           
4375       /* If we have an initialization value tied to the field */
4376       if (init)
4377         {
4378           /* The field is declared static */
4379           if (flags & ACC_STATIC)
4380             {
4381               /* We include the field and its initialization part into
4382                  a list used to generate <clinit>. After <clinit> is
4383                  walked, field initializations will be processed and
4384                  fields initialized with known constants will be taken
4385                  out of <clinit> and have their DECL_INITIAL set
4386                  appropriately. */
4387               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4388               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4389               if (TREE_OPERAND (init, 1) 
4390                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4391                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4392             }
4393           /* A non-static field declared with an immediate initialization is
4394              to be initialized in <init>, if any.  This field is remembered
4395              to be processed at the time of the generation of <init>. */
4396           else
4397             {
4398               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4399               SET_CPC_INITIALIZER_STMT (ctxp, init);
4400             }
4401           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4402           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4403         }
4404     }
4405   lineno = saved_lineno;
4406 }
4407
4408 /* Generate finit$, using the list of initialized fields to populate
4409    its body. finit$'s parameter(s) list is adjusted to include the
4410    one(s) used to initialized the field(s) caching outer context
4411    local(s).  */
4412
4413 static tree
4414 generate_finit (class_type)
4415      tree class_type;
4416 {
4417   int count = 0;
4418   tree list = TYPE_FINIT_STMT_LIST (class_type);
4419   tree mdecl, current, parms;
4420
4421   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4422                                                   class_type, NULL_TREE, 
4423                                                   &count);
4424   CRAFTED_PARAM_LIST_FIXUP (parms);
4425   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4426                                     finit_identifier_node, parms);
4427   fix_method_argument_names (parms, mdecl);
4428   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4429                        mdecl, NULL_TREE);
4430   DECL_FUNCTION_NAP (mdecl) = count;
4431   start_artificial_method_body (mdecl);
4432
4433   for (current = list; current; current = TREE_CHAIN (current))
4434     java_method_add_stmt (mdecl, 
4435                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4436                                                 current));
4437   end_artificial_method_body (mdecl);
4438   return mdecl;
4439 }
4440
4441 /* Generate a function to run the instance initialization code. The
4442    private method is called `instinit$'. Unless we're dealing with an
4443    anonymous class, we determine whether all ctors of CLASS_TYPE
4444    declare a checked exception in their `throws' clause in order to
4445    see whether it's necessary to encapsulate the instance initializer
4446    statements in a try/catch/rethrow sequence.  */
4447
4448 static tree
4449 generate_instinit (class_type)
4450      tree class_type;
4451 {
4452   tree current;
4453   tree compound = NULL_TREE;
4454   tree parms = tree_cons (this_identifier_node,
4455                           build_pointer_type (class_type), end_params_node);
4456   tree mdecl = create_artificial_method (class_type, ACC_PRIVATE,
4457                                          void_type_node,
4458                                          instinit_identifier_node, parms);
4459
4460   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4461                        mdecl, NULL_TREE);
4462
4463   /* Gather all the statements in a compound */
4464   for (current = TYPE_II_STMT_LIST (class_type); 
4465        current; current = TREE_CHAIN (current))
4466     compound = add_stmt_to_compound (compound, NULL_TREE, current);
4467
4468   /* We need to encapsulate COMPOUND by a try/catch statement to
4469      rethrow exceptions that might occur in the instance initializer.
4470      We do that only if all ctors of CLASS_TYPE are set to catch a
4471      checked exception. This doesn't apply to anonymous classes (since
4472      they don't have declared ctors.) */
4473   if (!ANONYMOUS_CLASS_P (class_type) && 
4474       ctors_unchecked_throws_clause_p (class_type))
4475     {
4476       compound = encapsulate_with_try_catch (0, exception_type_node, compound, 
4477                                              build1 (THROW_EXPR, NULL_TREE,
4478                                                      build_wfl_node (wpv_id)));
4479       DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
4480                                                       exception_type_node);
4481     }
4482
4483   start_artificial_method_body (mdecl);
4484   java_method_add_stmt (mdecl, compound);
4485   end_artificial_method_body (mdecl);
4486
4487   return mdecl;
4488 }
4489
4490 /* FIXME */
4491 static tree
4492 build_instinit_invocation (class_type)
4493      tree class_type;
4494 {
4495   tree to_return = NULL_TREE;
4496
4497   if (TYPE_II_STMT_LIST (class_type))
4498     {
4499       tree parm = build_tree_list (NULL_TREE,
4500                                    build_wfl_node (this_identifier_node));
4501       to_return =
4502         build_method_invocation (build_wfl_node (instinit_identifier_node),
4503                                  parm);
4504     }
4505   return to_return;
4506 }
4507
4508 /* Shared accros method_declarator and method_header to remember the
4509    patch stage that was reached during the declaration of the method.
4510    A method DECL is built differently is there is no patch
4511    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4512    pending on the currently defined method.  */
4513
4514 static int patch_stage;
4515
4516 /* Check the method declaration and add the method to its current
4517    class.  If the argument list is known to contain incomplete types,
4518    the method is partially added and the registration will be resume
4519    once the method arguments resolved. If TYPE is NULL, we're dealing
4520    with a constructor.  */
4521
4522 static tree
4523 method_header (flags, type, mdecl, throws)
4524      int flags;
4525      tree type, mdecl, throws;
4526 {
4527   tree type_wfl = NULL_TREE;
4528   tree meth_name = NULL_TREE;
4529   tree current, orig_arg, this_class = NULL;
4530   tree id, meth;
4531   int saved_lineno;
4532   int constructor_ok = 0, must_chain;
4533   int count;
4534
4535   if (mdecl == error_mark_node)
4536     return error_mark_node;
4537   meth = TREE_VALUE (mdecl);
4538   id = TREE_PURPOSE (mdecl);
4539   
4540   check_modifiers_consistency (flags);
4541
4542   if (GET_CPC ())
4543     this_class = TREE_TYPE (GET_CPC ());
4544
4545   if (!this_class || this_class == error_mark_node)
4546     return NULL_TREE;
4547   
4548   /* There are some forbidden modifiers for an abstract method and its
4549      class must be abstract as well.  */
4550   if (type && (flags & ACC_ABSTRACT))
4551     {
4552       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4553       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4554       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4555       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4556       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED, id, "Synchronized");
4557       ABSTRACT_CHECK (flags, ACC_STRICT, id, "Strictfp");
4558       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4559           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4560         parse_error_context 
4561           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4562            IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())),
4563            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4564     }
4565
4566   /* Things to be checked when declaring a constructor */
4567   if (!type)
4568     {
4569       int ec = java_error_count;
4570       /* 8.6: Constructor declarations: we might be trying to define a
4571          method without specifying a return type. */
4572       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4573         parse_error_context 
4574           (id, "Invalid method declaration, return type required");
4575       /* 8.6.3: Constructor modifiers */
4576       else
4577         {
4578           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4579           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4580           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4581           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4582           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4583           JCONSTRUCTOR_CHECK (flags, ACC_STRICT, id, "strictfp");
4584         }
4585       /* If we found error here, we don't consider it's OK to tread
4586          the method definition as a constructor, for the rest of this
4587          function */
4588       if (ec == java_error_count)
4589         constructor_ok = 1;
4590     }
4591
4592   /* Method declared within the scope of an interface are implicitly
4593      abstract and public. Conflicts with other erroneously provided
4594      modifiers are checked right after. */
4595
4596   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4597     {
4598       /* If FLAGS isn't set because of a modifier, turn the
4599          corresponding modifier WFL to NULL so we issue a warning on
4600          the obsolete use of the modifier */
4601       if (!(flags & ACC_PUBLIC))
4602         MODIFIER_WFL (PUBLIC_TK) = NULL;
4603       if (!(flags & ACC_ABSTRACT))
4604         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4605       flags |= ACC_PUBLIC;
4606       flags |= ACC_ABSTRACT;
4607     }
4608
4609   /* Inner class can't declare static methods */
4610   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4611     {
4612       parse_error_context 
4613         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4614          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4615          lang_printable_name (this_class, 0));
4616     }
4617
4618   /* Modifiers context reset moved up, so abstract method declaration
4619      modifiers can be later checked.  */
4620
4621   /* Set constructor returned type to void and method name to <init>,
4622      unless we found an error identifier the constructor (in which
4623      case we retain the original name) */
4624   if (!type)
4625     {
4626       type = void_type_node;
4627       if (constructor_ok)
4628         meth_name = init_identifier_node;
4629     }
4630   else
4631     meth_name = EXPR_WFL_NODE (id);
4632
4633   /* Do the returned type resolution and registration if necessary */
4634   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4635
4636   if (meth_name)
4637     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4638   EXPR_WFL_NODE (id) = meth_name;
4639   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4640
4641   if (must_chain)
4642     {
4643       patch_stage = JDEP_METHOD_RETURN;
4644       register_incomplete_type (patch_stage, type_wfl, id, type);
4645       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4646     }
4647   else
4648     TREE_TYPE (meth) = type;
4649
4650   saved_lineno = lineno;
4651   /* When defining an abstract or interface method, the curly
4652      bracket at level 1 doesn't exist because there is no function
4653      body */
4654   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4655             EXPR_WFL_LINENO (id));
4656
4657   /* Remember the original argument list */
4658   orig_arg = TYPE_ARG_TYPES (meth);
4659
4660   if (patch_stage)              /* includes ret type and/or all args */
4661     {
4662       jdep *jdep;
4663       meth = add_method_1 (this_class, flags, meth_name, meth);
4664       /* Patch for the return type */
4665       if (patch_stage == JDEP_METHOD_RETURN)
4666         {
4667           jdep = CLASSD_LAST (ctxp->classd_list);
4668           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4669         }
4670       /* This is the stop JDEP. METH allows the function's signature
4671          to be computed. */
4672       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4673     }
4674   else
4675     meth = add_method (this_class, flags, meth_name, 
4676                        build_java_signature (meth));
4677
4678   /* Remember final parameters */
4679   MARK_FINAL_PARMS (meth, orig_arg);
4680
4681   /* Fix the method argument list so we have the argument name
4682      information */
4683   fix_method_argument_names (orig_arg, meth);
4684
4685   /* Register the parameter number and re-install the current line
4686      number */
4687   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4688   lineno = saved_lineno;
4689
4690   /* Register exception specified by the `throws' keyword for
4691      resolution and set the method decl appropriate field to the list.
4692      Note: the grammar ensures that what we get here are class
4693      types. */
4694   if (throws)
4695     {
4696       throws = nreverse (throws);
4697       for (current = throws; current; current = TREE_CHAIN (current))
4698         {
4699           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4700                                     NULL_TREE, NULL_TREE);
4701           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4702             &TREE_VALUE (current);
4703         }
4704       DECL_FUNCTION_THROWS (meth) = throws;
4705     }
4706
4707   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4708     DECL_FUNCTION_WFL (meth) = id;
4709
4710   /* Set the flag if we correctly processed a constructor */
4711   if (constructor_ok)
4712     {
4713       DECL_CONSTRUCTOR_P (meth) = 1;
4714       /* Compute and store the number of artificial parameters declared
4715          for this constructor */
4716       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4717            current = TREE_CHAIN (current))
4718         if (FIELD_LOCAL_ALIAS (current))
4719           count++;
4720       DECL_FUNCTION_NAP (meth) = count;
4721     }
4722
4723   /* Eventually set the @deprecated tag flag */
4724   CHECK_DEPRECATED (meth);
4725
4726   /* If doing xref, store column and line number information instead
4727      of the line number only. */
4728   if (flag_emit_xref)
4729     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4730
4731   return meth;
4732 }
4733
4734 static void
4735 fix_method_argument_names (orig_arg, meth)
4736     tree orig_arg, meth;
4737 {
4738   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4739   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4740     {
4741       TREE_PURPOSE (arg) = this_identifier_node;
4742       arg = TREE_CHAIN (arg);
4743     }
4744   while (orig_arg != end_params_node)
4745     {
4746       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4747       orig_arg = TREE_CHAIN (orig_arg);
4748       arg = TREE_CHAIN (arg);
4749     }
4750 }
4751
4752 /* Complete the method declaration with METHOD_BODY.  */
4753
4754 static void
4755 finish_method_declaration (method_body)
4756      tree method_body;
4757 {
4758   int flags;
4759
4760   if (!current_function_decl)
4761     return;
4762
4763   flags = get_access_flags_from_decl (current_function_decl);
4764
4765   /* 8.4.5 Method Body */
4766   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4767     {
4768       tree name = DECL_NAME (current_function_decl);
4769       parse_error_context (DECL_FUNCTION_WFL (current_function_decl), 
4770                            "%s method `%s' can't have a body defined",
4771                            (METHOD_NATIVE (current_function_decl) ?
4772                             "Native" : "Abstract"),
4773                            IDENTIFIER_POINTER (name));
4774       method_body = NULL_TREE;
4775     }
4776   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4777     {
4778       tree name = DECL_NAME (current_function_decl);
4779       parse_error_context
4780         (DECL_FUNCTION_WFL (current_function_decl), 
4781          "Non native and non abstract method `%s' must have a body defined",
4782          IDENTIFIER_POINTER (name));
4783       method_body = NULL_TREE;
4784     }
4785
4786   if (flag_emit_class_files && method_body 
4787       && TREE_CODE (method_body) == NOP_EXPR 
4788       && TREE_TYPE (current_function_decl) 
4789       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4790     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4791
4792   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4793   maybe_absorb_scoping_blocks ();
4794   /* Exit function's body */
4795   exit_block ();
4796   /* Merge last line of the function with first line, directly in the
4797      function decl. It will be used to emit correct debug info. */
4798   if (!flag_emit_xref)
4799     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4800
4801   /* Since function's argument's list are shared, reset the
4802      ARG_FINAL_P parameter that might have been set on some of this
4803      function parameters. */
4804   UNMARK_FINAL_PARMS (current_function_decl);
4805   
4806   /* So we don't have an irrelevant function declaration context for
4807      the next static block we'll see. */
4808   current_function_decl = NULL_TREE;
4809 }
4810
4811 /* Build a an error message for constructor circularity errors.  */
4812
4813 static char *
4814 constructor_circularity_msg (from, to)
4815      tree from, to;
4816 {
4817   static char string [4096];
4818   char *t = xstrdup (lang_printable_name (from, 0));
4819   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4820   free (t);
4821   return string;
4822 }
4823
4824 /* Verify a circular call to METH. Return 1 if an error is found, 0
4825    otherwise.  */
4826
4827 static GTY(()) tree vcc_list;
4828 static int
4829 verify_constructor_circularity (meth, current)
4830      tree meth, current;
4831 {
4832   tree c;
4833
4834   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4835     {
4836       if (TREE_VALUE (c) == meth)
4837         {
4838           char *t;
4839           if (vcc_list)
4840             {
4841               tree liste;
4842               vcc_list = nreverse (vcc_list);
4843               for (liste = vcc_list; liste; liste = TREE_CHAIN (liste))
4844                 {
4845                   parse_error_context 
4846                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4847                      constructor_circularity_msg
4848                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4849                   java_error_count--;
4850                 }
4851             }
4852           t = xstrdup (lang_printable_name (meth, 0));
4853           parse_error_context (TREE_PURPOSE (c), 
4854                                "%s: recursive invocation of constructor `%s'",
4855                                constructor_circularity_msg (current, meth), t);
4856           free (t);
4857           vcc_list = NULL_TREE;
4858           return 1;
4859         }
4860     }
4861   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4862     {
4863       vcc_list = tree_cons (c, current, vcc_list);
4864       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4865         return 1;
4866       vcc_list = TREE_CHAIN (vcc_list);
4867     }
4868   return 0;
4869 }
4870
4871 /* Check modifiers that can be declared but exclusively */
4872
4873 static void
4874 check_modifiers_consistency (flags)
4875      int flags;
4876 {
4877   int acc_count = 0;
4878   tree cl = NULL_TREE;
4879
4880   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4881   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4882   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4883   if (acc_count > 1)
4884     parse_error_context
4885       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4886
4887   acc_count = 0;
4888   cl = NULL_TREE;
4889   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
4890   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
4891   if (acc_count > 1)
4892     parse_error_context (cl,
4893                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4894 }
4895
4896 /* Check the methode header METH for abstract specifics features */
4897
4898 static void
4899 check_abstract_method_header (meth)
4900      tree meth;
4901 {
4902   int flags = get_access_flags_from_decl (meth);
4903
4904   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4905                               ACC_ABSTRACT, "abstract method",
4906                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4907   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4908                               ACC_PUBLIC, "abstract method",
4909                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4910
4911   check_modifiers ("Illegal modifier `%s' for interface method",
4912                   flags, INTERFACE_METHOD_MODIFIERS);
4913 }
4914
4915 /* Create a FUNCTION_TYPE node and start augmenting it with the
4916    declared function arguments. Arguments type that can't be resolved
4917    are left as they are, but the returned node is marked as containing
4918    incomplete types.  */
4919
4920 static tree
4921 method_declarator (id, list)
4922      tree id, list;
4923 {
4924   tree arg_types = NULL_TREE, current, node;
4925   tree meth = make_node (FUNCTION_TYPE);
4926   jdep *jdep;
4927
4928   patch_stage = JDEP_NO_PATCH;
4929
4930   if (GET_CPC () == error_mark_node)
4931     return error_mark_node;
4932
4933   /* If we're dealing with an inner class constructor, we hide the
4934      this$<n> decl in the name field of its parameter declaration.  We
4935      also might have to hide the outer context local alias
4936      initializers. Not done when the class is a toplevel class. */
4937   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4938       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4939     {
4940       tree aliases_list, type, thisn;
4941       /* First the aliases, linked to the regular parameters */
4942       aliases_list =
4943         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4944                                                 TREE_TYPE (GET_CPC ()),
4945                                                 NULL_TREE, NULL);
4946       list = chainon (nreverse (aliases_list), list);
4947
4948       /* Then this$<n> */
4949       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4950       thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
4951       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4952                         list);
4953     }
4954   
4955   for (current = list; current; current = TREE_CHAIN (current))
4956     {
4957       int must_chain = 0;
4958       tree wfl_name = TREE_PURPOSE (current);
4959       tree type = TREE_VALUE (current);
4960       tree name = EXPR_WFL_NODE (wfl_name);
4961       tree already, arg_node;
4962       tree type_wfl = NULL_TREE;
4963       tree real_type;
4964
4965       /* Obtain a suitable type for resolution, if necessary */
4966       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4967
4968       /* Process NAME, as it may specify extra dimension(s) for it */
4969       type = build_array_from_name (type, type_wfl, name, &name);
4970       EXPR_WFL_NODE (wfl_name) = name;
4971
4972       real_type = GET_REAL_TYPE (type);
4973       if (TREE_CODE (real_type) == RECORD_TYPE)
4974         {
4975           real_type = promote_type (real_type);
4976           if (TREE_CODE (type) == TREE_LIST)
4977             TREE_PURPOSE (type) = real_type;
4978         }
4979
4980       /* Check redefinition */
4981       for (already = arg_types; already; already = TREE_CHAIN (already))
4982         if (TREE_PURPOSE (already) == name)
4983           {
4984             parse_error_context
4985               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4986                IDENTIFIER_POINTER (name),
4987                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4988             break;
4989           }
4990
4991       /* If we've an incomplete argument type, we know there is a location
4992          to patch when the type get resolved, later.  */
4993       jdep = NULL;
4994       if (must_chain)
4995         {
4996           patch_stage = JDEP_METHOD;
4997           type = register_incomplete_type (patch_stage, 
4998                                            type_wfl, wfl_name, type);
4999           jdep = CLASSD_LAST (ctxp->classd_list);
5000           JDEP_MISC (jdep) = id;
5001         }
5002
5003       /* The argument node: a name and a (possibly) incomplete type.  */
5004       arg_node = build_tree_list (name, real_type);
5005       /* Remeber arguments declared final. */
5006       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
5007       
5008       if (jdep)
5009         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
5010       TREE_CHAIN (arg_node) = arg_types;
5011       arg_types = arg_node;
5012     }
5013   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
5014   node = build_tree_list (id, meth);
5015   return node;
5016 }
5017
5018 static int
5019 unresolved_type_p (wfl, returned)
5020      tree wfl;
5021      tree *returned;
5022      
5023 {
5024   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
5025     {
5026       if (returned)
5027         {
5028           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
5029           if (decl && current_class && (decl == TYPE_NAME (current_class)))
5030             *returned = TREE_TYPE (decl);
5031           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
5032             *returned = TREE_TYPE (GET_CPC ());
5033           else
5034             *returned = NULL_TREE;
5035         }
5036       return 1;
5037     }
5038   if (returned)
5039     *returned = wfl;
5040   return 0;
5041 }
5042
5043 /* From NAME, build a qualified identifier node using the
5044    qualification from the current package definition. */
5045
5046 static tree
5047 parser_qualified_classname (name)
5048      tree name;
5049 {
5050   tree nested_class_name;
5051
5052   if ((nested_class_name = maybe_make_nested_class_name (name)))
5053     return nested_class_name;
5054
5055   if (ctxp->package)
5056     return merge_qualified_name (ctxp->package, name);
5057   else 
5058     return name;
5059 }
5060
5061 /* Called once the type a interface extends is resolved. Returns 0 if
5062    everything is OK.  */
5063
5064 static int
5065 parser_check_super_interface (super_decl, this_decl, this_wfl)
5066      tree super_decl, this_decl, this_wfl;
5067 {
5068   tree super_type = TREE_TYPE (super_decl);
5069
5070   /* Has to be an interface */
5071   if (!CLASS_INTERFACE (super_decl))
5072     {
5073       parse_error_context 
5074         (this_wfl, "%s `%s' can't implement/extend %s `%s'",
5075          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
5076           "Interface" : "Class"),
5077          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5078          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
5079          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
5080       return 1;
5081     }
5082
5083   /* Check top-level interface access. Inner classes are subject to member 
5084      access rules (6.6.1). */
5085   if (! INNER_CLASS_P (super_type)
5086       && check_pkg_class_access (DECL_NAME (super_decl),
5087                                  lookup_cl (this_decl), true))
5088     return 1;
5089
5090   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
5091                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5092                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
5093   return 0;
5094 }
5095
5096 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
5097    0 if everthing is OK.  */
5098
5099 static int
5100 parser_check_super (super_decl, this_decl, wfl)
5101      tree super_decl, this_decl, wfl;
5102 {
5103   tree super_type = TREE_TYPE (super_decl);
5104
5105   /* SUPER should be a CLASS (neither an array nor an interface) */
5106   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
5107     {
5108       parse_error_context 
5109         (wfl, "Class `%s' can't subclass %s `%s'",
5110          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5111          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
5112          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
5113       return 1;
5114     }
5115
5116   if (CLASS_FINAL (TYPE_NAME (super_type)))
5117     {
5118       parse_error_context (wfl, "Can't subclass final classes: %s",
5119                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
5120       return 1;
5121     }
5122
5123   /* Check top-level class scope. Inner classes are subject to member access
5124      rules (6.6.1). */
5125   if (! INNER_CLASS_P (super_type)
5126       && (check_pkg_class_access (DECL_NAME (super_decl), wfl, true)))
5127     return 1;
5128   
5129   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
5130                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5131                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
5132   return 0;
5133 }
5134
5135 /* Create a new dependency list and link it (in a LIFO manner) to the
5136    CTXP list of type dependency list.  */
5137
5138 static void
5139 create_jdep_list (ctxp)
5140      struct parser_ctxt *ctxp;
5141 {
5142   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
5143   new->first = new->last = NULL;
5144   new->next = ctxp->classd_list;
5145   ctxp->classd_list = new;
5146 }
5147
5148 static jdeplist *
5149 reverse_jdep_list (ctxp)
5150      struct parser_ctxt *ctxp;
5151 {
5152   register jdeplist *prev = NULL, *current, *next;
5153   for (current = ctxp->classd_list; current; current = next)
5154     {
5155       next = current->next;
5156       current->next = prev;
5157       prev = current;
5158     }
5159   return prev;
5160 }
5161
5162 /* Create a fake pointer based on the ID stored in
5163    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
5164    registered again. */
5165
5166 static tree
5167 obtain_incomplete_type (type_name)
5168      tree type_name;
5169 {
5170   tree ptr = NULL_TREE, name;
5171
5172   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
5173     name = EXPR_WFL_NODE (type_name);
5174   else if (INCOMPLETE_TYPE_P (type_name))
5175     name = TYPE_NAME (type_name);
5176   else
5177     abort ();
5178
5179   BUILD_PTR_FROM_NAME (ptr, name);
5180   layout_type (ptr);
5181
5182   return ptr;
5183 }
5184
5185 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
5186    non NULL instead of computing a new fake type based on WFL. The new
5187    dependency is inserted in the current type dependency list, in FIFO
5188    manner.  */
5189
5190 static tree
5191 register_incomplete_type (kind, wfl, decl, ptr)
5192      int kind;
5193      tree wfl, decl, ptr;
5194 {
5195   jdep *new = (jdep *)xmalloc (sizeof (jdep));
5196
5197   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
5198     ptr = obtain_incomplete_type (wfl);
5199
5200   JDEP_KIND (new) = kind;
5201   JDEP_DECL (new) = decl;
5202   JDEP_TO_RESOLVE (new) = ptr;
5203   JDEP_WFL (new) = wfl;
5204   JDEP_CHAIN (new) = NULL;
5205   JDEP_MISC (new) = NULL_TREE;
5206   /* For some dependencies, set the enclosing class of the current
5207      class to be the enclosing context */
5208   if ((kind == JDEP_INTERFACE  || kind == JDEP_ANONYMOUS)
5209       && GET_ENCLOSING_CPC ())
5210     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
5211   else if (kind == JDEP_SUPER)
5212     JDEP_ENCLOSING (new) = (GET_ENCLOSING_CPC () ? 
5213                             TREE_VALUE (GET_ENCLOSING_CPC ()) : NULL_TREE);
5214   else
5215     JDEP_ENCLOSING (new) = GET_CPC ();
5216   JDEP_GET_PATCH (new) = (tree *)NULL;
5217
5218   JDEP_INSERT (ctxp->classd_list, new);
5219
5220   return ptr;
5221 }
5222
5223 /* This checks for circular references with innerclasses. We start
5224    from SOURCE and should never reach TARGET. Extended/implemented
5225    types in SOURCE have their enclosing context checked not to reach
5226    TARGET. When the last enclosing context of SOURCE is reached, its
5227    extended/implemented types are also checked not to reach TARGET.
5228    In case of error, WFL of the offending type is returned; NULL_TREE
5229    otherwise.  */
5230
5231 static tree
5232 check_inner_circular_reference (source, target)
5233      tree source;
5234      tree target;
5235 {
5236   tree basetype_vec = TYPE_BINFO_BASETYPES (source);
5237   tree ctx, cl;
5238   int i;
5239
5240   if (!basetype_vec)
5241     return NULL_TREE;
5242
5243   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
5244     {
5245       tree su;
5246
5247       /* We can end up with a NULL_TREE or an incomplete type here if
5248          we encountered previous type resolution errors. It's safe to
5249          simply ignore these cases.  */
5250       if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
5251         continue;
5252       su = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
5253       if (INCOMPLETE_TYPE_P (su))
5254         continue;
5255
5256       if (inherits_from_p (su, target))
5257         return lookup_cl (TYPE_NAME (su));
5258
5259       for (ctx = DECL_CONTEXT (TYPE_NAME (su)); ctx; ctx = DECL_CONTEXT (ctx))
5260         {
5261           /* An enclosing context shouldn't be TARGET */
5262           if (ctx == TYPE_NAME (target))
5263             return lookup_cl (TYPE_NAME (su));
5264
5265           /* When we reach the enclosing last context, start a check
5266              on it, with the same target */
5267           if (! DECL_CONTEXT (ctx) &&
5268               (cl = check_inner_circular_reference (TREE_TYPE (ctx), target)))
5269             return cl;
5270         }
5271     }
5272   return NULL_TREE;
5273 }
5274
5275 /* Explore TYPE's `extends' clause member(s) and return the WFL of the
5276    offending type if a circularity is detected. NULL_TREE is returned
5277    otherwise. TYPE can be an interface or a class.   */
5278
5279 static tree
5280 check_circular_reference (type)
5281      tree type;
5282 {
5283   tree basetype_vec = TYPE_BINFO_BASETYPES (type);
5284   int i;
5285
5286   if (!basetype_vec)
5287     return NULL_TREE;
5288
5289   if (! CLASS_INTERFACE (TYPE_NAME (type)))
5290     {
5291       if (inherits_from_p (CLASSTYPE_SUPER (type), type))
5292         return lookup_cl (TYPE_NAME (type));
5293       return NULL_TREE;
5294     }
5295     
5296   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
5297     {
5298       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
5299       if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node
5300           && interface_of_p (type, BINFO_TYPE (vec_elt)))
5301         return lookup_cl (TYPE_NAME (BINFO_TYPE (vec_elt)));
5302     }
5303   return NULL_TREE;
5304 }
5305
5306 void
5307 java_check_circular_reference ()
5308 {
5309   tree current;
5310   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5311     {
5312       tree type = TREE_TYPE (current);
5313       tree cl;
5314
5315       cl = check_circular_reference (type);
5316       if (! cl)
5317         cl = check_inner_circular_reference (type, type);
5318       if (cl)
5319         parse_error_context (cl, "Cyclic class inheritance%s",
5320                              (cyclic_inheritance_report ?
5321                               cyclic_inheritance_report : ""));
5322     }
5323 }
5324
5325 /* Augment the parameter list PARM with parameters crafted to
5326    initialize outer context locals aliases. Through ARTIFICIAL, a
5327    count is kept of the number of crafted parameters. MODE governs
5328    what eventually gets created: something suitable for a function
5329    creation or a function invocation, either the constructor or
5330    finit$.  */
5331
5332 static tree
5333 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
5334     int mode;
5335     tree class_type, parm;
5336     int *artificial;
5337 {
5338   tree field;
5339   tree additional_parms = NULL_TREE;
5340
5341   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5342     if (FIELD_LOCAL_ALIAS (field))
5343       {
5344         const char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5345         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5346         tree mangled_id;
5347
5348         switch (mode)
5349           {
5350           case AIPL_FUNCTION_DECLARATION:
5351             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5352                                                          &buffer [4]);
5353             purpose = build_wfl_node (mangled_id);
5354             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5355               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5356             else
5357               value = TREE_TYPE (field);
5358             break;
5359
5360           case AIPL_FUNCTION_CREATION:
5361             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (purpose,
5362                                                          &buffer [4]);
5363             value = TREE_TYPE (field);
5364             break;
5365
5366           case AIPL_FUNCTION_FINIT_INVOCATION:
5367             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5368                                                          &buffer [4]);
5369             /* Now, this is wrong. purpose should always be the NAME
5370                of something and value its matching value (decl, type,
5371                etc...) FIXME -- but there is a lot to fix. */
5372
5373             /* When invoked for this kind of operation, we already
5374                know whether a field is used or not. */
5375             purpose = TREE_TYPE (field);
5376             value = build_wfl_node (mangled_id);
5377             break;
5378
5379           case AIPL_FUNCTION_CTOR_INVOCATION:
5380             /* There are two case: the constructor invokation happends
5381                outside the local inner, in which case, locales from the outer
5382                context are directly used.
5383
5384                Otherwise, we fold to using the alias directly. */
5385             if (class_type == current_class)
5386               value = field;
5387             else
5388               {
5389                 name = get_identifier (&buffer[4]);
5390                 value = IDENTIFIER_LOCAL_VALUE (name);
5391               }
5392             break;
5393           }
5394         additional_parms = tree_cons (purpose, value, additional_parms);
5395         if (artificial)
5396           *artificial +=1;
5397       }
5398   if (additional_parms)
5399     {
5400       if (ANONYMOUS_CLASS_P (class_type) 
5401           && mode == AIPL_FUNCTION_CTOR_INVOCATION)
5402         additional_parms = nreverse (additional_parms);
5403       parm = chainon (additional_parms, parm);
5404     }
5405
5406    return parm;
5407 }
5408
5409 /* Craft a constructor for CLASS_DECL -- what we should do when none
5410    where found. ARGS is non NULL when a special signature must be
5411    enforced. This is the case for anonymous classes.  */
5412
5413 static tree
5414 craft_constructor (class_decl, args)
5415      tree class_decl, args;
5416 {
5417   tree class_type = TREE_TYPE (class_decl);
5418   tree parm = NULL_TREE;
5419   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5420                ACC_PUBLIC : 0);
5421   int i = 0, artificial = 0;
5422   tree decl, ctor_name;
5423   char buffer [80];
5424   
5425   /* The constructor name is <init> unless we're dealing with an
5426      anonymous class, in which case the name will be fixed after having
5427      be expanded. */
5428   if (ANONYMOUS_CLASS_P (class_type))
5429     ctor_name = DECL_NAME (class_decl);
5430   else
5431     ctor_name = init_identifier_node;
5432
5433   /* If we're dealing with an inner class constructor, we hide the
5434      this$<n> decl in the name field of its parameter declaration. */
5435   if (PURE_INNER_CLASS_TYPE_P (class_type))
5436     {
5437       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5438       parm = tree_cons (build_current_thisn (class_type),
5439                         build_pointer_type (type), parm);
5440
5441       /* Some more arguments to be hidden here. The values of the local
5442          variables of the outer context that the inner class needs to see. */
5443       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5444                                                      class_type, parm, 
5445                                                      &artificial);
5446     }
5447
5448   /* Then if there are any args to be enforced, enforce them now */
5449   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5450     {
5451       sprintf (buffer, "parm%d", i++);
5452       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5453     }
5454
5455   CRAFTED_PARAM_LIST_FIXUP (parm);
5456   decl = create_artificial_method (class_type, flags, void_type_node, 
5457                                    ctor_name, parm);
5458   fix_method_argument_names (parm, decl);
5459   /* Now, mark the artificial parameters. */
5460   DECL_FUNCTION_NAP (decl) = artificial;
5461   DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
5462   return decl;
5463 }
5464
5465
5466 /* Fix the constructors. This will be called right after circular
5467    references have been checked. It is necessary to fix constructors
5468    early even if no code generation will take place for that class:
5469    some generated constructor might be required by the class whose
5470    compilation triggered this one to be simply loaded.  */
5471
5472 void
5473 java_fix_constructors ()
5474 {
5475   tree current;
5476
5477   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5478     {
5479       tree class_type = TREE_TYPE (current);
5480       int saw_ctor = 0;
5481       tree decl;
5482
5483       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5484         continue;
5485
5486       current_class = class_type;
5487       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5488         {
5489           if (DECL_CONSTRUCTOR_P (decl))
5490             {
5491               fix_constructors (decl);
5492               saw_ctor = 1;
5493             }
5494         }
5495
5496       /* Anonymous class constructor can't be generated that early. */
5497       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5498         craft_constructor (current, NULL_TREE);
5499     }
5500 }
5501
5502 /* safe_layout_class just makes sure that we can load a class without
5503    disrupting the current_class, input_file, lineno, etc, information
5504    about the class processed currently.  */
5505
5506 void
5507 safe_layout_class (class)
5508      tree class;
5509 {
5510   tree save_current_class = current_class;
5511   const char *save_input_filename = input_filename;
5512   int save_lineno = lineno;
5513
5514   layout_class (class);
5515
5516   current_class = save_current_class;
5517   input_filename = save_input_filename;
5518   lineno = save_lineno;
5519 }
5520
5521 static tree
5522 jdep_resolve_class (dep)
5523      jdep *dep;
5524 {
5525   tree decl;
5526
5527   if (JDEP_RESOLVED_P (dep))
5528     decl = JDEP_RESOLVED_DECL (dep);
5529   else
5530     {
5531       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5532                             JDEP_DECL (dep), JDEP_WFL (dep));
5533       JDEP_RESOLVED (dep, decl);
5534     }
5535     
5536   if (!decl)
5537     complete_class_report_errors (dep);
5538   else if (PURE_INNER_CLASS_DECL_P (decl))
5539     {
5540       tree inner = TREE_TYPE (decl);
5541       if (! CLASS_LOADED_P (inner))
5542         {
5543           safe_layout_class (inner);
5544           if (TYPE_SIZE (inner) == error_mark_node)
5545             TYPE_SIZE (inner) = NULL_TREE;
5546         }
5547       check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
5548     }
5549   return decl;
5550 }
5551
5552 /* Complete unsatisfied class declaration and their dependencies */
5553
5554 void
5555 java_complete_class ()
5556 {
5557   tree cclass;
5558   jdeplist *cclassd;
5559   int error_found;
5560   tree type;
5561
5562   /* Process imports */
5563   process_imports ();
5564
5565   /* Rever things so we have the right order */
5566   ctxp->class_list = nreverse (ctxp->class_list);
5567   ctxp->classd_list = reverse_jdep_list (ctxp);
5568
5569   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5570        cclass && cclassd; 
5571        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5572     {
5573       jdep *dep;
5574
5575       /* We keep the compilation unit imports in the class so that
5576          they can be used later to resolve type dependencies that
5577          aren't necessary to solve now. */
5578       TYPE_IMPORT_LIST (TREE_TYPE (cclass)) = ctxp->import_list;
5579       TYPE_IMPORT_DEMAND_LIST (TREE_TYPE (cclass)) = ctxp->import_demand_list;
5580
5581       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5582         {
5583           tree decl;
5584           if (!(decl = jdep_resolve_class (dep)))
5585             continue;
5586
5587           /* Now it's time to patch */
5588           switch (JDEP_KIND (dep))
5589             {
5590             case JDEP_SUPER:
5591               /* Simply patch super */
5592               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5593                 continue;
5594               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5595                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5596               break;
5597
5598             case JDEP_FIELD:
5599               {
5600                 /* We do part of the job done in add_field */
5601                 tree field_decl = JDEP_DECL (dep);
5602                 tree field_type = TREE_TYPE (decl);
5603                 if (TREE_CODE (field_type) == RECORD_TYPE)
5604                   field_type = promote_type (field_type);
5605                 TREE_TYPE (field_decl) = field_type;
5606                 DECL_ALIGN (field_decl) = 0;
5607                 DECL_USER_ALIGN (field_decl) = 0;
5608                 layout_decl (field_decl, 0);
5609                 SOURCE_FRONTEND_DEBUG 
5610                   (("Completed field/var decl `%s' with `%s'",
5611                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5612                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5613                 break;
5614               }
5615             case JDEP_METHOD:   /* We start patching a method */
5616             case JDEP_METHOD_RETURN:
5617               error_found = 0;
5618               while (1)
5619                 {
5620                   if (decl)
5621                     {
5622                       type = TREE_TYPE(decl);
5623                       if (TREE_CODE (type) == RECORD_TYPE)
5624                         type = promote_type (type);
5625                       JDEP_APPLY_PATCH (dep, type);
5626                       SOURCE_FRONTEND_DEBUG 
5627                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5628                            "Completing fct `%s' with ret type `%s'":
5629                            "Completing arg `%s' with type `%s'"),
5630                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5631                                               (JDEP_DECL_WFL (dep))),
5632                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5633                     }
5634                   else
5635                     error_found = 1;
5636                   dep = JDEP_CHAIN (dep);
5637                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5638                     break;
5639                   else
5640                     decl = jdep_resolve_class (dep);
5641                 }
5642               if (!error_found)
5643                 {
5644                   tree mdecl = JDEP_DECL (dep), signature;
5645                   /* Recompute and reset the signature, check first that
5646                      all types are now defined. If they're not,
5647                      don't build the signature. */
5648                   if (check_method_types_complete (mdecl))
5649                     {
5650                       signature = build_java_signature (TREE_TYPE (mdecl));
5651                       set_java_signature (TREE_TYPE (mdecl), signature);
5652                     }
5653                 }
5654               else
5655                 continue;
5656               break;
5657
5658             case JDEP_INTERFACE:
5659               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5660                                                 JDEP_WFL (dep)))
5661                 continue;
5662               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5663               break;
5664
5665             case JDEP_PARM:
5666             case JDEP_VARIABLE:
5667               type = TREE_TYPE(decl);
5668               if (TREE_CODE (type) == RECORD_TYPE)
5669                 type = promote_type (type);
5670               JDEP_APPLY_PATCH (dep, type);
5671               break;
5672
5673             case JDEP_TYPE:
5674               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5675               SOURCE_FRONTEND_DEBUG 
5676                 (("Completing a random type dependency on a '%s' node",
5677                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5678               break;
5679
5680             case JDEP_EXCEPTION:
5681               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5682               SOURCE_FRONTEND_DEBUG 
5683                 (("Completing `%s' `throws' argument node",
5684                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5685               break;
5686
5687             case JDEP_ANONYMOUS:
5688               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5689               break;
5690
5691             default:
5692               abort ();
5693             }
5694         }
5695     }
5696   return;
5697 }
5698
5699 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5700    array.  */
5701
5702 static tree
5703 resolve_class (enclosing, class_type, decl, cl)
5704      tree enclosing, class_type, decl, cl;
5705 {
5706   tree tname = TYPE_NAME (class_type);
5707   tree resolved_type = TREE_TYPE (class_type);
5708   int array_dims = 0;
5709   tree resolved_type_decl;
5710   
5711   if (resolved_type != NULL_TREE)
5712     {
5713       tree resolved_type_decl = TYPE_NAME (resolved_type);
5714       if (resolved_type_decl == NULL_TREE
5715           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5716         {
5717           resolved_type_decl = build_decl (TYPE_DECL,
5718                                            TYPE_NAME (class_type),
5719                                            resolved_type);
5720         }
5721       return resolved_type_decl;
5722     }
5723
5724   /* 1- Check to see if we have an array. If true, find what we really
5725      want to resolve  */
5726   if ((array_dims = build_type_name_from_array_name (tname,
5727                                                      &TYPE_NAME (class_type))))
5728     WFL_STRIP_BRACKET (cl, cl);
5729
5730   /* 2- Resolve the bare type */
5731   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5732                                                decl, cl)))
5733     return NULL_TREE;
5734   resolved_type = TREE_TYPE (resolved_type_decl);
5735
5736   /* 3- If we have and array, reconstruct the array down to its nesting */
5737   if (array_dims)
5738     {
5739       for (; array_dims; array_dims--)
5740         resolved_type = build_java_array_type (resolved_type, -1);
5741       resolved_type_decl = TYPE_NAME (resolved_type);
5742     }
5743   TREE_TYPE (class_type) = resolved_type;
5744   return resolved_type_decl;
5745 }
5746
5747 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5748    are used to report error messages. Do not try to replace TYPE_NAME
5749    (class_type) by a variable, since it is changed by
5750    find_in_imports{_on_demand} and (but it doesn't really matter)
5751    qualify_and_find.  */
5752
5753 tree
5754 do_resolve_class (enclosing, class_type, decl, cl)
5755      tree enclosing, class_type, decl, cl;
5756 {
5757   tree new_class_decl = NULL_TREE, super = NULL_TREE;
5758   tree saved_enclosing_type = enclosing ? TREE_TYPE (enclosing) : NULL_TREE;
5759   tree decl_result;
5760   htab_t circularity_hash;
5761
5762   /* This hash table is used to register the classes we're going
5763      through when searching the current class as an inner class, in
5764      order to detect circular references. Remember to free it before
5765      returning the section 0- of this function. */
5766   circularity_hash = htab_create (20, htab_hash_pointer, htab_eq_pointer, 
5767                                   NULL);
5768
5769   /* 0- Search in the current class as an inner class.
5770      Maybe some code here should be added to load the class or
5771      something, at least if the class isn't an inner class and ended
5772      being loaded from class file. FIXME. */
5773   while (enclosing)
5774     {
5775       new_class_decl = resolve_inner_class (circularity_hash, cl, &enclosing,
5776                                             &super, class_type);
5777       if (new_class_decl)
5778         break;
5779
5780       /* If we haven't found anything because SUPER reached Object and
5781          ENCLOSING happens to be an innerclass, try the enclosing context. */
5782       if ((!super || super == object_type_node) && 
5783           enclosing && INNER_CLASS_DECL_P (enclosing))
5784         enclosing = DECL_CONTEXT (enclosing);
5785       else
5786         enclosing = NULL_TREE;
5787     }
5788
5789   htab_delete (circularity_hash);
5790
5791   if (new_class_decl)
5792     return new_class_decl;
5793
5794   /* 1- Check for the type in single imports. This will change
5795      TYPE_NAME() if something relevant is found */
5796   find_in_imports (saved_enclosing_type, class_type);
5797
5798   /* 2- And check for the type in the current compilation unit */
5799   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5800     {
5801       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5802           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5803         load_class (TYPE_NAME (class_type), 0);
5804       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5805     }
5806
5807   /* 3- Search according to the current package definition */
5808   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5809     {
5810       if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
5811                                              TYPE_NAME (class_type))))
5812         return new_class_decl;
5813     }
5814
5815   /* 4- Check the import on demands. Don't allow bar.baz to be
5816      imported from foo.* */
5817   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5818     if (find_in_imports_on_demand (saved_enclosing_type, class_type))
5819       return NULL_TREE;
5820
5821   /* If found in find_in_imports_on_demant, the type has already been
5822      loaded. */
5823   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5824     return new_class_decl;
5825
5826   /* 5- Try with a name qualified with the package name we've seen so far */
5827   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5828     {
5829       tree package;
5830
5831       /* If there is a current package (ctxp->package), it's the first
5832          element of package_list and we can skip it. */
5833       for (package = (ctxp->package ? 
5834                       TREE_CHAIN (package_list) : package_list);
5835            package; package = TREE_CHAIN (package))
5836         if ((new_class_decl = qualify_and_find (class_type,
5837                                                TREE_PURPOSE (package), 
5838                                                TYPE_NAME (class_type))))
5839           return new_class_decl;
5840     }
5841
5842   /* 5- Check an other compilation unit that bears the name of type */
5843   load_class (TYPE_NAME (class_type), 0);
5844   
5845   if (!cl)
5846     cl = lookup_cl (decl);
5847   
5848   /* If we don't have a value for CL, then we're being called recursively. 
5849      We can't check package access just yet, but it will be taken care of
5850      by the caller. */
5851   if (cl)
5852     {
5853       if (check_pkg_class_access (TYPE_NAME (class_type), cl, true))
5854         return NULL_TREE;
5855     }
5856
5857   /* 6- Last call for a resolution */
5858   decl_result = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5859
5860   /* The final lookup might have registered a.b.c into a.b$c If we
5861      failed at the first lookup, progressively change the name if
5862      applicable and use the matching DECL instead. */
5863   if (!decl_result && QUALIFIED_P (TYPE_NAME (class_type)))
5864     {
5865       char *separator;
5866       tree name = TYPE_NAME (class_type);
5867       char *namebuffer = alloca (IDENTIFIER_LENGTH (name) + 1);
5868
5869       strcpy (namebuffer, IDENTIFIER_POINTER (name));
5870
5871       do {
5872
5873        /* Reach the last '.', and if applicable, replace it by a `$' and
5874           see if this exists as a type. */
5875        if ((separator = strrchr (namebuffer, '.')))
5876          {
5877            *separator = '$';
5878            name = get_identifier (namebuffer);
5879            decl_result = IDENTIFIER_CLASS_VALUE (name);
5880          }
5881       } while (!decl_result && separator);
5882     }
5883   return decl_result;
5884 }
5885
5886 static tree
5887 qualify_and_find (class_type, package, name)
5888      tree class_type, package, name;
5889 {
5890   tree new_qualified = merge_qualified_name (package, name);
5891   tree new_class_decl;
5892
5893   if (!IDENTIFIER_CLASS_VALUE (new_qualified))
5894     load_class (new_qualified, 0);
5895   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
5896     {
5897       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5898           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5899         load_class (new_qualified, 0);
5900       TYPE_NAME (class_type) = new_qualified;
5901       return IDENTIFIER_CLASS_VALUE (new_qualified);
5902     }
5903   return NULL_TREE;
5904 }
5905
5906 /* Resolve NAME and lay it out (if not done and if not the current
5907    parsed class). Return a decl node. This function is meant to be
5908    called when type resolution is necessary during the walk pass.  */
5909
5910 static tree
5911 resolve_and_layout (something, cl)
5912      tree something;
5913      tree cl;
5914 {
5915   tree decl, decl_type;
5916
5917   /* Don't do that on the current class */
5918   if (something == current_class)
5919     return TYPE_NAME (current_class);
5920
5921   /* Don't do anything for void and other primitive types */
5922   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5923     return NULL_TREE;
5924
5925   /* Pointer types can be reall pointer types or fake pointers. When
5926      finding a real pointer, recheck for primitive types */
5927   if (TREE_CODE (something) == POINTER_TYPE)
5928     {
5929       if (TREE_TYPE (something))
5930         {
5931           something = TREE_TYPE (something);
5932           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5933             return NULL_TREE;
5934         }
5935       else
5936         something = TYPE_NAME (something);
5937     }
5938
5939   /* Don't do anything for arrays of primitive types */
5940   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5941       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5942     return NULL_TREE;
5943
5944   /* Something might be a WFL */
5945   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5946     something = EXPR_WFL_NODE (something);
5947
5948   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5949      TYPE_DECL or a real TYPE */
5950   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5951     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5952             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5953
5954   if (!(decl = resolve_no_layout (something, cl)))
5955     return NULL_TREE;
5956
5957   /* Resolve and layout if necessary */
5958   decl_type = TREE_TYPE (decl);
5959   layout_class_methods (decl_type);
5960   /* Check methods */
5961   if (CLASS_FROM_SOURCE_P (decl_type))
5962     java_check_methods (decl);
5963   /* Layout the type if necessary */ 
5964   if (decl_type != current_class && !CLASS_LOADED_P (decl_type))
5965     safe_layout_class (decl_type);
5966
5967   return decl;
5968 }
5969
5970 /* Resolve a class, returns its decl but doesn't perform any
5971    layout. The current parsing context is saved and restored */
5972
5973 static tree
5974 resolve_no_layout (name, cl)
5975      tree name, cl;
5976 {
5977   tree ptr, decl;
5978   BUILD_PTR_FROM_NAME (ptr, name);
5979   java_parser_context_save_global ();
5980   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5981   java_parser_context_restore_global ();
5982   
5983   return decl;
5984 }
5985
5986 /* Called when reporting errors. Skip the '[]'s in a complex array
5987    type description that failed to be resolved. purify_type_name can't
5988    use an identifier tree.  */
5989
5990 static const char *
5991 purify_type_name (name)
5992      const char *name;
5993 {
5994   int len = strlen (name);
5995   int bracket_found;
5996
5997   STRING_STRIP_BRACKETS (name, len, bracket_found);
5998   if (bracket_found)
5999     {
6000       char *stripped_name = xmemdup (name, len, len+1);
6001       stripped_name [len] = '\0';
6002       return stripped_name;
6003     }
6004   return name;
6005 }
6006
6007 /* The type CURRENT refers to can't be found. We print error messages.  */
6008
6009 static void
6010 complete_class_report_errors (dep)
6011      jdep *dep;
6012 {
6013   const char *name;
6014
6015   if (!JDEP_WFL (dep))
6016     return;
6017
6018   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
6019   switch (JDEP_KIND (dep))
6020     {
6021     case JDEP_SUPER:
6022       parse_error_context  
6023         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
6024          purify_type_name (name),
6025          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6026       break;
6027     case JDEP_FIELD:
6028       parse_error_context
6029         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
6030          purify_type_name (name),
6031          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6032       break;
6033     case JDEP_METHOD:           /* Covers arguments */
6034       parse_error_context
6035         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
6036          purify_type_name (name),
6037          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
6038          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
6039       break;
6040     case JDEP_METHOD_RETURN:    /* Covers return type */
6041       parse_error_context
6042         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
6043          purify_type_name (name),
6044          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
6045       break;
6046     case JDEP_INTERFACE:
6047       parse_error_context
6048         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
6049          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
6050          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
6051          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6052       break;
6053     case JDEP_VARIABLE:
6054       parse_error_context
6055         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
6056          purify_type_name (IDENTIFIER_POINTER 
6057                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
6058          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6059       break;
6060     case JDEP_EXCEPTION:        /* As specified by `throws' */
6061       parse_error_context 
6062           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
6063          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
6064       break;
6065     default:
6066       /* Fix for -Wall. Just break doing nothing. The error will be
6067          caught later */
6068       break;
6069     }
6070 }
6071
6072 /* Return a static string containing the DECL prototype string. If
6073    DECL is a constructor, use the class name instead of the form
6074    <init> */
6075
6076 static const char *
6077 get_printable_method_name (decl)
6078      tree decl;
6079 {
6080   const char *to_return;
6081   tree name = NULL_TREE;
6082
6083   if (DECL_CONSTRUCTOR_P (decl))
6084     {
6085       name = DECL_NAME (decl);
6086       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
6087     }
6088       
6089   to_return = lang_printable_name (decl, 0);
6090   if (DECL_CONSTRUCTOR_P (decl))
6091     DECL_NAME (decl) = name;
6092   
6093   return to_return;
6094 }
6095
6096 /* Track method being redefined inside the same class. As a side
6097    effect, set DECL_NAME to an IDENTIFIER (prior entering this
6098    function it's a FWL, so we can track errors more accurately.)  */
6099
6100 static int
6101 check_method_redefinition (class, method)
6102      tree class, method;
6103 {
6104   tree redef, sig;
6105
6106   /* There's no need to verify <clinit> and finit$ and instinit$ */
6107   if (DECL_CLINIT_P (method)
6108       || DECL_FINIT_P (method) || DECL_INSTINIT_P (method))
6109     return 0;
6110
6111   sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
6112   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
6113     {
6114       if (redef == method)
6115         break;
6116       if (DECL_NAME (redef) == DECL_NAME (method)
6117           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef))
6118           && !DECL_ARTIFICIAL (method))
6119         {
6120           parse_error_context 
6121             (DECL_FUNCTION_WFL (method), "Duplicate %s declaration `%s'",
6122              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
6123              get_printable_method_name (redef));
6124           return 1;
6125         }
6126     }
6127   return 0;
6128 }
6129
6130 /* Return 1 if check went ok, 0 otherwise.  */
6131 static int
6132 check_abstract_method_definitions (do_interface, class_decl, type)
6133      int do_interface;
6134      tree class_decl, type;
6135 {
6136   tree class = TREE_TYPE (class_decl);
6137   tree method, end_type;
6138   int ok = 1;
6139
6140   end_type = (do_interface ? object_type_node : type);
6141   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
6142     {
6143       tree other_super, other_method, method_sig, method_name;
6144       int found = 0;
6145       int end_type_reached = 0;
6146       
6147       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
6148         continue;
6149       
6150       /* Now verify that somewhere in between TYPE and CLASS,
6151          abstract method METHOD gets a non abstract definition
6152          that is inherited by CLASS.  */
6153       
6154       method_sig = build_java_signature (TREE_TYPE (method));
6155       method_name = DECL_NAME (method);
6156       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
6157         method_name = EXPR_WFL_NODE (method_name);
6158
6159       other_super = class;
6160       do {
6161         if (other_super == end_type)
6162           end_type_reached = 1;
6163         
6164         /* Method search */
6165         for (other_method = TYPE_METHODS (other_super); other_method;
6166             other_method = TREE_CHAIN (other_method))
6167           {
6168             tree s = build_java_signature (TREE_TYPE (other_method));
6169             tree other_name = DECL_NAME (other_method);
6170             
6171             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
6172               other_name = EXPR_WFL_NODE (other_name);
6173             if (!DECL_CLINIT_P (other_method)
6174                 && !DECL_CONSTRUCTOR_P (other_method)
6175                 && method_name == other_name
6176                 && method_sig == s
6177                 && !METHOD_ABSTRACT (other_method))
6178              {
6179                found = 1;
6180                break;
6181              }
6182           }
6183         other_super = CLASSTYPE_SUPER (other_super);
6184       } while (!end_type_reached);
6185  
6186       /* Report that abstract METHOD didn't find an implementation
6187          that CLASS can use. */
6188       if (!found)
6189         {
6190           char *t = xstrdup (lang_printable_name 
6191                             (TREE_TYPE (TREE_TYPE (method)), 0));
6192           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
6193           
6194           parse_error_context 
6195             (lookup_cl (class_decl),
6196              "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",
6197              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6198              t, lang_printable_name (method, 0), 
6199              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
6200               "interface" : "class"),
6201              IDENTIFIER_POINTER (ccn),
6202              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
6203              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
6204           ok = 0;
6205           free (t);
6206         }
6207     }
6208
6209   if (ok && do_interface)
6210     {
6211       /* Check for implemented interfaces. */
6212       int i;
6213       tree vector = TYPE_BINFO_BASETYPES (type);
6214       for (i = 1; ok && vector && i < TREE_VEC_LENGTH (vector); i++)
6215         {
6216           tree super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
6217           ok = check_abstract_method_definitions (1, class_decl, super);
6218         }
6219     }
6220
6221   return ok;
6222 }
6223
6224 /* Check that CLASS_DECL somehow implements all inherited abstract
6225    methods.  */
6226
6227 static void
6228 java_check_abstract_method_definitions (class_decl)
6229      tree class_decl;
6230 {
6231   tree class = TREE_TYPE (class_decl);
6232   tree super, vector;
6233   int i;
6234
6235   if (CLASS_ABSTRACT (class_decl))
6236     return;
6237
6238   /* Check for inherited types */
6239   super = class;
6240   do {
6241     super = CLASSTYPE_SUPER (super);
6242     check_abstract_method_definitions (0, class_decl, super);
6243   } while (super != object_type_node);
6244
6245   /* Check for implemented interfaces. */
6246   vector = TYPE_BINFO_BASETYPES (class);
6247   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
6248     {
6249       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
6250       check_abstract_method_definitions (1, class_decl, super);
6251     }
6252 }
6253
6254 /* Check all the types method DECL uses and return 1 if all of them
6255    are now complete, 0 otherwise. This is used to check whether its
6256    safe to build a method signature or not.  */
6257
6258 static int
6259 check_method_types_complete (decl)
6260      tree decl;
6261 {
6262   tree type = TREE_TYPE (decl);
6263   tree args;
6264
6265   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
6266     return 0;
6267   
6268   args = TYPE_ARG_TYPES (type);
6269   if (TREE_CODE (type) == METHOD_TYPE)
6270     args = TREE_CHAIN (args);
6271   for (; args != end_params_node; args = TREE_CHAIN (args))
6272     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
6273       return 0;
6274
6275   return 1;
6276 }
6277
6278 /* Visible interface to check methods contained in CLASS_DECL */
6279
6280 void
6281 java_check_methods (class_decl)
6282      tree class_decl;
6283 {
6284   if (CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)))
6285     return;
6286
6287   if (CLASS_INTERFACE (class_decl))
6288     java_check_abstract_methods (class_decl);
6289   else
6290     java_check_regular_methods (class_decl);
6291   
6292   CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)) = 1;
6293 }
6294
6295 /* Check all the methods of CLASS_DECL. Methods are first completed
6296    then checked according to regular method existence rules.  If no
6297    constructor for CLASS_DECL were encountered, then build its
6298    declaration.  */
6299
6300 static void
6301 java_check_regular_methods (class_decl)
6302      tree class_decl;
6303 {
6304   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
6305   tree method;
6306   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
6307   tree found = NULL_TREE;
6308   tree mthrows;
6309
6310   /* It is not necessary to check methods defined in java.lang.Object */
6311   if (class == object_type_node)
6312     return;
6313
6314   if (!TYPE_NVIRTUALS (class))
6315     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6316
6317   /* Should take interfaces into account. FIXME */
6318   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
6319     {
6320       tree sig;
6321       tree method_wfl = DECL_FUNCTION_WFL (method);
6322       int aflags;
6323
6324       /* Check for redefinitions */
6325       if (check_method_redefinition (class, method))
6326         continue;
6327
6328       /* If we see one constructor a mark so we don't generate the
6329          default one. Also skip other verifications: constructors
6330          can't be inherited hence hiden or overriden */
6331      if (DECL_CONSTRUCTOR_P (method))
6332        {
6333          saw_constructor = 1;
6334          continue;
6335        }
6336
6337       /* We verify things thrown by the method. They must inherits from
6338          java.lang.Throwable */
6339       for (mthrows = DECL_FUNCTION_THROWS (method);
6340            mthrows; mthrows = TREE_CHAIN (mthrows))
6341         {
6342           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
6343             parse_error_context 
6344               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
6345                IDENTIFIER_POINTER 
6346                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
6347         }
6348
6349       sig = build_java_argument_signature (TREE_TYPE (method));
6350       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
6351
6352       /* Inner class can't declare static methods */
6353       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
6354         {
6355           char *t = xstrdup (lang_printable_name (class, 0));
6356           parse_error_context 
6357             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
6358              lang_printable_name (method, 0), t);
6359           free (t);
6360         }
6361
6362       /* Nothing overrides or it's a private method. */
6363       if (!found)
6364         continue;
6365       if (METHOD_PRIVATE (found))
6366         {
6367           found = NULL_TREE;
6368           continue;
6369         }
6370
6371       /* If `found' is declared in an interface, make sure the
6372          modifier matches. */
6373       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6374           && clinit_identifier_node != DECL_NAME (found)
6375           && !METHOD_PUBLIC (method))
6376         {
6377           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6378           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6379                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6380                                lang_printable_name (method, 0),
6381                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6382         }
6383
6384       /* Can't override a method with the same name and different return
6385          types. */
6386       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6387         {
6388           char *t = xstrdup 
6389             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6390           parse_error_context 
6391             (method_wfl,
6392              "Method `%s' was defined with return type `%s' in class `%s'", 
6393              lang_printable_name (found, 0), t,
6394              IDENTIFIER_POINTER 
6395                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6396           free (t);
6397         }
6398
6399       aflags = get_access_flags_from_decl (found);
6400
6401       /* Can't override final. Can't override static. */
6402       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6403         {
6404           /* Static *can* override static */
6405           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6406             continue;
6407           parse_error_context 
6408             (method_wfl,
6409              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6410              (METHOD_FINAL (found) ? "Final" : "Static"),
6411              lang_printable_name (found, 0),
6412              (METHOD_FINAL (found) ? "final" : "static"),
6413              IDENTIFIER_POINTER
6414                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6415           continue;
6416         }
6417
6418       /* Static method can't override instance method. */
6419       if (METHOD_STATIC (method))
6420         {
6421           parse_error_context 
6422             (method_wfl,
6423              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6424              lang_printable_name (found, 0),
6425              IDENTIFIER_POINTER
6426                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6427           continue;
6428         }
6429
6430       /* - Overriding/hiding public must be public
6431          - Overriding/hiding protected must be protected or public
6432          - If the overriden or hidden method has default (package)
6433            access, then the overriding or hiding method must not be
6434            private; otherwise, a compile-time error occurs.  If
6435            `found' belongs to an interface, things have been already
6436            taken care of.  */
6437       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6438           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6439               || (METHOD_PROTECTED (found) 
6440                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6441               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6442                   && METHOD_PRIVATE (method))))
6443         {
6444           parse_error_context 
6445             (method_wfl,
6446              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6447              (METHOD_PUBLIC (method) ? "public" : 
6448               (METHOD_PRIVATE (method) ? "private" : "protected")),
6449              IDENTIFIER_POINTER (DECL_NAME 
6450                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6451           continue;
6452         }
6453
6454       /* Overriding methods must have compatible `throws' clauses on checked
6455          exceptions, if any */
6456       check_throws_clauses (method, method_wfl, found);
6457
6458       /* Inheriting multiple methods with the same signature. FIXME */
6459     }
6460   
6461   if (!TYPE_NVIRTUALS (class))
6462     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6463
6464   /* Search for inherited abstract method not yet implemented in this
6465      class.  */
6466   java_check_abstract_method_definitions (class_decl);
6467
6468   if (!saw_constructor)
6469     abort ();
6470 }
6471
6472 /* Return a non zero value if the `throws' clause of METHOD (if any)
6473    is incompatible with the `throws' clause of FOUND (if any).  */
6474
6475 static void
6476 check_throws_clauses (method, method_wfl, found)
6477      tree method, method_wfl, found;
6478 {
6479   tree mthrows, fthrows;
6480
6481   /* Can't check these things with class loaded from bytecode. FIXME */
6482   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6483     return;
6484
6485   for (mthrows = DECL_FUNCTION_THROWS (method);
6486        mthrows; mthrows = TREE_CHAIN (mthrows))
6487     {
6488       /* We don't verify unchecked expressions */
6489       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6490         continue;
6491       /* Checked expression must be compatible */
6492       for (fthrows = DECL_FUNCTION_THROWS (found); 
6493            fthrows; fthrows = TREE_CHAIN (fthrows))
6494         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6495           break;
6496       if (!fthrows)
6497         {
6498           parse_error_context 
6499             (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'",
6500              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6501              lang_printable_name (found, 0),
6502              IDENTIFIER_POINTER 
6503                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6504         }
6505     }
6506 }
6507
6508 /* Check abstract method of interface INTERFACE */
6509
6510 static void
6511 java_check_abstract_methods (interface_decl)
6512      tree interface_decl;
6513 {
6514   int i, n;
6515   tree method, basetype_vec, found;
6516   tree interface = TREE_TYPE (interface_decl);
6517
6518   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6519     {
6520       /* 2- Check for double definition inside the defining interface */
6521       if (check_method_redefinition (interface, method))
6522         continue;
6523
6524       /* 3- Overriding is OK as far as we preserve the return type and
6525          the thrown exceptions (FIXME) */
6526       found = lookup_java_interface_method2 (interface, method);
6527       if (found)
6528         {
6529           char *t;
6530           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6531           parse_error_context 
6532             (DECL_FUNCTION_WFL (found),
6533              "Method `%s' was defined with return type `%s' in class `%s'",
6534              lang_printable_name (found, 0), t,
6535              IDENTIFIER_POINTER 
6536                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6537           free (t);
6538           continue;
6539         }
6540     }
6541
6542   /* 4- Inherited methods can't differ by their returned types */
6543   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6544     return;
6545   n = TREE_VEC_LENGTH (basetype_vec);
6546   for (i = 0; i < n; i++)
6547     {
6548       tree sub_interface_method, sub_interface;
6549       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6550       if (!vec_elt)
6551         continue;
6552       sub_interface = BINFO_TYPE (vec_elt);
6553       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6554            sub_interface_method;
6555            sub_interface_method = TREE_CHAIN (sub_interface_method))
6556         {
6557           found = lookup_java_interface_method2 (interface, 
6558                                                  sub_interface_method);
6559           if (found && (found != sub_interface_method))
6560             {
6561               parse_error_context 
6562                 (lookup_cl (sub_interface_method),
6563                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6564                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6565                  lang_printable_name (found, 0),
6566                  IDENTIFIER_POINTER 
6567                    (DECL_NAME (TYPE_NAME 
6568                                (DECL_CONTEXT (sub_interface_method)))),
6569                  IDENTIFIER_POINTER 
6570                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6571             }
6572         }
6573     }
6574 }
6575
6576 /* Lookup methods in interfaces using their name and partial
6577    signature. Return a matching method only if their types differ.  */
6578
6579 static tree
6580 lookup_java_interface_method2 (class, method_decl)
6581      tree class, method_decl;
6582 {
6583   int i, n;
6584   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6585
6586   if (!basetype_vec)
6587     return NULL_TREE;
6588
6589   n = TREE_VEC_LENGTH (basetype_vec);
6590   for (i = 0; i < n; i++)
6591     {
6592       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6593       if ((BINFO_TYPE (vec_elt) != object_type_node)
6594           && (to_return = 
6595               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6596         return to_return;
6597     }
6598   for (i = 0; i < n; i++)
6599     {
6600       to_return = lookup_java_interface_method2 
6601         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6602       if (to_return)
6603         return to_return;
6604     }
6605
6606   return NULL_TREE;
6607 }
6608
6609 /* Lookup method using their name and partial signature. Return a
6610    matching method only if their types differ.  */
6611
6612 static tree
6613 lookup_java_method2 (clas, method_decl, do_interface)
6614      tree clas, method_decl;
6615      int do_interface;
6616 {
6617   tree method, method_signature, method_name, method_type, name;
6618
6619   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6620   name = DECL_NAME (method_decl);
6621   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6622                  EXPR_WFL_NODE (name) : name);
6623   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6624
6625   while (clas != NULL_TREE)
6626     {
6627       for (method = TYPE_METHODS (clas);
6628            method != NULL_TREE;  method = TREE_CHAIN (method))
6629         {
6630           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6631           tree name = DECL_NAME (method);
6632           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6633                EXPR_WFL_NODE (name) : name) == method_name
6634               && method_sig == method_signature 
6635               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6636             return method;
6637         }
6638       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6639     }
6640   return NULL_TREE;
6641 }
6642
6643 /* Return the line that matches DECL line number, and try its best to
6644    position the column number. Used during error reports.  */
6645
6646 static GTY(()) tree cl_v;
6647 static tree
6648 lookup_cl (decl)
6649      tree decl;
6650 {
6651   char *line, *found;
6652   
6653   if (!decl)
6654     return NULL_TREE;
6655
6656   if (cl_v == NULL_TREE)
6657     {
6658       cl_v = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6659     }
6660
6661   EXPR_WFL_FILENAME_NODE (cl_v) = get_identifier (DECL_SOURCE_FILE (decl));
6662   EXPR_WFL_SET_LINECOL (cl_v, DECL_SOURCE_LINE_FIRST (decl), -1);
6663
6664   line = java_get_line_col (EXPR_WFL_FILENAME (cl_v), 
6665                             EXPR_WFL_LINENO (cl_v), EXPR_WFL_COLNO (cl_v));
6666
6667   found = strstr ((const char *)line, 
6668                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6669   if (found)
6670     EXPR_WFL_SET_LINECOL (cl_v, EXPR_WFL_LINENO (cl_v), found - line);
6671
6672   return cl_v;
6673 }
6674
6675 /* Look for a simple name in the single-type import list */
6676
6677 static tree
6678 find_name_in_single_imports (name)
6679      tree name;
6680 {
6681   tree node;
6682
6683   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6684     if (TREE_VALUE (node) == name)
6685       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6686
6687   return NULL_TREE;
6688 }
6689
6690 /* Process all single-type import. */
6691
6692 static int
6693 process_imports ()
6694 {
6695   tree import;
6696   int error_found;
6697
6698   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6699     {
6700       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6701       char *original_name;
6702
6703       obstack_grow0 (&temporary_obstack,
6704                      IDENTIFIER_POINTER (to_be_found),
6705                      IDENTIFIER_LENGTH (to_be_found));
6706       original_name = obstack_finish (&temporary_obstack);
6707
6708       /* Don't load twice something already defined. */
6709       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6710         continue;
6711       
6712       while (1)
6713         {
6714           tree left;
6715
6716           QUALIFIED_P (to_be_found) = 1;
6717           load_class (to_be_found, 0);
6718           error_found =
6719             check_pkg_class_access (to_be_found, TREE_PURPOSE (import), true);
6720           
6721           /* We found it, we can bail out */
6722           if (IDENTIFIER_CLASS_VALUE (to_be_found))
6723             break;
6724
6725           /* We haven't found it. Maybe we're trying to access an
6726              inner class.  The only way for us to know is to try again
6727              after having dropped a qualifier. If we can't break it further,
6728              we have an error. */
6729           if (breakdown_qualified (&left, NULL, to_be_found))
6730             break;
6731
6732           to_be_found = left;
6733         }
6734       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6735         {
6736           parse_error_context (TREE_PURPOSE (import),
6737                                "Class or interface `%s' not found in import",
6738                                original_name);
6739           error_found = 1;
6740         }
6741
6742       obstack_free (&temporary_obstack, original_name);
6743       if (error_found)
6744         return 1;
6745     }
6746   return 0;
6747 }
6748
6749 /* Possibly find and mark a class imported by a single-type import
6750    statement.  */
6751
6752 static void
6753 find_in_imports (enclosing_type, class_type)
6754      tree enclosing_type;
6755      tree class_type;
6756 {
6757   tree import = (enclosing_type ? TYPE_IMPORT_LIST (enclosing_type) : 
6758                  ctxp->import_list);
6759   while (import)
6760     {
6761       if (TREE_VALUE (import) == TYPE_NAME (class_type))
6762         {
6763           TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6764           QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6765           return;
6766         }
6767       import = TREE_CHAIN (import);
6768     }
6769 }
6770
6771 static int
6772 note_possible_classname (name, len)
6773      const char *name;
6774      int len;
6775 {
6776   tree node;
6777   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6778     len = len - 5;
6779   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6780     len = len - 6;
6781   else
6782     return 0;
6783   node = ident_subst (name, len, "", '/', '.', "");
6784   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6785   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6786   return 1;
6787 }
6788
6789 /* Read a import directory, gathering potential match for further type
6790    references. Indifferently reads a filesystem or a ZIP archive
6791    directory.  */
6792
6793 static void
6794 read_import_dir (wfl)
6795      tree wfl;
6796 {
6797   tree package_id = EXPR_WFL_NODE (wfl);
6798   const char *package_name = IDENTIFIER_POINTER (package_id);
6799   int package_length = IDENTIFIER_LENGTH (package_id);
6800   DIR *dirp = NULL;
6801   JCF *saved_jcf = current_jcf;
6802
6803   int found = 0;
6804   int k;
6805   void *entry;
6806   struct buffer filename[1];
6807
6808   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6809     return;
6810   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6811
6812   BUFFER_INIT (filename);
6813   buffer_grow (filename, package_length + 100);
6814
6815   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6816     {
6817       const char *entry_name = jcf_path_name (entry);
6818       int entry_length = strlen (entry_name);
6819       if (jcf_path_is_zipfile (entry))
6820         {
6821           ZipFile *zipf;
6822           buffer_grow (filename, entry_length);
6823           memcpy (filename->data, entry_name, entry_length - 1);
6824           filename->data[entry_length-1] = '\0';
6825           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6826           if (zipf == NULL)
6827             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6828           else
6829             {
6830               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6831               BUFFER_RESET (filename);
6832               for (k = 0; k < package_length; k++)
6833                 {
6834                   char ch = package_name[k];
6835                   *filename->ptr++ = ch == '.' ? '/' : ch;
6836                 }
6837               *filename->ptr++ = '/';
6838
6839               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6840                 {
6841                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6842                   int current_entry_len = zipd->filename_length;
6843
6844                   if (current_entry_len >= BUFFER_LENGTH (filename)
6845                       && strncmp (filename->data, current_entry, 
6846                                   BUFFER_LENGTH (filename)) != 0)
6847                     continue;
6848                   found |= note_possible_classname (current_entry,
6849                                                     current_entry_len);
6850                 }
6851             }
6852         }
6853       else
6854         {
6855           BUFFER_RESET (filename);
6856           buffer_grow (filename, entry_length + package_length + 4);
6857           strcpy (filename->data, entry_name);
6858           filename->ptr = filename->data + entry_length;
6859           for (k = 0; k < package_length; k++)
6860             {
6861               char ch = package_name[k];
6862               *filename->ptr++ = ch == '.' ? '/' : ch;
6863             }
6864           *filename->ptr = '\0';
6865
6866           dirp = opendir (filename->data);
6867           if (dirp == NULL)
6868             continue;
6869           *filename->ptr++ = '/';
6870           for (;;)
6871             {
6872               int len; 
6873               const char *d_name;
6874               struct dirent *direntp = readdir (dirp);
6875               if (!direntp)
6876                 break;
6877               d_name = direntp->d_name;
6878               len = strlen (direntp->d_name);
6879               buffer_grow (filename, len+1);
6880               strcpy (filename->ptr, d_name);
6881               found |= note_possible_classname (filename->data + entry_length,
6882                                                 package_length+len+1);
6883             }
6884           if (dirp)
6885             closedir (dirp);
6886         }
6887     }
6888
6889   free (filename->data);
6890
6891   /* Here we should have a unified way of retrieving an entry, to be
6892      indexed. */
6893   if (!found)
6894     {
6895       static int first = 1;
6896       if (first)
6897         {
6898           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives", package_name);
6899           java_error_count++;
6900           first = 0;
6901         }
6902       else
6903         parse_error_context (wfl, "Package `%s' not found in import",
6904                              package_name);
6905       current_jcf = saved_jcf;
6906       return;
6907     }
6908   current_jcf = saved_jcf;
6909 }
6910
6911 /* Possibly find a type in the import on demands specified
6912    types. Returns 1 if an error occurred, 0 otherwise. Run through the
6913    entire list, to detected potential double definitions.  */
6914                  
6915 static int
6916 find_in_imports_on_demand (enclosing_type, class_type)
6917      tree enclosing_type;
6918      tree class_type;
6919 {
6920   tree class_type_name = TYPE_NAME (class_type);
6921   tree import = (enclosing_type ? TYPE_IMPORT_DEMAND_LIST (enclosing_type) :
6922                   ctxp->import_demand_list);
6923   tree cl = NULL_TREE;
6924   int seen_once = -1;   /* -1 when not set, 1 if seen once, >1 otherwise. */
6925   int to_return = -1;   /* -1 when not set, 0 or 1 otherwise */
6926   tree node;
6927
6928   for (; import; import = TREE_CHAIN (import))
6929     {
6930       int saved_lineno = lineno;
6931       int access_check;
6932       const char *id_name;
6933       tree decl, type_name_copy;
6934
6935       obstack_grow (&temporary_obstack, 
6936                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6937                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6938       obstack_1grow (&temporary_obstack, '.');
6939       obstack_grow0 (&temporary_obstack, 
6940                      IDENTIFIER_POINTER (class_type_name),
6941                      IDENTIFIER_LENGTH (class_type_name));
6942       id_name = obstack_finish (&temporary_obstack);
6943               
6944       if (! (node = maybe_get_identifier (id_name)))
6945         continue;
6946
6947       /* Setup lineno so that it refers to the line of the import (in
6948          case we parse a class file and encounter errors */
6949       lineno = EXPR_WFL_LINENO (TREE_PURPOSE (import));
6950
6951       type_name_copy = TYPE_NAME (class_type);
6952       TYPE_NAME (class_type) = node;
6953       QUALIFIED_P (node) = 1;
6954       decl = IDENTIFIER_CLASS_VALUE (node);
6955       access_check = -1;
6956       /* If there is no DECL set for the class or if the class isn't
6957          loaded and not seen in source yet, then load */
6958       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6959                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6960         {
6961           load_class (node, 0);
6962           decl = IDENTIFIER_CLASS_VALUE (node);
6963         }
6964       if (decl && ! INNER_CLASS_P (TREE_TYPE (decl)))
6965         access_check = check_pkg_class_access (node, TREE_PURPOSE (import),
6966                                                false);
6967       else
6968         /* 6.6.1: Inner classes are subject to member access rules. */
6969         access_check = 0;
6970
6971       lineno = saved_lineno;
6972
6973       /* If the loaded class is not accessible or couldn't be loaded,
6974          we restore the original TYPE_NAME and process the next
6975          import. */
6976       if (access_check || !decl)
6977         {
6978           TYPE_NAME (class_type) = type_name_copy;
6979           continue;
6980         }
6981       
6982       /* If the loaded class is accessible, we keep a tab on it to
6983          detect and report multiple inclusions. */
6984       if (IS_A_CLASSFILE_NAME (node))
6985         {
6986           if (seen_once < 0)
6987             {
6988               cl = TREE_PURPOSE (import);
6989               seen_once = 1;
6990             }
6991           else if (seen_once >= 0)
6992             {
6993               tree location = (cl ? cl : TREE_PURPOSE (import));
6994               tree package = (cl ? EXPR_WFL_NODE (cl) : 
6995                               EXPR_WFL_NODE (TREE_PURPOSE (import)));
6996               seen_once++;
6997               parse_error_context 
6998                 (location,
6999                  "Type `%s' also potentially defined in package `%s'",
7000                  IDENTIFIER_POINTER (TYPE_NAME (class_type)), 
7001                  IDENTIFIER_POINTER (package));
7002             }
7003         }
7004       to_return = access_check;
7005     }
7006
7007   if (seen_once == 1)
7008     return to_return;
7009   else
7010     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
7011 }
7012
7013 /* Add package NAME to the list of package encountered so far. To
7014    speed up class lookup in do_resolve_class, we make sure a
7015    particular package is added only once.  */
7016
7017 static void
7018 register_package (name)
7019      tree name;
7020 {
7021   static htab_t pht;
7022   PTR *e;
7023
7024   if (pht == NULL)
7025     pht = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL);
7026
7027   e = htab_find_slot (pht, name, INSERT);
7028   if (*e == NULL)
7029     {
7030       package_list = chainon (package_list, build_tree_list (name, NULL));
7031       *e = name;
7032     }
7033 }
7034
7035 static tree
7036 resolve_package (pkg, next, type_name)
7037      tree pkg, *next, *type_name;
7038 {
7039   tree current;
7040   tree decl = NULL_TREE;
7041   *type_name = NULL_TREE;
7042
7043   /* The trick is to determine when the package name stops and were
7044      the name of something contained in the package starts. Then we
7045      return a fully qualified name of what we want to get. */
7046
7047   *next = EXPR_WFL_QUALIFICATION (pkg);
7048
7049   /* Try to progressively construct a type name */
7050   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
7051     for (current = EXPR_WFL_QUALIFICATION (pkg); 
7052          current; current = TREE_CHAIN (current))
7053       {
7054         /* If we don't have what we're expecting, exit now. TYPE_NAME
7055            will be null and the error caught later. */
7056         if (TREE_CODE (QUAL_WFL (current)) != EXPR_WITH_FILE_LOCATION)
7057           break;
7058         *type_name = 
7059           merge_qualified_name (*type_name, EXPR_WFL_NODE (QUAL_WFL (current)));
7060         if ((decl = resolve_no_layout (*type_name, NULL_TREE)))
7061           {
7062             /* resolve_package should be used in a loop, hence we
7063                point at this one to naturally process the next one at
7064                the next iteration. */
7065             *next = current;
7066             break;
7067           }
7068       }
7069   return decl;
7070 }
7071
7072
7073 /* Check accessibility of inner classes according to member access rules. 
7074    DECL is the inner class, ENCLOSING_DECL is the class from which the
7075    access is being attempted. */
7076
7077 static void
7078 check_inner_class_access (decl, enclosing_decl, cl)
7079      tree decl, enclosing_decl, cl;
7080 {
7081   const char *access;
7082   tree enclosing_decl_type;
7083
7084   /* We don't issue an error message when CL is null. CL can be null
7085      as a result of processing a JDEP crafted by source_start_java_method
7086      for the purpose of patching its parm decl. But the error would
7087      have been already trapped when fixing the method's signature.
7088      DECL can also be NULL in case of earlier errors. */
7089   if (!decl || !cl)
7090     return;
7091
7092   enclosing_decl_type = TREE_TYPE (enclosing_decl);
7093
7094   if (CLASS_PRIVATE (decl))
7095     {
7096       /* Access is permitted only within the body of the top-level
7097          class in which DECL is declared. */
7098       tree top_level = decl;
7099       while (DECL_CONTEXT (top_level))
7100         top_level = DECL_CONTEXT (top_level);      
7101       while (DECL_CONTEXT (enclosing_decl))
7102         enclosing_decl = DECL_CONTEXT (enclosing_decl);
7103       if (top_level == enclosing_decl)
7104         return;      
7105       access = "private";
7106     }
7107   else if (CLASS_PROTECTED (decl))
7108     {
7109       tree decl_context;
7110       /* Access is permitted from within the same package... */
7111       if (in_same_package (decl, enclosing_decl))
7112         return;
7113       
7114       /* ... or from within the body of a subtype of the context in which
7115          DECL is declared. */
7116       decl_context = DECL_CONTEXT (decl);
7117       while (enclosing_decl)
7118         {
7119           if (CLASS_INTERFACE (decl))
7120             {
7121               if (interface_of_p (TREE_TYPE (decl_context), 
7122                                   enclosing_decl_type))
7123                 return;
7124             }
7125           else
7126             {
7127               /* Eww. The order of the arguments is different!! */
7128               if (inherits_from_p (enclosing_decl_type, 
7129                                    TREE_TYPE (decl_context)))
7130                 return;
7131             }
7132           enclosing_decl = DECL_CONTEXT (enclosing_decl);
7133         }      
7134       access = "protected";
7135     }
7136   else if (! CLASS_PUBLIC (decl))
7137     {
7138       /* Access is permitted only from within the same package as DECL. */
7139       if (in_same_package (decl, enclosing_decl))
7140         return;
7141       access = "non-public";
7142     }
7143   else
7144     /* Class is public. */
7145     return;
7146
7147   parse_error_context (cl, "Nested %s %s is %s; cannot be accessed from here",
7148                        (CLASS_INTERFACE (decl) ? "interface" : "class"),
7149                        lang_printable_name (decl, 0), access);
7150 }
7151
7152 /* Accessibility check for top-level classes. If CLASS_NAME is in a
7153    foreign package, it must be PUBLIC. Return 0 if no access
7154    violations were found, 1 otherwise. If VERBOSE is true and an error
7155    was found, it is reported and accounted for.  */
7156
7157 static int
7158 check_pkg_class_access (class_name, cl, verbose)
7159      tree class_name;
7160      tree cl;
7161      bool verbose;
7162 {
7163   tree type;
7164
7165   if (!IDENTIFIER_CLASS_VALUE (class_name))
7166     return 0;
7167
7168   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
7169     return 0;
7170
7171   if (!CLASS_PUBLIC (TYPE_NAME (type)))
7172     {
7173       /* Access to a private class within the same package is
7174          allowed. */
7175       tree l, r;
7176       breakdown_qualified (&l, &r, class_name);
7177       if (!QUALIFIED_P (class_name) && !ctxp->package)
7178         /* Both in the empty package. */
7179         return 0;
7180       if (l == ctxp->package)
7181         /* Both in the same package. */
7182         return 0;
7183
7184       if (verbose)
7185         parse_error_context 
7186           (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
7187            (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
7188            IDENTIFIER_POINTER (class_name));
7189       return 1;
7190     }
7191   return 0;
7192 }
7193
7194 /* Local variable declaration. */
7195
7196 static void
7197 declare_local_variables (modifier, type, vlist)
7198      int modifier;
7199      tree type;
7200      tree vlist;
7201 {
7202   tree decl, current, saved_type;
7203   tree type_wfl = NULL_TREE;
7204   int must_chain = 0;
7205   int final_p = 0;
7206
7207   /* Push a new block if statements were seen between the last time we
7208      pushed a block and now. Keep a count of blocks to close */
7209   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
7210     {
7211       tree b = enter_block ();
7212       BLOCK_IS_IMPLICIT (b) = 1;
7213     }
7214
7215   if (modifier)
7216     {
7217       int i;
7218       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
7219       if (modifier == ACC_FINAL)
7220         final_p = 1;
7221       else 
7222         {
7223           parse_error_context 
7224             (ctxp->modifier_ctx [i], 
7225              "Only `final' is allowed as a local variables modifier");
7226           return;
7227         }
7228     }
7229
7230   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
7231      hold the TYPE value if a new incomplete has to be created (as
7232      opposed to being found already existing and reused). */
7233   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
7234
7235   /* If TYPE is fully resolved and we don't have a reference, make one */
7236   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
7237
7238   /* Go through all the declared variables */
7239   for (current = vlist, saved_type = type; current;
7240        current = TREE_CHAIN (current), type = saved_type)
7241     {
7242       tree other, real_type;
7243       tree wfl  = TREE_PURPOSE (current);
7244       tree name = EXPR_WFL_NODE (wfl);
7245       tree init = TREE_VALUE (current);
7246
7247       /* Process NAME, as it may specify extra dimension(s) for it */
7248       type = build_array_from_name (type, type_wfl, name, &name);
7249
7250       /* Variable redefinition check */
7251       if ((other = lookup_name_in_blocks (name)))
7252         {
7253           variable_redefinition_error (wfl, name, TREE_TYPE (other),
7254                                        DECL_SOURCE_LINE (other));
7255           continue;
7256         }
7257
7258       /* Type adjustment. We may have just readjusted TYPE because
7259          the variable specified more dimensions. Make sure we have
7260          a reference if we can and don't have one already. */
7261       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
7262
7263       real_type = GET_REAL_TYPE (type);
7264       /* Never layout this decl. This will be done when its scope
7265          will be entered */
7266       decl = build_decl (VAR_DECL, name, real_type);
7267       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
7268       DECL_FINAL (decl) = final_p;
7269       BLOCK_CHAIN_DECL (decl);
7270       
7271       /* If doing xreferencing, replace the line number with the WFL
7272          compound value */
7273       if (flag_emit_xref)
7274         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
7275       
7276       /* Don't try to use an INIT statement when an error was found */
7277       if (init && java_error_count)
7278         init = NULL_TREE;
7279       
7280       /* Add the initialization function to the current function's code */
7281       if (init)
7282         {
7283           /* Name might have been readjusted */
7284           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
7285           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
7286           java_method_add_stmt (current_function_decl,
7287                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
7288                                                       init));
7289         }
7290     
7291       /* Setup dependency the type of the decl */
7292       if (must_chain)
7293         {
7294           jdep *dep;
7295           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
7296           dep = CLASSD_LAST (ctxp->classd_list);
7297           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
7298         }
7299     }
7300   SOURCE_FRONTEND_DEBUG (("Defined locals"));
7301 }
7302
7303 /* Called during parsing. Build decls from argument list.  */
7304
7305 static void
7306 source_start_java_method (fndecl)
7307      tree fndecl;
7308 {
7309   tree tem;
7310   tree parm_decl;
7311   int i;
7312
7313   if (!fndecl)
7314     return;
7315
7316   current_function_decl = fndecl;
7317
7318   /* New scope for the function */
7319   enter_block ();
7320   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
7321        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
7322     {
7323       tree type = TREE_VALUE (tem);
7324       tree name = TREE_PURPOSE (tem);
7325       
7326       /* If type is incomplete. Create an incomplete decl and ask for
7327          the decl to be patched later */
7328       if (INCOMPLETE_TYPE_P (type))
7329         {
7330           jdep *jdep;
7331           tree real_type = GET_REAL_TYPE (type);
7332           parm_decl = build_decl (PARM_DECL, name, real_type);
7333           type = obtain_incomplete_type (type);
7334           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
7335           jdep = CLASSD_LAST (ctxp->classd_list);
7336           JDEP_MISC (jdep) = name;
7337           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
7338         }
7339       else
7340         parm_decl = build_decl (PARM_DECL, name, type);
7341
7342       /* Remember if a local variable was declared final (via its
7343          TREE_LIST of type/name.) Set DECL_FINAL accordingly. */
7344       if (ARG_FINAL_P (tem))
7345         {
7346           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (parm_decl);
7347           DECL_FINAL (parm_decl) = 1;
7348         }
7349
7350       BLOCK_CHAIN_DECL (parm_decl);
7351     }
7352   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7353   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
7354     nreverse (tem);
7355   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
7356   DECL_MAX_LOCALS (current_function_decl) = i;
7357 }
7358
7359 /* Called during parsing. Creates an artificial method declaration.  */
7360
7361 static tree
7362 create_artificial_method (class, flags, type, name, args)
7363      tree class;
7364      int flags;
7365      tree type, name, args;
7366 {
7367   tree mdecl;
7368
7369   java_parser_context_save_global ();
7370   lineno = 0;                                                               
7371   mdecl = make_node (FUNCTION_TYPE);                                
7372   TREE_TYPE (mdecl) = type;
7373   TYPE_ARG_TYPES (mdecl) = args;
7374   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
7375   java_parser_context_restore_global ();
7376   DECL_ARTIFICIAL (mdecl) = 1;                                      
7377   return mdecl;
7378 }
7379
7380 /* Starts the body if an artificial method.  */
7381
7382 static void
7383 start_artificial_method_body (mdecl)
7384      tree mdecl;
7385 {
7386   DECL_SOURCE_LINE (mdecl) = 1;
7387   DECL_SOURCE_LINE_MERGE (mdecl, 1);
7388   source_start_java_method (mdecl);
7389   enter_block ();
7390 }
7391
7392 static void
7393 end_artificial_method_body (mdecl)
7394      tree mdecl;
7395 {
7396   /* exit_block modifies DECL_FUNCTION_BODY (current_function_decl).
7397      It has to be evaluated first. (if mdecl is current_function_decl,
7398      we have an undefined behavior if no temporary variable is used.) */
7399   tree b = exit_block ();
7400   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = b;
7401   exit_block ();
7402 }
7403
7404 /* Dump a tree of some kind.  This is a convenience wrapper for the
7405    dump_* functions in tree-dump.c.  */
7406 static void
7407 dump_java_tree (phase, t)
7408      enum tree_dump_index phase;
7409      tree t;
7410 {
7411   FILE *stream;
7412   int flags;
7413
7414   stream = dump_begin (phase, &flags);
7415   if (stream)
7416     {
7417       dump_node (t, flags, stream);
7418       dump_end (phase, stream);
7419     }
7420 }
7421
7422 /* Terminate a function and expand its body.  */
7423
7424 static void
7425 source_end_java_method ()
7426 {
7427   tree fndecl = current_function_decl;
7428
7429   if (!fndecl)
7430     return;
7431
7432   java_parser_context_save_global ();
7433   lineno = ctxp->last_ccb_indent1;
7434
7435   /* Turn function bodies with only a NOP expr null, so they don't get
7436      generated at all and we won't get warnings when using the -W
7437      -Wall flags. */
7438   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7439     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7440
7441   /* We've generated all the trees for this function, and it has been
7442      patched.  Dump it to a file if the user requested it.  */
7443   dump_java_tree (TDI_original, fndecl);
7444
7445   /* Generate function's code */
7446   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7447       && ! flag_emit_class_files
7448       && ! flag_emit_xref)
7449     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7450
7451   /* pop out of its parameters */
7452   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7453   poplevel (1, 0, 1);
7454   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7455
7456   /* Generate rtl for function exit.  */
7457   if (! flag_emit_class_files && ! flag_emit_xref)
7458     {
7459       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7460       expand_function_end (input_filename, lineno, 0);
7461
7462       /* Run the optimizers and output assembler code for this function. */
7463       rest_of_compilation (fndecl);
7464     }
7465
7466   current_function_decl = NULL_TREE;
7467   java_parser_context_restore_global ();
7468 }
7469
7470 /* Record EXPR in the current function block. Complements compound
7471    expression second operand if necessary.  */
7472
7473 tree
7474 java_method_add_stmt (fndecl, expr)
7475      tree fndecl, expr;
7476 {
7477   if (!GET_CURRENT_BLOCK (fndecl))
7478     return NULL_TREE;
7479   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7480 }
7481
7482 static tree
7483 add_stmt_to_block (b, type, stmt)
7484      tree b, type, stmt;
7485 {
7486   tree body = BLOCK_EXPR_BODY (b), c;
7487   
7488   if (java_error_count)
7489     return body;
7490     
7491   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7492     return body;
7493
7494   BLOCK_EXPR_BODY (b) = c;
7495   TREE_SIDE_EFFECTS (c) = 1;
7496   return c;
7497 }
7498
7499 /* Add STMT to EXISTING if possible, otherwise create a new
7500    COMPOUND_EXPR and add STMT to it. */
7501
7502 static tree
7503 add_stmt_to_compound (existing, type, stmt)
7504      tree existing, type, stmt;
7505 {
7506   if (existing)
7507     return build (COMPOUND_EXPR, type, existing, stmt);
7508   else
7509     return stmt;
7510 }
7511
7512 void java_layout_seen_class_methods ()
7513 {
7514   tree previous_list = all_class_list;
7515   tree end = NULL_TREE;
7516   tree current;
7517
7518   while (1)
7519     {
7520       for (current = previous_list; 
7521            current != end; current = TREE_CHAIN (current))
7522         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7523       
7524       if (previous_list != all_class_list)
7525         {
7526           end = previous_list;
7527           previous_list = all_class_list;
7528         }
7529       else
7530         break;
7531     }
7532 }
7533
7534 static GTY(()) tree stop_reordering;
7535 void
7536 java_reorder_fields ()
7537 {
7538   tree current;
7539
7540   for (current = gclass_list; current; current = TREE_CHAIN (current))
7541     {
7542       current_class = TREE_TYPE (TREE_VALUE (current));
7543
7544       if (current_class == stop_reordering)
7545         break;
7546
7547       /* Reverse the fields, but leave the dummy field in front.
7548          Fields are already ordered for Object and Class */
7549       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7550           && current_class != class_type_node)
7551       {
7552         /* If the dummy field is there, reverse the right fields and
7553            just layout the type for proper fields offset */
7554         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7555           {
7556             tree fields = TYPE_FIELDS (current_class);
7557             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7558             TYPE_SIZE (current_class) = NULL_TREE;
7559           }
7560         /* We don't have a dummy field, we need to layout the class,
7561            after having reversed the fields */
7562         else
7563           {
7564             TYPE_FIELDS (current_class) = 
7565               nreverse (TYPE_FIELDS (current_class));
7566             TYPE_SIZE (current_class) = NULL_TREE;
7567           }
7568       }
7569     }
7570   /* There are cases were gclass_list will be empty. */
7571   if (gclass_list)
7572     stop_reordering = TREE_TYPE (TREE_VALUE (gclass_list));
7573 }
7574
7575 /* Layout the methods of all classes loaded in one way or another.
7576    Check methods of source parsed classes. Then reorder the
7577    fields and layout the classes or the type of all source parsed
7578    classes */
7579
7580 void
7581 java_layout_classes ()
7582 {
7583   tree current;
7584   int save_error_count = java_error_count;
7585
7586   /* Layout the methods of all classes seen so far */
7587   java_layout_seen_class_methods ();
7588   java_parse_abort_on_error ();
7589   all_class_list = NULL_TREE;
7590
7591   /* Then check the methods of all parsed classes */
7592   for (current = gclass_list; current; current = TREE_CHAIN (current))
7593     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7594       java_check_methods (TREE_VALUE (current));
7595   java_parse_abort_on_error ();
7596
7597   for (current = gclass_list; current; current = TREE_CHAIN (current))
7598     {
7599       current_class = TREE_TYPE (TREE_VALUE (current));
7600       layout_class (current_class);
7601
7602       /* Error reported by the caller */
7603       if (java_error_count)
7604         return;
7605     }
7606
7607   /* We might have reloaded classes durign the process of laying out
7608      classes for code generation. We must layout the methods of those
7609      late additions, as constructor checks might use them */
7610   java_layout_seen_class_methods ();
7611   java_parse_abort_on_error ();
7612 }
7613
7614 /* Expand methods in the current set of classes rememebered for
7615    generation.  */
7616
7617 static void
7618 java_complete_expand_classes ()
7619 {
7620   tree current;
7621
7622   do_not_fold = flag_emit_xref;
7623
7624   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7625     if (!INNER_CLASS_DECL_P (current))
7626       java_complete_expand_class (current);
7627 }
7628
7629 /* Expand the methods found in OUTER, starting first by OUTER's inner
7630    classes, if any.  */
7631
7632 static void
7633 java_complete_expand_class (outer)
7634      tree outer;
7635 {
7636   tree inner_list;
7637
7638   set_nested_class_simple_name_value (outer, 1); /* Set */
7639
7640   /* We need to go after all inner classes and start expanding them,
7641      starting with most nested ones. We have to do that because nested
7642      classes might add functions to outer classes */
7643
7644   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7645        inner_list; inner_list = TREE_CHAIN (inner_list))
7646     java_complete_expand_class (TREE_PURPOSE (inner_list));
7647
7648   java_complete_expand_methods (outer);
7649   set_nested_class_simple_name_value (outer, 0); /* Reset */
7650 }
7651
7652 /* Expand methods registered in CLASS_DECL. The general idea is that
7653    we expand regular methods first. This allows us get an estimate on
7654    how outer context local alias fields are really used so we can add
7655    to the constructor just enough code to initialize them properly (it
7656    also lets us generate finit$ correctly.) Then we expand the
7657    constructors and then <clinit>.  */
7658
7659 static void
7660 java_complete_expand_methods (class_decl)
7661      tree class_decl;
7662 {
7663   tree clinit, decl, first_decl;
7664
7665   current_class = TREE_TYPE (class_decl);
7666
7667   /* Initialize a new constant pool */
7668   init_outgoing_cpool ();
7669
7670   /* Pre-expand <clinit> to figure whether we really need it or
7671      not. If we do need it, we pre-expand the static fields so they're
7672      ready to be used somewhere else. <clinit> will be fully expanded
7673      after we processed the constructors. */
7674   first_decl = TYPE_METHODS (current_class);
7675   clinit = maybe_generate_pre_expand_clinit (current_class);
7676
7677   /* Then generate finit$ (if we need to) because constructors will
7678    try to use it.*/
7679   if (TYPE_FINIT_STMT_LIST (current_class))
7680     java_complete_expand_method (generate_finit (current_class));
7681
7682   /* Then generate instinit$ (if we need to) because constructors will
7683      try to use it. */
7684   if (TYPE_II_STMT_LIST (current_class))
7685     java_complete_expand_method (generate_instinit (current_class));
7686
7687   /* Now do the constructors */
7688   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7689     {
7690       int no_body;
7691
7692       if (!DECL_CONSTRUCTOR_P (decl))
7693         continue;
7694       
7695       no_body = !DECL_FUNCTION_BODY (decl);
7696       /* Don't generate debug info on line zero when expanding a
7697          generated constructor. */
7698       if (no_body)
7699         restore_line_number_status (1);
7700
7701       java_complete_expand_method (decl);
7702
7703       if (no_body)
7704         restore_line_number_status (0);
7705     }
7706
7707   /* First, do the ordinary methods. */
7708   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7709     {
7710       /* Ctors aren't part of this batch. */
7711       if (DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7712         continue;
7713       
7714       /* Skip abstract or native methods -- but do handle native
7715          methods when generating JNI stubs.  */
7716       if (METHOD_ABSTRACT (decl) || (! flag_jni && METHOD_NATIVE (decl)))
7717         {
7718           DECL_FUNCTION_BODY (decl) = NULL_TREE;
7719           continue;
7720         }
7721
7722       if (METHOD_NATIVE (decl))
7723         {
7724           tree body;
7725           current_function_decl = decl;
7726           body = build_jni_stub (decl);
7727           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7728         }
7729
7730       java_complete_expand_method (decl);
7731     }
7732
7733   /* If there is indeed a <clinit>, fully expand it now */
7734   if (clinit)
7735     {
7736       /* Prevent the use of `this' inside <clinit> */
7737       ctxp->explicit_constructor_p = 1;
7738       java_complete_expand_method (clinit);
7739       ctxp->explicit_constructor_p = 0;
7740     }
7741   
7742   /* We might have generated a class$ that we now want to expand */
7743   if (TYPE_DOT_CLASS (current_class))
7744     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7745
7746   /* Now verify constructor circularity (stop after the first one we
7747      prove wrong.) */
7748   if (!CLASS_INTERFACE (class_decl))
7749     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7750       if (DECL_CONSTRUCTOR_P (decl) 
7751           && verify_constructor_circularity (decl, decl))
7752         break;
7753
7754   /* Save the constant pool. We'll need to restore it later. */
7755   TYPE_CPOOL (current_class) = outgoing_cpool;
7756 }
7757
7758 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7759    safely used in some other methods/constructors.  */
7760
7761 static tree
7762 maybe_generate_pre_expand_clinit (class_type)
7763      tree class_type;
7764 {
7765   tree current, mdecl;
7766
7767   if (!TYPE_CLINIT_STMT_LIST (class_type))
7768     return NULL_TREE;
7769
7770   /* Go through all static fields and pre expand them */
7771   for (current = TYPE_FIELDS (class_type); current; 
7772        current = TREE_CHAIN (current))
7773     if (FIELD_STATIC (current))
7774       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7775
7776   /* Then build the <clinit> method */
7777   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7778                                     clinit_identifier_node, end_params_node);
7779   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7780                        mdecl, NULL_TREE);
7781   start_artificial_method_body (mdecl);
7782
7783   /* We process the list of assignment we produced as the result of
7784      the declaration of initialized static field and add them as
7785      statement to the <clinit> method. */
7786   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7787        current = TREE_CHAIN (current))
7788     {
7789       tree stmt = current;
7790       /* We build the assignment expression that will initialize the
7791          field to its value. There are strict rules on static
7792          initializers (8.5). FIXME */
7793       if (TREE_CODE (stmt) != BLOCK && stmt != empty_stmt_node)
7794         stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
7795       java_method_add_stmt (mdecl, stmt);
7796     }
7797
7798   end_artificial_method_body (mdecl);
7799
7800   /* Now we want to place <clinit> as the last method (because we need
7801      it at least for interface so that it doesn't interfere with the
7802      dispatch table based lookup. */
7803   if (TREE_CHAIN (TYPE_METHODS (class_type)))
7804     {
7805       current = TREE_CHAIN (TYPE_METHODS (class_type));
7806       TYPE_METHODS (class_type) = current;
7807
7808       while (TREE_CHAIN (current))
7809         current = TREE_CHAIN (current);
7810
7811       TREE_CHAIN (current) = mdecl;
7812       TREE_CHAIN (mdecl) = NULL_TREE;
7813     }
7814
7815   return mdecl;
7816 }
7817
7818 /* Analyzes a method body and look for something that isn't a
7819    MODIFY_EXPR with a constant value.  */
7820
7821 static int
7822 analyze_clinit_body (this_class, bbody)
7823      tree this_class, bbody;
7824 {
7825   while (bbody)
7826     switch (TREE_CODE (bbody))
7827       {
7828       case BLOCK:
7829         bbody = BLOCK_EXPR_BODY (bbody);
7830         break;
7831         
7832       case EXPR_WITH_FILE_LOCATION:
7833         bbody = EXPR_WFL_NODE (bbody);
7834         break;
7835         
7836       case COMPOUND_EXPR:
7837         if (analyze_clinit_body (this_class, TREE_OPERAND (bbody, 0)))
7838           return 1;
7839         bbody = TREE_OPERAND (bbody, 1);
7840         break;
7841         
7842       case MODIFY_EXPR:
7843         /* If we're generating to class file and we're dealing with an
7844            array initialization, we return 1 to keep <clinit> */
7845         if (TREE_CODE (TREE_OPERAND (bbody, 1)) == NEW_ARRAY_INIT
7846             && flag_emit_class_files)
7847           return 1;
7848
7849         /* There are a few cases where we're required to keep
7850            <clinit>:
7851            - If this is an assignment whose operand is not constant,
7852            - If this is an assignment to a non-initialized field,
7853            - If this field is not a member of the current class.
7854         */
7855         return (! TREE_CONSTANT (TREE_OPERAND (bbody, 1))
7856                 || ! DECL_INITIAL (TREE_OPERAND (bbody, 0))
7857                 || DECL_CONTEXT (TREE_OPERAND (bbody, 0)) != this_class);
7858
7859       default:
7860         return 1;
7861       }
7862   return 0;
7863 }
7864
7865
7866 /* See whether we could get rid of <clinit>. Criteria are: all static
7867    final fields have constant initial values and the body of <clinit>
7868    is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
7869
7870 static int
7871 maybe_yank_clinit (mdecl)
7872      tree mdecl;
7873 {
7874   tree type, current;
7875   tree fbody, bbody;
7876   
7877   if (!DECL_CLINIT_P (mdecl))
7878     return 0;
7879
7880   /* If the body isn't empty, then we keep <clinit>. Note that if
7881      we're emitting classfiles, this isn't enough not to rule it
7882      out. */
7883   fbody = DECL_FUNCTION_BODY (mdecl);
7884   bbody = BLOCK_EXPR_BODY (fbody);
7885   if (bbody && bbody != error_mark_node)
7886     bbody = BLOCK_EXPR_BODY (bbody);
7887   else
7888     return 0;
7889   if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
7890     return 0;
7891
7892   type = DECL_CONTEXT (mdecl);
7893   current = TYPE_FIELDS (type);
7894
7895   for (current = (current ? TREE_CHAIN (current) : current); 
7896        current; current = TREE_CHAIN (current))
7897     {
7898       tree f_init;
7899
7900       /* We're not interested in non-static fields.  */
7901       if (!FIELD_STATIC (current))
7902         continue;
7903
7904       /* Nor in fields without initializers. */
7905       f_init = DECL_INITIAL (current);
7906       if (f_init == NULL_TREE)
7907         continue;
7908
7909       /* Anything that isn't String or a basic type is ruled out -- or
7910          if we know how to deal with it (when doing things natively) we
7911          should generated an empty <clinit> so that SUID are computed
7912          correctly. */
7913       if (! JSTRING_TYPE_P (TREE_TYPE (current))
7914           && ! JNUMERIC_TYPE_P (TREE_TYPE (current)))
7915         return 0;
7916
7917       if (! FIELD_FINAL (current) || ! TREE_CONSTANT (f_init))
7918         return 0;
7919     }
7920
7921   /* Now we analyze the method body and look for something that
7922      isn't a MODIFY_EXPR */
7923   if (bbody != empty_stmt_node && analyze_clinit_body (type, bbody))
7924     return 0;
7925
7926   /* Get rid of <clinit> in the class' list of methods */
7927   if (TYPE_METHODS (type) == mdecl)
7928     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
7929   else
7930     for (current = TYPE_METHODS (type); current; 
7931          current = TREE_CHAIN (current))
7932       if (TREE_CHAIN (current) == mdecl)
7933         {
7934           TREE_CHAIN (current) = TREE_CHAIN (mdecl);
7935           break;
7936         }
7937
7938   return 1;
7939 }
7940
7941 /* Install the argument from MDECL. Suitable to completion and
7942    expansion of mdecl's body.  */
7943
7944 static void
7945 start_complete_expand_method (mdecl)
7946      tree mdecl;
7947 {
7948   tree tem;
7949
7950   pushlevel (1);                /* Prepare for a parameter push */
7951   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7952   DECL_ARGUMENTS (mdecl) = tem;
7953
7954   for (; tem; tem = TREE_CHAIN (tem))
7955     {
7956       /* TREE_CHAIN (tem) will change after pushdecl. */ 
7957       tree next = TREE_CHAIN (tem);
7958       tree type = TREE_TYPE (tem);
7959       if (PROMOTE_PROTOTYPES
7960           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
7961           && INTEGRAL_TYPE_P (type))
7962         type = integer_type_node;
7963       DECL_ARG_TYPE (tem) = type;
7964       layout_decl (tem, 0);
7965       pushdecl (tem);
7966       /* Re-install the next so that the list is kept and the loop
7967          advances. */
7968       TREE_CHAIN (tem) = next;
7969     }
7970   pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7971   lineno = DECL_SOURCE_LINE_FIRST (mdecl);
7972   build_result_decl (mdecl);
7973 }
7974
7975
7976 /* Complete and expand a method.  */
7977
7978 static void
7979 java_complete_expand_method (mdecl)
7980      tree mdecl;
7981 {
7982   tree fbody, block_body, exception_copy;
7983
7984   current_function_decl = mdecl;
7985   /* Fix constructors before expanding them */
7986   if (DECL_CONSTRUCTOR_P (mdecl))
7987     fix_constructors (mdecl);
7988   
7989   /* Expand functions that have a body */
7990   if (!DECL_FUNCTION_BODY (mdecl))
7991     return;
7992
7993   fbody = DECL_FUNCTION_BODY (mdecl);
7994   block_body = BLOCK_EXPR_BODY (fbody);
7995   exception_copy = NULL_TREE;
7996
7997   current_function_decl = mdecl;
7998
7999   if (! quiet_flag)
8000     fprintf (stderr, " [%s.",
8001              lang_printable_name (DECL_CONTEXT (mdecl), 0));
8002   announce_function (mdecl);
8003   if (! quiet_flag)
8004     fprintf (stderr, "]");
8005   
8006   /* Prepare the function for tree completion */
8007   start_complete_expand_method (mdecl);
8008
8009   /* Install the current this */
8010   current_this = (!METHOD_STATIC (mdecl) ? 
8011                   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
8012
8013   /* Purge the `throws' list of unchecked exceptions (we save a copy
8014      of the list and re-install it later.) */
8015   exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
8016   purge_unchecked_exceptions (mdecl);
8017   
8018   /* Install exceptions thrown with `throws' */
8019   PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
8020   
8021   if (block_body != NULL_TREE)
8022     {
8023       block_body = java_complete_tree (block_body);
8024       
8025       /* Before we check initialization, attached all class initialization
8026          variable to the block_body */
8027       htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
8028                      attach_init_test_initialization_flags, block_body);
8029       
8030       if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
8031         {
8032           check_for_initialization (block_body, mdecl);
8033           
8034           /* Go through all the flags marking the initialization of
8035              static variables and see whether they're definitively
8036              assigned, in which case the type is remembered as
8037              definitively initialized in MDECL. */
8038           if (STATIC_CLASS_INIT_OPT_P ())
8039             {
8040               /* Always register the context as properly initialized in
8041                  MDECL. This used with caution helps removing extra
8042                  initialization of self. */
8043               if (METHOD_STATIC (mdecl))
8044                 {
8045                   *(htab_find_slot 
8046                     (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (mdecl),
8047                      DECL_CONTEXT (mdecl), INSERT)) = DECL_CONTEXT (mdecl);
8048                 }
8049             }
8050         }
8051       ctxp->explicit_constructor_p = 0;
8052     }
8053   
8054   BLOCK_EXPR_BODY (fbody) = block_body;
8055   
8056   /* If we saw a return but couldn't evaluate it properly, we'll have
8057      an error_mark_node here. */
8058   if (block_body != error_mark_node
8059       && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
8060       && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
8061       && !flag_emit_xref)
8062     missing_return_error (current_function_decl);
8063
8064   /* See if we can get rid of <clinit> if MDECL happens to be <clinit> */
8065   maybe_yank_clinit (mdecl);
8066
8067   /* Pop the current level, with special measures if we found errors. */
8068   if (java_error_count)
8069     pushdecl_force_head (DECL_ARGUMENTS (mdecl));
8070   poplevel (1, 0, 1);
8071
8072   /* Pop the exceptions and sanity check */
8073   POP_EXCEPTIONS();
8074   if (currently_caught_type_list)
8075     abort ();
8076
8077   /* Restore the copy of the list of exceptions if emitting xrefs. */
8078   DECL_FUNCTION_THROWS (mdecl) = exception_copy;
8079 }
8080
8081 /* For with each class for which there's code to generate. */
8082
8083 static void
8084 java_expand_method_bodies (class)
8085      tree class;
8086 {
8087   tree decl;
8088   for (decl = TYPE_METHODS (class); decl; decl = TREE_CHAIN (decl))
8089     {
8090       if (!DECL_FUNCTION_BODY (decl))
8091         continue;
8092
8093       current_function_decl = decl;
8094
8095       /* It's time to assign the variable flagging static class
8096          initialization based on which classes invoked static methods
8097          are definitely initializing. This should be flagged. */
8098       if (STATIC_CLASS_INIT_OPT_P ())
8099         {
8100           tree list = DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (decl);
8101           for (; list != NULL_TREE;  list = TREE_CHAIN (list))
8102             {
8103               /* Executed for each statement calling a static function.
8104                  LIST is a TREE_LIST whose PURPOSE is the called function
8105                  and VALUE is a compound whose second operand can be patched
8106                  with static class initialization flag assignments.  */
8107
8108               tree called_method = TREE_PURPOSE (list);
8109               tree compound = TREE_VALUE (list);
8110               tree assignment_compound_list
8111                 = build_tree_list (called_method, NULL);
8112
8113               /* For each class definitely initialized in
8114                  CALLED_METHOD, fill ASSIGNMENT_COMPOUND with
8115                  assignment to the class initialization flag. */
8116               htab_traverse (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method),
8117                              emit_test_initialization,
8118                              assignment_compound_list);
8119
8120               if (TREE_VALUE (assignment_compound_list))
8121                 TREE_OPERAND (compound, 1)
8122                   = TREE_VALUE (assignment_compound_list);
8123             }
8124         }
8125
8126       /* Prepare the function for RTL expansion */  
8127       start_complete_expand_method (decl);
8128
8129       /* Expand function start, generate initialization flag
8130          assignment, and handle synchronized methods. */
8131       complete_start_java_method (decl);
8132
8133       /* Expand the rest of the function body and terminate
8134          expansion. */
8135       source_end_java_method ();
8136     }
8137 }
8138
8139 \f
8140
8141 /* This section of the code deals with accessing enclosing context
8142    fields either directly by using the relevant access to this$<n> or
8143    by invoking an access method crafted for that purpose.  */
8144
8145 /* Build the necessary access from an inner class to an outer
8146    class. This routine could be optimized to cache previous result
8147    (decl, current_class and returned access).  When an access method
8148    needs to be generated, it always takes the form of a read. It might
8149    be later turned into a write by calling outer_field_access_fix.  */
8150
8151 static tree
8152 build_outer_field_access (id, decl)
8153      tree id, decl;
8154 {
8155   tree access = NULL_TREE;
8156   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
8157   tree decl_ctx = DECL_CONTEXT (decl);
8158
8159   /* If the immediate enclosing context of the current class is the
8160      field decl's class or inherits from it; build the access as
8161      `this$<n>.<field>'. Note that we will break the `private' barrier
8162      if we're not emitting bytecodes. */
8163   if ((ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
8164       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
8165     {
8166       tree thisn = build_current_thisn (current_class);
8167       access = make_qualified_primary (build_wfl_node (thisn), 
8168                                        id, EXPR_WFL_LINECOL (id));
8169     }
8170   /* Otherwise, generate access methods to outer this and access the
8171      field (either using an access method or by direct access.) */
8172   else
8173     {
8174       int lc = EXPR_WFL_LINECOL (id);
8175
8176       /* Now we chain the required number of calls to the access$0 to
8177          get a hold to the enclosing instance we need, and then we
8178          build the field access. */
8179       access = build_access_to_thisn (current_class, decl_ctx, lc);
8180
8181       /* If the field is private and we're generating bytecode, then
8182          we generate an access method */
8183       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
8184         {
8185           tree name = build_outer_field_access_methods (decl);
8186           access = build_outer_field_access_expr (lc, decl_ctx,
8187                                                   name, access, NULL_TREE);
8188         }
8189       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
8190          Once again we break the `private' access rule from a foreign
8191          class. */
8192       else
8193         access = make_qualified_primary (access, id, lc);
8194     }
8195   return resolve_expression_name (access, NULL);
8196 }
8197
8198 /* Return a non zero value if NODE describes an outer field inner
8199    access.  */
8200
8201 static int
8202 outer_field_access_p (type, decl)
8203     tree type, decl;
8204 {
8205   if (!INNER_CLASS_TYPE_P (type) 
8206       || TREE_CODE (decl) != FIELD_DECL
8207       || DECL_CONTEXT (decl) == type)
8208     return 0;
8209   
8210   /* If the inner class extends the declaration context of the field
8211      we're try to acces, then this isn't an outer field access */
8212   if (inherits_from_p (type, DECL_CONTEXT (decl)))
8213     return 0;
8214
8215   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
8216        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
8217     {
8218       if (type == DECL_CONTEXT (decl))
8219         return 1;
8220
8221       if (!DECL_CONTEXT (TYPE_NAME (type)))
8222         {
8223           /* Before we give up, see whether the field is inherited from
8224              the enclosing context we're considering. */
8225           if (inherits_from_p (type, DECL_CONTEXT (decl)))
8226             return 1;
8227           break;
8228         }
8229     }
8230
8231   return 0;
8232 }
8233
8234 /* Return a non zero value if NODE represents an outer field inner
8235    access that was been already expanded. As a side effect, it returns
8236    the name of the field being accessed and the argument passed to the
8237    access function, suitable for a regeneration of the access method
8238    call if necessary. */
8239
8240 static int
8241 outer_field_expanded_access_p (node, name, arg_type, arg)
8242     tree node, *name, *arg_type, *arg;
8243 {
8244   int identified = 0;
8245
8246   if (TREE_CODE (node) != CALL_EXPR)
8247     return 0;
8248
8249   /* Well, gcj generates slightly different tree nodes when compiling
8250      to native or bytecodes. It's the case for function calls. */
8251
8252   if (flag_emit_class_files 
8253       && TREE_CODE (node) == CALL_EXPR
8254       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
8255     identified = 1;
8256   else if (!flag_emit_class_files)
8257     {
8258       node = TREE_OPERAND (node, 0);
8259       
8260       if (node && TREE_OPERAND (node, 0)
8261           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
8262         {
8263           node = TREE_OPERAND (node, 0);
8264           if (TREE_OPERAND (node, 0)
8265               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
8266               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
8267                   (DECL_NAME (TREE_OPERAND (node, 0)))))
8268             identified = 1;
8269         }
8270     }
8271
8272   if (identified && name && arg_type && arg)
8273     {
8274       tree argument = TREE_OPERAND (node, 1);
8275       *name = DECL_NAME (TREE_OPERAND (node, 0));
8276       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
8277       *arg = TREE_VALUE (argument);
8278     }
8279   return identified;
8280 }
8281
8282 /* Detect in NODE an outer field read access from an inner class and
8283    transform it into a write with RHS as an argument. This function is
8284    called from the java_complete_lhs when an assignment to a LHS can
8285    be identified. */
8286
8287 static tree
8288 outer_field_access_fix (wfl, node, rhs)
8289     tree wfl, node, rhs;
8290 {
8291   tree name, arg_type, arg;
8292   
8293   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
8294     {
8295       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
8296                                             arg_type, name, arg, rhs);
8297       return java_complete_tree (node);
8298     }
8299   return NULL_TREE;
8300 }
8301
8302 /* Construct the expression that calls an access method:
8303      <type>.access$<n>(<arg1> [, <arg2>]); 
8304
8305    ARG2 can be NULL and will be omitted in that case. It will denote a
8306    read access.  */
8307
8308 static tree
8309 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
8310     int lc;
8311     tree type, access_method_name, arg1, arg2;
8312 {
8313   tree args, cn, access;
8314
8315   args = arg1 ? arg1 : 
8316     build_wfl_node (build_current_thisn (current_class));
8317   args = build_tree_list (NULL_TREE, args);
8318
8319   if (arg2)
8320     args = tree_cons (NULL_TREE, arg2, args);
8321
8322   access = build_method_invocation (build_wfl_node (access_method_name), args);
8323   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
8324   return make_qualified_primary (cn, access, lc);
8325 }
8326
8327 static tree
8328 build_new_access_id ()
8329 {
8330   static int access_n_counter = 1;
8331   char buffer [128];
8332
8333   sprintf (buffer, "access$%d", access_n_counter++);
8334   return get_identifier (buffer);
8335 }
8336
8337 /* Create the static access functions for the outer field DECL. We define a
8338    read:
8339      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
8340        return inst$.field;
8341      }
8342    and a write access:
8343      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
8344                                      TREE_TYPE (<field>) value$) {
8345        return inst$.field = value$;
8346      }
8347    We should have a usage flags on the DECL so we can lazily turn the ones
8348    we're using for code generation. FIXME.
8349 */
8350
8351 static tree
8352 build_outer_field_access_methods (decl)
8353     tree decl;
8354 {
8355   tree id, args, stmt, mdecl;
8356   
8357   if (FIELD_INNER_ACCESS_P (decl))
8358     return FIELD_INNER_ACCESS (decl);
8359
8360   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
8361  
8362   /* Create the identifier and a function named after it. */
8363   id = build_new_access_id ();
8364
8365   /* The identifier is marked as bearing the name of a generated write
8366      access function for outer field accessed from inner classes. */
8367   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8368
8369   /* Create the read access */
8370   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
8371   TREE_CHAIN (args) = end_params_node;
8372   stmt = make_qualified_primary (build_wfl_node (inst_id),
8373                                  build_wfl_node (DECL_NAME (decl)), 0);
8374   stmt = build_return (0, stmt);
8375   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8376                                            TREE_TYPE (decl), id, args, stmt);
8377   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8378
8379   /* Create the write access method. No write access for final variable */
8380   if (!FIELD_FINAL (decl))
8381     {
8382       args = build_tree_list (inst_id, 
8383                               build_pointer_type (DECL_CONTEXT (decl)));
8384       TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
8385       TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
8386       stmt = make_qualified_primary (build_wfl_node (inst_id),
8387                                      build_wfl_node (DECL_NAME (decl)), 0);
8388       stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
8389                                                 build_wfl_node (wpv_id)));
8390       mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8391                                                TREE_TYPE (decl), id, 
8392                                                args, stmt);
8393     }
8394   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8395
8396   /* Return the access name */
8397   return FIELD_INNER_ACCESS (decl) = id;
8398 }
8399
8400 /* Build an field access method NAME.  */
8401
8402 static tree 
8403 build_outer_field_access_method (class, type, name, args, body)
8404     tree class, type, name, args, body;
8405 {
8406   tree saved_current_function_decl, mdecl;
8407
8408   /* Create the method */
8409   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
8410   fix_method_argument_names (args, mdecl);
8411   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8412
8413   /* Attach the method body. */
8414   saved_current_function_decl = current_function_decl;
8415   start_artificial_method_body (mdecl);
8416   java_method_add_stmt (mdecl, body);
8417   end_artificial_method_body (mdecl);
8418   current_function_decl = saved_current_function_decl;
8419
8420   return mdecl;
8421 }
8422
8423 \f
8424 /* This section deals with building access function necessary for
8425    certain kinds of method invocation from inner classes.  */
8426
8427 static tree
8428 build_outer_method_access_method (decl)
8429     tree decl;
8430 {
8431   tree saved_current_function_decl, mdecl;
8432   tree args = NULL_TREE, call_args = NULL_TREE;
8433   tree carg, id, body, class;
8434   char buffer [80];
8435   int parm_id_count = 0;
8436
8437   /* Test this abort with an access to a private field */
8438   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
8439     abort ();
8440
8441   /* Check the cache first */
8442   if (DECL_FUNCTION_INNER_ACCESS (decl))
8443     return DECL_FUNCTION_INNER_ACCESS (decl);
8444
8445   class = DECL_CONTEXT (decl);
8446
8447   /* Obtain an access identifier and mark it */
8448   id = build_new_access_id ();
8449   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8450
8451   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
8452   /* Create the arguments, as much as the original */
8453   for (; carg && carg != end_params_node; 
8454        carg = TREE_CHAIN (carg))
8455     {
8456       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
8457       args = chainon (args, build_tree_list (get_identifier (buffer), 
8458                                              TREE_VALUE (carg)));
8459     }
8460   args = chainon (args, end_params_node);
8461
8462   /* Create the method */
8463   mdecl = create_artificial_method (class, ACC_STATIC, 
8464                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
8465   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8466   /* There is a potential bug here. We should be able to use
8467      fix_method_argument_names, but then arg names get mixed up and
8468      eventually a constructor will have its this$0 altered and the
8469      outer context won't be assignment properly. The test case is
8470      stub.java FIXME */
8471   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
8472
8473   /* Attach the method body. */
8474   saved_current_function_decl = current_function_decl;
8475   start_artificial_method_body (mdecl);
8476
8477   /* The actual method invocation uses the same args. When invoking a
8478      static methods that way, we don't want to skip the first
8479      argument. */
8480   carg = args;
8481   if (!METHOD_STATIC (decl))
8482     carg = TREE_CHAIN (carg);
8483   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
8484     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
8485                            call_args);
8486
8487   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
8488                                   call_args);
8489   if (!METHOD_STATIC (decl))
8490     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
8491                                    body, 0);
8492   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
8493     body = build_return (0, body);
8494   java_method_add_stmt (mdecl,body);
8495   end_artificial_method_body (mdecl);
8496   current_function_decl = saved_current_function_decl;
8497
8498   /* Back tag the access function so it know what it accesses */
8499   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
8500
8501   /* Tag the current method so it knows it has an access generated */
8502   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
8503 }
8504
8505 \f
8506 /* This section of the code deals with building expressions to access
8507    the enclosing instance of an inner class. The enclosing instance is
8508    kept in a generated field called this$<n>, with <n> being the
8509    inner class nesting level (starting from 0.)  */
8510     
8511 /* Build an access to a given this$<n>, always chaining access call to
8512    others. Access methods to this$<n> are build on the fly if
8513    necessary. This CAN'T be used to solely access this$<n-1> from
8514    this$<n> (which alway yield to special cases and optimization, see
8515    for example build_outer_field_access).  */
8516
8517 static tree
8518 build_access_to_thisn (from, to, lc)
8519      tree from, to;
8520      int lc;
8521 {
8522   tree access = NULL_TREE;
8523
8524   while (from != to && PURE_INNER_CLASS_TYPE_P (from))
8525     {
8526       if (!access)
8527         {
8528           access = build_current_thisn (from);
8529           access = build_wfl_node (access);
8530         }
8531       else
8532         {
8533           tree access0_wfl, cn;
8534
8535           maybe_build_thisn_access_method (from);
8536           access0_wfl = build_wfl_node (access0_identifier_node);
8537           cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
8538           EXPR_WFL_LINECOL (access0_wfl) = lc;
8539           access = build_tree_list (NULL_TREE, access);
8540           access = build_method_invocation (access0_wfl, access);
8541           access = make_qualified_primary (cn, access, lc);
8542         }
8543
8544       /* If FROM isn't an inner class, that's fine, we've done enough.
8545          What we're looking for can be accessed from there.  */
8546       from = DECL_CONTEXT (TYPE_NAME (from));
8547       if (!from)
8548         break;
8549       from = TREE_TYPE (from);
8550     }
8551   return access;
8552 }
8553
8554 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
8555    is returned if nothing needs to be generated. Otherwise, the method
8556    generated and a method decl is returned.  
8557
8558    NOTE: These generated methods should be declared in a class file
8559    attribute so that they can't be referred to directly.  */
8560
8561 static tree
8562 maybe_build_thisn_access_method (type)
8563     tree type;
8564 {
8565   tree mdecl, args, stmt, rtype;
8566   tree saved_current_function_decl;
8567
8568   /* If TYPE is a top-level class, no access method is required.
8569      If there already is such an access method, bail out. */
8570   if (CLASS_ACCESS0_GENERATED_P (type) || !PURE_INNER_CLASS_TYPE_P (type))
8571     return NULL_TREE;
8572
8573   /* We generate the method. The method looks like:
8574      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
8575   */
8576   args = build_tree_list (inst_id, build_pointer_type (type));
8577   TREE_CHAIN (args) = end_params_node;
8578   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
8579   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
8580                                     access0_identifier_node, args);
8581   fix_method_argument_names (args, mdecl);
8582   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
8583   stmt = build_current_thisn (type);
8584   stmt = make_qualified_primary (build_wfl_node (inst_id), 
8585                                  build_wfl_node (stmt), 0);
8586   stmt = build_return (0, stmt);
8587
8588   saved_current_function_decl = current_function_decl;
8589   start_artificial_method_body (mdecl);
8590   java_method_add_stmt (mdecl, stmt);
8591   end_artificial_method_body (mdecl);
8592   current_function_decl = saved_current_function_decl;
8593
8594   CLASS_ACCESS0_GENERATED_P (type) = 1;
8595
8596   return mdecl;
8597 }
8598
8599 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
8600    the first level of innerclassing. this$1 for the next one, etc...
8601    This function can be invoked with TYPE to NULL, available and then
8602    has to count the parser context.  */
8603
8604 static GTY(()) tree saved_thisn;
8605 static GTY(()) tree saved_type;
8606
8607 static tree
8608 build_current_thisn (type)
8609     tree type;
8610 {
8611   static int saved_i = -1;
8612   static int saved_type_i = 0;
8613   tree decl;
8614   char buffer [24];
8615   int i = 0;
8616
8617   if (type)
8618     {
8619       if (type == saved_type)
8620         i = saved_type_i;
8621       else
8622         {
8623           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
8624                decl; decl = DECL_CONTEXT (decl), i++)
8625             ;
8626       
8627           saved_type = type;
8628           saved_type_i = i;
8629         }
8630     }
8631   else
8632     i = list_length (GET_CPC_LIST ())-2;
8633
8634   if (i == saved_i)
8635     return saved_thisn;
8636     
8637   sprintf (buffer, "this$%d", i);
8638   saved_i = i;
8639   saved_thisn = get_identifier (buffer);
8640   return saved_thisn;
8641 }
8642
8643 /* Return the assignement to the hidden enclosing context `this$<n>'
8644    by the second incoming parameter to the innerclass constructor. The
8645    form used is `this.this$<n> = this$<n>;'.  */
8646
8647 static tree
8648 build_thisn_assign ()
8649 {
8650   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
8651     {
8652       tree thisn = build_current_thisn (current_class);
8653       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
8654                                          build_wfl_node (thisn), 0);
8655       tree rhs = build_wfl_node (thisn);
8656       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
8657       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
8658     }
8659   return NULL_TREE;
8660 }
8661
8662 \f
8663 /* Building the synthetic `class$' used to implement the `.class' 1.1
8664    extension for non primitive types. This method looks like:
8665
8666     static Class class$(String type) throws NoClassDefFoundError
8667     {
8668       try {return (java.lang.Class.forName (String));}
8669       catch (ClassNotFoundException e) {
8670         throw new NoClassDefFoundError(e.getMessage());}
8671     } */
8672
8673 static GTY(()) tree get_message_wfl;
8674 static GTY(()) tree type_parm_wfl;
8675
8676 static tree
8677 build_dot_class_method (class)
8678      tree class;
8679 {
8680 #define BWF(S) build_wfl_node (get_identifier ((S)))
8681 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8682   tree args, tmp, saved_current_function_decl, mdecl;
8683   tree stmt, throw_stmt;
8684
8685   if (!get_message_wfl)
8686     {
8687       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8688       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8689     }
8690
8691   /* Build the arguments */
8692   args = build_tree_list (get_identifier ("type$"),
8693                           build_pointer_type (string_type_node));
8694   TREE_CHAIN (args) = end_params_node;
8695
8696   /* Build the qualified name java.lang.Class.forName */
8697   tmp = MQN (MQN (MQN (BWF ("java"), 
8698                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8699   load_class (class_not_found_type_node, 1);
8700   load_class (no_class_def_found_type_node, 1);
8701   
8702   /* Create the "class$" function */
8703   mdecl = create_artificial_method (class, ACC_STATIC, 
8704                                     build_pointer_type (class_type_node),
8705                                     classdollar_identifier_node, args);
8706   DECL_FUNCTION_THROWS (mdecl) = 
8707     build_tree_list (NULL_TREE, no_class_def_found_type_node);
8708
8709   /* We start by building the try block. We need to build:
8710        return (java.lang.Class.forName (type)); */
8711   stmt = build_method_invocation (tmp, 
8712                                   build_tree_list (NULL_TREE, type_parm_wfl));
8713   stmt = build_return (0, stmt);
8714
8715   /* Now onto the catch block. We start by building the expression
8716      throwing a new exception: throw new NoClassDefFoundError (_.getMessage) */
8717   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8718                                     get_message_wfl, 0);
8719   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8720   
8721   /* Build new NoClassDefFoundError (_.getMessage) */
8722   throw_stmt = build_new_invocation 
8723     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8724      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8725
8726   /* Build the throw, (it's too early to use BUILD_THROW) */
8727   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8728
8729   /* Encapsulate STMT in a try block. The catch clause executes THROW_STMT */
8730   stmt = encapsulate_with_try_catch (0, class_not_found_type_node,
8731                                      stmt, throw_stmt);
8732
8733   fix_method_argument_names (args, mdecl);
8734   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8735   saved_current_function_decl = current_function_decl;
8736   start_artificial_method_body (mdecl);
8737   java_method_add_stmt (mdecl, stmt);
8738   end_artificial_method_body (mdecl);
8739   current_function_decl = saved_current_function_decl;
8740   TYPE_DOT_CLASS (class) = mdecl;
8741
8742   return mdecl;
8743 }
8744
8745 static tree
8746 build_dot_class_method_invocation (type)
8747      tree type;
8748 {
8749   tree sig_id, s;
8750
8751   if (TYPE_ARRAY_P (type))
8752     sig_id = build_java_signature (type);
8753   else
8754     sig_id = DECL_NAME (TYPE_NAME (type));
8755
8756   /* Ensure that the proper name separator is used */
8757   sig_id = unmangle_classname (IDENTIFIER_POINTER (sig_id),
8758                                IDENTIFIER_LENGTH (sig_id));
8759
8760   s = build_string (IDENTIFIER_LENGTH (sig_id), 
8761                     IDENTIFIER_POINTER (sig_id));
8762   return build_method_invocation (build_wfl_node (classdollar_identifier_node),
8763                                   build_tree_list (NULL_TREE, s));
8764 }
8765
8766 /* This section of the code deals with constructor.  */
8767
8768 /* Craft a body for default constructor. Patch existing constructor
8769    bodies with call to super() and field initialization statements if
8770    necessary.  */
8771
8772 static void
8773 fix_constructors (mdecl)
8774      tree mdecl;
8775 {
8776   tree iii;                     /* Instance Initializer Invocation */
8777   tree body = DECL_FUNCTION_BODY (mdecl);
8778   tree thisn_assign, compound = NULL_TREE;
8779   tree class_type = DECL_CONTEXT (mdecl);
8780
8781   if (DECL_FIXED_CONSTRUCTOR_P (mdecl))
8782     return;
8783   DECL_FIXED_CONSTRUCTOR_P (mdecl) = 1;
8784
8785   if (!body)
8786     {
8787       /* It is an error for the compiler to generate a default
8788          constructor if the superclass doesn't have a constructor that
8789          takes no argument, or the same args for an anonymous class */
8790       if (verify_constructor_super (mdecl))
8791         {
8792           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8793           tree save = DECL_NAME (mdecl);
8794           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8795           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8796           parse_error_context
8797             (lookup_cl (TYPE_NAME (class_type)), 
8798              "No constructor matching `%s' found in class `%s'",
8799              lang_printable_name (mdecl, 0), n);
8800           DECL_NAME (mdecl) = save;
8801         }
8802       
8803       /* The constructor body must be crafted by hand. It's the
8804          constructor we defined when we realize we didn't have the
8805          CLASSNAME() constructor */
8806       start_artificial_method_body (mdecl);
8807       
8808       /* Insert an assignment to the this$<n> hidden field, if
8809          necessary */
8810       if ((thisn_assign = build_thisn_assign ()))
8811         java_method_add_stmt (mdecl, thisn_assign);
8812
8813       /* We don't generate a super constructor invocation if we're
8814          compiling java.lang.Object. build_super_invocation takes care
8815          of that. */
8816       java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8817
8818       /* FIXME */
8819       if ((iii = build_instinit_invocation (class_type)))
8820         java_method_add_stmt (mdecl, iii);
8821
8822       end_artificial_method_body (mdecl);
8823     }
8824   /* Search for an explicit constructor invocation */
8825   else 
8826     {
8827       int found = 0;
8828       int invokes_this = 0;
8829       tree found_call = NULL_TREE;
8830       tree main_block = BLOCK_EXPR_BODY (body);
8831       
8832       while (body)
8833         switch (TREE_CODE (body))
8834           {
8835           case CALL_EXPR:
8836             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8837             if (CALL_THIS_CONSTRUCTOR_P (body))
8838               invokes_this = 1;
8839             body = NULL_TREE;
8840             break;
8841           case COMPOUND_EXPR:
8842           case EXPR_WITH_FILE_LOCATION:
8843             found_call = body;
8844             body = TREE_OPERAND (body, 0);
8845             break;
8846           case BLOCK:
8847             found_call = body;
8848             body = BLOCK_EXPR_BODY (body);
8849             break;
8850           default:
8851             found = 0;
8852             body = NULL_TREE;
8853           }
8854
8855       /* Generate the assignment to this$<n>, if necessary */
8856       if ((thisn_assign = build_thisn_assign ()))
8857         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8858
8859       /* The constructor is missing an invocation of super() */
8860       if (!found)
8861         compound = add_stmt_to_compound (compound, NULL_TREE,
8862                                          build_super_invocation (mdecl));
8863       /* Explicit super() invokation should take place before the
8864          instance initializer blocks. */
8865       else
8866         {
8867           compound = add_stmt_to_compound (compound, NULL_TREE,
8868                                            TREE_OPERAND (found_call, 0));
8869           TREE_OPERAND (found_call, 0) = empty_stmt_node;
8870         }
8871       
8872       DECL_INIT_CALLS_THIS (mdecl) = invokes_this;
8873
8874       /* Insert the instance initializer block right after. */
8875       if (!invokes_this && (iii = build_instinit_invocation (class_type)))
8876         compound = add_stmt_to_compound (compound, NULL_TREE, iii);
8877
8878       /* Fix the constructor main block if we're adding extra stmts */
8879       if (compound)
8880         {
8881           compound = add_stmt_to_compound (compound, NULL_TREE,
8882                                            BLOCK_EXPR_BODY (main_block));
8883           BLOCK_EXPR_BODY (main_block) = compound;
8884         }
8885     }
8886 }
8887
8888 /* Browse constructors in the super class, searching for a constructor
8889    that doesn't take any argument. Return 0 if one is found, 1
8890    otherwise.  If the current class is an anonymous inner class, look
8891    for something that has the same signature. */
8892
8893 static int
8894 verify_constructor_super (mdecl)
8895      tree mdecl;
8896 {
8897   tree class = CLASSTYPE_SUPER (current_class);
8898   int super_inner = PURE_INNER_CLASS_TYPE_P (class);
8899   tree sdecl;
8900
8901   if (!class)
8902     return 0;
8903
8904   if (ANONYMOUS_CLASS_P (current_class))
8905     {
8906       tree mdecl_arg_type;
8907       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8908       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8909         if (DECL_CONSTRUCTOR_P (sdecl))
8910           {
8911             tree m_arg_type;
8912             tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8913             if (super_inner)
8914               arg_type = TREE_CHAIN (arg_type);
8915             for (m_arg_type = mdecl_arg_type; 
8916                  (arg_type != end_params_node 
8917                   && m_arg_type != end_params_node);
8918                  arg_type = TREE_CHAIN (arg_type), 
8919                    m_arg_type = TREE_CHAIN (m_arg_type))
8920               if (!valid_method_invocation_conversion_p 
8921                      (TREE_VALUE (arg_type),
8922                       TREE_VALUE (m_arg_type)))
8923                 break;
8924
8925             if (arg_type == end_params_node && m_arg_type == end_params_node)
8926               return 0;
8927           }
8928     }
8929   else
8930     {
8931       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8932         {
8933           tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8934           if (super_inner)
8935             arg = TREE_CHAIN (arg);
8936           if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
8937             return 0;
8938         }
8939     }
8940   return 1;
8941 }
8942
8943 /* Generate code for all context remembered for code generation.  */
8944
8945 static GTY(()) tree reversed_class_list;
8946 void
8947 java_expand_classes ()
8948 {
8949   int save_error_count = 0;
8950   static struct parser_ctxt *cur_ctxp = NULL;
8951
8952   java_parse_abort_on_error ();
8953   if (!(ctxp = ctxp_for_generation))
8954     return;
8955   java_layout_classes ();
8956   java_parse_abort_on_error ();
8957
8958   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
8959     {
8960       ctxp = cur_ctxp;
8961       input_filename = ctxp->filename;
8962       lang_init_source (2);            /* Error msgs have method prototypes */
8963       java_complete_expand_classes (); /* Complete and expand classes */
8964       java_parse_abort_on_error ();
8965     }
8966   input_filename = main_input_filename;
8967
8968
8969   /* Find anonymous classes and expand their constructor. This extra pass is
8970      neccessary because the constructor itself is only generated when the
8971      method in which it is defined is expanded. */
8972   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
8973     {
8974       tree current;
8975       ctxp = cur_ctxp;
8976       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8977         {
8978           current_class = TREE_TYPE (current);
8979           if (ANONYMOUS_CLASS_P (current_class))
8980             {
8981               tree d;
8982               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8983                 {
8984                   if (DECL_CONSTRUCTOR_P (d))
8985                     {
8986                       restore_line_number_status (1);
8987                       java_complete_expand_method (d);
8988                       restore_line_number_status (0);
8989                       break;    /* There is only one constructor. */
8990                     }
8991                 }
8992             }
8993         }
8994     }
8995
8996   /* If we've found error at that stage, don't try to generate
8997      anything, unless we're emitting xrefs or checking the syntax only
8998      (but not using -fsyntax-only for the purpose of generating
8999      bytecode. */
9000   if (java_error_count && !flag_emit_xref 
9001       && (!flag_syntax_only && !flag_emit_class_files))
9002     return;
9003
9004   /* Now things are stable, go for generation of the class data. */
9005
9006   /* We pessimistically marked all fields external until we knew
9007      what set of classes we were planning to compile.  Now mark
9008      those that will be generated locally as not external.  */
9009   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
9010     {
9011       tree current;
9012       ctxp = cur_ctxp;
9013       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
9014         {
9015           tree class = TREE_TYPE (current);
9016           tree field;
9017           for (field = TYPE_FIELDS (class); field ; field = TREE_CHAIN (field))
9018             if (FIELD_STATIC (field))
9019               DECL_EXTERNAL (field) = 0;
9020         }
9021     }
9022
9023   /* Compile the classes.  */
9024   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
9025     {
9026       tree current;
9027       reversed_class_list = NULL;
9028
9029       ctxp = cur_ctxp;
9030
9031       /* We write out the classes in reverse order.  This ensures that
9032          inner classes are written before their containing classes,
9033          which is important for parallel builds.  Otherwise, the
9034          class file for the outer class may be found, but the class
9035          file for the inner class may not be present.  In that
9036          situation, the compiler cannot fall back to the original
9037          source, having already read the outer class, so we must
9038          prevent that situation.  */
9039       for (current = ctxp->class_list; 
9040            current; 
9041            current = TREE_CHAIN (current))
9042         reversed_class_list
9043           = tree_cons (NULL_TREE, current, reversed_class_list);
9044
9045       for (current = reversed_class_list; 
9046            current; 
9047            current = TREE_CHAIN (current))
9048         {
9049           current_class = TREE_TYPE (TREE_VALUE (current));
9050           outgoing_cpool = TYPE_CPOOL (current_class);
9051           if (flag_emit_class_files)
9052             write_classfile (current_class);
9053           if (flag_emit_xref)
9054             expand_xref (current_class);
9055           else if (! flag_syntax_only)
9056             {
9057               java_expand_method_bodies (current_class);
9058               finish_class ();
9059             }
9060         }
9061     }
9062 }
9063
9064 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
9065    a tree list node containing RIGHT. Fore coming RIGHTs will be
9066    chained to this hook. LOCATION contains the location of the
9067    separating `.' operator.  */
9068
9069 static tree
9070 make_qualified_primary (primary, right, location)
9071      tree primary, right;
9072      int location;
9073 {
9074   tree wfl;
9075
9076   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
9077     wfl = build_wfl_wrap (primary, location);
9078   else
9079     {
9080       wfl = primary;
9081       /* If wfl wasn't qualified, we build a first anchor */
9082       if (!EXPR_WFL_QUALIFICATION (wfl))
9083         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
9084     }
9085
9086   /* And chain them */
9087   EXPR_WFL_LINECOL (right) = location;
9088   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
9089   PRIMARY_P (wfl) =  1;
9090   return wfl;
9091 }
9092
9093 /* Simple merge of two name separated by a `.' */
9094
9095 static tree
9096 merge_qualified_name (left, right)
9097      tree left, right;
9098 {
9099   tree node;
9100   if (!left && !right)
9101     return NULL_TREE;
9102
9103   if (!left)
9104     return right;
9105
9106   if (!right)
9107     return left;
9108
9109   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
9110                 IDENTIFIER_LENGTH (left));
9111   obstack_1grow (&temporary_obstack, '.');
9112   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
9113                  IDENTIFIER_LENGTH (right));
9114   node =  get_identifier (obstack_base (&temporary_obstack));
9115   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
9116   QUALIFIED_P (node) = 1;
9117   return node;
9118 }
9119
9120 /* Merge the two parts of a qualified name into LEFT.  Set the
9121    location information of the resulting node to LOCATION, usually
9122    inherited from the location information of the `.' operator. */
9123
9124 static tree
9125 make_qualified_name (left, right, location)
9126      tree left, right;
9127      int location;
9128 {
9129 #ifdef USE_COMPONENT_REF
9130   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
9131   EXPR_WFL_LINECOL (node) = location;
9132   return node;
9133 #else
9134   tree left_id = EXPR_WFL_NODE (left);
9135   tree right_id = EXPR_WFL_NODE (right);
9136   tree wfl, merge;
9137
9138   merge = merge_qualified_name (left_id, right_id);
9139
9140   /* Left wasn't qualified and is now qualified */
9141   if (!QUALIFIED_P (left_id))
9142     {
9143       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
9144       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
9145       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
9146     }
9147   
9148   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
9149   EXPR_WFL_LINECOL (wfl) = location;
9150   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
9151
9152   EXPR_WFL_NODE (left) = merge;
9153   return left;
9154 #endif
9155 }
9156
9157 /* Extract the last identifier component of the qualified in WFL. The
9158    last identifier is removed from the linked list */
9159
9160 static tree
9161 cut_identifier_in_qualified (wfl)
9162      tree wfl;
9163 {
9164   tree q;
9165   tree previous = NULL_TREE;
9166   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
9167     if (!TREE_CHAIN (q))
9168       {
9169         if (!previous)
9170           /* Operating on a non qualified qualified WFL.  */
9171           abort ();
9172
9173         TREE_CHAIN (previous) = NULL_TREE;
9174         return TREE_PURPOSE (q);
9175       }
9176 }
9177
9178 /* Resolve the expression name NAME. Return its decl.  */
9179
9180 static tree
9181 resolve_expression_name (id, orig)
9182      tree id;
9183      tree *orig;
9184 {
9185   tree name = EXPR_WFL_NODE (id);
9186   tree decl;
9187
9188   /* 6.5.5.1: Simple expression names */
9189   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
9190     {
9191       /* 15.13.1: NAME can appear within the scope of a local variable
9192          declaration */
9193       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
9194         return decl;
9195
9196       /* 15.13.1: NAME can appear within a class declaration */
9197       else 
9198         {
9199           decl = lookup_field_wrapper (current_class, name);
9200           if (decl)
9201             {
9202               tree access = NULL_TREE;
9203               int fs = FIELD_STATIC (decl);
9204
9205               /* If we're accessing an outer scope local alias, make
9206                  sure we change the name of the field we're going to
9207                  build access to. */
9208               if (FIELD_LOCAL_ALIAS_USED (decl))
9209                 name = DECL_NAME (decl);
9210
9211               /* Instance variable (8.3.1.1) can't appear within
9212                  static method, static initializer or initializer for
9213                  a static variable. */
9214               if (!fs && METHOD_STATIC (current_function_decl))
9215                 {
9216                   static_ref_err (id, name, current_class);
9217                   return error_mark_node;
9218                 }
9219               /* Instance variables can't appear as an argument of
9220                  an explicit constructor invocation */
9221               if (!fs && ctxp->explicit_constructor_p
9222                   && !enclosing_context_p (DECL_CONTEXT (decl), current_class))
9223                 {
9224                   parse_error_context
9225                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
9226                   return error_mark_node;
9227                 }
9228
9229               /* If we're processing an inner class and we're trying
9230                  to access a field belonging to an outer class, build
9231                  the access to the field */
9232               if (!fs && outer_field_access_p (current_class, decl))
9233                 {
9234                   if (CLASS_STATIC (TYPE_NAME (current_class)))
9235                     {
9236                       static_ref_err (id, DECL_NAME (decl), current_class);
9237                       return error_mark_node;
9238                     }
9239                   access = build_outer_field_access (id, decl);
9240                   if (orig)
9241                     *orig = access;
9242                   return access;
9243                 }
9244
9245               /* Otherwise build what it takes to access the field */
9246               access = build_field_ref ((fs ? NULL_TREE : current_this),
9247                                         DECL_CONTEXT (decl), name);
9248               if (fs)
9249                 access = maybe_build_class_init_for_field (decl, access);
9250               /* We may be asked to save the real field access node */
9251               if (orig)
9252                 *orig = access;
9253               /* And we return what we got */
9254               return access;
9255             }
9256           /* Fall down to error report on undefined variable */
9257         }
9258     }
9259   /* 6.5.5.2 Qualified Expression Names */
9260   else
9261     {
9262       if (orig)
9263         *orig = NULL_TREE;
9264       qualify_ambiguous_name (id);
9265       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
9266       /* 15.10.2: Accessing Superclass Members using super */
9267       return resolve_field_access (id, orig, NULL);
9268     }
9269
9270   /* We've got an error here */
9271   if (INNER_CLASS_TYPE_P (current_class))
9272     parse_error_context (id, 
9273                          "Local variable `%s' can't be accessed from within the inner class `%s' unless it is declared final",
9274                          IDENTIFIER_POINTER (name),
9275                          IDENTIFIER_POINTER (DECL_NAME
9276                                              (TYPE_NAME (current_class))));
9277   else
9278     parse_error_context (id, "Undefined variable `%s'", 
9279                          IDENTIFIER_POINTER (name));
9280
9281   return error_mark_node;
9282 }
9283
9284 static void
9285 static_ref_err (wfl, field_id, class_type)
9286     tree wfl, field_id, class_type;
9287 {
9288   parse_error_context 
9289     (wfl, 
9290      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
9291      IDENTIFIER_POINTER (field_id), 
9292      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
9293 }
9294
9295 /* 15.10.1 Field Access Using a Primary and/or Expression Name.
9296    We return something suitable to generate the field access. We also
9297    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
9298    recipient's address can be null. */
9299
9300 static tree
9301 resolve_field_access (qual_wfl, field_decl, field_type)
9302      tree qual_wfl;
9303      tree *field_decl, *field_type;
9304 {
9305   int is_static = 0;
9306   tree field_ref;
9307   tree decl, where_found, type_found;
9308
9309   if (resolve_qualified_expression_name (qual_wfl, &decl,
9310                                          &where_found, &type_found))
9311     return error_mark_node;
9312
9313   /* Resolve the LENGTH field of an array here */
9314   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
9315       && type_found && TYPE_ARRAY_P (type_found) 
9316       && ! flag_emit_class_files && ! flag_emit_xref)
9317     {
9318       tree length = build_java_array_length_access (where_found);
9319       field_ref = length;
9320
9321       /* In case we're dealing with a static array, we need to
9322          initialize its class before the array length can be fetched.
9323          It's also a good time to create a DECL_RTL for the field if
9324          none already exists, otherwise if the field was declared in a
9325          class found in an external file and hasn't been (and won't
9326          be) accessed for its value, none will be created. */
9327       if (TREE_CODE (where_found) == VAR_DECL && FIELD_STATIC (where_found))
9328         {
9329           build_static_field_ref (where_found);
9330           field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
9331         }
9332     }
9333   /* We might have been trying to resolve field.method(). In which
9334      case, the resolution is over and decl is the answer */
9335   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
9336     field_ref = decl;
9337   else if (JDECL_P (decl))
9338     {
9339       if (!type_found)
9340         type_found = DECL_CONTEXT (decl);
9341       is_static = FIELD_STATIC (decl);
9342       field_ref = build_field_ref ((is_static && !flag_emit_xref? 
9343                                     NULL_TREE : where_found), 
9344                                    type_found, DECL_NAME (decl));
9345       if (field_ref == error_mark_node)
9346         return error_mark_node;
9347       if (is_static)
9348         field_ref = maybe_build_class_init_for_field (decl, field_ref);
9349     }
9350   else
9351     field_ref = decl;
9352
9353   if (field_decl)
9354     *field_decl = decl;
9355   if (field_type)
9356     *field_type = (QUAL_DECL_TYPE (decl) ? 
9357                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
9358   return field_ref;
9359 }
9360
9361 /* If NODE is an access to f static field, strip out the class
9362    initialization part and return the field decl, otherwise, return
9363    NODE. */
9364
9365 static tree
9366 strip_out_static_field_access_decl (node)
9367     tree node;
9368 {
9369   if (TREE_CODE (node) == COMPOUND_EXPR)
9370     {
9371       tree op1 = TREE_OPERAND (node, 1);
9372       if (TREE_CODE (op1) == COMPOUND_EXPR)
9373          {
9374            tree call = TREE_OPERAND (op1, 0);
9375            if (TREE_CODE (call) == CALL_EXPR
9376                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
9377                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
9378                == soft_initclass_node)
9379              return TREE_OPERAND (op1, 1);
9380          }
9381       else if (JDECL_P (op1))
9382         return op1;
9383     }
9384   return node;
9385 }
9386
9387 /* 6.5.5.2: Qualified Expression Names */
9388
9389 static int
9390 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
9391      tree wfl;
9392      tree *found_decl, *type_found, *where_found;
9393 {
9394   int from_type = 0;            /* Field search initiated from a type */
9395   int from_super = 0, from_cast = 0, from_qualified_this = 0;
9396   int previous_call_static = 0;
9397   int is_static;
9398   tree decl = NULL_TREE, type = NULL_TREE, q;
9399   /* For certain for of inner class instantiation */
9400   tree saved_current, saved_this;               
9401 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
9402   { current_class = saved_current; current_this = saved_this;}
9403
9404   *type_found = *where_found = NULL_TREE;
9405
9406   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
9407     {
9408       tree qual_wfl = QUAL_WFL (q);
9409       tree ret_decl;            /* for EH checking */
9410       int location;             /* for EH checking */
9411
9412       /* 15.10.1 Field Access Using a Primary */
9413       switch (TREE_CODE (qual_wfl))
9414         {
9415         case CALL_EXPR:
9416         case NEW_CLASS_EXPR:
9417           /* If the access to the function call is a non static field,
9418              build the code to access it. */
9419           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9420             {
9421               decl = maybe_access_field (decl, *where_found, 
9422                                          DECL_CONTEXT (decl));
9423               if (decl == error_mark_node)
9424                 return 1;
9425             }
9426
9427           /* And code for the function call */
9428           if (complete_function_arguments (qual_wfl))
9429             return 1;
9430
9431           /* We might have to setup a new current class and a new this
9432              for the search of an inner class, relative to the type of
9433              a expression resolved as `decl'. The current values are
9434              saved and restored shortly after */
9435           saved_current = current_class;
9436           saved_this = current_this;
9437           if (decl 
9438               && (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9439                   || from_qualified_this))
9440             {
9441               /* If we still have `from_qualified_this', we have the form
9442                  <T>.this.f() and we need to build <T>.this */
9443               if (from_qualified_this)
9444                 {
9445                   decl = build_access_to_thisn (current_class, type, 0);
9446                   decl = java_complete_tree (decl);
9447                   type = TREE_TYPE (TREE_TYPE (decl));
9448                 }
9449               current_class = type;
9450               current_this = decl;
9451               from_qualified_this = 0;
9452             }
9453
9454           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
9455             CALL_USING_SUPER (qual_wfl) = 1;
9456           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
9457                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
9458           *where_found = patch_method_invocation (qual_wfl, decl, type,
9459                                                   from_super,
9460                                                   &is_static, &ret_decl);
9461           from_super = 0;
9462           if (*where_found == error_mark_node)
9463             {
9464               RESTORE_THIS_AND_CURRENT_CLASS;
9465               return 1;
9466             }
9467           *type_found = type = QUAL_DECL_TYPE (*where_found);
9468
9469           /* If we're creating an inner class instance, check for that
9470              an enclosing instance is in scope */
9471           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9472               && INNER_ENCLOSING_SCOPE_CHECK (type))
9473             {
9474               parse_error_context 
9475                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
9476                  lang_printable_name (type, 0),
9477                  (!current_this ? "" :
9478                   "; an explicit one must be provided when creating this inner class"));
9479               RESTORE_THIS_AND_CURRENT_CLASS;
9480               return 1;
9481             }
9482
9483           /* In case we had to change then to resolve a inner class
9484              instantiation using a primary qualified by a `new' */
9485           RESTORE_THIS_AND_CURRENT_CLASS;
9486
9487           /* EH check. No check on access$<n> functions */
9488           if (location 
9489               && !OUTER_FIELD_ACCESS_IDENTIFIER_P 
9490                     (DECL_NAME (current_function_decl)))
9491             check_thrown_exceptions (location, ret_decl);
9492
9493           /* If the previous call was static and this one is too,
9494              build a compound expression to hold the two (because in
9495              that case, previous function calls aren't transported as
9496              forcoming function's argument. */
9497           if (previous_call_static && is_static)
9498             {
9499               decl = build (COMPOUND_EXPR, TREE_TYPE (*where_found),
9500                             decl, *where_found);
9501               TREE_SIDE_EFFECTS (decl) = 1;
9502             }
9503           else
9504             {
9505               previous_call_static = is_static;
9506               decl = *where_found;
9507             }
9508           from_type = 0;
9509           continue;
9510
9511         case NEW_ARRAY_EXPR:
9512         case NEW_ANONYMOUS_ARRAY_EXPR:
9513           *where_found = decl = java_complete_tree (qual_wfl);
9514           if (decl == error_mark_node)
9515             return 1;
9516           *type_found = type = QUAL_DECL_TYPE (decl);
9517           continue;
9518
9519         case CONVERT_EXPR:
9520           *where_found = decl = java_complete_tree (qual_wfl);
9521           if (decl == error_mark_node)
9522             return 1;
9523           *type_found = type = QUAL_DECL_TYPE (decl);
9524           from_cast = 1;
9525           continue;
9526
9527         case CONDITIONAL_EXPR:
9528         case STRING_CST:
9529         case MODIFY_EXPR:
9530           *where_found = decl = java_complete_tree (qual_wfl);
9531           if (decl == error_mark_node)
9532             return 1;
9533           *type_found = type = QUAL_DECL_TYPE (decl);
9534           continue;
9535
9536         case ARRAY_REF:
9537           /* If the access to the function call is a non static field,
9538              build the code to access it. */
9539           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9540             {
9541               decl = maybe_access_field (decl, *where_found, type);
9542               if (decl == error_mark_node)
9543                 return 1;
9544             }
9545           /* And code for the array reference expression */
9546           decl = java_complete_tree (qual_wfl);
9547           if (decl == error_mark_node)
9548             return 1;
9549           type = QUAL_DECL_TYPE (decl);
9550           continue;
9551
9552         case PLUS_EXPR:
9553           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9554             return 1;
9555           if ((type = patch_string (decl)))
9556             decl = type;
9557           *where_found = QUAL_RESOLUTION (q) = decl;
9558           *type_found = type = TREE_TYPE (decl);
9559           break;
9560
9561         case CLASS_LITERAL:
9562           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9563             return 1;
9564           *where_found = QUAL_RESOLUTION (q) = decl;
9565           *type_found = type = TREE_TYPE (decl);
9566           break;
9567
9568         default:
9569           /* Fix for -Wall Just go to the next statement. Don't
9570              continue */
9571           break;
9572         }
9573
9574       /* If we fall here, we weren't processing a (static) function call. */
9575       previous_call_static = 0;
9576
9577       /* It can be the keyword THIS */
9578       if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION
9579           && EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
9580         {
9581           if (!current_this)
9582             {
9583               parse_error_context 
9584                 (wfl, "Keyword `this' used outside allowed context");
9585               return 1;
9586             }
9587           if (ctxp->explicit_constructor_p
9588               && type == current_class)
9589             {
9590               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9591               return 1;
9592             }
9593           /* We have to generate code for intermediate access */
9594           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
9595             {
9596               *where_found = decl = current_this;
9597               *type_found = type = QUAL_DECL_TYPE (decl);
9598             }
9599           /* We're trying to access the this from somewhere else. Make sure
9600              it's allowed before doing so. */
9601           else
9602             {
9603               if (!enclosing_context_p (type, current_class))
9604                 {
9605                   char *p  = xstrdup (lang_printable_name (type, 0));
9606                   parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'", 
9607                                        p, p, 
9608                                        lang_printable_name (current_class, 0));
9609                   free (p);
9610                   return 1;
9611                 }
9612               from_qualified_this = 1;
9613               /* If there's nothing else after that, we need to
9614                  produce something now, otherwise, the section of the
9615                  code that needs to produce <T>.this will generate
9616                  what is necessary. */
9617               if (!TREE_CHAIN (q))
9618                 {
9619                   decl = build_access_to_thisn (current_class, type, 0);
9620                   *where_found = decl = java_complete_tree (decl);
9621                   *type_found = type = TREE_TYPE (decl);
9622                 }
9623             }
9624
9625           from_type = 0;
9626           continue;
9627         }
9628
9629       /* 15.10.2 Accessing Superclass Members using SUPER */
9630       if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION
9631           && EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
9632         {
9633           tree node;
9634           /* Check on the restricted use of SUPER */
9635           if (METHOD_STATIC (current_function_decl)
9636               || current_class == object_type_node)
9637             {
9638               parse_error_context 
9639                 (wfl, "Keyword `super' used outside allowed context");
9640               return 1;
9641             }
9642           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
9643           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
9644                              CLASSTYPE_SUPER (current_class),
9645                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
9646           *where_found = decl = java_complete_tree (node);
9647           if (decl == error_mark_node)
9648             return 1;
9649           *type_found = type = QUAL_DECL_TYPE (decl);
9650           from_super = from_type = 1;
9651           continue;
9652         }
9653
9654       /* 15.13.1: Can't search for field name in packages, so we
9655          assume a variable/class name was meant. */
9656       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
9657         {
9658           tree name;
9659           if ((decl = resolve_package (wfl, &q, &name)))
9660             {
9661               tree list;
9662               *where_found = decl;
9663
9664               /* We want to be absolutely sure that the class is laid
9665                  out. We're going to search something inside it. */
9666               *type_found = type = TREE_TYPE (decl);
9667               layout_class (type);
9668               from_type = 1;
9669
9670               /* Fix them all the way down, if any are left. */
9671               if (q)
9672                 {
9673                   list = TREE_CHAIN (q);
9674                   while (list)
9675                     {
9676                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
9677                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
9678                       list = TREE_CHAIN (list);
9679                     }
9680                 }
9681             }
9682           else
9683             {
9684               if (from_super || from_cast)
9685                 parse_error_context 
9686                   ((from_cast ? qual_wfl : wfl),
9687                    "No variable `%s' defined in class `%s'",
9688                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9689                    lang_printable_name (type, 0));
9690               else
9691                 parse_error_context
9692                   (qual_wfl, "Undefined variable or class name: `%s'",
9693                    IDENTIFIER_POINTER (name));
9694               return 1;
9695             }
9696         }
9697
9698       /* We have a type name. It's been already resolved when the
9699          expression was qualified. */
9700       else if (RESOLVE_TYPE_NAME_P (qual_wfl) && QUAL_RESOLUTION (q))
9701         {
9702           decl = QUAL_RESOLUTION (q);
9703
9704           /* Sneak preview. If next we see a `new', we're facing a
9705              qualification with resulted in a type being selected
9706              instead of a field.  Report the error */
9707           if(TREE_CHAIN (q) 
9708              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
9709             {
9710               parse_error_context (qual_wfl, "Undefined variable `%s'",
9711                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9712               return 1;
9713             }
9714
9715           if (not_accessible_p (TREE_TYPE (decl), decl, type, 0))
9716             {
9717               parse_error_context 
9718                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
9719                  java_accstring_lookup (get_access_flags_from_decl (decl)),
9720                  GET_TYPE_NAME (type),
9721                  IDENTIFIER_POINTER (DECL_NAME (decl)),
9722                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9723               return 1;
9724             }
9725           check_deprecation (qual_wfl, decl);
9726
9727           type = TREE_TYPE (decl);
9728           from_type = 1;
9729         }
9730       /* We resolve an expression name */
9731       else 
9732         {
9733           tree field_decl = NULL_TREE;
9734
9735           /* If there exists an early resolution, use it. That occurs
9736              only once and we know that there are more things to
9737              come. Don't do that when processing something after SUPER
9738              (we need more thing to be put in place below */
9739           if (!from_super && QUAL_RESOLUTION (q))
9740             {
9741               decl = QUAL_RESOLUTION (q);
9742               if (!type)
9743                 {
9744                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
9745                     {
9746                       if (current_this)
9747                         *where_found = current_this;
9748                       else
9749                         {
9750                           static_ref_err (qual_wfl, DECL_NAME (decl),
9751                                           current_class);
9752                           return 1;
9753                         }
9754                       if (outer_field_access_p (current_class, decl))
9755                         decl = build_outer_field_access (qual_wfl, decl);
9756                     }
9757                   else
9758                     {
9759                       *where_found = TREE_TYPE (decl);
9760                       if (TREE_CODE (*where_found) == POINTER_TYPE)
9761                         *where_found = TREE_TYPE (*where_found);
9762                     }
9763                 }
9764             }
9765
9766           /* Report and error if we're using a numerical litteral as a
9767              qualifier. It can only be an INTEGER_CST. */
9768           else if (TREE_CODE (qual_wfl) == INTEGER_CST)
9769             {
9770               parse_error_context
9771                 (wfl, "Can't use type `%s' as a qualifier",
9772                  lang_printable_name (TREE_TYPE (qual_wfl), 0));
9773               return 1;
9774             }
9775
9776           /* We have to search for a field, knowing the type of its
9777              container. The flag FROM_TYPE indicates that we resolved
9778              the last member of the expression as a type name, which
9779              means that for the resolution of this field, we'll look
9780              for other errors than if it was resolved as a member of
9781              an other field. */
9782           else
9783             {
9784               int is_static;
9785               tree field_decl_type; /* For layout */
9786
9787               if (!from_type && !JREFERENCE_TYPE_P (type))
9788                 {
9789                   parse_error_context 
9790                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9791                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9792                      lang_printable_name (type, 0),
9793                      IDENTIFIER_POINTER (DECL_NAME (decl)));
9794                   return 1;
9795                 }
9796               
9797               field_decl = lookup_field_wrapper (type,
9798                                                  EXPR_WFL_NODE (qual_wfl));
9799
9800               /* Maybe what we're trying to access to is an inner
9801                  class, only if decl is a TYPE_DECL. */
9802               if (!field_decl && TREE_CODE (decl) == TYPE_DECL)
9803                 {
9804                   tree ptr, inner_decl;
9805
9806                   BUILD_PTR_FROM_NAME (ptr, EXPR_WFL_NODE (qual_wfl));
9807                   inner_decl = resolve_class (decl, ptr, NULL_TREE, qual_wfl);
9808                   if (inner_decl)
9809                     {
9810                       check_inner_class_access (inner_decl, decl, qual_wfl); 
9811                       type = TREE_TYPE (inner_decl);
9812                       decl = inner_decl;
9813                       from_type = 1;
9814                       continue;
9815                     }
9816                 }
9817
9818               if (field_decl == NULL_TREE)
9819                 {
9820                   parse_error_context 
9821                     (qual_wfl, "No variable `%s' defined in type `%s'",
9822                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9823                      GET_TYPE_NAME (type));
9824                   return 1;
9825                 }
9826               if (field_decl == error_mark_node)
9827                 return 1;
9828
9829               /* Layout the type of field_decl, since we may need
9830                  it. Don't do primitive types or loaded classes. The
9831                  situation of non primitive arrays may not handled
9832                  properly here. FIXME */
9833               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9834                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9835               else
9836                 field_decl_type = TREE_TYPE (field_decl);
9837               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9838                   && !CLASS_LOADED_P (field_decl_type)
9839                   && !TYPE_ARRAY_P (field_decl_type))
9840                 resolve_and_layout (field_decl_type, NULL_TREE);
9841               
9842               /* Check on accessibility here */
9843               if (not_accessible_p (current_class, field_decl,
9844                                     DECL_CONTEXT (field_decl), from_super))
9845                 {
9846                   parse_error_context 
9847                     (qual_wfl,
9848                      "Can't access %s field `%s.%s' from `%s'",
9849                      java_accstring_lookup 
9850                        (get_access_flags_from_decl (field_decl)),
9851                      GET_TYPE_NAME (type),
9852                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9853                      IDENTIFIER_POINTER 
9854                        (DECL_NAME (TYPE_NAME (current_class))));
9855                   return 1;
9856                 }
9857               check_deprecation (qual_wfl, field_decl);
9858               
9859               /* There are things to check when fields are accessed
9860                  from type. There are no restrictions on a static
9861                  declaration of the field when it is accessed from an
9862                  interface */
9863               is_static = FIELD_STATIC (field_decl);
9864               if (!from_super && from_type 
9865                   && !TYPE_INTERFACE_P (type) 
9866                   && !is_static 
9867                   && (current_function_decl 
9868                       && METHOD_STATIC (current_function_decl)))
9869                 {
9870                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9871                   return 1;
9872                 }
9873               from_cast = from_super = 0;
9874
9875               /* It's an access from a type but it isn't static, we
9876                  make it relative to `this'. */
9877               if (!is_static && from_type)
9878                 decl = current_this;
9879
9880               /* If we need to generate something to get a proper
9881                  handle on what this field is accessed from, do it
9882                  now. */
9883               if (!is_static)
9884                 {
9885                   decl = maybe_access_field (decl, *where_found, *type_found);
9886                   if (decl == error_mark_node)
9887                     return 1;
9888                 }
9889
9890               /* We want to keep the location were found it, and the type
9891                  we found. */
9892               *where_found = decl;
9893               *type_found = type;
9894
9895               /* Generate the correct expression for field access from
9896                  qualified this */
9897               if (from_qualified_this)
9898                 {
9899                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9900                   from_qualified_this = 0;
9901                 }
9902
9903               /* This is the decl found and eventually the next one to
9904                  search from */
9905               decl = field_decl;
9906             }
9907           from_type = 0;
9908           type = QUAL_DECL_TYPE (decl);
9909
9910           /* Sneak preview. If decl is qualified by a `new', report
9911              the error here to be accurate on the peculiar construct */
9912           if (TREE_CHAIN (q) 
9913               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9914               && !JREFERENCE_TYPE_P (type))
9915             {
9916               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9917                                    lang_printable_name (type, 0));
9918               return 1;
9919             }
9920         }
9921       /* `q' might have changed due to a after package resolution
9922          re-qualification */
9923       if (!q)
9924         break;
9925     }
9926   *found_decl = decl;
9927   return 0;
9928 }
9929
9930 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9931    can't be accessed from REFERENCE (a record type). If MEMBER
9932    features a protected access, we then use WHERE which, if non null,
9933    holds the type of MEMBER's access that is checked against
9934    6.6.2.1. This function should be used when decl is a field or a
9935    method.  */
9936
9937 static int
9938 not_accessible_p (reference, member, where, from_super)
9939      tree reference, member;
9940      tree where;
9941      int from_super;
9942 {
9943   int access_flag = get_access_flags_from_decl (member);
9944
9945   /* Inner classes are processed by check_inner_class_access */
9946   if (INNER_CLASS_TYPE_P (reference))
9947     return 0;
9948
9949   /* Access always granted for members declared public */
9950   if (access_flag & ACC_PUBLIC)
9951     return 0;
9952   
9953   /* Check access on protected members */
9954   if (access_flag & ACC_PROTECTED)
9955     {
9956       /* Access granted if it occurs from within the package
9957          containing the class in which the protected member is
9958          declared */
9959       if (class_in_current_package (DECL_CONTEXT (member)))
9960         return 0;
9961
9962       /* If accessed with the form `super.member', then access is granted */
9963       if (from_super)
9964         return 0;
9965
9966       /* If where is active, access was made through a
9967          qualifier. Access is granted if the type of the qualifier is
9968          or is a sublass of the type the access made from (6.6.2.1.)  */
9969       if (where && !inherits_from_p (reference, where))
9970         return 1;
9971
9972       /* Otherwise, access is granted if occurring from the class where
9973          member is declared or a subclass of it. Find the right
9974          context to perform the check */
9975       if (PURE_INNER_CLASS_TYPE_P (reference))
9976         {
9977           while (INNER_CLASS_TYPE_P (reference))
9978             {
9979               if (inherits_from_p (reference, DECL_CONTEXT (member)))
9980                 return 0;
9981               reference = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (reference)));
9982             }
9983         }
9984       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9985         return 0;
9986       return 1;
9987     }
9988
9989   /* Check access on private members. Access is granted only if it
9990      occurs from within the class in which it is declared -- that does
9991      it for innerclasses too. */
9992   if (access_flag & ACC_PRIVATE)
9993     {
9994       if (reference == DECL_CONTEXT (member))
9995         return 0;
9996       if (enclosing_context_p (reference, DECL_CONTEXT (member)))
9997         return 0;
9998       return 1;
9999     }
10000
10001   /* Default access are permitted only when occurring within the
10002      package in which the type (REFERENCE) is declared. In other words,
10003      REFERENCE is defined in the current package */
10004   if (ctxp->package)
10005     return !class_in_current_package (reference);
10006
10007   /* Otherwise, access is granted */
10008   return 0;
10009 }
10010
10011 /* Test deprecated decl access.  */
10012 static void
10013 check_deprecation (wfl, decl)
10014      tree wfl, decl;
10015 {
10016   const char *file = DECL_SOURCE_FILE (decl);
10017   /* Complain if the field is deprecated and the file it was defined
10018      in isn't compiled at the same time the file which contains its
10019      use is */
10020   if (DECL_DEPRECATED (decl) 
10021       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
10022     {
10023       char the [20];
10024       switch (TREE_CODE (decl))
10025         {
10026         case FUNCTION_DECL:
10027           strcpy (the, "method");
10028           break;
10029         case FIELD_DECL:
10030         case VAR_DECL:
10031           strcpy (the, "field");
10032           break;
10033         case TYPE_DECL:
10034           parse_warning_context (wfl, "The class `%s' has been deprecated",
10035                                  IDENTIFIER_POINTER (DECL_NAME (decl)));
10036           return;
10037         default:
10038           abort ();
10039         }
10040       /* Don't issue a message if the context as been deprecated as a
10041          whole. */
10042       if (! CLASS_DEPRECATED (TYPE_NAME (DECL_CONTEXT (decl))))
10043         parse_warning_context 
10044           (wfl, "The %s `%s' in class `%s' has been deprecated", 
10045            the, lang_printable_name (decl, 0),
10046            IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
10047     }
10048 }
10049
10050 /* Returns 1 if class was declared in the current package, 0 otherwise */
10051
10052 static GTY(()) tree cicp_cache;
10053 static int
10054 class_in_current_package (class)
10055      tree class;
10056 {
10057   int qualified_flag;
10058   tree left;
10059
10060   if (cicp_cache == class)
10061     return 1;
10062
10063   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
10064
10065   /* If the current package is empty and the name of CLASS is
10066      qualified, class isn't in the current package.  If there is a
10067      current package and the name of the CLASS is not qualified, class
10068      isn't in the current package */
10069   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
10070     return 0;
10071
10072   /* If there is not package and the name of CLASS isn't qualified,
10073      they belong to the same unnamed package */
10074   if (!ctxp->package && !qualified_flag)
10075     return 1;
10076
10077   /* Compare the left part of the name of CLASS with the package name */
10078   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
10079   if (ctxp->package == left)
10080     {
10081       cicp_cache = class;
10082       return 1;
10083     }
10084   return 0;
10085 }
10086
10087 /* This function may generate code to access DECL from WHERE. This is
10088    done only if certain conditions meet.  */
10089
10090 static tree
10091 maybe_access_field (decl, where, type)
10092   tree decl, where, type;
10093 {
10094   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
10095       && !FIELD_STATIC (decl))
10096     decl = build_field_ref (where ? where : current_this, 
10097                             (type ? type : DECL_CONTEXT (decl)),
10098                             DECL_NAME (decl));
10099   return decl;
10100 }
10101
10102 /* Build a method invocation, by patching PATCH. If non NULL
10103    and according to the situation, PRIMARY and WHERE may be
10104    used. IS_STATIC is set to 1 if the invoked function is static. */
10105
10106 static tree
10107 patch_method_invocation (patch, primary, where, from_super,
10108                         is_static, ret_decl)
10109      tree patch, primary, where;
10110      int from_super;
10111      int *is_static;
10112      tree *ret_decl;
10113 {
10114   tree wfl = TREE_OPERAND (patch, 0);
10115   tree args = TREE_OPERAND (patch, 1);
10116   tree name = EXPR_WFL_NODE (wfl);
10117   tree list;
10118   int is_static_flag = 0;
10119   int is_super_init = 0;
10120   tree this_arg = NULL_TREE;
10121   int is_array_clone_call = 0;
10122   
10123   /* Should be overriden if everything goes well. Otherwise, if
10124      something fails, it should keep this value. It stop the
10125      evaluation of a bogus assignment. See java_complete_tree,
10126      MODIFY_EXPR: for the reasons why we sometimes want to keep on
10127      evaluating an assignment */
10128   TREE_TYPE (patch) = error_mark_node;
10129
10130   /* Since lookup functions are messing with line numbers, save the
10131      context now.  */
10132   java_parser_context_save_global ();
10133
10134   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
10135
10136   /* Resolution of qualified name, excluding constructors */
10137   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
10138     {
10139       tree identifier, identifier_wfl, type, resolved;
10140       /* Extract the last IDENTIFIER of the qualified
10141          expression. This is a wfl and we will use it's location
10142          data during error report. */
10143       identifier_wfl = cut_identifier_in_qualified (wfl);
10144       identifier = EXPR_WFL_NODE (identifier_wfl);
10145       
10146       /* Given the context, IDENTIFIER is syntactically qualified
10147          as a MethodName. We need to qualify what's before */
10148       qualify_ambiguous_name (wfl);
10149       resolved = resolve_field_access (wfl, NULL, NULL);
10150
10151       if (TREE_CODE (resolved) == VAR_DECL && FIELD_STATIC (resolved)
10152          && FIELD_FINAL (resolved) 
10153          && !inherits_from_p (DECL_CONTEXT (resolved), current_class)
10154          && !flag_emit_class_files && !flag_emit_xref)
10155        resolved = build_class_init (DECL_CONTEXT (resolved), resolved);
10156
10157       if (resolved == error_mark_node)
10158         PATCH_METHOD_RETURN_ERROR ();
10159
10160       type = GET_SKIP_TYPE (resolved);
10161       resolve_and_layout (type, NULL_TREE);
10162       
10163       if (JPRIMITIVE_TYPE_P (type))
10164         {
10165           parse_error_context
10166             (identifier_wfl,
10167              "Can't invoke a method on primitive type `%s'",
10168              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
10169           PATCH_METHOD_RETURN_ERROR ();         
10170         }
10171
10172       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
10173       args = nreverse (args);
10174
10175       /* We're resolving a call from a type */
10176       if (TREE_CODE (resolved) == TYPE_DECL)
10177         {
10178           if (CLASS_INTERFACE (resolved))
10179             {
10180               parse_error_context
10181                 (identifier_wfl,
10182                 "Can't make static reference to method `%s' in interface `%s'",
10183                  IDENTIFIER_POINTER (identifier), 
10184                  IDENTIFIER_POINTER (name));
10185               PATCH_METHOD_RETURN_ERROR ();
10186             }
10187           if (list && !METHOD_STATIC (list))
10188             {
10189               char *fct_name = xstrdup (lang_printable_name (list, 0));
10190               parse_error_context 
10191                 (identifier_wfl,
10192                  "Can't make static reference to method `%s %s' in class `%s'",
10193                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
10194                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
10195               free (fct_name);
10196               PATCH_METHOD_RETURN_ERROR ();
10197             }
10198         }
10199       else
10200         this_arg = primary = resolved;
10201       
10202       if (TYPE_ARRAY_P (type) && identifier == get_identifier ("clone"))
10203         is_array_clone_call = 1;
10204       
10205       /* IDENTIFIER_WFL will be used to report any problem further */
10206       wfl = identifier_wfl;
10207     }
10208   /* Resolution of simple names, names generated after a primary: or
10209      constructors */
10210   else
10211     {
10212       tree class_to_search = NULL_TREE;
10213       int lc;                   /* Looking for Constructor */
10214       
10215       /* We search constructor in their target class */
10216       if (CALL_CONSTRUCTOR_P (patch))
10217         {
10218           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10219             class_to_search = EXPR_WFL_NODE (wfl);
10220           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
10221                    this_identifier_node)
10222             class_to_search = NULL_TREE;
10223           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
10224                    super_identifier_node)
10225             {
10226               is_super_init = 1;
10227               if (CLASSTYPE_SUPER (current_class))
10228                 class_to_search = 
10229                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
10230               else
10231                 {
10232                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
10233                   PATCH_METHOD_RETURN_ERROR ();
10234                 }
10235             }
10236
10237           /* Class to search is NULL if we're searching the current one */
10238           if (class_to_search)
10239             {
10240               class_to_search = resolve_and_layout (class_to_search, wfl);
10241
10242               if (!class_to_search)
10243                 {
10244                   parse_error_context 
10245                     (wfl, "Class `%s' not found in type declaration",
10246                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
10247                   PATCH_METHOD_RETURN_ERROR ();
10248                 }
10249               
10250               /* Can't instantiate an abstract class, but we can
10251                  invoke it's constructor. It's use within the `new'
10252                  context is denied here. */
10253               if (CLASS_ABSTRACT (class_to_search) 
10254                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
10255                 {
10256                   parse_error_context 
10257                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
10258                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
10259                   PATCH_METHOD_RETURN_ERROR ();
10260                 }
10261
10262               class_to_search = TREE_TYPE (class_to_search);
10263             }
10264           else
10265             class_to_search = current_class;
10266           lc = 1;
10267         }
10268       /* This is a regular search in the local class, unless an
10269          alternate class is specified. */
10270       else
10271         {
10272           if (where != NULL_TREE)
10273             class_to_search = where;
10274           else if (QUALIFIED_P (name))
10275             class_to_search = current_class;
10276           else
10277             {
10278               class_to_search = current_class;
10279
10280               for (;;)
10281                 {
10282                   if (has_method (class_to_search, name))
10283                     break;
10284                   if (! INNER_CLASS_TYPE_P (class_to_search))
10285                     {
10286                       parse_error_context (wfl,
10287                                            "No method named `%s' in scope",
10288                                            IDENTIFIER_POINTER (name));
10289                       PATCH_METHOD_RETURN_ERROR ();
10290                     }
10291                   class_to_search
10292                     = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_to_search)));
10293                 }
10294             }
10295           lc = 0;
10296         }
10297
10298       /* NAME is a simple identifier or comes from a primary. Search
10299          in the class whose declaration contain the method being
10300          invoked. */
10301       resolve_and_layout (class_to_search, NULL_TREE);
10302
10303       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
10304       /* Don't continue if no method were found, as the next statement
10305          can't be executed then. */
10306       if (!list)
10307         PATCH_METHOD_RETURN_ERROR ();
10308       
10309       if (TYPE_ARRAY_P (class_to_search)
10310           && DECL_NAME (list) == get_identifier ("clone"))
10311         is_array_clone_call = 1;
10312
10313       /* Check for static reference if non static methods */
10314       if (check_for_static_method_reference (wfl, patch, list, 
10315                                              class_to_search, primary))
10316         PATCH_METHOD_RETURN_ERROR ();
10317
10318       /* Check for inner classes creation from illegal contexts */
10319       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
10320                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
10321           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search)
10322           && !DECL_INIT_P (current_function_decl))
10323         {
10324           parse_error_context 
10325             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
10326              lang_printable_name (class_to_search, 0),
10327              (!current_this ? "" :
10328               "; an explicit one must be provided when creating this inner class"));
10329           PATCH_METHOD_RETURN_ERROR ();
10330         }
10331
10332       /* Non static methods are called with the current object extra
10333          argument. If patch a `new TYPE()', the argument is the value
10334          returned by the object allocator. If method is resolved as a
10335          primary, use the primary otherwise use the current THIS. */
10336       args = nreverse (args);
10337       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
10338         {
10339           this_arg = primary ? primary : current_this;
10340
10341           /* If we're using an access method, things are different.
10342              There are two familly of cases:
10343
10344              1) We're not generating bytecodes:
10345
10346              - LIST is non static. It's invocation is transformed from
10347                x(a1,...,an) into this$<n>.x(a1,....an).
10348              - LIST is static. It's invocation is transformed from
10349                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
10350
10351              2) We're generating bytecodes:
10352              
10353              - LIST is non static. It's invocation is transformed from
10354                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
10355              - LIST is static. It's invocation is transformed from
10356                x(a1,....,an) into TYPE_OF(this$<n>).x(a1,....an).
10357
10358              Of course, this$<n> can be abitrary complex, ranging from
10359              this$0 (the immediate outer context) to 
10360              access$0(access$0(...(this$0))). 
10361              
10362              maybe_use_access_method returns a non zero value if the
10363              this_arg has to be moved into the (then generated) stub
10364              argument list. In the meantime, the selected function
10365              might have be replaced by a generated stub. */
10366           if (!primary &&
10367               maybe_use_access_method (is_super_init, &list, &this_arg))
10368             {
10369               args = tree_cons (NULL_TREE, this_arg, args);
10370               this_arg = NULL_TREE; /* So it doesn't get chained twice */
10371             }
10372         }
10373     }
10374
10375   /* Merge point of all resolution schemes. If we have nothing, this
10376      is an error, already signaled */
10377   if (!list) 
10378     PATCH_METHOD_RETURN_ERROR ();
10379
10380   /* Check accessibility, position the is_static flag, build and
10381      return the call */
10382   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list,
10383                         (primary ? TREE_TYPE (TREE_TYPE (primary)) : 
10384                          NULL_TREE), from_super)
10385       /* Calls to clone() on array types are permitted as a special-case. */
10386       && !is_array_clone_call)
10387     {
10388       const char *const fct_name = IDENTIFIER_POINTER (DECL_NAME (list));
10389       const char *const access =
10390         java_accstring_lookup (get_access_flags_from_decl (list));
10391       const char *const klass =
10392         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list))));
10393       const char *const refklass =
10394         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
10395       const char *const what = (DECL_CONSTRUCTOR_P (list)
10396                                 ? "constructor" : "method");
10397       /* FIXME: WFL yields the wrong message here but I don't know
10398          what else to use.  */
10399       parse_error_context (wfl,
10400                            "Can't access %s %s `%s.%s' from `%s'",
10401                            access, what, klass, fct_name, refklass);
10402       PATCH_METHOD_RETURN_ERROR ();
10403     }
10404
10405   /* Deprecation check: check whether the method being invoked or the
10406      instance-being-created's type are deprecated. */
10407   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10408     check_deprecation (wfl, TYPE_NAME (DECL_CONTEXT (list)));
10409   else
10410     check_deprecation (wfl, list);
10411
10412   /* If invoking a innerclass constructor, there are hidden parameters
10413      to pass */
10414   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
10415       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10416     {
10417       /* And make sure we add the accessed local variables to be saved
10418          in field aliases. */
10419       args = build_alias_initializer_parameter_list
10420         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
10421
10422       /* Secretly pass the current_this/primary as a second argument */
10423       if (primary || current_this)
10424         {
10425           tree extra_arg;
10426           tree this_type = (current_this ?
10427                             TREE_TYPE (TREE_TYPE (current_this)) : NULL_TREE);
10428           /* Method's (list) enclosing context */
10429           tree mec = DECL_CONTEXT (TYPE_NAME (DECL_CONTEXT (list)));
10430           /* If we have a primary, use it. */
10431           if (primary)
10432             extra_arg = primary;
10433           /* The current `this' is an inner class but isn't a direct
10434              enclosing context for the inner class we're trying to
10435              create. Build an access to the proper enclosing context
10436              and use it. */
10437           else if (current_this && PURE_INNER_CLASS_TYPE_P (this_type)
10438                    && this_type != TREE_TYPE (mec))
10439             {
10440
10441               extra_arg = build_access_to_thisn (current_class,
10442                                                  TREE_TYPE (mec), 0);
10443               extra_arg = java_complete_tree (extra_arg);
10444             }
10445           /* Otherwise, just use the current `this' as an enclosing
10446              context. */
10447           else
10448             extra_arg = current_this;
10449           args = tree_cons (NULL_TREE, extra_arg, args);
10450         }
10451       else
10452         args = tree_cons (NULL_TREE, integer_zero_node, args);
10453     }
10454
10455   /* This handles the situation where a constructor invocation needs
10456      to have an enclosing context passed as a second parameter (the
10457      constructor is one of an inner class). */
10458   if ((is_super_init || 
10459        (TREE_CODE (patch) == CALL_EXPR && name == this_identifier_node))
10460       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10461     {
10462       tree dest = TYPE_NAME (DECL_CONTEXT (list));
10463       tree extra_arg = 
10464         build_access_to_thisn (current_class, DECL_CONTEXT (dest), 0);
10465       extra_arg = java_complete_tree (extra_arg);
10466       args = tree_cons (NULL_TREE, extra_arg, args);
10467     }
10468
10469   is_static_flag = METHOD_STATIC (list);
10470   if (! is_static_flag && this_arg != NULL_TREE)
10471     args = tree_cons (NULL_TREE, this_arg, args);
10472
10473   /* In the context of an explicit constructor invocation, we can't
10474      invoke any method relying on `this'. Exceptions are: we're
10475      invoking a static function, primary exists and is not the current
10476      this, we're creating a new object. */
10477   if (ctxp->explicit_constructor_p 
10478       && !is_static_flag 
10479       && (!primary || primary == current_this)
10480       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
10481     {
10482       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
10483       PATCH_METHOD_RETURN_ERROR ();
10484     }
10485   java_parser_context_restore_global ();
10486   if (is_static) 
10487     *is_static = is_static_flag;
10488   /* Sometimes, we want the decl of the selected method. Such as for
10489      EH checking */
10490   if (ret_decl)
10491     *ret_decl = list;
10492   patch = patch_invoke (patch, list, args);
10493
10494   /* Now is a good time to insert the call to finit$ */
10495   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
10496     {
10497       tree finit_parms, finit_call;
10498       
10499       /* Prepare to pass hidden parameters to finit$, if any. */
10500       finit_parms = build_alias_initializer_parameter_list 
10501         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
10502       
10503       finit_call = 
10504         build_method_invocation (build_wfl_node (finit_identifier_node),
10505                                  finit_parms);
10506
10507       /* Generate the code used to initialize fields declared with an
10508          initialization statement and build a compound statement along
10509          with the super constructor invocation. */
10510       CAN_COMPLETE_NORMALLY (patch) = 1;
10511       patch = build (COMPOUND_EXPR, void_type_node, patch,
10512                      java_complete_tree (finit_call));
10513     }
10514   return patch;
10515 }
10516
10517 /* Check that we're not trying to do a static reference to a method in
10518    non static method. Return 1 if it's the case, 0 otherwise. */
10519
10520 static int
10521 check_for_static_method_reference (wfl, node, method, where, primary)
10522      tree wfl, node, method, where, primary;
10523 {
10524   if (METHOD_STATIC (current_function_decl) 
10525       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
10526     {
10527       char *fct_name = xstrdup (lang_printable_name (method, 0));
10528       parse_error_context 
10529         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
10530          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
10531          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
10532       free (fct_name);
10533       return 1;
10534     }
10535   return 0;
10536 }
10537
10538 /* Fix the invocation of *MDECL if necessary in the case of a
10539    invocation from an inner class. *THIS_ARG might be modified
10540    appropriately and an alternative access to *MDECL might be
10541    returned.  */
10542
10543 static int
10544 maybe_use_access_method (is_super_init, mdecl, this_arg)
10545      int is_super_init;
10546      tree *mdecl, *this_arg;
10547 {
10548   tree ctx;
10549   tree md = *mdecl, ta = *this_arg;
10550   int to_return = 0;
10551   int non_static_context = !METHOD_STATIC (md);
10552
10553   if (is_super_init 
10554       || DECL_CONTEXT (md) == current_class
10555       || !PURE_INNER_CLASS_TYPE_P (current_class) 
10556       || DECL_FINIT_P (md)
10557       || DECL_INSTINIT_P (md))
10558     return 0;
10559   
10560   /* If we're calling a method found in an enclosing class, generate
10561      what it takes to retrieve the right this. Don't do that if we're
10562      invoking a static method. Note that if MD's type is unrelated to
10563      CURRENT_CLASS, then the current this can be used. */
10564
10565   if (non_static_context && DECL_CONTEXT (md) != object_type_node)
10566     {
10567       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
10568       if (inherits_from_p (ctx, DECL_CONTEXT (md)))
10569         {
10570           ta = build_current_thisn (current_class);
10571           ta = build_wfl_node (ta);
10572         }
10573       else
10574         {
10575           tree type = ctx;
10576           while (type)
10577             {
10578               maybe_build_thisn_access_method (type);
10579               if (inherits_from_p (type, DECL_CONTEXT (md)))
10580                 {
10581                   ta = build_access_to_thisn (ctx, type, 0);
10582                   break;
10583                 }
10584               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
10585                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
10586             }
10587         }
10588       ta = java_complete_tree (ta);
10589     }
10590
10591   /* We might have to use an access method to get to MD. We can
10592      break the method access rule as far as we're not generating
10593      bytecode */
10594   if (METHOD_PRIVATE (md) && flag_emit_class_files)
10595     {
10596       md = build_outer_method_access_method (md);
10597       to_return = 1;
10598     }
10599
10600   *mdecl = md;
10601   *this_arg = ta;
10602
10603   /* Returnin a non zero value indicates we were doing a non static
10604      method invokation that is now a static invocation. It will have
10605      callee displace `this' to insert it in the regular argument
10606      list. */
10607   return (non_static_context && to_return);
10608 }
10609
10610 /* Patch an invoke expression METHOD and ARGS, based on its invocation
10611    mode.  */
10612
10613 static tree
10614 patch_invoke (patch, method, args)
10615      tree patch, method, args;
10616 {
10617   tree dtable, func;
10618   tree original_call, t, ta;
10619   tree check = NULL_TREE;
10620
10621   /* Last step for args: convert build-in types. If we're dealing with
10622      a new TYPE() type call, the first argument to the constructor
10623      isn't found in the incoming argument list, but delivered by
10624      `new' */
10625   t = TYPE_ARG_TYPES (TREE_TYPE (method));
10626   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10627     t = TREE_CHAIN (t);
10628   for (ta = args; t != end_params_node && ta; 
10629        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
10630     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
10631         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
10632       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
10633
10634   /* Resolve unresolved returned type isses */
10635   t = TREE_TYPE (TREE_TYPE (method));
10636   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
10637     resolve_and_layout (TREE_TYPE (t), NULL);
10638
10639   if (flag_emit_class_files || flag_emit_xref)
10640     func = method;
10641   else
10642     {
10643       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
10644         {
10645         case INVOKE_VIRTUAL:
10646           dtable = invoke_build_dtable (0, args);
10647           func = build_invokevirtual (dtable, method);
10648           break;
10649
10650         case INVOKE_NONVIRTUAL:
10651           /* If the object for the method call is null, we throw an
10652              exception.  We don't do this if the object is the current
10653              method's `this'.  In other cases we just rely on an
10654              optimization pass to eliminate redundant checks.  */
10655           if (TREE_VALUE (args) != current_this)
10656             {
10657               /* We use a save_expr here to make sure we only evaluate
10658                  the new `self' expression once.  */
10659               tree save_arg = save_expr (TREE_VALUE (args));
10660               TREE_VALUE (args) = save_arg;
10661               check = java_check_reference (save_arg, 1);
10662             }
10663           /* Fall through.  */
10664
10665         case INVOKE_SUPER:
10666         case INVOKE_STATIC:
10667           {
10668             tree signature = build_java_signature (TREE_TYPE (method));
10669             func = build_known_method_ref (method, TREE_TYPE (method),
10670                                            DECL_CONTEXT (method),
10671                                            signature, args);
10672           }
10673           break;
10674
10675         case INVOKE_INTERFACE:
10676           dtable = invoke_build_dtable (1, args);
10677           func = build_invokeinterface (dtable, method);
10678           break;
10679
10680         default:
10681           abort ();
10682         }
10683
10684       /* Ensure self_type is initialized, (invokestatic). FIXME */
10685       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
10686     }
10687
10688   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
10689   TREE_OPERAND (patch, 0) = func;
10690   TREE_OPERAND (patch, 1) = args;
10691   patch = check_for_builtin (method, patch);
10692   original_call = patch;
10693
10694   /* We're processing a `new TYPE ()' form. New is called and its
10695      returned value is the first argument to the constructor. We build
10696      a COMPOUND_EXPR and use saved expression so that the overall NEW
10697      expression value is a pointer to a newly created and initialized
10698      class. */
10699   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
10700     {
10701       tree class = DECL_CONTEXT (method);
10702       tree c1, saved_new, size, new;
10703       tree alloc_node;
10704
10705       if (flag_emit_class_files || flag_emit_xref)
10706         {
10707           TREE_TYPE (patch) = build_pointer_type (class);
10708           return patch;
10709         }
10710       if (!TYPE_SIZE (class))
10711         safe_layout_class (class);
10712       size = size_in_bytes (class);
10713       alloc_node =
10714         (class_has_finalize_method (class) ? alloc_object_node
10715                                            : alloc_no_finalizer_node);
10716       new = build (CALL_EXPR, promote_type (class),
10717                    build_address_of (alloc_node),
10718                    tree_cons (NULL_TREE, build_class_ref (class),
10719                               build_tree_list (NULL_TREE, 
10720                                                size_in_bytes (class))),
10721                    NULL_TREE);
10722       saved_new = save_expr (new);
10723       c1 = build_tree_list (NULL_TREE, saved_new);
10724       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
10725       TREE_OPERAND (original_call, 1) = c1;
10726       TREE_SET_CODE (original_call, CALL_EXPR);
10727       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
10728     }
10729
10730   /* If CHECK is set, then we are building a check to see if the object
10731      is NULL.  */
10732   if (check != NULL_TREE)
10733     {
10734       patch = build (COMPOUND_EXPR, TREE_TYPE (patch), check, patch);
10735       TREE_SIDE_EFFECTS (patch) = 1;
10736     }
10737
10738   /* In order to be able to modify PATCH later, we SAVE_EXPR it and
10739      put it as the first expression of a COMPOUND_EXPR. The second
10740      expression being an empty statement to be later patched if
10741      necessary. We remember a TREE_LIST (the PURPOSE is the method,
10742      the VALUE is the compound) in a hashtable and return a
10743      COMPOUND_EXPR built so that the result of the evaluation of the
10744      original PATCH node is returned. */
10745   if (STATIC_CLASS_INIT_OPT_P ()
10746       && current_function_decl && METHOD_STATIC (method))
10747     {
10748       tree list;
10749       tree fndecl = current_function_decl;
10750       tree save = save_expr (patch);
10751       tree type = TREE_TYPE (patch);
10752
10753       patch = build (COMPOUND_EXPR, type, save, empty_stmt_node);
10754       list = tree_cons (method, patch,
10755                         DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl));
10756
10757       DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl) = list;
10758
10759       patch = build (COMPOUND_EXPR, type, patch, save);
10760     }
10761
10762   return patch;
10763 }
10764
10765 static int
10766 invocation_mode (method, super)
10767      tree method;
10768      int super;
10769 {
10770   int access = get_access_flags_from_decl (method);
10771
10772   if (super)
10773     return INVOKE_SUPER;
10774
10775   if (access & ACC_STATIC)
10776     return INVOKE_STATIC;
10777
10778   /* We have to look for a constructor before we handle nonvirtual
10779      calls; otherwise the constructor will look nonvirtual.  */
10780   if (DECL_CONSTRUCTOR_P (method))
10781     return INVOKE_STATIC;
10782
10783   if (access & ACC_FINAL || access & ACC_PRIVATE)
10784     return INVOKE_NONVIRTUAL;
10785
10786   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
10787     return INVOKE_NONVIRTUAL;
10788
10789   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
10790     return INVOKE_INTERFACE;
10791
10792   return INVOKE_VIRTUAL;
10793 }
10794
10795 /* Retrieve a refined list of matching methods. It covers the step
10796    15.11.2 (Compile-Time Step 2) */
10797
10798 static tree
10799 lookup_method_invoke (lc, cl, class, name, arg_list)
10800      int lc;
10801      tree cl;
10802      tree class, name, arg_list;
10803 {
10804   tree atl = end_params_node;           /* Arg Type List */
10805   tree method, signature, list, node;
10806   const char *candidates;               /* Used for error report */
10807   char *dup;
10808
10809   /* Fix the arguments */
10810   for (node = arg_list; node; node = TREE_CHAIN (node))
10811     {
10812       tree current_arg = TREE_TYPE (TREE_VALUE (node));
10813       /* Non primitive type may have to be resolved */
10814       if (!JPRIMITIVE_TYPE_P (current_arg))
10815         resolve_and_layout (current_arg, NULL_TREE);
10816       /* And promoted */
10817       if (TREE_CODE (current_arg) == RECORD_TYPE)
10818         current_arg = promote_type (current_arg);
10819       atl = tree_cons (NULL_TREE, current_arg, atl);
10820     }
10821
10822   /* Presto. If we're dealing with an anonymous class and a
10823      constructor call, generate the right constructor now, since we
10824      know the arguments' types. */
10825
10826   if (lc && ANONYMOUS_CLASS_P (class))
10827     {
10828       tree saved_current_class;
10829       tree mdecl = craft_constructor (TYPE_NAME (class), atl);
10830       saved_current_class = current_class;
10831       current_class = class;
10832       fix_constructors (mdecl);
10833       current_class = saved_current_class;
10834     }
10835
10836   /* Find all candidates and then refine the list, searching for the
10837      most specific method. */
10838   list = find_applicable_accessible_methods_list (lc, class, name, atl);
10839   list = find_most_specific_methods_list (list);
10840   if (list && !TREE_CHAIN (list))
10841     return TREE_VALUE (list);
10842
10843   /* Issue an error. List candidates if any. Candidates are listed
10844      only if accessible (non accessible methods may end-up here for
10845      the sake of a better error report). */
10846   candidates = NULL;
10847   if (list)
10848     {
10849       tree current;
10850       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
10851       for (current = list; current; current = TREE_CHAIN (current))
10852         {
10853           tree cm = TREE_VALUE (current);
10854           char string [4096];
10855           if (!cm || not_accessible_p (class, cm, NULL_TREE, 0))
10856             continue;
10857           sprintf 
10858             (string, "  `%s' in `%s'%s",
10859              get_printable_method_name (cm),
10860              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
10861              (TREE_CHAIN (current) ? "\n" : ""));
10862           obstack_grow (&temporary_obstack, string, strlen (string));
10863         }
10864       obstack_1grow (&temporary_obstack, '\0');
10865       candidates = obstack_finish (&temporary_obstack);
10866     }
10867   /* Issue the error message */
10868   method = make_node (FUNCTION_TYPE);
10869   TYPE_ARG_TYPES (method) = atl;
10870   signature = build_java_argument_signature (method);
10871   dup = xstrdup (lang_printable_name (class, 0));
10872   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
10873                        (lc ? "constructor" : "method"),
10874                        (lc ? dup : IDENTIFIER_POINTER (name)),
10875                        IDENTIFIER_POINTER (signature), dup,
10876                        (candidates ? candidates : ""));
10877   free (dup);
10878   return NULL_TREE;
10879 }
10880
10881 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
10882    when we're looking for a constructor. */
10883
10884 static tree
10885 find_applicable_accessible_methods_list (lc, class, name, arglist)
10886      int lc;
10887      tree class, name, arglist;
10888 {
10889   static htab_t searched_classes;
10890   static int search_not_done = 0;
10891   tree list = NULL_TREE, all_list = NULL_TREE;
10892
10893   /* Check the hash table to determine if this class has been searched 
10894      already. */
10895   if (searched_classes)
10896     {
10897       if (htab_find (searched_classes, class) != NULL)
10898         return NULL;
10899     }
10900   else
10901     {
10902       searched_classes = htab_create (10, htab_hash_pointer,
10903                                       htab_eq_pointer, NULL);
10904     }
10905     
10906   search_not_done++;
10907   *htab_find_slot (searched_classes, class, INSERT) = class;
10908
10909   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
10910     {
10911       load_class (class, 1);
10912       safe_layout_class (class);
10913     }
10914
10915   /* Search interfaces */
10916   if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
10917       && CLASS_INTERFACE (TYPE_NAME (class)))
10918     {
10919       int i, n;
10920       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10921       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10922                                       name, arglist, &list, &all_list);
10923       n = TREE_VEC_LENGTH (basetype_vec);
10924       for (i = 1; i < n; i++)
10925         {
10926           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10927           tree rlist;
10928
10929           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
10930                                                            arglist);
10931           list = chainon (rlist, list);
10932         }
10933     }
10934   /* Search classes */
10935   else
10936     {
10937       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10938                                       name, arglist, &list, &all_list);
10939
10940       /* When looking finit$, class$ or instinit$, we turn LC to 1 so
10941          that we only search in class. Note that we should have found
10942          something at this point. */
10943       if (ID_FINIT_P (name) || ID_CLASSDOLLAR_P (name) || ID_INSTINIT_P (name))
10944         {
10945           lc = 1;
10946           if (!list)
10947             abort ();
10948         }
10949
10950       /* We must search all interfaces of this class */
10951       if (!lc)
10952       {
10953         tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10954         int n = TREE_VEC_LENGTH (basetype_vec), i;
10955         for (i = 1; i < n; i++)
10956           {
10957             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10958             if (t != object_type_node)
10959               {
10960                 tree rlist
10961                   = find_applicable_accessible_methods_list (lc, t,
10962                                                              name, arglist);
10963                 list = chainon (rlist, list);
10964               }
10965           }
10966       }
10967
10968       /* Search superclass */
10969       if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
10970         {
10971           tree rlist;
10972           class = CLASSTYPE_SUPER (class);
10973           rlist = find_applicable_accessible_methods_list (lc, class, 
10974                                                            name, arglist);
10975           list = chainon (rlist, list);
10976         }
10977     }
10978
10979   search_not_done--;
10980
10981   /* We're done. Reset the searched classes list and finally search
10982      java.lang.Object if it wasn't searched already. */
10983   if (!search_not_done)
10984     {
10985       if (!lc
10986           && TYPE_METHODS (object_type_node)
10987           && htab_find (searched_classes, object_type_node) == NULL)
10988         {
10989           search_applicable_methods_list (lc, 
10990                                           TYPE_METHODS (object_type_node),
10991                                           name, arglist, &list, &all_list);
10992         }
10993       htab_delete (searched_classes);
10994       searched_classes = NULL;
10995     }
10996
10997   /* Either return the list obtained or all selected (but
10998      inaccessible) methods for better error report. */
10999   return (!list ? all_list : list);
11000 }
11001
11002 /* Effectively search for the appropriate method in method */
11003
11004 static void 
11005 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
11006      int lc;
11007      tree method, name, arglist;
11008      tree *list, *all_list;
11009 {
11010   for (; method; method = TREE_CHAIN (method))
11011     {
11012       /* When dealing with constructor, stop here, otherwise search
11013          other classes */
11014       if (lc && !DECL_CONSTRUCTOR_P (method))
11015         continue;
11016       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
11017                        || (DECL_NAME (method) != name)))
11018         continue;
11019
11020       if (argument_types_convertible (method, arglist))
11021         {
11022           /* Retain accessible methods only */
11023           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
11024                                  method, NULL_TREE, 0))
11025             *list = tree_cons (NULL_TREE, method, *list);
11026           else
11027             /* Also retain all selected method here */
11028             *all_list = tree_cons (NULL_TREE, method, *list);
11029         }
11030     }
11031 }
11032
11033 /* 15.11.2.2 Choose the Most Specific Method */
11034
11035 static tree
11036 find_most_specific_methods_list (list)
11037      tree list;
11038 {
11039   int max = 0;
11040   int abstract, candidates;
11041   tree current, new_list = NULL_TREE;
11042   for (current = list; current; current = TREE_CHAIN (current))
11043     {
11044       tree method;
11045       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
11046
11047       for (method = list; method; method = TREE_CHAIN (method))
11048         {
11049           tree method_v, current_v;
11050           /* Don't test a method against itself */
11051           if (method == current)
11052             continue;
11053
11054           method_v = TREE_VALUE (method);
11055           current_v = TREE_VALUE (current);
11056
11057           /* Compare arguments and location where methods where declared */
11058           if (argument_types_convertible (method_v, current_v))
11059             {
11060               if (valid_method_invocation_conversion_p 
11061                   (DECL_CONTEXT (method_v), DECL_CONTEXT (current_v))
11062                   || (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v))
11063                       && enclosing_context_p (DECL_CONTEXT (method_v),
11064                                               DECL_CONTEXT (current_v))))
11065                 {
11066                   int v = (DECL_SPECIFIC_COUNT (current_v) += 
11067                     (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v)) ? 2 : 1));
11068                   max = (v > max ? v : max);
11069                 }
11070             }
11071         }
11072     }
11073
11074   /* Review the list and select the maximally specific methods */
11075   for (current = list, abstract = -1, candidates = -1;
11076        current; current = TREE_CHAIN (current))
11077     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
11078       {
11079         new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
11080         abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
11081         candidates++;
11082       }
11083
11084   /* If we have several and they're all abstract, just pick the
11085      closest one. */
11086   if (candidates > 0 && (candidates == abstract))
11087     {
11088       new_list = nreverse (new_list);
11089       TREE_CHAIN (new_list) = NULL_TREE;
11090     }
11091
11092   /* We have several (we couldn't find a most specific), all but one
11093      are abstract, we pick the only non abstract one. */
11094   if (candidates > 0 && (candidates == abstract+1))
11095     {
11096       for (current = new_list; current; current = TREE_CHAIN (current))
11097         if (!METHOD_ABSTRACT (TREE_VALUE (current)))
11098           {
11099             TREE_CHAIN (current) = NULL_TREE;
11100             new_list = current;
11101           }
11102     }
11103
11104   /* If we can't find one, lower expectations and try to gather multiple
11105      maximally specific methods */
11106   while (!new_list && max)
11107     {
11108       while (--max > 0)
11109         {
11110           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
11111             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
11112         }
11113     }
11114
11115   return new_list;
11116 }
11117
11118 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
11119    converted by method invocation conversion (5.3) to the type of the
11120    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
11121    to change less often than M1. */
11122
11123 static GTY(()) tree m2_arg_value;
11124 static GTY(()) tree m2_arg_cache;
11125
11126 static int
11127 argument_types_convertible (m1, m2_or_arglist)
11128     tree m1, m2_or_arglist;
11129 {
11130   register tree m1_arg, m2_arg;
11131
11132   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
11133
11134   if (m2_arg_value == m2_or_arglist)
11135     m2_arg = m2_arg_cache;
11136   else
11137     {
11138       /* M2_OR_ARGLIST can be a function DECL or a raw list of
11139          argument types */
11140       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
11141         {
11142           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
11143           if (!METHOD_STATIC (m2_or_arglist))
11144             m2_arg = TREE_CHAIN (m2_arg);
11145         }
11146       else
11147         m2_arg = m2_or_arglist;
11148
11149       m2_arg_value = m2_or_arglist;
11150       m2_arg_cache = m2_arg;
11151     }
11152
11153   while (m1_arg != end_params_node && m2_arg != end_params_node)
11154     {
11155       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
11156       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
11157                                                  TREE_VALUE (m2_arg)))
11158         break;
11159       m1_arg = TREE_CHAIN (m1_arg);
11160       m2_arg = TREE_CHAIN (m2_arg);
11161     }
11162   return m1_arg == end_params_node && m2_arg == end_params_node;
11163 }
11164
11165 /* Qualification routines */
11166
11167 static void
11168 qualify_ambiguous_name (id)
11169      tree id;
11170 {
11171   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
11172     saved_current_class;
11173   int again, super_found = 0, this_found = 0, new_array_found = 0;
11174   int code;
11175
11176   /* We first qualify the first element, then derive qualification of
11177      others based on the first one. If the first element is qualified
11178      by a resolution (field or type), this resolution is stored in the
11179      QUAL_RESOLUTION of the qual element being examined. We need to
11180      save the current_class since the use of SUPER might change the
11181      its value. */
11182   saved_current_class = current_class;
11183   qual = EXPR_WFL_QUALIFICATION (id);
11184   do {
11185
11186     /* Simple qualified expression feature a qual_wfl that is a
11187        WFL. Expression derived from a primary feature more complicated
11188        things like a CALL_EXPR. Expression from primary need to be
11189        worked out to extract the part on which the qualification will
11190        take place. */
11191     qual_wfl = QUAL_WFL (qual);
11192     switch (TREE_CODE (qual_wfl))
11193       {
11194       case CALL_EXPR:
11195         qual_wfl = TREE_OPERAND (qual_wfl, 0);
11196         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION
11197             || (EXPR_WFL_QUALIFICATION (qual_wfl)
11198                 && TREE_CODE (EXPR_WFL_QUALIFICATION (qual_wfl)) == TREE_LIST))
11199           {
11200             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
11201             qual_wfl = QUAL_WFL (qual);
11202           }
11203         break;
11204       case NEW_ARRAY_EXPR:
11205       case NEW_ANONYMOUS_ARRAY_EXPR:
11206         qual = TREE_CHAIN (qual);
11207         again = new_array_found = 1;
11208         continue;
11209       case CONVERT_EXPR:
11210         break;
11211       case NEW_CLASS_EXPR:
11212         qual_wfl = TREE_OPERAND (qual_wfl, 0);
11213         break;
11214       case ARRAY_REF:
11215         while (TREE_CODE (qual_wfl) == ARRAY_REF)
11216           qual_wfl = TREE_OPERAND (qual_wfl, 0);
11217         break;
11218       case STRING_CST:
11219         qual = TREE_CHAIN (qual);
11220         qual_wfl = QUAL_WFL (qual);
11221         break;
11222       case CLASS_LITERAL:
11223         qual = TREE_CHAIN (qual);
11224         qual_wfl = QUAL_WFL (qual);
11225       break;
11226       default:
11227         /* Fix for -Wall. Just break doing nothing */
11228         break;
11229       }
11230
11231     ptr_type = current_class;
11232     again = 0;
11233     code = TREE_CODE (qual_wfl);
11234
11235     /* Pos evaluation: non WFL leading expression nodes */
11236     if (code == CONVERT_EXPR
11237         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
11238       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
11239
11240     else if (code == INTEGER_CST)
11241       name = qual_wfl;
11242
11243     else if (code == CONVERT_EXPR &&
11244              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
11245       name = TREE_OPERAND (qual_wfl, 0);
11246
11247     else if (code == CONVERT_EXPR
11248              && TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == CALL_EXPR
11249              && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0))
11250                  == EXPR_WITH_FILE_LOCATION))
11251       name = TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0);
11252
11253     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
11254              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
11255       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
11256
11257     else if (code == TREE_LIST)
11258       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
11259
11260     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
11261              || code == PLUS_EXPR)
11262       {
11263         qual = TREE_CHAIN (qual);
11264         qual_wfl = QUAL_WFL (qual);
11265         again = 1;
11266       }
11267     else
11268       {
11269         name = EXPR_WFL_NODE (qual_wfl);
11270         if (!name)
11271           {
11272             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
11273             again = 1;
11274           }
11275       }
11276
11277     /* If we have a THIS (from a primary), we set the context accordingly */
11278     if (name == this_identifier_node)
11279       {
11280         /* This isn't really elegant. One more added irregularity
11281            before I start using COMPONENT_REF (hopefully very soon.)  */
11282         if (TREE_CODE (TREE_PURPOSE (qual)) == ARRAY_REF
11283             && TREE_CODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
11284                EXPR_WITH_FILE_LOCATION
11285             && EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) == 
11286                this_identifier_node)
11287             {
11288               qual = TREE_OPERAND (TREE_PURPOSE (qual), 0);
11289               qual = EXPR_WFL_QUALIFICATION (qual);
11290             }
11291         qual = TREE_CHAIN (qual);
11292         qual_wfl = QUAL_WFL (qual);
11293         if (TREE_CODE (qual_wfl) == CALL_EXPR)
11294           again = 1;
11295         else if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION)
11296           name = EXPR_WFL_NODE (qual_wfl);
11297         else if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
11298           name = TREE_OPERAND (qual_wfl, 0);
11299         this_found = 1;
11300       }
11301     /* If we have a SUPER, we set the context accordingly */
11302     if (name == super_identifier_node)
11303       {
11304         current_class = CLASSTYPE_SUPER (ptr_type);
11305         /* Check that there is such a thing as a super class. If not,
11306            return.  The error will be caught later on, during the
11307            resolution */
11308         if (!current_class)
11309           {
11310             current_class = saved_current_class;
11311             return;
11312           }
11313         qual = TREE_CHAIN (qual);
11314         /* Do one more interation to set things up */
11315         super_found = again = 1;
11316       }
11317   } while (again);
11318   
11319   /* If name appears within the scope of a local variable declaration
11320      or parameter declaration, then it is an expression name. We don't
11321      carry this test out if we're in the context of the use of SUPER
11322      or THIS */
11323   if (!this_found && !super_found 
11324       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
11325       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
11326     {
11327       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11328       QUAL_RESOLUTION (qual) = decl;
11329     }
11330
11331   /* If within the class/interface NAME was found to be used there
11332      exists a (possibly inherited) field named NAME, then this is an
11333      expression name. If we saw a NEW_ARRAY_EXPR before and want to
11334      address length, it is OK. */
11335   else if ((decl = lookup_field_wrapper (ptr_type, name))
11336            || name == length_identifier_node)
11337     {
11338       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11339       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
11340     }
11341
11342   /* We reclassify NAME as yielding to a type name resolution if:
11343      - NAME is a class/interface declared within the compilation
11344        unit containing NAME,
11345      - NAME is imported via a single-type-import declaration,
11346      - NAME is declared in an another compilation unit of the package
11347        of the compilation unit containing NAME,
11348      - NAME is declared by exactly on type-import-on-demand declaration
11349      of the compilation unit containing NAME. 
11350      - NAME is actually a STRING_CST.
11351      This can't happen if the expression was qualified by `this.' */
11352   else if (! this_found &&
11353            (TREE_CODE (name) == STRING_CST ||
11354             TREE_CODE (name) == INTEGER_CST ||
11355             (decl = resolve_and_layout (name, NULL_TREE))))
11356     {
11357       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
11358       QUAL_RESOLUTION (qual) = decl;
11359     }
11360
11361   /* Method call, array references and cast are expression name */
11362   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
11363            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
11364            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR
11365            || TREE_CODE (QUAL_WFL (qual)) == MODIFY_EXPR)
11366     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11367
11368   /* Check here that NAME isn't declared by more than one
11369      type-import-on-demand declaration of the compilation unit
11370      containing NAME. FIXME */
11371
11372   /* Otherwise, NAME is reclassified as a package name */
11373   else 
11374     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
11375
11376   /* Propagate the qualification accross other components of the
11377      qualified name */
11378   for (qual = TREE_CHAIN (qual); qual;
11379        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
11380     {
11381       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
11382         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
11383       else 
11384         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
11385     }
11386
11387   /* Store the global qualification for the ambiguous part of ID back
11388      into ID fields */
11389   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
11390     RESOLVE_EXPRESSION_NAME_P (id) = 1;
11391   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
11392     RESOLVE_TYPE_NAME_P (id) = 1;
11393   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
11394     RESOLVE_PACKAGE_NAME_P (id) = 1;
11395
11396   /* Restore the current class */
11397   current_class = saved_current_class;
11398 }
11399
11400 static int
11401 breakdown_qualified (left, right, source)
11402     tree *left, *right, source;
11403 {
11404   char *p, *base;
11405   int   l = IDENTIFIER_LENGTH (source);
11406
11407   base = alloca (l + 1);
11408   memcpy (base, IDENTIFIER_POINTER (source), l + 1);
11409
11410   /* Breakdown NAME into REMAINDER . IDENTIFIER */
11411   p = base + l - 1;
11412   while (*p != '.' && p != base)
11413     p--;
11414
11415   /* We didn't find a '.'. Return an error */
11416   if (p == base)
11417     return 1;
11418
11419   *p = '\0';
11420   if (right)
11421     *right = get_identifier (p+1);
11422   *left = get_identifier (base);
11423   
11424   return 0;
11425 }
11426
11427 /* Return TRUE if two classes are from the same package. */
11428
11429 static int
11430 in_same_package (name1, name2)
11431   tree name1, name2;
11432 {
11433   tree tmp;
11434   tree pkg1;
11435   tree pkg2;
11436   
11437   if (TREE_CODE (name1) == TYPE_DECL)
11438     name1 = DECL_NAME (name1);
11439   if (TREE_CODE (name2) == TYPE_DECL)
11440     name2 = DECL_NAME (name2);
11441
11442   if (QUALIFIED_P (name1) != QUALIFIED_P (name2))
11443     /* One in empty package. */
11444     return 0;
11445
11446   if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0)
11447     /* Both in empty package. */
11448     return 1;
11449
11450   breakdown_qualified (&pkg1, &tmp, name1);
11451   breakdown_qualified (&pkg2, &tmp, name2);
11452   
11453   return (pkg1 == pkg2);
11454 }
11455
11456 /* Patch tree nodes in a function body. When a BLOCK is found, push
11457    local variable decls if present.
11458    Same as java_complete_lhs, but does resolve static finals to values. */
11459
11460 static tree
11461 java_complete_tree (node)
11462      tree node;
11463 {
11464   node = java_complete_lhs (node);
11465   if (JDECL_P (node) && CLASS_FINAL_VARIABLE_P (node)
11466       && DECL_INITIAL (node) != NULL_TREE
11467       && !flag_emit_xref)
11468     {
11469       tree value = DECL_INITIAL (node);
11470       DECL_INITIAL (node) = NULL_TREE;
11471       value = fold_constant_for_init (value, node);
11472       DECL_INITIAL (node) = value;
11473       if (value != NULL_TREE)
11474         {
11475           /* fold_constant_for_init sometimes widens the original type
11476              of the constant (i.e. byte to int). It's not desirable,
11477              especially if NODE is a function argument. */
11478           if ((TREE_CODE (value) == INTEGER_CST
11479                || TREE_CODE (value) == REAL_CST)
11480               && TREE_TYPE (node) != TREE_TYPE (value))
11481             return convert (TREE_TYPE (node), value);
11482           else
11483             return value;
11484         }
11485     }
11486   return node;
11487 }
11488
11489 static tree
11490 java_stabilize_reference (node)
11491      tree node;
11492 {
11493   if (TREE_CODE (node) == COMPOUND_EXPR)
11494     {
11495       tree op0 = TREE_OPERAND (node, 0);
11496       tree op1 = TREE_OPERAND (node, 1);
11497       TREE_OPERAND (node, 0) = save_expr (op0);
11498       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
11499       return node;
11500     }
11501   return stabilize_reference (node);
11502 }
11503
11504 /* Patch tree nodes in a function body. When a BLOCK is found, push
11505    local variable decls if present.
11506    Same as java_complete_tree, but does not resolve static finals to values. */
11507
11508 static tree
11509 java_complete_lhs (node)
11510      tree node;
11511 {
11512   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
11513   int flag;
11514
11515   /* CONVERT_EXPR always has its type set, even though it needs to be
11516      worked out. */
11517   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
11518     return node;
11519
11520   /* The switch block implements cases processing container nodes
11521      first.  Contained nodes are always written back. Leaves come
11522      next and return a value. */
11523   switch (TREE_CODE (node))
11524     {
11525     case BLOCK:
11526
11527       /* 1- Block section.
11528          Set the local values on decl names so we can identify them
11529          faster when they're referenced. At that stage, identifiers
11530          are legal so we don't check for declaration errors. */
11531       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11532         {
11533           DECL_CONTEXT (cn) = current_function_decl;
11534           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
11535         }
11536       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
11537           CAN_COMPLETE_NORMALLY (node) = 1;
11538       else
11539         {
11540           tree stmt = BLOCK_EXPR_BODY (node);
11541           tree *ptr;
11542           int error_seen = 0;
11543           if (TREE_CODE (stmt) == COMPOUND_EXPR)
11544             {
11545               /* Re-order from (((A; B); C); ...; Z) to 
11546                  (A; (B; (C ; (...; Z)))).
11547                  This makes it easier to scan the statements left-to-right
11548                  without using recursion (which might overflow the stack
11549                  if the block has many statements. */
11550               for (;;)
11551                 {
11552                   tree left = TREE_OPERAND (stmt, 0);
11553                   if (TREE_CODE (left) != COMPOUND_EXPR)
11554                     break;
11555                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
11556                   TREE_OPERAND (left, 1) = stmt;
11557                   stmt = left;
11558                 }
11559               BLOCK_EXPR_BODY (node) = stmt;
11560             }
11561
11562           /* Now do the actual complete, without deep recursion for
11563              long blocks. */
11564           ptr = &BLOCK_EXPR_BODY (node);
11565           while (TREE_CODE (*ptr) == COMPOUND_EXPR
11566                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
11567             {
11568               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
11569               tree *next = &TREE_OPERAND (*ptr, 1);
11570               TREE_OPERAND (*ptr, 0) = cur;
11571               if (cur == empty_stmt_node)
11572                 {
11573                   /* Optimization;  makes it easier to detect empty bodies.
11574                      Most useful for <clinit> with all-constant initializer. */
11575                   *ptr = *next;
11576                   continue;
11577                 }
11578               if (TREE_CODE (cur) == ERROR_MARK)
11579                 error_seen++;
11580               else if (! CAN_COMPLETE_NORMALLY (cur))
11581                 {
11582                   wfl_op2 = *next;
11583                   for (;;)
11584                     {
11585                       if (TREE_CODE (wfl_op2) == BLOCK)
11586                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
11587                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
11588                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
11589                       else
11590                         break;
11591                     }
11592                   if (TREE_CODE (wfl_op2) != CASE_EXPR
11593                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
11594                     unreachable_stmt_error (*ptr);
11595                 }
11596               ptr = next;
11597             }
11598           *ptr = java_complete_tree (*ptr);
11599
11600           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
11601             return error_mark_node;
11602           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
11603         }
11604       /* Turn local bindings to null */
11605       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11606         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
11607
11608       TREE_TYPE (node) = void_type_node;
11609       break;
11610
11611       /* 2- They are expressions but ultimately deal with statements */
11612
11613     case THROW_EXPR:
11614       wfl_op1 = TREE_OPERAND (node, 0);
11615       COMPLETE_CHECK_OP_0 (node);
11616       /* 14.19 A throw statement cannot complete normally. */
11617       CAN_COMPLETE_NORMALLY (node) = 0;
11618       return patch_throw_statement (node, wfl_op1);
11619
11620     case SYNCHRONIZED_EXPR:
11621       wfl_op1 = TREE_OPERAND (node, 0);
11622       return patch_synchronized_statement (node, wfl_op1);
11623
11624     case TRY_EXPR:
11625       return patch_try_statement (node);
11626
11627     case TRY_FINALLY_EXPR:
11628       COMPLETE_CHECK_OP_0 (node);
11629       COMPLETE_CHECK_OP_1 (node);
11630       if (TREE_OPERAND (node, 0) == empty_stmt_node)
11631         return TREE_OPERAND (node, 1);
11632       if (TREE_OPERAND (node, 1) == empty_stmt_node)
11633         return TREE_OPERAND (node, 0);
11634       CAN_COMPLETE_NORMALLY (node)
11635         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
11636            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
11637       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
11638       return node;
11639
11640     case LABELED_BLOCK_EXPR:
11641       PUSH_LABELED_BLOCK (node);
11642       if (LABELED_BLOCK_BODY (node))
11643         COMPLETE_CHECK_OP_1 (node);
11644       TREE_TYPE (node) = void_type_node;
11645       POP_LABELED_BLOCK ();
11646
11647       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
11648         {
11649           LABELED_BLOCK_BODY (node) = NULL_TREE;
11650           CAN_COMPLETE_NORMALLY (node) = 1;
11651         }
11652       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
11653         CAN_COMPLETE_NORMALLY (node) = 1;
11654       return node;
11655
11656     case EXIT_BLOCK_EXPR:
11657       /* We don't complete operand 1, because it's the return value of
11658          the EXIT_BLOCK_EXPR which doesn't exist it Java */
11659       return patch_bc_statement (node);
11660
11661     case CASE_EXPR:
11662       cn = java_complete_tree (TREE_OPERAND (node, 0));
11663       if (cn == error_mark_node)
11664         return cn;
11665
11666       /* First, the case expression must be constant. Values of final
11667          fields are accepted. */
11668       cn = fold (cn);
11669       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
11670           && JDECL_P (TREE_OPERAND (cn, 1))
11671           && FIELD_FINAL (TREE_OPERAND (cn, 1))
11672           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
11673         {
11674           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
11675                                        TREE_OPERAND (cn, 1));
11676         }
11677       /* Accept final locals too. */
11678       else if (TREE_CODE (cn) == VAR_DECL && DECL_FINAL (cn))
11679         cn = fold_constant_for_init (DECL_INITIAL (cn), cn);
11680
11681       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
11682         {
11683           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11684           parse_error_context (node, "Constant expression required");
11685           return error_mark_node;
11686         }
11687
11688       nn = ctxp->current_loop;
11689
11690       /* It must be assignable to the type of the switch expression. */
11691       if (!try_builtin_assignconv (NULL_TREE, 
11692                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
11693         {
11694           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11695           parse_error_context 
11696             (wfl_operator,
11697              "Incompatible type for case. Can't convert `%s' to `int'",
11698              lang_printable_name (TREE_TYPE (cn), 0));
11699           return error_mark_node;
11700         }
11701
11702       cn = fold (convert (int_type_node, cn));
11703       TREE_CONSTANT_OVERFLOW (cn) = 0;
11704       CAN_COMPLETE_NORMALLY (cn) = 1;
11705
11706       /* Save the label on a list so that we can later check for
11707          duplicates.  */
11708       case_label_list = tree_cons (node, cn, case_label_list);
11709
11710       /* Multiple instance of a case label bearing the same value is
11711          checked later. The case expression is all right so far. */
11712       if (TREE_CODE (cn) == VAR_DECL)
11713         cn = DECL_INITIAL (cn);
11714       TREE_OPERAND (node, 0) = cn;
11715       TREE_TYPE (node) = void_type_node;
11716       CAN_COMPLETE_NORMALLY (node) = 1;
11717       TREE_SIDE_EFFECTS (node) = 1;
11718       break;
11719
11720     case DEFAULT_EXPR:
11721       nn = ctxp->current_loop;
11722       /* Only one default label is allowed per switch statement */
11723       if (SWITCH_HAS_DEFAULT (nn))
11724         {
11725           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11726           parse_error_context (wfl_operator, 
11727                                "Duplicate case label: `default'");
11728           return error_mark_node;
11729         }
11730       else
11731         SWITCH_HAS_DEFAULT (nn) = 1;
11732       TREE_TYPE (node) = void_type_node;
11733       TREE_SIDE_EFFECTS (node) = 1;
11734       CAN_COMPLETE_NORMALLY (node) = 1;
11735       break;
11736
11737     case SWITCH_EXPR:
11738     case LOOP_EXPR:
11739       PUSH_LOOP (node);
11740       /* Check whether the loop was enclosed in a labeled
11741          statement. If not, create one, insert the loop in it and
11742          return the node */
11743       nn = patch_loop_statement (node);
11744
11745       /* Anyways, walk the body of the loop */
11746       if (TREE_CODE (node) == LOOP_EXPR)
11747         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11748       /* Switch statement: walk the switch expression and the cases */
11749       else
11750         node = patch_switch_statement (node);
11751
11752       if (node == error_mark_node || TREE_OPERAND (node, 0) == error_mark_node)
11753         nn = error_mark_node;
11754       else
11755         {
11756           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
11757           /* If we returned something different, that's because we
11758              inserted a label. Pop the label too. */
11759           if (nn != node)
11760             {
11761               if (CAN_COMPLETE_NORMALLY (node))
11762                 CAN_COMPLETE_NORMALLY (nn) = 1;
11763               POP_LABELED_BLOCK ();
11764             }
11765         }
11766       POP_LOOP ();
11767       return nn;
11768
11769     case EXIT_EXPR:
11770       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11771       return patch_exit_expr (node);
11772
11773     case COND_EXPR:
11774       /* Condition */
11775       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11776       if (TREE_OPERAND (node, 0) == error_mark_node)
11777         return error_mark_node;
11778       /* then-else branches */
11779       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11780       if (TREE_OPERAND (node, 1) == error_mark_node)
11781         return error_mark_node;
11782       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
11783       if (TREE_OPERAND (node, 2) == error_mark_node)
11784         return error_mark_node;
11785       return patch_if_else_statement (node);
11786       break;
11787
11788     case CONDITIONAL_EXPR:
11789       /* Condition */
11790       wfl_op1 = TREE_OPERAND (node, 0);
11791       COMPLETE_CHECK_OP_0 (node);
11792       wfl_op2 = TREE_OPERAND (node, 1);
11793       COMPLETE_CHECK_OP_1 (node);
11794       wfl_op3 = TREE_OPERAND (node, 2);
11795       COMPLETE_CHECK_OP_2 (node);
11796       return patch_conditional_expr (node, wfl_op1, wfl_op2);
11797
11798       /* 3- Expression section */
11799     case COMPOUND_EXPR:
11800       wfl_op2 = TREE_OPERAND (node, 1);
11801       TREE_OPERAND (node, 0) = nn = 
11802         java_complete_tree (TREE_OPERAND (node, 0));
11803       if (wfl_op2 == empty_stmt_node)
11804         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
11805       else
11806         {
11807           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
11808             {
11809               /* An unreachable condition in a do-while statement
11810                  is *not* (technically) an unreachable statement. */
11811               nn = wfl_op2;
11812               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
11813                 nn = EXPR_WFL_NODE (nn);
11814               if (TREE_CODE (nn) != EXIT_EXPR)
11815                 {
11816                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
11817                   if (SUPPRESS_UNREACHABLE_ERROR (nn))
11818                     {
11819                       /* Perhaps this warning should have an
11820                          associated flag.  The code being compiled is
11821                          pedantically correct, but useless.  */
11822                       parse_warning_context (wfl_operator,
11823                                              "Unreachable statement");
11824                     }
11825                   else
11826                     parse_error_context (wfl_operator,
11827                                          "Unreachable statement");
11828                 }
11829             }
11830           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11831           if (TREE_OPERAND (node, 1) == error_mark_node)
11832             return error_mark_node;
11833           /* Even though we might allow the case where the first
11834              operand doesn't return normally, we still should compute
11835              CAN_COMPLETE_NORMALLY correctly.  */
11836           CAN_COMPLETE_NORMALLY (node)
11837             = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
11838                && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
11839         }
11840       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
11841       break;
11842
11843     case RETURN_EXPR:
11844       /* CAN_COMPLETE_NORMALLY (node) = 0; */
11845       return patch_return (node);
11846
11847     case EXPR_WITH_FILE_LOCATION:
11848       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11849           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11850         {
11851           tree wfl = node;
11852           node = resolve_expression_name (node, NULL);
11853           if (node == error_mark_node)
11854             return node;
11855           /* Keep line number information somewhere were it doesn't
11856              disrupt the completion process. */
11857           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
11858             {
11859               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
11860               TREE_OPERAND (node, 1) = wfl;
11861             }
11862           CAN_COMPLETE_NORMALLY (node) = 1;
11863         }
11864       else
11865         {
11866           tree body;
11867           int save_lineno = lineno;
11868           lineno = EXPR_WFL_LINENO (node);
11869           body = java_complete_tree (EXPR_WFL_NODE (node));
11870           lineno = save_lineno;
11871           EXPR_WFL_NODE (node) = body;
11872           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
11873           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
11874           if (body == empty_stmt_node || TREE_CONSTANT (body))
11875             {
11876               /* Makes it easier to constant fold, detect empty bodies. */
11877               return body;
11878             }
11879           if (body == error_mark_node)
11880             {
11881               /* Its important for the evaluation of assignment that
11882                  this mark on the TREE_TYPE is propagated. */
11883               TREE_TYPE (node) = error_mark_node;
11884               return error_mark_node;
11885             }
11886           else
11887             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
11888           
11889         }
11890       break;
11891
11892     case NEW_ARRAY_EXPR:
11893       /* Patch all the dimensions */
11894       flag = 0;
11895       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11896         {
11897           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
11898           tree dim = convert (int_type_node, 
11899                               java_complete_tree (TREE_VALUE (cn)));
11900           if (dim == error_mark_node)
11901             {
11902               flag = 1;
11903               continue;
11904             }
11905           else
11906             {
11907               TREE_VALUE (cn) = dim;
11908               /* Setup the location of the current dimension, for
11909                  later error report. */
11910               TREE_PURPOSE (cn) = 
11911                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
11912               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
11913             }
11914         }
11915       /* They complete the array creation expression, if no errors
11916          were found. */
11917       CAN_COMPLETE_NORMALLY (node) = 1;
11918       return (flag ? error_mark_node
11919               : force_evaluation_order (patch_newarray (node)));
11920
11921     case NEW_ANONYMOUS_ARRAY_EXPR:
11922       /* Create the array type if necessary. */
11923       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
11924         {
11925           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
11926           if (!(type = resolve_type_during_patch (type)))
11927             return error_mark_node;
11928           type = build_array_from_name (type, NULL_TREE,
11929                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
11930           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
11931         }
11932       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
11933                                    ANONYMOUS_ARRAY_INITIALIZER (node));
11934       if (node == error_mark_node)
11935         return error_mark_node;
11936       CAN_COMPLETE_NORMALLY (node) = 1;
11937       return node;
11938
11939     case NEW_CLASS_EXPR:
11940     case CALL_EXPR:
11941       /* Complete function's argument(s) first */
11942       if (complete_function_arguments (node))
11943         return error_mark_node;
11944       else
11945         {
11946           tree decl, wfl = TREE_OPERAND (node, 0);
11947           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
11948           int from_super = (EXPR_WFL_NODE (TREE_OPERAND (node, 0)) ==
11949                            super_identifier_node);
11950
11951           node = patch_method_invocation (node, NULL_TREE, NULL_TREE,
11952                                           from_super, 0, &decl);
11953           if (node == error_mark_node)
11954             return error_mark_node;
11955
11956           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
11957           /* If we call this(...), register signature and positions */
11958           if (in_this)
11959             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
11960               tree_cons (wfl, decl, 
11961                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
11962           CAN_COMPLETE_NORMALLY (node) = 1;
11963           return force_evaluation_order (node);
11964         }
11965
11966     case MODIFY_EXPR:
11967       /* Save potential wfls */
11968       wfl_op1 = TREE_OPERAND (node, 0);
11969       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
11970       
11971       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
11972           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
11973           && DECL_INITIAL (nn) != NULL_TREE)
11974         {
11975           tree value;
11976           
11977           value = fold_constant_for_init (nn, nn);
11978
11979           /* When we have a primitype type, or a string and we're not
11980              emitting a class file, we actually don't want to generate
11981              anything for the assignment. */
11982           if (value != NULL_TREE &&
11983               (JPRIMITIVE_TYPE_P (TREE_TYPE (value)) || 
11984                (TREE_TYPE (value) == string_ptr_type_node &&
11985                 ! flag_emit_class_files)))
11986             {
11987               /* Prepare node for patch_assignment */
11988               TREE_OPERAND (node, 1) = value;
11989               /* Call patch assignment to verify the assignment */
11990               if (patch_assignment (node, wfl_op1) == error_mark_node)
11991                 return error_mark_node;
11992               /* Set DECL_INITIAL properly (a conversion might have
11993                  been decided by patch_assignment) and return the
11994                  empty statement. */
11995               else
11996                 {
11997                   tree patched = patch_string (TREE_OPERAND (node, 1));
11998                   if (patched)
11999                     DECL_INITIAL (nn) = patched;
12000                   else
12001                     DECL_INITIAL (nn) = TREE_OPERAND (node, 1);
12002                   DECL_FIELD_FINAL_IUD (nn) = 1;
12003                   return empty_stmt_node;
12004                 }
12005             }
12006           if (! flag_emit_class_files)
12007             DECL_INITIAL (nn) = NULL_TREE;
12008         }
12009       wfl_op2 = TREE_OPERAND (node, 1);
12010
12011       if (TREE_OPERAND (node, 0) == error_mark_node)
12012         return error_mark_node;
12013
12014       flag = COMPOUND_ASSIGN_P (wfl_op2);
12015       if (flag)
12016         {
12017           /* This might break when accessing outer field from inner
12018              class. TESTME, FIXME */
12019           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
12020
12021           /* Hand stabilize the lhs on both places */
12022           TREE_OPERAND (node, 0) = lvalue;
12023           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
12024             (flag_emit_class_files ? lvalue : save_expr (lvalue));
12025
12026           /* 15.25.2.a: Left hand is not an array access. FIXME */
12027           /* Now complete the RHS. We write it back later on. */
12028           nn = java_complete_tree (TREE_OPERAND (node, 1));
12029
12030           if ((cn = patch_string (nn)))
12031             nn = cn;
12032
12033           /* The last part of the rewrite for E1 op= E2 is to have 
12034              E1 = (T)(E1 op E2), with T being the type of E1. */
12035           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
12036                                                TREE_TYPE (lvalue), nn));
12037
12038           /* If the assignment is compound and has reference type,
12039              then ensure the LHS has type String and nothing else.  */
12040           if (JREFERENCE_TYPE_P (TREE_TYPE (lvalue))
12041               && ! JSTRING_TYPE_P (TREE_TYPE (lvalue)))
12042             parse_error_context (wfl_op2,
12043                                  "Incompatible type for `+='. Can't convert `%s' to `java.lang.String'",
12044                                  lang_printable_name (TREE_TYPE (lvalue), 0));
12045
12046           /* 15.25.2.b: Left hand is an array access. FIXME */
12047         }
12048
12049       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
12050          function to complete this RHS. Note that a NEW_ARRAY_INIT
12051          might have been already fully expanded if created as a result
12052          of processing an anonymous array initializer. We avoid doing
12053          the operation twice by testing whether the node already bears
12054          a type. */
12055       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
12056         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
12057                                    TREE_OPERAND (node, 1));
12058       /* Otherwise we simply complete the RHS */
12059       else
12060         nn = java_complete_tree (TREE_OPERAND (node, 1));
12061
12062       if (nn == error_mark_node)
12063         return error_mark_node;
12064
12065       /* Write back the RHS as we evaluated it. */
12066       TREE_OPERAND (node, 1) = nn;
12067
12068       /* In case we're handling = with a String as a RHS, we need to
12069          produce a String out of the RHS (it might still be a
12070          STRING_CST or a StringBuffer at this stage */
12071       if ((nn = patch_string (TREE_OPERAND (node, 1))))
12072         TREE_OPERAND (node, 1) = nn;
12073
12074       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
12075                                         TREE_OPERAND (node, 1))))
12076         {
12077           /* We return error_mark_node if outer_field_access_fix
12078              detects we write into a final. */
12079           if (nn == error_mark_node)
12080             return error_mark_node;
12081           node = nn;
12082         }
12083       else
12084         {
12085           node = patch_assignment (node, wfl_op1);
12086           if (node == error_mark_node)
12087             return error_mark_node;
12088           /* Reorganize the tree if necessary. */
12089           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
12090                        || JSTRING_P (TREE_TYPE (node))))
12091             node = java_refold (node);
12092         }
12093
12094       /* Seek to set DECL_INITIAL to a proper value, since it might have
12095          undergone a conversion in patch_assignment. We do that only when
12096          it's necessary to have DECL_INITIAL properly set. */
12097       nn = TREE_OPERAND (node, 0);
12098       if (TREE_CODE (nn) == VAR_DECL 
12099           && DECL_INITIAL (nn) && CONSTANT_VALUE_P (DECL_INITIAL (nn))
12100           && FIELD_STATIC (nn) && FIELD_FINAL (nn) 
12101           && (JPRIMITIVE_TYPE_P (TREE_TYPE (nn))
12102               || TREE_TYPE (nn) == string_ptr_type_node))
12103         DECL_INITIAL (nn) = TREE_OPERAND (node, 1);
12104
12105       CAN_COMPLETE_NORMALLY (node) = 1;
12106       return node;
12107
12108     case MULT_EXPR:
12109     case PLUS_EXPR:
12110     case MINUS_EXPR:
12111     case LSHIFT_EXPR:
12112     case RSHIFT_EXPR:
12113     case URSHIFT_EXPR:
12114     case BIT_AND_EXPR:
12115     case BIT_XOR_EXPR:
12116     case BIT_IOR_EXPR:
12117     case TRUNC_MOD_EXPR:
12118     case TRUNC_DIV_EXPR:
12119     case RDIV_EXPR:
12120     case TRUTH_ANDIF_EXPR:
12121     case TRUTH_ORIF_EXPR:
12122     case EQ_EXPR: 
12123     case NE_EXPR:
12124     case GT_EXPR:
12125     case GE_EXPR:
12126     case LT_EXPR:
12127     case LE_EXPR:
12128       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
12129          knows how to handle those cases. */
12130       wfl_op1 = TREE_OPERAND (node, 0);
12131       wfl_op2 = TREE_OPERAND (node, 1);
12132
12133       CAN_COMPLETE_NORMALLY (node) = 1;
12134       /* Don't complete string nodes if dealing with the PLUS operand. */
12135       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
12136         {
12137           nn = java_complete_tree (wfl_op1);
12138           if (nn == error_mark_node)
12139             return error_mark_node;
12140
12141           TREE_OPERAND (node, 0) = nn;
12142         }
12143       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
12144         {
12145           nn = java_complete_tree (wfl_op2);
12146           if (nn == error_mark_node)
12147             return error_mark_node;
12148
12149           TREE_OPERAND (node, 1) = nn;
12150         }
12151       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
12152
12153     case INSTANCEOF_EXPR:
12154       wfl_op1 = TREE_OPERAND (node, 0);
12155       COMPLETE_CHECK_OP_0 (node);
12156       if (flag_emit_xref)
12157         {
12158           TREE_TYPE (node) = boolean_type_node;
12159           return node;
12160         }
12161       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
12162
12163     case UNARY_PLUS_EXPR:
12164     case NEGATE_EXPR:
12165     case TRUTH_NOT_EXPR:
12166     case BIT_NOT_EXPR:
12167     case PREDECREMENT_EXPR:
12168     case PREINCREMENT_EXPR:
12169     case POSTDECREMENT_EXPR:
12170     case POSTINCREMENT_EXPR:
12171     case CONVERT_EXPR:
12172       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
12173          how to handle those cases. */
12174       wfl_op1 = TREE_OPERAND (node, 0);
12175       CAN_COMPLETE_NORMALLY (node) = 1;
12176       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
12177       if (TREE_OPERAND (node, 0) == error_mark_node)
12178         return error_mark_node;
12179       node = patch_unaryop (node, wfl_op1);
12180       CAN_COMPLETE_NORMALLY (node) = 1;
12181       break;
12182
12183     case ARRAY_REF:
12184       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
12185          how to handle those cases. */
12186       wfl_op1 = TREE_OPERAND (node, 0);
12187       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
12188       if (TREE_OPERAND (node, 0) == error_mark_node)
12189         return error_mark_node;
12190       if (!flag_emit_class_files && !flag_emit_xref)
12191         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
12192       /* The same applies to wfl_op2 */
12193       wfl_op2 = TREE_OPERAND (node, 1);
12194       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
12195       if (TREE_OPERAND (node, 1) == error_mark_node)
12196         return error_mark_node;
12197       if (!flag_emit_class_files && !flag_emit_xref)
12198         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
12199       return patch_array_ref (node);
12200
12201     case RECORD_TYPE:
12202       return node;;
12203
12204     case COMPONENT_REF:
12205       /* The first step in the re-write of qualified name handling.  FIXME.
12206          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
12207       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
12208       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
12209         {
12210           tree name = TREE_OPERAND (node, 1);
12211           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
12212           if (field == NULL_TREE)
12213             {
12214               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
12215               return error_mark_node;
12216             }
12217           if (! FIELD_STATIC (field))
12218             {
12219               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
12220               return error_mark_node;
12221             }
12222           return field;
12223         }
12224       else
12225         abort ();
12226       break;
12227
12228     case THIS_EXPR:
12229       /* Can't use THIS in a static environment */
12230       if (!current_this)
12231         {
12232           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12233           parse_error_context (wfl_operator,
12234                                "Keyword `this' used outside allowed context");
12235           TREE_TYPE (node) = error_mark_node;
12236           return error_mark_node;
12237         }
12238       if (ctxp->explicit_constructor_p)
12239         {
12240           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12241           parse_error_context 
12242             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
12243           TREE_TYPE (node) = error_mark_node;
12244           return error_mark_node;
12245         }
12246       return current_this;
12247       
12248     case CLASS_LITERAL:
12249       CAN_COMPLETE_NORMALLY (node) = 1;
12250       node = patch_incomplete_class_ref (node);
12251       if (node == error_mark_node)
12252         return error_mark_node;
12253       break;
12254
12255     default:
12256       CAN_COMPLETE_NORMALLY (node) = 1;
12257       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
12258          and it's time to turn it into the appropriate String object */
12259       if ((nn = patch_string (node)))
12260         node = nn;
12261       else
12262         internal_error ("No case for %s", tree_code_name [TREE_CODE (node)]);
12263     }
12264   return node;
12265 }
12266
12267 /* Complete function call's argument. Return a non zero value is an
12268    error was found.  */
12269
12270 static int
12271 complete_function_arguments (node)
12272      tree node;
12273 {
12274   int flag = 0;
12275   tree cn;
12276
12277   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
12278   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
12279     {
12280       tree wfl = TREE_VALUE (cn), parm, temp;
12281       parm = java_complete_tree (wfl);
12282
12283       if (parm == error_mark_node)
12284         {
12285           flag = 1;
12286           continue;
12287         }
12288       /* If have a string literal that we haven't transformed yet or a
12289          crafted string buffer, as a result of use of the the String
12290          `+' operator. Build `parm.toString()' and expand it. */
12291       if ((temp = patch_string (parm)))
12292         parm = temp;
12293
12294       TREE_VALUE (cn) = parm;
12295     }
12296   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
12297   return flag;
12298 }
12299
12300 /* Sometimes (for loops and variable initialized during their
12301    declaration), we want to wrap a statement around a WFL and turn it
12302    debugable.  */
12303
12304 static tree
12305 build_debugable_stmt (location, stmt)
12306     int location;
12307     tree stmt;
12308 {
12309   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
12310     {
12311       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
12312       EXPR_WFL_LINECOL (stmt) = location;
12313     }
12314   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
12315   return stmt;
12316 }
12317
12318 static tree
12319 build_expr_block (body, decls)
12320      tree body, decls;
12321 {
12322   tree node = make_node (BLOCK);
12323   BLOCK_EXPR_DECLS (node) = decls;
12324   BLOCK_EXPR_BODY (node) = body;
12325   if (body)
12326     TREE_TYPE (node) = TREE_TYPE (body);
12327   TREE_SIDE_EFFECTS (node) = 1;
12328   return node;
12329 }
12330
12331 /* Create a new function block and link it appropriately to current
12332    function block chain */
12333
12334 static tree
12335 enter_block ()
12336 {
12337   tree b = build_expr_block (NULL_TREE, NULL_TREE);
12338
12339   /* Link block B supercontext to the previous block. The current
12340      function DECL is used as supercontext when enter_a_block is called
12341      for the first time for a given function. The current function body
12342      (DECL_FUNCTION_BODY) is set to be block B.  */
12343
12344   tree fndecl = current_function_decl; 
12345
12346   if (!fndecl) {
12347     BLOCK_SUPERCONTEXT (b) = current_static_block;
12348     current_static_block = b;
12349   }
12350
12351   else if (!DECL_FUNCTION_BODY (fndecl))
12352     {
12353       BLOCK_SUPERCONTEXT (b) = fndecl;
12354       DECL_FUNCTION_BODY (fndecl) = b;
12355     }
12356   else
12357     {
12358       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
12359       DECL_FUNCTION_BODY (fndecl) = b;
12360     }
12361   return b;
12362 }
12363
12364 /* Exit a block by changing the current function body
12365    (DECL_FUNCTION_BODY) to the current block super context, only if
12366    the block being exited isn't the method's top level one.  */
12367
12368 static tree
12369 exit_block ()
12370 {
12371   tree b;
12372   if (current_function_decl)
12373     {
12374       b = DECL_FUNCTION_BODY (current_function_decl);
12375       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
12376         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
12377     }
12378   else
12379     {
12380       b = current_static_block;
12381
12382       if (BLOCK_SUPERCONTEXT (b))
12383         current_static_block = BLOCK_SUPERCONTEXT (b);
12384     }
12385   return b;
12386 }
12387
12388 /* Lookup for NAME in the nested function's blocks, all the way up to
12389    the current toplevel one. It complies with Java's local variable
12390    scoping rules.  */
12391
12392 static tree
12393 lookup_name_in_blocks (name)
12394      tree name;
12395 {
12396   tree b = GET_CURRENT_BLOCK (current_function_decl);
12397
12398   while (b != current_function_decl)
12399     {
12400       tree current;
12401
12402       /* Paranoid sanity check. To be removed */
12403       if (TREE_CODE (b) != BLOCK)
12404         abort ();
12405
12406       for (current = BLOCK_EXPR_DECLS (b); current; 
12407            current = TREE_CHAIN (current))
12408         if (DECL_NAME (current) == name)
12409           return current;
12410       b = BLOCK_SUPERCONTEXT (b);
12411     }
12412   return NULL_TREE;
12413 }
12414
12415 static void
12416 maybe_absorb_scoping_blocks ()
12417 {
12418   while (BLOCK_IS_IMPLICIT (GET_CURRENT_BLOCK (current_function_decl)))
12419     {
12420       tree b = exit_block ();
12421       java_method_add_stmt (current_function_decl, b);
12422       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
12423     }
12424 }
12425
12426 \f
12427 /* This section of the source is reserved to build_* functions that
12428    are building incomplete tree nodes and the patch_* functions that
12429    are completing them.  */
12430
12431 /* Wrap a non WFL node around a WFL.  */
12432
12433 static tree
12434 build_wfl_wrap (node, location)
12435     tree node;
12436     int location;
12437 {
12438   tree wfl, node_to_insert = node;
12439   
12440   /* We want to process THIS . xxx symbolicaly, to keep it consistent
12441      with the way we're processing SUPER. A THIS from a primary as a
12442      different form than a SUPER. Turn THIS into something symbolic */
12443   if (TREE_CODE (node) == THIS_EXPR)
12444     node_to_insert = wfl = build_wfl_node (this_identifier_node);
12445   else
12446     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
12447
12448   EXPR_WFL_LINECOL (wfl) = location;
12449   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
12450   return wfl;
12451 }
12452
12453 /* Build a super() constructor invocation. Returns empty_stmt_node if
12454    we're currently dealing with the class java.lang.Object. */
12455
12456 static tree
12457 build_super_invocation (mdecl)
12458      tree mdecl;
12459 {
12460   if (DECL_CONTEXT (mdecl) == object_type_node)
12461     return empty_stmt_node;
12462   else
12463     {
12464       tree super_wfl = build_wfl_node (super_identifier_node);
12465       tree a = NULL_TREE, t;
12466       /* If we're dealing with an anonymous class, pass the arguments
12467          of the crafted constructor along. */
12468       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
12469         {
12470           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
12471           for (; t != end_params_node; t = TREE_CHAIN (t))
12472             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
12473         }
12474       return build_method_invocation (super_wfl, a);
12475     }
12476 }
12477
12478 /* Build a SUPER/THIS qualified method invocation.  */
12479
12480 static tree
12481 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
12482      int use_this;
12483      tree name, args;
12484      int lloc, rloc;
12485 {
12486   tree invok;
12487   tree wfl = 
12488     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
12489   EXPR_WFL_LINECOL (wfl) = lloc;
12490   invok = build_method_invocation (name, args);
12491   return make_qualified_primary (wfl, invok, rloc);
12492 }
12493
12494 /* Build an incomplete CALL_EXPR node. */
12495
12496 static tree
12497 build_method_invocation (name, args)
12498     tree name;
12499     tree args;
12500 {
12501   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
12502   TREE_SIDE_EFFECTS (call) = 1;
12503   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12504   return call;
12505 }
12506
12507 /* Build an incomplete new xxx(...) node. */
12508
12509 static tree
12510 build_new_invocation (name, args)
12511     tree name, args;
12512 {
12513   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
12514   TREE_SIDE_EFFECTS (call) = 1;
12515   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12516   return call;
12517 }
12518
12519 /* Build an incomplete assignment expression. */
12520
12521 static tree
12522 build_assignment (op, op_location, lhs, rhs)
12523      int op, op_location;
12524      tree lhs, rhs;
12525 {
12526   tree assignment;
12527   /* Build the corresponding binop if we deal with a Compound
12528      Assignment operator. Mark the binop sub-tree as part of a
12529      Compound Assignment expression */
12530   if (op != ASSIGN_TK)
12531     {
12532       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
12533       COMPOUND_ASSIGN_P (rhs) = 1;
12534     }
12535   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
12536   TREE_SIDE_EFFECTS (assignment) = 1;
12537   EXPR_WFL_LINECOL (assignment) = op_location;
12538   return assignment;
12539 }
12540
12541 /* Print an INTEGER_CST node as decimal in a static buffer, and return
12542    the buffer.  This is used only for string conversion.  */
12543 static char *
12544 string_convert_int_cst (node)
12545      tree node;
12546 {
12547   static char buffer[80];
12548
12549   unsigned HOST_WIDE_INT lo = TREE_INT_CST_LOW (node);
12550   unsigned HOST_WIDE_INT hi = TREE_INT_CST_HIGH (node);
12551   char *p = buffer + sizeof (buffer) - 1;
12552   int neg = 0;
12553
12554   unsigned HOST_WIDE_INT hibit = (((unsigned HOST_WIDE_INT) 1)
12555                                   << (HOST_BITS_PER_WIDE_INT - 1));
12556
12557   *p-- = '\0';
12558
12559   /* If negative, note the fact and negate the value.  */
12560   if ((hi & hibit))
12561     {
12562       lo = ~lo;
12563       hi = ~hi;
12564       if (++lo == 0)
12565         ++hi;
12566       neg = 1;
12567     }
12568
12569   /* Divide by 10 until there are no bits left.  */
12570   while (hi || lo)
12571     {
12572       unsigned HOST_WIDE_INT acc = 0;
12573       unsigned HOST_WIDE_INT outhi = 0, outlo = 0;
12574       unsigned int i;
12575
12576       /* Use long division to compute the result and the remainder.  */
12577       for (i = 0; i < 2 * HOST_BITS_PER_WIDE_INT; ++i)
12578         {
12579           /* Shift a bit into accumulator.  */
12580           acc <<= 1;
12581           if ((hi & hibit))
12582             acc |= 1;
12583
12584           /* Shift the value.  */
12585           hi <<= 1;
12586           if ((lo & hibit))
12587             hi |= 1;
12588           lo <<= 1;
12589
12590           /* Shift the correct bit into the result.  */
12591           outhi <<= 1;
12592           if ((outlo & hibit))
12593             outhi |= 1;
12594           outlo <<= 1;
12595           if (acc >= 10)
12596             {
12597               acc -= 10;
12598               outlo |= 1;
12599             }
12600         }
12601
12602       /* FIXME: ASCII assumption.  */
12603       *p-- = '0' + acc;
12604
12605       hi = outhi;
12606       lo = outlo;
12607     }
12608
12609   if (neg)
12610     *p-- = '-';
12611
12612   return p + 1;
12613 }
12614
12615 /* Print an INTEGER_CST node in a static buffer, and return the
12616    buffer.  This is used only for error handling.  */
12617 char *
12618 print_int_node (node)
12619     tree node;
12620 {
12621   static char buffer [80];
12622   if (TREE_CONSTANT_OVERFLOW (node))
12623     sprintf (buffer, "<overflow>");
12624     
12625   if (TREE_INT_CST_HIGH (node) == 0)
12626     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
12627              TREE_INT_CST_LOW (node));
12628   else if (TREE_INT_CST_HIGH (node) == -1
12629            && TREE_INT_CST_LOW (node) != 0)
12630     {
12631       buffer [0] = '-';
12632       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
12633                -TREE_INT_CST_LOW (node));
12634     }
12635   else
12636     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
12637              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
12638
12639   return buffer;
12640 }
12641
12642 \f
12643 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
12644    context.  */
12645
12646 /* 15.25 Assignment operators. */
12647
12648 static tree
12649 patch_assignment (node, wfl_op1)
12650      tree node;
12651      tree wfl_op1;
12652 {
12653   tree rhs = TREE_OPERAND (node, 1);
12654   tree lvalue = TREE_OPERAND (node, 0), llvalue;
12655   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
12656   int error_found = 0;
12657   int lvalue_from_array = 0;
12658   int is_return = 0;
12659
12660   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12661
12662   /* Lhs can be a named variable */
12663   if (JDECL_P (lvalue))
12664     {
12665       lhs_type = TREE_TYPE (lvalue);
12666     }
12667   /* Or Lhs can be an array access. */
12668   else if (TREE_CODE (lvalue) == ARRAY_REF)
12669     {
12670       lhs_type = TREE_TYPE (lvalue);
12671       lvalue_from_array = 1;
12672     }
12673   /* Or a field access */
12674   else if (TREE_CODE (lvalue) == COMPONENT_REF)
12675     lhs_type = TREE_TYPE (lvalue);
12676   /* Or a function return slot */
12677   else if (TREE_CODE (lvalue) == RESULT_DECL)
12678     {
12679       /* If the return type is an integral type, then we create the
12680          RESULT_DECL with a promoted type, but we need to do these
12681          checks against the unpromoted type to ensure type safety.  So
12682          here we look at the real type, not the type of the decl we
12683          are modifying.  */
12684       lhs_type = TREE_TYPE (TREE_TYPE (current_function_decl));
12685       is_return = 1;
12686     }
12687   /* Otherwise, we might want to try to write into an optimized static
12688      final, this is an of a different nature, reported further on. */
12689   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
12690            && resolve_expression_name (wfl_op1, &llvalue))
12691     {
12692       lhs_type = TREE_TYPE (lvalue);
12693     }
12694   else 
12695     {
12696       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
12697       error_found = 1;
12698     }
12699
12700   rhs_type = TREE_TYPE (rhs);
12701
12702   /* 5.1 Try the assignment conversion for builtin type. */
12703   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
12704
12705   /* 5.2 If it failed, try a reference conversion */
12706   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
12707     lhs_type = promote_type (rhs_type);
12708
12709   /* 15.25.2 If we have a compound assignment, convert RHS into the
12710      type of the LHS */
12711   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12712     new_rhs = convert (lhs_type, rhs);
12713
12714   /* Explicit cast required. This is an error */
12715   if (!new_rhs)
12716     {
12717       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
12718       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
12719       tree wfl;
12720       char operation [32];      /* Max size known */
12721
12722       /* If the assignment is part of a declaration, we use the WFL of
12723          the declared variable to point out the error and call it a
12724          declaration problem. If the assignment is a genuine =
12725          operator, we call is a operator `=' problem, otherwise we
12726          call it an assignment problem. In both of these last cases,
12727          we use the WFL of the operator to indicate the error. */
12728
12729       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
12730         {
12731           wfl = wfl_op1;
12732           strcpy (operation, "declaration");
12733         }
12734       else
12735         {
12736           wfl = wfl_operator;
12737           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12738             strcpy (operation, "assignment");
12739           else if (is_return)
12740             strcpy (operation, "`return'");
12741           else
12742             strcpy (operation, "`='");
12743         }
12744
12745       if (!valid_cast_to_p (rhs_type, lhs_type))
12746         parse_error_context
12747           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
12748            operation, t1, t2);
12749       else
12750         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
12751                              operation, t1, t2);
12752       free (t1); free (t2);
12753       error_found = 1;
12754     }
12755
12756   if (error_found)
12757     return error_mark_node;
12758
12759   /* If we're processing a `return' statement, promote the actual type
12760      to the promoted type.  */
12761   if (is_return)
12762     new_rhs = convert (TREE_TYPE (lvalue), new_rhs);
12763
12764   /* 10.10: Array Store Exception runtime check */
12765   if (!flag_emit_class_files
12766       && !flag_emit_xref
12767       && lvalue_from_array 
12768       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
12769     {
12770       tree array, store_check, base, index_expr;
12771       
12772       /* Save RHS so that it doesn't get re-evaluated by the store check. */ 
12773       new_rhs = save_expr (new_rhs);
12774
12775       /* Get the INDIRECT_REF. */
12776       array = TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0);
12777       /* Get the array pointer expr. */
12778       array = TREE_OPERAND (array, 0);
12779       store_check = build_java_arraystore_check (array, new_rhs);
12780       
12781       index_expr = TREE_OPERAND (lvalue, 1);
12782       
12783       if (TREE_CODE (index_expr) == COMPOUND_EXPR)
12784         {
12785           /* A COMPOUND_EXPR here is a bounds check. The bounds check must 
12786              happen before the store check, so prepare to insert the store
12787              check within the second operand of the existing COMPOUND_EXPR. */
12788           base = index_expr;
12789         }
12790       else
12791         base = lvalue;
12792       
12793       index_expr = TREE_OPERAND (base, 1);
12794       TREE_OPERAND (base, 1) = build (COMPOUND_EXPR, TREE_TYPE (index_expr), 
12795                                       store_check, index_expr);
12796     }
12797
12798   /* Final locals can be used as case values in switch
12799      statement. Prepare them for this eventuality. */
12800   if (TREE_CODE (lvalue) == VAR_DECL 
12801       && DECL_FINAL (lvalue)
12802       && TREE_CONSTANT (new_rhs)
12803       && IDENTIFIER_LOCAL_VALUE (DECL_NAME (lvalue))
12804       && JINTEGRAL_TYPE_P (TREE_TYPE (lvalue))
12805       )
12806     {
12807       TREE_CONSTANT (lvalue) = 1;
12808       DECL_INITIAL (lvalue) = new_rhs;
12809     }
12810
12811   TREE_OPERAND (node, 0) = lvalue;
12812   TREE_OPERAND (node, 1) = new_rhs;
12813   TREE_TYPE (node) = lhs_type;
12814   return node;
12815 }
12816
12817 /* Check that type SOURCE can be cast into type DEST. If the cast
12818    can't occur at all, return NULL; otherwise, return a possibly
12819    modified rhs.  */
12820
12821 static tree
12822 try_reference_assignconv (lhs_type, rhs)
12823      tree lhs_type, rhs;
12824 {
12825   tree new_rhs = NULL_TREE;
12826   tree rhs_type = TREE_TYPE (rhs);
12827
12828   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
12829     {
12830       /* `null' may be assigned to any reference type */
12831       if (rhs == null_pointer_node)
12832         new_rhs = null_pointer_node;
12833       /* Try the reference assignment conversion */
12834       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
12835         new_rhs = rhs;
12836       /* This is a magic assignment that we process differently */
12837       else if (TREE_CODE (rhs) == JAVA_EXC_OBJ_EXPR)
12838         new_rhs = rhs;
12839     }
12840   return new_rhs;
12841 }
12842
12843 /* Check that RHS can be converted into LHS_TYPE by the assignment
12844    conversion (5.2), for the cases of RHS being a builtin type. Return
12845    NULL_TREE if the conversion fails or if because RHS isn't of a
12846    builtin type. Return a converted RHS if the conversion is possible.  */
12847
12848 static tree
12849 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
12850      tree wfl_op1, lhs_type, rhs;
12851 {
12852   tree new_rhs = NULL_TREE;
12853   tree rhs_type = TREE_TYPE (rhs);
12854
12855   /* Handle boolean specially.  */
12856   if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
12857       || TREE_CODE (lhs_type) == BOOLEAN_TYPE)
12858     {
12859       if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
12860           && TREE_CODE (lhs_type) == BOOLEAN_TYPE)
12861         new_rhs = rhs;
12862     }
12863
12864   /* 5.1.1 Try Identity Conversion,
12865      5.1.2 Try Widening Primitive Conversion */
12866   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
12867     new_rhs = convert (lhs_type, rhs);
12868
12869   /* Try a narrowing primitive conversion (5.1.3): 
12870        - expression is a constant expression of type int AND
12871        - variable is byte, short or char AND
12872        - The value of the expression is representable in the type of the 
12873          variable */
12874   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
12875            && (lhs_type == byte_type_node || lhs_type == char_type_node
12876                || lhs_type == short_type_node))
12877     {
12878       if (int_fits_type_p (rhs, lhs_type))
12879         new_rhs = convert (lhs_type, rhs);
12880       else if (wfl_op1)         /* Might be called with a NULL */
12881         parse_warning_context 
12882           (wfl_op1, "Constant expression `%s' too wide for narrowing primitive conversion to `%s'", 
12883            print_int_node (rhs), lang_printable_name (lhs_type, 0));
12884       /* Reported a warning that will turn into an error further
12885          down, so we don't return */
12886     }
12887
12888   return new_rhs;
12889 }
12890
12891 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
12892    conversion (5.1.1) or widening primitive conversion (5.1.2).  Return
12893    0 is the conversion test fails.  This implements parts the method
12894    invocation convertion (5.3).  */
12895
12896 static int
12897 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
12898      tree lhs_type, rhs_type;
12899 {
12900   /* 5.1.1: This is the identity conversion part. */
12901   if (lhs_type == rhs_type)
12902     return 1;
12903
12904   /* Reject non primitive types and boolean conversions.  */
12905   if (!JNUMERIC_TYPE_P (lhs_type) || !JNUMERIC_TYPE_P (rhs_type))
12906     return 0;
12907
12908   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
12909      than a char can't be converted into a char. Short can't too, but
12910      the < test below takes care of that */
12911   if (lhs_type == char_type_node && rhs_type == byte_type_node)
12912     return 0;
12913
12914   /* Accept all promoted type here. Note, we can't use <= in the test
12915      below, because we still need to bounce out assignments of short
12916      to char and the likes */
12917   if (lhs_type == int_type_node
12918       && (rhs_type == promoted_byte_type_node
12919           || rhs_type == promoted_short_type_node
12920           || rhs_type == promoted_char_type_node
12921           || rhs_type == promoted_boolean_type_node))
12922     return 1;
12923
12924   /* From here, an integral is widened if its precision is smaller
12925      than the precision of the LHS or if the LHS is a floating point
12926      type, or the RHS is a float and the RHS a double. */
12927   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
12928        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
12929       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
12930       || (rhs_type == float_type_node && lhs_type == double_type_node))
12931     return 1;
12932
12933   return 0;
12934 }
12935
12936 /* Check that something of SOURCE type can be assigned or cast to
12937    something of DEST type at runtime. Return 1 if the operation is
12938    valid, 0 otherwise. If CAST is set to 1, we're treating the case
12939    were SOURCE is cast into DEST, which borrows a lot of the
12940    assignment check. */
12941
12942 static int
12943 valid_ref_assignconv_cast_p (source, dest, cast)
12944      tree source;
12945      tree dest;
12946      int cast;
12947 {
12948   /* SOURCE or DEST might be null if not from a declared entity. */
12949   if (!source || !dest)
12950     return 0;
12951   if (JNULLP_TYPE_P (source))
12952     return 1;
12953   if (TREE_CODE (source) == POINTER_TYPE)
12954     source = TREE_TYPE (source);
12955   if (TREE_CODE (dest) == POINTER_TYPE)
12956     dest = TREE_TYPE (dest);
12957
12958   /* If source and dest are being compiled from bytecode, they may need to
12959      be loaded. */
12960   if (CLASS_P (source) && !CLASS_LOADED_P (source))
12961     {
12962       load_class (source, 1);
12963       safe_layout_class (source);
12964     }
12965   if (CLASS_P (dest) && !CLASS_LOADED_P (dest))
12966     {
12967       load_class (dest, 1);
12968       safe_layout_class (dest);
12969     }
12970
12971   /* Case where SOURCE is a class type */
12972   if (TYPE_CLASS_P (source))
12973     {
12974       if (TYPE_CLASS_P (dest))
12975         return  (source == dest 
12976                  || inherits_from_p (source, dest)
12977                  || (cast && inherits_from_p (dest, source)));
12978       if (TYPE_INTERFACE_P (dest))
12979         {
12980           /* If doing a cast and SOURCE is final, the operation is
12981              always correct a compile time (because even if SOURCE
12982              does not implement DEST, a subclass of SOURCE might). */
12983           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
12984             return 1;
12985           /* Otherwise, SOURCE must implement DEST */
12986           return interface_of_p (dest, source);
12987         }
12988       /* DEST is an array, cast permited if SOURCE is of Object type */
12989       return (cast && source == object_type_node ? 1 : 0);
12990     }
12991   if (TYPE_INTERFACE_P (source))
12992     {
12993       if (TYPE_CLASS_P (dest))
12994         {
12995           /* If not casting, DEST must be the Object type */
12996           if (!cast)
12997             return dest == object_type_node;
12998           /* We're doing a cast. The cast is always valid is class
12999              DEST is not final, otherwise, DEST must implement SOURCE */
13000           else if (!CLASS_FINAL (TYPE_NAME (dest)))
13001             return 1;
13002           else
13003             return interface_of_p (source, dest);
13004         }
13005       if (TYPE_INTERFACE_P (dest))
13006         {
13007           /* If doing a cast, then if SOURCE and DEST contain method
13008              with the same signature but different return type, then
13009              this is a (compile time) error */
13010           if (cast)
13011             {
13012               tree method_source, method_dest;
13013               tree source_type;
13014               tree source_sig;
13015               tree source_name;
13016               for (method_source = TYPE_METHODS (source); method_source; 
13017                    method_source = TREE_CHAIN (method_source))
13018                 {
13019                   source_sig = 
13020                     build_java_argument_signature (TREE_TYPE (method_source));
13021                   source_type = TREE_TYPE (TREE_TYPE (method_source));
13022                   source_name = DECL_NAME (method_source);
13023                   for (method_dest = TYPE_METHODS (dest);
13024                        method_dest; method_dest = TREE_CHAIN (method_dest))
13025                     if (source_sig == 
13026                         build_java_argument_signature (TREE_TYPE (method_dest))
13027                         && source_name == DECL_NAME (method_dest)
13028                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
13029                       return 0;
13030                 }
13031               return 1;
13032             }
13033           else
13034             return source == dest || interface_of_p (dest, source);
13035         }
13036       else
13037         {
13038           /* Array */
13039           return (cast
13040                   && (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable
13041                       || (DECL_NAME (TYPE_NAME (source))
13042                           == java_io_serializable)));
13043         }
13044     }
13045   if (TYPE_ARRAY_P (source))
13046     {
13047       if (TYPE_CLASS_P (dest))
13048         return dest == object_type_node;
13049       /* Can't cast an array to an interface unless the interface is
13050          java.lang.Cloneable or java.io.Serializable.  */
13051       if (TYPE_INTERFACE_P (dest))
13052         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable
13053                 || DECL_NAME (TYPE_NAME (dest)) == java_io_serializable);
13054       else                      /* Arrays */
13055         {
13056           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
13057           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
13058           
13059           /* In case of severe errors, they turn out null */
13060           if (!dest_element_type || !source_element_type)
13061             return 0;
13062           if (source_element_type == dest_element_type)
13063             return 1;
13064           return valid_ref_assignconv_cast_p (source_element_type,
13065                                               dest_element_type, cast);
13066         }
13067       return 0;
13068     }
13069   return 0;
13070 }
13071
13072 static int
13073 valid_cast_to_p (source, dest)
13074      tree source;
13075      tree dest;
13076 {
13077   if (TREE_CODE (source) == POINTER_TYPE)
13078     source = TREE_TYPE (source);
13079   if (TREE_CODE (dest) == POINTER_TYPE)
13080     dest = TREE_TYPE (dest);
13081
13082   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
13083     return valid_ref_assignconv_cast_p (source, dest, 1);
13084
13085   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
13086     return 1;
13087
13088   else if (TREE_CODE (source) == BOOLEAN_TYPE
13089            && TREE_CODE (dest) == BOOLEAN_TYPE)
13090     return 1;
13091
13092   return 0;
13093 }
13094
13095 static tree
13096 do_unary_numeric_promotion (arg)
13097      tree arg;
13098 {
13099   tree type = TREE_TYPE (arg);
13100   if ((TREE_CODE (type) == INTEGER_TYPE && TYPE_PRECISION (type) < 32)
13101       || TREE_CODE (type) == CHAR_TYPE)
13102     arg = convert (int_type_node, arg);
13103   return arg;
13104 }
13105
13106 /* Return a non zero value if SOURCE can be converted into DEST using
13107    the method invocation conversion rule (5.3).  */
13108 static int
13109 valid_method_invocation_conversion_p (dest, source)
13110      tree dest, source;
13111 {
13112   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
13113            && valid_builtin_assignconv_identity_widening_p (dest, source))
13114           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
13115               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
13116               && valid_ref_assignconv_cast_p (source, dest, 0)));
13117 }
13118
13119 /* Build an incomplete binop expression. */
13120
13121 static tree
13122 build_binop (op, op_location, op1, op2)
13123      enum tree_code op;
13124      int op_location;
13125      tree op1, op2;
13126 {
13127   tree binop = build (op, NULL_TREE, op1, op2);
13128   TREE_SIDE_EFFECTS (binop) = 1;
13129   /* Store the location of the operator, for better error report. The
13130      string of the operator will be rebuild based on the OP value. */
13131   EXPR_WFL_LINECOL (binop) = op_location;
13132   return binop;
13133 }
13134
13135 /* Build the string of the operator retained by NODE. If NODE is part
13136    of a compound expression, add an '=' at the end of the string. This
13137    function is called when an error needs to be reported on an
13138    operator. The string is returned as a pointer to a static character
13139    buffer. */
13140
13141 static char *
13142 operator_string (node)
13143      tree node;
13144 {
13145 #define BUILD_OPERATOR_STRING(S)                                        \
13146   {                                                                     \
13147     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
13148     return buffer;                                                      \
13149   }
13150   
13151   static char buffer [10];
13152   switch (TREE_CODE (node))
13153     {
13154     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
13155     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
13156     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
13157     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
13158     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
13159     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
13160     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
13161     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
13162     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
13163     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
13164     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
13165     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
13166     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
13167     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
13168     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
13169     case GT_EXPR: BUILD_OPERATOR_STRING (">");
13170     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
13171     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
13172     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
13173     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
13174     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
13175     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
13176     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
13177     case PREINCREMENT_EXPR:     /* Fall through */
13178     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
13179     case PREDECREMENT_EXPR:     /* Fall through */
13180     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
13181     default:
13182       internal_error ("unregistered operator %s",
13183                       tree_code_name [TREE_CODE (node)]);
13184     }
13185   return NULL;
13186 #undef BUILD_OPERATOR_STRING
13187 }
13188
13189 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
13190
13191 static int
13192 java_decl_equiv (var_acc1, var_acc2)
13193      tree var_acc1, var_acc2;
13194 {
13195   if (JDECL_P (var_acc1))
13196     return (var_acc1 == var_acc2);
13197   
13198   return (TREE_CODE (var_acc1) == COMPONENT_REF
13199           && TREE_CODE (var_acc2) == COMPONENT_REF
13200           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
13201              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
13202           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
13203 }
13204
13205 /* Return a non zero value if CODE is one of the operators that can be
13206    used in conjunction with the `=' operator in a compound assignment.  */
13207
13208 static int
13209 binop_compound_p (code)
13210     enum tree_code code;
13211 {
13212   int i;
13213   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
13214     if (binop_lookup [i] == code)
13215       break;
13216
13217   return i < BINOP_COMPOUND_CANDIDATES;
13218 }
13219
13220 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
13221
13222 static tree
13223 java_refold (t)
13224      tree t;
13225 {
13226   tree c, b, ns, decl;
13227
13228   if (TREE_CODE (t) != MODIFY_EXPR)
13229     return t;
13230
13231   c = TREE_OPERAND (t, 1);
13232   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
13233          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
13234          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
13235     return t;
13236
13237   /* Now the left branch of the binary operator. */
13238   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
13239   if (! (b && TREE_CODE (b) == NOP_EXPR 
13240          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
13241     return t;
13242
13243   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
13244   if (! (ns && TREE_CODE (ns) == NOP_EXPR
13245          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
13246     return t;
13247
13248   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
13249   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
13250       /* It's got to be the an equivalent decl */
13251       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
13252     {
13253       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
13254       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
13255       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
13256       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
13257       /* Change the right part of the BINOP_EXPR */
13258       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
13259     }
13260
13261   return t;
13262 }
13263
13264 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
13265    errors but we modify NODE so that it contains the type computed
13266    according to the expression, when it's fixed. Otherwise, we write
13267    error_mark_node as the type. It allows us to further the analysis
13268    of remaining nodes and detects more errors in certain cases.  */
13269
13270 static tree
13271 patch_binop (node, wfl_op1, wfl_op2)
13272      tree node;
13273      tree wfl_op1;
13274      tree wfl_op2;
13275 {
13276   tree op1 = TREE_OPERAND (node, 0);
13277   tree op2 = TREE_OPERAND (node, 1);
13278   tree op1_type = TREE_TYPE (op1);
13279   tree op2_type = TREE_TYPE (op2);
13280   tree prom_type = NULL_TREE, cn;
13281   enum tree_code code = TREE_CODE (node);
13282
13283   /* If 1, tell the routine that we have to return error_mark_node
13284      after checking for the initialization of the RHS */
13285   int error_found = 0;
13286
13287   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13288
13289   /* If either op<n>_type are NULL, this might be early signs of an
13290      error situation, unless it's too early to tell (in case we're
13291      handling a `+', `==', `!=' or `instanceof'.) We want to set op<n>_type
13292      correctly so the error can be later on reported accurately. */
13293   if (! (code == PLUS_EXPR || code == NE_EXPR 
13294          || code == EQ_EXPR || code == INSTANCEOF_EXPR))
13295     {
13296       tree n;
13297       if (! op1_type)
13298         {
13299           n = java_complete_tree (op1);
13300           op1_type = TREE_TYPE (n);
13301         }
13302       if (! op2_type)
13303         {
13304           n = java_complete_tree (op2);
13305           op2_type = TREE_TYPE (n);
13306         }
13307     }
13308
13309   switch (code)
13310     {
13311     /* 15.16 Multiplicative operators */
13312     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
13313     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
13314     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
13315     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
13316       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13317         {
13318           if (!JNUMERIC_TYPE_P (op1_type))
13319             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13320           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13321             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13322           TREE_TYPE (node) = error_mark_node;
13323           error_found = 1;
13324           break;
13325         }
13326       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13327
13328       /* Detect integral division by zero */
13329       if ((code == RDIV_EXPR || code == TRUNC_MOD_EXPR)
13330           && TREE_CODE (prom_type) == INTEGER_TYPE
13331           && (op2 == integer_zero_node || op2 == long_zero_node ||
13332               (TREE_CODE (op2) == INTEGER_CST &&
13333                ! TREE_INT_CST_LOW (op2)  && ! TREE_INT_CST_HIGH (op2))))
13334         {
13335           parse_warning_context (wfl_operator, "Evaluating this expression will result in an arithmetic exception being thrown");
13336           TREE_CONSTANT (node) = 0;
13337         }
13338           
13339       /* Change the division operator if necessary */
13340       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
13341         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
13342
13343       /* Before divisions as is disapear, try to simplify and bail if
13344          applicable, otherwise we won't perform even simple
13345          simplifications like (1-1)/3. We can't do that with floating
13346          point number, folds can't handle them at this stage. */
13347       if (code == RDIV_EXPR && TREE_CONSTANT (op1) && TREE_CONSTANT (op2)
13348           && JINTEGRAL_TYPE_P (op1) && JINTEGRAL_TYPE_P (op2))
13349         {
13350           TREE_TYPE (node) = prom_type;
13351           node = fold (node);
13352           if (TREE_CODE (node) != code)
13353             return node;
13354         }
13355
13356       if (TREE_CODE (prom_type) == INTEGER_TYPE
13357           && flag_use_divide_subroutine
13358           && ! flag_emit_class_files
13359           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
13360         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
13361  
13362       /* This one is more complicated. FLOATs are processed by a
13363          function call to soft_fmod. Duplicate the value of the
13364          COMPOUND_ASSIGN_P flag. */
13365       if (code == TRUNC_MOD_EXPR)
13366         {
13367           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
13368           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
13369           TREE_SIDE_EFFECTS (mod)
13370             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13371           return mod;
13372         }
13373       break;
13374
13375     /* 15.17 Additive Operators */
13376     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
13377
13378       /* Operation is valid if either one argument is a string
13379          constant, a String object or a StringBuffer crafted for the
13380          purpose of the a previous usage of the String concatenation
13381          operator */
13382
13383       if (TREE_CODE (op1) == STRING_CST 
13384           || TREE_CODE (op2) == STRING_CST
13385           || JSTRING_TYPE_P (op1_type)
13386           || JSTRING_TYPE_P (op2_type)
13387           || IS_CRAFTED_STRING_BUFFER_P (op1)
13388           || IS_CRAFTED_STRING_BUFFER_P (op2))
13389         return build_string_concatenation (op1, op2);
13390
13391     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
13392                                    Numeric Types */
13393       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13394         {
13395           if (!JNUMERIC_TYPE_P (op1_type))
13396             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13397           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13398             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13399           TREE_TYPE (node) = error_mark_node;
13400           error_found = 1;
13401           break;
13402         }
13403       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13404       break;
13405
13406     /* 15.18 Shift Operators */
13407     case LSHIFT_EXPR:
13408     case RSHIFT_EXPR:
13409     case URSHIFT_EXPR:
13410       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
13411         {
13412           if (!JINTEGRAL_TYPE_P (op1_type))
13413             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13414           else
13415             {
13416               if (JNUMERIC_TYPE_P (op2_type))
13417                 parse_error_context (wfl_operator,
13418                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
13419                                      operator_string (node),
13420                                      lang_printable_name (op2_type, 0));
13421               else
13422                 parse_error_context (wfl_operator,
13423                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
13424                                      operator_string (node),
13425                                      lang_printable_name (op2_type, 0));
13426             }
13427           TREE_TYPE (node) = error_mark_node;
13428           error_found = 1;
13429           break;
13430         }
13431
13432       /* Unary numeric promotion (5.6.1) is performed on each operand
13433          separately */
13434       op1 = do_unary_numeric_promotion (op1);
13435       op2 = do_unary_numeric_promotion (op2);
13436
13437       /* The type of the shift expression is the type of the promoted
13438          type of the left-hand operand */
13439       prom_type = TREE_TYPE (op1);
13440
13441       /* Shift int only up to 0x1f and long up to 0x3f */
13442       if (prom_type == int_type_node)
13443         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13444                            build_int_2 (0x1f, 0)));
13445       else
13446         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13447                            build_int_2 (0x3f, 0)));
13448
13449       /* The >>> operator is a >> operating on unsigned quantities */
13450       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
13451         {
13452           tree to_return;
13453           tree utype = java_unsigned_type (prom_type);
13454           op1 = convert (utype, op1);
13455           TREE_SET_CODE (node, RSHIFT_EXPR);
13456           TREE_OPERAND (node, 0) = op1;
13457           TREE_OPERAND (node, 1) = op2;
13458           TREE_TYPE (node) = utype;
13459           to_return = convert (prom_type, node);
13460           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
13461           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
13462           TREE_SIDE_EFFECTS (to_return)
13463             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13464           return to_return;
13465         }
13466       break;
13467
13468       /* 15.19.1 Type Comparison Operator instaceof */
13469     case INSTANCEOF_EXPR:
13470
13471       TREE_TYPE (node) = boolean_type_node;
13472
13473       /* OP1_TYPE might be NULL when OP1 is a string constant.  */
13474       if ((cn = patch_string (op1))) 
13475         {
13476           op1 = cn;
13477           op1_type = TREE_TYPE (op1);
13478         }
13479       if (op1_type == NULL_TREE)
13480         abort ();
13481
13482       if (!(op2_type = resolve_type_during_patch (op2)))
13483         return error_mark_node;
13484
13485       /* The first operand must be a reference type or the null type */
13486       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
13487         error_found = 1;        /* Error reported further below */
13488
13489       /* The second operand must be a reference type */
13490       if (!JREFERENCE_TYPE_P (op2_type))
13491         {
13492           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
13493           parse_error_context
13494             (wfl_operator, "Invalid argument `%s' for `instanceof'",
13495              lang_printable_name (op2_type, 0));
13496           error_found = 1;
13497         }
13498
13499       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
13500         {
13501           /* If the first operand is null, the result is always false */
13502           if (op1 == null_pointer_node)
13503             return boolean_false_node;
13504           else if (flag_emit_class_files)
13505             {
13506               TREE_OPERAND (node, 1) = op2_type;
13507               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
13508               return node;
13509             }
13510           /* Otherwise we have to invoke instance of to figure it out */
13511           else
13512             return build_instanceof (op1, op2_type);
13513         }
13514       /* There is no way the expression operand can be an instance of
13515          the type operand. This is a compile time error. */
13516       else
13517         {
13518           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
13519           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
13520           parse_error_context 
13521             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
13522              t1, lang_printable_name (op2_type, 0));
13523           free (t1);
13524           error_found = 1;
13525         }
13526       
13527       break;
13528
13529       /* 15.21 Bitwise and Logical Operators */
13530     case BIT_AND_EXPR:
13531     case BIT_XOR_EXPR:
13532     case BIT_IOR_EXPR:
13533       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
13534         /* Binary numeric promotion is performed on both operand and the
13535            expression retain that type */
13536         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13537
13538       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
13539                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
13540         /* The type of the bitwise operator expression is BOOLEAN */
13541         prom_type = boolean_type_node;
13542       else
13543         {
13544           if (!JINTEGRAL_TYPE_P (op1_type))
13545             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13546           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
13547             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
13548           TREE_TYPE (node) = error_mark_node;
13549           error_found = 1;
13550           /* Insert a break here if adding thing before the switch's
13551              break for this case */
13552         }
13553       break;
13554
13555       /* 15.22 Conditional-And Operator */
13556     case TRUTH_ANDIF_EXPR:
13557       /* 15.23 Conditional-Or Operator */
13558     case TRUTH_ORIF_EXPR:
13559       /* Operands must be of BOOLEAN type */
13560       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
13561           TREE_CODE (op2_type) != BOOLEAN_TYPE)
13562         {
13563           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
13564             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
13565           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
13566             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
13567           TREE_TYPE (node) = boolean_type_node;
13568           error_found = 1;
13569           break;
13570         }
13571       else if (integer_zerop (op1))
13572         {
13573           return code == TRUTH_ANDIF_EXPR ? op1 : op2;
13574         }
13575       else if (integer_onep (op1))
13576         {
13577           return code == TRUTH_ANDIF_EXPR ? op2 : op1;
13578         }
13579       /* The type of the conditional operators is BOOLEAN */
13580       prom_type = boolean_type_node;
13581       break;
13582
13583       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
13584     case LT_EXPR:
13585     case GT_EXPR:
13586     case LE_EXPR:
13587     case GE_EXPR:
13588       /* The type of each of the operands must be a primitive numeric
13589          type */
13590       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
13591         {
13592           if (!JNUMERIC_TYPE_P (op1_type))
13593             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13594           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13595             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13596           TREE_TYPE (node) = boolean_type_node;
13597           error_found = 1;
13598           break;
13599         }
13600       /* Binary numeric promotion is performed on the operands */
13601       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13602       /* The type of the relation expression is always BOOLEAN */
13603       prom_type = boolean_type_node;
13604       break;
13605
13606       /* 15.20 Equality Operator */
13607     case EQ_EXPR:
13608     case NE_EXPR:
13609       /* It's time for us to patch the strings. */
13610       if ((cn = patch_string (op1))) 
13611        {
13612          op1 = cn;
13613          op1_type = TREE_TYPE (op1);
13614        }
13615       if ((cn = patch_string (op2))) 
13616        {
13617          op2 = cn;
13618          op2_type = TREE_TYPE (op2);
13619        }
13620       
13621       /* 15.20.1 Numerical Equality Operators == and != */
13622       /* Binary numeric promotion is performed on the operands */
13623       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
13624         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13625       
13626       /* 15.20.2 Boolean Equality Operators == and != */
13627       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
13628           TREE_CODE (op2_type) == BOOLEAN_TYPE)
13629         ;                       /* Nothing to do here */
13630       
13631       /* 15.20.3 Reference Equality Operators == and != */
13632       /* Types have to be either references or the null type. If
13633          they're references, it must be possible to convert either
13634          type to the other by casting conversion. */
13635       else if (op1 == null_pointer_node || op2 == null_pointer_node 
13636                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
13637                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
13638                        || valid_ref_assignconv_cast_p (op2_type, 
13639                                                        op1_type, 1))))
13640         ;                       /* Nothing to do here */
13641           
13642       /* Else we have an error figure what can't be converted into
13643          what and report the error */
13644       else
13645         {
13646           char *t1;
13647           t1 = xstrdup (lang_printable_name (op1_type, 0));
13648           parse_error_context 
13649             (wfl_operator,
13650              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
13651              operator_string (node), t1, 
13652              lang_printable_name (op2_type, 0));
13653           free (t1);
13654           TREE_TYPE (node) = boolean_type_node;
13655           error_found = 1;
13656           break;
13657         }
13658       prom_type = boolean_type_node;
13659       break;
13660     default:
13661       abort ();
13662     }
13663
13664   if (error_found)
13665     return error_mark_node;
13666
13667   TREE_OPERAND (node, 0) = op1;
13668   TREE_OPERAND (node, 1) = op2;
13669   TREE_TYPE (node) = prom_type;
13670   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13671   
13672   if (flag_emit_xref)
13673     return node;
13674
13675   /* fold does not respect side-effect order as required for Java but not C.
13676    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
13677    * bytecode.
13678    */
13679   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
13680       : ! TREE_SIDE_EFFECTS (node))
13681     node = fold (node);
13682   return node;
13683 }
13684
13685 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
13686    zero value, the value of CSTE comes after the valude of STRING */
13687
13688 static tree
13689 do_merge_string_cste (cste, string, string_len, after)
13690      tree cste;
13691      const char *string;
13692      int string_len, after;
13693 {
13694   const char *old = TREE_STRING_POINTER (cste);
13695   int old_len = TREE_STRING_LENGTH (cste);
13696   int len = old_len + string_len;
13697   char *new = alloca (len+1);
13698
13699   if (after)
13700     {
13701       memcpy (new, string, string_len);
13702       memcpy (&new [string_len], old, old_len);
13703     }
13704   else
13705     {
13706       memcpy (new, old, old_len);
13707       memcpy (&new [old_len], string, string_len);
13708     }
13709   new [len] = '\0';
13710   return build_string (len, new);
13711 }
13712
13713 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
13714    new STRING_CST on success, NULL_TREE on failure */
13715
13716 static tree
13717 merge_string_cste (op1, op2, after)
13718      tree op1, op2;
13719      int after;
13720 {
13721   /* Handle two string constants right away */
13722   if (TREE_CODE (op2) == STRING_CST)
13723     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
13724                                  TREE_STRING_LENGTH (op2), after);
13725   
13726   /* Reasonable integer constant can be treated right away */
13727   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
13728     {
13729       static const char *const boolean_true = "true";
13730       static const char *const boolean_false = "false";
13731       static const char *const null_pointer = "null";
13732       char ch[3];
13733       const char *string;
13734       
13735       if (op2 == boolean_true_node)
13736         string = boolean_true;
13737       else if (op2 == boolean_false_node)
13738         string = boolean_false;
13739       else if (op2 == null_pointer_node)
13740         string = null_pointer;
13741       else if (TREE_TYPE (op2) == char_type_node)
13742         {
13743           ch[0] = (char )TREE_INT_CST_LOW (op2);
13744           ch[1] = '\0';
13745           string = ch;
13746         }
13747       else
13748         string = string_convert_int_cst (op2);
13749
13750       return do_merge_string_cste (op1, string, strlen (string), after);
13751     }
13752   return NULL_TREE;
13753 }
13754
13755 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
13756    has to be a STRING_CST and the other part must be a STRING_CST or a
13757    INTEGRAL constant. Return a new STRING_CST if the operation
13758    succeed, NULL_TREE otherwise.
13759
13760    If the case we want to optimize for space, we might want to return
13761    NULL_TREE for each invocation of this routine. FIXME */
13762
13763 static tree
13764 string_constant_concatenation (op1, op2)
13765      tree op1, op2;
13766 {
13767   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
13768     {
13769       tree string, rest;
13770       int invert;
13771       
13772       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
13773       rest   = (string == op1 ? op2 : op1);
13774       invert = (string == op1 ? 0 : 1 );
13775       
13776       /* Walk REST, only if it looks reasonable */
13777       if (TREE_CODE (rest) != STRING_CST
13778           && !IS_CRAFTED_STRING_BUFFER_P (rest)
13779           && !JSTRING_TYPE_P (TREE_TYPE (rest))
13780           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
13781         {
13782           rest = java_complete_tree (rest);
13783           if (rest == error_mark_node)
13784             return error_mark_node;
13785           rest = fold (rest);
13786         }
13787       return merge_string_cste (string, rest, invert);
13788     }
13789   return NULL_TREE;
13790 }
13791
13792 /* Implement the `+' operator. Does static optimization if possible,
13793    otherwise create (if necessary) and append elements to a
13794    StringBuffer. The StringBuffer will be carried around until it is
13795    used for a function call or an assignment. Then toString() will be
13796    called on it to turn it into a String object. */
13797
13798 static tree
13799 build_string_concatenation (op1, op2)
13800      tree op1, op2;
13801 {
13802   tree result;
13803   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13804
13805   if (flag_emit_xref)
13806     return build (PLUS_EXPR, string_type_node, op1, op2);
13807   
13808   /* Try to do some static optimization */
13809   if ((result = string_constant_concatenation (op1, op2)))
13810     return result;
13811
13812   /* Discard empty strings on either side of the expression */
13813   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
13814     {
13815       op1 = op2;
13816       op2 = NULL_TREE;
13817     }
13818   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
13819     op2 = NULL_TREE;
13820
13821   /* If operands are string constant, turn then into object references */
13822   if (TREE_CODE (op1) == STRING_CST)
13823     op1 = patch_string_cst (op1);
13824   if (op2 && TREE_CODE (op2) == STRING_CST)
13825     op2 = patch_string_cst (op2);
13826
13827   /* If either one of the constant is null and the other non null
13828      operand is a String constant, return it. */
13829   if ((TREE_CODE (op1) == STRING_CST) && !op2)
13830     return op1;
13831
13832   /* If OP1 isn't already a StringBuffer, create and
13833      initialize a new one */
13834   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
13835     {
13836       /* Two solutions here: 
13837          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
13838          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
13839       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
13840         op1 = BUILD_STRING_BUFFER (op1);
13841       else
13842         {
13843           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
13844           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
13845         }
13846     }
13847
13848   if (op2)
13849     {
13850       /* OP1 is no longer the last node holding a crafted StringBuffer */
13851       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
13852       /* Create a node for `{new...,xxx}.append (op2)' */
13853       if (op2)
13854         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
13855     }
13856
13857   /* Mark the last node holding a crafted StringBuffer */
13858   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
13859
13860   TREE_SIDE_EFFECTS (op1) = side_effects;
13861   return op1;
13862 }
13863
13864 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
13865    StringBuffer. If no string were found to be patched, return
13866    NULL. */
13867
13868 static tree
13869 patch_string (node)
13870     tree node;
13871 {
13872   if (node == error_mark_node)
13873     return error_mark_node;
13874   if (TREE_CODE (node) == STRING_CST)
13875     return patch_string_cst (node);
13876   else if (IS_CRAFTED_STRING_BUFFER_P (node))
13877     {
13878       int saved = ctxp->explicit_constructor_p;
13879       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
13880       tree ret;
13881       /* Temporary disable forbid the use of `this'. */
13882       ctxp->explicit_constructor_p = 0;
13883       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
13884       /* String concatenation arguments must be evaluated in order too. */
13885       ret = force_evaluation_order (ret);
13886       /* Restore it at its previous value */
13887       ctxp->explicit_constructor_p = saved;
13888       return ret;
13889     }
13890   return NULL_TREE;
13891 }
13892
13893 /* Build the internal representation of a string constant.  */
13894
13895 static tree
13896 patch_string_cst (node)
13897      tree node;
13898 {
13899   int location;
13900   if (! flag_emit_class_files)
13901     {
13902       node = get_identifier (TREE_STRING_POINTER (node));
13903       location = alloc_name_constant (CONSTANT_String, node);
13904       node = build_ref_from_constant_pool (location);
13905     }
13906   TREE_TYPE (node) = string_ptr_type_node;
13907   TREE_CONSTANT (node) = 1;
13908   return node;
13909 }
13910
13911 /* Build an incomplete unary operator expression. */
13912
13913 static tree
13914 build_unaryop (op_token, op_location, op1)
13915      int op_token, op_location;
13916      tree op1;
13917 {
13918   enum tree_code op;
13919   tree unaryop;
13920   switch (op_token)
13921     {
13922     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
13923     case MINUS_TK: op = NEGATE_EXPR; break;
13924     case NEG_TK: op = TRUTH_NOT_EXPR; break;
13925     case NOT_TK: op = BIT_NOT_EXPR; break;
13926     default: abort ();
13927     }
13928
13929   unaryop = build1 (op, NULL_TREE, op1);
13930   TREE_SIDE_EFFECTS (unaryop) = 1;
13931   /* Store the location of the operator, for better error report. The
13932      string of the operator will be rebuild based on the OP value. */
13933   EXPR_WFL_LINECOL (unaryop) = op_location;
13934   return unaryop;
13935 }
13936
13937 /* Special case for the ++/-- operators, since they require an extra
13938    argument to build, which is set to NULL and patched
13939    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
13940
13941 static tree
13942 build_incdec (op_token, op_location, op1, is_post_p)
13943      int op_token, op_location;
13944      tree op1;
13945      int is_post_p;
13946 {
13947   static const enum tree_code lookup [2][2] = 
13948     {
13949       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
13950       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
13951     };
13952   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
13953                      NULL_TREE, op1, NULL_TREE);
13954   TREE_SIDE_EFFECTS (node) = 1;
13955   /* Store the location of the operator, for better error report. The
13956      string of the operator will be rebuild based on the OP value. */
13957   EXPR_WFL_LINECOL (node) = op_location;
13958   return node;
13959 }     
13960
13961 /* Build an incomplete cast operator, based on the use of the
13962    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
13963    set. java_complete_tree is trained to walk a CONVERT_EXPR even
13964    though its type is already set.  */
13965
13966 static tree
13967 build_cast (location, type, exp)
13968      int location;
13969      tree type, exp;
13970 {
13971   tree node = build1 (CONVERT_EXPR, type, exp);
13972   EXPR_WFL_LINECOL (node) = location;
13973   return node;
13974 }
13975
13976 /* Build an incomplete class reference operator.  */
13977 static tree
13978 build_incomplete_class_ref (location, class_name)
13979     int location;
13980     tree class_name;
13981 {
13982   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
13983   EXPR_WFL_LINECOL (node) = location;
13984   return node;
13985 }
13986
13987 /* Complete an incomplete class reference operator.  */
13988 static tree
13989 patch_incomplete_class_ref (node)
13990     tree node;
13991 {
13992   tree type = TREE_OPERAND (node, 0);
13993   tree ref_type;
13994
13995   if (!(ref_type = resolve_type_during_patch (type)))
13996     return error_mark_node;
13997
13998   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
13999     {
14000       tree dot = build_class_ref (ref_type);
14001       /* A class referenced by `foo.class' is initialized.  */
14002       if (!flag_emit_class_files)
14003        dot = build_class_init (ref_type, dot);
14004       return java_complete_tree (dot);
14005     }
14006
14007   /* If we're emitting class files and we have to deal with non
14008      primitive types, we invoke (and consider generating) the
14009      synthetic static method `class$'. */
14010   if (!TYPE_DOT_CLASS (current_class))
14011       build_dot_class_method (current_class);
14012   ref_type = build_dot_class_method_invocation (ref_type);
14013   return java_complete_tree (ref_type);
14014 }
14015
14016 /* 15.14 Unary operators. We return error_mark_node in case of error,
14017    but preserve the type of NODE if the type is fixed.  */
14018
14019 static tree
14020 patch_unaryop (node, wfl_op)
14021      tree node;
14022      tree wfl_op;
14023 {
14024   tree op = TREE_OPERAND (node, 0);
14025   tree op_type = TREE_TYPE (op);
14026   tree prom_type = NULL_TREE, value, decl;
14027   int outer_field_flag = 0;
14028   int code = TREE_CODE (node);
14029   int error_found = 0;
14030
14031   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14032
14033   switch (code)
14034     {
14035       /* 15.13.2 Postfix Increment Operator ++ */
14036     case POSTINCREMENT_EXPR:
14037       /* 15.13.3 Postfix Increment Operator -- */
14038     case POSTDECREMENT_EXPR:
14039       /* 15.14.1 Prefix Increment Operator ++ */
14040     case PREINCREMENT_EXPR:
14041       /* 15.14.2 Prefix Decrement Operator -- */
14042     case PREDECREMENT_EXPR:
14043       op = decl = strip_out_static_field_access_decl (op);
14044       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
14045       /* We might be trying to change an outer field accessed using
14046          access method. */
14047       if (outer_field_flag)
14048         {
14049           /* Retrieve the decl of the field we're trying to access. We
14050              do that by first retrieving the function we would call to
14051              access the field. It has been already verified that this
14052              field isn't final */
14053           if (flag_emit_class_files)
14054             decl = TREE_OPERAND (op, 0);
14055           else
14056             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
14057           decl = DECL_FUNCTION_ACCESS_DECL (decl);
14058         }
14059       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
14060       else if (!JDECL_P (decl) 
14061           && TREE_CODE (decl) != COMPONENT_REF
14062           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
14063           && TREE_CODE (decl) != INDIRECT_REF
14064           && !(TREE_CODE (decl) == COMPOUND_EXPR
14065                && TREE_OPERAND (decl, 1)
14066                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
14067         {
14068           TREE_TYPE (node) = error_mark_node;
14069           error_found = 1;
14070         }
14071       
14072       /* From now on, we know that op if a variable and that it has a
14073          valid wfl. We use wfl_op to locate errors related to the
14074          ++/-- operand. */
14075       if (!JNUMERIC_TYPE_P (op_type))
14076         {
14077           parse_error_context
14078             (wfl_op, "Invalid argument type `%s' to `%s'",
14079              lang_printable_name (op_type, 0), operator_string (node));
14080           TREE_TYPE (node) = error_mark_node;
14081           error_found = 1;
14082         }
14083       else
14084         {
14085           /* Before the addition, binary numeric promotion is performed on
14086              both operands, if really necessary */
14087           if (JINTEGRAL_TYPE_P (op_type))
14088             {
14089               value = build_int_2 (1, 0);
14090               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
14091             }
14092           else
14093             {
14094               value = build_int_2 (1, 0);
14095               TREE_TYPE (node) = 
14096                 binary_numeric_promotion (op_type, 
14097                                           TREE_TYPE (value), &op, &value);
14098             }
14099
14100           /* We remember we might be accessing an outer field */
14101           if (outer_field_flag)
14102             {
14103               /* We re-generate an access to the field */
14104               value = build (PLUS_EXPR, TREE_TYPE (op), 
14105                              build_outer_field_access (wfl_op, decl), value);
14106                                                     
14107               /* And we patch the original access$() into a write 
14108                  with plus_op as a rhs */
14109               return outer_field_access_fix (node, op, value);
14110             }
14111
14112           /* And write back into the node. */
14113           TREE_OPERAND (node, 0) = op;
14114           TREE_OPERAND (node, 1) = value;
14115           /* Convert the overall back into its original type, if
14116              necessary, and return */
14117           if (JINTEGRAL_TYPE_P (op_type))
14118             return fold (node);
14119           else
14120             return fold (convert (op_type, node));
14121         }
14122       break;
14123
14124       /* 15.14.3 Unary Plus Operator + */
14125     case UNARY_PLUS_EXPR:
14126       /* 15.14.4 Unary Minus Operator - */
14127     case NEGATE_EXPR:
14128       if (!JNUMERIC_TYPE_P (op_type))
14129         {
14130           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
14131           TREE_TYPE (node) = error_mark_node;
14132           error_found = 1;
14133         }
14134       /* Unary numeric promotion is performed on operand */
14135       else
14136         {
14137           op = do_unary_numeric_promotion (op);
14138           prom_type = TREE_TYPE (op);
14139           if (code == UNARY_PLUS_EXPR)
14140             return fold (op);
14141         }
14142       break;
14143
14144       /* 15.14.5 Bitwise Complement Operator ~ */
14145     case BIT_NOT_EXPR:
14146       if (!JINTEGRAL_TYPE_P (op_type))
14147         {
14148           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
14149           TREE_TYPE (node) = error_mark_node;
14150           error_found = 1;
14151         }
14152       else
14153         {
14154           op = do_unary_numeric_promotion (op);
14155           prom_type = TREE_TYPE (op);
14156         }
14157       break;
14158
14159       /* 15.14.6 Logical Complement Operator ! */
14160     case TRUTH_NOT_EXPR:
14161       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
14162         {
14163           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
14164           /* But the type is known. We will report an error if further
14165              attempt of a assignment is made with this rhs */
14166           TREE_TYPE (node) = boolean_type_node;
14167           error_found = 1;
14168         }
14169       else
14170         prom_type = boolean_type_node;
14171       break;
14172
14173       /* 15.15 Cast Expression */
14174     case CONVERT_EXPR:
14175       value = patch_cast (node, wfl_operator);
14176       if (value == error_mark_node)
14177         {
14178           /* If this cast is part of an assignment, we tell the code
14179              that deals with it not to complain about a mismatch,
14180              because things have been cast, anyways */
14181           TREE_TYPE (node) = error_mark_node;
14182           error_found = 1;
14183         }
14184       else
14185         {
14186           value = fold (value);
14187           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
14188           return value;
14189         }
14190       break;
14191     }
14192   
14193   if (error_found)
14194     return error_mark_node;
14195
14196   /* There are cases where node has been replaced by something else
14197      and we don't end up returning here: UNARY_PLUS_EXPR,
14198      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
14199   TREE_OPERAND (node, 0) = fold (op);
14200   TREE_TYPE (node) = prom_type;
14201   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
14202   return fold (node);
14203 }
14204
14205 /* Generic type resolution that sometimes takes place during node
14206    patching. Returned the resolved type or generate an error
14207    message. Return the resolved type or NULL_TREE.  */
14208
14209 static tree
14210 resolve_type_during_patch (type)
14211      tree type;
14212 {
14213   if (unresolved_type_p (type, NULL))
14214     {
14215       tree type_decl = resolve_and_layout (EXPR_WFL_NODE (type), type);
14216       if (!type_decl)
14217         {
14218           parse_error_context (type, 
14219                                "Class `%s' not found in type declaration",
14220                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
14221           return NULL_TREE;
14222         }
14223       return TREE_TYPE (type_decl);
14224     }
14225   return type;
14226 }
14227 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
14228    found. Otherwise NODE or something meant to replace it is returned.  */
14229
14230 static tree
14231 patch_cast (node, wfl_op)
14232      tree node;
14233      tree wfl_op;
14234 {
14235   tree op = TREE_OPERAND (node, 0);
14236   tree cast_type = TREE_TYPE (node);
14237   tree patched, op_type;
14238   char *t1;
14239
14240   /* Some string patching might be necessary at this stage */
14241   if ((patched = patch_string (op)))
14242     TREE_OPERAND (node, 0) = op = patched;
14243   op_type = TREE_TYPE (op);
14244
14245   /* First resolve OP_TYPE if unresolved */
14246   if (!(cast_type = resolve_type_during_patch (cast_type)))
14247     return error_mark_node;
14248
14249   /* Check on cast that are proven correct at compile time */
14250   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
14251     {
14252       /* Same type */
14253       if (cast_type == op_type)
14254         return node;
14255
14256       /* float and double type are converted to the original type main
14257          variant and then to the target type. */
14258       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
14259         op = convert (integer_type_node, op);
14260
14261       /* Try widening/narowwing convertion. Potentially, things need
14262          to be worked out in gcc so we implement the extreme cases
14263          correctly. fold_convert() needs to be fixed. */
14264       return convert (cast_type, op);
14265     }
14266
14267   /* It's also valid to cast a boolean into a boolean */
14268   if (op_type == boolean_type_node && cast_type == boolean_type_node)
14269     return node;
14270
14271   /* null can be casted to references */
14272   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
14273     return build_null_of_type (cast_type);
14274
14275   /* The remaining legal casts involve conversion between reference
14276      types. Check for their compile time correctness. */
14277   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
14278       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
14279     {
14280       TREE_TYPE (node) = promote_type (cast_type);
14281       /* Now, the case can be determined correct at compile time if
14282          OP_TYPE can be converted into CAST_TYPE by assignment
14283          conversion (5.2) */
14284
14285       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
14286         {
14287           TREE_SET_CODE (node, NOP_EXPR);
14288           return node;
14289         }
14290
14291       if (flag_emit_class_files)
14292         {
14293           TREE_SET_CODE (node, CONVERT_EXPR);
14294           return node;
14295         }
14296
14297       /* The cast requires a run-time check */
14298       return build (CALL_EXPR, promote_type (cast_type),
14299                     build_address_of (soft_checkcast_node),
14300                     tree_cons (NULL_TREE, build_class_ref (cast_type),
14301                                build_tree_list (NULL_TREE, op)),
14302                     NULL_TREE);
14303     }
14304
14305   /* Any other casts are proven incorrect at compile time */
14306   t1 = xstrdup (lang_printable_name (op_type, 0));
14307   parse_error_context (wfl_op, "Invalid cast from `%s' to `%s'",
14308                        t1, lang_printable_name (cast_type, 0));
14309   free (t1);
14310   return error_mark_node;
14311 }
14312
14313 /* Build a null constant and give it the type TYPE.  */
14314
14315 static tree
14316 build_null_of_type (type)
14317      tree type;
14318 {
14319   tree node = build_int_2 (0, 0);
14320   TREE_TYPE (node) = promote_type (type);
14321   return node;
14322 }
14323
14324 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
14325    a list of indices. */
14326 static tree
14327 build_array_ref (location, array, index)
14328      int location;
14329      tree array, index;
14330 {
14331   tree node = build (ARRAY_REF, NULL_TREE, array, index);
14332   EXPR_WFL_LINECOL (node) = location;
14333   return node;
14334 }
14335
14336 /* 15.12 Array Access Expression */
14337
14338 static tree
14339 patch_array_ref (node)
14340      tree node;
14341 {
14342   tree array = TREE_OPERAND (node, 0);
14343   tree array_type  = TREE_TYPE (array);
14344   tree index = TREE_OPERAND (node, 1);
14345   tree index_type = TREE_TYPE (index);
14346   int error_found = 0;
14347
14348   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14349
14350   if (TREE_CODE (array_type) == POINTER_TYPE)
14351     array_type = TREE_TYPE (array_type);
14352
14353   /* The array reference must be an array */
14354   if (!TYPE_ARRAY_P (array_type))
14355     {
14356       parse_error_context 
14357         (wfl_operator,
14358          "`[]' can only be applied to arrays. It can't be applied to `%s'",
14359          lang_printable_name (array_type, 0));
14360       TREE_TYPE (node) = error_mark_node;
14361       error_found = 1;
14362     }
14363
14364   /* The array index undergoes unary numeric promotion. The promoted
14365      type must be int */
14366   index = do_unary_numeric_promotion (index);
14367   if (TREE_TYPE (index) != int_type_node)
14368     {
14369       if (valid_cast_to_p (index_type, int_type_node))
14370         parse_error_context (wfl_operator,
14371    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
14372                              lang_printable_name (index_type, 0));
14373       else
14374         parse_error_context (wfl_operator,
14375           "Incompatible type for `[]'. Can't convert `%s' to `int'",
14376                              lang_printable_name (index_type, 0));
14377       TREE_TYPE (node) = error_mark_node;
14378       error_found = 1;
14379     }
14380
14381   if (error_found)
14382     return error_mark_node;
14383
14384   array_type = TYPE_ARRAY_ELEMENT (array_type);
14385
14386   if (flag_emit_class_files || flag_emit_xref)
14387     {
14388       TREE_OPERAND (node, 0) = array;
14389       TREE_OPERAND (node, 1) = index;
14390     }
14391   else
14392     node = build_java_arrayaccess (array, array_type, index);
14393   TREE_TYPE (node) = array_type;
14394   return node;
14395 }
14396
14397 /* 15.9 Array Creation Expressions */
14398
14399 static tree
14400 build_newarray_node (type, dims, extra_dims)
14401      tree type;
14402      tree dims;
14403      int extra_dims;
14404 {
14405   tree node =
14406     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
14407            build_int_2 (extra_dims, 0));
14408   return node;
14409 }
14410
14411 static tree
14412 patch_newarray (node)
14413      tree node;
14414 {
14415   tree type = TREE_OPERAND (node, 0);
14416   tree dims = TREE_OPERAND (node, 1);
14417   tree cdim, array_type;
14418   int error_found = 0;
14419   int ndims = 0;
14420   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
14421
14422   /* Dimension types are verified. It's better for the types to be
14423      verified in order. */
14424   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
14425     {
14426       int dim_error = 0;
14427       tree dim = TREE_VALUE (cdim);
14428
14429       /* Dim might have been saved during its evaluation */
14430       dim = (TREE_CODE (dim) == SAVE_EXPR ? TREE_OPERAND (dim, 0) : dim);
14431
14432       /* The type of each specified dimension must be an integral type. */
14433       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
14434         dim_error = 1;
14435
14436       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
14437          promoted type must be int. */
14438       else
14439         {
14440           dim = do_unary_numeric_promotion (dim);
14441           if (TREE_TYPE (dim) != int_type_node)
14442             dim_error = 1;
14443         }
14444
14445       /* Report errors on types here */
14446       if (dim_error)
14447         {
14448           parse_error_context 
14449             (TREE_PURPOSE (cdim), 
14450              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
14451              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
14452               "Explicit cast needed to" : "Can't"),
14453              lang_printable_name (TREE_TYPE (dim), 0));
14454           error_found = 1;
14455         }
14456
14457       TREE_PURPOSE (cdim) = NULL_TREE;
14458     }
14459
14460   /* Resolve array base type if unresolved */
14461   if (!(type = resolve_type_during_patch (type)))
14462     error_found = 1;
14463
14464   if (error_found)
14465     {
14466       /* We don't want further evaluation of this bogus array creation
14467          operation */
14468       TREE_TYPE (node) = error_mark_node;
14469       return error_mark_node;
14470     }
14471
14472   /* Set array_type to the actual (promoted) array type of the result. */
14473   if (TREE_CODE (type) == RECORD_TYPE)
14474     type = build_pointer_type (type);
14475   while (--xdims >= 0)
14476     {
14477       type = promote_type (build_java_array_type (type, -1));
14478     }
14479   dims = nreverse (dims);
14480   array_type = type;
14481   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
14482     {
14483       type = array_type;
14484       array_type
14485         = build_java_array_type (type,
14486                                  TREE_CODE (cdim) == INTEGER_CST
14487                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
14488                                  : -1);
14489       array_type = promote_type (array_type);
14490     }
14491   dims = nreverse (dims);
14492
14493   /* The node is transformed into a function call. Things are done
14494      differently according to the number of dimensions. If the number
14495      of dimension is equal to 1, then the nature of the base type
14496      (primitive or not) matters. */
14497   if (ndims == 1)
14498     return build_new_array (type, TREE_VALUE (dims));
14499   
14500   /* Can't reuse what's already written in expr.c because it uses the
14501      JVM stack representation. Provide a build_multianewarray. FIXME */
14502   return build (CALL_EXPR, array_type,
14503                 build_address_of (soft_multianewarray_node),
14504                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
14505                            tree_cons (NULL_TREE, 
14506                                       build_int_2 (ndims, 0), dims )),
14507                 NULL_TREE);
14508 }
14509
14510 /* 10.6 Array initializer.  */
14511
14512 /* Build a wfl for array element that don't have one, so we can
14513    pin-point errors.  */
14514
14515 static tree
14516 maybe_build_array_element_wfl (node)
14517      tree node;
14518 {
14519   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
14520     return build_expr_wfl (NULL_TREE, ctxp->filename,
14521                            ctxp->elc.line, ctxp->elc.prev_col);
14522   else
14523     return NULL_TREE;
14524 }
14525
14526 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
14527    identification of initialized arrays easier to detect during walk
14528    and expansion.  */
14529
14530 static tree
14531 build_new_array_init (location, values)
14532      int location;
14533      tree values;
14534 {
14535   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
14536   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
14537   EXPR_WFL_LINECOL (to_return) = location;
14538   return to_return;
14539 }
14540
14541 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
14542    occurred.  Otherwise return NODE after having set its type
14543    appropriately.  */
14544
14545 static tree
14546 patch_new_array_init (type, node)
14547      tree type, node;
14548 {
14549   int error_seen = 0;
14550   tree current, element_type;
14551   HOST_WIDE_INT length;
14552   int all_constant = 1;
14553   tree init = TREE_OPERAND (node, 0);
14554
14555   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
14556     {
14557       parse_error_context (node,
14558                            "Invalid array initializer for non-array type `%s'",
14559                            lang_printable_name (type, 1));
14560       return error_mark_node;
14561     }
14562   type = TREE_TYPE (type);
14563   element_type = TYPE_ARRAY_ELEMENT (type);
14564
14565   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
14566
14567   for (length = 0, current = CONSTRUCTOR_ELTS (init);
14568        current;  length++, current = TREE_CHAIN (current))
14569     {
14570       tree elt = TREE_VALUE (current);
14571       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
14572         {
14573           error_seen |= array_constructor_check_entry (element_type, current);
14574           elt = TREE_VALUE (current);
14575           /* When compiling to native code, STRING_CST is converted to
14576              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
14577           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
14578             all_constant = 0;
14579         }
14580       else
14581         {
14582           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
14583           TREE_PURPOSE (current) = NULL_TREE;
14584           all_constant = 0;
14585         }
14586       if (elt && TREE_CODE (elt) == TREE_LIST 
14587           && TREE_VALUE (elt) == error_mark_node)
14588         error_seen = 1;
14589     }
14590
14591   if (error_seen)
14592     return error_mark_node;
14593
14594   /* Create a new type. We can't reuse the one we have here by
14595      patching its dimension because it originally is of dimension -1
14596      hence reused by gcc. This would prevent triangular arrays. */
14597   type = build_java_array_type (element_type, length);
14598   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
14599   TREE_TYPE (node) = promote_type (type);
14600   TREE_CONSTANT (init) = all_constant;
14601   TREE_CONSTANT (node) = all_constant;
14602   return node;
14603 }
14604
14605 /* Verify that one entry of the initializer element list can be
14606    assigned to the array base type. Report 1 if an error occurred, 0
14607    otherwise.  */
14608
14609 static int
14610 array_constructor_check_entry (type, entry)
14611      tree type, entry;
14612 {
14613   char *array_type_string = NULL;       /* For error reports */
14614   tree value, type_value, new_value, wfl_value, patched;
14615   int error_seen = 0;
14616
14617   new_value = NULL_TREE;
14618   wfl_value = TREE_VALUE (entry);
14619
14620   value = java_complete_tree (TREE_VALUE (entry));
14621   /* patch_string return error_mark_node if arg is error_mark_node */
14622   if ((patched = patch_string (value)))
14623     value = patched;
14624   if (value == error_mark_node)
14625     return 1;
14626   
14627   type_value = TREE_TYPE (value);
14628   
14629   /* At anytime, try_builtin_assignconv can report a warning on
14630      constant overflow during narrowing. */
14631   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
14632   new_value = try_builtin_assignconv (wfl_operator, type, value);
14633   if (!new_value && (new_value = try_reference_assignconv (type, value)))
14634     type_value = promote_type (type);
14635
14636   /* Check and report errors */
14637   if (!new_value)
14638     {
14639       const char *const msg = (!valid_cast_to_p (type_value, type) ?
14640                    "Can't" : "Explicit cast needed to");
14641       if (!array_type_string)
14642         array_type_string = xstrdup (lang_printable_name (type, 1));
14643       parse_error_context 
14644         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
14645          msg, lang_printable_name (type_value, 1), array_type_string);
14646       error_seen = 1;
14647     }
14648   
14649   if (new_value)
14650     TREE_VALUE (entry) = new_value;
14651
14652   if (array_type_string)
14653     free (array_type_string);
14654
14655   TREE_PURPOSE (entry) = NULL_TREE;
14656   return error_seen;
14657 }
14658
14659 static tree
14660 build_this (location)
14661      int location;
14662 {
14663   tree node = build_wfl_node (this_identifier_node);
14664   TREE_SET_CODE (node, THIS_EXPR);
14665   EXPR_WFL_LINECOL (node) = location;
14666   return node;
14667 }
14668
14669 /* 14.15 The return statement. It builds a modify expression that
14670    assigns the returned value to the RESULT_DECL that hold the value
14671    to be returned. */
14672
14673 static tree
14674 build_return (location, op)
14675      int location;
14676      tree op;
14677 {
14678   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
14679   EXPR_WFL_LINECOL (node) = location;
14680   node = build_debugable_stmt (location, node);
14681   return node;
14682 }
14683
14684 static tree
14685 patch_return (node)
14686      tree node;
14687 {
14688   tree return_exp = TREE_OPERAND (node, 0);
14689   tree meth = current_function_decl;
14690   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
14691   int error_found = 0;
14692
14693   TREE_TYPE (node) = error_mark_node;
14694   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14695
14696   /* It's invalid to have a return value within a function that is
14697      declared with the keyword void or that is a constructor */
14698   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
14699     error_found = 1;
14700
14701   /* It's invalid to use a return statement in a static block */
14702   if (DECL_CLINIT_P (current_function_decl))
14703     error_found = 1;
14704
14705   /* It's invalid to have a no return value within a function that
14706      isn't declared with the keyword `void' */
14707   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
14708     error_found = 2;
14709   
14710   if (DECL_INSTINIT_P (current_function_decl))
14711     error_found = 1;
14712
14713   if (error_found)
14714     {
14715       if (DECL_INSTINIT_P (current_function_decl))
14716         parse_error_context (wfl_operator,
14717                              "`return' inside instance initializer");
14718         
14719       else if (DECL_CLINIT_P (current_function_decl))
14720         parse_error_context (wfl_operator,
14721                              "`return' inside static initializer");
14722
14723       else if (!DECL_CONSTRUCTOR_P (meth))
14724         {
14725           char *t = xstrdup (lang_printable_name (mtype, 0));
14726           parse_error_context (wfl_operator, 
14727                                "`return' with%s value from `%s %s'",
14728                                (error_found == 1 ? "" : "out"), 
14729                                t, lang_printable_name (meth, 0));
14730           free (t);
14731         }
14732       else
14733         parse_error_context (wfl_operator, 
14734                              "`return' with value from constructor `%s'",
14735                              lang_printable_name (meth, 0));
14736       return error_mark_node;
14737     }
14738
14739   /* If we have a return_exp, build a modify expression and expand
14740      it. Note: at that point, the assignment is declared valid, but we
14741      may want to carry some more hacks */
14742   if (return_exp)
14743     {
14744       tree exp = java_complete_tree (return_exp);
14745       tree modify, patched;
14746
14747       if ((patched = patch_string (exp)))
14748         exp = patched;
14749       
14750       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
14751       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
14752       modify = java_complete_tree (modify);
14753
14754       if (modify != error_mark_node)
14755         {
14756           TREE_SIDE_EFFECTS (modify) = 1;
14757           TREE_OPERAND (node, 0) = modify;
14758         }
14759       else
14760         return error_mark_node;
14761     }
14762   TREE_TYPE (node) = void_type_node;
14763   TREE_SIDE_EFFECTS (node) = 1;
14764   return node;
14765 }
14766
14767 /* 14.8 The if Statement */
14768
14769 static tree
14770 build_if_else_statement (location, expression, if_body, else_body)
14771      int location;
14772      tree expression, if_body, else_body;
14773 {
14774   tree node;
14775   if (!else_body)
14776     else_body = empty_stmt_node;
14777   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
14778   EXPR_WFL_LINECOL (node) = location;
14779   node = build_debugable_stmt (location, node);
14780   return node;
14781 }
14782
14783 static tree
14784 patch_if_else_statement (node)
14785      tree node;
14786 {
14787   tree expression = TREE_OPERAND (node, 0);
14788   int can_complete_normally
14789     = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
14790        | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2)));
14791
14792   TREE_TYPE (node) = error_mark_node;
14793   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14794
14795   /* The type of expression must be boolean */
14796   if (TREE_TYPE (expression) != boolean_type_node
14797       && TREE_TYPE (expression) != promoted_boolean_type_node)
14798     {
14799       parse_error_context 
14800         (wfl_operator, 
14801          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
14802          lang_printable_name (TREE_TYPE (expression), 0));
14803       return error_mark_node;
14804     }
14805   
14806   if (TREE_CODE (expression) == INTEGER_CST)
14807     {
14808       if (integer_zerop (expression))
14809         node = TREE_OPERAND (node, 2);
14810       else
14811         node = TREE_OPERAND (node, 1);
14812       if (CAN_COMPLETE_NORMALLY (node) != can_complete_normally)
14813         {
14814           node = build (COMPOUND_EXPR, void_type_node, node, empty_stmt_node);
14815           CAN_COMPLETE_NORMALLY (node) = can_complete_normally;
14816         }
14817       return node;
14818     }
14819   TREE_TYPE (node) = void_type_node;
14820   TREE_SIDE_EFFECTS (node) = 1;
14821   CAN_COMPLETE_NORMALLY (node) = can_complete_normally;
14822   return node;
14823 }
14824
14825 /* 14.6 Labeled Statements */
14826
14827 /* Action taken when a lableled statement is parsed. a new
14828    LABELED_BLOCK_EXPR is created. No statement is attached to the
14829    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
14830
14831 static tree
14832 build_labeled_block (location, label)
14833      int location;
14834      tree label;
14835 {
14836   tree label_name ;
14837   tree label_decl, node;
14838   if (label == NULL_TREE || label == continue_identifier_node)
14839     label_name = label;
14840   else
14841     {
14842       label_name = merge_qualified_name (label_id, label);
14843       /* Issue an error if we try to reuse a label that was previously
14844          declared */
14845       if (IDENTIFIER_LOCAL_VALUE (label_name))
14846         {
14847           EXPR_WFL_LINECOL (wfl_operator) = location;
14848           parse_error_context (wfl_operator,
14849             "Declaration of `%s' shadows a previous label declaration",
14850                                IDENTIFIER_POINTER (label));
14851           EXPR_WFL_LINECOL (wfl_operator) = 
14852             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
14853           parse_error_context (wfl_operator,
14854             "This is the location of the previous declaration of label `%s'",
14855                                IDENTIFIER_POINTER (label));
14856           java_error_count--;
14857         }
14858     }
14859
14860   label_decl = create_label_decl (label_name);
14861   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
14862   EXPR_WFL_LINECOL (node) = location;
14863   TREE_SIDE_EFFECTS (node) = 1;
14864   return node;
14865 }
14866
14867 /* A labeled statement LBE is attached a statement.  */
14868
14869 static tree
14870 finish_labeled_statement (lbe, statement)
14871      tree lbe;                  /* Labeled block expr */
14872      tree statement;
14873 {
14874   /* In anyways, tie the loop to its statement */
14875   LABELED_BLOCK_BODY (lbe) = statement;
14876   pop_labeled_block ();
14877   POP_LABELED_BLOCK ();
14878   return lbe;
14879 }
14880
14881 /* 14.10, 14.11, 14.12 Loop Statements */
14882
14883 /* Create an empty LOOP_EXPR and make it the last in the nested loop
14884    list. */
14885
14886 static tree
14887 build_new_loop (loop_body)
14888      tree loop_body;
14889 {
14890   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
14891   TREE_SIDE_EFFECTS (loop) = 1;
14892   PUSH_LOOP (loop);
14893   return loop;
14894 }
14895
14896 /* Create a loop body according to the following structure:
14897      COMPOUND_EXPR
14898        COMPOUND_EXPR            (loop main body)
14899          EXIT_EXPR              (this order is for while/for loops.
14900          LABELED_BLOCK_EXPR      the order is reversed for do loops)
14901            LABEL_DECL           (a continue occurring here branches at the 
14902            BODY                  end of this labeled block)
14903        INCREMENT                (if any)
14904
14905   REVERSED, if non zero, tells that the loop condition expr comes
14906   after the body, like in the do-while loop.
14907
14908   To obtain a loop, the loop body structure described above is
14909   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
14910
14911    LABELED_BLOCK_EXPR
14912      LABEL_DECL                   (use this label to exit the loop)
14913      LOOP_EXPR
14914        <structure described above> */
14915
14916 static tree
14917 build_loop_body (location, condition, reversed)
14918      int location;
14919      tree condition;
14920      int reversed;
14921 {
14922   tree first, second, body;
14923
14924   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
14925   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
14926   condition = build_debugable_stmt (location, condition);
14927   TREE_SIDE_EFFECTS (condition) = 1;
14928
14929   body = build_labeled_block (0, continue_identifier_node);
14930   first = (reversed ? body : condition);
14931   second = (reversed ? condition : body);
14932   return 
14933     build (COMPOUND_EXPR, NULL_TREE, 
14934            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
14935 }
14936
14937 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
14938    their order) on the current loop. Unlink the current loop from the
14939    loop list.  */
14940
14941 static tree
14942 finish_loop_body (location, condition, body, reversed)
14943      int location;
14944      tree condition, body;
14945      int reversed;
14946 {
14947   tree to_return = ctxp->current_loop;
14948   tree loop_body = LOOP_EXPR_BODY (to_return);
14949   if (condition)
14950     {
14951       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
14952       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
14953          The real EXIT_EXPR is one operand further. */
14954       EXPR_WFL_LINECOL (cnode) = location;
14955       /* This one is for accurate error reports */
14956       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
14957       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
14958     }
14959   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
14960   POP_LOOP ();
14961   return to_return;
14962 }
14963
14964 /* Tailored version of finish_loop_body for FOR loops, when FOR
14965    loops feature the condition part */
14966
14967 static tree
14968 finish_for_loop (location, condition, update, body)
14969     int location;
14970     tree condition, update, body;
14971 {
14972   /* Put the condition and the loop body in place */
14973   tree loop = finish_loop_body (location, condition, body, 0);
14974   /* LOOP is the current loop which has been now popped of the loop
14975      stack.  Mark the update block as reachable and install it.  We do
14976      this because the (current interpretation of the) JLS requires
14977      that the update expression be considered reachable even if the
14978      for loop's body doesn't complete normally.  */
14979   if (update != NULL_TREE && update != empty_stmt_node)
14980     {
14981       tree up2 = update;
14982       if (TREE_CODE (up2) == EXPR_WITH_FILE_LOCATION)
14983         up2 = EXPR_WFL_NODE (up2);
14984       /* Try to detect constraint violations.  These would be
14985          programming errors somewhere.  */
14986       if (! IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (up2)))
14987           || TREE_CODE (up2) == LOOP_EXPR)
14988         abort ();
14989       SUPPRESS_UNREACHABLE_ERROR (up2) = 1;
14990     }
14991   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
14992   return loop;
14993 }
14994
14995 /* Try to find the loop a block might be related to. This comprises
14996    the case where the LOOP_EXPR is found as the second operand of a
14997    COMPOUND_EXPR, because the loop happens to have an initialization
14998    part, then expressed as the first operand of the COMPOUND_EXPR. If
14999    the search finds something, 1 is returned. Otherwise, 0 is
15000    returned. The search is assumed to start from a
15001    LABELED_BLOCK_EXPR's block.  */
15002
15003 static tree
15004 search_loop (statement)
15005     tree statement;
15006 {
15007   if (TREE_CODE (statement) == LOOP_EXPR)
15008     return statement;
15009
15010   if (TREE_CODE (statement) == BLOCK)
15011     statement = BLOCK_SUBBLOCKS (statement);
15012   else
15013     return NULL_TREE;
15014
15015   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
15016     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
15017       statement = TREE_OPERAND (statement, 1);
15018
15019   return (TREE_CODE (statement) == LOOP_EXPR
15020           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
15021 }
15022
15023 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
15024    returned otherwise.  */
15025
15026 static int
15027 labeled_block_contains_loop_p (block, loop)
15028     tree block, loop;
15029 {
15030   if (!block)
15031     return 0;
15032
15033   if (LABELED_BLOCK_BODY (block) == loop)
15034     return 1;
15035
15036   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
15037     return 1;
15038
15039   return 0;
15040 }
15041
15042 /* If the loop isn't surrounded by a labeled statement, create one and
15043    insert LOOP as its body.  */
15044
15045 static tree
15046 patch_loop_statement (loop)
15047      tree loop;
15048 {
15049   tree loop_label;
15050
15051   TREE_TYPE (loop) = void_type_node;
15052   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
15053     return loop;
15054
15055   loop_label = build_labeled_block (0, NULL_TREE);
15056   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
15057      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
15058   LABELED_BLOCK_BODY (loop_label) = loop;
15059   PUSH_LABELED_BLOCK (loop_label);
15060   return loop_label;
15061 }
15062
15063 /* 14.13, 14.14: break and continue Statements */
15064
15065 /* Build a break or a continue statement. a null NAME indicates an
15066    unlabeled break/continue statement.  */
15067
15068 static tree
15069 build_bc_statement (location, is_break, name)
15070      int location, is_break;
15071      tree name;
15072 {
15073   tree break_continue, label_block_expr = NULL_TREE;
15074
15075   if (name)
15076     {
15077       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
15078             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
15079         /* Null means that we don't have a target for this named
15080            break/continue. In this case, we make the target to be the
15081            label name, so that the error can be reported accuratly in
15082            patch_bc_statement. */
15083         label_block_expr = EXPR_WFL_NODE (name);
15084     }
15085   /* Unlabeled break/continue will be handled during the
15086      break/continue patch operation */
15087   break_continue 
15088     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
15089
15090   IS_BREAK_STMT_P (break_continue) = is_break;
15091   TREE_SIDE_EFFECTS (break_continue) = 1;
15092   EXPR_WFL_LINECOL (break_continue) = location;
15093   break_continue = build_debugable_stmt (location, break_continue);
15094   return break_continue;
15095 }
15096
15097 /* Verification of a break/continue statement. */
15098
15099 static tree
15100 patch_bc_statement (node)
15101      tree node;
15102 {
15103   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
15104   tree labeled_block = ctxp->current_labeled_block;
15105   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15106  
15107   /* Having an identifier here means that the target is unknown. */
15108   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
15109     {
15110       parse_error_context (wfl_operator, "No label definition found for `%s'",
15111                            IDENTIFIER_POINTER (bc_label));
15112       return error_mark_node;
15113     }
15114   if (! IS_BREAK_STMT_P (node))
15115     {
15116       /* It's a continue statement. */
15117       for (;; labeled_block = TREE_CHAIN (labeled_block))
15118         {
15119           if (labeled_block == NULL_TREE)
15120             {
15121               if (bc_label == NULL_TREE)
15122                 parse_error_context (wfl_operator,
15123                                      "`continue' must be in loop");
15124               else
15125                 parse_error_context 
15126                   (wfl_operator, "continue label `%s' does not name a loop",
15127                    IDENTIFIER_POINTER (bc_label));
15128               return error_mark_node;
15129             }
15130           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
15131                == continue_identifier_node)
15132               && (bc_label == NULL_TREE
15133                   || TREE_CHAIN (labeled_block) == bc_label))
15134             {
15135               bc_label = labeled_block;
15136               break;
15137             }
15138         }
15139     }
15140   else if (!bc_label)
15141     { 
15142       for (;; labeled_block = TREE_CHAIN (labeled_block))
15143         {
15144           if (labeled_block == NULL_TREE)
15145             {
15146               parse_error_context (wfl_operator,
15147                                      "`break' must be in loop or switch");
15148               return error_mark_node;
15149             }
15150           target_stmt = LABELED_BLOCK_BODY (labeled_block);
15151           if (TREE_CODE (target_stmt) == SWITCH_EXPR
15152               || search_loop (target_stmt))
15153             {
15154               bc_label = labeled_block;
15155               break;
15156             }
15157         }
15158     }
15159
15160   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
15161   CAN_COMPLETE_NORMALLY (bc_label) = 1;
15162
15163   /* Our break/continue don't return values. */
15164   TREE_TYPE (node) = void_type_node;
15165   /* Encapsulate the break within a compound statement so that it's
15166      expanded all the times by expand_expr (and not clobbered
15167      sometimes, like after a if statement) */
15168   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
15169   TREE_SIDE_EFFECTS (node) = 1;
15170   return node;
15171 }
15172
15173 /* Process the exit expression belonging to a loop. Its type must be
15174    boolean.  */
15175
15176 static tree
15177 patch_exit_expr (node)
15178      tree node;
15179 {
15180   tree expression = TREE_OPERAND (node, 0);
15181   TREE_TYPE (node) = error_mark_node;
15182   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15183
15184   /* The type of expression must be boolean */
15185   if (TREE_TYPE (expression) != boolean_type_node)
15186     {
15187       parse_error_context 
15188         (wfl_operator, 
15189     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
15190          lang_printable_name (TREE_TYPE (expression), 0));
15191       return error_mark_node;
15192     }
15193   /* Now we know things are allright, invert the condition, fold and
15194      return */
15195   TREE_OPERAND (node, 0) = 
15196     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
15197
15198   if (! integer_zerop (TREE_OPERAND (node, 0))
15199       && ctxp->current_loop != NULL_TREE
15200       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
15201     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
15202   if (! integer_onep (TREE_OPERAND (node, 0)))
15203     CAN_COMPLETE_NORMALLY (node) = 1;
15204
15205
15206   TREE_TYPE (node) = void_type_node;
15207   return node;
15208 }
15209
15210 /* 14.9 Switch statement */
15211
15212 static tree
15213 patch_switch_statement (node)
15214      tree node;
15215 {
15216   tree se = TREE_OPERAND (node, 0), se_type;
15217   tree save, iter;
15218
15219   /* Complete the switch expression */
15220   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
15221   se_type = TREE_TYPE (se);
15222   /* The type of the switch expression must be char, byte, short or
15223      int */
15224   if (! JINTEGRAL_TYPE_P (se_type) || se_type == long_type_node)
15225     {
15226       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15227       parse_error_context (wfl_operator,
15228           "Incompatible type for `switch'. Can't convert `%s' to `int'",
15229                            lang_printable_name (se_type, 0));
15230       /* This is what java_complete_tree will check */
15231       TREE_OPERAND (node, 0) = error_mark_node;
15232       return error_mark_node;
15233     }
15234
15235   /* Save and restore the outer case label list.  */
15236   save = case_label_list;
15237   case_label_list = NULL_TREE;
15238
15239   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
15240
15241   /* See if we've found a duplicate label.  We can't leave this until
15242      code generation, because in `--syntax-only' and `-C' modes we
15243      don't do ordinary code generation.  */
15244   for (iter = case_label_list; iter != NULL_TREE; iter = TREE_CHAIN (iter))
15245     {
15246       HOST_WIDE_INT val = TREE_INT_CST_LOW (TREE_VALUE (iter));
15247       tree subiter;
15248       for (subiter = TREE_CHAIN (iter);
15249            subiter != NULL_TREE;
15250            subiter = TREE_CHAIN (subiter))
15251         {
15252           HOST_WIDE_INT subval = TREE_INT_CST_LOW (TREE_VALUE (subiter));
15253           if (val == subval)
15254             {
15255               EXPR_WFL_LINECOL (wfl_operator)
15256                 = EXPR_WFL_LINECOL (TREE_PURPOSE (iter));
15257               /* The case_label_list is in reverse order, so print the
15258                  outer label first.  */
15259               parse_error_context (wfl_operator, "duplicate case label: `"
15260                                    HOST_WIDE_INT_PRINT_DEC "'", subval);
15261               EXPR_WFL_LINECOL (wfl_operator)
15262                 = EXPR_WFL_LINECOL (TREE_PURPOSE (subiter));
15263               parse_error_context (wfl_operator, "original label is here");
15264
15265               break;
15266             }
15267         }
15268     }
15269
15270   case_label_list = save;
15271
15272   /* Ready to return */
15273   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
15274     {
15275       TREE_TYPE (node) = error_mark_node;
15276       return error_mark_node;
15277     }
15278   TREE_TYPE (node) = void_type_node;
15279   TREE_SIDE_EFFECTS (node) = 1;
15280   CAN_COMPLETE_NORMALLY (node)
15281     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
15282       || ! SWITCH_HAS_DEFAULT (node);
15283   return node;
15284 }
15285
15286 /* 14.18 The try/catch statements */
15287
15288 /* Encapsulate TRY_STMTS' in a try catch sequence. The catch clause
15289    catches TYPE and executes CATCH_STMTS.  */
15290
15291 static tree
15292 encapsulate_with_try_catch (location, type, try_stmts, catch_stmts)
15293      int location;
15294      tree type, try_stmts, catch_stmts;
15295 {
15296   tree try_block, catch_clause_param, catch_block, catch;
15297
15298   /* First build a try block */
15299   try_block = build_expr_block (try_stmts, NULL_TREE);
15300
15301   /* Build a catch block: we need a catch clause parameter */
15302   catch_clause_param = build_decl (VAR_DECL, 
15303                                    wpv_id, build_pointer_type (type));
15304   /* And a block */
15305   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
15306   
15307   /* Initialize the variable and store in the block */
15308   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
15309                  build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
15310   add_stmt_to_block (catch_block, NULL_TREE, catch);
15311
15312   /* Add the catch statements */
15313   add_stmt_to_block (catch_block, NULL_TREE, catch_stmts);
15314
15315   /* Now we can build a CATCH_EXPR */
15316   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
15317
15318   return build_try_statement (location, try_block, catch_block);
15319 }
15320
15321 static tree
15322 build_try_statement (location, try_block, catches)
15323      int location;
15324      tree try_block, catches;
15325 {
15326   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
15327   EXPR_WFL_LINECOL (node) = location;
15328   return node;
15329 }
15330
15331 static tree
15332 build_try_finally_statement (location, try_block, finally)
15333      int location;
15334      tree try_block, finally;
15335 {
15336   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
15337   EXPR_WFL_LINECOL (node) = location;
15338   return node;
15339 }
15340
15341 static tree
15342 patch_try_statement (node)
15343      tree node;
15344 {
15345   int error_found = 0;
15346   tree try = TREE_OPERAND (node, 0);
15347   /* Exception handlers are considered in left to right order */
15348   tree catch = nreverse (TREE_OPERAND (node, 1));
15349   tree current, caught_type_list = NULL_TREE;
15350
15351   /* Check catch clauses, if any. Every time we find an error, we try
15352      to process the next catch clause. We process the catch clause before
15353      the try block so that when processing the try block we can check thrown
15354      exceptions againts the caught type list. */
15355   for (current = catch; current; current = TREE_CHAIN (current))
15356     {
15357       tree carg_decl, carg_type;
15358       tree sub_current, catch_block, catch_clause;
15359       int unreachable;
15360
15361       /* At this point, the structure of the catch clause is
15362            CATCH_EXPR           (catch node)
15363              BLOCK              (with the decl of the parameter)
15364                COMPOUND_EXPR
15365                  MODIFY_EXPR   (assignment of the catch parameter)
15366                  BLOCK          (catch clause block)
15367        */
15368       catch_clause = TREE_OPERAND (current, 0);
15369       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
15370       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
15371
15372       /* Catch clauses can't have more than one parameter declared,
15373          but it's already enforced by the grammar. Make sure that the
15374          only parameter of the clause statement in of class Throwable
15375          or a subclass of Throwable, but that was done earlier. The
15376          catch clause parameter type has also been resolved. */
15377       
15378       /* Just make sure that the catch clause parameter type inherits
15379          from java.lang.Throwable */
15380       if (!inherits_from_p (carg_type, throwable_type_node))
15381         {
15382           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15383           parse_error_context (wfl_operator,
15384                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
15385                                lang_printable_name (carg_type, 0));
15386           error_found = 1;
15387           continue;
15388         }
15389       
15390       /* Partial check for unreachable catch statement: The catch
15391          clause is reachable iff is no earlier catch block A in
15392          the try statement such that the type of the catch
15393          clause's parameter is the same as or a subclass of the
15394          type of A's parameter */
15395       unreachable = 0;
15396       for (sub_current = catch;
15397            sub_current != current; sub_current = TREE_CHAIN (sub_current))
15398         {
15399           tree sub_catch_clause, decl;
15400           sub_catch_clause = TREE_OPERAND (sub_current, 0);
15401           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
15402
15403           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
15404             {
15405               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15406               parse_error_context 
15407                 (wfl_operator,
15408                  "`catch' not reached because of the catch clause at line %d",
15409                  EXPR_WFL_LINENO (sub_current));
15410               unreachable = error_found = 1;
15411               break;
15412             }
15413         }
15414       /* Complete the catch clause block */
15415       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
15416       if (catch_block == error_mark_node)
15417         {
15418           error_found = 1;
15419           continue;
15420         }
15421       if (CAN_COMPLETE_NORMALLY (catch_block))
15422         CAN_COMPLETE_NORMALLY (node) = 1;
15423       TREE_OPERAND (current, 0) = catch_block;
15424
15425       if (unreachable)
15426         continue;
15427
15428       /* Things to do here: the exception must be thrown */
15429
15430       /* Link this type to the caught type list */
15431       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
15432     }
15433
15434   PUSH_EXCEPTIONS (caught_type_list);
15435   if ((try = java_complete_tree (try)) == error_mark_node)
15436     error_found = 1;
15437   if (CAN_COMPLETE_NORMALLY (try))
15438     CAN_COMPLETE_NORMALLY (node) = 1;
15439   POP_EXCEPTIONS ();
15440
15441   /* Verification ends here */
15442   if (error_found) 
15443     return error_mark_node;
15444
15445   TREE_OPERAND (node, 0) = try;
15446   TREE_OPERAND (node, 1) = catch;
15447   TREE_TYPE (node) = void_type_node;
15448   return node;
15449 }
15450
15451 /* 14.17 The synchronized Statement */
15452
15453 static tree
15454 patch_synchronized_statement (node, wfl_op1)
15455     tree node, wfl_op1;
15456 {
15457   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
15458   tree block = TREE_OPERAND (node, 1);
15459
15460   tree tmp, enter, exit, expr_decl, assignment;
15461
15462   if (expr == error_mark_node)
15463     {
15464       block = java_complete_tree (block);
15465       return expr;
15466     }
15467
15468   /* We might be trying to synchronize on a STRING_CST */
15469   if ((tmp = patch_string (expr)))
15470     expr = tmp;
15471
15472   /* The TYPE of expr must be a reference type */
15473   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
15474     {
15475       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15476       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
15477                            lang_printable_name (TREE_TYPE (expr), 0));
15478       return error_mark_node;
15479     }
15480
15481   if (flag_emit_xref)
15482     {
15483       TREE_OPERAND (node, 0) = expr;
15484       TREE_OPERAND (node, 1) = java_complete_tree (block);
15485       CAN_COMPLETE_NORMALLY (node) = 1;
15486       return node;
15487     }
15488
15489   /* Generate a try-finally for the synchronized statement, except
15490      that the handler that catches all throw exception calls
15491      _Jv_MonitorExit and then rethrow the exception.
15492      The synchronized statement is then implemented as:
15493      TRY 
15494        {
15495          _Jv_MonitorEnter (expression)
15496          synchronized_block
15497          _Jv_MonitorExit (expression)
15498        }
15499      CATCH_ALL
15500        {
15501          e = _Jv_exception_info ();
15502          _Jv_MonitorExit (expression)
15503          Throw (e);
15504        } */
15505
15506   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
15507   BUILD_MONITOR_ENTER (enter, expr_decl);
15508   BUILD_MONITOR_EXIT (exit, expr_decl);
15509   CAN_COMPLETE_NORMALLY (enter) = 1;
15510   CAN_COMPLETE_NORMALLY (exit) = 1;
15511   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
15512   TREE_SIDE_EFFECTS (assignment) = 1;
15513   node = build (COMPOUND_EXPR, NULL_TREE,
15514                 build (COMPOUND_EXPR, NULL_TREE, assignment, enter),
15515                 build (TRY_FINALLY_EXPR, NULL_TREE, block, exit));
15516   node = build_expr_block (node, expr_decl);
15517
15518   return java_complete_tree (node);
15519 }
15520
15521 /* 14.16 The throw Statement */
15522
15523 static tree
15524 patch_throw_statement (node, wfl_op1)
15525     tree node, wfl_op1;
15526 {
15527   tree expr = TREE_OPERAND (node, 0);
15528   tree type = TREE_TYPE (expr);
15529   int unchecked_ok = 0, tryblock_throws_ok = 0;
15530
15531   /* Thrown expression must be assignable to java.lang.Throwable */
15532   if (!try_reference_assignconv (throwable_type_node, expr))
15533     {
15534       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15535       parse_error_context (wfl_operator,
15536     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
15537                            lang_printable_name (type, 0));
15538       /* If the thrown expression was a reference, we further the
15539          compile-time check. */
15540       if (!JREFERENCE_TYPE_P (type))
15541         return error_mark_node;
15542     }
15543
15544   /* At least one of the following must be true */
15545
15546   /* The type of the throw expression is a not checked exception,
15547      i.e. is a unchecked expression. */
15548   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
15549
15550   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15551   /* An instance can't throw a checked exception unless that exception
15552      is explicitly declared in the `throws' clause of each
15553      constructor. This doesn't apply to anonymous classes, since they
15554      don't have declared constructors. */
15555   if (!unchecked_ok 
15556       && DECL_INSTINIT_P (current_function_decl)
15557       && !ANONYMOUS_CLASS_P (current_class))
15558     {
15559       tree current;
15560       for (current = TYPE_METHODS (current_class); current; 
15561            current = TREE_CHAIN (current))
15562         if (DECL_CONSTRUCTOR_P (current) 
15563             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
15564           {
15565             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)", 
15566                                  lang_printable_name (TREE_TYPE (expr), 0));
15567             return error_mark_node;
15568           }
15569     }
15570
15571   /* Throw is contained in a try statement and at least one catch
15572      clause can receive the thrown expression or the current method is
15573      declared to throw such an exception. Or, the throw statement is
15574      contained in a method or constructor declaration and the type of
15575      the Expression is assignable to at least one type listed in the
15576      throws clause the declaration. */
15577   if (!unchecked_ok)
15578     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
15579   if (!(unchecked_ok || tryblock_throws_ok))
15580     {
15581       /* If there is a surrounding try block that has no matching
15582          clatch clause, report it first. A surrounding try block exits
15583          only if there is something after the list of checked
15584          exception thrown by the current function (if any). */
15585       if (IN_TRY_BLOCK_P ())
15586         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
15587                              lang_printable_name (type, 0));
15588       /* If we have no surrounding try statement and the method doesn't have
15589          any throws, report it now. FIXME */
15590
15591       /* We report that the exception can't be throw from a try block
15592          in all circumstances but when the `throw' is inside a static
15593          block. */
15594       else if (!EXCEPTIONS_P (currently_caught_type_list) 
15595                && !tryblock_throws_ok)
15596         {
15597           if (DECL_CLINIT_P (current_function_decl))
15598             parse_error_context (wfl_operator,
15599                    "Checked exception `%s' can't be thrown in initializer",
15600                                  lang_printable_name (type, 0));
15601           else
15602             parse_error_context (wfl_operator,
15603                    "Checked exception `%s' isn't thrown from a `try' block", 
15604                                  lang_printable_name (type, 0));
15605         }
15606       /* Otherwise, the current method doesn't have the appropriate
15607          throws declaration */
15608       else
15609         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
15610                              lang_printable_name (type, 0));
15611       return error_mark_node;
15612     }
15613
15614   if (! flag_emit_class_files && ! flag_emit_xref)
15615     BUILD_THROW (node, expr);
15616
15617   /* If doing xrefs, keep the location where the `throw' was seen. */
15618   if (flag_emit_xref)
15619     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
15620   return node;
15621 }
15622
15623 /* Check that exception said to be thrown by method DECL can be
15624    effectively caught from where DECL is invoked.  */
15625
15626 static void
15627 check_thrown_exceptions (location, decl)
15628      int location;
15629      tree decl;
15630 {
15631   tree throws;
15632   /* For all the unchecked exceptions thrown by DECL */
15633   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
15634        throws = TREE_CHAIN (throws)) 
15635     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
15636       {
15637 #if 1
15638         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
15639         if (DECL_NAME (decl) == get_identifier ("clone"))
15640           continue;
15641 #endif
15642         EXPR_WFL_LINECOL (wfl_operator) = location;
15643         if (DECL_FINIT_P (current_function_decl))
15644           parse_error_context
15645             (wfl_operator, "Exception `%s' can't be thrown in initializer",
15646              lang_printable_name (TREE_VALUE (throws), 0));
15647         else 
15648           {
15649             parse_error_context 
15650               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
15651                lang_printable_name (TREE_VALUE (throws), 0),
15652                (DECL_INIT_P (current_function_decl) ?
15653                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
15654                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
15655           }
15656       }
15657 }
15658
15659 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
15660    try-catch blocks, OR is listed in the `throws' clause of the
15661    current method.  */
15662
15663 static int
15664 check_thrown_exceptions_do (exception)
15665      tree exception;
15666 {
15667   tree list = currently_caught_type_list;
15668   resolve_and_layout (exception, NULL_TREE);
15669   /* First, all the nested try-catch-finally at that stage. The
15670      last element contains `throws' clause exceptions, if any. */
15671   if (IS_UNCHECKED_EXCEPTION_P (exception))
15672     return 1;
15673   while (list)
15674     {
15675       tree caught;
15676       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
15677         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
15678           return 1;
15679       list = TREE_CHAIN (list);
15680     }
15681   return 0;
15682 }
15683
15684 static void
15685 purge_unchecked_exceptions (mdecl)
15686      tree mdecl;
15687 {
15688   tree throws = DECL_FUNCTION_THROWS (mdecl);
15689   tree new = NULL_TREE;
15690
15691   while (throws)
15692     {
15693       tree next = TREE_CHAIN (throws);
15694       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
15695         {
15696           TREE_CHAIN (throws) = new;
15697           new = throws;
15698         }
15699       throws = next;
15700     }
15701   /* List is inverted here, but it doesn't matter */
15702   DECL_FUNCTION_THROWS (mdecl) = new;
15703 }
15704
15705 /* This function goes over all of CLASS_TYPE ctors and checks whether
15706    each of them features at least one unchecked exception in its
15707    `throws' clause. If it's the case, it returns `true', `false'
15708    otherwise.  */
15709
15710 static bool
15711 ctors_unchecked_throws_clause_p (class_type)
15712      tree class_type;
15713 {
15714   tree current;
15715
15716   for (current = TYPE_METHODS (class_type); current;
15717        current = TREE_CHAIN (current))
15718     {
15719       bool ctu = false; /* Ctor Throws Unchecked */
15720       if (DECL_CONSTRUCTOR_P (current))
15721         {
15722           tree throws;
15723           for (throws = DECL_FUNCTION_THROWS (current); throws && !ctu;
15724                throws = TREE_CHAIN (throws))
15725             if (inherits_from_p (TREE_VALUE (throws), exception_type_node))
15726               ctu = true;
15727         }
15728       /* We return false as we found one ctor that is unfit. */
15729       if (!ctu && DECL_CONSTRUCTOR_P (current))
15730         return false;
15731     }
15732   /* All ctors feature at least one unchecked exception in their
15733      `throws' clause. */
15734   return true;
15735 }
15736
15737 /* 15.24 Conditional Operator ?: */
15738
15739 static tree
15740 patch_conditional_expr (node, wfl_cond, wfl_op1)
15741      tree node, wfl_cond, wfl_op1;
15742 {
15743   tree cond = TREE_OPERAND (node, 0);
15744   tree op1 = TREE_OPERAND (node, 1);
15745   tree op2 = TREE_OPERAND (node, 2);
15746   tree resulting_type = NULL_TREE;
15747   tree t1, t2, patched;
15748   int error_found = 0;
15749
15750   /* Operands of ?: might be StringBuffers crafted as a result of a
15751      string concatenation. Obtain a descent operand here.  */
15752   if ((patched = patch_string (op1)))
15753     TREE_OPERAND (node, 1) = op1 = patched;
15754   if ((patched = patch_string (op2)))
15755     TREE_OPERAND (node, 2) = op2 = patched;
15756
15757   t1 = TREE_TYPE (op1);
15758   t2 = TREE_TYPE (op2);
15759
15760   /* The first expression must be a boolean */
15761   if (TREE_TYPE (cond) != boolean_type_node)
15762     {
15763       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
15764       parse_error_context (wfl_operator,
15765                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
15766                            lang_printable_name (TREE_TYPE (cond), 0));
15767       error_found = 1;
15768     }
15769
15770   /* Second and third can be numeric, boolean (i.e. primitive),
15771      references or null. Anything else results in an error */
15772   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
15773         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
15774             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
15775         || (t1 == boolean_type_node && t2 == boolean_type_node)))
15776     error_found = 1;
15777
15778   /* Determine the type of the conditional expression. Same types are
15779      easy to deal with */
15780   else if (t1 == t2)
15781     resulting_type = t1;
15782
15783   /* There are different rules for numeric types */
15784   else if (JNUMERIC_TYPE_P (t1))
15785     {
15786       /* if byte/short found, the resulting type is short */
15787       if ((t1 == byte_type_node && t2 == short_type_node)
15788           || (t1 == short_type_node && t2 == byte_type_node))
15789         resulting_type = short_type_node;
15790
15791       /* If t1 is a constant int and t2 is of type byte, short or char
15792          and t1's value fits in t2, then the resulting type is t2 */
15793       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
15794           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
15795         resulting_type = t2;
15796
15797       /* If t2 is a constant int and t1 is of type byte, short or char
15798          and t2's value fits in t1, then the resulting type is t1 */
15799       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
15800           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
15801         resulting_type = t1;
15802
15803       /* Otherwise, binary numeric promotion is applied and the
15804          resulting type is the promoted type of operand 1 and 2 */
15805       else 
15806         resulting_type = binary_numeric_promotion (t1, t2, 
15807                                                    &TREE_OPERAND (node, 1), 
15808                                                    &TREE_OPERAND (node, 2));
15809     }
15810
15811   /* Cases of a reference and a null type */
15812   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
15813     resulting_type = t1;
15814
15815   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
15816     resulting_type = t2;
15817
15818   /* Last case: different reference types. If a type can be converted
15819      into the other one by assignment conversion, the latter
15820      determines the type of the expression */
15821   else if ((resulting_type = try_reference_assignconv (t1, op2)))
15822     resulting_type = promote_type (t1);
15823
15824   else if ((resulting_type = try_reference_assignconv (t2, op1)))
15825     resulting_type = promote_type (t2);
15826
15827   /* If we don't have any resulting type, we're in trouble */
15828   if (!resulting_type)
15829     {
15830       char *t = xstrdup (lang_printable_name (t1, 0));
15831       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15832       parse_error_context (wfl_operator,
15833                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
15834                            t, lang_printable_name (t2, 0));
15835       free (t);
15836       error_found = 1;
15837     }
15838
15839   if (error_found)
15840     {
15841       TREE_TYPE (node) = error_mark_node;
15842       return error_mark_node;
15843     }
15844
15845   TREE_TYPE (node) = resulting_type;
15846   TREE_SET_CODE (node, COND_EXPR);
15847   CAN_COMPLETE_NORMALLY (node) = 1;
15848   return node;
15849 }
15850
15851 /* Wrap EXPR with code to initialize DECL's class, if appropriate. */
15852
15853 static tree
15854 maybe_build_class_init_for_field (decl, expr)
15855     tree decl, expr;
15856 {
15857   tree clas = DECL_CONTEXT (decl);
15858   if (flag_emit_class_files || flag_emit_xref)
15859     return expr;
15860
15861   if (TREE_CODE (decl) == VAR_DECL && FIELD_STATIC (decl)
15862       && FIELD_FINAL (decl))
15863     {
15864       tree init = DECL_INITIAL (decl);
15865       if (init != NULL_TREE)
15866         init = fold_constant_for_init (init, decl);
15867       if (init != NULL_TREE && CONSTANT_VALUE_P (init))
15868         return expr;
15869     }
15870
15871   return build_class_init (clas, expr);
15872 }
15873
15874 /* Try to constant fold NODE.
15875    If NODE is not a constant expression, return NULL_EXPR.
15876    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
15877
15878 static tree
15879 fold_constant_for_init (node, context)
15880      tree node;
15881      tree context;
15882 {
15883   tree op0, op1, val;
15884   enum tree_code code = TREE_CODE (node);
15885
15886   switch (code)
15887     {
15888     case STRING_CST:
15889     case INTEGER_CST:
15890     case REAL_CST:
15891       return node;
15892
15893     case PLUS_EXPR:
15894     case MINUS_EXPR:
15895     case MULT_EXPR:
15896     case TRUNC_MOD_EXPR:
15897     case RDIV_EXPR:
15898     case LSHIFT_EXPR:
15899     case RSHIFT_EXPR:
15900     case URSHIFT_EXPR:
15901     case BIT_AND_EXPR:
15902     case BIT_XOR_EXPR:
15903     case BIT_IOR_EXPR:
15904     case TRUTH_ANDIF_EXPR:
15905     case TRUTH_ORIF_EXPR:
15906     case EQ_EXPR: 
15907     case NE_EXPR:
15908     case GT_EXPR:
15909     case GE_EXPR:
15910     case LT_EXPR:
15911     case LE_EXPR:
15912       op0 = TREE_OPERAND (node, 0);
15913       op1 = TREE_OPERAND (node, 1);
15914       val = fold_constant_for_init (op0, context);
15915       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15916         return NULL_TREE;
15917       TREE_OPERAND (node, 0) = val;
15918       val = fold_constant_for_init (op1, context);
15919       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15920         return NULL_TREE;
15921       TREE_OPERAND (node, 1) = val;
15922       return patch_binop (node, op0, op1);
15923
15924     case UNARY_PLUS_EXPR:
15925     case NEGATE_EXPR:
15926     case TRUTH_NOT_EXPR:
15927     case BIT_NOT_EXPR:
15928     case CONVERT_EXPR:
15929       op0 = TREE_OPERAND (node, 0);
15930       val = fold_constant_for_init (op0, context);
15931       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15932         return NULL_TREE;
15933       TREE_OPERAND (node, 0) = val;
15934       return patch_unaryop (node, op0);
15935       break;
15936
15937     case COND_EXPR:
15938       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
15939       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15940         return NULL_TREE;
15941       TREE_OPERAND (node, 0) = val;
15942       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
15943       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15944         return NULL_TREE;
15945       TREE_OPERAND (node, 1) = val;
15946       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
15947       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15948         return NULL_TREE;
15949       TREE_OPERAND (node, 2) = val;
15950       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
15951         : TREE_OPERAND (node, 2);
15952
15953     case VAR_DECL:
15954     case FIELD_DECL:
15955       if (! FIELD_FINAL (node)
15956           || DECL_INITIAL (node) == NULL_TREE)
15957         return NULL_TREE;
15958       val = DECL_INITIAL (node);
15959       /* Guard against infinite recursion. */
15960       DECL_INITIAL (node) = NULL_TREE;
15961       val = fold_constant_for_init (val, node);
15962       DECL_INITIAL (node) = val;
15963       return val;
15964
15965     case EXPR_WITH_FILE_LOCATION:
15966       /* Compare java_complete_tree and resolve_expression_name. */
15967       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
15968           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
15969         {
15970           tree name = EXPR_WFL_NODE (node);
15971           tree decl;
15972           if (PRIMARY_P (node))
15973             return NULL_TREE;
15974           else if (! QUALIFIED_P (name))
15975             {
15976               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
15977               if (decl == NULL_TREE 
15978                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
15979                 return NULL_TREE;
15980               return fold_constant_for_init (decl, decl);
15981             }
15982           else
15983             {
15984               /* Install the proper context for the field resolution.
15985                  The prior context is restored once the name is
15986                  properly qualified. */
15987               tree saved_current_class = current_class;
15988               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
15989               current_class = DECL_CONTEXT (context);
15990               qualify_ambiguous_name (node);
15991               current_class = saved_current_class;
15992               if (resolve_field_access (node, &decl, NULL)
15993                   && decl != NULL_TREE)
15994                 return fold_constant_for_init (decl, decl);
15995               return NULL_TREE;
15996             }
15997         }
15998       else
15999         {
16000           op0 = TREE_OPERAND (node, 0);
16001           val = fold_constant_for_init (op0, context);
16002           if (val == NULL_TREE || ! TREE_CONSTANT (val))
16003             return NULL_TREE;
16004           TREE_OPERAND (node, 0) = val;
16005           return val;
16006         }
16007
16008 #ifdef USE_COMPONENT_REF
16009     case IDENTIFIER:
16010     case COMPONENT_REF:
16011       ?;
16012 #endif
16013
16014     default:
16015       return NULL_TREE;
16016     }
16017 }
16018
16019 #ifdef USE_COMPONENT_REF
16020 /* Context is 'T' for TypeName, 'P' for PackageName,
16021    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
16022
16023 tree
16024 resolve_simple_name (name, context)
16025      tree name;
16026      int context;
16027 {
16028 }
16029
16030 tree
16031 resolve_qualified_name (name, context)
16032      tree name;
16033      int context;
16034 {
16035 }
16036 #endif
16037
16038 /* Mark P, which is really a `struct parser_ctxt **' for GC.  */
16039
16040 static void
16041 mark_parser_ctxt (p)
16042      void *p;
16043 {
16044   struct parser_ctxt *pc = *((struct parser_ctxt **) p);
16045   int i;
16046
16047   if (!pc)
16048     return;
16049
16050 #ifndef JC1_LITE
16051   for (i = 0; i < 11; ++i)
16052     ggc_mark_tree (pc->modifier_ctx[i]);
16053   ggc_mark_tree (pc->class_type);
16054   ggc_mark_tree (pc->function_decl);
16055   ggc_mark_tree (pc->package);
16056   ggc_mark_tree (pc->class_list);
16057   ggc_mark_tree (pc->current_parsed_class);
16058   ggc_mark_tree (pc->current_parsed_class_un);
16059   ggc_mark_tree (pc->non_static_initialized);
16060   ggc_mark_tree (pc->static_initialized);
16061   ggc_mark_tree (pc->instance_initializers);
16062   ggc_mark_tree (pc->import_list);
16063   ggc_mark_tree (pc->import_demand_list);
16064   ggc_mark_tree (pc->current_loop);
16065   ggc_mark_tree (pc->current_labeled_block);
16066 #endif /* JC1_LITE */
16067
16068   if (pc->next)
16069     mark_parser_ctxt (&pc->next);
16070 }
16071
16072 void
16073 init_src_parse ()
16074 {
16075   /* Sanity check; we've been bit by this before.  */
16076   if (ARRAY_SIZE (ctxp->modifier_ctx) != MODIFIER_TK - PUBLIC_TK)
16077     abort ();
16078 }
16079
16080 \f
16081
16082 /* This section deals with the functions that are called when tables
16083    recording class initialization information are traversed.  */
16084
16085 /* Attach to PTR (a block) the declaration found in ENTRY. */
16086
16087 static int
16088 attach_init_test_initialization_flags (entry, ptr)
16089      PTR *entry;
16090      PTR ptr;
16091 {
16092   tree block = (tree)ptr;
16093   struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
16094   
16095   TREE_CHAIN (ite->value) = BLOCK_EXPR_DECLS (block);
16096   BLOCK_EXPR_DECLS (block) = ite->value;
16097   return true;
16098 }
16099
16100 /* This function is called for each classes that is known definitely
16101    assigned when a given static method was called. This function
16102    augments a compound expression (INFO) storing all assignment to
16103    initialized static class flags if a flag already existed, otherwise
16104    a new one is created.  */
16105
16106 static int
16107 emit_test_initialization (entry_p, info)
16108      PTR *entry_p;
16109      PTR info;
16110 {
16111   tree l = (tree) info;
16112   tree decl, init;
16113   tree key = (tree) *entry_p;
16114   tree *ite;
16115   htab_t cf_ht = DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl);
16116
16117   /* If we haven't found a flag and we're dealing with self registered
16118      with current_function_decl, then don't do anything. Self is
16119      always added as definitely initialized but this information is
16120      valid only if used outside the current function. */
16121   if (current_function_decl == TREE_PURPOSE (l)
16122       && java_treetreehash_find (cf_ht, key) == NULL)
16123     return true;
16124     
16125   ite = java_treetreehash_new (cf_ht, key);
16126
16127   /* If we don't have a variable, create one and install it. */
16128   if (*ite == NULL)
16129     {
16130       tree block;
16131       
16132       decl = build_decl (VAR_DECL, NULL_TREE, boolean_type_node);
16133       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
16134       LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
16135       DECL_CONTEXT (decl) = current_function_decl;
16136       DECL_INITIAL (decl) = boolean_true_node;
16137
16138       /* The trick is to find the right context for it. */
16139       block = BLOCK_SUBBLOCKS (GET_CURRENT_BLOCK (current_function_decl));
16140       TREE_CHAIN (decl) = BLOCK_EXPR_DECLS (block);
16141       BLOCK_EXPR_DECLS (block) = decl;
16142       *ite = decl;
16143     }
16144   else
16145     decl = *ite;
16146
16147   /* Now simply augment the compound that holds all the assignments
16148      pertaining to this method invocation. */
16149   init = build (MODIFY_EXPR, boolean_type_node, decl, boolean_true_node);
16150   TREE_SIDE_EFFECTS (init) = 1;
16151   TREE_VALUE (l) = add_stmt_to_compound (TREE_VALUE (l), void_type_node, init);
16152   TREE_SIDE_EFFECTS (TREE_VALUE (l)) = 1;
16153
16154   return true;
16155 }
16156
16157 #include "gt-java-parse.h"
16158 #include "gtype-java.h"