OSDN Git Service

Daily bump.
[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 "obstack.h"
55 #include "toplev.h"
56 #include "flags.h"
57 #include "java-tree.h"
58 #include "jcf.h"
59 #include "lex.h"
60 #include "parse.h"
61 #include "zipfile.h"
62 #include "convert.h"
63 #include "buffer.h"
64 #include "xref.h"
65 #include "function.h"
66 #include "except.h"
67 #include "ggc.h"
68
69 #ifndef DIR_SEPARATOR
70 #define DIR_SEPARATOR '/'
71 #endif
72
73 /* Local function prototypes */
74 static char *java_accstring_lookup PARAMS ((int));
75 static void  classitf_redefinition_error PARAMS ((const char *,tree, tree, tree));
76 static void  variable_redefinition_error PARAMS ((tree, tree, tree, int));
77 static tree  create_class PARAMS ((int, tree, tree, tree));
78 static tree  create_interface PARAMS ((int, tree, tree));
79 static void  end_class_declaration PARAMS ((int));
80 static tree  find_field PARAMS ((tree, tree));
81 static tree lookup_field_wrapper PARAMS ((tree, tree));
82 static int   duplicate_declaration_error_p PARAMS ((tree, tree, tree));
83 static void  register_fields PARAMS ((int, tree, tree));
84 static tree parser_qualified_classname PARAMS ((tree));
85 static int  parser_check_super PARAMS ((tree, tree, tree));
86 static int  parser_check_super_interface PARAMS ((tree, tree, tree));
87 static void check_modifiers_consistency PARAMS ((int));
88 static tree lookup_cl PARAMS ((tree));
89 static tree lookup_java_method2 PARAMS ((tree, tree, int));
90 static tree method_header PARAMS ((int, tree, tree, tree));
91 static void fix_method_argument_names PARAMS ((tree ,tree));
92 static tree method_declarator PARAMS ((tree, tree));
93 static void parse_warning_context PARAMS ((tree cl, const char *msg, ...))
94   ATTRIBUTE_PRINTF_2;
95 static void issue_warning_error_from_context PARAMS ((tree, const char *msg, va_list))
96   ATTRIBUTE_PRINTF (2, 0);
97 static void parse_ctor_invocation_error PARAMS ((void));
98 static tree parse_jdk1_1_error PARAMS ((const char *));
99 static void complete_class_report_errors PARAMS ((jdep *));
100 static int process_imports PARAMS ((void));
101 static void read_import_dir PARAMS ((tree));
102 static int find_in_imports_on_demand PARAMS ((tree, tree));
103 static void find_in_imports PARAMS ((tree, tree));
104 static void check_inner_class_access PARAMS ((tree, tree, tree));
105 static int check_pkg_class_access PARAMS ((tree, tree, bool));
106 static void register_package PARAMS ((tree));
107 static tree resolve_package PARAMS ((tree, tree *, tree *));
108 static tree resolve_class PARAMS ((tree, tree, tree, tree));
109 static void declare_local_variables PARAMS ((int, tree, tree));
110 static void dump_java_tree PARAMS ((enum tree_dump_index, tree));
111 static void source_start_java_method PARAMS ((tree));
112 static void source_end_java_method PARAMS ((void));
113 static tree find_name_in_single_imports PARAMS ((tree));
114 static void check_abstract_method_header PARAMS ((tree));
115 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
116 static tree resolve_expression_name PARAMS ((tree, tree *));
117 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
118 static int check_class_interface_creation PARAMS ((int, int, tree, 
119                                                   tree, tree, tree));
120 static tree patch_method_invocation PARAMS ((tree, tree, tree, int,
121                                             int *, tree *));
122 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
123 static int in_same_package PARAMS ((tree, tree));
124 static tree resolve_and_layout PARAMS ((tree, tree));
125 static tree qualify_and_find PARAMS ((tree, tree, tree));
126 static tree resolve_no_layout PARAMS ((tree, tree));
127 static int invocation_mode PARAMS ((tree, int));
128 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
129                                                             tree, tree));
130 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
131                                                    tree *, tree *));
132 static tree find_most_specific_methods_list PARAMS ((tree));
133 static int argument_types_convertible PARAMS ((tree, tree));
134 static tree patch_invoke PARAMS ((tree, tree, tree));
135 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
136 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
137 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
138 static tree check_inner_circular_reference PARAMS ((tree, tree));
139 static tree check_circular_reference PARAMS ((tree));
140 static tree obtain_incomplete_type PARAMS ((tree));
141 static tree java_complete_lhs PARAMS ((tree));
142 static tree java_complete_tree PARAMS ((tree));
143 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
144 static int analyze_clinit_body PARAMS ((tree, tree));
145 static int maybe_yank_clinit PARAMS ((tree));
146 static void start_complete_expand_method PARAMS ((tree));
147 static void java_complete_expand_method PARAMS ((tree));
148 static void java_expand_method_bodies PARAMS ((tree));
149 static int  unresolved_type_p PARAMS ((tree, tree *));
150 static void create_jdep_list PARAMS ((struct parser_ctxt *));
151 static tree build_expr_block PARAMS ((tree, tree));
152 static tree enter_block PARAMS ((void));
153 static tree exit_block PARAMS ((void));
154 static tree lookup_name_in_blocks PARAMS ((tree));
155 static void maybe_absorb_scoping_blocks PARAMS ((void));
156 static tree build_method_invocation PARAMS ((tree, tree));
157 static tree build_new_invocation PARAMS ((tree, tree));
158 static tree build_assignment PARAMS ((int, int, tree, tree));
159 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
160 static tree patch_assignment PARAMS ((tree, tree));
161 static tree patch_binop PARAMS ((tree, tree, tree));
162 static tree build_unaryop PARAMS ((int, int, tree));
163 static tree build_incdec PARAMS ((int, int, tree, int));
164 static tree patch_unaryop PARAMS ((tree, tree));
165 static tree build_cast PARAMS ((int, tree, tree));
166 static tree build_null_of_type PARAMS ((tree));
167 static tree patch_cast PARAMS ((tree, tree));
168 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
169 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
170 static int valid_cast_to_p PARAMS ((tree, tree));
171 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
172 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
173 static tree try_reference_assignconv PARAMS ((tree, tree));
174 static tree build_unresolved_array_type PARAMS ((tree));
175 static int build_type_name_from_array_name PARAMS ((tree, tree *));
176 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
177 static tree build_array_ref PARAMS ((int, tree, tree));
178 static tree patch_array_ref PARAMS ((tree));
179 static tree make_qualified_name PARAMS ((tree, tree, int));
180 static tree merge_qualified_name PARAMS ((tree, tree));
181 static tree make_qualified_primary PARAMS ((tree, tree, int));
182 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
183                                                      tree *, tree *));
184 static void qualify_ambiguous_name PARAMS ((tree));
185 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
186 static tree build_newarray_node PARAMS ((tree, tree, int));
187 static tree patch_newarray PARAMS ((tree));
188 static tree resolve_type_during_patch PARAMS ((tree));
189 static tree build_this PARAMS ((int));
190 static tree build_wfl_wrap PARAMS ((tree, int));
191 static tree build_return PARAMS ((int, tree));
192 static tree patch_return PARAMS ((tree));
193 static tree maybe_access_field PARAMS ((tree, tree, tree));
194 static int complete_function_arguments PARAMS ((tree));
195 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
196                                                       tree, tree));
197 static int not_accessible_p PARAMS ((tree, tree, tree, int));
198 static void check_deprecation PARAMS ((tree, tree));
199 static int class_in_current_package PARAMS ((tree));
200 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
201 static tree patch_if_else_statement PARAMS ((tree));
202 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
203 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
204 static tree patch_exit_expr PARAMS ((tree));
205 static tree build_labeled_block PARAMS ((int, tree));
206 static tree finish_labeled_statement PARAMS ((tree, tree));
207 static tree build_bc_statement PARAMS ((int, int, tree));
208 static tree patch_bc_statement PARAMS ((tree));
209 static tree patch_loop_statement PARAMS ((tree));
210 static tree build_new_loop PARAMS ((tree));
211 static tree build_loop_body PARAMS ((int, tree, int));
212 static tree finish_loop_body PARAMS ((int, tree, tree, int));
213 static tree build_debugable_stmt PARAMS ((int, tree));
214 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
215 static tree patch_switch_statement PARAMS ((tree));
216 static tree string_constant_concatenation PARAMS ((tree, tree));
217 static tree build_string_concatenation PARAMS ((tree, tree));
218 static tree patch_string_cst PARAMS ((tree));
219 static tree patch_string PARAMS ((tree));
220 static tree encapsulate_with_try_catch PARAMS ((int, tree, tree, tree));
221 static tree build_try_statement PARAMS ((int, tree, tree));
222 static tree build_try_finally_statement PARAMS ((int, tree, tree));
223 static tree patch_try_statement PARAMS ((tree));
224 static tree patch_synchronized_statement PARAMS ((tree, tree));
225 static tree patch_throw_statement PARAMS ((tree, tree));
226 static void check_thrown_exceptions PARAMS ((int, tree));
227 static int check_thrown_exceptions_do PARAMS ((tree));
228 static void purge_unchecked_exceptions PARAMS ((tree));
229 static bool ctors_unchecked_throws_clause_p PARAMS ((tree));
230 static void check_throws_clauses PARAMS ((tree, tree, tree));
231 static void finish_method_declaration PARAMS ((tree));
232 static tree build_super_invocation PARAMS ((tree));
233 static int verify_constructor_circularity PARAMS ((tree, tree));
234 static char *constructor_circularity_msg PARAMS ((tree, tree));
235 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
236                                                           int, int));
237 static const char *get_printable_method_name PARAMS ((tree));
238 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
239 static tree generate_finit PARAMS ((tree));
240 static tree generate_instinit PARAMS ((tree));
241 static tree build_instinit_invocation PARAMS ((tree));
242 static void fix_constructors PARAMS ((tree));
243 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
244                                                             tree, int *));
245 static tree craft_constructor PARAMS ((tree, tree));
246 static int verify_constructor_super PARAMS ((tree));
247 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
248 static void start_artificial_method_body PARAMS ((tree));
249 static void end_artificial_method_body PARAMS ((tree));
250 static int check_method_redefinition PARAMS ((tree, tree));
251 static int check_method_types_complete PARAMS ((tree));
252 static void java_check_regular_methods PARAMS ((tree));
253 static void java_check_abstract_methods PARAMS ((tree));
254 static void unreachable_stmt_error PARAMS ((tree));
255 static tree find_expr_with_wfl PARAMS ((tree));
256 static void missing_return_error PARAMS ((tree));
257 static tree build_new_array_init PARAMS ((int, tree));
258 static tree patch_new_array_init PARAMS ((tree, tree));
259 static tree maybe_build_array_element_wfl PARAMS ((tree));
260 static int array_constructor_check_entry PARAMS ((tree, tree));
261 static const char *purify_type_name PARAMS ((const char *));
262 static tree fold_constant_for_init PARAMS ((tree, tree));
263 static tree strip_out_static_field_access_decl PARAMS ((tree));
264 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
265 static void static_ref_err PARAMS ((tree, tree, tree));
266 static void parser_add_interface PARAMS ((tree, tree, tree));
267 static void add_superinterfaces PARAMS ((tree, tree));
268 static tree jdep_resolve_class PARAMS ((jdep *));
269 static int note_possible_classname PARAMS ((const char *, int));
270 static void java_complete_expand_classes PARAMS ((void));
271 static void java_complete_expand_class PARAMS ((tree));
272 static void java_complete_expand_methods PARAMS ((tree));
273 static tree cut_identifier_in_qualified PARAMS ((tree));
274 static tree java_stabilize_reference PARAMS ((tree));
275 static tree do_unary_numeric_promotion PARAMS ((tree));
276 static char * operator_string PARAMS ((tree));
277 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
278 static tree merge_string_cste PARAMS ((tree, tree, int));
279 static tree java_refold PARAMS ((tree));
280 static int java_decl_equiv PARAMS ((tree, tree));
281 static int binop_compound_p PARAMS ((enum tree_code));
282 static tree search_loop PARAMS ((tree));
283 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
284 static int check_abstract_method_definitions PARAMS ((int, tree, tree));
285 static void java_check_abstract_method_definitions PARAMS ((tree));
286 static void java_debug_context_do PARAMS ((int));
287 static void java_parser_context_push_initialized_field PARAMS ((void));
288 static void java_parser_context_pop_initialized_field PARAMS ((void));
289 static tree reorder_static_initialized PARAMS ((tree));
290 static void java_parser_context_suspend PARAMS ((void));
291 static void java_parser_context_resume PARAMS ((void));
292 static int pop_current_osb PARAMS ((struct parser_ctxt *));
293
294 /* JDK 1.1 work. FIXME */
295
296 static tree maybe_make_nested_class_name PARAMS ((tree));
297 static void make_nested_class_name PARAMS ((tree));
298 static void set_nested_class_simple_name_value PARAMS ((tree, int));
299 static void link_nested_class_to_enclosing PARAMS ((void));
300 static tree resolve_inner_class PARAMS ((struct hash_table *, tree, tree *,
301                                          tree *, tree));
302 static tree find_as_inner_class PARAMS ((tree, tree, tree));
303 static tree find_as_inner_class_do PARAMS ((tree, tree));
304 static int check_inner_class_redefinition PARAMS ((tree, tree));
305
306 static tree build_thisn_assign PARAMS ((void));
307 static tree build_current_thisn PARAMS ((tree));
308 static tree build_access_to_thisn PARAMS ((tree, tree, int));
309 static tree maybe_build_thisn_access_method PARAMS ((tree));
310
311 static tree build_outer_field_access PARAMS ((tree, tree));
312 static tree build_outer_field_access_methods PARAMS ((tree));
313 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
314                                                   tree, tree));
315 static tree build_outer_method_access_method PARAMS ((tree));
316 static tree build_new_access_id PARAMS ((void));
317 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
318                                                     tree, tree));
319
320 static int outer_field_access_p PARAMS ((tree, tree));
321 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
322                                                  tree *, tree *));
323 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
324 static tree build_incomplete_class_ref PARAMS ((int, tree));
325 static tree patch_incomplete_class_ref PARAMS ((tree));
326 static tree create_anonymous_class PARAMS ((int, tree));
327 static void patch_anonymous_class PARAMS ((tree, tree, tree));
328 static void add_inner_class_fields PARAMS ((tree, tree));
329
330 static tree build_dot_class_method PARAMS ((tree));
331 static tree build_dot_class_method_invocation PARAMS ((tree));
332 static void create_new_parser_context PARAMS ((int));
333 static void mark_parser_ctxt PARAMS ((void *));
334 static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
335
336 static bool attach_init_test_initialization_flags PARAMS ((struct hash_entry *,
337                                                           PTR));
338 static bool emit_test_initialization PARAMS ((struct hash_entry *, 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 tree label_id = NULL_TREE;
379
380 /* The "StringBuffer" identifier used for the String `+' operator. */
381 static tree wfl_string_buffer = NULL_TREE; 
382
383 /* The "append" identifier used for String `+' operator.  */
384 static tree wfl_append = NULL_TREE;
385
386 /* The "toString" identifier used for String `+' operator. */
387 static tree wfl_to_string = NULL_TREE;
388
389 /* The "java.lang" import qualified name.  */
390 static tree java_lang_id = NULL_TREE;
391
392 /* The generated `inst$' identifier used for generated enclosing
393    instance/field access functions.  */
394 static tree inst_id = NULL_TREE;
395
396 /* The "java.lang.Cloneable" qualified name.  */
397 static tree java_lang_cloneable = NULL_TREE;
398
399 /* The "java.io.Serializable" qualified name.  */
400 static tree java_io_serializable = NULL_TREE; 
401
402 /* Context and flag for static blocks */
403 static tree current_static_block = NULL_TREE;
404
405 /* The generated `write_parm_value$' identifier.  */
406 static tree wpv_id;
407
408 /* The list of all packages we've seen so far */
409 static tree package_list = NULL_TREE;
410  
411 /* Hold THIS for the scope of the current method decl.  */
412 static 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 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 tree case_label_list; 
424
425 static tree src_parse_roots[1];
426
427 /* All classes seen from source code */
428 #define gclass_list src_parse_roots[0]
429
430 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
431    line and point it out.  */
432 /* Should point out the one that don't fit. ASCII/unicode, going
433    backward. FIXME */
434
435 #define check_modifiers(__message, __value, __mask) do {        \
436   if ((__value) & ~(__mask))                                    \
437     {                                                           \
438       int i, remainder = (__value) & ~(__mask);                 \
439       for (i = 0; i <= 10; i++)                                 \
440         if ((1 << i) & remainder)                               \
441           parse_error_context (ctxp->modifier_ctx [i], (__message), \
442                                java_accstring_lookup (1 << i)); \
443     }                                                           \
444 } while (0)
445
446 %}
447
448 %union {
449   tree node;
450   int sub_token;
451   struct {
452     int token;
453     int location;
454   } operator;
455   int value;
456 }
457
458 %{
459 #include "lex.c"
460 %}
461
462 %pure_parser
463
464 /* Things defined here have to match the order of what's in the
465    binop_lookup table.  */
466
467 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
468 %token   LS_TK           SRS_TK          ZRS_TK
469 %token   AND_TK          XOR_TK          OR_TK
470 %token   BOOL_AND_TK BOOL_OR_TK 
471 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
472
473 /* This maps to the same binop_lookup entry than the token above */
474
475 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
476 %token   REM_ASSIGN_TK   
477 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
478 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
479
480
481 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
482
483 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
484 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
485 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
486 %token   PAD_TK          ABSTRACT_TK        STRICT_TK
487 %token   MODIFIER_TK
488
489 /* Keep those two in order, too */
490 %token   DECR_TK INCR_TK
491
492 /* From now one, things can be in any order */
493
494 %token   DEFAULT_TK      IF_TK              THROW_TK
495 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
496 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
497 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
498 %token   VOID_TK         CATCH_TK           INTERFACE_TK
499 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
500 %token   SUPER_TK        WHILE_TK           CLASS_TK
501 %token   SWITCH_TK       CONST_TK           TRY_TK
502 %token   FOR_TK          NEW_TK             CONTINUE_TK
503 %token   GOTO_TK         PACKAGE_TK         THIS_TK
504
505 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
506 %token   CHAR_TK         INTEGRAL_TK
507
508 %token   FLOAT_TK        DOUBLE_TK          FP_TK
509
510 %token   ID_TK
511
512 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
513
514 %token   ASSIGN_ANY_TK   ASSIGN_TK
515 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
516
517 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
518 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
519
520 %type    <value>        modifiers MODIFIER_TK final synchronized
521
522 %type    <node>         super ID_TK identifier
523 %type    <node>         name simple_name qualified_name
524 %type    <node>         type_declaration compilation_unit
525                         field_declaration method_declaration extends_interfaces
526                         interfaces interface_type_list
527                         class_member_declaration
528                         import_declarations package_declaration 
529                         type_declarations interface_body
530                         interface_member_declaration constant_declaration
531                         interface_member_declarations interface_type
532                         abstract_method_declaration interface_type_list
533 %type    <node>         class_body_declaration class_member_declaration
534                         static_initializer constructor_declaration block
535 %type    <node>         class_body_declarations constructor_header
536 %type    <node>         class_or_interface_type class_type class_type_list
537                         constructor_declarator explicit_constructor_invocation
538 %type    <node>         dim_expr dim_exprs this_or_super throws
539
540 %type    <node>         variable_declarator_id variable_declarator
541                         variable_declarators variable_initializer
542                         variable_initializers constructor_body
543                         array_initializer
544
545 %type    <node>         class_body block_end constructor_block_end
546 %type    <node>         statement statement_without_trailing_substatement
547                         labeled_statement if_then_statement label_decl
548                         if_then_else_statement while_statement for_statement
549                         statement_nsi labeled_statement_nsi do_statement
550                         if_then_else_statement_nsi while_statement_nsi
551                         for_statement_nsi statement_expression_list for_init
552                         for_update statement_expression expression_statement
553                         primary_no_new_array expression primary
554                         array_creation_expression array_type
555                         class_instance_creation_expression field_access
556                         method_invocation array_access something_dot_new
557                         argument_list postfix_expression while_expression 
558                         post_increment_expression post_decrement_expression
559                         unary_expression_not_plus_minus unary_expression
560                         pre_increment_expression pre_decrement_expression
561                         unary_expression_not_plus_minus cast_expression
562                         multiplicative_expression additive_expression
563                         shift_expression relational_expression 
564                         equality_expression and_expression 
565                         exclusive_or_expression inclusive_or_expression
566                         conditional_and_expression conditional_or_expression
567                         conditional_expression assignment_expression
568                         left_hand_side assignment for_header for_begin
569                         constant_expression do_statement_begin empty_statement
570                         switch_statement synchronized_statement throw_statement
571                         try_statement switch_expression switch_block
572                         catches catch_clause catch_clause_parameter finally
573                         anonymous_class_creation trap_overflow_corner_case
574 %type    <node>         return_statement break_statement continue_statement
575
576 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
577 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
578 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
579 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
580 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
581 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
582 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
583 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
584 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
585 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
586 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
587 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
588 %type    <operator>     NEW_TK
589
590 %type    <node>         method_body 
591         
592 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
593                         STRING_LIT_TK NULL_TK VOID_TK
594
595 %type    <node>         IF_TK WHILE_TK FOR_TK
596
597 %type    <node>         formal_parameter_list formal_parameter
598                         method_declarator method_header
599
600 %type    <node>         primitive_type reference_type type 
601                         BOOLEAN_TK INTEGRAL_TK FP_TK
602
603 /* Added or modified JDK 1.1 rule types  */
604 %type    <node>         type_literals
605
606 %%
607 /* 19.2 Production from 2.3: The Syntactic Grammar  */
608 goal:
609                 {
610                   /* Register static variables with the garbage
611                      collector.  */
612                   ggc_add_tree_root (&label_id, 1);
613                   ggc_add_tree_root (&wfl_string_buffer, 1);
614                   ggc_add_tree_root (&wfl_append, 1);
615                   ggc_add_tree_root (&wfl_to_string, 1);
616                   ggc_add_tree_root (&java_lang_id, 1);
617                   ggc_add_tree_root (&inst_id, 1);
618                   ggc_add_tree_root (&java_lang_cloneable, 1);
619                   ggc_add_tree_root (&java_io_serializable, 1);
620                   ggc_add_tree_root (&current_static_block, 1);
621                   ggc_add_tree_root (&wpv_id, 1);
622                   ggc_add_tree_root (&package_list, 1);
623                   ggc_add_tree_root (&current_this, 1);
624                   ggc_add_tree_root (&currently_caught_type_list, 1);
625                   ggc_add_tree_root (&case_label_list, 1);
626                   ggc_add_root (&ctxp, 1, 
627                                 sizeof (struct parser_ctxt *),
628                                 mark_parser_ctxt);
629                   ggc_add_root (&ctxp_for_generation, 1, 
630                                 sizeof (struct parser_ctxt *),
631                                 mark_parser_ctxt);
632                 }
633         compilation_unit
634                 {}
635 ;
636
637 /* 19.3 Productions from 3: Lexical structure  */
638 literal:
639         INT_LIT_TK
640 |       FP_LIT_TK
641 |       BOOL_LIT_TK
642 |       CHAR_LIT_TK
643 |       STRING_LIT_TK
644 |       NULL_TK
645 ;
646
647 /* 19.4 Productions from 4: Types, Values and Variables  */
648 type:
649         primitive_type
650 |       reference_type
651 ;
652
653 primitive_type:
654         INTEGRAL_TK
655 |       FP_TK
656 |       BOOLEAN_TK
657 ;
658
659 reference_type:
660         class_or_interface_type
661 |       array_type
662 ;
663
664 class_or_interface_type:
665         name
666 ;
667
668 class_type:
669         class_or_interface_type /* Default rule */
670 ;
671
672 interface_type:
673          class_or_interface_type
674 ;
675
676 array_type:
677         primitive_type dims
678                 { 
679                   int osb = pop_current_osb (ctxp);
680                   tree t = build_java_array_type (($1), -1);
681                   while (--osb)
682                     t = build_unresolved_array_type (t);
683                   $$ = t;
684                 }
685 |       name dims
686                 { 
687                   int osb = pop_current_osb (ctxp);
688                   tree t = $1;
689                   while (osb--)
690                     t = build_unresolved_array_type (t);
691                   $$ = t;
692                 }
693 ;
694
695 /* 19.5 Productions from 6: Names  */
696 name:
697         simple_name             /* Default rule */
698 |       qualified_name          /* Default rule */
699 ;
700
701 simple_name:
702         identifier              /* Default rule */
703 ;
704
705 qualified_name:
706         name DOT_TK identifier
707                 { $$ = make_qualified_name ($1, $3, $2.location); }
708 ;
709
710 identifier:
711         ID_TK
712 ;
713
714 /* 19.6: Production from 7: Packages  */
715 compilation_unit:
716                 {$$ = NULL;}
717 |       package_declaration
718 |       import_declarations
719 |       type_declarations
720 |       package_declaration import_declarations
721 |       package_declaration type_declarations
722 |       import_declarations type_declarations
723 |       package_declaration import_declarations type_declarations
724 ;
725
726 import_declarations:
727         import_declaration
728                 {
729                   $$ = NULL;
730                 }
731 |       import_declarations import_declaration
732                 {
733                   $$ = NULL;
734                 }
735 ;
736
737 type_declarations:
738         type_declaration
739 |       type_declarations type_declaration
740 ;
741
742 package_declaration:
743         PACKAGE_TK name SC_TK
744                 { 
745                   ctxp->package = EXPR_WFL_NODE ($2);
746                   register_package (ctxp->package);
747                 }
748 |       PACKAGE_TK error
749                 {yyerror ("Missing name"); RECOVER;}
750 |       PACKAGE_TK name error
751                 {yyerror ("';' expected"); RECOVER;}
752 ;
753
754 import_declaration:
755         single_type_import_declaration
756 |       type_import_on_demand_declaration
757 ;
758
759 single_type_import_declaration:
760         IMPORT_TK name SC_TK
761                 {
762                   tree name = EXPR_WFL_NODE ($2), last_name;
763                   int   i = IDENTIFIER_LENGTH (name)-1;
764                   const char *last = &IDENTIFIER_POINTER (name)[i];
765                   while (last != IDENTIFIER_POINTER (name))
766                     {
767                       if (last [0] == '.')
768                         break;
769                       last--;
770                     }
771                   last_name = get_identifier (++last);
772                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
773                     {
774                       tree err = find_name_in_single_imports (last_name);
775                       if (err && err != name)
776                         parse_error_context
777                           ($2, "Ambiguous class: `%s' and `%s'",
778                            IDENTIFIER_POINTER (name), 
779                            IDENTIFIER_POINTER (err));
780                       else
781                         REGISTER_IMPORT ($2, last_name);
782                     }
783                   else
784                     REGISTER_IMPORT ($2, last_name);
785                 }
786 |       IMPORT_TK error
787                 {yyerror ("Missing name"); RECOVER;}
788 |       IMPORT_TK name error
789                 {yyerror ("';' expected"); RECOVER;}
790 ;
791
792 type_import_on_demand_declaration:
793         IMPORT_TK name DOT_TK MULT_TK SC_TK
794                 {
795                   tree name = EXPR_WFL_NODE ($2);
796                   tree it;
797                   /* Search for duplicates. */
798                   for (it = ctxp->import_demand_list; it; it = TREE_CHAIN (it))
799                     if (EXPR_WFL_NODE (TREE_PURPOSE (it)) == name)
800                       break;
801                   /* Don't import the same thing more than once, just ignore
802                      duplicates (7.5.2) */
803                   if (! it)
804                     {
805                       read_import_dir ($2);
806                       ctxp->import_demand_list = 
807                         chainon (ctxp->import_demand_list,
808                                  build_tree_list ($2, NULL_TREE));
809                     }
810                 }
811 |       IMPORT_TK name DOT_TK error
812                 {yyerror ("'*' expected"); RECOVER;}
813 |       IMPORT_TK name DOT_TK MULT_TK error
814                 {yyerror ("';' expected"); RECOVER;}
815 ;
816
817 type_declaration:
818         class_declaration
819                 { end_class_declaration (0); }
820 |       interface_declaration
821                 { end_class_declaration (0); }
822 |       empty_statement
823 |       error
824                 {
825                   YYERROR_NOW;
826                   yyerror ("Class or interface declaration expected");
827                 }
828 ;
829
830 /* 19.7 Shortened from the original:
831    modifiers: modifier | modifiers modifier
832    modifier: any of public...  */
833 modifiers:
834         MODIFIER_TK
835                 {
836                   $$ = (1 << $1);
837                 }
838 |       modifiers MODIFIER_TK
839                 {
840                   int acc = (1 << $2);
841                   if ($$ & acc)
842                     parse_error_context 
843                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
844                        java_accstring_lookup (acc));
845                   else
846                     {
847                       $$ |= acc;
848                     }
849                 }
850 ;
851
852 /* 19.8.1 Production from $8.1: Class Declaration */
853 class_declaration:
854         modifiers CLASS_TK identifier super interfaces
855                 { create_class ($1, $3, $4, $5); }
856         class_body
857 |       CLASS_TK identifier super interfaces 
858                 { create_class (0, $2, $3, $4); }
859         class_body
860 |       modifiers CLASS_TK error
861                 {yyerror ("Missing class name"); RECOVER;}
862 |       CLASS_TK error
863                 {yyerror ("Missing class name"); RECOVER;}
864 |       CLASS_TK identifier error
865                 {
866                   if (!ctxp->class_err) yyerror ("'{' expected"); 
867                   DRECOVER(class1);
868                 }
869 |       modifiers CLASS_TK identifier error
870                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
871 ;
872
873 super:
874                 { $$ = NULL; }
875 |       EXTENDS_TK class_type
876                 { $$ = $2; }
877 |       EXTENDS_TK class_type error
878                 {yyerror ("'{' expected"); ctxp->class_err=1;}
879 |       EXTENDS_TK error
880                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
881 ;
882
883 interfaces:
884                 { $$ = NULL_TREE; }
885 |       IMPLEMENTS_TK interface_type_list
886                 { $$ = $2; }
887 |       IMPLEMENTS_TK error
888                 {
889                   ctxp->class_err=1;
890                   yyerror ("Missing interface name"); 
891                 }
892 ;
893
894 interface_type_list:
895         interface_type
896                 { 
897                   ctxp->interface_number = 1;
898                   $$ = build_tree_list ($1, NULL_TREE);
899                 }
900 |       interface_type_list C_TK interface_type
901                 { 
902                   ctxp->interface_number++;
903                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
904                 }
905 |       interface_type_list C_TK error
906                 {yyerror ("Missing interface name"); RECOVER;}
907 ;
908
909 class_body:
910         OCB_TK CCB_TK
911                 { 
912                   /* Store the location of the `}' when doing xrefs */
913                   if (flag_emit_xref)
914                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
915                       EXPR_WFL_ADD_COL ($2.location, 1);
916                   $$ = GET_CPC ();
917                 }
918 |       OCB_TK class_body_declarations CCB_TK
919                 { 
920                   /* Store the location of the `}' when doing xrefs */
921                   if (flag_emit_xref)
922                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
923                       EXPR_WFL_ADD_COL ($3.location, 1);
924                   $$ = GET_CPC ();
925                 }
926 ;
927
928 class_body_declarations:
929         class_body_declaration
930 |       class_body_declarations class_body_declaration
931 ;
932
933 class_body_declaration:
934         class_member_declaration
935 |       static_initializer
936 |       constructor_declaration
937 |       block                   /* Added, JDK1.1, instance initializer */
938                 {
939                   if ($1 != empty_stmt_node)
940                     {
941                       TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
942                       SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
943                     }
944                 }
945 ;
946
947 class_member_declaration:
948         field_declaration
949 |       method_declaration
950 |       class_declaration       /* Added, JDK1.1 inner classes */
951                 { end_class_declaration (1); }
952 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
953                 { end_class_declaration (1); }
954 |       empty_statement
955 ;
956
957 /* 19.8.2 Productions from 8.3: Field Declarations  */
958 field_declaration:
959         type variable_declarators SC_TK
960                 { register_fields (0, $1, $2); }
961 |       modifiers type variable_declarators SC_TK
962                 {
963                   check_modifiers 
964                     ("Illegal modifier `%s' for field declaration",
965                      $1, FIELD_MODIFIERS);
966                   check_modifiers_consistency ($1);
967                   register_fields ($1, $2, $3);
968                 }
969 ;
970
971 variable_declarators:
972         /* Should we use build_decl_list () instead ? FIXME */
973         variable_declarator     /* Default rule */
974 |       variable_declarators C_TK variable_declarator
975                 { $$ = chainon ($1, $3); }
976 |       variable_declarators C_TK error
977                 {yyerror ("Missing term"); RECOVER;}
978 ;
979
980 variable_declarator:
981         variable_declarator_id
982                 { $$ = build_tree_list ($1, NULL_TREE); }
983 |       variable_declarator_id ASSIGN_TK variable_initializer
984                 { 
985                   if (java_error_count)
986                     $3 = NULL_TREE;
987                   $$ = build_tree_list 
988                     ($1, build_assignment ($2.token, $2.location, $1, $3));
989                 }
990 |       variable_declarator_id ASSIGN_TK error
991                 {
992                   yyerror ("Missing variable initializer");
993                   $$ = build_tree_list ($1, NULL_TREE);
994                   RECOVER;
995                 }
996 |       variable_declarator_id ASSIGN_TK variable_initializer error
997                 {
998                   yyerror ("';' expected");
999                   $$ = build_tree_list ($1, NULL_TREE);
1000                   RECOVER;
1001                 }
1002 ;
1003
1004 variable_declarator_id:
1005         identifier
1006 |       variable_declarator_id OSB_TK CSB_TK
1007                 { $$ = build_unresolved_array_type ($1); }
1008 |       identifier error
1009                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
1010 |       variable_declarator_id OSB_TK error
1011                 { 
1012                   tree node = java_lval.node;
1013                   if (node && (TREE_CODE (node) == INTEGER_CST
1014                                || TREE_CODE (node) == EXPR_WITH_FILE_LOCATION))
1015                     yyerror ("Can't specify array dimension in a declaration");
1016                   else
1017                     yyerror ("']' expected");
1018                   DRECOVER(vdi);
1019                 }
1020 |       variable_declarator_id CSB_TK error
1021                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
1022 ;
1023
1024 variable_initializer:
1025         expression
1026 |       array_initializer
1027 ;
1028
1029 /* 19.8.3 Productions from 8.4: Method Declarations  */
1030 method_declaration:
1031         method_header 
1032                 {
1033                   current_function_decl = $1;
1034                   if (current_function_decl
1035                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
1036                     source_start_java_method (current_function_decl);
1037                   else
1038                     current_function_decl = NULL_TREE;
1039                 }
1040         method_body
1041                 { finish_method_declaration ($3); }
1042 |       method_header error
1043                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
1044 ;
1045
1046 method_header:  
1047         type method_declarator throws
1048                 { $$ = method_header (0, $1, $2, $3); }
1049 |       VOID_TK method_declarator throws
1050                 { $$ = method_header (0, void_type_node, $2, $3); }
1051 |       modifiers type method_declarator throws
1052                 { $$ = method_header ($1, $2, $3, $4); }
1053 |       modifiers VOID_TK method_declarator throws
1054                 { $$ = method_header ($1, void_type_node, $3, $4); }
1055 |       type error
1056                 {
1057                   yyerror ("Invalid method declaration, method name required");
1058                   RECOVER;
1059                 }
1060 |       modifiers type error
1061                 {RECOVER;}
1062 |       VOID_TK error
1063                 {yyerror ("Identifier expected"); RECOVER;}
1064 |       modifiers VOID_TK error
1065                 {yyerror ("Identifier expected"); RECOVER;}
1066 |       modifiers error
1067                 {
1068                   yyerror ("Invalid method declaration, return type required");
1069                   RECOVER;
1070                 }
1071 ;
1072
1073 method_declarator:
1074         identifier OP_TK CP_TK
1075                 { 
1076                   ctxp->formal_parameter_number = 0;
1077                   $$ = method_declarator ($1, NULL_TREE);
1078                 }
1079 |       identifier OP_TK formal_parameter_list CP_TK
1080                 { $$ = method_declarator ($1, $3); }
1081 |       method_declarator OSB_TK CSB_TK
1082                 {
1083                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1084                   TREE_PURPOSE ($1) = 
1085                     build_unresolved_array_type (TREE_PURPOSE ($1));
1086                   parse_warning_context 
1087                     (wfl_operator, 
1088                      "Discouraged form of returned type specification");
1089                 }
1090 |       identifier OP_TK error
1091                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1092 |       method_declarator OSB_TK error
1093                 {yyerror ("']' expected"); RECOVER;}
1094 ;
1095
1096 formal_parameter_list:
1097         formal_parameter
1098                 {
1099                   ctxp->formal_parameter_number = 1;
1100                 }
1101 |       formal_parameter_list C_TK formal_parameter
1102                 {
1103                   ctxp->formal_parameter_number += 1;
1104                   $$ = chainon ($1, $3);
1105                 }
1106 |       formal_parameter_list C_TK error
1107                 { yyerror ("Missing formal parameter term"); RECOVER; }
1108 ;
1109
1110 formal_parameter:
1111         type variable_declarator_id
1112                 {
1113                   $$ = build_tree_list ($2, $1);
1114                 }
1115 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1116                 { 
1117                   $$ = build_tree_list ($3, $2);
1118                   ARG_FINAL_P ($$) = 1;
1119                 }
1120 |       type error
1121                 {
1122                   yyerror ("Missing identifier"); RECOVER;
1123                   $$ = NULL_TREE;
1124                 }
1125 |       final type error
1126                 {
1127                   yyerror ("Missing identifier"); RECOVER;
1128                   $$ = NULL_TREE;
1129                 }
1130 ;
1131
1132 final:
1133         modifiers
1134                 {
1135                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1136                                    $1, ACC_FINAL);
1137                   if ($1 != ACC_FINAL)
1138                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1139                 }
1140 ;
1141
1142 throws:
1143                 { $$ = NULL_TREE; }
1144 |       THROWS_TK class_type_list
1145                 { $$ = $2; }
1146 |       THROWS_TK error
1147                 {yyerror ("Missing class type term"); RECOVER;}
1148 ;
1149
1150 class_type_list:
1151         class_type
1152                 { $$ = build_tree_list ($1, $1); }
1153 |       class_type_list C_TK class_type
1154                 { $$ = tree_cons ($3, $3, $1); }
1155 |       class_type_list C_TK error
1156                 {yyerror ("Missing class type term"); RECOVER;}
1157 ;
1158
1159 method_body:
1160         block
1161 |       SC_TK { $$ = NULL_TREE; }
1162 ;
1163
1164 /* 19.8.4 Productions from 8.5: Static Initializers  */
1165 static_initializer:
1166         static block
1167                 {
1168                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1169                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1170                   current_static_block = NULL_TREE;
1171                 }
1172 ;
1173
1174 static:                         /* Test lval.sub_token here */
1175         modifiers
1176                 {
1177                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1178                   /* Can't have a static initializer in an innerclass */
1179                   if ($1 | ACC_STATIC &&
1180                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1181                     parse_error_context 
1182                       (MODIFIER_WFL (STATIC_TK),
1183                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1184                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1185                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1186                 }
1187 ;
1188
1189 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1190 constructor_declaration:
1191         constructor_header
1192                 {
1193                   current_function_decl = $1;
1194                   source_start_java_method (current_function_decl);
1195                 }
1196         constructor_body
1197                 { finish_method_declaration ($3); }
1198 ;
1199
1200 constructor_header:
1201         constructor_declarator throws
1202                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1203 |       modifiers constructor_declarator throws
1204                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1205 ;
1206
1207 constructor_declarator:
1208         simple_name OP_TK CP_TK
1209                 { 
1210                   ctxp->formal_parameter_number = 0;  
1211                   $$ = method_declarator ($1, NULL_TREE);
1212                 }
1213 |       simple_name OP_TK formal_parameter_list CP_TK
1214                 { $$ = method_declarator ($1, $3); }
1215 ;
1216
1217 constructor_body:
1218         /* Unlike regular method, we always need a complete (empty)
1219            body so we can safely perform all the required code
1220            addition (super invocation and field initialization) */
1221         block_begin constructor_block_end
1222                 { 
1223                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1224                   $$ = $2;
1225                 }
1226 |       block_begin explicit_constructor_invocation constructor_block_end
1227                 { $$ = $3; }
1228 |       block_begin block_statements constructor_block_end
1229                 { $$ = $3; }
1230 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1231                 { $$ = $4; }
1232 ;
1233
1234 constructor_block_end:
1235         block_end
1236 ;
1237
1238 /* Error recovery for that rule moved down expression_statement: rule.  */
1239 explicit_constructor_invocation:
1240         this_or_super OP_TK CP_TK SC_TK
1241                 { 
1242                   $$ = build_method_invocation ($1, NULL_TREE); 
1243                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1244                   $$ = java_method_add_stmt (current_function_decl, $$);
1245                 }
1246 |       this_or_super OP_TK argument_list CP_TK SC_TK
1247                 { 
1248                   $$ = build_method_invocation ($1, $3); 
1249                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1250                   $$ = java_method_add_stmt (current_function_decl, $$);
1251                 }
1252         /* Added, JDK1.1 inner classes. Modified because the rule
1253            'primary' couldn't work.  */
1254 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1255                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1256 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1257                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1258 ;
1259
1260 this_or_super:                  /* Added, simplifies error diagnostics */
1261         THIS_TK
1262                 {
1263                   tree wfl = build_wfl_node (this_identifier_node);
1264                   EXPR_WFL_LINECOL (wfl) = $1.location;
1265                   $$ = wfl;
1266                 }
1267 |       SUPER_TK
1268                 {
1269                   tree wfl = build_wfl_node (super_identifier_node);
1270                   EXPR_WFL_LINECOL (wfl) = $1.location;
1271                   $$ = wfl;
1272                 }
1273 ;
1274
1275 /* 19.9 Productions from 9: Interfaces  */
1276 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1277 interface_declaration:
1278         INTERFACE_TK identifier
1279                 { create_interface (0, $2, NULL_TREE); }
1280         interface_body
1281 |       modifiers INTERFACE_TK identifier
1282                 { create_interface ($1, $3, NULL_TREE); }
1283         interface_body
1284 |       INTERFACE_TK identifier extends_interfaces
1285                 { create_interface (0, $2, $3); }
1286         interface_body
1287 |       modifiers INTERFACE_TK identifier extends_interfaces
1288                 { create_interface ($1, $3, $4); }
1289         interface_body
1290 |       INTERFACE_TK identifier error
1291                 {yyerror ("'{' expected"); RECOVER;}
1292 |       modifiers INTERFACE_TK identifier error
1293                 {yyerror ("'{' expected"); RECOVER;}
1294 ;
1295
1296 extends_interfaces:
1297         EXTENDS_TK interface_type
1298                 { 
1299                   ctxp->interface_number = 1;
1300                   $$ = build_tree_list ($2, NULL_TREE);
1301                 }
1302 |       extends_interfaces C_TK interface_type
1303                 { 
1304                   ctxp->interface_number++;
1305                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1306                 }
1307 |       EXTENDS_TK error
1308                 {yyerror ("Invalid interface type"); RECOVER;}
1309 |       extends_interfaces C_TK error
1310                 {yyerror ("Missing term"); RECOVER;}
1311 ;
1312
1313 interface_body:
1314         OCB_TK CCB_TK
1315                 { $$ = NULL_TREE; }
1316 |       OCB_TK interface_member_declarations CCB_TK
1317                 { $$ = NULL_TREE; }
1318 ;
1319
1320 interface_member_declarations:
1321         interface_member_declaration
1322 |       interface_member_declarations interface_member_declaration
1323 ;
1324
1325 interface_member_declaration:
1326         constant_declaration
1327 |       abstract_method_declaration
1328 |       class_declaration       /* Added, JDK1.1 inner classes */
1329                 { end_class_declaration (1); }
1330 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1331                 { end_class_declaration (1); }
1332 ;
1333
1334 constant_declaration:
1335         field_declaration
1336 ;
1337
1338 abstract_method_declaration:
1339         method_header SC_TK
1340                 { 
1341                   check_abstract_method_header ($1);
1342                   current_function_decl = NULL_TREE; /* FIXME ? */
1343                 }
1344 |       method_header error
1345                 {yyerror ("';' expected"); RECOVER;}
1346 ;
1347
1348 /* 19.10 Productions from 10: Arrays  */
1349 array_initializer:
1350         OCB_TK CCB_TK
1351                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1352 |       OCB_TK C_TK CCB_TK
1353                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1354 |       OCB_TK variable_initializers CCB_TK
1355                 { $$ = build_new_array_init ($1.location, $2); }
1356 |       OCB_TK variable_initializers C_TK CCB_TK
1357                 { $$ = build_new_array_init ($1.location, $2); }
1358 ;
1359
1360 variable_initializers:
1361         variable_initializer
1362                 { 
1363                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1364                                   $1, NULL_TREE);
1365                 }
1366 |       variable_initializers C_TK variable_initializer
1367                 {
1368                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1369                 }
1370 |       variable_initializers C_TK error
1371                 {yyerror ("Missing term"); RECOVER;}
1372 ;
1373
1374 /* 19.11 Production from 14: Blocks and Statements  */
1375 block:
1376         OCB_TK CCB_TK
1377                 { 
1378                   /* Store the location of the `}' when doing xrefs */
1379                   if (current_function_decl && flag_emit_xref)
1380                     DECL_END_SOURCE_LINE (current_function_decl) = 
1381                       EXPR_WFL_ADD_COL ($2.location, 1);
1382                   $$ = empty_stmt_node; 
1383                 }
1384 |       block_begin block_statements block_end
1385                 { $$ = $3; }
1386 ;
1387
1388 block_begin:
1389         OCB_TK
1390                 { enter_block (); }
1391 ;
1392
1393 block_end:
1394         CCB_TK
1395                 { 
1396                   maybe_absorb_scoping_blocks ();
1397                   /* Store the location of the `}' when doing xrefs */
1398                   if (current_function_decl && flag_emit_xref)
1399                     DECL_END_SOURCE_LINE (current_function_decl) = 
1400                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1401                   $$ = exit_block ();
1402                   if (!BLOCK_SUBBLOCKS ($$))
1403                     BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
1404                 }
1405 ;
1406
1407 block_statements:
1408         block_statement
1409 |       block_statements block_statement
1410 ;
1411
1412 block_statement:
1413         local_variable_declaration_statement
1414 |       statement
1415                 { java_method_add_stmt (current_function_decl, $1); }
1416 |       class_declaration       /* Added, JDK1.1 local classes */
1417                 { 
1418                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1419                   end_class_declaration (1);
1420                 }
1421 ;
1422
1423 local_variable_declaration_statement:
1424         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1425 ;
1426
1427 local_variable_declaration:
1428         type variable_declarators
1429                 { declare_local_variables (0, $1, $2); }
1430 |       final type variable_declarators /* Added, JDK1.1 final locals */
1431                 { declare_local_variables ($1, $2, $3); }
1432 ;
1433
1434 statement:
1435         statement_without_trailing_substatement
1436 |       labeled_statement
1437 |       if_then_statement
1438 |       if_then_else_statement
1439 |       while_statement
1440 |       for_statement
1441                 { $$ = exit_block (); }
1442 ;
1443
1444 statement_nsi:
1445         statement_without_trailing_substatement
1446 |       labeled_statement_nsi
1447 |       if_then_else_statement_nsi
1448 |       while_statement_nsi
1449 |       for_statement_nsi
1450                 { $$ = exit_block (); }
1451 ;
1452
1453 statement_without_trailing_substatement:
1454         block
1455 |       empty_statement
1456 |       expression_statement
1457 |       switch_statement
1458 |       do_statement
1459 |       break_statement
1460 |       continue_statement
1461 |       return_statement
1462 |       synchronized_statement
1463 |       throw_statement
1464 |       try_statement
1465 ;
1466
1467 empty_statement:
1468         SC_TK
1469                 { 
1470                   if (flag_extraneous_semicolon 
1471                       && ! current_static_block 
1472                       && (! current_function_decl || 
1473                           /* Verify we're not in a inner class declaration */
1474                           (GET_CPC () != TYPE_NAME
1475                            (DECL_CONTEXT (current_function_decl)))))
1476                            
1477                     {
1478                       EXPR_WFL_SET_LINECOL (wfl_operator, lineno, -1);
1479                       parse_warning_context (wfl_operator, "An empty declaration is a deprecated feature that should not be used");
1480                     }
1481                   $$ = empty_stmt_node;
1482                 }
1483 ;
1484
1485 label_decl:
1486         identifier REL_CL_TK
1487                 {
1488                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1489                                             EXPR_WFL_NODE ($1));
1490                   pushlevel (2);
1491                   push_labeled_block ($$);
1492                   PUSH_LABELED_BLOCK ($$);
1493                 }
1494 ;
1495
1496 labeled_statement:
1497         label_decl statement
1498                 { $$ = finish_labeled_statement ($1, $2); }
1499 |       identifier error
1500                 {yyerror ("':' expected"); RECOVER;}
1501 ;
1502
1503 labeled_statement_nsi:
1504         label_decl statement_nsi
1505                 { $$ = finish_labeled_statement ($1, $2); }
1506 ;
1507
1508 /* We concentrate here a bunch of error handling rules that we couldn't write
1509    earlier, because expression_statement catches a missing ';'.  */
1510 expression_statement:
1511         statement_expression SC_TK
1512                 {
1513                   /* We have a statement. Generate a WFL around it so
1514                      we can debug it */
1515                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1516                   /* We know we have a statement, so set the debug
1517                      info to be eventually generate here. */
1518                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1519                 }
1520 |       error SC_TK 
1521                 {
1522                   YYNOT_TWICE yyerror ("Invalid expression statement");
1523                   DRECOVER (expr_stmt);
1524                 }
1525 |       error OCB_TK
1526                 {
1527                   YYNOT_TWICE yyerror ("Invalid expression statement");
1528                   DRECOVER (expr_stmt);
1529                 }
1530 |       error CCB_TK
1531                 {
1532                   YYNOT_TWICE yyerror ("Invalid expression statement");
1533                   DRECOVER (expr_stmt);
1534                 }
1535 |       this_or_super OP_TK error
1536                 {yyerror ("')' expected"); RECOVER;}
1537 |       this_or_super OP_TK CP_TK error
1538                 {
1539                   parse_ctor_invocation_error ();
1540                   RECOVER;
1541                 }
1542 |       this_or_super OP_TK argument_list error
1543                 {yyerror ("')' expected"); RECOVER;}
1544 |       this_or_super OP_TK argument_list CP_TK error
1545                 {
1546                   parse_ctor_invocation_error ();
1547                   RECOVER;
1548                 }
1549 |       name DOT_TK SUPER_TK error
1550                 {yyerror ("'(' expected"); RECOVER;}
1551 |       name DOT_TK SUPER_TK OP_TK error
1552                 {yyerror ("')' expected"); RECOVER;}
1553 |       name DOT_TK SUPER_TK OP_TK argument_list error
1554                 {yyerror ("')' expected"); RECOVER;}
1555 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1556                 {yyerror ("';' expected"); RECOVER;}
1557 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1558                 {yyerror ("';' expected"); RECOVER;}
1559 ;
1560
1561 statement_expression: 
1562         assignment
1563 |       pre_increment_expression
1564 |       pre_decrement_expression
1565 |       post_increment_expression
1566 |       post_decrement_expression
1567 |       method_invocation
1568 |       class_instance_creation_expression
1569 ;
1570
1571 if_then_statement:
1572         IF_TK OP_TK expression CP_TK statement
1573                 { 
1574                   $$ = build_if_else_statement ($2.location, $3, 
1575                                                 $5, NULL_TREE);
1576                 }
1577 |       IF_TK error
1578                 {yyerror ("'(' expected"); RECOVER;}
1579 |       IF_TK OP_TK error
1580                 {yyerror ("Missing term"); RECOVER;}
1581 |       IF_TK OP_TK expression error
1582                 {yyerror ("')' expected"); RECOVER;}
1583 ;
1584
1585 if_then_else_statement:
1586         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1587                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1588 ;
1589
1590 if_then_else_statement_nsi:
1591         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1592                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1593 ;
1594
1595 switch_statement:
1596         switch_expression
1597                 {
1598                   enter_block ();
1599                 }
1600         switch_block
1601                 { 
1602                   /* Make into "proper list" of COMPOUND_EXPRs.
1603                      I.e. make the last statement also have its own
1604                      COMPOUND_EXPR. */
1605                   maybe_absorb_scoping_blocks ();
1606                   TREE_OPERAND ($1, 1) = exit_block ();
1607                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1608                 }
1609 ;
1610
1611 switch_expression:
1612         SWITCH_TK OP_TK expression CP_TK
1613                 { 
1614                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1615                   EXPR_WFL_LINECOL ($$) = $2.location;
1616                 }
1617 |       SWITCH_TK error
1618                 {yyerror ("'(' expected"); RECOVER;}
1619 |       SWITCH_TK OP_TK error
1620                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1621 |       SWITCH_TK OP_TK expression CP_TK error
1622                 {yyerror ("'{' expected"); RECOVER;}
1623 ;
1624
1625 /* Default assignment is there to avoid type node on switch_block
1626    node. */
1627
1628 switch_block:
1629         OCB_TK CCB_TK
1630                 { $$ = NULL_TREE; }
1631 |       OCB_TK switch_labels CCB_TK
1632                 { $$ = NULL_TREE; }
1633 |       OCB_TK switch_block_statement_groups CCB_TK
1634                 { $$ = NULL_TREE; }
1635 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1636                 { $$ = NULL_TREE; }
1637 ;
1638
1639 switch_block_statement_groups: 
1640         switch_block_statement_group
1641 |       switch_block_statement_groups switch_block_statement_group
1642 ;
1643
1644 switch_block_statement_group:
1645         switch_labels block_statements
1646 ;
1647
1648 switch_labels:
1649         switch_label
1650 |       switch_labels switch_label
1651 ;
1652
1653 switch_label:
1654         CASE_TK constant_expression REL_CL_TK
1655                 { 
1656                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1657                   EXPR_WFL_LINECOL (lab) = $1.location;
1658                   java_method_add_stmt (current_function_decl, lab);
1659                 }
1660 |       DEFAULT_TK REL_CL_TK
1661                 { 
1662                   tree lab = build (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1663                   EXPR_WFL_LINECOL (lab) = $1.location;
1664                   java_method_add_stmt (current_function_decl, lab);
1665                 }
1666 |       CASE_TK error
1667                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1668 |       CASE_TK constant_expression error
1669                 {yyerror ("':' expected"); RECOVER;}
1670 |       DEFAULT_TK error
1671                 {yyerror ("':' expected"); RECOVER;}
1672 ;
1673
1674 while_expression:
1675         WHILE_TK OP_TK expression CP_TK
1676                 { 
1677                   tree body = build_loop_body ($2.location, $3, 0);
1678                   $$ = build_new_loop (body);
1679                 }
1680 ;
1681
1682 while_statement:
1683         while_expression statement
1684                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1685 |       WHILE_TK error
1686                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1687 |       WHILE_TK OP_TK error
1688                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1689 |       WHILE_TK OP_TK expression error
1690                 {yyerror ("')' expected"); RECOVER;}
1691 ;
1692
1693 while_statement_nsi:
1694         while_expression statement_nsi
1695                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1696 ;
1697
1698 do_statement_begin:
1699         DO_TK
1700                 { 
1701                   tree body = build_loop_body (0, NULL_TREE, 1);
1702                   $$ = build_new_loop (body);
1703                 }
1704         /* Need error handing here. FIXME */
1705 ;
1706
1707 do_statement: 
1708         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1709                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1710 ;
1711
1712 for_statement:
1713         for_begin SC_TK expression SC_TK for_update CP_TK statement
1714                 {
1715                   if (TREE_CODE_CLASS (TREE_CODE ($3)) == 'c')
1716                     $3 = build_wfl_node ($3);
1717                   $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);
1718                 }
1719 |       for_begin SC_TK SC_TK for_update CP_TK statement
1720                 { 
1721                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1722                   /* We have not condition, so we get rid of the EXIT_EXPR */
1723                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1724                     empty_stmt_node;
1725                 }
1726 |       for_begin SC_TK error
1727                 {yyerror ("Invalid control expression"); RECOVER;}
1728 |       for_begin SC_TK expression SC_TK error
1729                 {yyerror ("Invalid update expression"); RECOVER;}
1730 |       for_begin SC_TK SC_TK error
1731                 {yyerror ("Invalid update expression"); RECOVER;}
1732 ;
1733
1734 for_statement_nsi:
1735         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1736                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1737 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1738                 { 
1739                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1740                   /* We have not condition, so we get rid of the EXIT_EXPR */
1741                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1742                     empty_stmt_node;
1743                 }
1744 ;
1745
1746 for_header:
1747         FOR_TK OP_TK
1748                 { 
1749                   /* This scope defined for local variable that may be
1750                      defined within the scope of the for loop */
1751                   enter_block (); 
1752                 }
1753 |       FOR_TK error
1754                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1755 |       FOR_TK OP_TK error
1756                 {yyerror ("Invalid init statement"); RECOVER;}
1757 ;
1758
1759 for_begin:
1760         for_header for_init
1761                 { 
1762                   /* We now declare the loop body. The loop is
1763                      declared as a for loop. */
1764                   tree body = build_loop_body (0, NULL_TREE, 0);
1765                   $$ =  build_new_loop (body);
1766                   FOR_LOOP_P ($$) = 1;
1767                   /* The loop is added to the current block the for
1768                      statement is defined within */
1769                   java_method_add_stmt (current_function_decl, $$);
1770                 }
1771 ;
1772 for_init:                       /* Can be empty */
1773                 { $$ = empty_stmt_node; }
1774 |       statement_expression_list
1775                 { 
1776                   /* Init statement recorded within the previously
1777                      defined block scope */
1778                   $$ = java_method_add_stmt (current_function_decl, $1);
1779                 }
1780 |       local_variable_declaration
1781                 { 
1782                   /* Local variable are recorded within the previously
1783                      defined block scope */
1784                   $$ = NULL_TREE;
1785                 }
1786 |       statement_expression_list error
1787                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1788 ;
1789
1790 for_update:                     /* Can be empty */
1791                 {$$ = empty_stmt_node;}
1792 |       statement_expression_list
1793                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1794 ;
1795
1796 statement_expression_list:
1797         statement_expression
1798                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1799 |       statement_expression_list C_TK statement_expression
1800                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1801 |       statement_expression_list C_TK error
1802                 {yyerror ("Missing term"); RECOVER;}
1803 ;
1804
1805 break_statement:
1806         BREAK_TK SC_TK
1807                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1808 |       BREAK_TK identifier SC_TK
1809                 { $$ = build_bc_statement ($1.location, 1, $2); }
1810 |       BREAK_TK error
1811                 {yyerror ("Missing term"); RECOVER;}
1812 |       BREAK_TK identifier error
1813                 {yyerror ("';' expected"); RECOVER;}
1814 ;
1815
1816 continue_statement:
1817         CONTINUE_TK SC_TK
1818                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1819 |       CONTINUE_TK identifier SC_TK
1820                 { $$ = build_bc_statement ($1.location, 0, $2); }
1821 |       CONTINUE_TK error
1822                 {yyerror ("Missing term"); RECOVER;}
1823 |       CONTINUE_TK identifier error
1824                 {yyerror ("';' expected"); RECOVER;}
1825 ;
1826
1827 return_statement:
1828         RETURN_TK SC_TK
1829                 { $$ = build_return ($1.location, NULL_TREE); }
1830 |       RETURN_TK expression SC_TK
1831                 { $$ = build_return ($1.location, $2); }
1832 |       RETURN_TK error
1833                 {yyerror ("Missing term"); RECOVER;}
1834 |       RETURN_TK expression error
1835                 {yyerror ("';' expected"); RECOVER;}
1836 ;
1837
1838 throw_statement:
1839         THROW_TK expression SC_TK
1840                 { 
1841                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1842                   EXPR_WFL_LINECOL ($$) = $1.location;
1843                 }
1844 |       THROW_TK error
1845                 {yyerror ("Missing term"); RECOVER;}
1846 |       THROW_TK expression error
1847                 {yyerror ("';' expected"); RECOVER;}
1848 ;
1849
1850 synchronized_statement:
1851         synchronized OP_TK expression CP_TK block
1852                 { 
1853                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1854                   EXPR_WFL_LINECOL ($$) = 
1855                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1856                 }
1857 |       synchronized OP_TK expression CP_TK error
1858                 {yyerror ("'{' expected"); RECOVER;}
1859 |       synchronized error
1860                 {yyerror ("'(' expected"); RECOVER;}
1861 |       synchronized OP_TK error CP_TK
1862                 {yyerror ("Missing term"); RECOVER;}
1863 |       synchronized OP_TK error
1864                 {yyerror ("Missing term"); RECOVER;}
1865 ;
1866
1867 synchronized:
1868         modifiers
1869                 {
1870                   check_modifiers (
1871              "Illegal modifier `%s'. Only `synchronized' was expected here",
1872                                    $1, ACC_SYNCHRONIZED);
1873                   if ($1 != ACC_SYNCHRONIZED)
1874                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1875                       build_wfl_node (NULL_TREE);
1876                 }
1877 ;
1878
1879 try_statement:
1880         TRY_TK block catches
1881                 { $$ = build_try_statement ($1.location, $2, $3); }
1882 |       TRY_TK block finally
1883                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1884 |       TRY_TK block catches finally
1885                 { $$ = build_try_finally_statement 
1886                     ($1.location, build_try_statement ($1.location,
1887                                                        $2, $3), $4);
1888                 }
1889 |       TRY_TK error
1890                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1891 ;
1892
1893 catches:
1894         catch_clause
1895 |       catches catch_clause
1896                 { 
1897                   TREE_CHAIN ($2) = $1;
1898                   $$ = $2;
1899                 }
1900 ;
1901
1902 catch_clause:
1903         catch_clause_parameter block
1904                 { 
1905                   java_method_add_stmt (current_function_decl, $2);
1906                   exit_block ();
1907                   $$ = $1;
1908                 }
1909
1910 catch_clause_parameter:
1911         CATCH_TK OP_TK formal_parameter CP_TK
1912                 { 
1913                   /* We add a block to define a scope for
1914                      formal_parameter (CCBP). The formal parameter is
1915                      declared initialized by the appropriate function
1916                      call */
1917                   tree ccpb = enter_block ();
1918                   tree init = build_assignment
1919                     (ASSIGN_TK, $2.location, TREE_PURPOSE ($3), 
1920                      build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
1921                   declare_local_variables (0, TREE_VALUE ($3),
1922                                            build_tree_list (TREE_PURPOSE ($3),
1923                                                             init));
1924                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1925                   EXPR_WFL_LINECOL ($$) = $1.location;
1926                 }
1927 |       CATCH_TK error
1928                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1929 |       CATCH_TK OP_TK error 
1930                 {
1931                   yyerror ("Missing term or ')' expected"); 
1932                   RECOVER; $$ = NULL_TREE;
1933                 }
1934 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1935                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1936 ;
1937
1938 finally:
1939         FINALLY_TK block
1940                 { $$ = $2; }
1941 |       FINALLY_TK error
1942                 {yyerror ("'{' expected"); RECOVER; }
1943 ;
1944
1945 /* 19.12 Production from 15: Expressions  */
1946 primary:
1947         primary_no_new_array
1948 |       array_creation_expression
1949 ;
1950
1951 primary_no_new_array:
1952         literal
1953 |       THIS_TK
1954                 { $$ = build_this ($1.location); }
1955 |       OP_TK expression CP_TK
1956                 {$$ = $2;}
1957 |       class_instance_creation_expression
1958 |       field_access
1959 |       method_invocation
1960 |       array_access
1961 |       type_literals
1962         /* Added, JDK1.1 inner classes. Documentation is wrong
1963            refering to a 'ClassName' (class_name) rule that doesn't
1964            exist. Used name: instead.  */
1965 |       name DOT_TK THIS_TK
1966                 { 
1967                   tree wfl = build_wfl_node (this_identifier_node);
1968                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1969                 }
1970 |       OP_TK expression error 
1971                 {yyerror ("')' expected"); RECOVER;}
1972 |       name DOT_TK error
1973                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1974 |       primitive_type DOT_TK error
1975                 {yyerror ("'class' expected" ); RECOVER;}
1976 |       VOID_TK DOT_TK error
1977                 {yyerror ("'class' expected" ); RECOVER;}
1978 ;
1979
1980 type_literals:
1981         name DOT_TK CLASS_TK
1982                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1983 |       array_type DOT_TK CLASS_TK
1984                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1985 |       primitive_type DOT_TK CLASS_TK
1986                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1987 |       VOID_TK DOT_TK CLASS_TK
1988                 { 
1989                    $$ = build_incomplete_class_ref ($2.location,
1990                                                    void_type_node);
1991                 }
1992 ;
1993
1994 class_instance_creation_expression:
1995         NEW_TK class_type OP_TK argument_list CP_TK
1996                 { $$ = build_new_invocation ($2, $4); }
1997 |       NEW_TK class_type OP_TK CP_TK
1998                 { $$ = build_new_invocation ($2, NULL_TREE); }
1999 |       anonymous_class_creation
2000         /* Added, JDK1.1 inner classes, modified to use name or
2001            primary instead of primary solely which couldn't work in
2002            all situations.  */
2003 |       something_dot_new identifier OP_TK CP_TK
2004                 { 
2005                   tree ctor = build_new_invocation ($2, NULL_TREE);
2006                   $$ = make_qualified_primary ($1, ctor, 
2007                                                EXPR_WFL_LINECOL ($1));
2008                 }
2009 |       something_dot_new identifier OP_TK CP_TK class_body
2010 |       something_dot_new identifier OP_TK argument_list CP_TK
2011                 { 
2012                   tree ctor = build_new_invocation ($2, $4);
2013                   $$ = make_qualified_primary ($1, ctor, 
2014                                                EXPR_WFL_LINECOL ($1));
2015                 }
2016 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
2017 |       NEW_TK error SC_TK 
2018                 {yyerror ("'(' expected"); DRECOVER(new_1);}
2019 |       NEW_TK class_type error
2020                 {yyerror ("'(' expected"); RECOVER;}
2021 |       NEW_TK class_type OP_TK error
2022                 {yyerror ("')' or term expected"); RECOVER;}
2023 |       NEW_TK class_type OP_TK argument_list error
2024                 {yyerror ("')' expected"); RECOVER;}
2025 |       something_dot_new error
2026                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
2027 |       something_dot_new identifier error
2028                 {yyerror ("'(' expected"); RECOVER;}
2029 ;
2030
2031 /* Created after JDK1.1 rules originally added to
2032    class_instance_creation_expression, but modified to use
2033    'class_type' instead of 'TypeName' (type_name) which is mentionned
2034    in the documentation but doesn't exist. */
2035
2036 anonymous_class_creation:
2037         NEW_TK class_type OP_TK argument_list CP_TK 
2038                 { create_anonymous_class ($1.location, $2); }
2039         class_body
2040                 { 
2041                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2042                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2043
2044                   end_class_declaration (1);
2045
2046                   /* Now we can craft the new expression */
2047                   $$ = build_new_invocation (id, $4);
2048
2049                   /* Note that we can't possibly be here if
2050                      `class_type' is an interface (in which case the
2051                      anonymous class extends Object and implements
2052                      `class_type', hence its constructor can't have
2053                      arguments.) */
2054
2055                   /* Otherwise, the innerclass must feature a
2056                      constructor matching `argument_list'. Anonymous
2057                      classes are a bit special: it's impossible to
2058                      define constructor for them, hence constructors
2059                      must be generated following the hints provided by
2060                      the `new' expression. Whether a super constructor
2061                      of that nature exists or not is to be verified
2062                      later on in verify_constructor_super. 
2063
2064                      It's during the expansion of a `new' statement
2065                      refering to an anonymous class that a ctor will
2066                      be generated for the anonymous class, with the
2067                      right arguments. */
2068
2069                 }
2070 |       NEW_TK class_type OP_TK CP_TK 
2071                 { create_anonymous_class ($1.location, $2); }
2072         class_body         
2073                 { 
2074                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2075                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2076
2077                   end_class_declaration (1);
2078
2079                   /* Now we can craft the new expression. The
2080                      statement doesn't need to be remember so that a
2081                      constructor can be generated, since its signature
2082                      is already known. */
2083                   $$ = build_new_invocation (id, NULL_TREE);
2084                 }
2085 ;
2086
2087 something_dot_new:              /* Added, not part of the specs. */
2088         name DOT_TK NEW_TK
2089                 { $$ = $1; }
2090 |       primary DOT_TK NEW_TK
2091                 { $$ = $1; }
2092 ;
2093
2094 argument_list:
2095         expression
2096                 { 
2097                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2098                   ctxp->formal_parameter_number = 1; 
2099                 }
2100 |       argument_list C_TK expression
2101                 {
2102                   ctxp->formal_parameter_number += 1;
2103                   $$ = tree_cons (NULL_TREE, $3, $1);
2104                 }
2105 |       argument_list C_TK error
2106                 {yyerror ("Missing term"); RECOVER;}
2107 ;
2108
2109 array_creation_expression:
2110         NEW_TK primitive_type dim_exprs
2111                 { $$ = build_newarray_node ($2, $3, 0); }
2112 |       NEW_TK class_or_interface_type dim_exprs
2113                 { $$ = build_newarray_node ($2, $3, 0); }
2114 |       NEW_TK primitive_type dim_exprs dims
2115                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2116 |       NEW_TK class_or_interface_type dim_exprs dims
2117                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2118         /* Added, JDK1.1 anonymous array. Initial documentation rule
2119            modified */
2120 |       NEW_TK class_or_interface_type dims array_initializer
2121                 {
2122                   char *sig;
2123                   int osb = pop_current_osb (ctxp);
2124                   while (osb--)
2125                     obstack_grow (&temporary_obstack, "[]", 2);
2126                   obstack_1grow (&temporary_obstack, '\0');
2127                   sig = obstack_finish (&temporary_obstack);
2128                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2129                               $2, get_identifier (sig), $4);
2130                 }
2131 |       NEW_TK primitive_type dims array_initializer
2132                 { 
2133                   int osb = pop_current_osb (ctxp);
2134                   tree type = $2;
2135                   while (osb--)
2136                     type = build_java_array_type (type, -1);
2137                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2138                               build_pointer_type (type), NULL_TREE, $4);
2139                 }
2140 |       NEW_TK error CSB_TK
2141                 {yyerror ("'[' expected"); DRECOVER ("]");}
2142 |       NEW_TK error OSB_TK
2143                 {yyerror ("']' expected"); RECOVER;}
2144 ;
2145
2146 dim_exprs:
2147         dim_expr
2148                 { $$ = build_tree_list (NULL_TREE, $1); }
2149 |       dim_exprs dim_expr
2150                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2151 ;
2152
2153 dim_expr:
2154         OSB_TK expression CSB_TK
2155                 { 
2156                   if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
2157                     {
2158                       $2 = build_wfl_node ($2);
2159                       TREE_TYPE ($2) = NULL_TREE;
2160                     }
2161                   EXPR_WFL_LINECOL ($2) = $1.location;
2162                   $$ = $2;
2163                 }
2164 |       OSB_TK expression error
2165                 {yyerror ("']' expected"); RECOVER;}
2166 |       OSB_TK error
2167                 {
2168                   yyerror ("Missing term");
2169                   yyerror ("']' expected");
2170                   RECOVER;
2171                 }
2172 ;
2173
2174 dims:                           
2175         OSB_TK CSB_TK
2176                 { 
2177                   int allocate = 0;
2178                   /* If not initialized, allocate memory for the osb
2179                      numbers stack */
2180                   if (!ctxp->osb_limit)
2181                     {
2182                       allocate = ctxp->osb_limit = 32;
2183                       ctxp->osb_depth = -1;
2184                     }
2185                   /* If capacity overflown, reallocate a bigger chunk */
2186                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2187                     allocate = ctxp->osb_limit << 1;
2188                   
2189                   if (allocate)
2190                     {
2191                       allocate *= sizeof (int);
2192                       if (ctxp->osb_number)
2193                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2194                                                             allocate);
2195                       else
2196                         ctxp->osb_number = (int *)xmalloc (allocate);
2197                     }
2198                   ctxp->osb_depth++;
2199                   CURRENT_OSB (ctxp) = 1;
2200                 }
2201 |       dims OSB_TK CSB_TK
2202                 { CURRENT_OSB (ctxp)++; }
2203 |       dims OSB_TK error
2204                 { yyerror ("']' expected"); RECOVER;}
2205 ;
2206
2207 field_access:
2208         primary DOT_TK identifier
2209                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2210                 /*  FIXME - REWRITE TO: 
2211                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2212 |       SUPER_TK DOT_TK identifier
2213                 {
2214                   tree super_wfl = build_wfl_node (super_identifier_node);
2215                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2216                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2217                 }
2218 |       SUPER_TK error
2219                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2220 ;
2221
2222 method_invocation:
2223         name OP_TK CP_TK
2224                 { $$ = build_method_invocation ($1, NULL_TREE); }
2225 |       name OP_TK argument_list CP_TK
2226                 { $$ = build_method_invocation ($1, $3); }
2227 |       primary DOT_TK identifier OP_TK CP_TK
2228                 { 
2229                   if (TREE_CODE ($1) == THIS_EXPR)
2230                     $$ = build_this_super_qualified_invocation 
2231                       (1, $3, NULL_TREE, 0, $2.location);
2232                   else
2233                     {
2234                       tree invok = build_method_invocation ($3, NULL_TREE);
2235                       $$ = make_qualified_primary ($1, invok, $2.location);
2236                     }
2237                 }
2238 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2239                 { 
2240                   if (TREE_CODE ($1) == THIS_EXPR)
2241                     $$ = build_this_super_qualified_invocation 
2242                       (1, $3, $5, 0, $2.location);
2243                   else
2244                     {
2245                       tree invok = build_method_invocation ($3, $5);
2246                       $$ = make_qualified_primary ($1, invok, $2.location);
2247                     }
2248                 }
2249 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2250                 { 
2251                   $$ = build_this_super_qualified_invocation 
2252                     (0, $3, NULL_TREE, $1.location, $2.location);
2253                 }
2254 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2255                 {
2256                   $$ = build_this_super_qualified_invocation 
2257                     (0, $3, $5, $1.location, $2.location);
2258                 }
2259         /* Screws up thing. I let it here until I'm convinced it can
2260            be removed. FIXME
2261 |       primary DOT_TK error
2262                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2263 |       SUPER_TK DOT_TK error CP_TK
2264                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2265 |       SUPER_TK DOT_TK error DOT_TK
2266                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2267 ;
2268
2269 array_access:
2270         name OSB_TK expression CSB_TK
2271                 { $$ = build_array_ref ($2.location, $1, $3); }
2272 |       primary_no_new_array OSB_TK expression CSB_TK
2273                 { $$ = build_array_ref ($2.location, $1, $3); }
2274 |       name OSB_TK error
2275                 {
2276                   yyerror ("Missing term and ']' expected");
2277                   DRECOVER(array_access);
2278                 }
2279 |       name OSB_TK expression error
2280                 {
2281                   yyerror ("']' expected");
2282                   DRECOVER(array_access);
2283                 }
2284 |       primary_no_new_array OSB_TK error
2285                 {
2286                   yyerror ("Missing term and ']' expected");
2287                   DRECOVER(array_access);
2288                 }
2289 |       primary_no_new_array OSB_TK expression error
2290                 {
2291                   yyerror ("']' expected");
2292                   DRECOVER(array_access);
2293                 }
2294 ;
2295
2296 postfix_expression:
2297         primary
2298 |       name
2299 |       post_increment_expression
2300 |       post_decrement_expression
2301 ;
2302
2303 post_increment_expression:
2304         postfix_expression INCR_TK
2305                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2306 ;
2307
2308 post_decrement_expression:
2309         postfix_expression DECR_TK
2310                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2311 ;
2312
2313 trap_overflow_corner_case:
2314         pre_increment_expression
2315 |       pre_decrement_expression
2316 |       PLUS_TK unary_expression
2317                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2318 |       unary_expression_not_plus_minus
2319 |       PLUS_TK error
2320                 {yyerror ("Missing term"); RECOVER}
2321 ;
2322
2323 unary_expression:
2324         trap_overflow_corner_case
2325                 {
2326                   error_if_numeric_overflow ($1);
2327                   $$ = $1;
2328                 }
2329 |       MINUS_TK trap_overflow_corner_case
2330                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2331 |       MINUS_TK error
2332                 {yyerror ("Missing term"); RECOVER}
2333 ;
2334
2335 pre_increment_expression:
2336         INCR_TK unary_expression
2337                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2338 |       INCR_TK error
2339                 {yyerror ("Missing term"); RECOVER}
2340 ;
2341
2342 pre_decrement_expression:
2343         DECR_TK unary_expression
2344                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2345 |       DECR_TK error
2346                 {yyerror ("Missing term"); RECOVER}
2347 ;
2348
2349 unary_expression_not_plus_minus:
2350         postfix_expression
2351 |       NOT_TK unary_expression
2352                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2353 |       NEG_TK unary_expression
2354                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2355 |       cast_expression
2356 |       NOT_TK error
2357                 {yyerror ("Missing term"); RECOVER}
2358 |       NEG_TK error
2359                 {yyerror ("Missing term"); RECOVER}
2360 ;
2361
2362 cast_expression:                /* Error handling here is potentially weak */
2363         OP_TK primitive_type dims CP_TK unary_expression
2364                 { 
2365                   tree type = $2;
2366                   int osb = pop_current_osb (ctxp);
2367                   while (osb--)
2368                     type = build_java_array_type (type, -1);
2369                   $$ = build_cast ($1.location, type, $5); 
2370                 }
2371 |       OP_TK primitive_type CP_TK unary_expression
2372                 { $$ = build_cast ($1.location, $2, $4); }
2373 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2374                 { $$ = build_cast ($1.location, $2, $4); }
2375 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2376                 { 
2377                   const char *ptr;
2378                   int osb = pop_current_osb (ctxp); 
2379                   obstack_grow (&temporary_obstack, 
2380                                 IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2381                                 IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2382                   while (osb--)
2383                     obstack_grow (&temporary_obstack, "[]", 2);
2384                   obstack_1grow (&temporary_obstack, '\0');
2385                   ptr = obstack_finish (&temporary_obstack);
2386                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2387                   $$ = build_cast ($1.location, $2, $5);
2388                 }
2389 |       OP_TK primitive_type OSB_TK error
2390                 {yyerror ("']' expected, invalid type expression");}
2391 |       OP_TK error
2392                 {
2393                   YYNOT_TWICE yyerror ("Invalid type expression"); RECOVER;
2394                   RECOVER;
2395                 }
2396 |       OP_TK primitive_type dims CP_TK error
2397                 {yyerror ("Missing term"); RECOVER;}
2398 |       OP_TK primitive_type CP_TK error
2399                 {yyerror ("Missing term"); RECOVER;}
2400 |       OP_TK name dims CP_TK error
2401                 {yyerror ("Missing term"); RECOVER;}
2402 ;
2403
2404 multiplicative_expression:
2405         unary_expression
2406 |       multiplicative_expression MULT_TK unary_expression
2407                 { 
2408                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2409                                     $2.location, $1, $3);
2410                 }
2411 |       multiplicative_expression DIV_TK unary_expression
2412                 {
2413                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2414                                     $1, $3); 
2415                 }
2416 |       multiplicative_expression REM_TK unary_expression
2417                 {
2418                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2419                                     $1, $3); 
2420                 }
2421 |       multiplicative_expression MULT_TK error
2422                 {yyerror ("Missing term"); RECOVER;}
2423 |       multiplicative_expression DIV_TK error
2424                 {yyerror ("Missing term"); RECOVER;}
2425 |       multiplicative_expression REM_TK error
2426                 {yyerror ("Missing term"); RECOVER;}
2427 ;
2428
2429 additive_expression:
2430         multiplicative_expression
2431 |       additive_expression PLUS_TK multiplicative_expression
2432                 {
2433                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2434                                     $1, $3); 
2435                 }
2436 |       additive_expression MINUS_TK multiplicative_expression
2437                 {
2438                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2439                                     $1, $3); 
2440                 }
2441 |       additive_expression PLUS_TK error
2442                 {yyerror ("Missing term"); RECOVER;}
2443 |       additive_expression MINUS_TK error
2444                 {yyerror ("Missing term"); RECOVER;}
2445 ;
2446
2447 shift_expression:
2448         additive_expression
2449 |       shift_expression LS_TK additive_expression
2450                 {
2451                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2452                                     $1, $3); 
2453                 }
2454 |       shift_expression SRS_TK additive_expression
2455                 {
2456                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2457                                     $1, $3); 
2458                 }
2459 |       shift_expression ZRS_TK additive_expression
2460                 {
2461                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2462                                     $1, $3); 
2463                 }
2464 |       shift_expression LS_TK error
2465                 {yyerror ("Missing term"); RECOVER;}
2466 |       shift_expression SRS_TK error
2467                 {yyerror ("Missing term"); RECOVER;}
2468 |       shift_expression ZRS_TK error
2469                 {yyerror ("Missing term"); RECOVER;}
2470 ;
2471
2472 relational_expression:
2473         shift_expression
2474 |       relational_expression LT_TK shift_expression
2475                 {
2476                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2477                                     $1, $3); 
2478                 }
2479 |       relational_expression GT_TK shift_expression
2480                 {
2481                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2482                                     $1, $3); 
2483                 }
2484 |       relational_expression LTE_TK shift_expression
2485                 {
2486                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2487                                     $1, $3); 
2488                 }
2489 |       relational_expression GTE_TK shift_expression
2490                 {
2491                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2492                                     $1, $3); 
2493                 }
2494 |       relational_expression INSTANCEOF_TK reference_type
2495                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2496 |       relational_expression LT_TK error
2497                 {yyerror ("Missing term"); RECOVER;}
2498 |       relational_expression GT_TK error
2499                 {yyerror ("Missing term"); RECOVER;}
2500 |       relational_expression LTE_TK error
2501                 {yyerror ("Missing term"); RECOVER;}
2502 |       relational_expression GTE_TK error
2503                 {yyerror ("Missing term"); RECOVER;}
2504 |       relational_expression INSTANCEOF_TK error
2505                 {yyerror ("Invalid reference type"); RECOVER;}
2506 ;
2507
2508 equality_expression:
2509         relational_expression
2510 |       equality_expression EQ_TK relational_expression
2511                 {
2512                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2513                                     $1, $3); 
2514                 }
2515 |       equality_expression NEQ_TK relational_expression
2516                 {
2517                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2518                                     $1, $3); 
2519                 }
2520 |       equality_expression EQ_TK error
2521                 {yyerror ("Missing term"); RECOVER;}
2522 |       equality_expression NEQ_TK error
2523                 {yyerror ("Missing term"); RECOVER;}
2524 ;
2525
2526 and_expression:
2527         equality_expression
2528 |       and_expression AND_TK equality_expression
2529                 {
2530                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2531                                     $1, $3); 
2532                 }
2533 |       and_expression AND_TK error
2534                 {yyerror ("Missing term"); RECOVER;}
2535 ;
2536
2537 exclusive_or_expression:
2538         and_expression
2539 |       exclusive_or_expression XOR_TK and_expression
2540                 {
2541                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2542                                     $1, $3); 
2543                 }
2544 |       exclusive_or_expression XOR_TK error
2545                 {yyerror ("Missing term"); RECOVER;}
2546 ;
2547
2548 inclusive_or_expression:
2549         exclusive_or_expression
2550 |       inclusive_or_expression OR_TK exclusive_or_expression
2551                 {
2552                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2553                                     $1, $3); 
2554                 }
2555 |       inclusive_or_expression OR_TK error
2556                 {yyerror ("Missing term"); RECOVER;}
2557 ;
2558
2559 conditional_and_expression:
2560         inclusive_or_expression
2561 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2562                 {
2563                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2564                                     $1, $3); 
2565                 }
2566 |       conditional_and_expression BOOL_AND_TK error
2567                 {yyerror ("Missing term"); RECOVER;}
2568 ;
2569
2570 conditional_or_expression:
2571         conditional_and_expression
2572 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2573                 {
2574                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2575                                     $1, $3); 
2576                 }
2577 |       conditional_or_expression BOOL_OR_TK error
2578                 {yyerror ("Missing term"); RECOVER;}
2579 ;
2580
2581 conditional_expression:         /* Error handling here is weak */
2582         conditional_or_expression
2583 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2584                 {
2585                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2586                   EXPR_WFL_LINECOL ($$) = $2.location;
2587                 }
2588 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2589                 {
2590                   YYERROR_NOW;
2591                   yyerror ("Missing term");
2592                   DRECOVER (1);
2593                 }
2594 |       conditional_or_expression REL_QM_TK error
2595                 {yyerror ("Missing term"); DRECOVER (2);}
2596 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2597                 {yyerror ("Missing term"); DRECOVER (3);}
2598 ;
2599
2600 assignment_expression:
2601         conditional_expression
2602 |       assignment
2603 ;
2604
2605 assignment:
2606         left_hand_side assignment_operator assignment_expression
2607                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2608 |       left_hand_side assignment_operator error
2609                 {
2610                   YYNOT_TWICE yyerror ("Missing term");
2611                   DRECOVER (assign);
2612                 }
2613 ;
2614
2615 left_hand_side:
2616         name
2617 |       field_access
2618 |       array_access
2619 ;
2620
2621 assignment_operator:
2622         ASSIGN_ANY_TK
2623 |       ASSIGN_TK
2624 ;
2625
2626 expression:
2627         assignment_expression
2628 ;
2629
2630 constant_expression:
2631         expression
2632 ;
2633
2634 %%
2635
2636 /* Helper function to retrieve an OSB count. Should be used when the
2637    `dims:' rule is being used.  */
2638
2639 static int
2640 pop_current_osb (ctxp)
2641      struct parser_ctxt *ctxp;
2642 {
2643   int to_return;
2644
2645   if (ctxp->osb_depth < 0)
2646     abort ();
2647   
2648   to_return = CURRENT_OSB (ctxp);
2649   ctxp->osb_depth--;
2650   
2651   return to_return;
2652 }
2653
2654 \f
2655
2656 /* This section of the code deal with save/restoring parser contexts.
2657    Add mode documentation here. FIXME */
2658
2659 /* Helper function. Create a new parser context. With
2660    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2661    context is copied, otherwise, the new context is zeroed. The newly
2662    created context becomes the current one.  */
2663
2664 static void
2665 create_new_parser_context (copy_from_previous)
2666     int copy_from_previous;
2667 {
2668   struct parser_ctxt *new;
2669
2670   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2671   if (copy_from_previous)
2672     {
2673       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2674       new->saved_data_ctx = 1;
2675     }
2676   else
2677     memset ((PTR) new, 0, sizeof (struct parser_ctxt));
2678       
2679   new->next = ctxp;
2680   ctxp = new;
2681 }
2682
2683 /* Create a new parser context and make it the current one. */
2684
2685 void
2686 java_push_parser_context ()
2687 {
2688   create_new_parser_context (0);
2689 }  
2690
2691 void 
2692 java_pop_parser_context (generate)
2693      int generate;
2694 {
2695   tree current;
2696   struct parser_ctxt *toFree, *next;
2697
2698   if (!ctxp)
2699     return;
2700
2701   toFree = ctxp;
2702   next = ctxp->next;
2703   if (next)
2704     {
2705       lineno = ctxp->lineno;
2706       current_class = ctxp->class_type;
2707     }
2708
2709   /* If the old and new lexers differ, then free the old one.  */
2710   if (ctxp->lexer && next && ctxp->lexer != next->lexer)
2711     java_destroy_lexer (ctxp->lexer);
2712
2713   /* Set the single import class file flag to 0 for the current list
2714      of imported things */
2715   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2716     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 0;
2717
2718   /* And restore those of the previous context */
2719   if ((ctxp = next))            /* Assignment is really meant here */
2720     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2721       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1;
2722   
2723   /* If we pushed a context to parse a class intended to be generated,
2724      we keep it so we can remember the class. What we could actually
2725      do is to just update a list of class names.  */
2726   if (generate)
2727     {
2728       toFree->next = ctxp_for_generation;
2729       ctxp_for_generation = toFree;
2730     }
2731   else
2732     free (toFree);
2733 }
2734
2735 /* Create a parser context for the use of saving some global
2736    variables.  */
2737
2738 void
2739 java_parser_context_save_global ()
2740 {
2741   if (!ctxp)
2742     {
2743       java_push_parser_context ();
2744       ctxp->saved_data_ctx = 1;
2745     }
2746
2747   /* If this context already stores data, create a new one suitable
2748      for data storage. */
2749   else if (ctxp->saved_data)
2750     create_new_parser_context (1);
2751
2752   ctxp->lineno = lineno;
2753   ctxp->class_type = current_class;
2754   ctxp->filename = input_filename;
2755   ctxp->function_decl = current_function_decl;
2756   ctxp->saved_data = 1;
2757 }
2758
2759 /* Restore some global variables from the previous context. Make the
2760    previous context the current one.  */
2761
2762 void
2763 java_parser_context_restore_global ()
2764 {
2765   lineno = ctxp->lineno;
2766   current_class = ctxp->class_type;
2767   input_filename = ctxp->filename;
2768   if (wfl_operator)
2769     {
2770       tree s;
2771       BUILD_FILENAME_IDENTIFIER_NODE (s, input_filename);
2772       EXPR_WFL_FILENAME_NODE (wfl_operator) = s;
2773     }
2774   current_function_decl = ctxp->function_decl;
2775   ctxp->saved_data = 0;
2776   if (ctxp->saved_data_ctx)
2777     java_pop_parser_context (0);
2778 }
2779
2780 /* Suspend vital data for the current class/function being parsed so
2781    that an other class can be parsed. Used to let local/anonymous
2782    classes be parsed.  */
2783
2784 static void
2785 java_parser_context_suspend ()
2786 {
2787   /* This makes debugging through java_debug_context easier */
2788   static const char *const name = "<inner buffer context>";
2789
2790   /* Duplicate the previous context, use it to save the globals we're
2791      interested in */
2792   create_new_parser_context (1);
2793   ctxp->function_decl = current_function_decl;
2794   ctxp->class_type = current_class;
2795
2796   /* Then create a new context which inherits all data from the
2797      previous one. This will be the new current context  */
2798   create_new_parser_context (1);
2799
2800   /* Help debugging */
2801   ctxp->next->filename = name;
2802 }
2803
2804 /* Resume vital data for the current class/function being parsed so
2805    that an other class can be parsed. Used to let local/anonymous
2806    classes be parsed.  The trick is the data storing file position
2807    informations must be restored to their current value, so parsing
2808    can resume as if no context was ever saved. */
2809
2810 static void
2811 java_parser_context_resume ()
2812 {
2813   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2814   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2815   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2816
2817   /* We need to inherit the list of classes to complete/generate */
2818   restored->classd_list = old->classd_list;
2819   restored->class_list = old->class_list;
2820
2821   /* Restore the current class and function from the saver */
2822   current_class = saver->class_type;
2823   current_function_decl = saver->function_decl;
2824
2825   /* Retrive the restored context */
2826   ctxp = restored;
2827
2828   /* Re-installed the data for the parsing to carry on */
2829   memcpy (&ctxp->marker_begining, &old->marker_begining, 
2830           (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2831
2832   /* Buffer context can now be discarded */
2833   free (saver);
2834   free (old);
2835 }
2836
2837 /* Add a new anchor node to which all statement(s) initializing static
2838    and non static initialized upon declaration field(s) will be
2839    linked.  */
2840
2841 static void
2842 java_parser_context_push_initialized_field ()
2843 {
2844   tree node;
2845
2846   node = build_tree_list (NULL_TREE, NULL_TREE);
2847   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2848   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2849
2850   node = build_tree_list (NULL_TREE, NULL_TREE);
2851   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2852   CPC_INITIALIZER_LIST (ctxp) = node;
2853
2854   node = build_tree_list (NULL_TREE, NULL_TREE);
2855   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2856   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2857 }
2858
2859 /* Pop the lists of initialized field. If this lists aren't empty,
2860    remember them so we can use it to create and populate the finit$
2861    or <clinit> functions. */
2862
2863 static void
2864 java_parser_context_pop_initialized_field ()
2865 {
2866   tree stmts;
2867   tree class_type = TREE_TYPE (GET_CPC ());
2868
2869   if (CPC_INITIALIZER_LIST (ctxp))
2870     {
2871       stmts = CPC_INITIALIZER_STMT (ctxp);
2872       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2873       if (stmts && !java_error_count)
2874         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2875     }
2876
2877   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2878     {
2879       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2880       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2881         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2882       /* Keep initialization in order to enforce 8.5 */
2883       if (stmts && !java_error_count)
2884         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2885     }
2886
2887   /* JDK 1.1 instance initializers */
2888   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2889     {
2890       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2891       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2892         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2893       if (stmts && !java_error_count)
2894         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2895     }
2896 }
2897
2898 static tree
2899 reorder_static_initialized (list)
2900      tree list;
2901 {
2902   /* We have to keep things in order. The alias initializer have to
2903      come first, then the initialized regular field, in reverse to
2904      keep them in lexical order. */
2905   tree marker, previous = NULL_TREE;
2906   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2907     if (TREE_CODE (marker) == TREE_LIST 
2908         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2909       break;
2910   
2911   /* No static initialized, the list is fine as is */
2912   if (!previous)
2913     list = TREE_CHAIN (marker);
2914
2915   /* No marker? reverse the whole list */
2916   else if (!marker)
2917     list = nreverse (list);
2918
2919   /* Otherwise, reverse what's after the marker and the new reordered
2920      sublist will replace the marker. */
2921   else
2922     {
2923       TREE_CHAIN (previous) = NULL_TREE;
2924       list = nreverse (list);
2925       list = chainon (TREE_CHAIN (marker), list);
2926     }
2927   return list;
2928 }
2929
2930 /* Helper functions to dump the parser context stack.  */
2931
2932 #define TAB_CONTEXT(C) \
2933   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2934
2935 static void
2936 java_debug_context_do (tab)
2937      int tab;
2938 {
2939   struct parser_ctxt *copy = ctxp;
2940   while (copy)
2941     {
2942       TAB_CONTEXT (tab);
2943       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2944       TAB_CONTEXT (tab);
2945       fprintf (stderr, "filename: %s\n", copy->filename);
2946       TAB_CONTEXT (tab);
2947       fprintf (stderr, "lineno: %d\n", copy->lineno);
2948       TAB_CONTEXT (tab);
2949       fprintf (stderr, "package: %s\n",
2950                (copy->package ? 
2951                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2952       TAB_CONTEXT (tab);
2953       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2954       TAB_CONTEXT (tab);
2955       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2956       copy = copy->next;
2957       tab += 2;
2958     }
2959 }
2960
2961 /* Dump the stacked up parser contexts. Intended to be called from a
2962    debugger.  */
2963
2964 void
2965 java_debug_context ()
2966 {
2967   java_debug_context_do (0);
2968 }
2969
2970 \f
2971
2972 /* Flag for the error report routine to issue the error the first time
2973    it's called (overriding the default behavior which is to drop the
2974    first invocation and honor the second one, taking advantage of a
2975    richer context.  */
2976 static int force_error = 0;
2977
2978 /* Reporting an constructor invocation error.  */
2979 static void
2980 parse_ctor_invocation_error ()
2981 {
2982   if (DECL_CONSTRUCTOR_P (current_function_decl))
2983     yyerror ("Constructor invocation must be first thing in a constructor"); 
2984   else
2985     yyerror ("Only constructors can invoke constructors");
2986 }
2987
2988 /* Reporting JDK1.1 features not implemented.  */
2989
2990 static tree
2991 parse_jdk1_1_error (msg)
2992     const char *msg;
2993 {
2994   sorry (": `%s' JDK1.1(TM) feature", msg);
2995   java_error_count++;
2996   return empty_stmt_node;
2997 }
2998
2999 static int do_warning = 0;
3000
3001 void
3002 yyerror (msg)
3003      const char *msg;
3004 {
3005   static java_lc elc;
3006   static int  prev_lineno;
3007   static const char *prev_msg;
3008
3009   int save_lineno;
3010   char *remainder, *code_from_source;
3011   
3012   if (!force_error && prev_lineno == lineno)
3013     return;
3014
3015   /* Save current error location but report latter, when the context is
3016      richer.  */
3017   if (ctxp->java_error_flag == 0)
3018     {
3019       ctxp->java_error_flag = 1;
3020       elc = ctxp->elc;
3021       /* Do something to use the previous line if we're reaching the
3022          end of the file... */
3023 #ifdef VERBOSE_SKELETON
3024       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
3025 #endif
3026       return;
3027     }
3028
3029   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
3030   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
3031     return;
3032
3033   ctxp->java_error_flag = 0;
3034   if (do_warning)
3035     java_warning_count++;
3036   else
3037     java_error_count++;
3038   
3039   if (elc.col == 0 && msg && msg[1] == ';')
3040     {
3041       elc.col  = ctxp->p_line->char_col-1;
3042       elc.line = ctxp->p_line->lineno;
3043     }
3044
3045   save_lineno = lineno;
3046   prev_lineno = lineno = elc.line;
3047   prev_msg = msg;
3048
3049   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
3050   obstack_grow0 (&temporary_obstack, 
3051                  code_from_source, strlen (code_from_source));
3052   remainder = obstack_finish (&temporary_obstack);
3053   if (do_warning)
3054     warning ("%s.\n%s", msg, remainder);
3055   else
3056     error ("%s.\n%s", msg, remainder);
3057
3058   /* This allow us to cheaply avoid an extra 'Invalid expression
3059      statement' error report when errors have been already reported on
3060      the same line. This occurs when we report an error but don't have
3061      a synchronization point other than ';', which
3062      expression_statement is the only one to take care of.  */
3063   ctxp->prevent_ese = lineno = save_lineno;
3064 }
3065
3066 static void
3067 issue_warning_error_from_context (cl, msg, ap)
3068      tree cl;
3069      const char *msg;
3070      va_list ap;
3071 {
3072   const char *saved, *saved_input_filename;
3073   char buffer [4096];
3074   vsprintf (buffer, msg, ap);
3075   force_error = 1;
3076
3077   ctxp->elc.line = EXPR_WFL_LINENO (cl);
3078   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
3079                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
3080
3081   /* We have a CL, that's a good reason for using it if it contains data */
3082   saved = ctxp->filename;
3083   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
3084     ctxp->filename = EXPR_WFL_FILENAME (cl);
3085   saved_input_filename = input_filename;
3086   input_filename = ctxp->filename;
3087   java_error (NULL);
3088   java_error (buffer);
3089   ctxp->filename = saved;
3090   input_filename = saved_input_filename;
3091   force_error = 0;
3092 }
3093
3094 /* Issue an error message at a current source line CL */
3095
3096 void
3097 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
3098 {
3099   VA_OPEN (ap, msg);
3100   VA_FIXEDARG (ap, tree, cl);
3101   VA_FIXEDARG (ap, const char *, msg);
3102   issue_warning_error_from_context (cl, msg, ap);
3103   VA_CLOSE (ap);
3104 }
3105
3106 /* Issue a warning at a current source line CL */
3107
3108 static void
3109 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3110 {
3111   VA_OPEN (ap, msg);
3112   VA_FIXEDARG (ap, tree, cl);
3113   VA_FIXEDARG (ap, const char *, msg);
3114
3115   force_error = do_warning = 1;
3116   issue_warning_error_from_context (cl, msg, ap);
3117   do_warning = force_error = 0;
3118   VA_CLOSE (ap);
3119 }
3120
3121 static tree
3122 find_expr_with_wfl (node)
3123      tree node;
3124 {
3125   while (node)
3126     {
3127       char code;
3128       tree to_return;
3129
3130       switch (TREE_CODE (node))
3131         {
3132         case BLOCK:
3133           node = BLOCK_EXPR_BODY (node);
3134           continue;
3135
3136         case COMPOUND_EXPR:
3137           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3138           if (to_return)
3139             return to_return;
3140           node = TREE_OPERAND (node, 1);
3141           continue;
3142
3143         case LOOP_EXPR:
3144           node = TREE_OPERAND (node, 0);
3145           continue;
3146           
3147         case LABELED_BLOCK_EXPR:
3148           node = TREE_OPERAND (node, 1);
3149           continue;
3150
3151         default:
3152           code = TREE_CODE_CLASS (TREE_CODE (node));
3153           if (((code == '1') || (code == '2') || (code == 'e'))
3154               && EXPR_WFL_LINECOL (node))
3155             return node;
3156           return NULL_TREE;
3157         }
3158     }
3159   return NULL_TREE;
3160 }
3161
3162 /* Issue a missing return statement error. Uses METHOD to figure the
3163    last line of the method the error occurs in.  */
3164
3165 static void
3166 missing_return_error (method)
3167      tree method;
3168 {
3169   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3170   parse_error_context (wfl_operator, "Missing return statement");
3171 }
3172
3173 /* Issue an unreachable statement error. From NODE, find the next
3174    statement to report appropriately.  */
3175 static void
3176 unreachable_stmt_error (node)
3177      tree node;
3178 {
3179   /* Browse node to find the next expression node that has a WFL. Use
3180      the location to report the error */
3181   if (TREE_CODE (node) == COMPOUND_EXPR)
3182     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3183   else
3184     node = find_expr_with_wfl (node);
3185
3186   if (node)
3187     {
3188       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3189       parse_error_context (wfl_operator, "Unreachable statement");
3190     }
3191   else
3192     abort ();
3193 }
3194
3195 int
3196 java_report_errors ()
3197 {
3198   if (java_error_count)
3199     fprintf (stderr, "%d error%s", 
3200              java_error_count, (java_error_count == 1 ? "" : "s"));
3201   if (java_warning_count)
3202     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3203              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3204   if (java_error_count || java_warning_count)
3205     putc ('\n', stderr);
3206   return java_error_count;
3207 }
3208
3209 static char *
3210 java_accstring_lookup (flags)
3211      int flags;
3212 {
3213   static char buffer [80];
3214 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3215
3216   /* Access modifier looked-up first for easier report on forbidden
3217      access. */
3218   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3219   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3220   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3221   if (flags & ACC_STATIC) COPY_RETURN ("static");
3222   if (flags & ACC_FINAL) COPY_RETURN ("final");
3223   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3224   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3225   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3226   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3227   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3228   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3229
3230   buffer [0] = '\0';
3231   return buffer;
3232 #undef COPY_RETURN
3233 }
3234
3235 /* Issuing error messages upon redefinition of classes, interfaces or
3236    variables. */
3237
3238 static void
3239 classitf_redefinition_error (context, id, decl, cl)
3240      const char *context;
3241      tree id, decl, cl;
3242 {
3243   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3244                        context, IDENTIFIER_POINTER (id), 
3245                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3246   /* Here we should point out where its redefined. It's a unicode. FIXME */
3247 }
3248
3249 static void
3250 variable_redefinition_error (context, name, type, line)
3251      tree context, name, type;
3252      int line;
3253 {
3254   const char *type_name;
3255
3256   /* Figure a proper name for type. We might haven't resolved it */
3257   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3258     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3259   else
3260     type_name = lang_printable_name (type, 0);
3261
3262   parse_error_context (context,
3263                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3264                        IDENTIFIER_POINTER (name),
3265                        type_name, IDENTIFIER_POINTER (name), line);
3266 }
3267
3268 /* If ANAME is terminated with `[]', it indicates an array. This
3269    function returns the number of `[]' found and if this number is
3270    greater than zero, it extracts the array type name and places it in
3271    the node pointed to by TRIMMED unless TRIMMED is null.  */
3272
3273 static int
3274 build_type_name_from_array_name (aname, trimmed)
3275      tree aname;
3276      tree *trimmed;
3277 {
3278   const char *name = IDENTIFIER_POINTER (aname);
3279   int len = IDENTIFIER_LENGTH (aname);
3280   int array_dims;
3281
3282   STRING_STRIP_BRACKETS (name, len, array_dims);
3283
3284   if (array_dims && trimmed)
3285     *trimmed = get_identifier_with_length (name, len);
3286
3287   return array_dims;
3288 }
3289
3290 static tree
3291 build_array_from_name (type, type_wfl, name, ret_name)
3292      tree type, type_wfl, name, *ret_name;
3293 {
3294   int more_dims = 0;
3295
3296   /* Eventually get more dims */
3297   more_dims = build_type_name_from_array_name (name, &name);
3298   
3299   /* If we have, then craft a new type for this variable */
3300   if (more_dims)
3301     {
3302       tree save = type;
3303
3304       /* If we have a pointer, use its type */
3305       if (TREE_CODE (type) == POINTER_TYPE)
3306         type = TREE_TYPE (type);
3307
3308       /* Building the first dimension of a primitive type uses this
3309          function */
3310       if (JPRIMITIVE_TYPE_P (type))
3311         {
3312           type = build_java_array_type (type, -1);
3313           more_dims--;
3314         }
3315       /* Otherwise, if we have a WFL for this type, use it (the type
3316          is already an array on an unresolved type, and we just keep
3317          on adding dimensions) */
3318       else if (type_wfl)
3319         {
3320           type = type_wfl;
3321           more_dims += build_type_name_from_array_name (TYPE_NAME (save),
3322                                                         NULL);
3323         }
3324
3325       /* Add all the dimensions */
3326       while (more_dims--)
3327         type = build_unresolved_array_type (type);
3328
3329       /* The type may have been incomplete in the first place */
3330       if (type_wfl)
3331         type = obtain_incomplete_type (type);
3332     }
3333
3334   if (ret_name)
3335     *ret_name = name;
3336   return type;
3337 }
3338
3339 /* Build something that the type identifier resolver will identify as
3340    being an array to an unresolved type. TYPE_WFL is a WFL on a
3341    identifier. */
3342
3343 static tree
3344 build_unresolved_array_type (type_or_wfl)
3345      tree type_or_wfl;
3346 {
3347   const char *ptr;
3348   tree wfl;
3349
3350   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3351      just create a array type */
3352   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3353     return build_java_array_type (type_or_wfl, -1);
3354
3355   obstack_grow (&temporary_obstack,
3356                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3357                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3358   obstack_grow0 (&temporary_obstack, "[]", 2);
3359   ptr = obstack_finish (&temporary_obstack);
3360   wfl = build_expr_wfl (get_identifier (ptr),
3361                         EXPR_WFL_FILENAME (type_or_wfl),
3362                         EXPR_WFL_LINENO (type_or_wfl),
3363                         EXPR_WFL_COLNO (type_or_wfl));
3364   /* Re-install the existing qualifications so that the type can be
3365      resolved properly. */
3366   EXPR_WFL_QUALIFICATION (wfl) = EXPR_WFL_QUALIFICATION (type_or_wfl);
3367   return wfl;
3368 }
3369
3370 static void
3371 parser_add_interface (class_decl, interface_decl, wfl)
3372      tree class_decl, interface_decl, wfl;
3373 {
3374   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3375     parse_error_context (wfl, "Interface `%s' repeated",
3376                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3377 }
3378
3379 /* Bulk of common class/interface checks. Return 1 if an error was
3380    encountered. TAG is 0 for a class, 1 for an interface.  */
3381
3382 static int
3383 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3384      int is_interface, flags;
3385      tree raw_name, qualified_name, decl, cl;
3386 {
3387   tree node;
3388   int sca = 0;                  /* Static class allowed */
3389   int icaf = 0;                 /* Inner class allowed flags */
3390   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3391
3392   if (!quiet_flag)
3393     fprintf (stderr, " %s%s %s", 
3394              (CPC_INNER_P () ? "inner" : ""),
3395              (is_interface ? "interface" : "class"), 
3396              IDENTIFIER_POINTER (qualified_name));
3397
3398   /* Scope of an interface/class type name:
3399        - Can't be imported by a single type import
3400        - Can't already exists in the package */
3401   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3402       && (node = find_name_in_single_imports (raw_name))
3403       && !CPC_INNER_P ())
3404     {
3405       parse_error_context 
3406         (cl, "%s name `%s' clashes with imported type `%s'",
3407          (is_interface ? "Interface" : "Class"),
3408          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3409       return 1;
3410     }
3411   if (decl && CLASS_COMPLETE_P (decl))
3412     {
3413       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3414                                    qualified_name, decl, cl);
3415       return 1;
3416     }
3417
3418   if (check_inner_class_redefinition (raw_name, cl))
3419     return 1;
3420
3421   /* If public, file name should match class/interface name, except
3422      when dealing with an inner class */
3423   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3424     {
3425       const char *f;
3426
3427       /* Contains OS dependent assumption on path separator. FIXME */
3428       for (f = &input_filename [strlen (input_filename)]; 
3429            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3430            f--)
3431         ;
3432       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3433         f++;
3434       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3435                    f , IDENTIFIER_LENGTH (raw_name)) ||
3436           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3437         parse_error_context
3438           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3439                              (is_interface ? "interface" : "class"),
3440                              IDENTIFIER_POINTER (qualified_name),
3441                              IDENTIFIER_POINTER (raw_name));
3442     }
3443
3444   /* Static classes can be declared only in top level classes. Note:
3445      once static, a inner class is a top level class. */
3446   if (flags & ACC_STATIC)
3447     {
3448       /* Catch the specific error of declaring an class inner class
3449          with no toplevel enclosing class. Prevent check_modifiers from
3450          complaining a second time */
3451       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3452         {
3453           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3454                                IDENTIFIER_POINTER (qualified_name));
3455           sca = ACC_STATIC;
3456         }
3457       /* Else, in the context of a top-level class declaration, let
3458          `check_modifiers' do its job, otherwise, give it a go */
3459       else
3460         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3461     }
3462
3463   /* Inner classes can be declared private or protected
3464      within their enclosing classes. */
3465   if (CPC_INNER_P ())
3466     {
3467       /* A class which is local to a block can't be public, private,
3468          protected or static. But it is created final, so allow this
3469          one. */
3470       if (current_function_decl)
3471         icaf = sca = uaaf = ACC_FINAL;
3472       else
3473         {
3474           check_modifiers_consistency (flags);
3475           icaf = ACC_PROTECTED;
3476           if (! CLASS_INTERFACE (GET_CPC ()))
3477             icaf |= ACC_PRIVATE;
3478         }
3479     }
3480
3481   if (is_interface) 
3482     {
3483       if (CPC_INNER_P ())
3484         uaaf = INTERFACE_INNER_MODIFIERS;
3485       else
3486         uaaf = INTERFACE_MODIFIERS;
3487       
3488       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3489                        flags, uaaf);
3490     }
3491   else
3492     check_modifiers ((current_function_decl ?
3493                       "Illegal modifier `%s' for local class declaration" :
3494                       "Illegal modifier `%s' for class declaration"),
3495                      flags, uaaf|sca|icaf);
3496   return 0;
3497 }
3498
3499 static void
3500 make_nested_class_name (cpc_list)
3501      tree cpc_list;
3502 {
3503   tree name;
3504
3505   if (!cpc_list)
3506     return;
3507   else
3508     make_nested_class_name (TREE_CHAIN (cpc_list));
3509
3510   /* Pick the qualified name when dealing with the first upmost
3511      enclosing class */
3512   name = (TREE_CHAIN (cpc_list) ? 
3513           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3514   obstack_grow (&temporary_obstack,
3515                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3516   obstack_1grow (&temporary_obstack, '$');
3517 }
3518
3519 /* Can't redefine a class already defined in an earlier scope. */
3520
3521 static int
3522 check_inner_class_redefinition (raw_name, cl)
3523      tree raw_name, cl;
3524 {
3525   tree scope_list;
3526
3527   for (scope_list = GET_CPC_LIST (); scope_list; 
3528        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3529     if (raw_name == GET_CPC_UN_NODE (scope_list))
3530       {
3531         parse_error_context 
3532           (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",
3533            IDENTIFIER_POINTER (raw_name));
3534         return 1;
3535       }
3536   return 0;
3537 }
3538
3539 /* Tries to find a decl for CLASS_TYPE within ENCLOSING. If we fail,
3540    we remember ENCLOSING and SUPER.  */
3541
3542 static tree
3543 resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
3544      struct hash_table *circularity_hash;
3545      tree cl, *enclosing, *super, class_type;
3546 {
3547   tree local_enclosing = *enclosing;
3548   tree local_super = NULL_TREE;
3549
3550   while (local_enclosing)
3551     {
3552       tree intermediate, decl;
3553
3554       hash_lookup (circularity_hash, 
3555                    (const  hash_table_key) local_enclosing, TRUE, NULL);
3556
3557       if ((decl = find_as_inner_class (local_enclosing, class_type, cl)))
3558         return decl;
3559
3560       intermediate = local_enclosing;
3561       /* Explore enclosing contexts. */
3562       while (INNER_CLASS_DECL_P (intermediate))
3563         {
3564           intermediate = DECL_CONTEXT (intermediate);
3565           if ((decl = find_as_inner_class (intermediate, class_type, cl)))
3566             return decl;
3567         }
3568
3569       /* Now go to the upper classes, bail out if necessary. We will
3570          analyze the returned SUPER and act accordingly (see
3571          do_resolve_class.) */
3572       local_super = CLASSTYPE_SUPER (TREE_TYPE (local_enclosing));
3573       if (!local_super || local_super == object_type_node)
3574         break;
3575
3576       if (TREE_CODE (local_super) == POINTER_TYPE)
3577         local_super = do_resolve_class (NULL, local_super, NULL, NULL);
3578       else
3579         local_super = TYPE_NAME (local_super);
3580
3581       /* We may not have checked for circular inheritance yet, so do so
3582          here to prevent an infinite loop. */
3583       if (hash_lookup (circularity_hash,
3584                        (const hash_table_key) local_super, FALSE, NULL))
3585         {
3586           if (!cl)
3587             cl = lookup_cl (local_enclosing);
3588           
3589           parse_error_context
3590             (cl, "Cyclic inheritance involving %s",
3591              IDENTIFIER_POINTER (DECL_NAME (local_enclosing)));
3592           local_enclosing = NULL_TREE;
3593         }
3594       else
3595         local_enclosing = local_super;
3596     }
3597
3598   /* We failed. Return LOCAL_SUPER and LOCAL_ENCLOSING. */
3599   *super = local_super;
3600   *enclosing = local_enclosing;
3601
3602   return NULL_TREE;
3603 }
3604
3605 /* Within ENCLOSING, find a decl for NAME and return it. NAME can be
3606    qualified. */
3607
3608 static tree
3609 find_as_inner_class (enclosing, name, cl)
3610      tree enclosing, name, cl;
3611 {
3612   tree qual, to_return;
3613   if (!enclosing)
3614     return NULL_TREE;
3615
3616   name = TYPE_NAME (name);
3617
3618   /* First search: within the scope of `enclosing', search for name */
3619   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3620     qual = EXPR_WFL_QUALIFICATION (cl);
3621   else if (cl)
3622     qual = build_tree_list (cl, NULL_TREE);
3623   else
3624     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3625   
3626   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3627     return to_return;
3628
3629   /* We're dealing with a qualified name. Try to resolve thing until
3630      we get something that is an enclosing class. */
3631   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3632     {
3633       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3634
3635       for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3636            qual = TREE_CHAIN (qual))
3637         {
3638           acc = merge_qualified_name (acc, 
3639                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3640           BUILD_PTR_FROM_NAME (ptr, acc);
3641           decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3642         }
3643
3644       /* A NULL qual and a decl means that the search ended
3645          successfully?!? We have to do something then. FIXME */
3646       
3647       if (decl)
3648         enclosing = decl;
3649       else
3650         qual = EXPR_WFL_QUALIFICATION (cl);
3651     }
3652   /* Otherwise, create a qual for the other part of the resolution. */
3653   else
3654     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3655   
3656   return find_as_inner_class_do (qual, enclosing);
3657 }
3658
3659 /* We go inside the list of sub classes and try to find a way
3660    through. */
3661
3662 static tree
3663 find_as_inner_class_do (qual, enclosing)
3664      tree qual, enclosing;
3665 {
3666   if (!qual)
3667     return NULL_TREE;
3668
3669   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3670     {
3671       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3672       tree next_enclosing = NULL_TREE;
3673       tree inner_list;
3674
3675       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3676            inner_list; inner_list = TREE_CHAIN (inner_list))
3677         {
3678           if (TREE_VALUE (inner_list) == name_to_match)
3679             {
3680               next_enclosing = TREE_PURPOSE (inner_list);
3681               break;
3682             }
3683         }
3684       enclosing = next_enclosing;
3685     }
3686
3687   return (!qual && enclosing ? enclosing : NULL_TREE);
3688 }
3689
3690 /* Reach all inner classes and tie their unqualified name to a
3691    DECL. */
3692
3693 static void
3694 set_nested_class_simple_name_value (outer, set)
3695      tree outer;
3696      int set;
3697 {
3698   tree l;
3699
3700   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3701     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3702                                                 TREE_PURPOSE (l) : NULL_TREE);
3703 }
3704
3705 static void
3706 link_nested_class_to_enclosing ()
3707 {
3708   if (GET_ENCLOSING_CPC ())
3709     {
3710       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3711       DECL_INNER_CLASS_LIST (enclosing) = 
3712         tree_cons (GET_CPC (), GET_CPC_UN (),
3713                    DECL_INNER_CLASS_LIST (enclosing));
3714     }
3715 }
3716
3717 static tree
3718 maybe_make_nested_class_name (name)
3719      tree name;
3720 {
3721   tree id = NULL_TREE;
3722
3723   if (CPC_INNER_P ())
3724     {
3725       make_nested_class_name (GET_CPC_LIST ());
3726       obstack_grow0 (&temporary_obstack,
3727                      IDENTIFIER_POINTER (name), 
3728                      IDENTIFIER_LENGTH (name));
3729       id = get_identifier (obstack_finish (&temporary_obstack));
3730       if (ctxp->package)
3731         QUALIFIED_P (id) = 1;
3732     }
3733   return id;
3734 }
3735
3736 /* If DECL is NULL, create and push a new DECL, record the current
3737    line CL and do other maintenance things.  */
3738
3739 static tree
3740 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3741      tree decl, raw_name, qualified_name, cl;
3742 {
3743   if (!decl)
3744     decl = push_class (make_class (), qualified_name);
3745
3746   /* Take care of the file and line business */
3747   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3748   /* If we're emiting xrefs, store the line/col number information */
3749   if (flag_emit_xref)
3750     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3751   else
3752     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3753   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3754   CLASS_PARSED_P (TREE_TYPE (decl)) = 1;
3755   CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) =
3756     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3757
3758   PUSH_CPC (decl, raw_name);
3759   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3760
3761   /* Link the declaration to the already seen ones */
3762   TREE_CHAIN (decl) = ctxp->class_list;
3763   ctxp->class_list = decl;
3764
3765   /* Create a new nodes in the global lists */
3766   gclass_list = tree_cons (NULL_TREE, decl, gclass_list);
3767   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3768
3769   /* Install a new dependency list element */
3770   create_jdep_list (ctxp);
3771
3772   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3773                           IDENTIFIER_POINTER (qualified_name)));
3774   return decl;
3775 }
3776
3777 static void
3778 add_superinterfaces (decl, interface_list)
3779      tree decl, interface_list;
3780 {
3781   tree node;
3782   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3783      takes care of ensuring that:
3784        - This is an accessible interface type,
3785        - Circularity detection.
3786    parser_add_interface is then called. If present but not defined,
3787    the check operation is delayed until the super interface gets
3788    defined.  */
3789   for (node = interface_list; node; node = TREE_CHAIN (node))
3790     {
3791       tree current = TREE_PURPOSE (node);
3792       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3793       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3794         {
3795           if (!parser_check_super_interface (idecl, decl, current))
3796             parser_add_interface (decl, idecl, current);
3797         }
3798       else
3799         register_incomplete_type (JDEP_INTERFACE,
3800                                   current, decl, NULL_TREE);
3801     }
3802 }
3803
3804 /* Create an interface in pass1 and return its decl. Return the
3805    interface's decl in pass 2.  */
3806
3807 static tree
3808 create_interface (flags, id, super)
3809      int flags;
3810      tree id, super;
3811 {
3812   tree raw_name = EXPR_WFL_NODE (id);
3813   tree q_name = parser_qualified_classname (raw_name);
3814   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3815
3816   /* Certain syntax errors are making SUPER be like ID. Avoid this
3817      case. */
3818   if (ctxp->class_err && id == super)
3819     super = NULL;
3820
3821   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3822
3823   /* Basic checks: scope, redefinition, modifiers */ 
3824   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3825     {
3826       PUSH_ERROR ();
3827       return NULL_TREE;
3828     }
3829
3830   /* Suspend the current parsing context if we're parsing an inner
3831      interface */
3832   if (CPC_INNER_P ())
3833     {
3834       java_parser_context_suspend ();
3835       /* Interface members are public. */
3836       if (CLASS_INTERFACE (GET_CPC ()))
3837         flags |= ACC_PUBLIC;
3838     }
3839
3840   /* Push a new context for (static) initialized upon declaration fields */
3841   java_parser_context_push_initialized_field ();
3842
3843   /* Interface modifiers check
3844        - public/abstract allowed (already done at that point)
3845        - abstract is obsolete (comes first, it's a warning, or should be)
3846        - Can't use twice the same (checked in the modifier rule) */
3847   if ((flags & ACC_ABSTRACT) && flag_redundant)
3848     parse_warning_context 
3849       (MODIFIER_WFL (ABSTRACT_TK),
3850        "Redundant use of `abstract' modifier. Interface `%s' is implicitly abstract", IDENTIFIER_POINTER (raw_name));
3851
3852   /* Create a new decl if DECL is NULL, otherwise fix it */
3853   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3854
3855   /* Set super info and mark the class a complete */
3856   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3857                   object_type_node, ctxp->interface_number);
3858   ctxp->interface_number = 0;
3859   CLASS_COMPLETE_P (decl) = 1;
3860   add_superinterfaces (decl, super);
3861
3862   return decl;
3863 }
3864
3865 /* Anonymous class counter. Will be reset to 1 every time a non
3866    anonymous class gets created. */
3867 static int anonymous_class_counter = 1;
3868
3869 /* Patch anonymous class CLASS, by either extending or implementing
3870    DEP.  */
3871
3872 static void
3873 patch_anonymous_class (type_decl, class_decl, wfl)
3874     tree type_decl, class_decl, wfl;
3875 {
3876   tree class = TREE_TYPE (class_decl);
3877   tree type =  TREE_TYPE (type_decl);
3878   tree binfo = TYPE_BINFO (class);
3879
3880   /* If it's an interface, implement it */
3881   if (CLASS_INTERFACE (type_decl))
3882     {
3883       tree s_binfo;
3884       int length;
3885
3886       if (parser_check_super_interface (type_decl, class_decl, wfl))
3887         return;
3888
3889       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3890       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3891       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3892       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3893       /* And add the interface */
3894       parser_add_interface (class_decl, type_decl, wfl);
3895     }
3896   /* Otherwise, it's a type we want to extend */
3897   else
3898     {
3899       if (parser_check_super (type_decl, class_decl, wfl))
3900         return;
3901       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3902     }
3903 }
3904
3905 static tree
3906 create_anonymous_class (location, type_name)
3907     int location;
3908     tree type_name;
3909 {
3910   char buffer [80];
3911   tree super = NULL_TREE, itf = NULL_TREE;
3912   tree id, type_decl, class;
3913
3914   /* The unqualified name of the anonymous class. It's just a number. */
3915   sprintf (buffer, "%d", anonymous_class_counter++);
3916   id = build_wfl_node (get_identifier (buffer));
3917   EXPR_WFL_LINECOL (id) = location;
3918
3919   /* We know about the type to extend/implement. We go ahead */
3920   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3921     {
3922       /* Create a class which either implements on extends the designated
3923          class. The class bears an innacessible name. */
3924       if (CLASS_INTERFACE (type_decl))
3925         {
3926           /* It's OK to modify it here. It's been already used and
3927              shouldn't be reused */
3928           ctxp->interface_number = 1;
3929           /* Interfaces should presented as a list of WFLs */
3930           itf = build_tree_list (type_name, NULL_TREE);
3931         }
3932       else
3933         super = type_name;
3934     }
3935
3936   class = create_class (ACC_FINAL, id, super, itf);
3937
3938   /* We didn't know anything about the stuff. We register a dependence. */
3939   if (!type_decl)
3940     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3941
3942   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3943   return class;
3944 }
3945
3946 /* Create a class in pass1 and return its decl. Return class
3947    interface's decl in pass 2.  */
3948
3949 static tree
3950 create_class (flags, id, super, interfaces)
3951      int flags;
3952      tree id, super, interfaces;
3953 {
3954   tree raw_name = EXPR_WFL_NODE (id);
3955   tree class_id, decl;
3956   tree super_decl_type;
3957
3958   /* Certain syntax errors are making SUPER be like ID. Avoid this
3959      case. */
3960   if (ctxp->class_err && id == super)
3961     super = NULL;
3962
3963   class_id = parser_qualified_classname (raw_name);
3964   decl = IDENTIFIER_CLASS_VALUE (class_id);
3965   EXPR_WFL_NODE (id) = class_id;
3966
3967   /* Basic check: scope, redefinition, modifiers */
3968   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3969     {
3970       PUSH_ERROR ();
3971       return NULL_TREE;
3972     }
3973   
3974   /* Suspend the current parsing context if we're parsing an inner
3975      class or an anonymous class. */
3976   if (CPC_INNER_P ())
3977     {
3978       java_parser_context_suspend ();
3979       /* Interface members are public. */
3980       if (CLASS_INTERFACE (GET_CPC ()))
3981         flags |= ACC_PUBLIC;
3982     }
3983     
3984   /* Push a new context for (static) initialized upon declaration fields */
3985   java_parser_context_push_initialized_field ();
3986
3987   /* Class modifier check: 
3988        - Allowed modifier (already done at that point)
3989        - abstract AND final forbidden 
3990        - Public classes defined in the correct file */
3991   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3992     parse_error_context
3993       (id, "Class `%s' can't be declared both abstract and final",
3994        IDENTIFIER_POINTER (raw_name));
3995
3996   /* Create a new decl if DECL is NULL, otherwise fix it */
3997   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3998
3999   /* If SUPER exists, use it, otherwise use Object */
4000   if (super)
4001     {
4002       /* Can't extend java.lang.Object */
4003       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
4004         {
4005           parse_error_context (id, "Can't extend `java.lang.Object'");
4006           return NULL_TREE;
4007         }
4008
4009       super_decl_type = 
4010         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
4011     }
4012   else if (TREE_TYPE (decl) != object_type_node)
4013     super_decl_type = object_type_node;
4014   /* We're defining java.lang.Object */
4015   else
4016     super_decl_type = NULL_TREE;
4017
4018   /* A class nested in an interface is implicitly static. */
4019   if (INNER_CLASS_DECL_P (decl)
4020       && CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (DECL_CONTEXT (decl)))))
4021     {
4022       flags |= ACC_STATIC;
4023     }
4024
4025   /* Set super info and mark the class as complete. */
4026   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
4027                   ctxp->interface_number);
4028   ctxp->interface_number = 0;
4029   CLASS_COMPLETE_P (decl) = 1;
4030   add_superinterfaces (decl, interfaces);
4031
4032   /* Add the private this$<n> field, Replicate final locals still in
4033      scope as private final fields mangled like val$<local_name>.
4034      This doesn't not occur for top level (static) inner classes. */
4035   if (PURE_INNER_CLASS_DECL_P (decl))
4036     add_inner_class_fields (decl, current_function_decl);
4037
4038   /* If doing xref, store the location at which the inherited class
4039      (if any) was seen. */
4040   if (flag_emit_xref && super)
4041     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
4042
4043   /* Eventually sets the @deprecated tag flag */
4044   CHECK_DEPRECATED (decl);
4045
4046   /* Reset the anonymous class counter when declaring non inner classes */
4047   if (!INNER_CLASS_DECL_P (decl))
4048     anonymous_class_counter = 1;
4049
4050   return decl;
4051 }
4052
4053 /* End a class declaration: register the statements used to create
4054    finit$ and <clinit>, pop the current class and resume the prior
4055    parser context if necessary.  */
4056
4057 static void
4058 end_class_declaration (resume)
4059      int resume;
4060 {
4061   /* If an error occurred, context weren't pushed and won't need to be
4062      popped by a resume. */
4063   int no_error_occurred = ctxp->next && GET_CPC () != error_mark_node;
4064
4065   if (GET_CPC () != error_mark_node)
4066     dump_java_tree (TDI_class, GET_CPC ());
4067
4068   java_parser_context_pop_initialized_field ();
4069   POP_CPC ();
4070   if (resume && no_error_occurred)
4071     java_parser_context_resume ();
4072
4073   /* We're ending a class declaration, this is a good time to reset
4074      the interface cout. Note that might have been already done in
4075      create_interface, but if at that time an inner class was being
4076      dealt with, the interface count was reset in a context created
4077      for the sake of handling inner classes declaration. */
4078   ctxp->interface_number = 0;
4079 }
4080
4081 static void
4082 add_inner_class_fields (class_decl, fct_decl)
4083      tree class_decl;
4084      tree fct_decl;
4085 {
4086   tree block, marker, f;
4087
4088   f = add_field (TREE_TYPE (class_decl),
4089                  build_current_thisn (TREE_TYPE (class_decl)),
4090                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
4091                  ACC_PRIVATE);
4092   FIELD_THISN (f) = 1;
4093
4094   if (!fct_decl)
4095     return;
4096     
4097   for (block = GET_CURRENT_BLOCK (fct_decl); 
4098        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
4099     {
4100       tree decl;
4101       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
4102         {
4103           tree name, pname;
4104           tree wfl, init, list;
4105           
4106           /* Avoid non final arguments. */
4107           if (!LOCAL_FINAL_P (decl))
4108             continue;
4109           
4110           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
4111           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
4112           wfl = build_wfl_node (name);
4113           init = build_wfl_node (pname);
4114           /* Build an initialization for the field: it will be
4115              initialized by a parameter added to finit$, bearing a
4116              mangled name of the field itself (param$<n>.) The
4117              parameter is provided to finit$ by the constructor
4118              invoking it (hence the constructor will also feature a
4119              hidden parameter, set to the value of the outer context
4120              local at the time the inner class is created.)
4121              
4122              Note: we take into account all possible locals that can
4123              be accessed by the inner class. It's actually not trivial
4124              to minimize these aliases down to the ones really
4125              used. One way to do that would be to expand all regular
4126              methods first, then finit$ to get a picture of what's
4127              used.  It works with the exception that we would have to
4128              go back on all constructor invoked in regular methods to
4129              have their invokation reworked (to include the right amount
4130              of alias initializer parameters.)
4131
4132              The only real way around, I think, is a first pass to
4133              identify locals really used in the inner class. We leave
4134              the flag FIELD_LOCAL_ALIAS_USED around for that future
4135              use.
4136              
4137              On the other hand, it only affect local inner classes,
4138              whose constructors (and finit$ call) will be featuring
4139              unecessary arguments. It's easy for a developper to keep
4140              this number of parameter down by using the `final'
4141              keyword only when necessary. For the time being, we can
4142              issue a warning on unecessary finals. FIXME */
4143           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
4144                                    wfl, init);
4145
4146           /* Register the field. The TREE_LIST holding the part
4147              initialized/initializer will be marked ARG_FINAL_P so
4148              that the created field can be marked
4149              FIELD_LOCAL_ALIAS. */
4150           list = build_tree_list (wfl, init);
4151           ARG_FINAL_P (list) = 1;
4152           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
4153         }
4154     }
4155
4156   if (!CPC_INITIALIZER_STMT (ctxp))
4157     return;
4158
4159   /* If we ever registered an alias field, insert and marker to
4160      remeber where the list ends. The second part of the list (the one
4161      featuring initialized fields) so it can be later reversed to
4162      enforce 8.5. The marker will be removed during that operation. */
4163   marker = build_tree_list (NULL_TREE, NULL_TREE);
4164   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
4165   SET_CPC_INITIALIZER_STMT (ctxp, marker);
4166 }
4167
4168 /* Can't use lookup_field () since we don't want to load the class and
4169    can't set the CLASS_LOADED_P flag */
4170
4171 static tree
4172 find_field (class, name)
4173      tree class;
4174      tree name;
4175 {
4176   tree decl;
4177   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
4178     {
4179       if (DECL_NAME (decl) == name)
4180         return decl;
4181     }
4182   return NULL_TREE;
4183 }
4184
4185 /* Wrap around lookup_field that doesn't potentially upset the value
4186    of CLASS */
4187
4188 static tree
4189 lookup_field_wrapper (class, name)
4190      tree class, name;
4191 {
4192   tree type = class;
4193   tree decl = NULL_TREE;
4194   java_parser_context_save_global ();
4195
4196   /* Last chance: if we're within the context of an inner class, we
4197      might be trying to access a local variable defined in an outer
4198      context. We try to look for it now. */
4199   if (INNER_CLASS_TYPE_P (class) && TREE_CODE (name) == IDENTIFIER_NODE)
4200     {
4201       tree new_name;
4202       MANGLE_OUTER_LOCAL_VARIABLE_NAME (new_name, name);
4203       decl = lookup_field (&type, new_name);
4204       if (decl && decl != error_mark_node)
4205         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4206     }
4207   if (!decl || decl == error_mark_node)
4208     {
4209       type = class;
4210       decl = lookup_field (&type, name);
4211     }
4212
4213   /* If the field still hasn't been found, try the next enclosing context. */
4214   if (!decl && INNER_CLASS_TYPE_P (class))
4215     {
4216       tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
4217       decl = lookup_field_wrapper (outer_type, name);
4218     }
4219
4220   java_parser_context_restore_global ();
4221   return decl == error_mark_node ? NULL : decl;
4222 }
4223
4224 /* Find duplicate field within the same class declarations and report
4225    the error. Returns 1 if a duplicated field was found, 0
4226    otherwise.  */
4227
4228 static int
4229 duplicate_declaration_error_p (new_field_name, new_type, cl)
4230      tree new_field_name, new_type, cl;
4231 {
4232   /* This might be modified to work with method decl as well */
4233   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4234   if (decl)
4235     {
4236       char *t1 = xstrdup (purify_type_name
4237                          ((TREE_CODE (new_type) == POINTER_TYPE 
4238                            && TREE_TYPE (new_type) == NULL_TREE) ?
4239                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4240                           lang_printable_name (new_type, 1)));
4241       /* The type may not have been completed by the time we report
4242          the error */
4243       char *t2 = xstrdup (purify_type_name
4244                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4245                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4246                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4247                           lang_printable_name (TREE_TYPE (decl), 1)));
4248       parse_error_context 
4249         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4250          t1, IDENTIFIER_POINTER (new_field_name),
4251          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4252          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4253       free (t1);
4254       free (t2);
4255       return 1;
4256     }
4257   return 0;
4258 }
4259
4260 /* Field registration routine. If TYPE doesn't exist, field
4261    declarations are linked to the undefined TYPE dependency list, to
4262    be later resolved in java_complete_class () */
4263
4264 static void
4265 register_fields (flags, type, variable_list)
4266      int flags;
4267      tree type, variable_list;
4268 {
4269   tree current, saved_type;
4270   tree class_type = NULL_TREE;
4271   int saved_lineno = lineno;
4272   int must_chain = 0;
4273   tree wfl = NULL_TREE;
4274
4275   if (GET_CPC ())
4276     class_type = TREE_TYPE (GET_CPC ());
4277
4278   if (!class_type || class_type == error_mark_node)
4279     return;
4280
4281   /* If we're adding fields to interfaces, those fields are public,
4282      static, final */
4283   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4284     {
4285       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4286                                  flags, ACC_PUBLIC, "interface field(s)");
4287       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4288                                  flags, ACC_STATIC, "interface field(s)");
4289       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4290                                  flags, ACC_FINAL, "interface field(s)");
4291       check_modifiers ("Illegal interface member modifier `%s'", flags,
4292                        INTERFACE_FIELD_MODIFIERS);
4293       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4294     }
4295
4296   /* Obtain a suitable type for resolution, if necessary */
4297   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4298
4299   /* If TYPE is fully resolved and we don't have a reference, make one */
4300   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4301
4302   for (current = variable_list, saved_type = type; current; 
4303        current = TREE_CHAIN (current), type = saved_type)
4304     {
4305       tree real_type;
4306       tree field_decl;
4307       tree cl = TREE_PURPOSE (current);
4308       tree init = TREE_VALUE (current);
4309       tree current_name = EXPR_WFL_NODE (cl);
4310
4311       /* Can't declare non-final static fields in inner classes */
4312       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4313           && !(flags & ACC_FINAL))
4314         parse_error_context 
4315           (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
4316            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4317            lang_printable_name (class_type, 0));
4318
4319       /* Process NAME, as it may specify extra dimension(s) for it */
4320       type = build_array_from_name (type, wfl, current_name, &current_name);
4321
4322       /* Type adjustment. We may have just readjusted TYPE because
4323          the variable specified more dimensions. Make sure we have
4324          a reference if we can and don't have one already. Also
4325          change the name if we have an init. */
4326       if (type != saved_type)
4327         {
4328           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4329           if (init)
4330             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4331         }
4332
4333       real_type = GET_REAL_TYPE (type);
4334       /* Check for redeclarations */
4335       if (duplicate_declaration_error_p (current_name, real_type, cl))
4336         continue;
4337
4338       /* Set lineno to the line the field was found and create a
4339          declaration for it. Eventually sets the @deprecated tag flag. */
4340       if (flag_emit_xref)
4341         lineno = EXPR_WFL_LINECOL (cl);
4342       else
4343         lineno = EXPR_WFL_LINENO (cl);
4344       field_decl = add_field (class_type, current_name, real_type, flags);
4345       CHECK_DEPRECATED (field_decl);
4346
4347       /* If the field denotes a final instance variable, then we
4348          allocate a LANG_DECL_SPECIFIC part to keep track of its
4349          initialization. We also mark whether the field was
4350          initialized upon its declaration. We don't do that if the
4351          created field is an alias to a final local. */
4352       if (!ARG_FINAL_P (current) && (flags & ACC_FINAL))
4353         {
4354           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field_decl);
4355           DECL_FIELD_FINAL_WFL (field_decl) = cl;
4356         }
4357
4358       /* If the couple initializer/initialized is marked ARG_FINAL_P,
4359          we mark the created field FIELD_LOCAL_ALIAS, so that we can
4360          hide parameters to this inner class finit$ and
4361          constructors. It also means that the field isn't final per
4362          say. */
4363       if (ARG_FINAL_P (current))
4364         {
4365           FIELD_LOCAL_ALIAS (field_decl) = 1;
4366           FIELD_FINAL (field_decl) = 0;
4367         }
4368       
4369       /* Check if we must chain. */
4370       if (must_chain)
4371         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4372           
4373       /* If we have an initialization value tied to the field */
4374       if (init)
4375         {
4376           /* The field is declared static */
4377           if (flags & ACC_STATIC)
4378             {
4379               /* We include the field and its initialization part into
4380                  a list used to generate <clinit>. After <clinit> is
4381                  walked, field initializations will be processed and
4382                  fields initialized with known constants will be taken
4383                  out of <clinit> and have their DECL_INITIAL set
4384                  appropriately. */
4385               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4386               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4387               if (TREE_OPERAND (init, 1) 
4388                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4389                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4390             }
4391           /* A non-static field declared with an immediate initialization is
4392              to be initialized in <init>, if any.  This field is remembered
4393              to be processed at the time of the generation of <init>. */
4394           else
4395             {
4396               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4397               SET_CPC_INITIALIZER_STMT (ctxp, init);
4398             }
4399           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4400           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4401         }
4402     }
4403   lineno = saved_lineno;
4404 }
4405
4406 /* Generate finit$, using the list of initialized fields to populate
4407    its body. finit$'s parameter(s) list is adjusted to include the
4408    one(s) used to initialized the field(s) caching outer context
4409    local(s).  */
4410
4411 static tree
4412 generate_finit (class_type)
4413      tree class_type;
4414 {
4415   int count = 0;
4416   tree list = TYPE_FINIT_STMT_LIST (class_type);
4417   tree mdecl, current, parms;
4418
4419   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4420                                                   class_type, NULL_TREE, 
4421                                                   &count);
4422   CRAFTED_PARAM_LIST_FIXUP (parms);
4423   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4424                                     finit_identifier_node, parms);
4425   fix_method_argument_names (parms, mdecl);
4426   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4427                        mdecl, NULL_TREE);
4428   DECL_FUNCTION_NAP (mdecl) = count;
4429   start_artificial_method_body (mdecl);
4430
4431   for (current = list; current; current = TREE_CHAIN (current))
4432     java_method_add_stmt (mdecl, 
4433                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4434                                                 current));
4435   end_artificial_method_body (mdecl);
4436   return mdecl;
4437 }
4438
4439 /* Generate a function to run the instance initialization code. The
4440    private method is called `instinit$'. Unless we're dealing with an
4441    anonymous class, we determine whether all ctors of CLASS_TYPE
4442    declare a checked exception in their `throws' clause in order to
4443    see whether it's necessary to encapsulate the instance initializer
4444    statements in a try/catch/rethrow sequence.  */
4445
4446 static tree
4447 generate_instinit (class_type)
4448      tree class_type;
4449 {
4450   tree current;
4451   tree compound = NULL_TREE;
4452   tree parms = tree_cons (this_identifier_node,
4453                           build_pointer_type (class_type), end_params_node);
4454   tree mdecl = create_artificial_method (class_type, ACC_PRIVATE,
4455                                          void_type_node,
4456                                          instinit_identifier_node, parms);
4457
4458   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4459                        mdecl, NULL_TREE);
4460
4461   /* Gather all the statements in a compound */
4462   for (current = TYPE_II_STMT_LIST (class_type); 
4463        current; current = TREE_CHAIN (current))
4464     compound = add_stmt_to_compound (compound, NULL_TREE, current);
4465
4466   /* We need to encapsulate COMPOUND by a try/catch statement to
4467      rethrow exceptions that might occur in the instance initializer.
4468      We do that only if all ctors of CLASS_TYPE are set to catch a
4469      checked exception. This doesn't apply to anonymous classes (since
4470      they don't have declared ctors.) */
4471   if (!ANONYMOUS_CLASS_P (class_type) && 
4472       ctors_unchecked_throws_clause_p (class_type))
4473     {
4474       compound = encapsulate_with_try_catch (0, exception_type_node, compound, 
4475                                              build1 (THROW_EXPR, NULL_TREE,
4476                                                      build_wfl_node (wpv_id)));
4477       DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
4478                                                       exception_type_node);
4479     }
4480
4481   start_artificial_method_body (mdecl);
4482   java_method_add_stmt (mdecl, compound);
4483   end_artificial_method_body (mdecl);
4484
4485   return mdecl;
4486 }
4487
4488 /* FIXME */
4489 static tree
4490 build_instinit_invocation (class_type)
4491      tree class_type;
4492 {
4493   tree to_return = NULL_TREE;
4494
4495   if (TYPE_II_STMT_LIST (class_type))
4496     {
4497       tree parm = build_tree_list (NULL_TREE,
4498                                    build_wfl_node (this_identifier_node));
4499       to_return =
4500         build_method_invocation (build_wfl_node (instinit_identifier_node),
4501                                  parm);
4502     }
4503   return to_return;
4504 }
4505
4506 /* Shared accros method_declarator and method_header to remember the
4507    patch stage that was reached during the declaration of the method.
4508    A method DECL is built differently is there is no patch
4509    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4510    pending on the currently defined method.  */
4511
4512 static int patch_stage;
4513
4514 /* Check the method declaration and add the method to its current
4515    class.  If the argument list is known to contain incomplete types,
4516    the method is partially added and the registration will be resume
4517    once the method arguments resolved. If TYPE is NULL, we're dealing
4518    with a constructor.  */
4519
4520 static tree
4521 method_header (flags, type, mdecl, throws)
4522      int flags;
4523      tree type, mdecl, throws;
4524 {
4525   tree type_wfl = NULL_TREE;
4526   tree meth_name = NULL_TREE;
4527   tree current, orig_arg, this_class = NULL;
4528   tree id, meth;
4529   int saved_lineno;
4530   int constructor_ok = 0, must_chain;
4531   int count;
4532
4533   if (mdecl == error_mark_node)
4534     return error_mark_node;
4535   meth = TREE_VALUE (mdecl);
4536   id = TREE_PURPOSE (mdecl);
4537   
4538   check_modifiers_consistency (flags);
4539
4540   if (GET_CPC ())
4541     this_class = TREE_TYPE (GET_CPC ());
4542
4543   if (!this_class || this_class == error_mark_node)
4544     return NULL_TREE;
4545   
4546   /* There are some forbidden modifiers for an abstract method and its
4547      class must be abstract as well.  */
4548   if (type && (flags & ACC_ABSTRACT))
4549     {
4550       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4551       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4552       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4553       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4554       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED, id, "Synchronized");
4555       ABSTRACT_CHECK (flags, ACC_STRICT, id, "Strictfp");
4556       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4557           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4558         parse_error_context 
4559           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4560            IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())),
4561            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4562     }
4563
4564   /* Things to be checked when declaring a constructor */
4565   if (!type)
4566     {
4567       int ec = java_error_count;
4568       /* 8.6: Constructor declarations: we might be trying to define a
4569          method without specifying a return type. */
4570       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4571         parse_error_context 
4572           (id, "Invalid method declaration, return type required");
4573       /* 8.6.3: Constructor modifiers */
4574       else
4575         {
4576           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4577           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4578           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4579           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4580           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4581           JCONSTRUCTOR_CHECK (flags, ACC_STRICT, id, "strictfp");
4582         }
4583       /* If we found error here, we don't consider it's OK to tread
4584          the method definition as a constructor, for the rest of this
4585          function */
4586       if (ec == java_error_count)
4587         constructor_ok = 1;
4588     }
4589
4590   /* Method declared within the scope of an interface are implicitly
4591      abstract and public. Conflicts with other erroneously provided
4592      modifiers are checked right after. */
4593
4594   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4595     {
4596       /* If FLAGS isn't set because of a modifier, turn the
4597          corresponding modifier WFL to NULL so we issue a warning on
4598          the obsolete use of the modifier */
4599       if (!(flags & ACC_PUBLIC))
4600         MODIFIER_WFL (PUBLIC_TK) = NULL;
4601       if (!(flags & ACC_ABSTRACT))
4602         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4603       flags |= ACC_PUBLIC;
4604       flags |= ACC_ABSTRACT;
4605     }
4606
4607   /* Inner class can't declare static methods */
4608   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4609     {
4610       parse_error_context 
4611         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4612          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4613          lang_printable_name (this_class, 0));
4614     }
4615
4616   /* Modifiers context reset moved up, so abstract method declaration
4617      modifiers can be later checked.  */
4618
4619   /* Set constructor returned type to void and method name to <init>,
4620      unless we found an error identifier the constructor (in which
4621      case we retain the original name) */
4622   if (!type)
4623     {
4624       type = void_type_node;
4625       if (constructor_ok)
4626         meth_name = init_identifier_node;
4627     }
4628   else
4629     meth_name = EXPR_WFL_NODE (id);
4630
4631   /* Do the returned type resolution and registration if necessary */
4632   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4633
4634   if (meth_name)
4635     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4636   EXPR_WFL_NODE (id) = meth_name;
4637   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4638
4639   if (must_chain)
4640     {
4641       patch_stage = JDEP_METHOD_RETURN;
4642       register_incomplete_type (patch_stage, type_wfl, id, type);
4643       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4644     }
4645   else
4646     TREE_TYPE (meth) = type;
4647
4648   saved_lineno = lineno;
4649   /* When defining an abstract or interface method, the curly
4650      bracket at level 1 doesn't exist because there is no function
4651      body */
4652   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4653             EXPR_WFL_LINENO (id));
4654
4655   /* Remember the original argument list */
4656   orig_arg = TYPE_ARG_TYPES (meth);
4657
4658   if (patch_stage)              /* includes ret type and/or all args */
4659     {
4660       jdep *jdep;
4661       meth = add_method_1 (this_class, flags, meth_name, meth);
4662       /* Patch for the return type */
4663       if (patch_stage == JDEP_METHOD_RETURN)
4664         {
4665           jdep = CLASSD_LAST (ctxp->classd_list);
4666           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4667         }
4668       /* This is the stop JDEP. METH allows the function's signature
4669          to be computed. */
4670       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4671     }
4672   else
4673     meth = add_method (this_class, flags, meth_name, 
4674                        build_java_signature (meth));
4675
4676   /* Remember final parameters */
4677   MARK_FINAL_PARMS (meth, orig_arg);
4678
4679   /* Fix the method argument list so we have the argument name
4680      information */
4681   fix_method_argument_names (orig_arg, meth);
4682
4683   /* Register the parameter number and re-install the current line
4684      number */
4685   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4686   lineno = saved_lineno;
4687
4688   /* Register exception specified by the `throws' keyword for
4689      resolution and set the method decl appropriate field to the list.
4690      Note: the grammar ensures that what we get here are class
4691      types. */
4692   if (throws)
4693     {
4694       throws = nreverse (throws);
4695       for (current = throws; current; current = TREE_CHAIN (current))
4696         {
4697           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4698                                     NULL_TREE, NULL_TREE);
4699           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4700             &TREE_VALUE (current);
4701         }
4702       DECL_FUNCTION_THROWS (meth) = throws;
4703     }
4704
4705   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4706     DECL_FUNCTION_WFL (meth) = id;
4707
4708   /* Set the flag if we correctly processed a constructor */
4709   if (constructor_ok)
4710     {
4711       DECL_CONSTRUCTOR_P (meth) = 1;
4712       /* Compute and store the number of artificial parameters declared
4713          for this constructor */
4714       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4715            current = TREE_CHAIN (current))
4716         if (FIELD_LOCAL_ALIAS (current))
4717           count++;
4718       DECL_FUNCTION_NAP (meth) = count;
4719     }
4720
4721   /* Eventually set the @deprecated tag flag */
4722   CHECK_DEPRECATED (meth);
4723
4724   /* If doing xref, store column and line number information instead
4725      of the line number only. */
4726   if (flag_emit_xref)
4727     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4728
4729   return meth;
4730 }
4731
4732 static void
4733 fix_method_argument_names (orig_arg, meth)
4734     tree orig_arg, meth;
4735 {
4736   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4737   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4738     {
4739       TREE_PURPOSE (arg) = this_identifier_node;
4740       arg = TREE_CHAIN (arg);
4741     }
4742   while (orig_arg != end_params_node)
4743     {
4744       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4745       orig_arg = TREE_CHAIN (orig_arg);
4746       arg = TREE_CHAIN (arg);
4747     }
4748 }
4749
4750 /* Complete the method declaration with METHOD_BODY.  */
4751
4752 static void
4753 finish_method_declaration (method_body)
4754      tree method_body;
4755 {
4756   int flags;
4757
4758   if (!current_function_decl)
4759     return;
4760
4761   flags = get_access_flags_from_decl (current_function_decl);
4762
4763   /* 8.4.5 Method Body */
4764   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4765     {
4766       tree name = DECL_NAME (current_function_decl);
4767       parse_error_context (DECL_FUNCTION_WFL (current_function_decl), 
4768                            "%s method `%s' can't have a body defined",
4769                            (METHOD_NATIVE (current_function_decl) ?
4770                             "Native" : "Abstract"),
4771                            IDENTIFIER_POINTER (name));
4772       method_body = NULL_TREE;
4773     }
4774   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4775     {
4776       tree name = DECL_NAME (current_function_decl);
4777       parse_error_context
4778         (DECL_FUNCTION_WFL (current_function_decl), 
4779          "Non native and non abstract method `%s' must have a body defined",
4780          IDENTIFIER_POINTER (name));
4781       method_body = NULL_TREE;
4782     }
4783
4784   if (flag_emit_class_files && method_body 
4785       && TREE_CODE (method_body) == NOP_EXPR 
4786       && TREE_TYPE (current_function_decl) 
4787       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4788     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4789
4790   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4791   maybe_absorb_scoping_blocks ();
4792   /* Exit function's body */
4793   exit_block ();
4794   /* Merge last line of the function with first line, directly in the
4795      function decl. It will be used to emit correct debug info. */
4796   if (!flag_emit_xref)
4797     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4798
4799   /* Since function's argument's list are shared, reset the
4800      ARG_FINAL_P parameter that might have been set on some of this
4801      function parameters. */
4802   UNMARK_FINAL_PARMS (current_function_decl);
4803   
4804   /* So we don't have an irrelevant function declaration context for
4805      the next static block we'll see. */
4806   current_function_decl = NULL_TREE;
4807 }
4808
4809 /* Build a an error message for constructor circularity errors.  */
4810
4811 static char *
4812 constructor_circularity_msg (from, to)
4813      tree from, to;
4814 {
4815   static char string [4096];
4816   char *t = xstrdup (lang_printable_name (from, 0));
4817   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4818   free (t);
4819   return string;
4820 }
4821
4822 /* Verify a circular call to METH. Return 1 if an error is found, 0
4823    otherwise.  */
4824
4825 static int
4826 verify_constructor_circularity (meth, current)
4827      tree meth, current;
4828 {
4829   static tree list = NULL_TREE;
4830   static int initialized_p;
4831   tree c;
4832
4833   /* If we haven't already registered LIST with the garbage collector,
4834      do so now.  */
4835   if (!initialized_p)
4836     {
4837       ggc_add_tree_root (&list, 1);
4838       initialized_p = 1;
4839     }
4840
4841   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4842     {
4843       if (TREE_VALUE (c) == meth)
4844         {
4845           char *t;
4846           if (list)
4847             {
4848               tree liste;
4849               list = nreverse (list);
4850               for (liste = list; liste; liste = TREE_CHAIN (liste))
4851                 {
4852                   parse_error_context 
4853                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4854                      constructor_circularity_msg
4855                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4856                   java_error_count--;
4857                 }
4858             }
4859           t = xstrdup (lang_printable_name (meth, 0));
4860           parse_error_context (TREE_PURPOSE (c), 
4861                                "%s: recursive invocation of constructor `%s'",
4862                                constructor_circularity_msg (current, meth), t);
4863           free (t);
4864           list = NULL_TREE;
4865           return 1;
4866         }
4867     }
4868   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4869     {
4870       list = tree_cons (c, current, list);
4871       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4872         return 1;
4873       list = TREE_CHAIN (list);
4874     }
4875   return 0;
4876 }
4877
4878 /* Check modifiers that can be declared but exclusively */
4879
4880 static void
4881 check_modifiers_consistency (flags)
4882      int flags;
4883 {
4884   int acc_count = 0;
4885   tree cl = NULL_TREE;
4886
4887   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4888   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4889   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4890   if (acc_count > 1)
4891     parse_error_context
4892       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4893
4894   acc_count = 0;
4895   cl = NULL_TREE;
4896   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
4897   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
4898   if (acc_count > 1)
4899     parse_error_context (cl,
4900                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4901 }
4902
4903 /* Check the methode header METH for abstract specifics features */
4904
4905 static void
4906 check_abstract_method_header (meth)
4907      tree meth;
4908 {
4909   int flags = get_access_flags_from_decl (meth);
4910
4911   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4912                               ACC_ABSTRACT, "abstract method",
4913                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4914   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4915                               ACC_PUBLIC, "abstract method",
4916                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4917
4918   check_modifiers ("Illegal modifier `%s' for interface method",
4919                   flags, INTERFACE_METHOD_MODIFIERS);
4920 }
4921
4922 /* Create a FUNCTION_TYPE node and start augmenting it with the
4923    declared function arguments. Arguments type that can't be resolved
4924    are left as they are, but the returned node is marked as containing
4925    incomplete types.  */
4926
4927 static tree
4928 method_declarator (id, list)
4929      tree id, list;
4930 {
4931   tree arg_types = NULL_TREE, current, node;
4932   tree meth = make_node (FUNCTION_TYPE);
4933   jdep *jdep;
4934
4935   patch_stage = JDEP_NO_PATCH;
4936
4937   if (GET_CPC () == error_mark_node)
4938     return error_mark_node;
4939
4940   /* If we're dealing with an inner class constructor, we hide the
4941      this$<n> decl in the name field of its parameter declaration.  We
4942      also might have to hide the outer context local alias
4943      initializers. Not done when the class is a toplevel class. */
4944   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4945       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4946     {
4947       tree aliases_list, type, thisn;
4948       /* First the aliases, linked to the regular parameters */
4949       aliases_list =
4950         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4951                                                 TREE_TYPE (GET_CPC ()),
4952                                                 NULL_TREE, NULL);
4953       list = chainon (nreverse (aliases_list), list);
4954
4955       /* Then this$<n> */
4956       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4957       thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
4958       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4959                         list);
4960     }
4961   
4962   for (current = list; current; current = TREE_CHAIN (current))
4963     {
4964       int must_chain = 0;
4965       tree wfl_name = TREE_PURPOSE (current);
4966       tree type = TREE_VALUE (current);
4967       tree name = EXPR_WFL_NODE (wfl_name);
4968       tree already, arg_node;
4969       tree type_wfl = NULL_TREE;
4970       tree real_type;
4971
4972       /* Obtain a suitable type for resolution, if necessary */
4973       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4974
4975       /* Process NAME, as it may specify extra dimension(s) for it */
4976       type = build_array_from_name (type, type_wfl, name, &name);
4977       EXPR_WFL_NODE (wfl_name) = name;
4978
4979       real_type = GET_REAL_TYPE (type);
4980       if (TREE_CODE (real_type) == RECORD_TYPE)
4981         {
4982           real_type = promote_type (real_type);
4983           if (TREE_CODE (type) == TREE_LIST)
4984             TREE_PURPOSE (type) = real_type;
4985         }
4986
4987       /* Check redefinition */
4988       for (already = arg_types; already; already = TREE_CHAIN (already))
4989         if (TREE_PURPOSE (already) == name)
4990           {
4991             parse_error_context
4992               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4993                IDENTIFIER_POINTER (name),
4994                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4995             break;
4996           }
4997
4998       /* If we've an incomplete argument type, we know there is a location
4999          to patch when the type get resolved, later.  */
5000       jdep = NULL;
5001       if (must_chain)
5002         {
5003           patch_stage = JDEP_METHOD;
5004           type = register_incomplete_type (patch_stage, 
5005                                            type_wfl, wfl_name, type);
5006           jdep = CLASSD_LAST (ctxp->classd_list);
5007           JDEP_MISC (jdep) = id;
5008         }
5009
5010       /* The argument node: a name and a (possibly) incomplete type.  */
5011       arg_node = build_tree_list (name, real_type);
5012       /* Remeber arguments declared final. */
5013       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
5014       
5015       if (jdep)
5016         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
5017       TREE_CHAIN (arg_node) = arg_types;
5018       arg_types = arg_node;
5019     }
5020   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
5021   node = build_tree_list (id, meth);
5022   return node;
5023 }
5024
5025 static int
5026 unresolved_type_p (wfl, returned)
5027      tree wfl;
5028      tree *returned;
5029      
5030 {
5031   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
5032     {
5033       if (returned)
5034         {
5035           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
5036           if (decl && current_class && (decl == TYPE_NAME (current_class)))
5037             *returned = TREE_TYPE (decl);
5038           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
5039             *returned = TREE_TYPE (GET_CPC ());
5040           else
5041             *returned = NULL_TREE;
5042         }
5043       return 1;
5044     }
5045   if (returned)
5046     *returned = wfl;
5047   return 0;
5048 }
5049
5050 /* From NAME, build a qualified identifier node using the
5051    qualification from the current package definition. */
5052
5053 static tree
5054 parser_qualified_classname (name)
5055      tree name;
5056 {
5057   tree nested_class_name;
5058
5059   if ((nested_class_name = maybe_make_nested_class_name (name)))
5060     return nested_class_name;
5061
5062   if (ctxp->package)
5063     return merge_qualified_name (ctxp->package, name);
5064   else 
5065     return name;
5066 }
5067
5068 /* Called once the type a interface extends is resolved. Returns 0 if
5069    everything is OK.  */
5070
5071 static int
5072 parser_check_super_interface (super_decl, this_decl, this_wfl)
5073      tree super_decl, this_decl, this_wfl;
5074 {
5075   tree super_type = TREE_TYPE (super_decl);
5076
5077   /* Has to be an interface */
5078   if (!CLASS_INTERFACE (super_decl))
5079     {
5080       parse_error_context 
5081         (this_wfl, "%s `%s' can't implement/extend %s `%s'",
5082          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
5083           "Interface" : "Class"),
5084          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5085          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
5086          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
5087       return 1;
5088     }
5089
5090   /* Check top-level interface access. Inner classes are subject to member 
5091      access rules (6.6.1). */
5092   if (! INNER_CLASS_P (super_type)
5093       && check_pkg_class_access (DECL_NAME (super_decl),
5094                                  lookup_cl (this_decl), true))
5095     return 1;
5096
5097   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
5098                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5099                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
5100   return 0;
5101 }
5102
5103 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
5104    0 if everthing is OK.  */
5105
5106 static int
5107 parser_check_super (super_decl, this_decl, wfl)
5108      tree super_decl, this_decl, wfl;
5109 {
5110   tree super_type = TREE_TYPE (super_decl);
5111
5112   /* SUPER should be a CLASS (neither an array nor an interface) */
5113   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
5114     {
5115       parse_error_context 
5116         (wfl, "Class `%s' can't subclass %s `%s'",
5117          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5118          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
5119          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
5120       return 1;
5121     }
5122
5123   if (CLASS_FINAL (TYPE_NAME (super_type)))
5124     {
5125       parse_error_context (wfl, "Can't subclass final classes: %s",
5126                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
5127       return 1;
5128     }
5129
5130   /* Check top-level class scope. Inner classes are subject to member access
5131      rules (6.6.1). */
5132   if (! INNER_CLASS_P (super_type)
5133       && (check_pkg_class_access (DECL_NAME (super_decl), wfl, true)))
5134     return 1;
5135   
5136   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
5137                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
5138                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
5139   return 0;
5140 }
5141
5142 /* Create a new dependency list and link it (in a LIFO manner) to the
5143    CTXP list of type dependency list.  */
5144
5145 static void
5146 create_jdep_list (ctxp)
5147      struct parser_ctxt *ctxp;
5148 {
5149   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
5150   new->first = new->last = NULL;
5151   new->next = ctxp->classd_list;
5152   ctxp->classd_list = new;
5153 }
5154
5155 static jdeplist *
5156 reverse_jdep_list (ctxp)
5157      struct parser_ctxt *ctxp;
5158 {
5159   register jdeplist *prev = NULL, *current, *next;
5160   for (current = ctxp->classd_list; current; current = next)
5161     {
5162       next = current->next;
5163       current->next = prev;
5164       prev = current;
5165     }
5166   return prev;
5167 }
5168
5169 /* Create a fake pointer based on the ID stored in
5170    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
5171    registered again. */
5172
5173 static tree
5174 obtain_incomplete_type (type_name)
5175      tree type_name;
5176 {
5177   tree ptr = NULL_TREE, name;
5178
5179   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
5180     name = EXPR_WFL_NODE (type_name);
5181   else if (INCOMPLETE_TYPE_P (type_name))
5182     name = TYPE_NAME (type_name);
5183   else
5184     abort ();
5185
5186   BUILD_PTR_FROM_NAME (ptr, name);
5187   layout_type (ptr);
5188
5189   return ptr;
5190 }
5191
5192 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
5193    non NULL instead of computing a new fake type based on WFL. The new
5194    dependency is inserted in the current type dependency list, in FIFO
5195    manner.  */
5196
5197 static tree
5198 register_incomplete_type (kind, wfl, decl, ptr)
5199      int kind;
5200      tree wfl, decl, ptr;
5201 {
5202   jdep *new = (jdep *)xmalloc (sizeof (jdep));
5203
5204   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
5205     ptr = obtain_incomplete_type (wfl);
5206
5207   JDEP_KIND (new) = kind;
5208   JDEP_DECL (new) = decl;
5209   JDEP_TO_RESOLVE (new) = ptr;
5210   JDEP_WFL (new) = wfl;
5211   JDEP_CHAIN (new) = NULL;
5212   JDEP_MISC (new) = NULL_TREE;
5213   /* For some dependencies, set the enclosing class of the current
5214      class to be the enclosing context */
5215   if ((kind == JDEP_INTERFACE  || kind == JDEP_ANONYMOUS)
5216       && GET_ENCLOSING_CPC ())
5217     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
5218   else if (kind == JDEP_SUPER)
5219     JDEP_ENCLOSING (new) = (GET_ENCLOSING_CPC () ? 
5220                             TREE_VALUE (GET_ENCLOSING_CPC ()) : NULL_TREE);
5221   else
5222     JDEP_ENCLOSING (new) = GET_CPC ();
5223   JDEP_GET_PATCH (new) = (tree *)NULL;
5224
5225   JDEP_INSERT (ctxp->classd_list, new);
5226
5227   return ptr;
5228 }
5229
5230 /* This checks for circular references with innerclasses. We start
5231    from SOURCE and should never reach TARGET. Extended/implemented
5232    types in SOURCE have their enclosing context checked not to reach
5233    TARGET. When the last enclosing context of SOURCE is reached, its
5234    extended/implemented types are also checked not to reach TARGET.
5235    In case of error, WFL of the offending type is returned; NULL_TREE
5236    otherwise.  */
5237
5238 static tree
5239 check_inner_circular_reference (source, target)
5240      tree source;
5241      tree target;
5242 {
5243   tree basetype_vec = TYPE_BINFO_BASETYPES (source);
5244   tree ctx, cl;
5245   int i;
5246
5247   if (!basetype_vec)
5248     return NULL_TREE;
5249
5250   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
5251     {
5252       tree su;
5253
5254       /* We can end up with a NULL_TREE or an incomplete type here if
5255          we encountered previous type resolution errors. It's safe to
5256          simply ignore these cases.  */
5257       if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
5258         continue;
5259       su = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
5260       if (INCOMPLETE_TYPE_P (su))
5261         continue;
5262
5263       if (inherits_from_p (su, target))
5264         return lookup_cl (TYPE_NAME (su));
5265
5266       for (ctx = DECL_CONTEXT (TYPE_NAME (su)); ctx; ctx = DECL_CONTEXT (ctx))
5267         {
5268           /* An enclosing context shouldn't be TARGET */
5269           if (ctx == TYPE_NAME (target))
5270             return lookup_cl (TYPE_NAME (su));
5271
5272           /* When we reach the enclosing last context, start a check
5273              on it, with the same target */
5274           if (! DECL_CONTEXT (ctx) &&
5275               (cl = check_inner_circular_reference (TREE_TYPE (ctx), target)))
5276             return cl;
5277         }
5278     }
5279   return NULL_TREE;
5280 }
5281
5282 /* Explore TYPE's `extends' clause member(s) and return the WFL of the
5283    offending type if a circularity is detected. NULL_TREE is returned
5284    otherwise. TYPE can be an interface or a class.   */
5285
5286 static tree
5287 check_circular_reference (type)
5288      tree type;
5289 {
5290   tree basetype_vec = TYPE_BINFO_BASETYPES (type);
5291   int i;
5292
5293   if (!basetype_vec)
5294     return NULL_TREE;
5295
5296   if (! CLASS_INTERFACE (TYPE_NAME (type)))
5297     {
5298       if (inherits_from_p (CLASSTYPE_SUPER (type), type))
5299         return lookup_cl (TYPE_NAME (type));
5300       return NULL_TREE;
5301     }
5302     
5303   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
5304     {
5305       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
5306       if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node
5307           && interface_of_p (type, BINFO_TYPE (vec_elt)))
5308         return lookup_cl (TYPE_NAME (BINFO_TYPE (vec_elt)));
5309     }
5310   return NULL_TREE;
5311 }
5312
5313 void
5314 java_check_circular_reference ()
5315 {
5316   tree current;
5317   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5318     {
5319       tree type = TREE_TYPE (current);
5320       tree cl;
5321
5322       cl = check_circular_reference (type);
5323       if (! cl)
5324         cl = check_inner_circular_reference (type, type);
5325       if (cl)
5326         parse_error_context (cl, "Cyclic class inheritance%s",
5327                              (cyclic_inheritance_report ?
5328                               cyclic_inheritance_report : ""));
5329     }
5330 }
5331
5332 /* Augment the parameter list PARM with parameters crafted to
5333    initialize outer context locals aliases. Through ARTIFICIAL, a
5334    count is kept of the number of crafted parameters. MODE governs
5335    what eventually gets created: something suitable for a function
5336    creation or a function invocation, either the constructor or
5337    finit$.  */
5338
5339 static tree
5340 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
5341     int mode;
5342     tree class_type, parm;
5343     int *artificial;
5344 {
5345   tree field;
5346   tree additional_parms = NULL_TREE;
5347
5348   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5349     if (FIELD_LOCAL_ALIAS (field))
5350       {
5351         const char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5352         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5353         tree mangled_id;
5354
5355         switch (mode)
5356           {
5357           case AIPL_FUNCTION_DECLARATION:
5358             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5359                                                          &buffer [4]);
5360             purpose = build_wfl_node (mangled_id);
5361             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5362               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5363             else
5364               value = TREE_TYPE (field);
5365             break;
5366
5367           case AIPL_FUNCTION_CREATION:
5368             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (purpose,
5369                                                          &buffer [4]);
5370             value = TREE_TYPE (field);
5371             break;
5372
5373           case AIPL_FUNCTION_FINIT_INVOCATION:
5374             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5375                                                          &buffer [4]);
5376             /* Now, this is wrong. purpose should always be the NAME
5377                of something and value its matching value (decl, type,
5378                etc...) FIXME -- but there is a lot to fix. */
5379
5380             /* When invoked for this kind of operation, we already
5381                know whether a field is used or not. */
5382             purpose = TREE_TYPE (field);
5383             value = build_wfl_node (mangled_id);
5384             break;
5385
5386           case AIPL_FUNCTION_CTOR_INVOCATION:
5387             /* There are two case: the constructor invokation happends
5388                outside the local inner, in which case, locales from the outer
5389                context are directly used.
5390
5391                Otherwise, we fold to using the alias directly. */
5392             if (class_type == current_class)
5393               value = field;
5394             else
5395               {
5396                 name = get_identifier (&buffer[4]);
5397                 value = IDENTIFIER_LOCAL_VALUE (name);
5398               }
5399             break;
5400           }
5401         additional_parms = tree_cons (purpose, value, additional_parms);
5402         if (artificial)
5403           *artificial +=1;
5404       }
5405   if (additional_parms)
5406     {
5407       if (ANONYMOUS_CLASS_P (class_type) 
5408           && mode == AIPL_FUNCTION_CTOR_INVOCATION)
5409         additional_parms = nreverse (additional_parms);
5410       parm = chainon (additional_parms, parm);
5411     }
5412
5413    return parm;
5414 }
5415
5416 /* Craft a constructor for CLASS_DECL -- what we should do when none
5417    where found. ARGS is non NULL when a special signature must be
5418    enforced. This is the case for anonymous classes.  */
5419
5420 static tree
5421 craft_constructor (class_decl, args)
5422      tree class_decl, args;
5423 {
5424   tree class_type = TREE_TYPE (class_decl);
5425   tree parm = NULL_TREE;
5426   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5427                ACC_PUBLIC : 0);
5428   int i = 0, artificial = 0;
5429   tree decl, ctor_name;
5430   char buffer [80];
5431   
5432   /* The constructor name is <init> unless we're dealing with an
5433      anonymous class, in which case the name will be fixed after having
5434      be expanded. */
5435   if (ANONYMOUS_CLASS_P (class_type))
5436     ctor_name = DECL_NAME (class_decl);
5437   else
5438     ctor_name = init_identifier_node;
5439
5440   /* If we're dealing with an inner class constructor, we hide the
5441      this$<n> decl in the name field of its parameter declaration. */
5442   if (PURE_INNER_CLASS_TYPE_P (class_type))
5443     {
5444       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5445       parm = tree_cons (build_current_thisn (class_type),
5446                         build_pointer_type (type), parm);
5447
5448       /* Some more arguments to be hidden here. The values of the local
5449          variables of the outer context that the inner class needs to see. */
5450       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5451                                                      class_type, parm, 
5452                                                      &artificial);
5453     }
5454
5455   /* Then if there are any args to be enforced, enforce them now */
5456   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5457     {
5458       sprintf (buffer, "parm%d", i++);
5459       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5460     }
5461
5462   CRAFTED_PARAM_LIST_FIXUP (parm);
5463   decl = create_artificial_method (class_type, flags, void_type_node, 
5464                                    ctor_name, parm);
5465   fix_method_argument_names (parm, decl);
5466   /* Now, mark the artificial parameters. */
5467   DECL_FUNCTION_NAP (decl) = artificial;
5468   DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
5469   return decl;
5470 }
5471
5472
5473 /* Fix the constructors. This will be called right after circular
5474    references have been checked. It is necessary to fix constructors
5475    early even if no code generation will take place for that class:
5476    some generated constructor might be required by the class whose
5477    compilation triggered this one to be simply loaded.  */
5478
5479 void
5480 java_fix_constructors ()
5481 {
5482   tree current;
5483
5484   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5485     {
5486       tree class_type = TREE_TYPE (current);
5487       int saw_ctor = 0;
5488       tree decl;
5489
5490       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5491         continue;
5492
5493       current_class = class_type;
5494       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5495         {
5496           if (DECL_CONSTRUCTOR_P (decl))
5497             {
5498               fix_constructors (decl);
5499               saw_ctor = 1;
5500             }
5501         }
5502
5503       /* Anonymous class constructor can't be generated that early. */
5504       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5505         craft_constructor (current, NULL_TREE);
5506     }
5507 }
5508
5509 /* safe_layout_class just makes sure that we can load a class without
5510    disrupting the current_class, input_file, lineno, etc, information
5511    about the class processed currently.  */
5512
5513 void
5514 safe_layout_class (class)
5515      tree class;
5516 {
5517   tree save_current_class = current_class;
5518   const char *save_input_filename = input_filename;
5519   int save_lineno = lineno;
5520
5521   layout_class (class);
5522
5523   current_class = save_current_class;
5524   input_filename = save_input_filename;
5525   lineno = save_lineno;
5526 }
5527
5528 static tree
5529 jdep_resolve_class (dep)
5530      jdep *dep;
5531 {
5532   tree decl;
5533
5534   if (JDEP_RESOLVED_P (dep))
5535     decl = JDEP_RESOLVED_DECL (dep);
5536   else
5537     {
5538       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5539                             JDEP_DECL (dep), JDEP_WFL (dep));
5540       JDEP_RESOLVED (dep, decl);
5541     }
5542     
5543   if (!decl)
5544     complete_class_report_errors (dep);
5545   else if (PURE_INNER_CLASS_DECL_P (decl))
5546     {
5547       tree inner = TREE_TYPE (decl);
5548       if (! CLASS_LOADED_P (inner))
5549         {
5550           safe_layout_class (inner);
5551           if (TYPE_SIZE (inner) == error_mark_node)
5552             TYPE_SIZE (inner) = NULL_TREE;
5553         }
5554       check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
5555     }
5556   return decl;
5557 }
5558
5559 /* Complete unsatisfied class declaration and their dependencies */
5560
5561 void
5562 java_complete_class ()
5563 {
5564   tree cclass;
5565   jdeplist *cclassd;
5566   int error_found;
5567   tree type;
5568
5569   /* Process imports */
5570   process_imports ();
5571
5572   /* Rever things so we have the right order */
5573   ctxp->class_list = nreverse (ctxp->class_list);
5574   ctxp->classd_list = reverse_jdep_list (ctxp);
5575
5576   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5577        cclass && cclassd; 
5578        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5579     {
5580       jdep *dep;
5581
5582       /* We keep the compilation unit imports in the class so that
5583          they can be used later to resolve type dependencies that
5584          aren't necessary to solve now. */
5585       TYPE_IMPORT_LIST (TREE_TYPE (cclass)) = ctxp->import_list;
5586       TYPE_IMPORT_DEMAND_LIST (TREE_TYPE (cclass)) = ctxp->import_demand_list;
5587
5588       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5589         {
5590           tree decl;
5591           if (!(decl = jdep_resolve_class (dep)))
5592             continue;
5593
5594           /* Now it's time to patch */
5595           switch (JDEP_KIND (dep))
5596             {
5597             case JDEP_SUPER:
5598               /* Simply patch super */
5599               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5600                 continue;
5601               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5602                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5603               break;
5604
5605             case JDEP_FIELD:
5606               {
5607                 /* We do part of the job done in add_field */
5608                 tree field_decl = JDEP_DECL (dep);
5609                 tree field_type = TREE_TYPE (decl);
5610                 if (TREE_CODE (field_type) == RECORD_TYPE)
5611                   field_type = promote_type (field_type);
5612                 TREE_TYPE (field_decl) = field_type;
5613                 DECL_ALIGN (field_decl) = 0;
5614                 DECL_USER_ALIGN (field_decl) = 0;
5615                 layout_decl (field_decl, 0);
5616                 SOURCE_FRONTEND_DEBUG 
5617                   (("Completed field/var decl `%s' with `%s'",
5618                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5619                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5620                 break;
5621               }
5622             case JDEP_METHOD:   /* We start patching a method */
5623             case JDEP_METHOD_RETURN:
5624               error_found = 0;
5625               while (1)
5626                 {
5627                   if (decl)
5628                     {
5629                       type = TREE_TYPE(decl);
5630                       if (TREE_CODE (type) == RECORD_TYPE)
5631                         type = promote_type (type);
5632                       JDEP_APPLY_PATCH (dep, type);
5633                       SOURCE_FRONTEND_DEBUG 
5634                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5635                            "Completing fct `%s' with ret type `%s'":
5636                            "Completing arg `%s' with type `%s'"),
5637                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5638                                               (JDEP_DECL_WFL (dep))),
5639                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5640                     }
5641                   else
5642                     error_found = 1;
5643                   dep = JDEP_CHAIN (dep);
5644                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5645                     break;
5646                   else
5647                     decl = jdep_resolve_class (dep);
5648                 }
5649               if (!error_found)
5650                 {
5651                   tree mdecl = JDEP_DECL (dep), signature;
5652                   /* Recompute and reset the signature, check first that
5653                      all types are now defined. If they're not,
5654                      don't build the signature. */
5655                   if (check_method_types_complete (mdecl))
5656                     {
5657                       signature = build_java_signature (TREE_TYPE (mdecl));
5658                       set_java_signature (TREE_TYPE (mdecl), signature);
5659                     }
5660                 }
5661               else
5662                 continue;
5663               break;
5664
5665             case JDEP_INTERFACE:
5666               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5667                                                 JDEP_WFL (dep)))
5668                 continue;
5669               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5670               break;
5671
5672             case JDEP_PARM:
5673             case JDEP_VARIABLE:
5674               type = TREE_TYPE(decl);
5675               if (TREE_CODE (type) == RECORD_TYPE)
5676                 type = promote_type (type);
5677               JDEP_APPLY_PATCH (dep, type);
5678               break;
5679
5680             case JDEP_TYPE:
5681               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5682               SOURCE_FRONTEND_DEBUG 
5683                 (("Completing a random type dependency on a '%s' node",
5684                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5685               break;
5686
5687             case JDEP_EXCEPTION:
5688               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5689               SOURCE_FRONTEND_DEBUG 
5690                 (("Completing `%s' `throws' argument node",
5691                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5692               break;
5693
5694             case JDEP_ANONYMOUS:
5695               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5696               break;
5697
5698             default:
5699               abort ();
5700             }
5701         }
5702     }
5703   return;
5704 }
5705
5706 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5707    array.  */
5708
5709 static tree
5710 resolve_class (enclosing, class_type, decl, cl)
5711      tree enclosing, class_type, decl, cl;
5712 {
5713   tree tname = TYPE_NAME (class_type);
5714   tree resolved_type = TREE_TYPE (class_type);
5715   int array_dims = 0;
5716   tree resolved_type_decl;
5717   
5718   if (resolved_type != NULL_TREE)
5719     {
5720       tree resolved_type_decl = TYPE_NAME (resolved_type);
5721       if (resolved_type_decl == NULL_TREE
5722           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5723         {
5724           resolved_type_decl = build_decl (TYPE_DECL,
5725                                            TYPE_NAME (class_type),
5726                                            resolved_type);
5727         }
5728       return resolved_type_decl;
5729     }
5730
5731   /* 1- Check to see if we have an array. If true, find what we really
5732      want to resolve  */
5733   if ((array_dims = build_type_name_from_array_name (tname,
5734                                                      &TYPE_NAME (class_type))))
5735     WFL_STRIP_BRACKET (cl, cl);
5736
5737   /* 2- Resolve the bare type */
5738   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5739                                                decl, cl)))
5740     return NULL_TREE;
5741   resolved_type = TREE_TYPE (resolved_type_decl);
5742
5743   /* 3- If we have and array, reconstruct the array down to its nesting */
5744   if (array_dims)
5745     {
5746       for (; array_dims; array_dims--)
5747         resolved_type = build_java_array_type (resolved_type, -1);
5748       resolved_type_decl = TYPE_NAME (resolved_type);
5749     }
5750   TREE_TYPE (class_type) = resolved_type;
5751   return resolved_type_decl;
5752 }
5753
5754 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5755    are used to report error messages. Do not try to replace TYPE_NAME
5756    (class_type) by a variable, since it is changed by
5757    find_in_imports{_on_demand} and (but it doesn't really matter)
5758    qualify_and_find.  */
5759
5760 tree
5761 do_resolve_class (enclosing, class_type, decl, cl)
5762      tree enclosing, class_type, decl, cl;
5763 {
5764   tree new_class_decl = NULL_TREE, super = NULL_TREE;
5765   tree saved_enclosing_type = enclosing ? TREE_TYPE (enclosing) : NULL_TREE;
5766   tree decl_result;
5767   struct hash_table _ht, *circularity_hash = &_ht;
5768
5769   /* This hash table is used to register the classes we're going
5770      through when searching the current class as an inner class, in
5771      order to detect circular references. Remember to free it before
5772      returning the section 0- of this function. */
5773   hash_table_init (circularity_hash, hash_newfunc,
5774                    java_hash_hash_tree_node, java_hash_compare_tree_node);
5775
5776   /* 0- Search in the current class as an inner class.
5777      Maybe some code here should be added to load the class or
5778      something, at least if the class isn't an inner class and ended
5779      being loaded from class file. FIXME. */
5780   while (enclosing)
5781     {
5782       new_class_decl = resolve_inner_class (circularity_hash, cl, &enclosing,
5783                                             &super, class_type);
5784       if (new_class_decl)
5785         break;
5786
5787       /* If we haven't found anything because SUPER reached Object and
5788          ENCLOSING happens to be an innerclass, try the enclosing context. */
5789       if ((!super || super == object_type_node) && 
5790           enclosing && INNER_CLASS_DECL_P (enclosing))
5791         enclosing = DECL_CONTEXT (enclosing);
5792       else
5793         enclosing = NULL_TREE;
5794     }
5795
5796   hash_table_free (circularity_hash);
5797
5798   if (new_class_decl)
5799     return new_class_decl;
5800
5801   /* 1- Check for the type in single imports. This will change
5802      TYPE_NAME() if something relevant is found */
5803   find_in_imports (saved_enclosing_type, class_type);
5804
5805   /* 2- And check for the type in the current compilation unit */
5806   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5807     {
5808       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5809           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5810         load_class (TYPE_NAME (class_type), 0);
5811       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5812     }
5813
5814   /* 3- Search according to the current package definition */
5815   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5816     {
5817       if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
5818                                              TYPE_NAME (class_type))))
5819         return new_class_decl;
5820     }
5821
5822   /* 4- Check the import on demands. Don't allow bar.baz to be
5823      imported from foo.* */
5824   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5825     if (find_in_imports_on_demand (saved_enclosing_type, class_type))
5826       return NULL_TREE;
5827
5828   /* If found in find_in_imports_on_demant, the type has already been
5829      loaded. */
5830   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5831     return new_class_decl;
5832
5833   /* 5- Try with a name qualified with the package name we've seen so far */
5834   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5835     {
5836       tree package;
5837
5838       /* If there is a current package (ctxp->package), it's the first
5839          element of package_list and we can skip it. */
5840       for (package = (ctxp->package ? 
5841                       TREE_CHAIN (package_list) : package_list);
5842            package; package = TREE_CHAIN (package))
5843         if ((new_class_decl = qualify_and_find (class_type,
5844                                                TREE_PURPOSE (package), 
5845                                                TYPE_NAME (class_type))))
5846           return new_class_decl;
5847     }
5848
5849   /* 5- Check an other compilation unit that bears the name of type */
5850   load_class (TYPE_NAME (class_type), 0);
5851   
5852   if (!cl)
5853     cl = lookup_cl (decl);
5854   
5855   /* If we don't have a value for CL, then we're being called recursively. 
5856      We can't check package access just yet, but it will be taken care of
5857      by the caller. */
5858   if (cl)
5859     {
5860       if (check_pkg_class_access (TYPE_NAME (class_type), cl, true))
5861         return NULL_TREE;
5862     }
5863
5864   /* 6- Last call for a resolution */
5865   decl_result = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5866
5867   /* The final lookup might have registered a.b.c into a.b$c If we
5868      failed at the first lookup, progressively change the name if
5869      applicable and use the matching DECL instead. */
5870   if (!decl_result && QUALIFIED_P (TYPE_NAME (class_type)))
5871     {
5872       char *separator;
5873       tree name = TYPE_NAME (class_type);
5874       char *namebuffer = alloca (IDENTIFIER_LENGTH (name) + 1);
5875
5876       strcpy (namebuffer, IDENTIFIER_POINTER (name));
5877
5878       do {
5879
5880        /* Reach the last '.', and if applicable, replace it by a `$' and
5881           see if this exists as a type. */
5882        if ((separator = strrchr (namebuffer, '.')))
5883          {
5884            *separator = '$';
5885            name = get_identifier (namebuffer);
5886            decl_result = IDENTIFIER_CLASS_VALUE (name);
5887          }
5888       } while (!decl_result && separator);
5889     }
5890   return decl_result;
5891 }
5892
5893 static tree
5894 qualify_and_find (class_type, package, name)
5895      tree class_type, package, name;
5896 {
5897   tree new_qualified = merge_qualified_name (package, name);
5898   tree new_class_decl;
5899
5900   if (!IDENTIFIER_CLASS_VALUE (new_qualified))
5901     load_class (new_qualified, 0);
5902   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
5903     {
5904       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5905           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5906         load_class (new_qualified, 0);
5907       TYPE_NAME (class_type) = new_qualified;
5908       return IDENTIFIER_CLASS_VALUE (new_qualified);
5909     }
5910   return NULL_TREE;
5911 }
5912
5913 /* Resolve NAME and lay it out (if not done and if not the current
5914    parsed class). Return a decl node. This function is meant to be
5915    called when type resolution is necessary during the walk pass.  */
5916
5917 static tree
5918 resolve_and_layout (something, cl)
5919      tree something;
5920      tree cl;
5921 {
5922   tree decl, decl_type;
5923
5924   /* Don't do that on the current class */
5925   if (something == current_class)
5926     return TYPE_NAME (current_class);
5927
5928   /* Don't do anything for void and other primitive types */
5929   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5930     return NULL_TREE;
5931
5932   /* Pointer types can be reall pointer types or fake pointers. When
5933      finding a real pointer, recheck for primitive types */
5934   if (TREE_CODE (something) == POINTER_TYPE)
5935     {
5936       if (TREE_TYPE (something))
5937         {
5938           something = TREE_TYPE (something);
5939           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5940             return NULL_TREE;
5941         }
5942       else
5943         something = TYPE_NAME (something);
5944     }
5945
5946   /* Don't do anything for arrays of primitive types */
5947   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5948       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5949     return NULL_TREE;
5950
5951   /* Something might be a WFL */
5952   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5953     something = EXPR_WFL_NODE (something);
5954
5955   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5956      TYPE_DECL or a real TYPE */
5957   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5958     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5959             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5960
5961   if (!(decl = resolve_no_layout (something, cl)))
5962     return NULL_TREE;
5963
5964   /* Resolve and layout if necessary */
5965   decl_type = TREE_TYPE (decl);
5966   layout_class_methods (decl_type);
5967   /* Check methods */
5968   if (CLASS_FROM_SOURCE_P (decl_type))
5969     java_check_methods (decl);
5970   /* Layout the type if necessary */ 
5971   if (decl_type != current_class && !CLASS_LOADED_P (decl_type))
5972     safe_layout_class (decl_type);
5973
5974   return decl;
5975 }
5976
5977 /* Resolve a class, returns its decl but doesn't perform any
5978    layout. The current parsing context is saved and restored */
5979
5980 static tree
5981 resolve_no_layout (name, cl)
5982      tree name, cl;
5983 {
5984   tree ptr, decl;
5985   BUILD_PTR_FROM_NAME (ptr, name);
5986   java_parser_context_save_global ();
5987   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5988   java_parser_context_restore_global ();
5989   
5990   return decl;
5991 }
5992
5993 /* Called when reporting errors. Skip the '[]'s in a complex array
5994    type description that failed to be resolved. purify_type_name can't
5995    use an identifier tree.  */
5996
5997 static const char *
5998 purify_type_name (name)
5999      const char *name;
6000 {
6001   int len = strlen (name);
6002   int bracket_found;
6003
6004   STRING_STRIP_BRACKETS (name, len, bracket_found);
6005   if (bracket_found)
6006     {
6007       char *stripped_name = xmemdup (name, len, len+1);
6008       stripped_name [len] = '\0';
6009       return stripped_name;
6010     }
6011   return name;
6012 }
6013
6014 /* The type CURRENT refers to can't be found. We print error messages.  */
6015
6016 static void
6017 complete_class_report_errors (dep)
6018      jdep *dep;
6019 {
6020   const char *name;
6021
6022   if (!JDEP_WFL (dep))
6023     return;
6024
6025   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
6026   switch (JDEP_KIND (dep))
6027     {
6028     case JDEP_SUPER:
6029       parse_error_context  
6030         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
6031          purify_type_name (name),
6032          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6033       break;
6034     case JDEP_FIELD:
6035       parse_error_context
6036         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
6037          purify_type_name (name),
6038          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6039       break;
6040     case JDEP_METHOD:           /* Covers arguments */
6041       parse_error_context
6042         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
6043          purify_type_name (name),
6044          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
6045          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
6046       break;
6047     case JDEP_METHOD_RETURN:    /* Covers return type */
6048       parse_error_context
6049         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
6050          purify_type_name (name),
6051          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
6052       break;
6053     case JDEP_INTERFACE:
6054       parse_error_context
6055         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
6056          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
6057          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
6058          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6059       break;
6060     case JDEP_VARIABLE:
6061       parse_error_context
6062         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
6063          purify_type_name (IDENTIFIER_POINTER 
6064                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
6065          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
6066       break;
6067     case JDEP_EXCEPTION:        /* As specified by `throws' */
6068       parse_error_context 
6069           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
6070          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
6071       break;
6072     default:
6073       /* Fix for -Wall. Just break doing nothing. The error will be
6074          caught later */
6075       break;
6076     }
6077 }
6078
6079 /* Return a static string containing the DECL prototype string. If
6080    DECL is a constructor, use the class name instead of the form
6081    <init> */
6082
6083 static const char *
6084 get_printable_method_name (decl)
6085      tree decl;
6086 {
6087   const char *to_return;
6088   tree name = NULL_TREE;
6089
6090   if (DECL_CONSTRUCTOR_P (decl))
6091     {
6092       name = DECL_NAME (decl);
6093       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
6094     }
6095       
6096   to_return = lang_printable_name (decl, 0);
6097   if (DECL_CONSTRUCTOR_P (decl))
6098     DECL_NAME (decl) = name;
6099   
6100   return to_return;
6101 }
6102
6103 /* Track method being redefined inside the same class. As a side
6104    effect, set DECL_NAME to an IDENTIFIER (prior entering this
6105    function it's a FWL, so we can track errors more accurately.)  */
6106
6107 static int
6108 check_method_redefinition (class, method)
6109      tree class, method;
6110 {
6111   tree redef, sig;
6112
6113   /* There's no need to verify <clinit> and finit$ and instinit$ */
6114   if (DECL_CLINIT_P (method)
6115       || DECL_FINIT_P (method) || DECL_INSTINIT_P (method))
6116     return 0;
6117
6118   sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
6119   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
6120     {
6121       if (redef == method)
6122         break;
6123       if (DECL_NAME (redef) == DECL_NAME (method)
6124           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef))
6125           && !DECL_ARTIFICIAL (method))
6126         {
6127           parse_error_context 
6128             (DECL_FUNCTION_WFL (method), "Duplicate %s declaration `%s'",
6129              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
6130              get_printable_method_name (redef));
6131           return 1;
6132         }
6133     }
6134   return 0;
6135 }
6136
6137 /* Return 1 if check went ok, 0 otherwise.  */
6138 static int
6139 check_abstract_method_definitions (do_interface, class_decl, type)
6140      int do_interface;
6141      tree class_decl, type;
6142 {
6143   tree class = TREE_TYPE (class_decl);
6144   tree method, end_type;
6145   int ok = 1;
6146
6147   end_type = (do_interface ? object_type_node : type);
6148   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
6149     {
6150       tree other_super, other_method, method_sig, method_name;
6151       int found = 0;
6152       int end_type_reached = 0;
6153       
6154       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
6155         continue;
6156       
6157       /* Now verify that somewhere in between TYPE and CLASS,
6158          abstract method METHOD gets a non abstract definition
6159          that is inherited by CLASS.  */
6160       
6161       method_sig = build_java_signature (TREE_TYPE (method));
6162       method_name = DECL_NAME (method);
6163       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
6164         method_name = EXPR_WFL_NODE (method_name);
6165
6166       other_super = class;
6167       do {
6168         if (other_super == end_type)
6169           end_type_reached = 1;
6170         
6171         /* Method search */
6172         for (other_method = TYPE_METHODS (other_super); other_method;
6173             other_method = TREE_CHAIN (other_method))
6174           {
6175             tree s = build_java_signature (TREE_TYPE (other_method));
6176             tree other_name = DECL_NAME (other_method);
6177             
6178             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
6179               other_name = EXPR_WFL_NODE (other_name);
6180             if (!DECL_CLINIT_P (other_method)
6181                 && !DECL_CONSTRUCTOR_P (other_method)
6182                 && method_name == other_name
6183                 && method_sig == s
6184                 && !METHOD_ABSTRACT (other_method))
6185              {
6186                found = 1;
6187                break;
6188              }
6189           }
6190         other_super = CLASSTYPE_SUPER (other_super);
6191       } while (!end_type_reached);
6192  
6193       /* Report that abstract METHOD didn't find an implementation
6194          that CLASS can use. */
6195       if (!found)
6196         {
6197           char *t = xstrdup (lang_printable_name 
6198                             (TREE_TYPE (TREE_TYPE (method)), 0));
6199           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
6200           
6201           parse_error_context 
6202             (lookup_cl (class_decl),
6203              "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",
6204              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6205              t, lang_printable_name (method, 0), 
6206              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
6207               "interface" : "class"),
6208              IDENTIFIER_POINTER (ccn),
6209              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
6210              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
6211           ok = 0;
6212           free (t);
6213         }
6214     }
6215
6216   if (ok && do_interface)
6217     {
6218       /* Check for implemented interfaces. */
6219       int i;
6220       tree vector = TYPE_BINFO_BASETYPES (type);
6221       for (i = 1; ok && vector && i < TREE_VEC_LENGTH (vector); i++)
6222         {
6223           tree super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
6224           ok = check_abstract_method_definitions (1, class_decl, super);
6225         }
6226     }
6227
6228   return ok;
6229 }
6230
6231 /* Check that CLASS_DECL somehow implements all inherited abstract
6232    methods.  */
6233
6234 static void
6235 java_check_abstract_method_definitions (class_decl)
6236      tree class_decl;
6237 {
6238   tree class = TREE_TYPE (class_decl);
6239   tree super, vector;
6240   int i;
6241
6242   if (CLASS_ABSTRACT (class_decl))
6243     return;
6244
6245   /* Check for inherited types */
6246   super = class;
6247   do {
6248     super = CLASSTYPE_SUPER (super);
6249     check_abstract_method_definitions (0, class_decl, super);
6250   } while (super != object_type_node);
6251
6252   /* Check for implemented interfaces. */
6253   vector = TYPE_BINFO_BASETYPES (class);
6254   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
6255     {
6256       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
6257       check_abstract_method_definitions (1, class_decl, super);
6258     }
6259 }
6260
6261 /* Check all the types method DECL uses and return 1 if all of them
6262    are now complete, 0 otherwise. This is used to check whether its
6263    safe to build a method signature or not.  */
6264
6265 static int
6266 check_method_types_complete (decl)
6267      tree decl;
6268 {
6269   tree type = TREE_TYPE (decl);
6270   tree args;
6271
6272   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
6273     return 0;
6274   
6275   args = TYPE_ARG_TYPES (type);
6276   if (TREE_CODE (type) == METHOD_TYPE)
6277     args = TREE_CHAIN (args);
6278   for (; args != end_params_node; args = TREE_CHAIN (args))
6279     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
6280       return 0;
6281
6282   return 1;
6283 }
6284
6285 /* Visible interface to check methods contained in CLASS_DECL */
6286
6287 void
6288 java_check_methods (class_decl)
6289      tree class_decl;
6290 {
6291   if (CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)))
6292     return;
6293
6294   if (CLASS_INTERFACE (class_decl))
6295     java_check_abstract_methods (class_decl);
6296   else
6297     java_check_regular_methods (class_decl);
6298   
6299   CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)) = 1;
6300 }
6301
6302 /* Check all the methods of CLASS_DECL. Methods are first completed
6303    then checked according to regular method existence rules.  If no
6304    constructor for CLASS_DECL were encountered, then build its
6305    declaration.  */
6306
6307 static void
6308 java_check_regular_methods (class_decl)
6309      tree class_decl;
6310 {
6311   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
6312   tree method;
6313   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
6314   tree found = NULL_TREE;
6315   tree mthrows;
6316
6317   /* It is not necessary to check methods defined in java.lang.Object */
6318   if (class == object_type_node)
6319     return;
6320
6321   if (!TYPE_NVIRTUALS (class))
6322     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6323
6324   /* Should take interfaces into account. FIXME */
6325   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
6326     {
6327       tree sig;
6328       tree method_wfl = DECL_FUNCTION_WFL (method);
6329       int aflags;
6330
6331       /* Check for redefinitions */
6332       if (check_method_redefinition (class, method))
6333         continue;
6334
6335       /* If we see one constructor a mark so we don't generate the
6336          default one. Also skip other verifications: constructors
6337          can't be inherited hence hiden or overriden */
6338      if (DECL_CONSTRUCTOR_P (method))
6339        {
6340          saw_constructor = 1;
6341          continue;
6342        }
6343
6344       /* We verify things thrown by the method. They must inherits from
6345          java.lang.Throwable */
6346       for (mthrows = DECL_FUNCTION_THROWS (method);
6347            mthrows; mthrows = TREE_CHAIN (mthrows))
6348         {
6349           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
6350             parse_error_context 
6351               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
6352                IDENTIFIER_POINTER 
6353                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
6354         }
6355
6356       sig = build_java_argument_signature (TREE_TYPE (method));
6357       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
6358
6359       /* Inner class can't declare static methods */
6360       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
6361         {
6362           char *t = xstrdup (lang_printable_name (class, 0));
6363           parse_error_context 
6364             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
6365              lang_printable_name (method, 0), t);
6366           free (t);
6367         }
6368
6369       /* Nothing overrides or it's a private method. */
6370       if (!found)
6371         continue;
6372       if (METHOD_PRIVATE (found))
6373         {
6374           found = NULL_TREE;
6375           continue;
6376         }
6377
6378       /* If `found' is declared in an interface, make sure the
6379          modifier matches. */
6380       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6381           && clinit_identifier_node != DECL_NAME (found)
6382           && !METHOD_PUBLIC (method))
6383         {
6384           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6385           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6386                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6387                                lang_printable_name (method, 0),
6388                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6389         }
6390
6391       /* Can't override a method with the same name and different return
6392          types. */
6393       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6394         {
6395           char *t = xstrdup 
6396             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6397           parse_error_context 
6398             (method_wfl,
6399              "Method `%s' was defined with return type `%s' in class `%s'", 
6400              lang_printable_name (found, 0), t,
6401              IDENTIFIER_POINTER 
6402                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6403           free (t);
6404         }
6405
6406       aflags = get_access_flags_from_decl (found);
6407
6408       /* Can't override final. Can't override static. */
6409       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6410         {
6411           /* Static *can* override static */
6412           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6413             continue;
6414           parse_error_context 
6415             (method_wfl,
6416              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6417              (METHOD_FINAL (found) ? "Final" : "Static"),
6418              lang_printable_name (found, 0),
6419              (METHOD_FINAL (found) ? "final" : "static"),
6420              IDENTIFIER_POINTER
6421                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6422           continue;
6423         }
6424
6425       /* Static method can't override instance method. */
6426       if (METHOD_STATIC (method))
6427         {
6428           parse_error_context 
6429             (method_wfl,
6430              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6431              lang_printable_name (found, 0),
6432              IDENTIFIER_POINTER
6433                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6434           continue;
6435         }
6436
6437       /* - Overriding/hiding public must be public
6438          - Overriding/hiding protected must be protected or public
6439          - If the overriden or hidden method has default (package)
6440            access, then the overriding or hiding method must not be
6441            private; otherwise, a compile-time error occurs.  If
6442            `found' belongs to an interface, things have been already
6443            taken care of.  */
6444       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6445           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6446               || (METHOD_PROTECTED (found) 
6447                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6448               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6449                   && METHOD_PRIVATE (method))))
6450         {
6451           parse_error_context 
6452             (method_wfl,
6453              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6454              (METHOD_PUBLIC (method) ? "public" : 
6455               (METHOD_PRIVATE (method) ? "private" : "protected")),
6456              IDENTIFIER_POINTER (DECL_NAME 
6457                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6458           continue;
6459         }
6460
6461       /* Overriding methods must have compatible `throws' clauses on checked
6462          exceptions, if any */
6463       check_throws_clauses (method, method_wfl, found);
6464
6465       /* Inheriting multiple methods with the same signature. FIXME */
6466     }
6467   
6468   if (!TYPE_NVIRTUALS (class))
6469     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6470
6471   /* Search for inherited abstract method not yet implemented in this
6472      class.  */
6473   java_check_abstract_method_definitions (class_decl);
6474
6475   if (!saw_constructor)
6476     abort ();
6477 }
6478
6479 /* Return a non zero value if the `throws' clause of METHOD (if any)
6480    is incompatible with the `throws' clause of FOUND (if any).  */
6481
6482 static void
6483 check_throws_clauses (method, method_wfl, found)
6484      tree method, method_wfl, found;
6485 {
6486   tree mthrows, fthrows;
6487
6488   /* Can't check these things with class loaded from bytecode. FIXME */
6489   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6490     return;
6491
6492   for (mthrows = DECL_FUNCTION_THROWS (method);
6493        mthrows; mthrows = TREE_CHAIN (mthrows))
6494     {
6495       /* We don't verify unchecked expressions */
6496       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6497         continue;
6498       /* Checked expression must be compatible */
6499       for (fthrows = DECL_FUNCTION_THROWS (found); 
6500            fthrows; fthrows = TREE_CHAIN (fthrows))
6501         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6502           break;
6503       if (!fthrows)
6504         {
6505           parse_error_context 
6506             (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'",
6507              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6508              lang_printable_name (found, 0),
6509              IDENTIFIER_POINTER 
6510                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6511         }
6512     }
6513 }
6514
6515 /* Check abstract method of interface INTERFACE */
6516
6517 static void
6518 java_check_abstract_methods (interface_decl)
6519      tree interface_decl;
6520 {
6521   int i, n;
6522   tree method, basetype_vec, found;
6523   tree interface = TREE_TYPE (interface_decl);
6524
6525   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6526     {
6527       /* 2- Check for double definition inside the defining interface */
6528       if (check_method_redefinition (interface, method))
6529         continue;
6530
6531       /* 3- Overriding is OK as far as we preserve the return type and
6532          the thrown exceptions (FIXME) */
6533       found = lookup_java_interface_method2 (interface, method);
6534       if (found)
6535         {
6536           char *t;
6537           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6538           parse_error_context 
6539             (DECL_FUNCTION_WFL (found),
6540              "Method `%s' was defined with return type `%s' in class `%s'",
6541              lang_printable_name (found, 0), t,
6542              IDENTIFIER_POINTER 
6543                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6544           free (t);
6545           continue;
6546         }
6547     }
6548
6549   /* 4- Inherited methods can't differ by their returned types */
6550   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6551     return;
6552   n = TREE_VEC_LENGTH (basetype_vec);
6553   for (i = 0; i < n; i++)
6554     {
6555       tree sub_interface_method, sub_interface;
6556       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6557       if (!vec_elt)
6558         continue;
6559       sub_interface = BINFO_TYPE (vec_elt);
6560       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6561            sub_interface_method;
6562            sub_interface_method = TREE_CHAIN (sub_interface_method))
6563         {
6564           found = lookup_java_interface_method2 (interface, 
6565                                                  sub_interface_method);
6566           if (found && (found != sub_interface_method))
6567             {
6568               parse_error_context 
6569                 (lookup_cl (sub_interface_method),
6570                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6571                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6572                  lang_printable_name (found, 0),
6573                  IDENTIFIER_POINTER 
6574                    (DECL_NAME (TYPE_NAME 
6575                                (DECL_CONTEXT (sub_interface_method)))),
6576                  IDENTIFIER_POINTER 
6577                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6578             }
6579         }
6580     }
6581 }
6582
6583 /* Lookup methods in interfaces using their name and partial
6584    signature. Return a matching method only if their types differ.  */
6585
6586 static tree
6587 lookup_java_interface_method2 (class, method_decl)
6588      tree class, method_decl;
6589 {
6590   int i, n;
6591   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6592
6593   if (!basetype_vec)
6594     return NULL_TREE;
6595
6596   n = TREE_VEC_LENGTH (basetype_vec);
6597   for (i = 0; i < n; i++)
6598     {
6599       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6600       if ((BINFO_TYPE (vec_elt) != object_type_node)
6601           && (to_return = 
6602               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6603         return to_return;
6604     }
6605   for (i = 0; i < n; i++)
6606     {
6607       to_return = lookup_java_interface_method2 
6608         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6609       if (to_return)
6610         return to_return;
6611     }
6612
6613   return NULL_TREE;
6614 }
6615
6616 /* Lookup method using their name and partial signature. Return a
6617    matching method only if their types differ.  */
6618
6619 static tree
6620 lookup_java_method2 (clas, method_decl, do_interface)
6621      tree clas, method_decl;
6622      int do_interface;
6623 {
6624   tree method, method_signature, method_name, method_type, name;
6625
6626   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6627   name = DECL_NAME (method_decl);
6628   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6629                  EXPR_WFL_NODE (name) : name);
6630   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6631
6632   while (clas != NULL_TREE)
6633     {
6634       for (method = TYPE_METHODS (clas);
6635            method != NULL_TREE;  method = TREE_CHAIN (method))
6636         {
6637           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6638           tree name = DECL_NAME (method);
6639           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6640                EXPR_WFL_NODE (name) : name) == method_name
6641               && method_sig == method_signature 
6642               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6643             return method;
6644         }
6645       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6646     }
6647   return NULL_TREE;
6648 }
6649
6650 /* Return the line that matches DECL line number, and try its best to
6651    position the column number. Used during error reports.  */
6652
6653 static tree
6654 lookup_cl (decl)
6655      tree decl;
6656 {
6657   static tree cl = NULL_TREE;
6658   char *line, *found;
6659   
6660   if (!decl)
6661     return NULL_TREE;
6662
6663   if (cl == NULL_TREE)
6664     {
6665       cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6666       ggc_add_tree_root (&cl, 1);
6667     }
6668
6669   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6670   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6671
6672   line = java_get_line_col (EXPR_WFL_FILENAME (cl), 
6673                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6674
6675   found = strstr ((const char *)line, 
6676                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6677   if (found)
6678     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6679
6680   return cl;
6681 }
6682
6683 /* Look for a simple name in the single-type import list */
6684
6685 static tree
6686 find_name_in_single_imports (name)
6687      tree name;
6688 {
6689   tree node;
6690
6691   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6692     if (TREE_VALUE (node) == name)
6693       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6694
6695   return NULL_TREE;
6696 }
6697
6698 /* Process all single-type import. */
6699
6700 static int
6701 process_imports ()
6702 {
6703   tree import;
6704   int error_found;
6705
6706   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6707     {
6708       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6709       char *original_name;
6710
6711       obstack_grow0 (&temporary_obstack,
6712                      IDENTIFIER_POINTER (to_be_found),
6713                      IDENTIFIER_LENGTH (to_be_found));
6714       original_name = obstack_finish (&temporary_obstack);
6715
6716       /* Don't load twice something already defined. */
6717       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6718         continue;
6719       
6720       while (1)
6721         {
6722           tree left;
6723
6724           QUALIFIED_P (to_be_found) = 1;
6725           load_class (to_be_found, 0);
6726           error_found =
6727             check_pkg_class_access (to_be_found, TREE_PURPOSE (import), true);
6728           
6729           /* We found it, we can bail out */
6730           if (IDENTIFIER_CLASS_VALUE (to_be_found))
6731             break;
6732
6733           /* We haven't found it. Maybe we're trying to access an
6734              inner class.  The only way for us to know is to try again
6735              after having dropped a qualifier. If we can't break it further,
6736              we have an error. */
6737           if (breakdown_qualified (&left, NULL, to_be_found))
6738             break;
6739
6740           to_be_found = left;
6741         }
6742       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6743         {
6744           parse_error_context (TREE_PURPOSE (import),
6745                                "Class or interface `%s' not found in import",
6746                                original_name);
6747           error_found = 1;
6748         }
6749
6750       obstack_free (&temporary_obstack, original_name);
6751       if (error_found)
6752         return 1;
6753     }
6754   return 0;
6755 }
6756
6757 /* Possibly find and mark a class imported by a single-type import
6758    statement.  */
6759
6760 static void
6761 find_in_imports (enclosing_type, class_type)
6762      tree enclosing_type;
6763      tree class_type;
6764 {
6765   tree import = (enclosing_type ? TYPE_IMPORT_LIST (enclosing_type) : 
6766                  ctxp->import_list);
6767   while (import)
6768     {
6769       if (TREE_VALUE (import) == TYPE_NAME (class_type))
6770         {
6771           TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6772           QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6773           return;
6774         }
6775       import = TREE_CHAIN (import);
6776     }
6777 }
6778
6779 static int
6780 note_possible_classname (name, len)
6781      const char *name;
6782      int len;
6783 {
6784   tree node;
6785   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6786     len = len - 5;
6787   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6788     len = len - 6;
6789   else
6790     return 0;
6791   node = ident_subst (name, len, "", '/', '.', "");
6792   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6793   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6794   return 1;
6795 }
6796
6797 /* Read a import directory, gathering potential match for further type
6798    references. Indifferently reads a filesystem or a ZIP archive
6799    directory.  */
6800
6801 static void
6802 read_import_dir (wfl)
6803      tree wfl;
6804 {
6805   tree package_id = EXPR_WFL_NODE (wfl);
6806   const char *package_name = IDENTIFIER_POINTER (package_id);
6807   int package_length = IDENTIFIER_LENGTH (package_id);
6808   DIR *dirp = NULL;
6809   JCF *saved_jcf = current_jcf;
6810
6811   int found = 0;
6812   int k;
6813   void *entry;
6814   struct buffer filename[1];
6815
6816   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6817     return;
6818   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6819
6820   BUFFER_INIT (filename);
6821   buffer_grow (filename, package_length + 100);
6822
6823   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6824     {
6825       const char *entry_name = jcf_path_name (entry);
6826       int entry_length = strlen (entry_name);
6827       if (jcf_path_is_zipfile (entry))
6828         {
6829           ZipFile *zipf;
6830           buffer_grow (filename, entry_length);
6831           memcpy (filename->data, entry_name, entry_length - 1);
6832           filename->data[entry_length-1] = '\0';
6833           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6834           if (zipf == NULL)
6835             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6836           else
6837             {
6838               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6839               BUFFER_RESET (filename);
6840               for (k = 0; k < package_length; k++)
6841                 {
6842                   char ch = package_name[k];
6843                   *filename->ptr++ = ch == '.' ? '/' : ch;
6844                 }
6845               *filename->ptr++ = '/';
6846
6847               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6848                 {
6849                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6850                   int current_entry_len = zipd->filename_length;
6851
6852                   if (current_entry_len >= BUFFER_LENGTH (filename)
6853                       && strncmp (filename->data, current_entry, 
6854                                   BUFFER_LENGTH (filename)) != 0)
6855                     continue;
6856                   found |= note_possible_classname (current_entry,
6857                                                     current_entry_len);
6858                 }
6859             }
6860         }
6861       else
6862         {
6863           BUFFER_RESET (filename);
6864           buffer_grow (filename, entry_length + package_length + 4);
6865           strcpy (filename->data, entry_name);
6866           filename->ptr = filename->data + entry_length;
6867           for (k = 0; k < package_length; k++)
6868             {
6869               char ch = package_name[k];
6870               *filename->ptr++ = ch == '.' ? '/' : ch;
6871             }
6872           *filename->ptr = '\0';
6873
6874           dirp = opendir (filename->data);
6875           if (dirp == NULL)
6876             continue;
6877           *filename->ptr++ = '/';
6878           for (;;)
6879             {
6880               int len; 
6881               const char *d_name;
6882               struct dirent *direntp = readdir (dirp);
6883               if (!direntp)
6884                 break;
6885               d_name = direntp->d_name;
6886               len = strlen (direntp->d_name);
6887               buffer_grow (filename, len+1);
6888               strcpy (filename->ptr, d_name);
6889               found |= note_possible_classname (filename->data + entry_length,
6890                                                 package_length+len+1);
6891             }
6892           if (dirp)
6893             closedir (dirp);
6894         }
6895     }
6896
6897   free (filename->data);
6898
6899   /* Here we should have a unified way of retrieving an entry, to be
6900      indexed. */
6901   if (!found)
6902     {
6903       static int first = 1;
6904       if (first)
6905         {
6906           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives", package_name);
6907           java_error_count++;
6908           first = 0;
6909         }
6910       else
6911         parse_error_context (wfl, "Package `%s' not found in import",
6912                              package_name);
6913       current_jcf = saved_jcf;
6914       return;
6915     }
6916   current_jcf = saved_jcf;
6917 }
6918
6919 /* Possibly find a type in the import on demands specified
6920    types. Returns 1 if an error occurred, 0 otherwise. Run through the
6921    entire list, to detected potential double definitions.  */
6922                  
6923 static int
6924 find_in_imports_on_demand (enclosing_type, class_type)
6925      tree enclosing_type;
6926      tree class_type;
6927 {
6928   tree class_type_name = TYPE_NAME (class_type);
6929   tree import = (enclosing_type ? TYPE_IMPORT_DEMAND_LIST (enclosing_type) :
6930                   ctxp->import_demand_list);
6931   tree cl = NULL_TREE;
6932   int seen_once = -1;   /* -1 when not set, 1 if seen once, >1 otherwise. */
6933   int to_return = -1;   /* -1 when not set, 0 or 1 otherwise */
6934   tree node;
6935
6936   for (; import; import = TREE_CHAIN (import))
6937     {
6938       int saved_lineno = lineno;
6939       int access_check;
6940       const char *id_name;
6941       tree decl, type_name_copy;
6942
6943       obstack_grow (&temporary_obstack, 
6944                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6945                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6946       obstack_1grow (&temporary_obstack, '.');
6947       obstack_grow0 (&temporary_obstack, 
6948                      IDENTIFIER_POINTER (class_type_name),
6949                      IDENTIFIER_LENGTH (class_type_name));
6950       id_name = obstack_finish (&temporary_obstack);
6951               
6952       if (! (node = maybe_get_identifier (id_name)))
6953         continue;
6954
6955       /* Setup lineno so that it refers to the line of the import (in
6956          case we parse a class file and encounter errors */
6957       lineno = EXPR_WFL_LINENO (TREE_PURPOSE (import));
6958
6959       type_name_copy = TYPE_NAME (class_type);
6960       TYPE_NAME (class_type) = node;
6961       QUALIFIED_P (node) = 1;
6962       decl = IDENTIFIER_CLASS_VALUE (node);
6963       access_check = -1;
6964       /* If there is no DECL set for the class or if the class isn't
6965          loaded and not seen in source yet, then load */
6966       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6967                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6968         {
6969           load_class (node, 0);
6970           decl = IDENTIFIER_CLASS_VALUE (node);
6971         }
6972       if (decl && ! INNER_CLASS_P (TREE_TYPE (decl)))
6973         access_check = check_pkg_class_access (node, TREE_PURPOSE (import),
6974                                                false);
6975       else
6976         /* 6.6.1: Inner classes are subject to member access rules. */
6977         access_check = 0;
6978
6979       lineno = saved_lineno;
6980
6981       /* If the loaded class is not accessible or couldn't be loaded,
6982          we restore the original TYPE_NAME and process the next
6983          import. */
6984       if (access_check || !decl)
6985         {
6986           TYPE_NAME (class_type) = type_name_copy;
6987           continue;
6988         }
6989       
6990       /* If the loaded class is accessible, we keep a tab on it to
6991          detect and report multiple inclusions. */
6992       if (IS_A_CLASSFILE_NAME (node))
6993         {
6994           if (seen_once < 0)
6995             {
6996               cl = TREE_PURPOSE (import);
6997               seen_once = 1;
6998             }
6999           else if (seen_once >= 0)
7000             {
7001               tree location = (cl ? cl : TREE_PURPOSE (import));
7002               tree package = (cl ? EXPR_WFL_NODE (cl) : 
7003                               EXPR_WFL_NODE (TREE_PURPOSE (import)));
7004               seen_once++;
7005               parse_error_context 
7006                 (location,
7007                  "Type `%s' also potentially defined in package `%s'",
7008                  IDENTIFIER_POINTER (TYPE_NAME (class_type)), 
7009                  IDENTIFIER_POINTER (package));
7010             }
7011         }
7012       to_return = access_check;
7013     }
7014
7015   if (seen_once == 1)
7016     return to_return;
7017   else
7018     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
7019 }
7020
7021 /* Add package NAME to the list of package encountered so far. To
7022    speed up class lookup in do_resolve_class, we make sure a
7023    particular package is added only once.  */
7024
7025 static void
7026 register_package (name)
7027      tree name;
7028 {
7029   static struct hash_table _pht, *pht = NULL;
7030
7031   if (!pht)
7032     {
7033       hash_table_init (&_pht, hash_newfunc, 
7034                        java_hash_hash_tree_node, java_hash_compare_tree_node);
7035       pht = &_pht;
7036     }
7037   
7038   if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
7039     {
7040       package_list = chainon (package_list, build_tree_list (name, NULL));
7041       hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
7042     }
7043 }
7044
7045 static tree
7046 resolve_package (pkg, next, type_name)
7047      tree pkg, *next, *type_name;
7048 {
7049   tree current;
7050   tree decl = NULL_TREE;
7051   *type_name = NULL_TREE;
7052
7053   /* The trick is to determine when the package name stops and were
7054      the name of something contained in the package starts. Then we
7055      return a fully qualified name of what we want to get. */
7056
7057   *next = EXPR_WFL_QUALIFICATION (pkg);
7058
7059   /* Try to progressively construct a type name */
7060   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
7061     for (current = EXPR_WFL_QUALIFICATION (pkg); 
7062          current; current = TREE_CHAIN (current))
7063       {
7064         /* If we don't have what we're expecting, exit now. TYPE_NAME
7065            will be null and the error caught later. */
7066         if (TREE_CODE (QUAL_WFL (current)) != EXPR_WITH_FILE_LOCATION)
7067           break;
7068         *type_name = 
7069           merge_qualified_name (*type_name, EXPR_WFL_NODE (QUAL_WFL (current)));
7070         if ((decl = resolve_no_layout (*type_name, NULL_TREE)))
7071           {
7072             /* resolve_package should be used in a loop, hence we
7073                point at this one to naturally process the next one at
7074                the next iteration. */
7075             *next = current;
7076             break;
7077           }
7078       }
7079   return decl;
7080 }
7081
7082
7083 /* Check accessibility of inner classes according to member access rules. 
7084    DECL is the inner class, ENCLOSING_DECL is the class from which the
7085    access is being attempted. */
7086
7087 static void
7088 check_inner_class_access (decl, enclosing_decl, cl)
7089      tree decl, enclosing_decl, cl;
7090 {
7091   const char *access;
7092   tree enclosing_decl_type;
7093
7094   /* We don't issue an error message when CL is null. CL can be null
7095      as a result of processing a JDEP crafted by source_start_java_method
7096      for the purpose of patching its parm decl. But the error would
7097      have been already trapped when fixing the method's signature.
7098      DECL can also be NULL in case of earlier errors. */
7099   if (!decl || !cl)
7100     return;
7101
7102   enclosing_decl_type = TREE_TYPE (enclosing_decl);
7103
7104   if (CLASS_PRIVATE (decl))
7105     {
7106       /* Access is permitted only within the body of the top-level
7107          class in which DECL is declared. */
7108       tree top_level = decl;
7109       while (DECL_CONTEXT (top_level))
7110         top_level = DECL_CONTEXT (top_level);      
7111       while (DECL_CONTEXT (enclosing_decl))
7112         enclosing_decl = DECL_CONTEXT (enclosing_decl);
7113       if (top_level == enclosing_decl)
7114         return;      
7115       access = "private";
7116     }
7117   else if (CLASS_PROTECTED (decl))
7118     {
7119       tree decl_context;
7120       /* Access is permitted from within the same package... */
7121       if (in_same_package (decl, enclosing_decl))
7122         return;
7123       
7124       /* ... or from within the body of a subtype of the context in which
7125          DECL is declared. */
7126       decl_context = DECL_CONTEXT (decl);
7127       while (enclosing_decl)
7128         {
7129           if (CLASS_INTERFACE (decl))
7130             {
7131               if (interface_of_p (TREE_TYPE (decl_context), 
7132                                   enclosing_decl_type))
7133                 return;
7134             }
7135           else
7136             {
7137               /* Eww. The order of the arguments is different!! */
7138               if (inherits_from_p (enclosing_decl_type, 
7139                                    TREE_TYPE (decl_context)))
7140                 return;
7141             }
7142           enclosing_decl = DECL_CONTEXT (enclosing_decl);
7143         }      
7144       access = "protected";
7145     }
7146   else if (! CLASS_PUBLIC (decl))
7147     {
7148       /* Access is permitted only from within the same package as DECL. */
7149       if (in_same_package (decl, enclosing_decl))
7150         return;
7151       access = "non-public";
7152     }
7153   else
7154     /* Class is public. */
7155     return;
7156
7157   parse_error_context (cl, "Nested %s %s is %s; cannot be accessed from here",
7158                        (CLASS_INTERFACE (decl) ? "interface" : "class"),
7159                        lang_printable_name (decl, 0), access);
7160 }
7161
7162 /* Accessibility check for top-level classes. If CLASS_NAME is in a
7163    foreign package, it must be PUBLIC. Return 0 if no access
7164    violations were found, 1 otherwise. If VERBOSE is true and an error
7165    was found, it is reported and accounted for.  */
7166
7167 static int
7168 check_pkg_class_access (class_name, cl, verbose)
7169      tree class_name;
7170      tree cl;
7171      bool verbose;
7172 {
7173   tree type;
7174
7175   if (!IDENTIFIER_CLASS_VALUE (class_name))
7176     return 0;
7177
7178   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
7179     return 0;
7180
7181   if (!CLASS_PUBLIC (TYPE_NAME (type)))
7182     {
7183       /* Access to a private class within the same package is
7184          allowed. */
7185       tree l, r;
7186       breakdown_qualified (&l, &r, class_name);
7187       if (!QUALIFIED_P (class_name) && !ctxp->package)
7188         /* Both in the empty package. */
7189         return 0;
7190       if (l == ctxp->package)
7191         /* Both in the same package. */
7192         return 0;
7193
7194       if (verbose)
7195         parse_error_context 
7196           (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
7197            (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
7198            IDENTIFIER_POINTER (class_name));
7199       return 1;
7200     }
7201   return 0;
7202 }
7203
7204 /* Local variable declaration. */
7205
7206 static void
7207 declare_local_variables (modifier, type, vlist)
7208      int modifier;
7209      tree type;
7210      tree vlist;
7211 {
7212   tree decl, current, saved_type;
7213   tree type_wfl = NULL_TREE;
7214   int must_chain = 0;
7215   int final_p = 0;
7216
7217   /* Push a new block if statements were seen between the last time we
7218      pushed a block and now. Keep a count of blocks to close */
7219   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
7220     {
7221       tree b = enter_block ();
7222       BLOCK_IS_IMPLICIT (b) = 1;
7223     }
7224
7225   if (modifier)
7226     {
7227       int i;
7228       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
7229       if (modifier == ACC_FINAL)
7230         final_p = 1;
7231       else 
7232         {
7233           parse_error_context 
7234             (ctxp->modifier_ctx [i], 
7235              "Only `final' is allowed as a local variables modifier");
7236           return;
7237         }
7238     }
7239
7240   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
7241      hold the TYPE value if a new incomplete has to be created (as
7242      opposed to being found already existing and reused). */
7243   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
7244
7245   /* If TYPE is fully resolved and we don't have a reference, make one */
7246   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
7247
7248   /* Go through all the declared variables */
7249   for (current = vlist, saved_type = type; current;
7250        current = TREE_CHAIN (current), type = saved_type)
7251     {
7252       tree other, real_type;
7253       tree wfl  = TREE_PURPOSE (current);
7254       tree name = EXPR_WFL_NODE (wfl);
7255       tree init = TREE_VALUE (current);
7256
7257       /* Process NAME, as it may specify extra dimension(s) for it */
7258       type = build_array_from_name (type, type_wfl, name, &name);
7259
7260       /* Variable redefinition check */
7261       if ((other = lookup_name_in_blocks (name)))
7262         {
7263           variable_redefinition_error (wfl, name, TREE_TYPE (other),
7264                                        DECL_SOURCE_LINE (other));
7265           continue;
7266         }
7267
7268       /* Type adjustment. We may have just readjusted TYPE because
7269          the variable specified more dimensions. Make sure we have
7270          a reference if we can and don't have one already. */
7271       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
7272
7273       real_type = GET_REAL_TYPE (type);
7274       /* Never layout this decl. This will be done when its scope
7275          will be entered */
7276       decl = build_decl (VAR_DECL, name, real_type);
7277       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
7278       DECL_FINAL (decl) = final_p;
7279       BLOCK_CHAIN_DECL (decl);
7280       
7281       /* If doing xreferencing, replace the line number with the WFL
7282          compound value */
7283       if (flag_emit_xref)
7284         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
7285       
7286       /* Don't try to use an INIT statement when an error was found */
7287       if (init && java_error_count)
7288         init = NULL_TREE;
7289       
7290       /* Add the initialization function to the current function's code */
7291       if (init)
7292         {
7293           /* Name might have been readjusted */
7294           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
7295           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
7296           java_method_add_stmt (current_function_decl,
7297                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
7298                                                       init));
7299         }
7300     
7301       /* Setup dependency the type of the decl */
7302       if (must_chain)
7303         {
7304           jdep *dep;
7305           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
7306           dep = CLASSD_LAST (ctxp->classd_list);
7307           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
7308         }
7309     }
7310   SOURCE_FRONTEND_DEBUG (("Defined locals"));
7311 }
7312
7313 /* Called during parsing. Build decls from argument list.  */
7314
7315 static void
7316 source_start_java_method (fndecl)
7317      tree fndecl;
7318 {
7319   tree tem;
7320   tree parm_decl;
7321   int i;
7322
7323   if (!fndecl)
7324     return;
7325
7326   current_function_decl = fndecl;
7327
7328   /* New scope for the function */
7329   enter_block ();
7330   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
7331        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
7332     {
7333       tree type = TREE_VALUE (tem);
7334       tree name = TREE_PURPOSE (tem);
7335       
7336       /* If type is incomplete. Create an incomplete decl and ask for
7337          the decl to be patched later */
7338       if (INCOMPLETE_TYPE_P (type))
7339         {
7340           jdep *jdep;
7341           tree real_type = GET_REAL_TYPE (type);
7342           parm_decl = build_decl (PARM_DECL, name, real_type);
7343           type = obtain_incomplete_type (type);
7344           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
7345           jdep = CLASSD_LAST (ctxp->classd_list);
7346           JDEP_MISC (jdep) = name;
7347           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
7348         }
7349       else
7350         parm_decl = build_decl (PARM_DECL, name, type);
7351
7352       /* Remember if a local variable was declared final (via its
7353          TREE_LIST of type/name.) Set DECL_FINAL accordingly. */
7354       if (ARG_FINAL_P (tem))
7355         {
7356           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (parm_decl);
7357           DECL_FINAL (parm_decl) = 1;
7358         }
7359
7360       BLOCK_CHAIN_DECL (parm_decl);
7361     }
7362   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7363   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
7364     nreverse (tem);
7365   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
7366   DECL_MAX_LOCALS (current_function_decl) = i;
7367 }
7368
7369 /* Called during parsing. Creates an artificial method declaration.  */
7370
7371 static tree
7372 create_artificial_method (class, flags, type, name, args)
7373      tree class;
7374      int flags;
7375      tree type, name, args;
7376 {
7377   tree mdecl;
7378
7379   java_parser_context_save_global ();
7380   lineno = 0;                                                               
7381   mdecl = make_node (FUNCTION_TYPE);                                
7382   TREE_TYPE (mdecl) = type;
7383   TYPE_ARG_TYPES (mdecl) = args;
7384   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
7385   java_parser_context_restore_global ();
7386   DECL_ARTIFICIAL (mdecl) = 1;                                      
7387   return mdecl;
7388 }
7389
7390 /* Starts the body if an artificial method.  */
7391
7392 static void
7393 start_artificial_method_body (mdecl)
7394      tree mdecl;
7395 {
7396   DECL_SOURCE_LINE (mdecl) = 1;
7397   DECL_SOURCE_LINE_MERGE (mdecl, 1);
7398   source_start_java_method (mdecl);
7399   enter_block ();
7400 }
7401
7402 static void
7403 end_artificial_method_body (mdecl)
7404      tree mdecl;
7405 {
7406   /* exit_block modifies DECL_FUNCTION_BODY (current_function_decl).
7407      It has to be evaluated first. (if mdecl is current_function_decl,
7408      we have an undefined behavior if no temporary variable is used.) */
7409   tree b = exit_block ();
7410   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = b;
7411   exit_block ();
7412 }
7413
7414 /* Dump a tree of some kind.  This is a convenience wrapper for the
7415    dump_* functions in tree-dump.c.  */
7416 static void
7417 dump_java_tree (phase, t)
7418      enum tree_dump_index phase;
7419      tree t;
7420 {
7421   FILE *stream;
7422   int flags;
7423
7424   stream = dump_begin (phase, &flags);
7425   if (stream)
7426     {
7427       dump_node (t, flags, stream);
7428       dump_end (phase, stream);
7429     }
7430 }
7431
7432 /* Terminate a function and expand its body.  */
7433
7434 static void
7435 source_end_java_method ()
7436 {
7437   tree fndecl = current_function_decl;
7438
7439   if (!fndecl)
7440     return;
7441
7442   java_parser_context_save_global ();
7443   lineno = ctxp->last_ccb_indent1;
7444
7445   /* Turn function bodies with only a NOP expr null, so they don't get
7446      generated at all and we won't get warnings when using the -W
7447      -Wall flags. */
7448   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7449     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7450
7451   /* We've generated all the trees for this function, and it has been
7452      patched.  Dump it to a file if the user requested it.  */
7453   dump_java_tree (TDI_original, fndecl);
7454
7455   /* Generate function's code */
7456   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7457       && ! flag_emit_class_files
7458       && ! flag_emit_xref)
7459     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7460
7461   /* pop out of its parameters */
7462   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7463   poplevel (1, 0, 1);
7464   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7465
7466   /* Generate rtl for function exit.  */
7467   if (! flag_emit_class_files && ! flag_emit_xref)
7468     {
7469       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7470       expand_function_end (input_filename, lineno, 0);
7471
7472       /* Run the optimizers and output assembler code for this function. */
7473       rest_of_compilation (fndecl);
7474     }
7475
7476   current_function_decl = NULL_TREE;
7477   java_parser_context_restore_global ();
7478 }
7479
7480 /* Record EXPR in the current function block. Complements compound
7481    expression second operand if necessary.  */
7482
7483 tree
7484 java_method_add_stmt (fndecl, expr)
7485      tree fndecl, expr;
7486 {
7487   if (!GET_CURRENT_BLOCK (fndecl))
7488     return NULL_TREE;
7489   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7490 }
7491
7492 static tree
7493 add_stmt_to_block (b, type, stmt)
7494      tree b, type, stmt;
7495 {
7496   tree body = BLOCK_EXPR_BODY (b), c;
7497   
7498   if (java_error_count)
7499     return body;
7500     
7501   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7502     return body;
7503
7504   BLOCK_EXPR_BODY (b) = c;
7505   TREE_SIDE_EFFECTS (c) = 1;
7506   return c;
7507 }
7508
7509 /* Add STMT to EXISTING if possible, otherwise create a new
7510    COMPOUND_EXPR and add STMT to it. */
7511
7512 static tree
7513 add_stmt_to_compound (existing, type, stmt)
7514      tree existing, type, stmt;
7515 {
7516   if (existing)
7517     return build (COMPOUND_EXPR, type, existing, stmt);
7518   else
7519     return stmt;
7520 }
7521
7522 void java_layout_seen_class_methods ()
7523 {
7524   tree previous_list = all_class_list;
7525   tree end = NULL_TREE;
7526   tree current;
7527
7528   while (1)
7529     {
7530       for (current = previous_list; 
7531            current != end; current = TREE_CHAIN (current))
7532         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7533       
7534       if (previous_list != all_class_list)
7535         {
7536           end = previous_list;
7537           previous_list = all_class_list;
7538         }
7539       else
7540         break;
7541     }
7542 }
7543
7544 void
7545 java_reorder_fields ()
7546 {
7547   static tree stop_reordering = NULL_TREE;
7548   static int initialized_p;
7549   tree current;
7550
7551   /* Register STOP_REORDERING with the garbage collector.  */
7552   if (!initialized_p)
7553     {
7554       ggc_add_tree_root (&stop_reordering, 1);
7555       initialized_p = 1;
7556     }
7557
7558   for (current = gclass_list; current; current = TREE_CHAIN (current))
7559     {
7560       current_class = TREE_TYPE (TREE_VALUE (current));
7561
7562       if (current_class == stop_reordering)
7563         break;
7564
7565       /* Reverse the fields, but leave the dummy field in front.
7566          Fields are already ordered for Object and Class */
7567       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7568           && current_class != class_type_node)
7569       {
7570         /* If the dummy field is there, reverse the right fields and
7571            just layout the type for proper fields offset */
7572         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7573           {
7574             tree fields = TYPE_FIELDS (current_class);
7575             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7576             TYPE_SIZE (current_class) = NULL_TREE;
7577           }
7578         /* We don't have a dummy field, we need to layout the class,
7579            after having reversed the fields */
7580         else
7581           {
7582             TYPE_FIELDS (current_class) = 
7583               nreverse (TYPE_FIELDS (current_class));
7584             TYPE_SIZE (current_class) = NULL_TREE;
7585           }
7586       }
7587     }
7588   /* There are cases were gclass_list will be empty. */
7589   if (gclass_list)
7590     stop_reordering = TREE_TYPE (TREE_VALUE (gclass_list));
7591 }
7592
7593 /* Layout the methods of all classes loaded in one way or another.
7594    Check methods of source parsed classes. Then reorder the
7595    fields and layout the classes or the type of all source parsed
7596    classes */
7597
7598 void
7599 java_layout_classes ()
7600 {
7601   tree current;
7602   int save_error_count = java_error_count;
7603
7604   /* Layout the methods of all classes seen so far */
7605   java_layout_seen_class_methods ();
7606   java_parse_abort_on_error ();
7607   all_class_list = NULL_TREE;
7608
7609   /* Then check the methods of all parsed classes */
7610   for (current = gclass_list; current; current = TREE_CHAIN (current))
7611     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7612       java_check_methods (TREE_VALUE (current));
7613   java_parse_abort_on_error ();
7614
7615   for (current = gclass_list; current; current = TREE_CHAIN (current))
7616     {
7617       current_class = TREE_TYPE (TREE_VALUE (current));
7618       layout_class (current_class);
7619
7620       /* Error reported by the caller */
7621       if (java_error_count)
7622         return;
7623     }
7624
7625   /* We might have reloaded classes durign the process of laying out
7626      classes for code generation. We must layout the methods of those
7627      late additions, as constructor checks might use them */
7628   java_layout_seen_class_methods ();
7629   java_parse_abort_on_error ();
7630 }
7631
7632 /* Expand methods in the current set of classes rememebered for
7633    generation.  */
7634
7635 static void
7636 java_complete_expand_classes ()
7637 {
7638   tree current;
7639
7640   do_not_fold = flag_emit_xref;
7641
7642   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7643     if (!INNER_CLASS_DECL_P (current))
7644       java_complete_expand_class (current);
7645 }
7646
7647 /* Expand the methods found in OUTER, starting first by OUTER's inner
7648    classes, if any.  */
7649
7650 static void
7651 java_complete_expand_class (outer)
7652      tree outer;
7653 {
7654   tree inner_list;
7655
7656   set_nested_class_simple_name_value (outer, 1); /* Set */
7657
7658   /* We need to go after all inner classes and start expanding them,
7659      starting with most nested ones. We have to do that because nested
7660      classes might add functions to outer classes */
7661
7662   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7663        inner_list; inner_list = TREE_CHAIN (inner_list))
7664     java_complete_expand_class (TREE_PURPOSE (inner_list));
7665
7666   java_complete_expand_methods (outer);
7667   set_nested_class_simple_name_value (outer, 0); /* Reset */
7668 }
7669
7670 /* Expand methods registered in CLASS_DECL. The general idea is that
7671    we expand regular methods first. This allows us get an estimate on
7672    how outer context local alias fields are really used so we can add
7673    to the constructor just enough code to initialize them properly (it
7674    also lets us generate finit$ correctly.) Then we expand the
7675    constructors and then <clinit>.  */
7676
7677 static void
7678 java_complete_expand_methods (class_decl)
7679      tree class_decl;
7680 {
7681   tree clinit, decl, first_decl;
7682
7683   current_class = TREE_TYPE (class_decl);
7684
7685   /* Initialize a new constant pool */
7686   init_outgoing_cpool ();
7687
7688   /* Pre-expand <clinit> to figure whether we really need it or
7689      not. If we do need it, we pre-expand the static fields so they're
7690      ready to be used somewhere else. <clinit> will be fully expanded
7691      after we processed the constructors. */
7692   first_decl = TYPE_METHODS (current_class);
7693   clinit = maybe_generate_pre_expand_clinit (current_class);
7694
7695   /* Then generate finit$ (if we need to) because constructors will
7696    try to use it.*/
7697   if (TYPE_FINIT_STMT_LIST (current_class))
7698     java_complete_expand_method (generate_finit (current_class));
7699
7700   /* Then generate instinit$ (if we need to) because constructors will
7701      try to use it. */
7702   if (TYPE_II_STMT_LIST (current_class))
7703     java_complete_expand_method (generate_instinit (current_class));
7704
7705   /* Now do the constructors */
7706   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7707     {
7708       int no_body;
7709
7710       if (!DECL_CONSTRUCTOR_P (decl))
7711         continue;
7712       
7713       no_body = !DECL_FUNCTION_BODY (decl);
7714       /* Don't generate debug info on line zero when expanding a
7715          generated constructor. */
7716       if (no_body)
7717         restore_line_number_status (1);
7718
7719       java_complete_expand_method (decl);
7720
7721       if (no_body)
7722         restore_line_number_status (0);
7723     }
7724
7725   /* First, do the ordinary methods. */
7726   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7727     {
7728       /* Ctors aren't part of this batch. */
7729       if (DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7730         continue;
7731       
7732       /* Skip abstract or native methods -- but do handle native
7733          methods when generating JNI stubs.  */
7734       if (METHOD_ABSTRACT (decl) || (! flag_jni && METHOD_NATIVE (decl)))
7735         {
7736           DECL_FUNCTION_BODY (decl) = NULL_TREE;
7737           continue;
7738         }
7739
7740       if (METHOD_NATIVE (decl))
7741         {
7742           tree body;
7743           current_function_decl = decl;
7744           body = build_jni_stub (decl);
7745           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7746         }
7747
7748       java_complete_expand_method (decl);
7749     }
7750
7751   /* If there is indeed a <clinit>, fully expand it now */
7752   if (clinit)
7753     {
7754       /* Prevent the use of `this' inside <clinit> */
7755       ctxp->explicit_constructor_p = 1;
7756       java_complete_expand_method (clinit);
7757       ctxp->explicit_constructor_p = 0;
7758     }
7759   
7760   /* We might have generated a class$ that we now want to expand */
7761   if (TYPE_DOT_CLASS (current_class))
7762     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7763
7764   /* Now verify constructor circularity (stop after the first one we
7765      prove wrong.) */
7766   if (!CLASS_INTERFACE (class_decl))
7767     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7768       if (DECL_CONSTRUCTOR_P (decl) 
7769           && verify_constructor_circularity (decl, decl))
7770         break;
7771
7772   /* Save the constant pool. We'll need to restore it later. */
7773   TYPE_CPOOL (current_class) = outgoing_cpool;
7774 }
7775
7776 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7777    safely used in some other methods/constructors.  */
7778
7779 static tree
7780 maybe_generate_pre_expand_clinit (class_type)
7781      tree class_type;
7782 {
7783   tree current, mdecl;
7784
7785   if (!TYPE_CLINIT_STMT_LIST (class_type))
7786     return NULL_TREE;
7787
7788   /* Go through all static fields and pre expand them */
7789   for (current = TYPE_FIELDS (class_type); current; 
7790        current = TREE_CHAIN (current))
7791     if (FIELD_STATIC (current))
7792       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7793
7794   /* Then build the <clinit> method */
7795   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7796                                     clinit_identifier_node, end_params_node);
7797   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7798                        mdecl, NULL_TREE);
7799   start_artificial_method_body (mdecl);
7800
7801   /* We process the list of assignment we produced as the result of
7802      the declaration of initialized static field and add them as
7803      statement to the <clinit> method. */
7804   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7805        current = TREE_CHAIN (current))
7806     {
7807       tree stmt = current;
7808       /* We build the assignment expression that will initialize the
7809          field to its value. There are strict rules on static
7810          initializers (8.5). FIXME */
7811       if (TREE_CODE (stmt) != BLOCK && stmt != empty_stmt_node)
7812         stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
7813       java_method_add_stmt (mdecl, stmt);
7814     }
7815
7816   end_artificial_method_body (mdecl);
7817
7818   /* Now we want to place <clinit> as the last method (because we need
7819      it at least for interface so that it doesn't interfere with the
7820      dispatch table based lookup. */
7821   if (TREE_CHAIN (TYPE_METHODS (class_type)))
7822     {
7823       current = TREE_CHAIN (TYPE_METHODS (class_type));
7824       TYPE_METHODS (class_type) = current;
7825
7826       while (TREE_CHAIN (current))
7827         current = TREE_CHAIN (current);
7828
7829       TREE_CHAIN (current) = mdecl;
7830       TREE_CHAIN (mdecl) = NULL_TREE;
7831     }
7832
7833   return mdecl;
7834 }
7835
7836 /* Analyzes a method body and look for something that isn't a
7837    MODIFY_EXPR with a constant value.  */
7838
7839 static int
7840 analyze_clinit_body (this_class, bbody)
7841      tree this_class, bbody;
7842 {
7843   while (bbody)
7844     switch (TREE_CODE (bbody))
7845       {
7846       case BLOCK:
7847         bbody = BLOCK_EXPR_BODY (bbody);
7848         break;
7849         
7850       case EXPR_WITH_FILE_LOCATION:
7851         bbody = EXPR_WFL_NODE (bbody);
7852         break;
7853         
7854       case COMPOUND_EXPR:
7855         if (analyze_clinit_body (this_class, TREE_OPERAND (bbody, 0)))
7856           return 1;
7857         bbody = TREE_OPERAND (bbody, 1);
7858         break;
7859         
7860       case MODIFY_EXPR:
7861         /* If we're generating to class file and we're dealing with an
7862            array initialization, we return 1 to keep <clinit> */
7863         if (TREE_CODE (TREE_OPERAND (bbody, 1)) == NEW_ARRAY_INIT
7864             && flag_emit_class_files)
7865           return 1;
7866
7867         /* There are a few cases where we're required to keep
7868            <clinit>:
7869            - If this is an assignment whose operand is not constant,
7870            - If this is an assignment to a non-initialized field,
7871            - If this field is not a member of the current class.
7872         */
7873         return (! TREE_CONSTANT (TREE_OPERAND (bbody, 1))
7874                 || ! DECL_INITIAL (TREE_OPERAND (bbody, 0))
7875                 || DECL_CONTEXT (TREE_OPERAND (bbody, 0)) != this_class);
7876
7877       default:
7878         return 1;
7879       }
7880   return 0;
7881 }
7882
7883
7884 /* See whether we could get rid of <clinit>. Criteria are: all static
7885    final fields have constant initial values and the body of <clinit>
7886    is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
7887
7888 static int
7889 maybe_yank_clinit (mdecl)
7890      tree mdecl;
7891 {
7892   tree type, current;
7893   tree fbody, bbody;
7894   
7895   if (!DECL_CLINIT_P (mdecl))
7896     return 0;
7897
7898   /* If the body isn't empty, then we keep <clinit>. Note that if
7899      we're emitting classfiles, this isn't enough not to rule it
7900      out. */
7901   fbody = DECL_FUNCTION_BODY (mdecl);
7902   bbody = BLOCK_EXPR_BODY (fbody);
7903   if (bbody && bbody != error_mark_node)
7904     bbody = BLOCK_EXPR_BODY (bbody);
7905   else
7906     return 0;
7907   if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
7908     return 0;
7909
7910   type = DECL_CONTEXT (mdecl);
7911   current = TYPE_FIELDS (type);
7912
7913   for (current = (current ? TREE_CHAIN (current) : current); 
7914        current; current = TREE_CHAIN (current))
7915     {
7916       tree f_init;
7917
7918       /* We're not interested in non-static fields.  */
7919       if (!FIELD_STATIC (current))
7920         continue;
7921
7922       /* Nor in fields without initializers. */
7923       f_init = DECL_INITIAL (current);
7924       if (f_init == NULL_TREE)
7925         continue;
7926
7927       /* Anything that isn't String or a basic type is ruled out -- or
7928          if we know how to deal with it (when doing things natively) we
7929          should generated an empty <clinit> so that SUID are computed
7930          correctly. */
7931       if (! JSTRING_TYPE_P (TREE_TYPE (current))
7932           && ! JNUMERIC_TYPE_P (TREE_TYPE (current)))
7933         return 0;
7934
7935       if (! FIELD_FINAL (current) || ! TREE_CONSTANT (f_init))
7936         return 0;
7937     }
7938
7939   /* Now we analyze the method body and look for something that
7940      isn't a MODIFY_EXPR */
7941   if (bbody != empty_stmt_node && analyze_clinit_body (type, bbody))
7942     return 0;
7943
7944   /* Get rid of <clinit> in the class' list of methods */
7945   if (TYPE_METHODS (type) == mdecl)
7946     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
7947   else
7948     for (current = TYPE_METHODS (type); current; 
7949          current = TREE_CHAIN (current))
7950       if (TREE_CHAIN (current) == mdecl)
7951         {
7952           TREE_CHAIN (current) = TREE_CHAIN (mdecl);
7953           break;
7954         }
7955
7956   return 1;
7957 }
7958
7959 /* Install the argument from MDECL. Suitable to completion and
7960    expansion of mdecl's body.  */
7961
7962 static void
7963 start_complete_expand_method (mdecl)
7964      tree mdecl;
7965 {
7966   tree tem;
7967
7968   pushlevel (1);                /* Prepare for a parameter push */
7969   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7970   DECL_ARGUMENTS (mdecl) = tem;
7971
7972   for (; tem; tem = TREE_CHAIN (tem))
7973     {
7974       /* TREE_CHAIN (tem) will change after pushdecl. */ 
7975       tree next = TREE_CHAIN (tem);
7976       tree type = TREE_TYPE (tem);
7977       if (PROMOTE_PROTOTYPES
7978           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
7979           && INTEGRAL_TYPE_P (type))
7980         type = integer_type_node;
7981       DECL_ARG_TYPE (tem) = type;
7982       layout_decl (tem, 0);
7983       pushdecl (tem);
7984       /* Re-install the next so that the list is kept and the loop
7985          advances. */
7986       TREE_CHAIN (tem) = next;
7987     }
7988   pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7989   lineno = DECL_SOURCE_LINE_FIRST (mdecl);
7990   build_result_decl (mdecl);
7991 }
7992
7993
7994 /* Complete and expand a method.  */
7995
7996 static void
7997 java_complete_expand_method (mdecl)
7998      tree mdecl;
7999 {
8000   tree fbody, block_body, exception_copy;
8001
8002   current_function_decl = mdecl;
8003   /* Fix constructors before expanding them */
8004   if (DECL_CONSTRUCTOR_P (mdecl))
8005     fix_constructors (mdecl);
8006   
8007   /* Expand functions that have a body */
8008   if (!DECL_FUNCTION_BODY (mdecl))
8009     return;
8010
8011   fbody = DECL_FUNCTION_BODY (mdecl);
8012   block_body = BLOCK_EXPR_BODY (fbody);
8013   exception_copy = NULL_TREE;
8014
8015   current_function_decl = mdecl;
8016
8017   if (! quiet_flag)
8018     fprintf (stderr, " [%s.",
8019              lang_printable_name (DECL_CONTEXT (mdecl), 0));
8020   announce_function (mdecl);
8021   if (! quiet_flag)
8022     fprintf (stderr, "]");
8023   
8024   /* Prepare the function for tree completion */
8025   start_complete_expand_method (mdecl);
8026
8027   /* Install the current this */
8028   current_this = (!METHOD_STATIC (mdecl) ? 
8029                   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
8030
8031   /* Purge the `throws' list of unchecked exceptions (we save a copy
8032      of the list and re-install it later.) */
8033   exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
8034   purge_unchecked_exceptions (mdecl);
8035   
8036   /* Install exceptions thrown with `throws' */
8037   PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
8038   
8039   if (block_body != NULL_TREE)
8040     {
8041       block_body = java_complete_tree (block_body);
8042       
8043       /* Before we check initialization, attached all class initialization
8044          variable to the block_body */
8045       hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
8046                      attach_init_test_initialization_flags, block_body);
8047       
8048       if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
8049         {
8050           check_for_initialization (block_body, mdecl);
8051           
8052           /* Go through all the flags marking the initialization of
8053              static variables and see whether they're definitively
8054              assigned, in which case the type is remembered as
8055              definitively initialized in MDECL. */
8056           if (STATIC_CLASS_INIT_OPT_P ())
8057             {
8058               /* Always register the context as properly initialized in
8059                  MDECL. This used with caution helps removing extra
8060                  initialization of self. */
8061               if (METHOD_STATIC (mdecl))
8062                 hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (mdecl),
8063                              (hash_table_key) DECL_CONTEXT (mdecl),
8064                              TRUE, NULL);
8065             }
8066         }
8067       ctxp->explicit_constructor_p = 0;
8068     }
8069   
8070   BLOCK_EXPR_BODY (fbody) = block_body;
8071   
8072   /* If we saw a return but couldn't evaluate it properly, we'll have
8073      an error_mark_node here. */
8074   if (block_body != error_mark_node
8075       && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
8076       && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
8077       && !flag_emit_xref)
8078     missing_return_error (current_function_decl);
8079
8080   /* See if we can get rid of <clinit> if MDECL happens to be <clinit> */
8081   maybe_yank_clinit (mdecl);
8082
8083   /* Pop the current level, with special measures if we found errors. */
8084   if (java_error_count)
8085     pushdecl_force_head (DECL_ARGUMENTS (mdecl));
8086   poplevel (1, 0, 1);
8087
8088   /* Pop the exceptions and sanity check */
8089   POP_EXCEPTIONS();
8090   if (currently_caught_type_list)
8091     abort ();
8092
8093   /* Restore the copy of the list of exceptions if emitting xrefs. */
8094   DECL_FUNCTION_THROWS (mdecl) = exception_copy;
8095 }
8096
8097 /* For with each class for which there's code to generate. */
8098
8099 static void
8100 java_expand_method_bodies (class)
8101      tree class;
8102 {
8103   tree decl;
8104   for (decl = TYPE_METHODS (class); decl; decl = TREE_CHAIN (decl))
8105     {
8106       if (!DECL_FUNCTION_BODY (decl))
8107         continue;
8108
8109       current_function_decl = decl;
8110
8111       /* It's time to assign the variable flagging static class
8112          initialization based on which classes invoked static methods
8113          are definitely initializing. This should be flagged. */
8114       if (STATIC_CLASS_INIT_OPT_P ())
8115         {
8116           tree list = DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (decl);
8117           for (; list != NULL_TREE;  list = TREE_CHAIN (list))
8118             {
8119               /* Executed for each statement calling a static function.
8120                  LIST is a TREE_LIST whose PURPOSE is the called function
8121                  and VALUE is a compound whose second operand can be patched
8122                  with static class initialization flag assignments.  */
8123
8124               tree called_method = TREE_PURPOSE (list);
8125               tree compound = TREE_VALUE (list);
8126               tree assignment_compound_list
8127                 = build_tree_list (called_method, NULL);
8128
8129               /* For each class definitely initialized in
8130                  CALLED_METHOD, fill ASSIGNMENT_COMPOUND with
8131                  assignment to the class initialization flag. */
8132               hash_traverse (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method),
8133                              emit_test_initialization,
8134                              assignment_compound_list);
8135
8136               if (TREE_VALUE (assignment_compound_list))
8137                 TREE_OPERAND (compound, 1)
8138                   = TREE_VALUE (assignment_compound_list);
8139             }
8140         }
8141
8142       /* Prepare the function for RTL expansion */  
8143       start_complete_expand_method (decl);
8144
8145       /* Expand function start, generate initialization flag
8146          assignment, and handle synchronized methods. */
8147       complete_start_java_method (decl);
8148
8149       /* Expand the rest of the function body and terminate
8150          expansion. */
8151       source_end_java_method ();
8152     }
8153 }
8154
8155 \f
8156
8157 /* This section of the code deals with accessing enclosing context
8158    fields either directly by using the relevant access to this$<n> or
8159    by invoking an access method crafted for that purpose.  */
8160
8161 /* Build the necessary access from an inner class to an outer
8162    class. This routine could be optimized to cache previous result
8163    (decl, current_class and returned access).  When an access method
8164    needs to be generated, it always takes the form of a read. It might
8165    be later turned into a write by calling outer_field_access_fix.  */
8166
8167 static tree
8168 build_outer_field_access (id, decl)
8169      tree id, decl;
8170 {
8171   tree access = NULL_TREE;
8172   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
8173   tree decl_ctx = DECL_CONTEXT (decl);
8174
8175   /* If the immediate enclosing context of the current class is the
8176      field decl's class or inherits from it; build the access as
8177      `this$<n>.<field>'. Note that we will break the `private' barrier
8178      if we're not emitting bytecodes. */
8179   if ((ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
8180       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
8181     {
8182       tree thisn = build_current_thisn (current_class);
8183       access = make_qualified_primary (build_wfl_node (thisn), 
8184                                        id, EXPR_WFL_LINECOL (id));
8185     }
8186   /* Otherwise, generate access methods to outer this and access the
8187      field (either using an access method or by direct access.) */
8188   else
8189     {
8190       int lc = EXPR_WFL_LINECOL (id);
8191
8192       /* Now we chain the required number of calls to the access$0 to
8193          get a hold to the enclosing instance we need, and then we
8194          build the field access. */
8195       access = build_access_to_thisn (current_class, decl_ctx, lc);
8196
8197       /* If the field is private and we're generating bytecode, then
8198          we generate an access method */
8199       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
8200         {
8201           tree name = build_outer_field_access_methods (decl);
8202           access = build_outer_field_access_expr (lc, decl_ctx,
8203                                                   name, access, NULL_TREE);
8204         }
8205       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
8206          Once again we break the `private' access rule from a foreign
8207          class. */
8208       else
8209         access = make_qualified_primary (access, id, lc);
8210     }
8211   return resolve_expression_name (access, NULL);
8212 }
8213
8214 /* Return a non zero value if NODE describes an outer field inner
8215    access.  */
8216
8217 static int
8218 outer_field_access_p (type, decl)
8219     tree type, decl;
8220 {
8221   if (!INNER_CLASS_TYPE_P (type) 
8222       || TREE_CODE (decl) != FIELD_DECL
8223       || DECL_CONTEXT (decl) == type)
8224     return 0;
8225   
8226   /* If the inner class extends the declaration context of the field
8227      we're try to acces, then this isn't an outer field access */
8228   if (inherits_from_p (type, DECL_CONTEXT (decl)))
8229     return 0;
8230
8231   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
8232        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
8233     {
8234       if (type == DECL_CONTEXT (decl))
8235         return 1;
8236
8237       if (!DECL_CONTEXT (TYPE_NAME (type)))
8238         {
8239           /* Before we give up, see whether the field is inherited from
8240              the enclosing context we're considering. */
8241           if (inherits_from_p (type, DECL_CONTEXT (decl)))
8242             return 1;
8243           break;
8244         }
8245     }
8246
8247   return 0;
8248 }
8249
8250 /* Return a non zero value if NODE represents an outer field inner
8251    access that was been already expanded. As a side effect, it returns
8252    the name of the field being accessed and the argument passed to the
8253    access function, suitable for a regeneration of the access method
8254    call if necessary. */
8255
8256 static int
8257 outer_field_expanded_access_p (node, name, arg_type, arg)
8258     tree node, *name, *arg_type, *arg;
8259 {
8260   int identified = 0;
8261
8262   if (TREE_CODE (node) != CALL_EXPR)
8263     return 0;
8264
8265   /* Well, gcj generates slightly different tree nodes when compiling
8266      to native or bytecodes. It's the case for function calls. */
8267
8268   if (flag_emit_class_files 
8269       && TREE_CODE (node) == CALL_EXPR
8270       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
8271     identified = 1;
8272   else if (!flag_emit_class_files)
8273     {
8274       node = TREE_OPERAND (node, 0);
8275       
8276       if (node && TREE_OPERAND (node, 0)
8277           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
8278         {
8279           node = TREE_OPERAND (node, 0);
8280           if (TREE_OPERAND (node, 0)
8281               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
8282               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
8283                   (DECL_NAME (TREE_OPERAND (node, 0)))))
8284             identified = 1;
8285         }
8286     }
8287
8288   if (identified && name && arg_type && arg)
8289     {
8290       tree argument = TREE_OPERAND (node, 1);
8291       *name = DECL_NAME (TREE_OPERAND (node, 0));
8292       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
8293       *arg = TREE_VALUE (argument);
8294     }
8295   return identified;
8296 }
8297
8298 /* Detect in NODE an outer field read access from an inner class and
8299    transform it into a write with RHS as an argument. This function is
8300    called from the java_complete_lhs when an assignment to a LHS can
8301    be identified. */
8302
8303 static tree
8304 outer_field_access_fix (wfl, node, rhs)
8305     tree wfl, node, rhs;
8306 {
8307   tree name, arg_type, arg;
8308   
8309   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
8310     {
8311       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
8312                                             arg_type, name, arg, rhs);
8313       return java_complete_tree (node);
8314     }
8315   return NULL_TREE;
8316 }
8317
8318 /* Construct the expression that calls an access method:
8319      <type>.access$<n>(<arg1> [, <arg2>]); 
8320
8321    ARG2 can be NULL and will be omitted in that case. It will denote a
8322    read access.  */
8323
8324 static tree
8325 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
8326     int lc;
8327     tree type, access_method_name, arg1, arg2;
8328 {
8329   tree args, cn, access;
8330
8331   args = arg1 ? arg1 : 
8332     build_wfl_node (build_current_thisn (current_class));
8333   args = build_tree_list (NULL_TREE, args);
8334
8335   if (arg2)
8336     args = tree_cons (NULL_TREE, arg2, args);
8337
8338   access = build_method_invocation (build_wfl_node (access_method_name), args);
8339   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
8340   return make_qualified_primary (cn, access, lc);
8341 }
8342
8343 static tree
8344 build_new_access_id ()
8345 {
8346   static int access_n_counter = 1;
8347   char buffer [128];
8348
8349   sprintf (buffer, "access$%d", access_n_counter++);
8350   return get_identifier (buffer);
8351 }
8352
8353 /* Create the static access functions for the outer field DECL. We define a
8354    read:
8355      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
8356        return inst$.field;
8357      }
8358    and a write access:
8359      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
8360                                      TREE_TYPE (<field>) value$) {
8361        return inst$.field = value$;
8362      }
8363    We should have a usage flags on the DECL so we can lazily turn the ones
8364    we're using for code generation. FIXME.
8365 */
8366
8367 static tree
8368 build_outer_field_access_methods (decl)
8369     tree decl;
8370 {
8371   tree id, args, stmt, mdecl;
8372   
8373   if (FIELD_INNER_ACCESS_P (decl))
8374     return FIELD_INNER_ACCESS (decl);
8375
8376   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
8377  
8378   /* Create the identifier and a function named after it. */
8379   id = build_new_access_id ();
8380
8381   /* The identifier is marked as bearing the name of a generated write
8382      access function for outer field accessed from inner classes. */
8383   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8384
8385   /* Create the read access */
8386   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
8387   TREE_CHAIN (args) = end_params_node;
8388   stmt = make_qualified_primary (build_wfl_node (inst_id),
8389                                  build_wfl_node (DECL_NAME (decl)), 0);
8390   stmt = build_return (0, stmt);
8391   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8392                                            TREE_TYPE (decl), id, args, stmt);
8393   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8394
8395   /* Create the write access method. No write access for final variable */
8396   if (!FIELD_FINAL (decl))
8397     {
8398       args = build_tree_list (inst_id, 
8399                               build_pointer_type (DECL_CONTEXT (decl)));
8400       TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
8401       TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
8402       stmt = make_qualified_primary (build_wfl_node (inst_id),
8403                                      build_wfl_node (DECL_NAME (decl)), 0);
8404       stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
8405                                                 build_wfl_node (wpv_id)));
8406       mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8407                                                TREE_TYPE (decl), id, 
8408                                                args, stmt);
8409     }
8410   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8411
8412   /* Return the access name */
8413   return FIELD_INNER_ACCESS (decl) = id;
8414 }
8415
8416 /* Build an field access method NAME.  */
8417
8418 static tree 
8419 build_outer_field_access_method (class, type, name, args, body)
8420     tree class, type, name, args, body;
8421 {
8422   tree saved_current_function_decl, mdecl;
8423
8424   /* Create the method */
8425   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
8426   fix_method_argument_names (args, mdecl);
8427   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8428
8429   /* Attach the method body. */
8430   saved_current_function_decl = current_function_decl;
8431   start_artificial_method_body (mdecl);
8432   java_method_add_stmt (mdecl, body);
8433   end_artificial_method_body (mdecl);
8434   current_function_decl = saved_current_function_decl;
8435
8436   return mdecl;
8437 }
8438
8439 \f
8440 /* This section deals with building access function necessary for
8441    certain kinds of method invocation from inner classes.  */
8442
8443 static tree
8444 build_outer_method_access_method (decl)
8445     tree decl;
8446 {
8447   tree saved_current_function_decl, mdecl;
8448   tree args = NULL_TREE, call_args = NULL_TREE;
8449   tree carg, id, body, class;
8450   char buffer [80];
8451   int parm_id_count = 0;
8452
8453   /* Test this abort with an access to a private field */
8454   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
8455     abort ();
8456
8457   /* Check the cache first */
8458   if (DECL_FUNCTION_INNER_ACCESS (decl))
8459     return DECL_FUNCTION_INNER_ACCESS (decl);
8460
8461   class = DECL_CONTEXT (decl);
8462
8463   /* Obtain an access identifier and mark it */
8464   id = build_new_access_id ();
8465   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8466
8467   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
8468   /* Create the arguments, as much as the original */
8469   for (; carg && carg != end_params_node; 
8470        carg = TREE_CHAIN (carg))
8471     {
8472       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
8473       args = chainon (args, build_tree_list (get_identifier (buffer), 
8474                                              TREE_VALUE (carg)));
8475     }
8476   args = chainon (args, end_params_node);
8477
8478   /* Create the method */
8479   mdecl = create_artificial_method (class, ACC_STATIC, 
8480                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
8481   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8482   /* There is a potential bug here. We should be able to use
8483      fix_method_argument_names, but then arg names get mixed up and
8484      eventually a constructor will have its this$0 altered and the
8485      outer context won't be assignment properly. The test case is
8486      stub.java FIXME */
8487   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
8488
8489   /* Attach the method body. */
8490   saved_current_function_decl = current_function_decl;
8491   start_artificial_method_body (mdecl);
8492
8493   /* The actual method invocation uses the same args. When invoking a
8494      static methods that way, we don't want to skip the first
8495      argument. */
8496   carg = args;
8497   if (!METHOD_STATIC (decl))
8498     carg = TREE_CHAIN (carg);
8499   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
8500     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
8501                            call_args);
8502
8503   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
8504                                   call_args);
8505   if (!METHOD_STATIC (decl))
8506     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
8507                                    body, 0);
8508   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
8509     body = build_return (0, body);
8510   java_method_add_stmt (mdecl,body);
8511   end_artificial_method_body (mdecl);
8512   current_function_decl = saved_current_function_decl;
8513
8514   /* Back tag the access function so it know what it accesses */
8515   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
8516
8517   /* Tag the current method so it knows it has an access generated */
8518   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
8519 }
8520
8521 \f
8522 /* This section of the code deals with building expressions to access
8523    the enclosing instance of an inner class. The enclosing instance is
8524    kept in a generated field called this$<n>, with <n> being the
8525    inner class nesting level (starting from 0.)  */
8526     
8527 /* Build an access to a given this$<n>, always chaining access call to
8528    others. Access methods to this$<n> are build on the fly if
8529    necessary. This CAN'T be used to solely access this$<n-1> from
8530    this$<n> (which alway yield to special cases and optimization, see
8531    for example build_outer_field_access).  */
8532
8533 static tree
8534 build_access_to_thisn (from, to, lc)
8535      tree from, to;
8536      int lc;
8537 {
8538   tree access = NULL_TREE;
8539
8540   while (from != to && PURE_INNER_CLASS_TYPE_P (from))
8541     {
8542       if (!access)
8543         {
8544           access = build_current_thisn (from);
8545           access = build_wfl_node (access);
8546         }
8547       else
8548         {
8549           tree access0_wfl, cn;
8550
8551           maybe_build_thisn_access_method (from);
8552           access0_wfl = build_wfl_node (access0_identifier_node);
8553           cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
8554           EXPR_WFL_LINECOL (access0_wfl) = lc;
8555           access = build_tree_list (NULL_TREE, access);
8556           access = build_method_invocation (access0_wfl, access);
8557           access = make_qualified_primary (cn, access, lc);
8558         }
8559
8560       /* If FROM isn't an inner class, that's fine, we've done enough.
8561          What we're looking for can be accessed from there.  */
8562       from = DECL_CONTEXT (TYPE_NAME (from));
8563       if (!from)
8564         break;
8565       from = TREE_TYPE (from);
8566     }
8567   return access;
8568 }
8569
8570 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
8571    is returned if nothing needs to be generated. Otherwise, the method
8572    generated and a method decl is returned.  
8573
8574    NOTE: These generated methods should be declared in a class file
8575    attribute so that they can't be referred to directly.  */
8576
8577 static tree
8578 maybe_build_thisn_access_method (type)
8579     tree type;
8580 {
8581   tree mdecl, args, stmt, rtype;
8582   tree saved_current_function_decl;
8583
8584   /* If TYPE is a top-level class, no access method is required.
8585      If there already is such an access method, bail out. */
8586   if (CLASS_ACCESS0_GENERATED_P (type) || !PURE_INNER_CLASS_TYPE_P (type))
8587     return NULL_TREE;
8588
8589   /* We generate the method. The method looks like:
8590      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
8591   */
8592   args = build_tree_list (inst_id, build_pointer_type (type));
8593   TREE_CHAIN (args) = end_params_node;
8594   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
8595   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
8596                                     access0_identifier_node, args);
8597   fix_method_argument_names (args, mdecl);
8598   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
8599   stmt = build_current_thisn (type);
8600   stmt = make_qualified_primary (build_wfl_node (inst_id), 
8601                                  build_wfl_node (stmt), 0);
8602   stmt = build_return (0, stmt);
8603
8604   saved_current_function_decl = current_function_decl;
8605   start_artificial_method_body (mdecl);
8606   java_method_add_stmt (mdecl, stmt);
8607   end_artificial_method_body (mdecl);
8608   current_function_decl = saved_current_function_decl;
8609
8610   CLASS_ACCESS0_GENERATED_P (type) = 1;
8611
8612   return mdecl;
8613 }
8614
8615 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
8616    the first level of innerclassing. this$1 for the next one, etc...
8617    This function can be invoked with TYPE to NULL, available and then
8618    has to count the parser context.  */
8619
8620 static tree
8621 build_current_thisn (type)
8622     tree type;
8623 {
8624   static int saved_i = -1;
8625   static tree saved_thisn = NULL_TREE;
8626   static tree saved_type = NULL_TREE;
8627   static int saved_type_i = 0;
8628   static int initialized_p;
8629   tree decl;
8630   char buffer [24];
8631   int i = 0;
8632
8633   /* Register SAVED_THISN and SAVED_TYPE with the garbage collector.  */
8634   if (!initialized_p)
8635     {
8636       ggc_add_tree_root (&saved_thisn, 1);
8637       ggc_add_tree_root (&saved_type, 1);
8638       initialized_p = 1;
8639     }
8640
8641   if (type)
8642     {
8643       if (type == saved_type)
8644         i = saved_type_i;
8645       else
8646         {
8647           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
8648                decl; decl = DECL_CONTEXT (decl), i++)
8649             ;
8650       
8651           saved_type = type;
8652           saved_type_i = i;
8653         }
8654     }
8655   else
8656     i = list_length (GET_CPC_LIST ())-2;
8657
8658   if (i == saved_i)
8659     return saved_thisn;
8660     
8661   sprintf (buffer, "this$%d", i);
8662   saved_i = i;
8663   saved_thisn = get_identifier (buffer);
8664   return saved_thisn;
8665 }
8666
8667 /* Return the assignement to the hidden enclosing context `this$<n>'
8668    by the second incoming parameter to the innerclass constructor. The
8669    form used is `this.this$<n> = this$<n>;'.  */
8670
8671 static tree
8672 build_thisn_assign ()
8673 {
8674   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
8675     {
8676       tree thisn = build_current_thisn (current_class);
8677       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
8678                                          build_wfl_node (thisn), 0);
8679       tree rhs = build_wfl_node (thisn);
8680       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
8681       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
8682     }
8683   return NULL_TREE;
8684 }
8685
8686 \f
8687 /* Building the synthetic `class$' used to implement the `.class' 1.1
8688    extension for non primitive types. This method looks like:
8689
8690     static Class class$(String type) throws NoClassDefFoundError
8691     {
8692       try {return (java.lang.Class.forName (String));}
8693       catch (ClassNotFoundException e) {
8694         throw new NoClassDefFoundError(e.getMessage());}
8695     } */
8696
8697 static tree
8698 build_dot_class_method (class)
8699      tree class;
8700 {
8701 #define BWF(S) build_wfl_node (get_identifier ((S)))
8702 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8703   tree args, tmp, saved_current_function_decl, mdecl;
8704   tree stmt, throw_stmt;
8705
8706   static tree get_message_wfl, type_parm_wfl;
8707
8708   if (!get_message_wfl)
8709     {
8710       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8711       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8712       ggc_add_tree_root (&get_message_wfl, 1);
8713       ggc_add_tree_root (&type_parm_wfl, 1);
8714     }
8715
8716   /* Build the arguments */
8717   args = build_tree_list (get_identifier ("type$"),
8718                           build_pointer_type (string_type_node));
8719   TREE_CHAIN (args) = end_params_node;
8720
8721   /* Build the qualified name java.lang.Class.forName */
8722   tmp = MQN (MQN (MQN (BWF ("java"), 
8723                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8724   load_class (class_not_found_type_node, 1);
8725   load_class (no_class_def_found_type_node, 1);
8726   
8727   /* Create the "class$" function */
8728   mdecl = create_artificial_method (class, ACC_STATIC, 
8729                                     build_pointer_type (class_type_node),
8730                                     classdollar_identifier_node, args);
8731   DECL_FUNCTION_THROWS (mdecl) = 
8732     build_tree_list (NULL_TREE, no_class_def_found_type_node);
8733
8734   /* We start by building the try block. We need to build:
8735        return (java.lang.Class.forName (type)); */
8736   stmt = build_method_invocation (tmp, 
8737                                   build_tree_list (NULL_TREE, type_parm_wfl));
8738   stmt = build_return (0, stmt);
8739
8740   /* Now onto the catch block. We start by building the expression
8741      throwing a new exception: throw new NoClassDefFoundError (_.getMessage) */
8742   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8743                                     get_message_wfl, 0);
8744   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8745   
8746   /* Build new NoClassDefFoundError (_.getMessage) */
8747   throw_stmt = build_new_invocation 
8748     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8749      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8750
8751   /* Build the throw, (it's too early to use BUILD_THROW) */
8752   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8753
8754   /* Encapsulate STMT in a try block. The catch clause executes THROW_STMT */
8755   stmt = encapsulate_with_try_catch (0, class_not_found_type_node,
8756                                      stmt, throw_stmt);
8757
8758   fix_method_argument_names (args, mdecl);
8759   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8760   saved_current_function_decl = current_function_decl;
8761   start_artificial_method_body (mdecl);
8762   java_method_add_stmt (mdecl, stmt);
8763   end_artificial_method_body (mdecl);
8764   current_function_decl = saved_current_function_decl;
8765   TYPE_DOT_CLASS (class) = mdecl;
8766
8767   return mdecl;
8768 }
8769
8770 static tree
8771 build_dot_class_method_invocation (type)
8772      tree type;
8773 {
8774   tree sig_id, s;
8775
8776   if (TYPE_ARRAY_P (type))
8777     sig_id = build_java_signature (type);
8778   else
8779     sig_id = DECL_NAME (TYPE_NAME (type));
8780
8781   /* Ensure that the proper name separator is used */
8782   sig_id = unmangle_classname (IDENTIFIER_POINTER (sig_id),
8783                                IDENTIFIER_LENGTH (sig_id));
8784
8785   s = build_string (IDENTIFIER_LENGTH (sig_id), 
8786                     IDENTIFIER_POINTER (sig_id));
8787   return build_method_invocation (build_wfl_node (classdollar_identifier_node),
8788                                   build_tree_list (NULL_TREE, s));
8789 }
8790
8791 /* This section of the code deals with constructor.  */
8792
8793 /* Craft a body for default constructor. Patch existing constructor
8794    bodies with call to super() and field initialization statements if
8795    necessary.  */
8796
8797 static void
8798 fix_constructors (mdecl)
8799      tree mdecl;
8800 {
8801   tree iii;                     /* Instance Initializer Invocation */
8802   tree body = DECL_FUNCTION_BODY (mdecl);
8803   tree thisn_assign, compound = NULL_TREE;
8804   tree class_type = DECL_CONTEXT (mdecl);
8805
8806   if (DECL_FIXED_CONSTRUCTOR_P (mdecl))
8807     return;
8808   DECL_FIXED_CONSTRUCTOR_P (mdecl) = 1;
8809
8810   if (!body)
8811     {
8812       /* It is an error for the compiler to generate a default
8813          constructor if the superclass doesn't have a constructor that
8814          takes no argument, or the same args for an anonymous class */
8815       if (verify_constructor_super (mdecl))
8816         {
8817           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8818           tree save = DECL_NAME (mdecl);
8819           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8820           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8821           parse_error_context
8822             (lookup_cl (TYPE_NAME (class_type)), 
8823              "No constructor matching `%s' found in class `%s'",
8824              lang_printable_name (mdecl, 0), n);
8825           DECL_NAME (mdecl) = save;
8826         }
8827       
8828       /* The constructor body must be crafted by hand. It's the
8829          constructor we defined when we realize we didn't have the
8830          CLASSNAME() constructor */
8831       start_artificial_method_body (mdecl);
8832       
8833       /* Insert an assignment to the this$<n> hidden field, if
8834          necessary */
8835       if ((thisn_assign = build_thisn_assign ()))
8836         java_method_add_stmt (mdecl, thisn_assign);
8837
8838       /* We don't generate a super constructor invocation if we're
8839          compiling java.lang.Object. build_super_invocation takes care
8840          of that. */
8841       java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8842
8843       /* FIXME */
8844       if ((iii = build_instinit_invocation (class_type)))
8845         java_method_add_stmt (mdecl, iii);
8846
8847       end_artificial_method_body (mdecl);
8848     }
8849   /* Search for an explicit constructor invocation */
8850   else 
8851     {
8852       int found = 0;
8853       int invokes_this = 0;
8854       tree found_call = NULL_TREE;
8855       tree main_block = BLOCK_EXPR_BODY (body);
8856       
8857       while (body)
8858         switch (TREE_CODE (body))
8859           {
8860           case CALL_EXPR:
8861             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8862             if (CALL_THIS_CONSTRUCTOR_P (body))
8863               invokes_this = 1;
8864             body = NULL_TREE;
8865             break;
8866           case COMPOUND_EXPR:
8867           case EXPR_WITH_FILE_LOCATION:
8868             found_call = body;
8869             body = TREE_OPERAND (body, 0);
8870             break;
8871           case BLOCK:
8872             found_call = body;
8873             body = BLOCK_EXPR_BODY (body);
8874             break;
8875           default:
8876             found = 0;
8877             body = NULL_TREE;
8878           }
8879
8880       /* Generate the assignment to this$<n>, if necessary */
8881       if ((thisn_assign = build_thisn_assign ()))
8882         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8883
8884       /* The constructor is missing an invocation of super() */
8885       if (!found)
8886         compound = add_stmt_to_compound (compound, NULL_TREE,
8887                                          build_super_invocation (mdecl));
8888       /* Explicit super() invokation should take place before the
8889          instance initializer blocks. */
8890       else
8891         {
8892           compound = add_stmt_to_compound (compound, NULL_TREE,
8893                                            TREE_OPERAND (found_call, 0));
8894           TREE_OPERAND (found_call, 0) = empty_stmt_node;
8895         }
8896       
8897       DECL_INIT_CALLS_THIS (mdecl) = invokes_this;
8898
8899       /* Insert the instance initializer block right after. */
8900       if (!invokes_this && (iii = build_instinit_invocation (class_type)))
8901         compound = add_stmt_to_compound (compound, NULL_TREE, iii);
8902
8903       /* Fix the constructor main block if we're adding extra stmts */
8904       if (compound)
8905         {
8906           compound = add_stmt_to_compound (compound, NULL_TREE,
8907                                            BLOCK_EXPR_BODY (main_block));
8908           BLOCK_EXPR_BODY (main_block) = compound;
8909         }
8910     }
8911 }
8912
8913 /* Browse constructors in the super class, searching for a constructor
8914    that doesn't take any argument. Return 0 if one is found, 1
8915    otherwise.  If the current class is an anonymous inner class, look
8916    for something that has the same signature. */
8917
8918 static int
8919 verify_constructor_super (mdecl)
8920      tree mdecl;
8921 {
8922   tree class = CLASSTYPE_SUPER (current_class);
8923   int super_inner = PURE_INNER_CLASS_TYPE_P (class);
8924   tree sdecl;
8925
8926   if (!class)
8927     return 0;
8928
8929   if (ANONYMOUS_CLASS_P (current_class))
8930     {
8931       tree mdecl_arg_type;
8932       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8933       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8934         if (DECL_CONSTRUCTOR_P (sdecl))
8935           {
8936             tree m_arg_type;
8937             tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8938             if (super_inner)
8939               arg_type = TREE_CHAIN (arg_type);
8940             for (m_arg_type = mdecl_arg_type; 
8941                  (arg_type != end_params_node 
8942                   && m_arg_type != end_params_node);
8943                  arg_type = TREE_CHAIN (arg_type), 
8944                    m_arg_type = TREE_CHAIN (m_arg_type))
8945               if (!valid_method_invocation_conversion_p 
8946                      (TREE_VALUE (arg_type),
8947                       TREE_VALUE (m_arg_type)))
8948                 break;
8949
8950             if (arg_type == end_params_node && m_arg_type == end_params_node)
8951               return 0;
8952           }
8953     }
8954   else
8955     {
8956       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8957         {
8958           tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8959           if (super_inner)
8960             arg = TREE_CHAIN (arg);
8961           if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
8962             return 0;
8963         }
8964     }
8965   return 1;
8966 }
8967
8968 /* Generate code for all context remembered for code generation.  */
8969
8970 void
8971 java_expand_classes ()
8972 {
8973   int save_error_count = 0;
8974   static struct parser_ctxt *cur_ctxp = NULL;
8975
8976   java_parse_abort_on_error ();
8977   if (!(ctxp = ctxp_for_generation))
8978     return;
8979   java_layout_classes ();
8980   java_parse_abort_on_error ();
8981
8982   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
8983     {
8984       ctxp = cur_ctxp;
8985       input_filename = ctxp->filename;
8986       lang_init_source (2);            /* Error msgs have method prototypes */
8987       java_complete_expand_classes (); /* Complete and expand classes */
8988       java_parse_abort_on_error ();
8989     }
8990   input_filename = main_input_filename;
8991
8992
8993   /* Find anonymous classes and expand their constructor. This extra pass is
8994      neccessary because the constructor itself is only generated when the
8995      method in which it is defined is expanded. */
8996   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
8997     {
8998       tree current;
8999       ctxp = cur_ctxp;
9000       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
9001         {
9002           current_class = TREE_TYPE (current);
9003           if (ANONYMOUS_CLASS_P (current_class))
9004             {
9005               tree d;
9006               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
9007                 {
9008                   if (DECL_CONSTRUCTOR_P (d))
9009                     {
9010                       restore_line_number_status (1);
9011                       java_complete_expand_method (d);
9012                       restore_line_number_status (0);
9013                       break;    /* There is only one constructor. */
9014                     }
9015                 }
9016             }
9017         }
9018     }
9019
9020   /* If we've found error at that stage, don't try to generate
9021      anything, unless we're emitting xrefs or checking the syntax only
9022      (but not using -fsyntax-only for the purpose of generating
9023      bytecode. */
9024   if (java_error_count && !flag_emit_xref 
9025       && (!flag_syntax_only && !flag_emit_class_files))
9026     return;
9027
9028   /* Now things are stable, go for generation of the class data. */
9029
9030   /* We pessimistically marked all fields external until we knew
9031      what set of classes we were planning to compile.  Now mark
9032      those that will be generated locally as not external.  */
9033   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
9034     {
9035       tree current;
9036       ctxp = cur_ctxp;
9037       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
9038         {
9039           tree class = TREE_TYPE (current);
9040           tree field;
9041           for (field = TYPE_FIELDS (class); field ; field = TREE_CHAIN (field))
9042             if (FIELD_STATIC (field))
9043               DECL_EXTERNAL (field) = 0;
9044         }
9045     }
9046
9047   /* Compile the classes.  */
9048   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
9049     {
9050       tree current;
9051       ctxp = cur_ctxp;
9052       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
9053         {
9054           current_class = TREE_TYPE (current);
9055           outgoing_cpool = TYPE_CPOOL (current_class);
9056           if (flag_emit_class_files)
9057             write_classfile (current_class);
9058           if (flag_emit_xref)
9059             expand_xref (current_class);
9060           else if (! flag_syntax_only)
9061             {
9062               java_expand_method_bodies (current_class);
9063               finish_class ();
9064             }
9065         }
9066     }
9067 }
9068
9069 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
9070    a tree list node containing RIGHT. Fore coming RIGHTs will be
9071    chained to this hook. LOCATION contains the location of the
9072    separating `.' operator.  */
9073
9074 static tree
9075 make_qualified_primary (primary, right, location)
9076      tree primary, right;
9077      int location;
9078 {
9079   tree wfl;
9080
9081   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
9082     wfl = build_wfl_wrap (primary, location);
9083   else
9084     {
9085       wfl = primary;
9086       /* If wfl wasn't qualified, we build a first anchor */
9087       if (!EXPR_WFL_QUALIFICATION (wfl))
9088         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
9089     }
9090
9091   /* And chain them */
9092   EXPR_WFL_LINECOL (right) = location;
9093   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
9094   PRIMARY_P (wfl) =  1;
9095   return wfl;
9096 }
9097
9098 /* Simple merge of two name separated by a `.' */
9099
9100 static tree
9101 merge_qualified_name (left, right)
9102      tree left, right;
9103 {
9104   tree node;
9105   if (!left && !right)
9106     return NULL_TREE;
9107
9108   if (!left)
9109     return right;
9110
9111   if (!right)
9112     return left;
9113
9114   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
9115                 IDENTIFIER_LENGTH (left));
9116   obstack_1grow (&temporary_obstack, '.');
9117   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
9118                  IDENTIFIER_LENGTH (right));
9119   node =  get_identifier (obstack_base (&temporary_obstack));
9120   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
9121   QUALIFIED_P (node) = 1;
9122   return node;
9123 }
9124
9125 /* Merge the two parts of a qualified name into LEFT.  Set the
9126    location information of the resulting node to LOCATION, usually
9127    inherited from the location information of the `.' operator. */
9128
9129 static tree
9130 make_qualified_name (left, right, location)
9131      tree left, right;
9132      int location;
9133 {
9134 #ifdef USE_COMPONENT_REF
9135   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
9136   EXPR_WFL_LINECOL (node) = location;
9137   return node;
9138 #else
9139   tree left_id = EXPR_WFL_NODE (left);
9140   tree right_id = EXPR_WFL_NODE (right);
9141   tree wfl, merge;
9142
9143   merge = merge_qualified_name (left_id, right_id);
9144
9145   /* Left wasn't qualified and is now qualified */
9146   if (!QUALIFIED_P (left_id))
9147     {
9148       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
9149       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
9150       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
9151     }
9152   
9153   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
9154   EXPR_WFL_LINECOL (wfl) = location;
9155   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
9156
9157   EXPR_WFL_NODE (left) = merge;
9158   return left;
9159 #endif
9160 }
9161
9162 /* Extract the last identifier component of the qualified in WFL. The
9163    last identifier is removed from the linked list */
9164
9165 static tree
9166 cut_identifier_in_qualified (wfl)
9167      tree wfl;
9168 {
9169   tree q;
9170   tree previous = NULL_TREE;
9171   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
9172     if (!TREE_CHAIN (q))
9173       {
9174         if (!previous)
9175           /* Operating on a non qualified qualified WFL.  */
9176           abort ();
9177
9178         TREE_CHAIN (previous) = NULL_TREE;
9179         return TREE_PURPOSE (q);
9180       }
9181 }
9182
9183 /* Resolve the expression name NAME. Return its decl.  */
9184
9185 static tree
9186 resolve_expression_name (id, orig)
9187      tree id;
9188      tree *orig;
9189 {
9190   tree name = EXPR_WFL_NODE (id);
9191   tree decl;
9192
9193   /* 6.5.5.1: Simple expression names */
9194   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
9195     {
9196       /* 15.13.1: NAME can appear within the scope of a local variable
9197          declaration */
9198       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
9199         return decl;
9200
9201       /* 15.13.1: NAME can appear within a class declaration */
9202       else 
9203         {
9204           decl = lookup_field_wrapper (current_class, name);
9205           if (decl)
9206             {
9207               tree access = NULL_TREE;
9208               int fs = FIELD_STATIC (decl);
9209
9210               /* If we're accessing an outer scope local alias, make
9211                  sure we change the name of the field we're going to
9212                  build access to. */
9213               if (FIELD_LOCAL_ALIAS_USED (decl))
9214                 name = DECL_NAME (decl);
9215
9216               /* Instance variable (8.3.1.1) can't appear within
9217                  static method, static initializer or initializer for
9218                  a static variable. */
9219               if (!fs && METHOD_STATIC (current_function_decl))
9220                 {
9221                   static_ref_err (id, name, current_class);
9222                   return error_mark_node;
9223                 }
9224               /* Instance variables can't appear as an argument of
9225                  an explicit constructor invocation */
9226               if (!fs && ctxp->explicit_constructor_p
9227                   && !enclosing_context_p (DECL_CONTEXT (decl), current_class))
9228                 {
9229                   parse_error_context
9230                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
9231                   return error_mark_node;
9232                 }
9233
9234               /* If we're processing an inner class and we're trying
9235                  to access a field belonging to an outer class, build
9236                  the access to the field */
9237               if (!fs && outer_field_access_p (current_class, decl))
9238                 {
9239                   if (CLASS_STATIC (TYPE_NAME (current_class)))
9240                     {
9241                       static_ref_err (id, DECL_NAME (decl), current_class);
9242                       return error_mark_node;
9243                     }
9244                   access = build_outer_field_access (id, decl);
9245                   if (orig)
9246                     *orig = access;
9247                   return access;
9248                 }
9249
9250               /* Otherwise build what it takes to access the field */
9251               access = build_field_ref ((fs ? NULL_TREE : current_this),
9252                                         DECL_CONTEXT (decl), name);
9253               if (fs)
9254                 access = maybe_build_class_init_for_field (decl, access);
9255               /* We may be asked to save the real field access node */
9256               if (orig)
9257                 *orig = access;
9258               /* And we return what we got */
9259               return access;
9260             }
9261           /* Fall down to error report on undefined variable */
9262         }
9263     }
9264   /* 6.5.5.2 Qualified Expression Names */
9265   else
9266     {
9267       if (orig)
9268         *orig = NULL_TREE;
9269       qualify_ambiguous_name (id);
9270       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
9271       /* 15.10.2: Accessing Superclass Members using super */
9272       return resolve_field_access (id, orig, NULL);
9273     }
9274
9275   /* We've got an error here */
9276   if (INNER_CLASS_TYPE_P (current_class))
9277     parse_error_context (id, 
9278                          "Local variable `%s' can't be accessed from within the inner class `%s' unless it is declared final",
9279                          IDENTIFIER_POINTER (name),
9280                          IDENTIFIER_POINTER (DECL_NAME
9281                                              (TYPE_NAME (current_class))));
9282   else
9283     parse_error_context (id, "Undefined variable `%s'", 
9284                          IDENTIFIER_POINTER (name));
9285
9286   return error_mark_node;
9287 }
9288
9289 static void
9290 static_ref_err (wfl, field_id, class_type)
9291     tree wfl, field_id, class_type;
9292 {
9293   parse_error_context 
9294     (wfl, 
9295      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
9296      IDENTIFIER_POINTER (field_id), 
9297      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
9298 }
9299
9300 /* 15.10.1 Field Access Using a Primary and/or Expression Name.
9301    We return something suitable to generate the field access. We also
9302    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
9303    recipient's address can be null. */
9304
9305 static tree
9306 resolve_field_access (qual_wfl, field_decl, field_type)
9307      tree qual_wfl;
9308      tree *field_decl, *field_type;
9309 {
9310   int is_static = 0;
9311   tree field_ref;
9312   tree decl, where_found, type_found;
9313
9314   if (resolve_qualified_expression_name (qual_wfl, &decl,
9315                                          &where_found, &type_found))
9316     return error_mark_node;
9317
9318   /* Resolve the LENGTH field of an array here */
9319   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
9320       && type_found && TYPE_ARRAY_P (type_found) 
9321       && ! flag_emit_class_files && ! flag_emit_xref)
9322     {
9323       tree length = build_java_array_length_access (where_found);
9324       field_ref = length;
9325
9326       /* In case we're dealing with a static array, we need to
9327          initialize its class before the array length can be fetched.
9328          It's also a good time to create a DECL_RTL for the field if
9329          none already exists, otherwise if the field was declared in a
9330          class found in an external file and hasn't been (and won't
9331          be) accessed for its value, none will be created. */
9332       if (TREE_CODE (where_found) == VAR_DECL && FIELD_STATIC (where_found))
9333         {
9334           build_static_field_ref (where_found);
9335           field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
9336         }
9337     }
9338   /* We might have been trying to resolve field.method(). In which
9339      case, the resolution is over and decl is the answer */
9340   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
9341     field_ref = decl;
9342   else if (JDECL_P (decl))
9343     {
9344       if (!type_found)
9345         type_found = DECL_CONTEXT (decl);
9346       is_static = FIELD_STATIC (decl);
9347       field_ref = build_field_ref ((is_static && !flag_emit_xref? 
9348                                     NULL_TREE : where_found), 
9349                                    type_found, DECL_NAME (decl));
9350       if (field_ref == error_mark_node)
9351         return error_mark_node;
9352       if (is_static)
9353         field_ref = maybe_build_class_init_for_field (decl, field_ref);
9354     }
9355   else
9356     field_ref = decl;
9357
9358   if (field_decl)
9359     *field_decl = decl;
9360   if (field_type)
9361     *field_type = (QUAL_DECL_TYPE (decl) ? 
9362                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
9363   return field_ref;
9364 }
9365
9366 /* If NODE is an access to f static field, strip out the class
9367    initialization part and return the field decl, otherwise, return
9368    NODE. */
9369
9370 static tree
9371 strip_out_static_field_access_decl (node)
9372     tree node;
9373 {
9374   if (TREE_CODE (node) == COMPOUND_EXPR)
9375     {
9376       tree op1 = TREE_OPERAND (node, 1);
9377       if (TREE_CODE (op1) == COMPOUND_EXPR)
9378          {
9379            tree call = TREE_OPERAND (op1, 0);
9380            if (TREE_CODE (call) == CALL_EXPR
9381                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
9382                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
9383                == soft_initclass_node)
9384              return TREE_OPERAND (op1, 1);
9385          }
9386       else if (JDECL_P (op1))
9387         return op1;
9388     }
9389   return node;
9390 }
9391
9392 /* 6.5.5.2: Qualified Expression Names */
9393
9394 static int
9395 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
9396      tree wfl;
9397      tree *found_decl, *type_found, *where_found;
9398 {
9399   int from_type = 0;            /* Field search initiated from a type */
9400   int from_super = 0, from_cast = 0, from_qualified_this = 0;
9401   int previous_call_static = 0;
9402   int is_static;
9403   tree decl = NULL_TREE, type = NULL_TREE, q;
9404   /* For certain for of inner class instantiation */
9405   tree saved_current, saved_this;               
9406 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
9407   { current_class = saved_current; current_this = saved_this;}
9408
9409   *type_found = *where_found = NULL_TREE;
9410
9411   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
9412     {
9413       tree qual_wfl = QUAL_WFL (q);
9414       tree ret_decl;            /* for EH checking */
9415       int location;             /* for EH checking */
9416
9417       /* 15.10.1 Field Access Using a Primary */
9418       switch (TREE_CODE (qual_wfl))
9419         {
9420         case CALL_EXPR:
9421         case NEW_CLASS_EXPR:
9422           /* If the access to the function call is a non static field,
9423              build the code to access it. */
9424           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9425             {
9426               decl = maybe_access_field (decl, *where_found, 
9427                                          DECL_CONTEXT (decl));
9428               if (decl == error_mark_node)
9429                 return 1;
9430             }
9431
9432           /* And code for the function call */
9433           if (complete_function_arguments (qual_wfl))
9434             return 1;
9435
9436           /* We might have to setup a new current class and a new this
9437              for the search of an inner class, relative to the type of
9438              a expression resolved as `decl'. The current values are
9439              saved and restored shortly after */
9440           saved_current = current_class;
9441           saved_this = current_this;
9442           if (decl 
9443               && (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9444                   || from_qualified_this))
9445             {
9446               /* If we still have `from_qualified_this', we have the form
9447                  <T>.this.f() and we need to build <T>.this */
9448               if (from_qualified_this)
9449                 {
9450                   decl = build_access_to_thisn (current_class, type, 0);
9451                   decl = java_complete_tree (decl);
9452                   type = TREE_TYPE (TREE_TYPE (decl));
9453                 }
9454               current_class = type;
9455               current_this = decl;
9456               from_qualified_this = 0;
9457             }
9458
9459           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
9460             CALL_USING_SUPER (qual_wfl) = 1;
9461           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
9462                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
9463           *where_found = patch_method_invocation (qual_wfl, decl, type,
9464                                                   from_super,
9465                                                   &is_static, &ret_decl);
9466           from_super = 0;
9467           if (*where_found == error_mark_node)
9468             {
9469               RESTORE_THIS_AND_CURRENT_CLASS;
9470               return 1;
9471             }
9472           *type_found = type = QUAL_DECL_TYPE (*where_found);
9473
9474           /* If we're creating an inner class instance, check for that
9475              an enclosing instance is in scope */
9476           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9477               && INNER_ENCLOSING_SCOPE_CHECK (type))
9478             {
9479               parse_error_context 
9480                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
9481                  lang_printable_name (type, 0),
9482                  (!current_this ? "" :
9483                   "; an explicit one must be provided when creating this inner class"));
9484               RESTORE_THIS_AND_CURRENT_CLASS;
9485               return 1;
9486             }
9487
9488           /* In case we had to change then to resolve a inner class
9489              instantiation using a primary qualified by a `new' */
9490           RESTORE_THIS_AND_CURRENT_CLASS;
9491
9492           /* EH check. No check on access$<n> functions */
9493           if (location 
9494               && !OUTER_FIELD_ACCESS_IDENTIFIER_P 
9495                     (DECL_NAME (current_function_decl)))
9496             check_thrown_exceptions (location, ret_decl);
9497
9498           /* If the previous call was static and this one is too,
9499              build a compound expression to hold the two (because in
9500              that case, previous function calls aren't transported as
9501              forcoming function's argument. */
9502           if (previous_call_static && is_static)
9503             {
9504               decl = build (COMPOUND_EXPR, TREE_TYPE (*where_found),
9505                             decl, *where_found);
9506               TREE_SIDE_EFFECTS (decl) = 1;
9507             }
9508           else
9509             {
9510               previous_call_static = is_static;
9511               decl = *where_found;
9512             }
9513           from_type = 0;
9514           continue;
9515
9516         case NEW_ARRAY_EXPR:
9517         case NEW_ANONYMOUS_ARRAY_EXPR:
9518           *where_found = decl = java_complete_tree (qual_wfl);
9519           if (decl == error_mark_node)
9520             return 1;
9521           *type_found = type = QUAL_DECL_TYPE (decl);
9522           continue;
9523
9524         case CONVERT_EXPR:
9525           *where_found = decl = java_complete_tree (qual_wfl);
9526           if (decl == error_mark_node)
9527             return 1;
9528           *type_found = type = QUAL_DECL_TYPE (decl);
9529           from_cast = 1;
9530           continue;
9531
9532         case CONDITIONAL_EXPR:
9533         case STRING_CST:
9534         case MODIFY_EXPR:
9535           *where_found = decl = java_complete_tree (qual_wfl);
9536           if (decl == error_mark_node)
9537             return 1;
9538           *type_found = type = QUAL_DECL_TYPE (decl);
9539           continue;
9540
9541         case ARRAY_REF:
9542           /* If the access to the function call is a non static field,
9543              build the code to access it. */
9544           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9545             {
9546               decl = maybe_access_field (decl, *where_found, type);
9547               if (decl == error_mark_node)
9548                 return 1;
9549             }
9550           /* And code for the array reference expression */
9551           decl = java_complete_tree (qual_wfl);
9552           if (decl == error_mark_node)
9553             return 1;
9554           type = QUAL_DECL_TYPE (decl);
9555           continue;
9556
9557         case PLUS_EXPR:
9558           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9559             return 1;
9560           if ((type = patch_string (decl)))
9561             decl = type;
9562           *where_found = QUAL_RESOLUTION (q) = decl;
9563           *type_found = type = TREE_TYPE (decl);
9564           break;
9565
9566         case CLASS_LITERAL:
9567           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9568             return 1;
9569           *where_found = QUAL_RESOLUTION (q) = decl;
9570           *type_found = type = TREE_TYPE (decl);
9571           break;
9572
9573         default:
9574           /* Fix for -Wall Just go to the next statement. Don't
9575              continue */
9576           break;
9577         }
9578
9579       /* If we fall here, we weren't processing a (static) function call. */
9580       previous_call_static = 0;
9581
9582       /* It can be the keyword THIS */
9583       if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION
9584           && EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
9585         {
9586           if (!current_this)
9587             {
9588               parse_error_context 
9589                 (wfl, "Keyword `this' used outside allowed context");
9590               return 1;
9591             }
9592           if (ctxp->explicit_constructor_p
9593               && type == current_class)
9594             {
9595               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9596               return 1;
9597             }
9598           /* We have to generate code for intermediate access */
9599           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
9600             {
9601               *where_found = decl = current_this;
9602               *type_found = type = QUAL_DECL_TYPE (decl);
9603             }
9604           /* We're trying to access the this from somewhere else. Make sure
9605              it's allowed before doing so. */
9606           else
9607             {
9608               if (!enclosing_context_p (type, current_class))
9609                 {
9610                   char *p  = xstrdup (lang_printable_name (type, 0));
9611                   parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'", 
9612                                        p, p, 
9613                                        lang_printable_name (current_class, 0));
9614                   free (p);
9615                   return 1;
9616                 }
9617               from_qualified_this = 1;
9618               /* If there's nothing else after that, we need to
9619                  produce something now, otherwise, the section of the
9620                  code that needs to produce <T>.this will generate
9621                  what is necessary. */
9622               if (!TREE_CHAIN (q))
9623                 {
9624                   decl = build_access_to_thisn (current_class, type, 0);
9625                   *where_found = decl = java_complete_tree (decl);
9626                   *type_found = type = TREE_TYPE (decl);
9627                 }
9628             }
9629
9630           from_type = 0;
9631           continue;
9632         }
9633
9634       /* 15.10.2 Accessing Superclass Members using SUPER */
9635       if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION
9636           && EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
9637         {
9638           tree node;
9639           /* Check on the restricted use of SUPER */
9640           if (METHOD_STATIC (current_function_decl)
9641               || current_class == object_type_node)
9642             {
9643               parse_error_context 
9644                 (wfl, "Keyword `super' used outside allowed context");
9645               return 1;
9646             }
9647           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
9648           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
9649                              CLASSTYPE_SUPER (current_class),
9650                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
9651           *where_found = decl = java_complete_tree (node);
9652           if (decl == error_mark_node)
9653             return 1;
9654           *type_found = type = QUAL_DECL_TYPE (decl);
9655           from_super = from_type = 1;
9656           continue;
9657         }
9658
9659       /* 15.13.1: Can't search for field name in packages, so we
9660          assume a variable/class name was meant. */
9661       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
9662         {
9663           tree name;
9664           if ((decl = resolve_package (wfl, &q, &name)))
9665             {
9666               tree list;
9667               *where_found = decl;
9668
9669               /* We want to be absolutely sure that the class is laid
9670                  out. We're going to search something inside it. */
9671               *type_found = type = TREE_TYPE (decl);
9672               layout_class (type);
9673               from_type = 1;
9674
9675               /* Fix them all the way down, if any are left. */
9676               if (q)
9677                 {
9678                   list = TREE_CHAIN (q);
9679                   while (list)
9680                     {
9681                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
9682                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
9683                       list = TREE_CHAIN (list);
9684                     }
9685                 }
9686             }
9687           else
9688             {
9689               if (from_super || from_cast)
9690                 parse_error_context 
9691                   ((from_cast ? qual_wfl : wfl),
9692                    "No variable `%s' defined in class `%s'",
9693                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9694                    lang_printable_name (type, 0));
9695               else
9696                 parse_error_context
9697                   (qual_wfl, "Undefined variable or class name: `%s'",
9698                    IDENTIFIER_POINTER (name));
9699               return 1;
9700             }
9701         }
9702
9703       /* We have a type name. It's been already resolved when the
9704          expression was qualified. */
9705       else if (RESOLVE_TYPE_NAME_P (qual_wfl) && QUAL_RESOLUTION (q))
9706         {
9707           decl = QUAL_RESOLUTION (q);
9708
9709           /* Sneak preview. If next we see a `new', we're facing a
9710              qualification with resulted in a type being selected
9711              instead of a field.  Report the error */
9712           if(TREE_CHAIN (q) 
9713              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
9714             {
9715               parse_error_context (qual_wfl, "Undefined variable `%s'",
9716                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9717               return 1;
9718             }
9719
9720           if (not_accessible_p (TREE_TYPE (decl), decl, type, 0))
9721             {
9722               parse_error_context 
9723                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
9724                  java_accstring_lookup (get_access_flags_from_decl (decl)),
9725                  GET_TYPE_NAME (type),
9726                  IDENTIFIER_POINTER (DECL_NAME (decl)),
9727                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9728               return 1;
9729             }
9730           check_deprecation (qual_wfl, decl);
9731
9732           type = TREE_TYPE (decl);
9733           from_type = 1;
9734         }
9735       /* We resolve an expression name */
9736       else 
9737         {
9738           tree field_decl = NULL_TREE;
9739
9740           /* If there exists an early resolution, use it. That occurs
9741              only once and we know that there are more things to
9742              come. Don't do that when processing something after SUPER
9743              (we need more thing to be put in place below */
9744           if (!from_super && QUAL_RESOLUTION (q))
9745             {
9746               decl = QUAL_RESOLUTION (q);
9747               if (!type)
9748                 {
9749                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
9750                     {
9751                       if (current_this)
9752                         *where_found = current_this;
9753                       else
9754                         {
9755                           static_ref_err (qual_wfl, DECL_NAME (decl),
9756                                           current_class);
9757                           return 1;
9758                         }
9759                       if (outer_field_access_p (current_class, decl))
9760                         decl = build_outer_field_access (qual_wfl, decl);
9761                     }
9762                   else
9763                     {
9764                       *where_found = TREE_TYPE (decl);
9765                       if (TREE_CODE (*where_found) == POINTER_TYPE)
9766                         *where_found = TREE_TYPE (*where_found);
9767                     }
9768                 }
9769             }
9770
9771           /* Report and error if we're using a numerical litteral as a
9772              qualifier. It can only be an INTEGER_CST. */
9773           else if (TREE_CODE (qual_wfl) == INTEGER_CST)
9774             {
9775               parse_error_context
9776                 (wfl, "Can't use type `%s' as a qualifier",
9777                  lang_printable_name (TREE_TYPE (qual_wfl), 0));
9778               return 1;
9779             }
9780
9781           /* We have to search for a field, knowing the type of its
9782              container. The flag FROM_TYPE indicates that we resolved
9783              the last member of the expression as a type name, which
9784              means that for the resolution of this field, we'll look
9785              for other errors than if it was resolved as a member of
9786              an other field. */
9787           else
9788             {
9789               int is_static;
9790               tree field_decl_type; /* For layout */
9791
9792               if (!from_type && !JREFERENCE_TYPE_P (type))
9793                 {
9794                   parse_error_context 
9795                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9796                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9797                      lang_printable_name (type, 0),
9798                      IDENTIFIER_POINTER (DECL_NAME (decl)));
9799                   return 1;
9800                 }
9801               
9802               field_decl = lookup_field_wrapper (type,
9803                                                  EXPR_WFL_NODE (qual_wfl));
9804
9805               /* Maybe what we're trying to access to is an inner
9806                  class, only if decl is a TYPE_DECL. */
9807               if (!field_decl && TREE_CODE (decl) == TYPE_DECL)
9808                 {
9809                   tree ptr, inner_decl;
9810
9811                   BUILD_PTR_FROM_NAME (ptr, EXPR_WFL_NODE (qual_wfl));
9812                   inner_decl = resolve_class (decl, ptr, NULL_TREE, qual_wfl);
9813                   if (inner_decl)
9814                     {
9815                       check_inner_class_access (inner_decl, decl, qual_wfl); 
9816                       type = TREE_TYPE (inner_decl);
9817                       decl = inner_decl;
9818                       from_type = 1;
9819                       continue;
9820                     }
9821                 }
9822
9823               if (field_decl == NULL_TREE)
9824                 {
9825                   parse_error_context 
9826                     (qual_wfl, "No variable `%s' defined in type `%s'",
9827                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9828                      GET_TYPE_NAME (type));
9829                   return 1;
9830                 }
9831               if (field_decl == error_mark_node)
9832                 return 1;
9833
9834               /* Layout the type of field_decl, since we may need
9835                  it. Don't do primitive types or loaded classes. The
9836                  situation of non primitive arrays may not handled
9837                  properly here. FIXME */
9838               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9839                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9840               else
9841                 field_decl_type = TREE_TYPE (field_decl);
9842               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9843                   && !CLASS_LOADED_P (field_decl_type)
9844                   && !TYPE_ARRAY_P (field_decl_type))
9845                 resolve_and_layout (field_decl_type, NULL_TREE);
9846               
9847               /* Check on accessibility here */
9848               if (not_accessible_p (current_class, field_decl,
9849                                     DECL_CONTEXT (field_decl), from_super))
9850                 {
9851                   parse_error_context 
9852                     (qual_wfl,
9853                      "Can't access %s field `%s.%s' from `%s'",
9854                      java_accstring_lookup 
9855                        (get_access_flags_from_decl (field_decl)),
9856                      GET_TYPE_NAME (type),
9857                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9858                      IDENTIFIER_POINTER 
9859                        (DECL_NAME (TYPE_NAME (current_class))));
9860                   return 1;
9861                 }
9862               check_deprecation (qual_wfl, field_decl);
9863               
9864               /* There are things to check when fields are accessed
9865                  from type. There are no restrictions on a static
9866                  declaration of the field when it is accessed from an
9867                  interface */
9868               is_static = FIELD_STATIC (field_decl);
9869               if (!from_super && from_type 
9870                   && !TYPE_INTERFACE_P (type) 
9871                   && !is_static 
9872                   && (current_function_decl 
9873                       && METHOD_STATIC (current_function_decl)))
9874                 {
9875                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9876                   return 1;
9877                 }
9878               from_cast = from_super = 0;
9879
9880               /* It's an access from a type but it isn't static, we
9881                  make it relative to `this'. */
9882               if (!is_static && from_type)
9883                 decl = current_this;
9884
9885               /* If we need to generate something to get a proper
9886                  handle on what this field is accessed from, do it
9887                  now. */
9888               if (!is_static)
9889                 {
9890                   decl = maybe_access_field (decl, *where_found, *type_found);
9891                   if (decl == error_mark_node)
9892                     return 1;
9893                 }
9894
9895               /* We want to keep the location were found it, and the type
9896                  we found. */
9897               *where_found = decl;
9898               *type_found = type;
9899
9900               /* Generate the correct expression for field access from
9901                  qualified this */
9902               if (from_qualified_this)
9903                 {
9904                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9905                   from_qualified_this = 0;
9906                 }
9907
9908               /* This is the decl found and eventually the next one to
9909                  search from */
9910               decl = field_decl;
9911             }
9912           from_type = 0;
9913           type = QUAL_DECL_TYPE (decl);
9914
9915           /* Sneak preview. If decl is qualified by a `new', report
9916              the error here to be accurate on the peculiar construct */
9917           if (TREE_CHAIN (q) 
9918               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9919               && !JREFERENCE_TYPE_P (type))
9920             {
9921               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9922                                    lang_printable_name (type, 0));
9923               return 1;
9924             }
9925         }
9926       /* `q' might have changed due to a after package resolution
9927          re-qualification */
9928       if (!q)
9929         break;
9930     }
9931   *found_decl = decl;
9932   return 0;
9933 }
9934
9935 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9936    can't be accessed from REFERENCE (a record type). If MEMBER
9937    features a protected access, we then use WHERE which, if non null,
9938    holds the type of MEMBER's access that is checked against
9939    6.6.2.1. This function should be used when decl is a field or a
9940    method.  */
9941
9942 static int
9943 not_accessible_p (reference, member, where, from_super)
9944      tree reference, member;
9945      tree where;
9946      int from_super;
9947 {
9948   int access_flag = get_access_flags_from_decl (member);
9949
9950   /* Inner classes are processed by check_inner_class_access */
9951   if (INNER_CLASS_TYPE_P (reference))
9952     return 0;
9953
9954   /* Access always granted for members declared public */
9955   if (access_flag & ACC_PUBLIC)
9956     return 0;
9957   
9958   /* Check access on protected members */
9959   if (access_flag & ACC_PROTECTED)
9960     {
9961       /* Access granted if it occurs from within the package
9962          containing the class in which the protected member is
9963          declared */
9964       if (class_in_current_package (DECL_CONTEXT (member)))
9965         return 0;
9966
9967       /* If accessed with the form `super.member', then access is granted */
9968       if (from_super)
9969         return 0;
9970
9971       /* If where is active, access was made through a
9972          qualifier. Access is granted if the type of the qualifier is
9973          or is a sublass of the type the access made from (6.6.2.1.)  */
9974       if (where && !inherits_from_p (reference, where))
9975         return 1;
9976
9977       /* Otherwise, access is granted if occurring from the class where
9978          member is declared or a subclass of it. Find the right
9979          context to perform the check */
9980       if (PURE_INNER_CLASS_TYPE_P (reference))
9981         {
9982           while (INNER_CLASS_TYPE_P (reference))
9983             {
9984               if (inherits_from_p (reference, DECL_CONTEXT (member)))
9985                 return 0;
9986               reference = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (reference)));
9987             }
9988         }
9989       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9990         return 0;
9991       return 1;
9992     }
9993
9994   /* Check access on private members. Access is granted only if it
9995      occurs from within the class in which it is declared -- that does
9996      it for innerclasses too. */
9997   if (access_flag & ACC_PRIVATE)
9998     {
9999       if (reference == DECL_CONTEXT (member))
10000         return 0;
10001       if (enclosing_context_p (reference, DECL_CONTEXT (member)))
10002         return 0;
10003       return 1;
10004     }
10005
10006   /* Default access are permitted only when occurring within the
10007      package in which the type (REFERENCE) is declared. In other words,
10008      REFERENCE is defined in the current package */
10009   if (ctxp->package)
10010     return !class_in_current_package (reference);
10011
10012   /* Otherwise, access is granted */
10013   return 0;
10014 }
10015
10016 /* Test deprecated decl access.  */
10017 static void
10018 check_deprecation (wfl, decl)
10019      tree wfl, decl;
10020 {
10021   const char *file = DECL_SOURCE_FILE (decl);
10022   /* Complain if the field is deprecated and the file it was defined
10023      in isn't compiled at the same time the file which contains its
10024      use is */
10025   if (DECL_DEPRECATED (decl) 
10026       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
10027     {
10028       char the [20];
10029       switch (TREE_CODE (decl))
10030         {
10031         case FUNCTION_DECL:
10032           strcpy (the, "method");
10033           break;
10034         case FIELD_DECL:
10035         case VAR_DECL:
10036           strcpy (the, "field");
10037           break;
10038         case TYPE_DECL:
10039           parse_warning_context (wfl, "The class `%s' has been deprecated",
10040                                  IDENTIFIER_POINTER (DECL_NAME (decl)));
10041           return;
10042         default:
10043           abort ();
10044         }
10045       /* Don't issue a message if the context as been deprecated as a
10046          whole. */
10047       if (! CLASS_DEPRECATED (TYPE_NAME (DECL_CONTEXT (decl))))
10048         parse_warning_context 
10049           (wfl, "The %s `%s' in class `%s' has been deprecated", 
10050            the, lang_printable_name (decl, 0),
10051            IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
10052     }
10053 }
10054
10055 /* Returns 1 if class was declared in the current package, 0 otherwise */
10056
10057 static int
10058 class_in_current_package (class)
10059      tree class;
10060 {
10061   static tree cache = NULL_TREE;
10062   int qualified_flag;
10063   tree left;
10064
10065   if (cache == class)
10066     return 1;
10067
10068   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
10069
10070   /* If the current package is empty and the name of CLASS is
10071      qualified, class isn't in the current package.  If there is a
10072      current package and the name of the CLASS is not qualified, class
10073      isn't in the current package */
10074   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
10075     return 0;
10076
10077   /* If there is not package and the name of CLASS isn't qualified,
10078      they belong to the same unnamed package */
10079   if (!ctxp->package && !qualified_flag)
10080     return 1;
10081
10082   /* Compare the left part of the name of CLASS with the package name */
10083   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
10084   if (ctxp->package == left)
10085     {
10086       static int initialized_p;
10087       /* Register CACHE with the garbage collector.  */
10088       if (!initialized_p)
10089         {
10090           ggc_add_tree_root (&cache, 1);
10091           initialized_p = 1;
10092         }
10093
10094       cache = class;
10095       return 1;
10096     }
10097   return 0;
10098 }
10099
10100 /* This function may generate code to access DECL from WHERE. This is
10101    done only if certain conditions meet.  */
10102
10103 static tree
10104 maybe_access_field (decl, where, type)
10105   tree decl, where, type;
10106 {
10107   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
10108       && !FIELD_STATIC (decl))
10109     decl = build_field_ref (where ? where : current_this, 
10110                             (type ? type : DECL_CONTEXT (decl)),
10111                             DECL_NAME (decl));
10112   return decl;
10113 }
10114
10115 /* Build a method invocation, by patching PATCH. If non NULL
10116    and according to the situation, PRIMARY and WHERE may be
10117    used. IS_STATIC is set to 1 if the invoked function is static. */
10118
10119 static tree
10120 patch_method_invocation (patch, primary, where, from_super,
10121                         is_static, ret_decl)
10122      tree patch, primary, where;
10123      int from_super;
10124      int *is_static;
10125      tree *ret_decl;
10126 {
10127   tree wfl = TREE_OPERAND (patch, 0);
10128   tree args = TREE_OPERAND (patch, 1);
10129   tree name = EXPR_WFL_NODE (wfl);
10130   tree list;
10131   int is_static_flag = 0;
10132   int is_super_init = 0;
10133   tree this_arg = NULL_TREE;
10134   int is_array_clone_call = 0;
10135   
10136   /* Should be overriden if everything goes well. Otherwise, if
10137      something fails, it should keep this value. It stop the
10138      evaluation of a bogus assignment. See java_complete_tree,
10139      MODIFY_EXPR: for the reasons why we sometimes want to keep on
10140      evaluating an assignment */
10141   TREE_TYPE (patch) = error_mark_node;
10142
10143   /* Since lookup functions are messing with line numbers, save the
10144      context now.  */
10145   java_parser_context_save_global ();
10146
10147   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
10148
10149   /* Resolution of qualified name, excluding constructors */
10150   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
10151     {
10152       tree identifier, identifier_wfl, type, resolved;
10153       /* Extract the last IDENTIFIER of the qualified
10154          expression. This is a wfl and we will use it's location
10155          data during error report. */
10156       identifier_wfl = cut_identifier_in_qualified (wfl);
10157       identifier = EXPR_WFL_NODE (identifier_wfl);
10158       
10159       /* Given the context, IDENTIFIER is syntactically qualified
10160          as a MethodName. We need to qualify what's before */
10161       qualify_ambiguous_name (wfl);
10162       resolved = resolve_field_access (wfl, NULL, NULL);
10163
10164       if (TREE_CODE (resolved) == VAR_DECL && FIELD_STATIC (resolved)
10165          && FIELD_FINAL (resolved) 
10166          && !inherits_from_p (DECL_CONTEXT (resolved), current_class)
10167          && !flag_emit_class_files && !flag_emit_xref)
10168        resolved = build_class_init (DECL_CONTEXT (resolved), resolved);
10169
10170       if (resolved == error_mark_node)
10171         PATCH_METHOD_RETURN_ERROR ();
10172
10173       type = GET_SKIP_TYPE (resolved);
10174       resolve_and_layout (type, NULL_TREE);
10175       
10176       if (JPRIMITIVE_TYPE_P (type))
10177         {
10178           parse_error_context
10179             (identifier_wfl,
10180              "Can't invoke a method on primitive type `%s'",
10181              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
10182           PATCH_METHOD_RETURN_ERROR ();         
10183         }
10184
10185       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
10186       args = nreverse (args);
10187
10188       /* We're resolving a call from a type */
10189       if (TREE_CODE (resolved) == TYPE_DECL)
10190         {
10191           if (CLASS_INTERFACE (resolved))
10192             {
10193               parse_error_context
10194                 (identifier_wfl,
10195                 "Can't make static reference to method `%s' in interface `%s'",
10196                  IDENTIFIER_POINTER (identifier), 
10197                  IDENTIFIER_POINTER (name));
10198               PATCH_METHOD_RETURN_ERROR ();
10199             }
10200           if (list && !METHOD_STATIC (list))
10201             {
10202               char *fct_name = xstrdup (lang_printable_name (list, 0));
10203               parse_error_context 
10204                 (identifier_wfl,
10205                  "Can't make static reference to method `%s %s' in class `%s'",
10206                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
10207                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
10208               free (fct_name);
10209               PATCH_METHOD_RETURN_ERROR ();
10210             }
10211         }
10212       else
10213         this_arg = primary = resolved;
10214       
10215       if (TYPE_ARRAY_P (type) && identifier == get_identifier ("clone"))
10216         is_array_clone_call = 1;
10217       
10218       /* IDENTIFIER_WFL will be used to report any problem further */
10219       wfl = identifier_wfl;
10220     }
10221   /* Resolution of simple names, names generated after a primary: or
10222      constructors */
10223   else
10224     {
10225       tree class_to_search = NULL_TREE;
10226       int lc;                   /* Looking for Constructor */
10227       
10228       /* We search constructor in their target class */
10229       if (CALL_CONSTRUCTOR_P (patch))
10230         {
10231           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10232             class_to_search = EXPR_WFL_NODE (wfl);
10233           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
10234                    this_identifier_node)
10235             class_to_search = NULL_TREE;
10236           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
10237                    super_identifier_node)
10238             {
10239               is_super_init = 1;
10240               if (CLASSTYPE_SUPER (current_class))
10241                 class_to_search = 
10242                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
10243               else
10244                 {
10245                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
10246                   PATCH_METHOD_RETURN_ERROR ();
10247                 }
10248             }
10249
10250           /* Class to search is NULL if we're searching the current one */
10251           if (class_to_search)
10252             {
10253               class_to_search = resolve_and_layout (class_to_search, wfl);
10254
10255               if (!class_to_search)
10256                 {
10257                   parse_error_context 
10258                     (wfl, "Class `%s' not found in type declaration",
10259                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
10260                   PATCH_METHOD_RETURN_ERROR ();
10261                 }
10262               
10263               /* Can't instantiate an abstract class, but we can
10264                  invoke it's constructor. It's use within the `new'
10265                  context is denied here. */
10266               if (CLASS_ABSTRACT (class_to_search) 
10267                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
10268                 {
10269                   parse_error_context 
10270                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
10271                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
10272                   PATCH_METHOD_RETURN_ERROR ();
10273                 }
10274
10275               class_to_search = TREE_TYPE (class_to_search);
10276             }
10277           else
10278             class_to_search = current_class;
10279           lc = 1;
10280         }
10281       /* This is a regular search in the local class, unless an
10282          alternate class is specified. */
10283       else
10284         {
10285           if (where != NULL_TREE)
10286             class_to_search = where;
10287           else if (QUALIFIED_P (name))
10288             class_to_search = current_class;
10289           else
10290             {
10291               class_to_search = current_class;
10292
10293               for (;;)
10294                 {
10295                   if (has_method (class_to_search, name))
10296                     break;
10297                   if (! INNER_CLASS_TYPE_P (class_to_search))
10298                     {
10299                       parse_error_context (wfl,
10300                                            "No method named `%s' in scope",
10301                                            IDENTIFIER_POINTER (name));
10302                       PATCH_METHOD_RETURN_ERROR ();
10303                     }
10304                   class_to_search
10305                     = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_to_search)));
10306                 }
10307             }
10308           lc = 0;
10309         }
10310
10311       /* NAME is a simple identifier or comes from a primary. Search
10312          in the class whose declaration contain the method being
10313          invoked. */
10314       resolve_and_layout (class_to_search, NULL_TREE);
10315
10316       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
10317       /* Don't continue if no method were found, as the next statement
10318          can't be executed then. */
10319       if (!list)
10320         PATCH_METHOD_RETURN_ERROR ();
10321       
10322       if (TYPE_ARRAY_P (class_to_search)
10323           && DECL_NAME (list) == get_identifier ("clone"))
10324         is_array_clone_call = 1;
10325
10326       /* Check for static reference if non static methods */
10327       if (check_for_static_method_reference (wfl, patch, list, 
10328                                              class_to_search, primary))
10329         PATCH_METHOD_RETURN_ERROR ();
10330
10331       /* Check for inner classes creation from illegal contexts */
10332       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
10333                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
10334           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search)
10335           && !DECL_INIT_P (current_function_decl))
10336         {
10337           parse_error_context 
10338             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
10339              lang_printable_name (class_to_search, 0),
10340              (!current_this ? "" :
10341               "; an explicit one must be provided when creating this inner class"));
10342           PATCH_METHOD_RETURN_ERROR ();
10343         }
10344
10345       /* Non static methods are called with the current object extra
10346          argument. If patch a `new TYPE()', the argument is the value
10347          returned by the object allocator. If method is resolved as a
10348          primary, use the primary otherwise use the current THIS. */
10349       args = nreverse (args);
10350       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
10351         {
10352           this_arg = primary ? primary : current_this;
10353
10354           /* If we're using an access method, things are different.
10355              There are two familly of cases:
10356
10357              1) We're not generating bytecodes:
10358
10359              - LIST is non static. It's invocation is transformed from
10360                x(a1,...,an) into this$<n>.x(a1,....an).
10361              - LIST is static. It's invocation is transformed from
10362                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
10363
10364              2) We're generating bytecodes:
10365              
10366              - LIST is non static. It's invocation is transformed from
10367                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
10368              - LIST is static. It's invocation is transformed from
10369                x(a1,....,an) into TYPE_OF(this$<n>).x(a1,....an).
10370
10371              Of course, this$<n> can be abitrary complex, ranging from
10372              this$0 (the immediate outer context) to 
10373              access$0(access$0(...(this$0))). 
10374              
10375              maybe_use_access_method returns a non zero value if the
10376              this_arg has to be moved into the (then generated) stub
10377              argument list. In the meantime, the selected function
10378              might have be replaced by a generated stub. */
10379           if (!primary &&
10380               maybe_use_access_method (is_super_init, &list, &this_arg))
10381             {
10382               args = tree_cons (NULL_TREE, this_arg, args);
10383               this_arg = NULL_TREE; /* So it doesn't get chained twice */
10384             }
10385         }
10386     }
10387
10388   /* Merge point of all resolution schemes. If we have nothing, this
10389      is an error, already signaled */
10390   if (!list) 
10391     PATCH_METHOD_RETURN_ERROR ();
10392
10393   /* Check accessibility, position the is_static flag, build and
10394      return the call */
10395   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list,
10396                         (primary ? TREE_TYPE (TREE_TYPE (primary)) : 
10397                          NULL_TREE), from_super)
10398       /* Calls to clone() on array types are permitted as a special-case. */
10399       && !is_array_clone_call)
10400     {
10401       const char *const fct_name = IDENTIFIER_POINTER (DECL_NAME (list));
10402       const char *const access =
10403         java_accstring_lookup (get_access_flags_from_decl (list));
10404       const char *const klass =
10405         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list))));
10406       const char *const refklass =
10407         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
10408       const char *const what = (DECL_CONSTRUCTOR_P (list)
10409                                 ? "constructor" : "method");
10410       /* FIXME: WFL yields the wrong message here but I don't know
10411          what else to use.  */
10412       parse_error_context (wfl,
10413                            "Can't access %s %s `%s.%s' from `%s'",
10414                            access, what, klass, fct_name, refklass);
10415       PATCH_METHOD_RETURN_ERROR ();
10416     }
10417
10418   /* Deprecation check: check whether the method being invoked or the
10419      instance-being-created's type are deprecated. */
10420   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10421     check_deprecation (wfl, TYPE_NAME (DECL_CONTEXT (list)));
10422   else
10423     check_deprecation (wfl, list);
10424
10425   /* If invoking a innerclass constructor, there are hidden parameters
10426      to pass */
10427   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
10428       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10429     {
10430       /* And make sure we add the accessed local variables to be saved
10431          in field aliases. */
10432       args = build_alias_initializer_parameter_list
10433         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
10434
10435       /* Secretly pass the current_this/primary as a second argument */
10436       if (primary || current_this)
10437         {
10438           tree extra_arg;
10439           tree this_type = (current_this ?
10440                             TREE_TYPE (TREE_TYPE (current_this)) : NULL_TREE);
10441           /* Method's (list) enclosing context */
10442           tree mec = DECL_CONTEXT (TYPE_NAME (DECL_CONTEXT (list)));
10443           /* If we have a primary, use it. */
10444           if (primary)
10445             extra_arg = primary;
10446           /* The current `this' is an inner class but isn't a direct
10447              enclosing context for the inner class we're trying to
10448              create. Build an access to the proper enclosing context
10449              and use it. */
10450           else if (current_this && PURE_INNER_CLASS_TYPE_P (this_type)
10451                    && this_type != TREE_TYPE (mec))
10452             {
10453
10454               extra_arg = build_access_to_thisn (current_class,
10455                                                  TREE_TYPE (mec), 0);
10456               extra_arg = java_complete_tree (extra_arg);
10457             }
10458           /* Otherwise, just use the current `this' as an enclosing
10459              context. */
10460           else
10461             extra_arg = current_this;
10462           args = tree_cons (NULL_TREE, extra_arg, args);
10463         }
10464       else
10465         args = tree_cons (NULL_TREE, integer_zero_node, args);
10466     }
10467
10468   /* This handles the situation where a constructor invocation needs
10469      to have an enclosing context passed as a second parameter (the
10470      constructor is one of an inner class). */
10471   if ((is_super_init || 
10472        (TREE_CODE (patch) == CALL_EXPR && name == this_identifier_node))
10473       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10474     {
10475       tree dest = TYPE_NAME (DECL_CONTEXT (list));
10476       tree extra_arg = 
10477         build_access_to_thisn (current_class, DECL_CONTEXT (dest), 0);
10478       extra_arg = java_complete_tree (extra_arg);
10479       args = tree_cons (NULL_TREE, extra_arg, args);
10480     }
10481
10482   is_static_flag = METHOD_STATIC (list);
10483   if (! is_static_flag && this_arg != NULL_TREE)
10484     args = tree_cons (NULL_TREE, this_arg, args);
10485
10486   /* In the context of an explicit constructor invocation, we can't
10487      invoke any method relying on `this'. Exceptions are: we're
10488      invoking a static function, primary exists and is not the current
10489      this, we're creating a new object. */
10490   if (ctxp->explicit_constructor_p 
10491       && !is_static_flag 
10492       && (!primary || primary == current_this)
10493       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
10494     {
10495       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
10496       PATCH_METHOD_RETURN_ERROR ();
10497     }
10498   java_parser_context_restore_global ();
10499   if (is_static) 
10500     *is_static = is_static_flag;
10501   /* Sometimes, we want the decl of the selected method. Such as for
10502      EH checking */
10503   if (ret_decl)
10504     *ret_decl = list;
10505   patch = patch_invoke (patch, list, args);
10506
10507   /* Now is a good time to insert the call to finit$ */
10508   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
10509     {
10510       tree finit_parms, finit_call;
10511       
10512       /* Prepare to pass hidden parameters to finit$, if any. */
10513       finit_parms = build_alias_initializer_parameter_list 
10514         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
10515       
10516       finit_call = 
10517         build_method_invocation (build_wfl_node (finit_identifier_node),
10518                                  finit_parms);
10519
10520       /* Generate the code used to initialize fields declared with an
10521          initialization statement and build a compound statement along
10522          with the super constructor invocation. */
10523       CAN_COMPLETE_NORMALLY (patch) = 1;
10524       patch = build (COMPOUND_EXPR, void_type_node, patch,
10525                      java_complete_tree (finit_call));
10526     }
10527   return patch;
10528 }
10529
10530 /* Check that we're not trying to do a static reference to a method in
10531    non static method. Return 1 if it's the case, 0 otherwise. */
10532
10533 static int
10534 check_for_static_method_reference (wfl, node, method, where, primary)
10535      tree wfl, node, method, where, primary;
10536 {
10537   if (METHOD_STATIC (current_function_decl) 
10538       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
10539     {
10540       char *fct_name = xstrdup (lang_printable_name (method, 0));
10541       parse_error_context 
10542         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
10543          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
10544          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
10545       free (fct_name);
10546       return 1;
10547     }
10548   return 0;
10549 }
10550
10551 /* Fix the invocation of *MDECL if necessary in the case of a
10552    invocation from an inner class. *THIS_ARG might be modified
10553    appropriately and an alternative access to *MDECL might be
10554    returned.  */
10555
10556 static int
10557 maybe_use_access_method (is_super_init, mdecl, this_arg)
10558      int is_super_init;
10559      tree *mdecl, *this_arg;
10560 {
10561   tree ctx;
10562   tree md = *mdecl, ta = *this_arg;
10563   int to_return = 0;
10564   int non_static_context = !METHOD_STATIC (md);
10565
10566   if (is_super_init 
10567       || DECL_CONTEXT (md) == current_class
10568       || !PURE_INNER_CLASS_TYPE_P (current_class) 
10569       || DECL_FINIT_P (md)
10570       || DECL_INSTINIT_P (md))
10571     return 0;
10572   
10573   /* If we're calling a method found in an enclosing class, generate
10574      what it takes to retrieve the right this. Don't do that if we're
10575      invoking a static method. Note that if MD's type is unrelated to
10576      CURRENT_CLASS, then the current this can be used. */
10577
10578   if (non_static_context && DECL_CONTEXT (md) != object_type_node)
10579     {
10580       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
10581       if (inherits_from_p (ctx, DECL_CONTEXT (md)))
10582         {
10583           ta = build_current_thisn (current_class);
10584           ta = build_wfl_node (ta);
10585         }
10586       else
10587         {
10588           tree type = ctx;
10589           while (type)
10590             {
10591               maybe_build_thisn_access_method (type);
10592               if (inherits_from_p (type, DECL_CONTEXT (md)))
10593                 {
10594                   ta = build_access_to_thisn (ctx, type, 0);
10595                   break;
10596                 }
10597               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
10598                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
10599             }
10600         }
10601       ta = java_complete_tree (ta);
10602     }
10603
10604   /* We might have to use an access method to get to MD. We can
10605      break the method access rule as far as we're not generating
10606      bytecode */
10607   if (METHOD_PRIVATE (md) && flag_emit_class_files)
10608     {
10609       md = build_outer_method_access_method (md);
10610       to_return = 1;
10611     }
10612
10613   *mdecl = md;
10614   *this_arg = ta;
10615
10616   /* Returnin a non zero value indicates we were doing a non static
10617      method invokation that is now a static invocation. It will have
10618      callee displace `this' to insert it in the regular argument
10619      list. */
10620   return (non_static_context && to_return);
10621 }
10622
10623 /* Patch an invoke expression METHOD and ARGS, based on its invocation
10624    mode.  */
10625
10626 static tree
10627 patch_invoke (patch, method, args)
10628      tree patch, method, args;
10629 {
10630   tree dtable, func;
10631   tree original_call, t, ta;
10632   tree check = NULL_TREE;
10633
10634   /* Last step for args: convert build-in types. If we're dealing with
10635      a new TYPE() type call, the first argument to the constructor
10636      isn't found in the incoming argument list, but delivered by
10637      `new' */
10638   t = TYPE_ARG_TYPES (TREE_TYPE (method));
10639   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10640     t = TREE_CHAIN (t);
10641   for (ta = args; t != end_params_node && ta; 
10642        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
10643     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
10644         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
10645       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
10646
10647   /* Resolve unresolved returned type isses */
10648   t = TREE_TYPE (TREE_TYPE (method));
10649   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
10650     resolve_and_layout (TREE_TYPE (t), NULL);
10651
10652   if (flag_emit_class_files || flag_emit_xref)
10653     func = method;
10654   else
10655     {
10656       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
10657         {
10658         case INVOKE_VIRTUAL:
10659           dtable = invoke_build_dtable (0, args);
10660           func = build_invokevirtual (dtable, method);
10661           break;
10662
10663         case INVOKE_NONVIRTUAL:
10664           /* If the object for the method call is null, we throw an
10665              exception.  We don't do this if the object is the current
10666              method's `this'.  In other cases we just rely on an
10667              optimization pass to eliminate redundant checks.  */
10668           if (TREE_VALUE (args) != current_this)
10669             {
10670               /* We use a save_expr here to make sure we only evaluate
10671                  the new `self' expression once.  */
10672               tree save_arg = save_expr (TREE_VALUE (args));
10673               TREE_VALUE (args) = save_arg;
10674               check = java_check_reference (save_arg, 1);
10675             }
10676           /* Fall through.  */
10677
10678         case INVOKE_SUPER:
10679         case INVOKE_STATIC:
10680           {
10681             tree signature = build_java_signature (TREE_TYPE (method));
10682             func = build_known_method_ref (method, TREE_TYPE (method),
10683                                            DECL_CONTEXT (method),
10684                                            signature, args);
10685           }
10686           break;
10687
10688         case INVOKE_INTERFACE:
10689           dtable = invoke_build_dtable (1, args);
10690           func = build_invokeinterface (dtable, method);
10691           break;
10692
10693         default:
10694           abort ();
10695         }
10696
10697       /* Ensure self_type is initialized, (invokestatic). FIXME */
10698       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
10699     }
10700
10701   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
10702   TREE_OPERAND (patch, 0) = func;
10703   TREE_OPERAND (patch, 1) = args;
10704   patch = check_for_builtin (method, patch);
10705   original_call = patch;
10706
10707   /* We're processing a `new TYPE ()' form. New is called and its
10708      returned value is the first argument to the constructor. We build
10709      a COMPOUND_EXPR and use saved expression so that the overall NEW
10710      expression value is a pointer to a newly created and initialized
10711      class. */
10712   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
10713     {
10714       tree class = DECL_CONTEXT (method);
10715       tree c1, saved_new, size, new;
10716       tree alloc_node;
10717
10718       if (flag_emit_class_files || flag_emit_xref)
10719         {
10720           TREE_TYPE (patch) = build_pointer_type (class);
10721           return patch;
10722         }
10723       if (!TYPE_SIZE (class))
10724         safe_layout_class (class);
10725       size = size_in_bytes (class);
10726       alloc_node =
10727         (class_has_finalize_method (class) ? alloc_object_node
10728                                            : alloc_no_finalizer_node);
10729       new = build (CALL_EXPR, promote_type (class),
10730                    build_address_of (alloc_node),
10731                    tree_cons (NULL_TREE, build_class_ref (class),
10732                               build_tree_list (NULL_TREE, 
10733                                                size_in_bytes (class))),
10734                    NULL_TREE);
10735       saved_new = save_expr (new);
10736       c1 = build_tree_list (NULL_TREE, saved_new);
10737       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
10738       TREE_OPERAND (original_call, 1) = c1;
10739       TREE_SET_CODE (original_call, CALL_EXPR);
10740       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
10741     }
10742
10743   /* If CHECK is set, then we are building a check to see if the object
10744      is NULL.  */
10745   if (check != NULL_TREE)
10746     {
10747       patch = build (COMPOUND_EXPR, TREE_TYPE (patch), check, patch);
10748       TREE_SIDE_EFFECTS (patch) = 1;
10749     }
10750
10751   /* In order to be able to modify PATCH later, we SAVE_EXPR it and
10752      put it as the first expression of a COMPOUND_EXPR. The second
10753      expression being an empty statement to be later patched if
10754      necessary. We remember a TREE_LIST (the PURPOSE is the method,
10755      the VALUE is the compound) in a hashtable and return a
10756      COMPOUND_EXPR built so that the result of the evaluation of the
10757      original PATCH node is returned. */
10758   if (STATIC_CLASS_INIT_OPT_P ()
10759       && current_function_decl && METHOD_STATIC (method))
10760     {
10761       tree list;
10762       tree fndecl = current_function_decl;
10763       tree save = save_expr (patch);
10764       tree type = TREE_TYPE (patch);
10765
10766       patch = build (COMPOUND_EXPR, type, save, empty_stmt_node);
10767       list = tree_cons (method, patch,
10768                         DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl));
10769
10770       DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl) = list;
10771
10772       patch = build (COMPOUND_EXPR, type, patch, save);
10773     }
10774
10775   return patch;
10776 }
10777
10778 static int
10779 invocation_mode (method, super)
10780      tree method;
10781      int super;
10782 {
10783   int access = get_access_flags_from_decl (method);
10784
10785   if (super)
10786     return INVOKE_SUPER;
10787
10788   if (access & ACC_STATIC)
10789     return INVOKE_STATIC;
10790
10791   /* We have to look for a constructor before we handle nonvirtual
10792      calls; otherwise the constructor will look nonvirtual.  */
10793   if (DECL_CONSTRUCTOR_P (method))
10794     return INVOKE_STATIC;
10795
10796   if (access & ACC_FINAL || access & ACC_PRIVATE)
10797     return INVOKE_NONVIRTUAL;
10798
10799   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
10800     return INVOKE_NONVIRTUAL;
10801
10802   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
10803     return INVOKE_INTERFACE;
10804
10805   return INVOKE_VIRTUAL;
10806 }
10807
10808 /* Retrieve a refined list of matching methods. It covers the step
10809    15.11.2 (Compile-Time Step 2) */
10810
10811 static tree
10812 lookup_method_invoke (lc, cl, class, name, arg_list)
10813      int lc;
10814      tree cl;
10815      tree class, name, arg_list;
10816 {
10817   tree atl = end_params_node;           /* Arg Type List */
10818   tree method, signature, list, node;
10819   const char *candidates;               /* Used for error report */
10820   char *dup;
10821
10822   /* Fix the arguments */
10823   for (node = arg_list; node; node = TREE_CHAIN (node))
10824     {
10825       tree current_arg = TREE_TYPE (TREE_VALUE (node));
10826       /* Non primitive type may have to be resolved */
10827       if (!JPRIMITIVE_TYPE_P (current_arg))
10828         resolve_and_layout (current_arg, NULL_TREE);
10829       /* And promoted */
10830       if (TREE_CODE (current_arg) == RECORD_TYPE)
10831         current_arg = promote_type (current_arg);
10832       atl = tree_cons (NULL_TREE, current_arg, atl);
10833     }
10834
10835   /* Presto. If we're dealing with an anonymous class and a
10836      constructor call, generate the right constructor now, since we
10837      know the arguments' types. */
10838
10839   if (lc && ANONYMOUS_CLASS_P (class))
10840     {
10841       tree saved_current_class;
10842       tree mdecl = craft_constructor (TYPE_NAME (class), atl);
10843       saved_current_class = current_class;
10844       current_class = class;
10845       fix_constructors (mdecl);
10846       current_class = saved_current_class;
10847     }
10848
10849   /* Find all candidates and then refine the list, searching for the
10850      most specific method. */
10851   list = find_applicable_accessible_methods_list (lc, class, name, atl);
10852   list = find_most_specific_methods_list (list);
10853   if (list && !TREE_CHAIN (list))
10854     return TREE_VALUE (list);
10855
10856   /* Issue an error. List candidates if any. Candidates are listed
10857      only if accessible (non accessible methods may end-up here for
10858      the sake of a better error report). */
10859   candidates = NULL;
10860   if (list)
10861     {
10862       tree current;
10863       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
10864       for (current = list; current; current = TREE_CHAIN (current))
10865         {
10866           tree cm = TREE_VALUE (current);
10867           char string [4096];
10868           if (!cm || not_accessible_p (class, cm, NULL_TREE, 0))
10869             continue;
10870           sprintf 
10871             (string, "  `%s' in `%s'%s",
10872              get_printable_method_name (cm),
10873              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
10874              (TREE_CHAIN (current) ? "\n" : ""));
10875           obstack_grow (&temporary_obstack, string, strlen (string));
10876         }
10877       obstack_1grow (&temporary_obstack, '\0');
10878       candidates = obstack_finish (&temporary_obstack);
10879     }
10880   /* Issue the error message */
10881   method = make_node (FUNCTION_TYPE);
10882   TYPE_ARG_TYPES (method) = atl;
10883   signature = build_java_argument_signature (method);
10884   dup = xstrdup (lang_printable_name (class, 0));
10885   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
10886                        (lc ? "constructor" : "method"),
10887                        (lc ? dup : IDENTIFIER_POINTER (name)),
10888                        IDENTIFIER_POINTER (signature), dup,
10889                        (candidates ? candidates : ""));
10890   free (dup);
10891   return NULL_TREE;
10892 }
10893
10894 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
10895    when we're looking for a constructor. */
10896
10897 static tree
10898 find_applicable_accessible_methods_list (lc, class, name, arglist)
10899      int lc;
10900      tree class, name, arglist;
10901 {
10902   static struct hash_table t, *searched_classes = NULL;
10903   static int search_not_done = 0;
10904   tree list = NULL_TREE, all_list = NULL_TREE;
10905
10906   /* Check the hash table to determine if this class has been searched 
10907      already. */
10908   if (searched_classes)
10909     {
10910       if (hash_lookup (searched_classes, 
10911                       (const hash_table_key) class, FALSE, NULL))
10912        return NULL;
10913     }
10914   else
10915     {
10916       hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
10917                       java_hash_compare_tree_node);
10918       searched_classes = &t;
10919     }
10920     
10921   search_not_done++;
10922   hash_lookup (searched_classes, 
10923                (const hash_table_key) class, TRUE, NULL);
10924
10925   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
10926     {
10927       load_class (class, 1);
10928       safe_layout_class (class);
10929     }
10930
10931   /* Search interfaces */
10932   if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
10933       && CLASS_INTERFACE (TYPE_NAME (class)))
10934     {
10935       int i, n;
10936       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10937       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10938                                       name, arglist, &list, &all_list);
10939       n = TREE_VEC_LENGTH (basetype_vec);
10940       for (i = 1; i < n; i++)
10941         {
10942           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10943           tree rlist;
10944
10945           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
10946                                                            arglist);
10947           list = chainon (rlist, list);
10948         }
10949     }
10950   /* Search classes */
10951   else
10952     {
10953       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10954                                       name, arglist, &list, &all_list);
10955
10956       /* When looking finit$, class$ or instinit$, we turn LC to 1 so
10957          that we only search in class. Note that we should have found
10958          something at this point. */
10959       if (ID_FINIT_P (name) || ID_CLASSDOLLAR_P (name) || ID_INSTINIT_P (name))
10960         {
10961           lc = 1;
10962           if (!list)
10963             abort ();
10964         }
10965
10966       /* We must search all interfaces of this class */
10967       if (!lc)
10968       {
10969         tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10970         int n = TREE_VEC_LENGTH (basetype_vec), i;
10971         for (i = 1; i < n; i++)
10972           {
10973             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10974             if (t != object_type_node)
10975               {
10976                 tree rlist
10977                   = find_applicable_accessible_methods_list (lc, t,
10978                                                              name, arglist);
10979                 list = chainon (rlist, list);
10980               }
10981           }
10982       }
10983
10984       /* Search superclass */
10985       if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
10986         {
10987           tree rlist;
10988           class = CLASSTYPE_SUPER (class);
10989           rlist = find_applicable_accessible_methods_list (lc, class, 
10990                                                            name, arglist);
10991           list = chainon (rlist, list);
10992         }
10993     }
10994
10995   search_not_done--;
10996
10997   /* We're done. Reset the searched classes list and finally search
10998      java.lang.Object if it wasn't searched already. */
10999   if (!search_not_done)
11000     {
11001       if (!lc
11002           && TYPE_METHODS (object_type_node)
11003           && !hash_lookup (searched_classes, 
11004                            (const hash_table_key) object_type_node, 
11005                            FALSE, NULL))
11006         {
11007           search_applicable_methods_list (lc, 
11008                                           TYPE_METHODS (object_type_node),
11009                                           name, arglist, &list, &all_list);
11010         }
11011       hash_table_free (searched_classes);
11012       searched_classes = NULL;
11013     }
11014
11015   /* Either return the list obtained or all selected (but
11016      inaccessible) methods for better error report. */
11017   return (!list ? all_list : list);
11018 }
11019
11020 /* Effectively search for the appropriate method in method */
11021
11022 static void 
11023 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
11024      int lc;
11025      tree method, name, arglist;
11026      tree *list, *all_list;
11027 {
11028   for (; method; method = TREE_CHAIN (method))
11029     {
11030       /* When dealing with constructor, stop here, otherwise search
11031          other classes */
11032       if (lc && !DECL_CONSTRUCTOR_P (method))
11033         continue;
11034       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
11035                        || (DECL_NAME (method) != name)))
11036         continue;
11037
11038       if (argument_types_convertible (method, arglist))
11039         {
11040           /* Retain accessible methods only */
11041           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
11042                                  method, NULL_TREE, 0))
11043             *list = tree_cons (NULL_TREE, method, *list);
11044           else
11045             /* Also retain all selected method here */
11046             *all_list = tree_cons (NULL_TREE, method, *list);
11047         }
11048     }
11049 }
11050
11051 /* 15.11.2.2 Choose the Most Specific Method */
11052
11053 static tree
11054 find_most_specific_methods_list (list)
11055      tree list;
11056 {
11057   int max = 0;
11058   int abstract, candidates;
11059   tree current, new_list = NULL_TREE;
11060   for (current = list; current; current = TREE_CHAIN (current))
11061     {
11062       tree method;
11063       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
11064
11065       for (method = list; method; method = TREE_CHAIN (method))
11066         {
11067           tree method_v, current_v;
11068           /* Don't test a method against itself */
11069           if (method == current)
11070             continue;
11071
11072           method_v = TREE_VALUE (method);
11073           current_v = TREE_VALUE (current);
11074
11075           /* Compare arguments and location where methods where declared */
11076           if (argument_types_convertible (method_v, current_v))
11077             {
11078               if (valid_method_invocation_conversion_p 
11079                   (DECL_CONTEXT (method_v), DECL_CONTEXT (current_v))
11080                   || (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v))
11081                       && enclosing_context_p (DECL_CONTEXT (method_v),
11082                                               DECL_CONTEXT (current_v))))
11083                 {
11084                   int v = (DECL_SPECIFIC_COUNT (current_v) += 
11085                     (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v)) ? 2 : 1));
11086                   max = (v > max ? v : max);
11087                 }
11088             }
11089         }
11090     }
11091
11092   /* Review the list and select the maximally specific methods */
11093   for (current = list, abstract = -1, candidates = -1;
11094        current; current = TREE_CHAIN (current))
11095     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
11096       {
11097         new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
11098         abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
11099         candidates++;
11100       }
11101
11102   /* If we have several and they're all abstract, just pick the
11103      closest one. */
11104   if (candidates > 0 && (candidates == abstract))
11105     {
11106       new_list = nreverse (new_list);
11107       TREE_CHAIN (new_list) = NULL_TREE;
11108     }
11109
11110   /* We have several (we couldn't find a most specific), all but one
11111      are abstract, we pick the only non abstract one. */
11112   if (candidates > 0 && (candidates == abstract+1))
11113     {
11114       for (current = new_list; current; current = TREE_CHAIN (current))
11115         if (!METHOD_ABSTRACT (TREE_VALUE (current)))
11116           {
11117             TREE_CHAIN (current) = NULL_TREE;
11118             new_list = current;
11119           }
11120     }
11121
11122   /* If we can't find one, lower expectations and try to gather multiple
11123      maximally specific methods */
11124   while (!new_list && max)
11125     {
11126       while (--max > 0)
11127         {
11128           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
11129             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
11130         }
11131     }
11132
11133   return new_list;
11134 }
11135
11136 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
11137    converted by method invocation conversion (5.3) to the type of the
11138    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
11139    to change less often than M1. */
11140
11141 static int
11142 argument_types_convertible (m1, m2_or_arglist)
11143     tree m1, m2_or_arglist;
11144 {
11145   static tree m2_arg_value = NULL_TREE;
11146   static tree m2_arg_cache = NULL_TREE;
11147   static int initialized_p;
11148
11149   register tree m1_arg, m2_arg;
11150
11151   /* Register M2_ARG_VALUE and M2_ARG_CACHE with the garbage
11152      collector.  */
11153   if (!initialized_p)
11154     {
11155       ggc_add_tree_root (&m2_arg_value, 1);
11156       ggc_add_tree_root (&m2_arg_cache, 1);
11157       initialized_p = 1;
11158     }
11159
11160   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
11161
11162   if (m2_arg_value == m2_or_arglist)
11163     m2_arg = m2_arg_cache;
11164   else
11165     {
11166       /* M2_OR_ARGLIST can be a function DECL or a raw list of
11167          argument types */
11168       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
11169         {
11170           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
11171           if (!METHOD_STATIC (m2_or_arglist))
11172             m2_arg = TREE_CHAIN (m2_arg);
11173         }
11174       else
11175         m2_arg = m2_or_arglist;
11176
11177       m2_arg_value = m2_or_arglist;
11178       m2_arg_cache = m2_arg;
11179     }
11180
11181   while (m1_arg != end_params_node && m2_arg != end_params_node)
11182     {
11183       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
11184       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
11185                                                  TREE_VALUE (m2_arg)))
11186         break;
11187       m1_arg = TREE_CHAIN (m1_arg);
11188       m2_arg = TREE_CHAIN (m2_arg);
11189     }
11190   return m1_arg == end_params_node && m2_arg == end_params_node;
11191 }
11192
11193 /* Qualification routines */
11194
11195 static void
11196 qualify_ambiguous_name (id)
11197      tree id;
11198 {
11199   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
11200     saved_current_class;
11201   int again, super_found = 0, this_found = 0, new_array_found = 0;
11202   int code;
11203
11204   /* We first qualify the first element, then derive qualification of
11205      others based on the first one. If the first element is qualified
11206      by a resolution (field or type), this resolution is stored in the
11207      QUAL_RESOLUTION of the qual element being examined. We need to
11208      save the current_class since the use of SUPER might change the
11209      its value. */
11210   saved_current_class = current_class;
11211   qual = EXPR_WFL_QUALIFICATION (id);
11212   do {
11213
11214     /* Simple qualified expression feature a qual_wfl that is a
11215        WFL. Expression derived from a primary feature more complicated
11216        things like a CALL_EXPR. Expression from primary need to be
11217        worked out to extract the part on which the qualification will
11218        take place. */
11219     qual_wfl = QUAL_WFL (qual);
11220     switch (TREE_CODE (qual_wfl))
11221       {
11222       case CALL_EXPR:
11223         qual_wfl = TREE_OPERAND (qual_wfl, 0);
11224         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION
11225             || (EXPR_WFL_QUALIFICATION (qual_wfl)
11226                 && TREE_CODE (EXPR_WFL_QUALIFICATION (qual_wfl)) == TREE_LIST))
11227           {
11228             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
11229             qual_wfl = QUAL_WFL (qual);
11230           }
11231         break;
11232       case NEW_ARRAY_EXPR:
11233       case NEW_ANONYMOUS_ARRAY_EXPR:
11234         qual = TREE_CHAIN (qual);
11235         again = new_array_found = 1;
11236         continue;
11237       case CONVERT_EXPR:
11238         break;
11239       case NEW_CLASS_EXPR:
11240         qual_wfl = TREE_OPERAND (qual_wfl, 0);
11241         break;
11242       case ARRAY_REF:
11243         while (TREE_CODE (qual_wfl) == ARRAY_REF)
11244           qual_wfl = TREE_OPERAND (qual_wfl, 0);
11245         break;
11246       case STRING_CST:
11247         qual = TREE_CHAIN (qual);
11248         qual_wfl = QUAL_WFL (qual);
11249         break;
11250       case CLASS_LITERAL:
11251         qual = TREE_CHAIN (qual);
11252         qual_wfl = QUAL_WFL (qual);
11253       break;
11254       default:
11255         /* Fix for -Wall. Just break doing nothing */
11256         break;
11257       }
11258
11259     ptr_type = current_class;
11260     again = 0;
11261     code = TREE_CODE (qual_wfl);
11262
11263     /* Pos evaluation: non WFL leading expression nodes */
11264     if (code == CONVERT_EXPR
11265         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
11266       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
11267
11268     else if (code == INTEGER_CST)
11269       name = qual_wfl;
11270
11271     else if (code == CONVERT_EXPR &&
11272              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
11273       name = TREE_OPERAND (qual_wfl, 0);
11274
11275     else if (code == CONVERT_EXPR
11276              && TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == CALL_EXPR
11277              && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0))
11278                  == EXPR_WITH_FILE_LOCATION))
11279       name = TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0);
11280
11281     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
11282              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
11283       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
11284
11285     else if (code == TREE_LIST)
11286       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
11287
11288     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
11289              || code == PLUS_EXPR)
11290       {
11291         qual = TREE_CHAIN (qual);
11292         qual_wfl = QUAL_WFL (qual);
11293         again = 1;
11294       }
11295     else
11296       {
11297         name = EXPR_WFL_NODE (qual_wfl);
11298         if (!name)
11299           {
11300             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
11301             again = 1;
11302           }
11303       }
11304
11305     /* If we have a THIS (from a primary), we set the context accordingly */
11306     if (name == this_identifier_node)
11307       {
11308         /* This isn't really elegant. One more added irregularity
11309            before I start using COMPONENT_REF (hopefully very soon.)  */
11310         if (TREE_CODE (TREE_PURPOSE (qual)) == ARRAY_REF
11311             && TREE_CODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
11312                EXPR_WITH_FILE_LOCATION
11313             && EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) == 
11314                this_identifier_node)
11315             {
11316               qual = TREE_OPERAND (TREE_PURPOSE (qual), 0);
11317               qual = EXPR_WFL_QUALIFICATION (qual);
11318             }
11319         qual = TREE_CHAIN (qual);
11320         qual_wfl = QUAL_WFL (qual);
11321         if (TREE_CODE (qual_wfl) == CALL_EXPR)
11322           again = 1;
11323         else if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION)
11324           name = EXPR_WFL_NODE (qual_wfl);
11325         else if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
11326           name = TREE_OPERAND (qual_wfl, 0);
11327         this_found = 1;
11328       }
11329     /* If we have a SUPER, we set the context accordingly */
11330     if (name == super_identifier_node)
11331       {
11332         current_class = CLASSTYPE_SUPER (ptr_type);
11333         /* Check that there is such a thing as a super class. If not,
11334            return.  The error will be caught later on, during the
11335            resolution */
11336         if (!current_class)
11337           {
11338             current_class = saved_current_class;
11339             return;
11340           }
11341         qual = TREE_CHAIN (qual);
11342         /* Do one more interation to set things up */
11343         super_found = again = 1;
11344       }
11345   } while (again);
11346   
11347   /* If name appears within the scope of a local variable declaration
11348      or parameter declaration, then it is an expression name. We don't
11349      carry this test out if we're in the context of the use of SUPER
11350      or THIS */
11351   if (!this_found && !super_found 
11352       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
11353       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
11354     {
11355       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11356       QUAL_RESOLUTION (qual) = decl;
11357     }
11358
11359   /* If within the class/interface NAME was found to be used there
11360      exists a (possibly inherited) field named NAME, then this is an
11361      expression name. If we saw a NEW_ARRAY_EXPR before and want to
11362      address length, it is OK. */
11363   else if ((decl = lookup_field_wrapper (ptr_type, name))
11364            || name == length_identifier_node)
11365     {
11366       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11367       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
11368     }
11369
11370   /* We reclassify NAME as yielding to a type name resolution if:
11371      - NAME is a class/interface declared within the compilation
11372        unit containing NAME,
11373      - NAME is imported via a single-type-import declaration,
11374      - NAME is declared in an another compilation unit of the package
11375        of the compilation unit containing NAME,
11376      - NAME is declared by exactly on type-import-on-demand declaration
11377      of the compilation unit containing NAME. 
11378      - NAME is actually a STRING_CST.
11379      This can't happen if the expression was qualified by `this.' */
11380   else if (! this_found &&
11381            (TREE_CODE (name) == STRING_CST ||
11382             TREE_CODE (name) == INTEGER_CST ||
11383             (decl = resolve_and_layout (name, NULL_TREE))))
11384     {
11385       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
11386       QUAL_RESOLUTION (qual) = decl;
11387     }
11388
11389   /* Method call, array references and cast are expression name */
11390   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
11391            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
11392            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR
11393            || TREE_CODE (QUAL_WFL (qual)) == MODIFY_EXPR)
11394     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
11395
11396   /* Check here that NAME isn't declared by more than one
11397      type-import-on-demand declaration of the compilation unit
11398      containing NAME. FIXME */
11399
11400   /* Otherwise, NAME is reclassified as a package name */
11401   else 
11402     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
11403
11404   /* Propagate the qualification accross other components of the
11405      qualified name */
11406   for (qual = TREE_CHAIN (qual); qual;
11407        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
11408     {
11409       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
11410         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
11411       else 
11412         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
11413     }
11414
11415   /* Store the global qualification for the ambiguous part of ID back
11416      into ID fields */
11417   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
11418     RESOLVE_EXPRESSION_NAME_P (id) = 1;
11419   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
11420     RESOLVE_TYPE_NAME_P (id) = 1;
11421   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
11422     RESOLVE_PACKAGE_NAME_P (id) = 1;
11423
11424   /* Restore the current class */
11425   current_class = saved_current_class;
11426 }
11427
11428 static int
11429 breakdown_qualified (left, right, source)
11430     tree *left, *right, source;
11431 {
11432   char *p, *base;
11433   int   l = IDENTIFIER_LENGTH (source);
11434
11435   base = alloca (l + 1);
11436   memcpy (base, IDENTIFIER_POINTER (source), l + 1);
11437
11438   /* Breakdown NAME into REMAINDER . IDENTIFIER */
11439   p = base + l - 1;
11440   while (*p != '.' && p != base)
11441     p--;
11442
11443   /* We didn't find a '.'. Return an error */
11444   if (p == base)
11445     return 1;
11446
11447   *p = '\0';
11448   if (right)
11449     *right = get_identifier (p+1);
11450   *left = get_identifier (base);
11451   
11452   return 0;
11453 }
11454
11455 /* Return TRUE if two classes are from the same package. */
11456
11457 static int
11458 in_same_package (name1, name2)
11459   tree name1, name2;
11460 {
11461   tree tmp;
11462   tree pkg1;
11463   tree pkg2;
11464   
11465   if (TREE_CODE (name1) == TYPE_DECL)
11466     name1 = DECL_NAME (name1);
11467   if (TREE_CODE (name2) == TYPE_DECL)
11468     name2 = DECL_NAME (name2);
11469
11470   if (QUALIFIED_P (name1) != QUALIFIED_P (name2))
11471     /* One in empty package. */
11472     return 0;
11473
11474   if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0)
11475     /* Both in empty package. */
11476     return 1;
11477
11478   breakdown_qualified (&pkg1, &tmp, name1);
11479   breakdown_qualified (&pkg2, &tmp, name2);
11480   
11481   return (pkg1 == pkg2);
11482 }
11483
11484 /* Patch tree nodes in a function body. When a BLOCK is found, push
11485    local variable decls if present.
11486    Same as java_complete_lhs, but does resolve static finals to values. */
11487
11488 static tree
11489 java_complete_tree (node)
11490      tree node;
11491 {
11492   node = java_complete_lhs (node);
11493   if (JDECL_P (node) && CLASS_FINAL_VARIABLE_P (node)
11494       && DECL_INITIAL (node) != NULL_TREE
11495       && !flag_emit_xref)
11496     {
11497       tree value = DECL_INITIAL (node);
11498       DECL_INITIAL (node) = NULL_TREE;
11499       value = fold_constant_for_init (value, node);
11500       DECL_INITIAL (node) = value;
11501       if (value != NULL_TREE)
11502         {
11503           /* fold_constant_for_init sometimes widens the original type
11504              of the constant (i.e. byte to int). It's not desirable,
11505              especially if NODE is a function argument. */
11506           if ((TREE_CODE (value) == INTEGER_CST
11507                || TREE_CODE (value) == REAL_CST)
11508               && TREE_TYPE (node) != TREE_TYPE (value))
11509             return convert (TREE_TYPE (node), value);
11510           else
11511             return value;
11512         }
11513     }
11514   return node;
11515 }
11516
11517 static tree
11518 java_stabilize_reference (node)
11519      tree node;
11520 {
11521   if (TREE_CODE (node) == COMPOUND_EXPR)
11522     {
11523       tree op0 = TREE_OPERAND (node, 0);
11524       tree op1 = TREE_OPERAND (node, 1);
11525       TREE_OPERAND (node, 0) = save_expr (op0);
11526       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
11527       return node;
11528     }
11529   return stabilize_reference (node);
11530 }
11531
11532 /* Patch tree nodes in a function body. When a BLOCK is found, push
11533    local variable decls if present.
11534    Same as java_complete_tree, but does not resolve static finals to values. */
11535
11536 static tree
11537 java_complete_lhs (node)
11538      tree node;
11539 {
11540   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
11541   int flag;
11542
11543   /* CONVERT_EXPR always has its type set, even though it needs to be
11544      worked out. */
11545   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
11546     return node;
11547
11548   /* The switch block implements cases processing container nodes
11549      first.  Contained nodes are always written back. Leaves come
11550      next and return a value. */
11551   switch (TREE_CODE (node))
11552     {
11553     case BLOCK:
11554
11555       /* 1- Block section.
11556          Set the local values on decl names so we can identify them
11557          faster when they're referenced. At that stage, identifiers
11558          are legal so we don't check for declaration errors. */
11559       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11560         {
11561           DECL_CONTEXT (cn) = current_function_decl;
11562           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
11563         }
11564       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
11565           CAN_COMPLETE_NORMALLY (node) = 1;
11566       else
11567         {
11568           tree stmt = BLOCK_EXPR_BODY (node);
11569           tree *ptr;
11570           int error_seen = 0;
11571           if (TREE_CODE (stmt) == COMPOUND_EXPR)
11572             {
11573               /* Re-order from (((A; B); C); ...; Z) to 
11574                  (A; (B; (C ; (...; Z)))).
11575                  This makes it easier to scan the statements left-to-right
11576                  without using recursion (which might overflow the stack
11577                  if the block has many statements. */
11578               for (;;)
11579                 {
11580                   tree left = TREE_OPERAND (stmt, 0);
11581                   if (TREE_CODE (left) != COMPOUND_EXPR)
11582                     break;
11583                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
11584                   TREE_OPERAND (left, 1) = stmt;
11585                   stmt = left;
11586                 }
11587               BLOCK_EXPR_BODY (node) = stmt;
11588             }
11589
11590           /* Now do the actual complete, without deep recursion for
11591              long blocks. */
11592           ptr = &BLOCK_EXPR_BODY (node);
11593           while (TREE_CODE (*ptr) == COMPOUND_EXPR
11594                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
11595             {
11596               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
11597               tree *next = &TREE_OPERAND (*ptr, 1);
11598               TREE_OPERAND (*ptr, 0) = cur;
11599               if (cur == empty_stmt_node)
11600                 {
11601                   /* Optimization;  makes it easier to detect empty bodies.
11602                      Most useful for <clinit> with all-constant initializer. */
11603                   *ptr = *next;
11604                   continue;
11605                 }
11606               if (TREE_CODE (cur) == ERROR_MARK)
11607                 error_seen++;
11608               else if (! CAN_COMPLETE_NORMALLY (cur))
11609                 {
11610                   wfl_op2 = *next;
11611                   for (;;)
11612                     {
11613                       if (TREE_CODE (wfl_op2) == BLOCK)
11614                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
11615                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
11616                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
11617                       else
11618                         break;
11619                     }
11620                   if (TREE_CODE (wfl_op2) != CASE_EXPR
11621                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
11622                     unreachable_stmt_error (*ptr);
11623                 }
11624               ptr = next;
11625             }
11626           *ptr = java_complete_tree (*ptr);
11627
11628           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
11629             return error_mark_node;
11630           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
11631         }
11632       /* Turn local bindings to null */
11633       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11634         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
11635
11636       TREE_TYPE (node) = void_type_node;
11637       break;
11638
11639       /* 2- They are expressions but ultimately deal with statements */
11640
11641     case THROW_EXPR:
11642       wfl_op1 = TREE_OPERAND (node, 0);
11643       COMPLETE_CHECK_OP_0 (node);
11644       /* 14.19 A throw statement cannot complete normally. */
11645       CAN_COMPLETE_NORMALLY (node) = 0;
11646       return patch_throw_statement (node, wfl_op1);
11647
11648     case SYNCHRONIZED_EXPR:
11649       wfl_op1 = TREE_OPERAND (node, 0);
11650       return patch_synchronized_statement (node, wfl_op1);
11651
11652     case TRY_EXPR:
11653       return patch_try_statement (node);
11654
11655     case TRY_FINALLY_EXPR:
11656       COMPLETE_CHECK_OP_0 (node);
11657       COMPLETE_CHECK_OP_1 (node);
11658       if (TREE_OPERAND (node, 0) == empty_stmt_node)
11659         return TREE_OPERAND (node, 1);
11660       if (TREE_OPERAND (node, 1) == empty_stmt_node)
11661         return TREE_OPERAND (node, 0);
11662       CAN_COMPLETE_NORMALLY (node)
11663         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
11664            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
11665       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
11666       return node;
11667
11668     case LABELED_BLOCK_EXPR:
11669       PUSH_LABELED_BLOCK (node);
11670       if (LABELED_BLOCK_BODY (node))
11671         COMPLETE_CHECK_OP_1 (node);
11672       TREE_TYPE (node) = void_type_node;
11673       POP_LABELED_BLOCK ();
11674
11675       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
11676         {
11677           LABELED_BLOCK_BODY (node) = NULL_TREE;
11678           CAN_COMPLETE_NORMALLY (node) = 1;
11679         }
11680       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
11681         CAN_COMPLETE_NORMALLY (node) = 1;
11682       return node;
11683
11684     case EXIT_BLOCK_EXPR:
11685       /* We don't complete operand 1, because it's the return value of
11686          the EXIT_BLOCK_EXPR which doesn't exist it Java */
11687       return patch_bc_statement (node);
11688
11689     case CASE_EXPR:
11690       cn = java_complete_tree (TREE_OPERAND (node, 0));
11691       if (cn == error_mark_node)
11692         return cn;
11693
11694       /* First, the case expression must be constant. Values of final
11695          fields are accepted. */
11696       cn = fold (cn);
11697       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
11698           && JDECL_P (TREE_OPERAND (cn, 1))
11699           && FIELD_FINAL (TREE_OPERAND (cn, 1))
11700           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
11701         {
11702           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
11703                                        TREE_OPERAND (cn, 1));
11704         }
11705       /* Accept final locals too. */
11706       else if (TREE_CODE (cn) == VAR_DECL && DECL_FINAL (cn))
11707         cn = fold_constant_for_init (DECL_INITIAL (cn), cn);
11708
11709       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
11710         {
11711           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11712           parse_error_context (node, "Constant expression required");
11713           return error_mark_node;
11714         }
11715
11716       nn = ctxp->current_loop;
11717
11718       /* It must be assignable to the type of the switch expression. */
11719       if (!try_builtin_assignconv (NULL_TREE, 
11720                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
11721         {
11722           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11723           parse_error_context 
11724             (wfl_operator,
11725              "Incompatible type for case. Can't convert `%s' to `int'",
11726              lang_printable_name (TREE_TYPE (cn), 0));
11727           return error_mark_node;
11728         }
11729
11730       cn = fold (convert (int_type_node, cn));
11731       TREE_CONSTANT_OVERFLOW (cn) = 0;
11732       CAN_COMPLETE_NORMALLY (cn) = 1;
11733
11734       /* Save the label on a list so that we can later check for
11735          duplicates.  */
11736       case_label_list = tree_cons (node, cn, case_label_list);
11737
11738       /* Multiple instance of a case label bearing the same value is
11739          checked later. The case expression is all right so far. */
11740       if (TREE_CODE (cn) == VAR_DECL)
11741         cn = DECL_INITIAL (cn);
11742       TREE_OPERAND (node, 0) = cn;
11743       TREE_TYPE (node) = void_type_node;
11744       CAN_COMPLETE_NORMALLY (node) = 1;
11745       TREE_SIDE_EFFECTS (node) = 1;
11746       break;
11747
11748     case DEFAULT_EXPR:
11749       nn = ctxp->current_loop;
11750       /* Only one default label is allowed per switch statement */
11751       if (SWITCH_HAS_DEFAULT (nn))
11752         {
11753           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11754           parse_error_context (wfl_operator, 
11755                                "Duplicate case label: `default'");
11756           return error_mark_node;
11757         }
11758       else
11759         SWITCH_HAS_DEFAULT (nn) = 1;
11760       TREE_TYPE (node) = void_type_node;
11761       TREE_SIDE_EFFECTS (node) = 1;
11762       CAN_COMPLETE_NORMALLY (node) = 1;
11763       break;
11764
11765     case SWITCH_EXPR:
11766     case LOOP_EXPR:
11767       PUSH_LOOP (node);
11768       /* Check whether the loop was enclosed in a labeled
11769          statement. If not, create one, insert the loop in it and
11770          return the node */
11771       nn = patch_loop_statement (node);
11772
11773       /* Anyways, walk the body of the loop */
11774       if (TREE_CODE (node) == LOOP_EXPR)
11775         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11776       /* Switch statement: walk the switch expression and the cases */
11777       else
11778         node = patch_switch_statement (node);
11779
11780       if (node == error_mark_node || TREE_OPERAND (node, 0) == error_mark_node)
11781         nn = error_mark_node;
11782       else
11783         {
11784           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
11785           /* If we returned something different, that's because we
11786              inserted a label. Pop the label too. */
11787           if (nn != node)
11788             {
11789               if (CAN_COMPLETE_NORMALLY (node))
11790                 CAN_COMPLETE_NORMALLY (nn) = 1;
11791               POP_LABELED_BLOCK ();
11792             }
11793         }
11794       POP_LOOP ();
11795       return nn;
11796
11797     case EXIT_EXPR:
11798       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11799       return patch_exit_expr (node);
11800
11801     case COND_EXPR:
11802       /* Condition */
11803       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11804       if (TREE_OPERAND (node, 0) == error_mark_node)
11805         return error_mark_node;
11806       /* then-else branches */
11807       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11808       if (TREE_OPERAND (node, 1) == error_mark_node)
11809         return error_mark_node;
11810       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
11811       if (TREE_OPERAND (node, 2) == error_mark_node)
11812         return error_mark_node;
11813       return patch_if_else_statement (node);
11814       break;
11815
11816     case CONDITIONAL_EXPR:
11817       /* Condition */
11818       wfl_op1 = TREE_OPERAND (node, 0);
11819       COMPLETE_CHECK_OP_0 (node);
11820       wfl_op2 = TREE_OPERAND (node, 1);
11821       COMPLETE_CHECK_OP_1 (node);
11822       wfl_op3 = TREE_OPERAND (node, 2);
11823       COMPLETE_CHECK_OP_2 (node);
11824       return patch_conditional_expr (node, wfl_op1, wfl_op2);
11825
11826       /* 3- Expression section */
11827     case COMPOUND_EXPR:
11828       wfl_op2 = TREE_OPERAND (node, 1);
11829       TREE_OPERAND (node, 0) = nn = 
11830         java_complete_tree (TREE_OPERAND (node, 0));
11831       if (wfl_op2 == empty_stmt_node)
11832         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
11833       else
11834         {
11835           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
11836             {
11837               /* An unreachable condition in a do-while statement
11838                  is *not* (technically) an unreachable statement. */
11839               nn = wfl_op2;
11840               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
11841                 nn = EXPR_WFL_NODE (nn);
11842               if (TREE_CODE (nn) != EXIT_EXPR)
11843                 {
11844                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
11845                   parse_error_context (wfl_operator, "Unreachable statement");
11846                 }
11847             }
11848           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11849           if (TREE_OPERAND (node, 1) == error_mark_node)
11850             return error_mark_node;
11851           /* Even though we might allow the case where the first
11852              operand doesn't return normally, we still should compute
11853              CAN_COMPLETE_NORMALLY correctly.  */
11854           CAN_COMPLETE_NORMALLY (node)
11855             = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
11856                && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
11857         }
11858       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
11859       break;
11860
11861     case RETURN_EXPR:
11862       /* CAN_COMPLETE_NORMALLY (node) = 0; */
11863       return patch_return (node);
11864
11865     case EXPR_WITH_FILE_LOCATION:
11866       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11867           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11868         {
11869           tree wfl = node;
11870           node = resolve_expression_name (node, NULL);
11871           if (node == error_mark_node)
11872             return node;
11873           /* Keep line number information somewhere were it doesn't
11874              disrupt the completion process. */
11875           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
11876             {
11877               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
11878               TREE_OPERAND (node, 1) = wfl;
11879             }
11880           CAN_COMPLETE_NORMALLY (node) = 1;
11881         }
11882       else
11883         {
11884           tree body;
11885           int save_lineno = lineno;
11886           lineno = EXPR_WFL_LINENO (node);
11887           body = java_complete_tree (EXPR_WFL_NODE (node));
11888           lineno = save_lineno;
11889           EXPR_WFL_NODE (node) = body;
11890           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
11891           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
11892           if (body == empty_stmt_node || TREE_CONSTANT (body))
11893             {
11894               /* Makes it easier to constant fold, detect empty bodies. */
11895               return body;
11896             }
11897           if (body == error_mark_node)
11898             {
11899               /* Its important for the evaluation of assignment that
11900                  this mark on the TREE_TYPE is propagated. */
11901               TREE_TYPE (node) = error_mark_node;
11902               return error_mark_node;
11903             }
11904           else
11905             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
11906           
11907         }
11908       break;
11909
11910     case NEW_ARRAY_EXPR:
11911       /* Patch all the dimensions */
11912       flag = 0;
11913       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11914         {
11915           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
11916           tree dim = convert (int_type_node, 
11917                               java_complete_tree (TREE_VALUE (cn)));
11918           if (dim == error_mark_node)
11919             {
11920               flag = 1;
11921               continue;
11922             }
11923           else
11924             {
11925               TREE_VALUE (cn) = dim;
11926               /* Setup the location of the current dimension, for
11927                  later error report. */
11928               TREE_PURPOSE (cn) = 
11929                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
11930               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
11931             }
11932         }
11933       /* They complete the array creation expression, if no errors
11934          were found. */
11935       CAN_COMPLETE_NORMALLY (node) = 1;
11936       return (flag ? error_mark_node
11937               : force_evaluation_order (patch_newarray (node)));
11938
11939     case NEW_ANONYMOUS_ARRAY_EXPR:
11940       /* Create the array type if necessary. */
11941       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
11942         {
11943           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
11944           if (!(type = resolve_type_during_patch (type)))
11945             return error_mark_node;
11946           type = build_array_from_name (type, NULL_TREE,
11947                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
11948           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
11949         }
11950       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
11951                                    ANONYMOUS_ARRAY_INITIALIZER (node));
11952       if (node == error_mark_node)
11953         return error_mark_node;
11954       CAN_COMPLETE_NORMALLY (node) = 1;
11955       return node;
11956
11957     case NEW_CLASS_EXPR:
11958     case CALL_EXPR:
11959       /* Complete function's argument(s) first */
11960       if (complete_function_arguments (node))
11961         return error_mark_node;
11962       else
11963         {
11964           tree decl, wfl = TREE_OPERAND (node, 0);
11965           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
11966           int from_super = (EXPR_WFL_NODE (TREE_OPERAND (node, 0)) ==
11967                            super_identifier_node);
11968
11969           node = patch_method_invocation (node, NULL_TREE, NULL_TREE,
11970                                           from_super, 0, &decl);
11971           if (node == error_mark_node)
11972             return error_mark_node;
11973
11974           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
11975           /* If we call this(...), register signature and positions */
11976           if (in_this)
11977             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
11978               tree_cons (wfl, decl, 
11979                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
11980           CAN_COMPLETE_NORMALLY (node) = 1;
11981           return force_evaluation_order (node);
11982         }
11983
11984     case MODIFY_EXPR:
11985       /* Save potential wfls */
11986       wfl_op1 = TREE_OPERAND (node, 0);
11987       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
11988       
11989       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
11990           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
11991           && DECL_INITIAL (nn) != NULL_TREE)
11992         {
11993           tree value;
11994           
11995           value = fold_constant_for_init (nn, nn);
11996
11997           /* When we have a primitype type, or a string and we're not
11998              emitting a class file, we actually don't want to generate
11999              anything for the assignment. */
12000           if (value != NULL_TREE &&
12001               (JPRIMITIVE_TYPE_P (TREE_TYPE (value)) || 
12002                (TREE_TYPE (value) == string_ptr_type_node &&
12003                 ! flag_emit_class_files)))
12004             {
12005               /* Prepare node for patch_assignment */
12006               TREE_OPERAND (node, 1) = value;
12007               /* Call patch assignment to verify the assignment */
12008               if (patch_assignment (node, wfl_op1) == error_mark_node)
12009                 return error_mark_node;
12010               /* Set DECL_INITIAL properly (a conversion might have
12011                  been decided by patch_assignment) and return the
12012                  empty statement. */
12013               else
12014                 {
12015                   tree patched = patch_string (TREE_OPERAND (node, 1));
12016                   if (patched)
12017                     DECL_INITIAL (nn) = patched;
12018                   else
12019                     DECL_INITIAL (nn) = TREE_OPERAND (node, 1);
12020                   DECL_FIELD_FINAL_IUD (nn) = 1;
12021                   return empty_stmt_node;
12022                 }
12023             }
12024           if (! flag_emit_class_files)
12025             DECL_INITIAL (nn) = NULL_TREE;
12026         }
12027       wfl_op2 = TREE_OPERAND (node, 1);
12028
12029       if (TREE_OPERAND (node, 0) == error_mark_node)
12030         return error_mark_node;
12031
12032       flag = COMPOUND_ASSIGN_P (wfl_op2);
12033       if (flag)
12034         {
12035           /* This might break when accessing outer field from inner
12036              class. TESTME, FIXME */
12037           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
12038
12039           /* Hand stabilize the lhs on both places */
12040           TREE_OPERAND (node, 0) = lvalue;
12041           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
12042             (flag_emit_class_files ? lvalue : save_expr (lvalue));
12043
12044           /* 15.25.2.a: Left hand is not an array access. FIXME */
12045           /* Now complete the RHS. We write it back later on. */
12046           nn = java_complete_tree (TREE_OPERAND (node, 1));
12047
12048           if ((cn = patch_string (nn)))
12049             nn = cn;
12050
12051           /* The last part of the rewrite for E1 op= E2 is to have 
12052              E1 = (T)(E1 op E2), with T being the type of E1. */
12053           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
12054                                                TREE_TYPE (lvalue), nn));
12055
12056           /* If the assignment is compound and has reference type,
12057              then ensure the LHS has type String and nothing else.  */
12058           if (JREFERENCE_TYPE_P (TREE_TYPE (lvalue))
12059               && ! JSTRING_TYPE_P (TREE_TYPE (lvalue)))
12060             parse_error_context (wfl_op2,
12061                                  "Incompatible type for `+='. Can't convert `%s' to `java.lang.String'",
12062                                  lang_printable_name (TREE_TYPE (lvalue), 0));
12063
12064           /* 15.25.2.b: Left hand is an array access. FIXME */
12065         }
12066
12067       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
12068          function to complete this RHS. Note that a NEW_ARRAY_INIT
12069          might have been already fully expanded if created as a result
12070          of processing an anonymous array initializer. We avoid doing
12071          the operation twice by testing whether the node already bears
12072          a type. */
12073       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
12074         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
12075                                    TREE_OPERAND (node, 1));
12076       /* Otherwise we simply complete the RHS */
12077       else
12078         nn = java_complete_tree (TREE_OPERAND (node, 1));
12079
12080       if (nn == error_mark_node)
12081         return error_mark_node;
12082
12083       /* Write back the RHS as we evaluated it. */
12084       TREE_OPERAND (node, 1) = nn;
12085
12086       /* In case we're handling = with a String as a RHS, we need to
12087          produce a String out of the RHS (it might still be a
12088          STRING_CST or a StringBuffer at this stage */
12089       if ((nn = patch_string (TREE_OPERAND (node, 1))))
12090         TREE_OPERAND (node, 1) = nn;
12091
12092       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
12093                                         TREE_OPERAND (node, 1))))
12094         {
12095           /* We return error_mark_node if outer_field_access_fix
12096              detects we write into a final. */
12097           if (nn == error_mark_node)
12098             return error_mark_node;
12099           node = nn;
12100         }
12101       else
12102         {
12103           node = patch_assignment (node, wfl_op1);
12104           if (node == error_mark_node)
12105             return error_mark_node;
12106           /* Reorganize the tree if necessary. */
12107           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
12108                        || JSTRING_P (TREE_TYPE (node))))
12109             node = java_refold (node);
12110         }
12111
12112       /* Seek to set DECL_INITIAL to a proper value, since it might have
12113          undergone a conversion in patch_assignment. We do that only when
12114          it's necessary to have DECL_INITIAL properly set. */
12115       nn = TREE_OPERAND (node, 0);
12116       if (TREE_CODE (nn) == VAR_DECL 
12117           && DECL_INITIAL (nn) && CONSTANT_VALUE_P (DECL_INITIAL (nn))
12118           && FIELD_STATIC (nn) && FIELD_FINAL (nn) 
12119           && (JPRIMITIVE_TYPE_P (TREE_TYPE (nn))
12120               || TREE_TYPE (nn) == string_ptr_type_node))
12121         DECL_INITIAL (nn) = TREE_OPERAND (node, 1);
12122
12123       CAN_COMPLETE_NORMALLY (node) = 1;
12124       return node;
12125
12126     case MULT_EXPR:
12127     case PLUS_EXPR:
12128     case MINUS_EXPR:
12129     case LSHIFT_EXPR:
12130     case RSHIFT_EXPR:
12131     case URSHIFT_EXPR:
12132     case BIT_AND_EXPR:
12133     case BIT_XOR_EXPR:
12134     case BIT_IOR_EXPR:
12135     case TRUNC_MOD_EXPR:
12136     case TRUNC_DIV_EXPR:
12137     case RDIV_EXPR:
12138     case TRUTH_ANDIF_EXPR:
12139     case TRUTH_ORIF_EXPR:
12140     case EQ_EXPR: 
12141     case NE_EXPR:
12142     case GT_EXPR:
12143     case GE_EXPR:
12144     case LT_EXPR:
12145     case LE_EXPR:
12146       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
12147          knows how to handle those cases. */
12148       wfl_op1 = TREE_OPERAND (node, 0);
12149       wfl_op2 = TREE_OPERAND (node, 1);
12150
12151       CAN_COMPLETE_NORMALLY (node) = 1;
12152       /* Don't complete string nodes if dealing with the PLUS operand. */
12153       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
12154         {
12155           nn = java_complete_tree (wfl_op1);
12156           if (nn == error_mark_node)
12157             return error_mark_node;
12158
12159           TREE_OPERAND (node, 0) = nn;
12160         }
12161       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
12162         {
12163           nn = java_complete_tree (wfl_op2);
12164           if (nn == error_mark_node)
12165             return error_mark_node;
12166
12167           TREE_OPERAND (node, 1) = nn;
12168         }
12169       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
12170
12171     case INSTANCEOF_EXPR:
12172       wfl_op1 = TREE_OPERAND (node, 0);
12173       COMPLETE_CHECK_OP_0 (node);
12174       if (flag_emit_xref)
12175         {
12176           TREE_TYPE (node) = boolean_type_node;
12177           return node;
12178         }
12179       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
12180
12181     case UNARY_PLUS_EXPR:
12182     case NEGATE_EXPR:
12183     case TRUTH_NOT_EXPR:
12184     case BIT_NOT_EXPR:
12185     case PREDECREMENT_EXPR:
12186     case PREINCREMENT_EXPR:
12187     case POSTDECREMENT_EXPR:
12188     case POSTINCREMENT_EXPR:
12189     case CONVERT_EXPR:
12190       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
12191          how to handle those cases. */
12192       wfl_op1 = TREE_OPERAND (node, 0);
12193       CAN_COMPLETE_NORMALLY (node) = 1;
12194       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
12195       if (TREE_OPERAND (node, 0) == error_mark_node)
12196         return error_mark_node;
12197       node = patch_unaryop (node, wfl_op1);
12198       CAN_COMPLETE_NORMALLY (node) = 1;
12199       break;
12200
12201     case ARRAY_REF:
12202       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
12203          how to handle those cases. */
12204       wfl_op1 = TREE_OPERAND (node, 0);
12205       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
12206       if (TREE_OPERAND (node, 0) == error_mark_node)
12207         return error_mark_node;
12208       if (!flag_emit_class_files && !flag_emit_xref)
12209         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
12210       /* The same applies to wfl_op2 */
12211       wfl_op2 = TREE_OPERAND (node, 1);
12212       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
12213       if (TREE_OPERAND (node, 1) == error_mark_node)
12214         return error_mark_node;
12215       if (!flag_emit_class_files && !flag_emit_xref)
12216         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
12217       return patch_array_ref (node);
12218
12219     case RECORD_TYPE:
12220       return node;;
12221
12222     case COMPONENT_REF:
12223       /* The first step in the re-write of qualified name handling.  FIXME.
12224          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
12225       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
12226       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
12227         {
12228           tree name = TREE_OPERAND (node, 1);
12229           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
12230           if (field == NULL_TREE)
12231             {
12232               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
12233               return error_mark_node;
12234             }
12235           if (! FIELD_STATIC (field))
12236             {
12237               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
12238               return error_mark_node;
12239             }
12240           return field;
12241         }
12242       else
12243         abort ();
12244       break;
12245
12246     case THIS_EXPR:
12247       /* Can't use THIS in a static environment */
12248       if (!current_this)
12249         {
12250           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12251           parse_error_context (wfl_operator,
12252                                "Keyword `this' used outside allowed context");
12253           TREE_TYPE (node) = error_mark_node;
12254           return error_mark_node;
12255         }
12256       if (ctxp->explicit_constructor_p)
12257         {
12258           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12259           parse_error_context 
12260             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
12261           TREE_TYPE (node) = error_mark_node;
12262           return error_mark_node;
12263         }
12264       return current_this;
12265       
12266     case CLASS_LITERAL:
12267       CAN_COMPLETE_NORMALLY (node) = 1;
12268       node = patch_incomplete_class_ref (node);
12269       if (node == error_mark_node)
12270         return error_mark_node;
12271       break;
12272
12273     default:
12274       CAN_COMPLETE_NORMALLY (node) = 1;
12275       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
12276          and it's time to turn it into the appropriate String object */
12277       if ((nn = patch_string (node)))
12278         node = nn;
12279       else
12280         internal_error ("No case for %s", tree_code_name [TREE_CODE (node)]);
12281     }
12282   return node;
12283 }
12284
12285 /* Complete function call's argument. Return a non zero value is an
12286    error was found.  */
12287
12288 static int
12289 complete_function_arguments (node)
12290      tree node;
12291 {
12292   int flag = 0;
12293   tree cn;
12294
12295   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
12296   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
12297     {
12298       tree wfl = TREE_VALUE (cn), parm, temp;
12299       parm = java_complete_tree (wfl);
12300
12301       if (parm == error_mark_node)
12302         {
12303           flag = 1;
12304           continue;
12305         }
12306       /* If have a string literal that we haven't transformed yet or a
12307          crafted string buffer, as a result of use of the the String
12308          `+' operator. Build `parm.toString()' and expand it. */
12309       if ((temp = patch_string (parm)))
12310         parm = temp;
12311
12312       TREE_VALUE (cn) = parm;
12313     }
12314   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
12315   return flag;
12316 }
12317
12318 /* Sometimes (for loops and variable initialized during their
12319    declaration), we want to wrap a statement around a WFL and turn it
12320    debugable.  */
12321
12322 static tree
12323 build_debugable_stmt (location, stmt)
12324     int location;
12325     tree stmt;
12326 {
12327   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
12328     {
12329       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
12330       EXPR_WFL_LINECOL (stmt) = location;
12331     }
12332   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
12333   return stmt;
12334 }
12335
12336 static tree
12337 build_expr_block (body, decls)
12338      tree body, decls;
12339 {
12340   tree node = make_node (BLOCK);
12341   BLOCK_EXPR_DECLS (node) = decls;
12342   BLOCK_EXPR_BODY (node) = body;
12343   if (body)
12344     TREE_TYPE (node) = TREE_TYPE (body);
12345   TREE_SIDE_EFFECTS (node) = 1;
12346   return node;
12347 }
12348
12349 /* Create a new function block and link it appropriately to current
12350    function block chain */
12351
12352 static tree
12353 enter_block ()
12354 {
12355   tree b = build_expr_block (NULL_TREE, NULL_TREE);
12356
12357   /* Link block B supercontext to the previous block. The current
12358      function DECL is used as supercontext when enter_a_block is called
12359      for the first time for a given function. The current function body
12360      (DECL_FUNCTION_BODY) is set to be block B.  */
12361
12362   tree fndecl = current_function_decl; 
12363
12364   if (!fndecl) {
12365     BLOCK_SUPERCONTEXT (b) = current_static_block;
12366     current_static_block = b;
12367   }
12368
12369   else if (!DECL_FUNCTION_BODY (fndecl))
12370     {
12371       BLOCK_SUPERCONTEXT (b) = fndecl;
12372       DECL_FUNCTION_BODY (fndecl) = b;
12373     }
12374   else
12375     {
12376       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
12377       DECL_FUNCTION_BODY (fndecl) = b;
12378     }
12379   return b;
12380 }
12381
12382 /* Exit a block by changing the current function body
12383    (DECL_FUNCTION_BODY) to the current block super context, only if
12384    the block being exited isn't the method's top level one.  */
12385
12386 static tree
12387 exit_block ()
12388 {
12389   tree b;
12390   if (current_function_decl)
12391     {
12392       b = DECL_FUNCTION_BODY (current_function_decl);
12393       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
12394         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
12395     }
12396   else
12397     {
12398       b = current_static_block;
12399
12400       if (BLOCK_SUPERCONTEXT (b))
12401         current_static_block = BLOCK_SUPERCONTEXT (b);
12402     }
12403   return b;
12404 }
12405
12406 /* Lookup for NAME in the nested function's blocks, all the way up to
12407    the current toplevel one. It complies with Java's local variable
12408    scoping rules.  */
12409
12410 static tree
12411 lookup_name_in_blocks (name)
12412      tree name;
12413 {
12414   tree b = GET_CURRENT_BLOCK (current_function_decl);
12415
12416   while (b != current_function_decl)
12417     {
12418       tree current;
12419
12420       /* Paranoid sanity check. To be removed */
12421       if (TREE_CODE (b) != BLOCK)
12422         abort ();
12423
12424       for (current = BLOCK_EXPR_DECLS (b); current; 
12425            current = TREE_CHAIN (current))
12426         if (DECL_NAME (current) == name)
12427           return current;
12428       b = BLOCK_SUPERCONTEXT (b);
12429     }
12430   return NULL_TREE;
12431 }
12432
12433 static void
12434 maybe_absorb_scoping_blocks ()
12435 {
12436   while (BLOCK_IS_IMPLICIT (GET_CURRENT_BLOCK (current_function_decl)))
12437     {
12438       tree b = exit_block ();
12439       java_method_add_stmt (current_function_decl, b);
12440       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
12441     }
12442 }
12443
12444 \f
12445 /* This section of the source is reserved to build_* functions that
12446    are building incomplete tree nodes and the patch_* functions that
12447    are completing them.  */
12448
12449 /* Wrap a non WFL node around a WFL.  */
12450
12451 static tree
12452 build_wfl_wrap (node, location)
12453     tree node;
12454     int location;
12455 {
12456   tree wfl, node_to_insert = node;
12457   
12458   /* We want to process THIS . xxx symbolicaly, to keep it consistent
12459      with the way we're processing SUPER. A THIS from a primary as a
12460      different form than a SUPER. Turn THIS into something symbolic */
12461   if (TREE_CODE (node) == THIS_EXPR)
12462     node_to_insert = wfl = build_wfl_node (this_identifier_node);
12463   else
12464     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
12465
12466   EXPR_WFL_LINECOL (wfl) = location;
12467   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
12468   return wfl;
12469 }
12470
12471 /* Build a super() constructor invocation. Returns empty_stmt_node if
12472    we're currently dealing with the class java.lang.Object. */
12473
12474 static tree
12475 build_super_invocation (mdecl)
12476      tree mdecl;
12477 {
12478   if (DECL_CONTEXT (mdecl) == object_type_node)
12479     return empty_stmt_node;
12480   else
12481     {
12482       tree super_wfl = build_wfl_node (super_identifier_node);
12483       tree a = NULL_TREE, t;
12484       /* If we're dealing with an anonymous class, pass the arguments
12485          of the crafted constructor along. */
12486       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
12487         {
12488           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
12489           for (; t != end_params_node; t = TREE_CHAIN (t))
12490             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
12491         }
12492       return build_method_invocation (super_wfl, a);
12493     }
12494 }
12495
12496 /* Build a SUPER/THIS qualified method invocation.  */
12497
12498 static tree
12499 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
12500      int use_this;
12501      tree name, args;
12502      int lloc, rloc;
12503 {
12504   tree invok;
12505   tree wfl = 
12506     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
12507   EXPR_WFL_LINECOL (wfl) = lloc;
12508   invok = build_method_invocation (name, args);
12509   return make_qualified_primary (wfl, invok, rloc);
12510 }
12511
12512 /* Build an incomplete CALL_EXPR node. */
12513
12514 static tree
12515 build_method_invocation (name, args)
12516     tree name;
12517     tree args;
12518 {
12519   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
12520   TREE_SIDE_EFFECTS (call) = 1;
12521   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12522   return call;
12523 }
12524
12525 /* Build an incomplete new xxx(...) node. */
12526
12527 static tree
12528 build_new_invocation (name, args)
12529     tree name, args;
12530 {
12531   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
12532   TREE_SIDE_EFFECTS (call) = 1;
12533   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12534   return call;
12535 }
12536
12537 /* Build an incomplete assignment expression. */
12538
12539 static tree
12540 build_assignment (op, op_location, lhs, rhs)
12541      int op, op_location;
12542      tree lhs, rhs;
12543 {
12544   tree assignment;
12545   /* Build the corresponding binop if we deal with a Compound
12546      Assignment operator. Mark the binop sub-tree as part of a
12547      Compound Assignment expression */
12548   if (op != ASSIGN_TK)
12549     {
12550       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
12551       COMPOUND_ASSIGN_P (rhs) = 1;
12552     }
12553   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
12554   TREE_SIDE_EFFECTS (assignment) = 1;
12555   EXPR_WFL_LINECOL (assignment) = op_location;
12556   return assignment;
12557 }
12558
12559 /* Print an INTEGER_CST node as decimal in a static buffer, and return
12560    the buffer.  This is used only for string conversion.  */
12561 static char *
12562 string_convert_int_cst (node)
12563      tree node;
12564 {
12565   static char buffer[80];
12566
12567   unsigned HOST_WIDE_INT lo = TREE_INT_CST_LOW (node);
12568   unsigned HOST_WIDE_INT hi = TREE_INT_CST_HIGH (node);
12569   char *p = buffer + sizeof (buffer) - 1;
12570   int neg = 0;
12571
12572   unsigned HOST_WIDE_INT hibit = (((unsigned HOST_WIDE_INT) 1)
12573                                   << (HOST_BITS_PER_WIDE_INT - 1));
12574
12575   *p-- = '\0';
12576
12577   /* If negative, note the fact and negate the value.  */
12578   if ((hi & hibit))
12579     {
12580       lo = ~lo;
12581       hi = ~hi;
12582       if (++lo == 0)
12583         ++hi;
12584       neg = 1;
12585     }
12586
12587   /* Divide by 10 until there are no bits left.  */
12588   while (hi || lo)
12589     {
12590       unsigned HOST_WIDE_INT acc = 0;
12591       unsigned HOST_WIDE_INT outhi = 0, outlo = 0;
12592       unsigned int i;
12593
12594       /* Use long division to compute the result and the remainder.  */
12595       for (i = 0; i < 2 * HOST_BITS_PER_WIDE_INT; ++i)
12596         {
12597           /* Shift a bit into accumulator.  */
12598           acc <<= 1;
12599           if ((hi & hibit))
12600             acc |= 1;
12601
12602           /* Shift the value.  */
12603           hi <<= 1;
12604           if ((lo & hibit))
12605             hi |= 1;
12606           lo <<= 1;
12607
12608           /* Shift the correct bit into the result.  */
12609           outhi <<= 1;
12610           if ((outlo & hibit))
12611             outhi |= 1;
12612           outlo <<= 1;
12613           if (acc >= 10)
12614             {
12615               acc -= 10;
12616               outlo |= 1;
12617             }
12618         }
12619
12620       /* FIXME: ASCII assumption.  */
12621       *p-- = '0' + acc;
12622
12623       hi = outhi;
12624       lo = outlo;
12625     }
12626
12627   if (neg)
12628     *p-- = '-';
12629
12630   return p + 1;
12631 }
12632
12633 /* Print an INTEGER_CST node in a static buffer, and return the
12634    buffer.  This is used only for error handling.  */
12635 char *
12636 print_int_node (node)
12637     tree node;
12638 {
12639   static char buffer [80];
12640   if (TREE_CONSTANT_OVERFLOW (node))
12641     sprintf (buffer, "<overflow>");
12642     
12643   if (TREE_INT_CST_HIGH (node) == 0)
12644     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
12645              TREE_INT_CST_LOW (node));
12646   else if (TREE_INT_CST_HIGH (node) == -1
12647            && TREE_INT_CST_LOW (node) != 0)
12648     {
12649       buffer [0] = '-';
12650       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
12651                -TREE_INT_CST_LOW (node));
12652     }
12653   else
12654     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
12655              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
12656
12657   return buffer;
12658 }
12659
12660 \f
12661 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
12662    context.  */
12663
12664 /* 15.25 Assignment operators. */
12665
12666 static tree
12667 patch_assignment (node, wfl_op1)
12668      tree node;
12669      tree wfl_op1;
12670 {
12671   tree rhs = TREE_OPERAND (node, 1);
12672   tree lvalue = TREE_OPERAND (node, 0), llvalue;
12673   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
12674   int error_found = 0;
12675   int lvalue_from_array = 0;
12676   int is_return = 0;
12677
12678   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12679
12680   /* Lhs can be a named variable */
12681   if (JDECL_P (lvalue))
12682     {
12683       lhs_type = TREE_TYPE (lvalue);
12684     }
12685   /* Or Lhs can be an array access. */
12686   else if (TREE_CODE (lvalue) == ARRAY_REF)
12687     {
12688       lhs_type = TREE_TYPE (lvalue);
12689       lvalue_from_array = 1;
12690     }
12691   /* Or a field access */
12692   else if (TREE_CODE (lvalue) == COMPONENT_REF)
12693     lhs_type = TREE_TYPE (lvalue);
12694   /* Or a function return slot */
12695   else if (TREE_CODE (lvalue) == RESULT_DECL)
12696     {
12697       /* If the return type is an integral type, then we create the
12698          RESULT_DECL with a promoted type, but we need to do these
12699          checks against the unpromoted type to ensure type safety.  So
12700          here we look at the real type, not the type of the decl we
12701          are modifying.  */
12702       lhs_type = TREE_TYPE (TREE_TYPE (current_function_decl));
12703       is_return = 1;
12704     }
12705   /* Otherwise, we might want to try to write into an optimized static
12706      final, this is an of a different nature, reported further on. */
12707   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
12708            && resolve_expression_name (wfl_op1, &llvalue))
12709     {
12710       lhs_type = TREE_TYPE (lvalue);
12711     }
12712   else 
12713     {
12714       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
12715       error_found = 1;
12716     }
12717
12718   rhs_type = TREE_TYPE (rhs);
12719
12720   /* 5.1 Try the assignment conversion for builtin type. */
12721   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
12722
12723   /* 5.2 If it failed, try a reference conversion */
12724   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
12725     lhs_type = promote_type (rhs_type);
12726
12727   /* 15.25.2 If we have a compound assignment, convert RHS into the
12728      type of the LHS */
12729   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12730     new_rhs = convert (lhs_type, rhs);
12731
12732   /* Explicit cast required. This is an error */
12733   if (!new_rhs)
12734     {
12735       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
12736       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
12737       tree wfl;
12738       char operation [32];      /* Max size known */
12739
12740       /* If the assignment is part of a declaration, we use the WFL of
12741          the declared variable to point out the error and call it a
12742          declaration problem. If the assignment is a genuine =
12743          operator, we call is a operator `=' problem, otherwise we
12744          call it an assignment problem. In both of these last cases,
12745          we use the WFL of the operator to indicate the error. */
12746
12747       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
12748         {
12749           wfl = wfl_op1;
12750           strcpy (operation, "declaration");
12751         }
12752       else
12753         {
12754           wfl = wfl_operator;
12755           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12756             strcpy (operation, "assignment");
12757           else if (is_return)
12758             strcpy (operation, "`return'");
12759           else
12760             strcpy (operation, "`='");
12761         }
12762
12763       if (!valid_cast_to_p (rhs_type, lhs_type))
12764         parse_error_context
12765           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
12766            operation, t1, t2);
12767       else
12768         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
12769                              operation, t1, t2);
12770       free (t1); free (t2);
12771       error_found = 1;
12772     }
12773
12774   if (error_found)
12775     return error_mark_node;
12776
12777   /* If we're processing a `return' statement, promote the actual type
12778      to the promoted type.  */
12779   if (is_return)
12780     new_rhs = convert (TREE_TYPE (lvalue), new_rhs);
12781
12782   /* 10.10: Array Store Exception runtime check */
12783   if (!flag_emit_class_files
12784       && !flag_emit_xref
12785       && lvalue_from_array 
12786       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
12787     {
12788       tree array, store_check, base, index_expr;
12789       
12790       /* Save RHS so that it doesn't get re-evaluated by the store check. */ 
12791       new_rhs = save_expr (new_rhs);
12792
12793       /* Get the INDIRECT_REF. */
12794       array = TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0);
12795       /* Get the array pointer expr. */
12796       array = TREE_OPERAND (array, 0);
12797       store_check = build_java_arraystore_check (array, new_rhs);
12798       
12799       index_expr = TREE_OPERAND (lvalue, 1);
12800       
12801       if (TREE_CODE (index_expr) == COMPOUND_EXPR)
12802         {
12803           /* A COMPOUND_EXPR here is a bounds check. The bounds check must 
12804              happen before the store check, so prepare to insert the store
12805              check within the second operand of the existing COMPOUND_EXPR. */
12806           base = index_expr;
12807         }
12808       else
12809         base = lvalue;
12810       
12811       index_expr = TREE_OPERAND (base, 1);
12812       TREE_OPERAND (base, 1) = build (COMPOUND_EXPR, TREE_TYPE (index_expr), 
12813                                       store_check, index_expr);
12814     }
12815
12816   /* Final locals can be used as case values in switch
12817      statement. Prepare them for this eventuality. */
12818   if (TREE_CODE (lvalue) == VAR_DECL 
12819       && DECL_FINAL (lvalue)
12820       && TREE_CONSTANT (new_rhs)
12821       && IDENTIFIER_LOCAL_VALUE (DECL_NAME (lvalue))
12822       && JINTEGRAL_TYPE_P (TREE_TYPE (lvalue))
12823       )
12824     {
12825       TREE_CONSTANT (lvalue) = 1;
12826       DECL_INITIAL (lvalue) = new_rhs;
12827     }
12828
12829   TREE_OPERAND (node, 0) = lvalue;
12830   TREE_OPERAND (node, 1) = new_rhs;
12831   TREE_TYPE (node) = lhs_type;
12832   return node;
12833 }
12834
12835 /* Check that type SOURCE can be cast into type DEST. If the cast
12836    can't occur at all, return NULL; otherwise, return a possibly
12837    modified rhs.  */
12838
12839 static tree
12840 try_reference_assignconv (lhs_type, rhs)
12841      tree lhs_type, rhs;
12842 {
12843   tree new_rhs = NULL_TREE;
12844   tree rhs_type = TREE_TYPE (rhs);
12845
12846   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
12847     {
12848       /* `null' may be assigned to any reference type */
12849       if (rhs == null_pointer_node)
12850         new_rhs = null_pointer_node;
12851       /* Try the reference assignment conversion */
12852       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
12853         new_rhs = rhs;
12854       /* This is a magic assignment that we process differently */
12855       else if (TREE_CODE (rhs) == JAVA_EXC_OBJ_EXPR)
12856         new_rhs = rhs;
12857     }
12858   return new_rhs;
12859 }
12860
12861 /* Check that RHS can be converted into LHS_TYPE by the assignment
12862    conversion (5.2), for the cases of RHS being a builtin type. Return
12863    NULL_TREE if the conversion fails or if because RHS isn't of a
12864    builtin type. Return a converted RHS if the conversion is possible.  */
12865
12866 static tree
12867 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
12868      tree wfl_op1, lhs_type, rhs;
12869 {
12870   tree new_rhs = NULL_TREE;
12871   tree rhs_type = TREE_TYPE (rhs);
12872
12873   /* Handle boolean specially.  */
12874   if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
12875       || TREE_CODE (lhs_type) == BOOLEAN_TYPE)
12876     {
12877       if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
12878           && TREE_CODE (lhs_type) == BOOLEAN_TYPE)
12879         new_rhs = rhs;
12880     }
12881
12882   /* 5.1.1 Try Identity Conversion,
12883      5.1.2 Try Widening Primitive Conversion */
12884   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
12885     new_rhs = convert (lhs_type, rhs);
12886
12887   /* Try a narrowing primitive conversion (5.1.3): 
12888        - expression is a constant expression of type int AND
12889        - variable is byte, short or char AND
12890        - The value of the expression is representable in the type of the 
12891          variable */
12892   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
12893            && (lhs_type == byte_type_node || lhs_type == char_type_node
12894                || lhs_type == short_type_node))
12895     {
12896       if (int_fits_type_p (rhs, lhs_type))
12897         new_rhs = convert (lhs_type, rhs);
12898       else if (wfl_op1)         /* Might be called with a NULL */
12899         parse_warning_context 
12900           (wfl_op1, "Constant expression `%s' too wide for narrowing primitive conversion to `%s'", 
12901            print_int_node (rhs), lang_printable_name (lhs_type, 0));
12902       /* Reported a warning that will turn into an error further
12903          down, so we don't return */
12904     }
12905
12906   return new_rhs;
12907 }
12908
12909 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
12910    conversion (5.1.1) or widening primitive conversion (5.1.2).  Return
12911    0 is the conversion test fails.  This implements parts the method
12912    invocation convertion (5.3).  */
12913
12914 static int
12915 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
12916      tree lhs_type, rhs_type;
12917 {
12918   /* 5.1.1: This is the identity conversion part. */
12919   if (lhs_type == rhs_type)
12920     return 1;
12921
12922   /* Reject non primitive types and boolean conversions.  */
12923   if (!JNUMERIC_TYPE_P (lhs_type) || !JNUMERIC_TYPE_P (rhs_type))
12924     return 0;
12925
12926   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
12927      than a char can't be converted into a char. Short can't too, but
12928      the < test below takes care of that */
12929   if (lhs_type == char_type_node && rhs_type == byte_type_node)
12930     return 0;
12931
12932   /* Accept all promoted type here. Note, we can't use <= in the test
12933      below, because we still need to bounce out assignments of short
12934      to char and the likes */
12935   if (lhs_type == int_type_node
12936       && (rhs_type == promoted_byte_type_node
12937           || rhs_type == promoted_short_type_node
12938           || rhs_type == promoted_char_type_node
12939           || rhs_type == promoted_boolean_type_node))
12940     return 1;
12941
12942   /* From here, an integral is widened if its precision is smaller
12943      than the precision of the LHS or if the LHS is a floating point
12944      type, or the RHS is a float and the RHS a double. */
12945   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
12946        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
12947       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
12948       || (rhs_type == float_type_node && lhs_type == double_type_node))
12949     return 1;
12950
12951   return 0;
12952 }
12953
12954 /* Check that something of SOURCE type can be assigned or cast to
12955    something of DEST type at runtime. Return 1 if the operation is
12956    valid, 0 otherwise. If CAST is set to 1, we're treating the case
12957    were SOURCE is cast into DEST, which borrows a lot of the
12958    assignment check. */
12959
12960 static int
12961 valid_ref_assignconv_cast_p (source, dest, cast)
12962      tree source;
12963      tree dest;
12964      int cast;
12965 {
12966   /* SOURCE or DEST might be null if not from a declared entity. */
12967   if (!source || !dest)
12968     return 0;
12969   if (JNULLP_TYPE_P (source))
12970     return 1;
12971   if (TREE_CODE (source) == POINTER_TYPE)
12972     source = TREE_TYPE (source);
12973   if (TREE_CODE (dest) == POINTER_TYPE)
12974     dest = TREE_TYPE (dest);
12975
12976   /* If source and dest are being compiled from bytecode, they may need to
12977      be loaded. */
12978   if (CLASS_P (source) && !CLASS_LOADED_P (source))
12979     {
12980       load_class (source, 1);
12981       safe_layout_class (source);
12982     }
12983   if (CLASS_P (dest) && !CLASS_LOADED_P (dest))
12984     {
12985       load_class (dest, 1);
12986       safe_layout_class (dest);
12987     }
12988
12989   /* Case where SOURCE is a class type */
12990   if (TYPE_CLASS_P (source))
12991     {
12992       if (TYPE_CLASS_P (dest))
12993         return  (source == dest 
12994                  || inherits_from_p (source, dest)
12995                  || (cast && inherits_from_p (dest, source)));
12996       if (TYPE_INTERFACE_P (dest))
12997         {
12998           /* If doing a cast and SOURCE is final, the operation is
12999              always correct a compile time (because even if SOURCE
13000              does not implement DEST, a subclass of SOURCE might). */
13001           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
13002             return 1;
13003           /* Otherwise, SOURCE must implement DEST */
13004           return interface_of_p (dest, source);
13005         }
13006       /* DEST is an array, cast permited if SOURCE is of Object type */
13007       return (cast && source == object_type_node ? 1 : 0);
13008     }
13009   if (TYPE_INTERFACE_P (source))
13010     {
13011       if (TYPE_CLASS_P (dest))
13012         {
13013           /* If not casting, DEST must be the Object type */
13014           if (!cast)
13015             return dest == object_type_node;
13016           /* We're doing a cast. The cast is always valid is class
13017              DEST is not final, otherwise, DEST must implement SOURCE */
13018           else if (!CLASS_FINAL (TYPE_NAME (dest)))
13019             return 1;
13020           else
13021             return interface_of_p (source, dest);
13022         }
13023       if (TYPE_INTERFACE_P (dest))
13024         {
13025           /* If doing a cast, then if SOURCE and DEST contain method
13026              with the same signature but different return type, then
13027              this is a (compile time) error */
13028           if (cast)
13029             {
13030               tree method_source, method_dest;
13031               tree source_type;
13032               tree source_sig;
13033               tree source_name;
13034               for (method_source = TYPE_METHODS (source); method_source; 
13035                    method_source = TREE_CHAIN (method_source))
13036                 {
13037                   source_sig = 
13038                     build_java_argument_signature (TREE_TYPE (method_source));
13039                   source_type = TREE_TYPE (TREE_TYPE (method_source));
13040                   source_name = DECL_NAME (method_source);
13041                   for (method_dest = TYPE_METHODS (dest);
13042                        method_dest; method_dest = TREE_CHAIN (method_dest))
13043                     if (source_sig == 
13044                         build_java_argument_signature (TREE_TYPE (method_dest))
13045                         && source_name == DECL_NAME (method_dest)
13046                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
13047                       return 0;
13048                 }
13049               return 1;
13050             }
13051           else
13052             return source == dest || interface_of_p (dest, source);
13053         }
13054       else
13055         {
13056           /* Array */
13057           return (cast
13058                   && (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable
13059                       || (DECL_NAME (TYPE_NAME (source))
13060                           == java_io_serializable)));
13061         }
13062     }
13063   if (TYPE_ARRAY_P (source))
13064     {
13065       if (TYPE_CLASS_P (dest))
13066         return dest == object_type_node;
13067       /* Can't cast an array to an interface unless the interface is
13068          java.lang.Cloneable or java.io.Serializable.  */
13069       if (TYPE_INTERFACE_P (dest))
13070         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable
13071                 || DECL_NAME (TYPE_NAME (dest)) == java_io_serializable);
13072       else                      /* Arrays */
13073         {
13074           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
13075           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
13076           
13077           /* In case of severe errors, they turn out null */
13078           if (!dest_element_type || !source_element_type)
13079             return 0;
13080           if (source_element_type == dest_element_type)
13081             return 1;
13082           return valid_ref_assignconv_cast_p (source_element_type,
13083                                               dest_element_type, cast);
13084         }
13085       return 0;
13086     }
13087   return 0;
13088 }
13089
13090 static int
13091 valid_cast_to_p (source, dest)
13092      tree source;
13093      tree dest;
13094 {
13095   if (TREE_CODE (source) == POINTER_TYPE)
13096     source = TREE_TYPE (source);
13097   if (TREE_CODE (dest) == POINTER_TYPE)
13098     dest = TREE_TYPE (dest);
13099
13100   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
13101     return valid_ref_assignconv_cast_p (source, dest, 1);
13102
13103   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
13104     return 1;
13105
13106   else if (TREE_CODE (source) == BOOLEAN_TYPE
13107            && TREE_CODE (dest) == BOOLEAN_TYPE)
13108     return 1;
13109
13110   return 0;
13111 }
13112
13113 static tree
13114 do_unary_numeric_promotion (arg)
13115      tree arg;
13116 {
13117   tree type = TREE_TYPE (arg);
13118   if ((TREE_CODE (type) == INTEGER_TYPE && TYPE_PRECISION (type) < 32)
13119       || TREE_CODE (type) == CHAR_TYPE)
13120     arg = convert (int_type_node, arg);
13121   return arg;
13122 }
13123
13124 /* Return a non zero value if SOURCE can be converted into DEST using
13125    the method invocation conversion rule (5.3).  */
13126 static int
13127 valid_method_invocation_conversion_p (dest, source)
13128      tree dest, source;
13129 {
13130   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
13131            && valid_builtin_assignconv_identity_widening_p (dest, source))
13132           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
13133               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
13134               && valid_ref_assignconv_cast_p (source, dest, 0)));
13135 }
13136
13137 /* Build an incomplete binop expression. */
13138
13139 static tree
13140 build_binop (op, op_location, op1, op2)
13141      enum tree_code op;
13142      int op_location;
13143      tree op1, op2;
13144 {
13145   tree binop = build (op, NULL_TREE, op1, op2);
13146   TREE_SIDE_EFFECTS (binop) = 1;
13147   /* Store the location of the operator, for better error report. The
13148      string of the operator will be rebuild based on the OP value. */
13149   EXPR_WFL_LINECOL (binop) = op_location;
13150   return binop;
13151 }
13152
13153 /* Build the string of the operator retained by NODE. If NODE is part
13154    of a compound expression, add an '=' at the end of the string. This
13155    function is called when an error needs to be reported on an
13156    operator. The string is returned as a pointer to a static character
13157    buffer. */
13158
13159 static char *
13160 operator_string (node)
13161      tree node;
13162 {
13163 #define BUILD_OPERATOR_STRING(S)                                        \
13164   {                                                                     \
13165     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
13166     return buffer;                                                      \
13167   }
13168   
13169   static char buffer [10];
13170   switch (TREE_CODE (node))
13171     {
13172     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
13173     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
13174     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
13175     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
13176     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
13177     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
13178     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
13179     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
13180     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
13181     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
13182     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
13183     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
13184     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
13185     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
13186     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
13187     case GT_EXPR: BUILD_OPERATOR_STRING (">");
13188     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
13189     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
13190     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
13191     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
13192     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
13193     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
13194     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
13195     case PREINCREMENT_EXPR:     /* Fall through */
13196     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
13197     case PREDECREMENT_EXPR:     /* Fall through */
13198     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
13199     default:
13200       internal_error ("unregistered operator %s",
13201                       tree_code_name [TREE_CODE (node)]);
13202     }
13203   return NULL;
13204 #undef BUILD_OPERATOR_STRING
13205 }
13206
13207 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
13208
13209 static int
13210 java_decl_equiv (var_acc1, var_acc2)
13211      tree var_acc1, var_acc2;
13212 {
13213   if (JDECL_P (var_acc1))
13214     return (var_acc1 == var_acc2);
13215   
13216   return (TREE_CODE (var_acc1) == COMPONENT_REF
13217           && TREE_CODE (var_acc2) == COMPONENT_REF
13218           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
13219              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
13220           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
13221 }
13222
13223 /* Return a non zero value if CODE is one of the operators that can be
13224    used in conjunction with the `=' operator in a compound assignment.  */
13225
13226 static int
13227 binop_compound_p (code)
13228     enum tree_code code;
13229 {
13230   int i;
13231   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
13232     if (binop_lookup [i] == code)
13233       break;
13234
13235   return i < BINOP_COMPOUND_CANDIDATES;
13236 }
13237
13238 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
13239
13240 static tree
13241 java_refold (t)
13242      tree t;
13243 {
13244   tree c, b, ns, decl;
13245
13246   if (TREE_CODE (t) != MODIFY_EXPR)
13247     return t;
13248
13249   c = TREE_OPERAND (t, 1);
13250   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
13251          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
13252          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
13253     return t;
13254
13255   /* Now the left branch of the binary operator. */
13256   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
13257   if (! (b && TREE_CODE (b) == NOP_EXPR 
13258          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
13259     return t;
13260
13261   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
13262   if (! (ns && TREE_CODE (ns) == NOP_EXPR
13263          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
13264     return t;
13265
13266   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
13267   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
13268       /* It's got to be the an equivalent decl */
13269       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
13270     {
13271       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
13272       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
13273       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
13274       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
13275       /* Change the right part of the BINOP_EXPR */
13276       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
13277     }
13278
13279   return t;
13280 }
13281
13282 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
13283    errors but we modify NODE so that it contains the type computed
13284    according to the expression, when it's fixed. Otherwise, we write
13285    error_mark_node as the type. It allows us to further the analysis
13286    of remaining nodes and detects more errors in certain cases.  */
13287
13288 static tree
13289 patch_binop (node, wfl_op1, wfl_op2)
13290      tree node;
13291      tree wfl_op1;
13292      tree wfl_op2;
13293 {
13294   tree op1 = TREE_OPERAND (node, 0);
13295   tree op2 = TREE_OPERAND (node, 1);
13296   tree op1_type = TREE_TYPE (op1);
13297   tree op2_type = TREE_TYPE (op2);
13298   tree prom_type = NULL_TREE, cn;
13299   enum tree_code code = TREE_CODE (node);
13300
13301   /* If 1, tell the routine that we have to return error_mark_node
13302      after checking for the initialization of the RHS */
13303   int error_found = 0;
13304
13305   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13306
13307   /* If either op<n>_type are NULL, this might be early signs of an
13308      error situation, unless it's too early to tell (in case we're
13309      handling a `+', `==', `!=' or `instanceof'.) We want to set op<n>_type
13310      correctly so the error can be later on reported accurately. */
13311   if (! (code == PLUS_EXPR || code == NE_EXPR 
13312          || code == EQ_EXPR || code == INSTANCEOF_EXPR))
13313     {
13314       tree n;
13315       if (! op1_type)
13316         {
13317           n = java_complete_tree (op1);
13318           op1_type = TREE_TYPE (n);
13319         }
13320       if (! op2_type)
13321         {
13322           n = java_complete_tree (op2);
13323           op2_type = TREE_TYPE (n);
13324         }
13325     }
13326
13327   switch (code)
13328     {
13329     /* 15.16 Multiplicative operators */
13330     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
13331     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
13332     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
13333     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
13334       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13335         {
13336           if (!JNUMERIC_TYPE_P (op1_type))
13337             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13338           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13339             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13340           TREE_TYPE (node) = error_mark_node;
13341           error_found = 1;
13342           break;
13343         }
13344       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13345
13346       /* Detect integral division by zero */
13347       if ((code == RDIV_EXPR || code == TRUNC_MOD_EXPR)
13348           && TREE_CODE (prom_type) == INTEGER_TYPE
13349           && (op2 == integer_zero_node || op2 == long_zero_node ||
13350               (TREE_CODE (op2) == INTEGER_CST &&
13351                ! TREE_INT_CST_LOW (op2)  && ! TREE_INT_CST_HIGH (op2))))
13352         {
13353           parse_warning_context (wfl_operator, "Evaluating this expression will result in an arithmetic exception being thrown");
13354           TREE_CONSTANT (node) = 0;
13355         }
13356           
13357       /* Change the division operator if necessary */
13358       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
13359         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
13360
13361       /* Before divisions as is disapear, try to simplify and bail if
13362          applicable, otherwise we won't perform even simple
13363          simplifications like (1-1)/3. We can't do that with floating
13364          point number, folds can't handle them at this stage. */
13365       if (code == RDIV_EXPR && TREE_CONSTANT (op1) && TREE_CONSTANT (op2)
13366           && JINTEGRAL_TYPE_P (op1) && JINTEGRAL_TYPE_P (op2))
13367         {
13368           TREE_TYPE (node) = prom_type;
13369           node = fold (node);
13370           if (TREE_CODE (node) != code)
13371             return node;
13372         }
13373
13374       if (TREE_CODE (prom_type) == INTEGER_TYPE
13375           && flag_use_divide_subroutine
13376           && ! flag_emit_class_files
13377           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
13378         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
13379  
13380       /* This one is more complicated. FLOATs are processed by a
13381          function call to soft_fmod. Duplicate the value of the
13382          COMPOUND_ASSIGN_P flag. */
13383       if (code == TRUNC_MOD_EXPR)
13384         {
13385           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
13386           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
13387           TREE_SIDE_EFFECTS (mod)
13388             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13389           return mod;
13390         }
13391       break;
13392
13393     /* 15.17 Additive Operators */
13394     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
13395
13396       /* Operation is valid if either one argument is a string
13397          constant, a String object or a StringBuffer crafted for the
13398          purpose of the a previous usage of the String concatenation
13399          operator */
13400
13401       if (TREE_CODE (op1) == STRING_CST 
13402           || TREE_CODE (op2) == STRING_CST
13403           || JSTRING_TYPE_P (op1_type)
13404           || JSTRING_TYPE_P (op2_type)
13405           || IS_CRAFTED_STRING_BUFFER_P (op1)
13406           || IS_CRAFTED_STRING_BUFFER_P (op2))
13407         return build_string_concatenation (op1, op2);
13408
13409     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
13410                                    Numeric Types */
13411       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13412         {
13413           if (!JNUMERIC_TYPE_P (op1_type))
13414             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13415           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13416             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13417           TREE_TYPE (node) = error_mark_node;
13418           error_found = 1;
13419           break;
13420         }
13421       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13422       break;
13423
13424     /* 15.18 Shift Operators */
13425     case LSHIFT_EXPR:
13426     case RSHIFT_EXPR:
13427     case URSHIFT_EXPR:
13428       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
13429         {
13430           if (!JINTEGRAL_TYPE_P (op1_type))
13431             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13432           else
13433             {
13434               if (JNUMERIC_TYPE_P (op2_type))
13435                 parse_error_context (wfl_operator,
13436                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
13437                                      operator_string (node),
13438                                      lang_printable_name (op2_type, 0));
13439               else
13440                 parse_error_context (wfl_operator,
13441                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
13442                                      operator_string (node),
13443                                      lang_printable_name (op2_type, 0));
13444             }
13445           TREE_TYPE (node) = error_mark_node;
13446           error_found = 1;
13447           break;
13448         }
13449
13450       /* Unary numeric promotion (5.6.1) is performed on each operand
13451          separately */
13452       op1 = do_unary_numeric_promotion (op1);
13453       op2 = do_unary_numeric_promotion (op2);
13454
13455       /* The type of the shift expression is the type of the promoted
13456          type of the left-hand operand */
13457       prom_type = TREE_TYPE (op1);
13458
13459       /* Shift int only up to 0x1f and long up to 0x3f */
13460       if (prom_type == int_type_node)
13461         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13462                            build_int_2 (0x1f, 0)));
13463       else
13464         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13465                            build_int_2 (0x3f, 0)));
13466
13467       /* The >>> operator is a >> operating on unsigned quantities */
13468       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
13469         {
13470           tree to_return;
13471           tree utype = java_unsigned_type (prom_type);
13472           op1 = convert (utype, op1);
13473           TREE_SET_CODE (node, RSHIFT_EXPR);
13474           TREE_OPERAND (node, 0) = op1;
13475           TREE_OPERAND (node, 1) = op2;
13476           TREE_TYPE (node) = utype;
13477           to_return = convert (prom_type, node);
13478           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
13479           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
13480           TREE_SIDE_EFFECTS (to_return)
13481             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13482           return to_return;
13483         }
13484       break;
13485
13486       /* 15.19.1 Type Comparison Operator instaceof */
13487     case INSTANCEOF_EXPR:
13488
13489       TREE_TYPE (node) = boolean_type_node;
13490
13491       if (!(op2_type = resolve_type_during_patch (op2)))
13492         return error_mark_node;
13493
13494       /* The first operand must be a reference type or the null type */
13495       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
13496         error_found = 1;        /* Error reported further below */
13497
13498       /* The second operand must be a reference type */
13499       if (!JREFERENCE_TYPE_P (op2_type))
13500         {
13501           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
13502           parse_error_context
13503             (wfl_operator, "Invalid argument `%s' for `instanceof'",
13504              lang_printable_name (op2_type, 0));
13505           error_found = 1;
13506         }
13507
13508       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
13509         {
13510           /* If the first operand is null, the result is always false */
13511           if (op1 == null_pointer_node)
13512             return boolean_false_node;
13513           else if (flag_emit_class_files)
13514             {
13515               TREE_OPERAND (node, 1) = op2_type;
13516               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
13517               return node;
13518             }
13519           /* Otherwise we have to invoke instance of to figure it out */
13520           else
13521             return build_instanceof (op1, op2_type);
13522         }
13523       /* There is no way the expression operand can be an instance of
13524          the type operand. This is a compile time error. */
13525       else
13526         {
13527           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
13528           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
13529           parse_error_context 
13530             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
13531              t1, lang_printable_name (op2_type, 0));
13532           free (t1);
13533           error_found = 1;
13534         }
13535       
13536       break;
13537
13538       /* 15.21 Bitwise and Logical Operators */
13539     case BIT_AND_EXPR:
13540     case BIT_XOR_EXPR:
13541     case BIT_IOR_EXPR:
13542       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
13543         /* Binary numeric promotion is performed on both operand and the
13544            expression retain that type */
13545         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13546
13547       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
13548                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
13549         /* The type of the bitwise operator expression is BOOLEAN */
13550         prom_type = boolean_type_node;
13551       else
13552         {
13553           if (!JINTEGRAL_TYPE_P (op1_type))
13554             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13555           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
13556             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
13557           TREE_TYPE (node) = error_mark_node;
13558           error_found = 1;
13559           /* Insert a break here if adding thing before the switch's
13560              break for this case */
13561         }
13562       break;
13563
13564       /* 15.22 Conditional-And Operator */
13565     case TRUTH_ANDIF_EXPR:
13566       /* 15.23 Conditional-Or Operator */
13567     case TRUTH_ORIF_EXPR:
13568       /* Operands must be of BOOLEAN type */
13569       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
13570           TREE_CODE (op2_type) != BOOLEAN_TYPE)
13571         {
13572           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
13573             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
13574           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
13575             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
13576           TREE_TYPE (node) = boolean_type_node;
13577           error_found = 1;
13578           break;
13579         }
13580       else if (integer_zerop (op1))
13581         {
13582           return code == TRUTH_ANDIF_EXPR ? op1 : op2;
13583         }
13584       else if (integer_onep (op1))
13585         {
13586           return code == TRUTH_ANDIF_EXPR ? op2 : op1;
13587         }
13588       /* The type of the conditional operators is BOOLEAN */
13589       prom_type = boolean_type_node;
13590       break;
13591
13592       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
13593     case LT_EXPR:
13594     case GT_EXPR:
13595     case LE_EXPR:
13596     case GE_EXPR:
13597       /* The type of each of the operands must be a primitive numeric
13598          type */
13599       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
13600         {
13601           if (!JNUMERIC_TYPE_P (op1_type))
13602             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13603           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13604             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13605           TREE_TYPE (node) = boolean_type_node;
13606           error_found = 1;
13607           break;
13608         }
13609       /* Binary numeric promotion is performed on the operands */
13610       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13611       /* The type of the relation expression is always BOOLEAN */
13612       prom_type = boolean_type_node;
13613       break;
13614
13615       /* 15.20 Equality Operator */
13616     case EQ_EXPR:
13617     case NE_EXPR:
13618       /* It's time for us to patch the strings. */
13619       if ((cn = patch_string (op1))) 
13620        {
13621          op1 = cn;
13622          op1_type = TREE_TYPE (op1);
13623        }
13624       if ((cn = patch_string (op2))) 
13625        {
13626          op2 = cn;
13627          op2_type = TREE_TYPE (op2);
13628        }
13629       
13630       /* 15.20.1 Numerical Equality Operators == and != */
13631       /* Binary numeric promotion is performed on the operands */
13632       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
13633         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13634       
13635       /* 15.20.2 Boolean Equality Operators == and != */
13636       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
13637           TREE_CODE (op2_type) == BOOLEAN_TYPE)
13638         ;                       /* Nothing to do here */
13639       
13640       /* 15.20.3 Reference Equality Operators == and != */
13641       /* Types have to be either references or the null type. If
13642          they're references, it must be possible to convert either
13643          type to the other by casting conversion. */
13644       else if (op1 == null_pointer_node || op2 == null_pointer_node 
13645                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
13646                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
13647                        || valid_ref_assignconv_cast_p (op2_type, 
13648                                                        op1_type, 1))))
13649         ;                       /* Nothing to do here */
13650           
13651       /* Else we have an error figure what can't be converted into
13652          what and report the error */
13653       else
13654         {
13655           char *t1;
13656           t1 = xstrdup (lang_printable_name (op1_type, 0));
13657           parse_error_context 
13658             (wfl_operator,
13659              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
13660              operator_string (node), t1, 
13661              lang_printable_name (op2_type, 0));
13662           free (t1);
13663           TREE_TYPE (node) = boolean_type_node;
13664           error_found = 1;
13665           break;
13666         }
13667       prom_type = boolean_type_node;
13668       break;
13669     default:
13670       abort ();
13671     }
13672
13673   if (error_found)
13674     return error_mark_node;
13675
13676   TREE_OPERAND (node, 0) = op1;
13677   TREE_OPERAND (node, 1) = op2;
13678   TREE_TYPE (node) = prom_type;
13679   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13680   
13681   if (flag_emit_xref)
13682     return node;
13683
13684   /* fold does not respect side-effect order as required for Java but not C.
13685    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
13686    * bytecode.
13687    */
13688   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
13689       : ! TREE_SIDE_EFFECTS (node))
13690     node = fold (node);
13691   return node;
13692 }
13693
13694 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
13695    zero value, the value of CSTE comes after the valude of STRING */
13696
13697 static tree
13698 do_merge_string_cste (cste, string, string_len, after)
13699      tree cste;
13700      const char *string;
13701      int string_len, after;
13702 {
13703   const char *old = TREE_STRING_POINTER (cste);
13704   int old_len = TREE_STRING_LENGTH (cste);
13705   int len = old_len + string_len;
13706   char *new = alloca (len+1);
13707
13708   if (after)
13709     {
13710       memcpy (new, string, string_len);
13711       memcpy (&new [string_len], old, old_len);
13712     }
13713   else
13714     {
13715       memcpy (new, old, old_len);
13716       memcpy (&new [old_len], string, string_len);
13717     }
13718   new [len] = '\0';
13719   return build_string (len, new);
13720 }
13721
13722 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
13723    new STRING_CST on success, NULL_TREE on failure */
13724
13725 static tree
13726 merge_string_cste (op1, op2, after)
13727      tree op1, op2;
13728      int after;
13729 {
13730   /* Handle two string constants right away */
13731   if (TREE_CODE (op2) == STRING_CST)
13732     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
13733                                  TREE_STRING_LENGTH (op2), after);
13734   
13735   /* Reasonable integer constant can be treated right away */
13736   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
13737     {
13738       static const char *const boolean_true = "true";
13739       static const char *const boolean_false = "false";
13740       static const char *const null_pointer = "null";
13741       char ch[3];
13742       const char *string;
13743       
13744       if (op2 == boolean_true_node)
13745         string = boolean_true;
13746       else if (op2 == boolean_false_node)
13747         string = boolean_false;
13748       else if (op2 == null_pointer_node)
13749         string = null_pointer;
13750       else if (TREE_TYPE (op2) == char_type_node)
13751         {
13752           ch[0] = (char )TREE_INT_CST_LOW (op2);
13753           ch[1] = '\0';
13754           string = ch;
13755         }
13756       else
13757         string = string_convert_int_cst (op2);
13758
13759       return do_merge_string_cste (op1, string, strlen (string), after);
13760     }
13761   return NULL_TREE;
13762 }
13763
13764 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
13765    has to be a STRING_CST and the other part must be a STRING_CST or a
13766    INTEGRAL constant. Return a new STRING_CST if the operation
13767    succeed, NULL_TREE otherwise.
13768
13769    If the case we want to optimize for space, we might want to return
13770    NULL_TREE for each invocation of this routine. FIXME */
13771
13772 static tree
13773 string_constant_concatenation (op1, op2)
13774      tree op1, op2;
13775 {
13776   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
13777     {
13778       tree string, rest;
13779       int invert;
13780       
13781       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
13782       rest   = (string == op1 ? op2 : op1);
13783       invert = (string == op1 ? 0 : 1 );
13784       
13785       /* Walk REST, only if it looks reasonable */
13786       if (TREE_CODE (rest) != STRING_CST
13787           && !IS_CRAFTED_STRING_BUFFER_P (rest)
13788           && !JSTRING_TYPE_P (TREE_TYPE (rest))
13789           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
13790         {
13791           rest = java_complete_tree (rest);
13792           if (rest == error_mark_node)
13793             return error_mark_node;
13794           rest = fold (rest);
13795         }
13796       return merge_string_cste (string, rest, invert);
13797     }
13798   return NULL_TREE;
13799 }
13800
13801 /* Implement the `+' operator. Does static optimization if possible,
13802    otherwise create (if necessary) and append elements to a
13803    StringBuffer. The StringBuffer will be carried around until it is
13804    used for a function call or an assignment. Then toString() will be
13805    called on it to turn it into a String object. */
13806
13807 static tree
13808 build_string_concatenation (op1, op2)
13809      tree op1, op2;
13810 {
13811   tree result;
13812   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13813
13814   if (flag_emit_xref)
13815     return build (PLUS_EXPR, string_type_node, op1, op2);
13816   
13817   /* Try to do some static optimization */
13818   if ((result = string_constant_concatenation (op1, op2)))
13819     return result;
13820
13821   /* Discard empty strings on either side of the expression */
13822   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
13823     {
13824       op1 = op2;
13825       op2 = NULL_TREE;
13826     }
13827   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
13828     op2 = NULL_TREE;
13829
13830   /* If operands are string constant, turn then into object references */
13831   if (TREE_CODE (op1) == STRING_CST)
13832     op1 = patch_string_cst (op1);
13833   if (op2 && TREE_CODE (op2) == STRING_CST)
13834     op2 = patch_string_cst (op2);
13835
13836   /* If either one of the constant is null and the other non null
13837      operand is a String object, return it. */
13838   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
13839     return op1;
13840
13841   /* If OP1 isn't already a StringBuffer, create and
13842      initialize a new one */
13843   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
13844     {
13845       /* Two solutions here: 
13846          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
13847          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
13848       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
13849         op1 = BUILD_STRING_BUFFER (op1);
13850       else
13851         {
13852           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
13853           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
13854         }
13855     }
13856
13857   if (op2)
13858     {
13859       /* OP1 is no longer the last node holding a crafted StringBuffer */
13860       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
13861       /* Create a node for `{new...,xxx}.append (op2)' */
13862       if (op2)
13863         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
13864     }
13865
13866   /* Mark the last node holding a crafted StringBuffer */
13867   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
13868
13869   TREE_SIDE_EFFECTS (op1) = side_effects;
13870   return op1;
13871 }
13872
13873 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
13874    StringBuffer. If no string were found to be patched, return
13875    NULL. */
13876
13877 static tree
13878 patch_string (node)
13879     tree node;
13880 {
13881   if (node == error_mark_node)
13882     return error_mark_node;
13883   if (TREE_CODE (node) == STRING_CST)
13884     return patch_string_cst (node);
13885   else if (IS_CRAFTED_STRING_BUFFER_P (node))
13886     {
13887       int saved = ctxp->explicit_constructor_p;
13888       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
13889       tree ret;
13890       /* Temporary disable forbid the use of `this'. */
13891       ctxp->explicit_constructor_p = 0;
13892       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
13893       /* String concatenation arguments must be evaluated in order too. */
13894       ret = force_evaluation_order (ret);
13895       /* Restore it at its previous value */
13896       ctxp->explicit_constructor_p = saved;
13897       return ret;
13898     }
13899   return NULL_TREE;
13900 }
13901
13902 /* Build the internal representation of a string constant.  */
13903
13904 static tree
13905 patch_string_cst (node)
13906      tree node;
13907 {
13908   int location;
13909   if (! flag_emit_class_files)
13910     {
13911       node = get_identifier (TREE_STRING_POINTER (node));
13912       location = alloc_name_constant (CONSTANT_String, node);
13913       node = build_ref_from_constant_pool (location);
13914     }
13915   TREE_TYPE (node) = string_ptr_type_node;
13916   TREE_CONSTANT (node) = 1;
13917   return node;
13918 }
13919
13920 /* Build an incomplete unary operator expression. */
13921
13922 static tree
13923 build_unaryop (op_token, op_location, op1)
13924      int op_token, op_location;
13925      tree op1;
13926 {
13927   enum tree_code op;
13928   tree unaryop;
13929   switch (op_token)
13930     {
13931     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
13932     case MINUS_TK: op = NEGATE_EXPR; break;
13933     case NEG_TK: op = TRUTH_NOT_EXPR; break;
13934     case NOT_TK: op = BIT_NOT_EXPR; break;
13935     default: abort ();
13936     }
13937
13938   unaryop = build1 (op, NULL_TREE, op1);
13939   TREE_SIDE_EFFECTS (unaryop) = 1;
13940   /* Store the location of the operator, for better error report. The
13941      string of the operator will be rebuild based on the OP value. */
13942   EXPR_WFL_LINECOL (unaryop) = op_location;
13943   return unaryop;
13944 }
13945
13946 /* Special case for the ++/-- operators, since they require an extra
13947    argument to build, which is set to NULL and patched
13948    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
13949
13950 static tree
13951 build_incdec (op_token, op_location, op1, is_post_p)
13952      int op_token, op_location;
13953      tree op1;
13954      int is_post_p;
13955 {
13956   static const enum tree_code lookup [2][2] = 
13957     {
13958       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
13959       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
13960     };
13961   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
13962                      NULL_TREE, op1, NULL_TREE);
13963   TREE_SIDE_EFFECTS (node) = 1;
13964   /* Store the location of the operator, for better error report. The
13965      string of the operator will be rebuild based on the OP value. */
13966   EXPR_WFL_LINECOL (node) = op_location;
13967   return node;
13968 }     
13969
13970 /* Build an incomplete cast operator, based on the use of the
13971    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
13972    set. java_complete_tree is trained to walk a CONVERT_EXPR even
13973    though its type is already set.  */
13974
13975 static tree
13976 build_cast (location, type, exp)
13977      int location;
13978      tree type, exp;
13979 {
13980   tree node = build1 (CONVERT_EXPR, type, exp);
13981   EXPR_WFL_LINECOL (node) = location;
13982   return node;
13983 }
13984
13985 /* Build an incomplete class reference operator.  */
13986 static tree
13987 build_incomplete_class_ref (location, class_name)
13988     int location;
13989     tree class_name;
13990 {
13991   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
13992   EXPR_WFL_LINECOL (node) = location;
13993   return node;
13994 }
13995
13996 /* Complete an incomplete class reference operator.  */
13997 static tree
13998 patch_incomplete_class_ref (node)
13999     tree node;
14000 {
14001   tree type = TREE_OPERAND (node, 0);
14002   tree ref_type;
14003
14004   if (!(ref_type = resolve_type_during_patch (type)))
14005     return error_mark_node;
14006
14007   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
14008     {
14009       tree dot = build_class_ref (ref_type);
14010       /* A class referenced by `foo.class' is initialized.  */
14011       if (!flag_emit_class_files)
14012        dot = build_class_init (ref_type, dot);
14013       return java_complete_tree (dot);
14014     }
14015
14016   /* If we're emitting class files and we have to deal with non
14017      primitive types, we invoke (and consider generating) the
14018      synthetic static method `class$'. */
14019   if (!TYPE_DOT_CLASS (current_class))
14020       build_dot_class_method (current_class);
14021   ref_type = build_dot_class_method_invocation (ref_type);
14022   return java_complete_tree (ref_type);
14023 }
14024
14025 /* 15.14 Unary operators. We return error_mark_node in case of error,
14026    but preserve the type of NODE if the type is fixed.  */
14027
14028 static tree
14029 patch_unaryop (node, wfl_op)
14030      tree node;
14031      tree wfl_op;
14032 {
14033   tree op = TREE_OPERAND (node, 0);
14034   tree op_type = TREE_TYPE (op);
14035   tree prom_type = NULL_TREE, value, decl;
14036   int outer_field_flag = 0;
14037   int code = TREE_CODE (node);
14038   int error_found = 0;
14039
14040   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14041
14042   switch (code)
14043     {
14044       /* 15.13.2 Postfix Increment Operator ++ */
14045     case POSTINCREMENT_EXPR:
14046       /* 15.13.3 Postfix Increment Operator -- */
14047     case POSTDECREMENT_EXPR:
14048       /* 15.14.1 Prefix Increment Operator ++ */
14049     case PREINCREMENT_EXPR:
14050       /* 15.14.2 Prefix Decrement Operator -- */
14051     case PREDECREMENT_EXPR:
14052       op = decl = strip_out_static_field_access_decl (op);
14053       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
14054       /* We might be trying to change an outer field accessed using
14055          access method. */
14056       if (outer_field_flag)
14057         {
14058           /* Retrieve the decl of the field we're trying to access. We
14059              do that by first retrieving the function we would call to
14060              access the field. It has been already verified that this
14061              field isn't final */
14062           if (flag_emit_class_files)
14063             decl = TREE_OPERAND (op, 0);
14064           else
14065             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
14066           decl = DECL_FUNCTION_ACCESS_DECL (decl);
14067         }
14068       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
14069       else if (!JDECL_P (decl) 
14070           && TREE_CODE (decl) != COMPONENT_REF
14071           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
14072           && TREE_CODE (decl) != INDIRECT_REF
14073           && !(TREE_CODE (decl) == COMPOUND_EXPR
14074                && TREE_OPERAND (decl, 1)
14075                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
14076         {
14077           TREE_TYPE (node) = error_mark_node;
14078           error_found = 1;
14079         }
14080       
14081       /* From now on, we know that op if a variable and that it has a
14082          valid wfl. We use wfl_op to locate errors related to the
14083          ++/-- operand. */
14084       if (!JNUMERIC_TYPE_P (op_type))
14085         {
14086           parse_error_context
14087             (wfl_op, "Invalid argument type `%s' to `%s'",
14088              lang_printable_name (op_type, 0), operator_string (node));
14089           TREE_TYPE (node) = error_mark_node;
14090           error_found = 1;
14091         }
14092       else
14093         {
14094           /* Before the addition, binary numeric promotion is performed on
14095              both operands, if really necessary */
14096           if (JINTEGRAL_TYPE_P (op_type))
14097             {
14098               value = build_int_2 (1, 0);
14099               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
14100             }
14101           else
14102             {
14103               value = build_int_2 (1, 0);
14104               TREE_TYPE (node) = 
14105                 binary_numeric_promotion (op_type, 
14106                                           TREE_TYPE (value), &op, &value);
14107             }
14108
14109           /* We remember we might be accessing an outer field */
14110           if (outer_field_flag)
14111             {
14112               /* We re-generate an access to the field */
14113               value = build (PLUS_EXPR, TREE_TYPE (op), 
14114                              build_outer_field_access (wfl_op, decl), value);
14115                                                     
14116               /* And we patch the original access$() into a write 
14117                  with plus_op as a rhs */
14118               return outer_field_access_fix (node, op, value);
14119             }
14120
14121           /* And write back into the node. */
14122           TREE_OPERAND (node, 0) = op;
14123           TREE_OPERAND (node, 1) = value;
14124           /* Convert the overall back into its original type, if
14125              necessary, and return */
14126           if (JINTEGRAL_TYPE_P (op_type))
14127             return fold (node);
14128           else
14129             return fold (convert (op_type, node));
14130         }
14131       break;
14132
14133       /* 15.14.3 Unary Plus Operator + */
14134     case UNARY_PLUS_EXPR:
14135       /* 15.14.4 Unary Minus Operator - */
14136     case NEGATE_EXPR:
14137       if (!JNUMERIC_TYPE_P (op_type))
14138         {
14139           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
14140           TREE_TYPE (node) = error_mark_node;
14141           error_found = 1;
14142         }
14143       /* Unary numeric promotion is performed on operand */
14144       else
14145         {
14146           op = do_unary_numeric_promotion (op);
14147           prom_type = TREE_TYPE (op);
14148           if (code == UNARY_PLUS_EXPR)
14149             return fold (op);
14150         }
14151       break;
14152
14153       /* 15.14.5 Bitwise Complement Operator ~ */
14154     case BIT_NOT_EXPR:
14155       if (!JINTEGRAL_TYPE_P (op_type))
14156         {
14157           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
14158           TREE_TYPE (node) = error_mark_node;
14159           error_found = 1;
14160         }
14161       else
14162         {
14163           op = do_unary_numeric_promotion (op);
14164           prom_type = TREE_TYPE (op);
14165         }
14166       break;
14167
14168       /* 15.14.6 Logical Complement Operator ! */
14169     case TRUTH_NOT_EXPR:
14170       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
14171         {
14172           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
14173           /* But the type is known. We will report an error if further
14174              attempt of a assignment is made with this rhs */
14175           TREE_TYPE (node) = boolean_type_node;
14176           error_found = 1;
14177         }
14178       else
14179         prom_type = boolean_type_node;
14180       break;
14181
14182       /* 15.15 Cast Expression */
14183     case CONVERT_EXPR:
14184       value = patch_cast (node, wfl_operator);
14185       if (value == error_mark_node)
14186         {
14187           /* If this cast is part of an assignment, we tell the code
14188              that deals with it not to complain about a mismatch,
14189              because things have been cast, anyways */
14190           TREE_TYPE (node) = error_mark_node;
14191           error_found = 1;
14192         }
14193       else
14194         {
14195           value = fold (value);
14196           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
14197           return value;
14198         }
14199       break;
14200     }
14201   
14202   if (error_found)
14203     return error_mark_node;
14204
14205   /* There are cases where node has been replaced by something else
14206      and we don't end up returning here: UNARY_PLUS_EXPR,
14207      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
14208   TREE_OPERAND (node, 0) = fold (op);
14209   TREE_TYPE (node) = prom_type;
14210   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
14211   return fold (node);
14212 }
14213
14214 /* Generic type resolution that sometimes takes place during node
14215    patching. Returned the resolved type or generate an error
14216    message. Return the resolved type or NULL_TREE.  */
14217
14218 static tree
14219 resolve_type_during_patch (type)
14220      tree type;
14221 {
14222   if (unresolved_type_p (type, NULL))
14223     {
14224       tree type_decl = resolve_and_layout (EXPR_WFL_NODE (type), type);
14225       if (!type_decl)
14226         {
14227           parse_error_context (type, 
14228                                "Class `%s' not found in type declaration",
14229                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
14230           return NULL_TREE;
14231         }
14232       return TREE_TYPE (type_decl);
14233     }
14234   return type;
14235 }
14236 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
14237    found. Otherwise NODE or something meant to replace it is returned.  */
14238
14239 static tree
14240 patch_cast (node, wfl_op)
14241      tree node;
14242      tree wfl_op;
14243 {
14244   tree op = TREE_OPERAND (node, 0);
14245   tree cast_type = TREE_TYPE (node);
14246   tree patched, op_type;
14247   char *t1;
14248
14249   /* Some string patching might be necessary at this stage */
14250   if ((patched = patch_string (op)))
14251     TREE_OPERAND (node, 0) = op = patched;
14252   op_type = TREE_TYPE (op);
14253
14254   /* First resolve OP_TYPE if unresolved */
14255   if (!(cast_type = resolve_type_during_patch (cast_type)))
14256     return error_mark_node;
14257
14258   /* Check on cast that are proven correct at compile time */
14259   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
14260     {
14261       /* Same type */
14262       if (cast_type == op_type)
14263         return node;
14264
14265       /* float and double type are converted to the original type main
14266          variant and then to the target type. */
14267       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
14268         op = convert (integer_type_node, op);
14269
14270       /* Try widening/narowwing convertion. Potentially, things need
14271          to be worked out in gcc so we implement the extreme cases
14272          correctly. fold_convert() needs to be fixed. */
14273       return convert (cast_type, op);
14274     }
14275
14276   /* It's also valid to cast a boolean into a boolean */
14277   if (op_type == boolean_type_node && cast_type == boolean_type_node)
14278     return node;
14279
14280   /* null can be casted to references */
14281   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
14282     return build_null_of_type (cast_type);
14283
14284   /* The remaining legal casts involve conversion between reference
14285      types. Check for their compile time correctness. */
14286   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
14287       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
14288     {
14289       TREE_TYPE (node) = promote_type (cast_type);
14290       /* Now, the case can be determined correct at compile time if
14291          OP_TYPE can be converted into CAST_TYPE by assignment
14292          conversion (5.2) */
14293
14294       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
14295         {
14296           TREE_SET_CODE (node, NOP_EXPR);
14297           return node;
14298         }
14299
14300       if (flag_emit_class_files)
14301         {
14302           TREE_SET_CODE (node, CONVERT_EXPR);
14303           return node;
14304         }
14305
14306       /* The cast requires a run-time check */
14307       return build (CALL_EXPR, promote_type (cast_type),
14308                     build_address_of (soft_checkcast_node),
14309                     tree_cons (NULL_TREE, build_class_ref (cast_type),
14310                                build_tree_list (NULL_TREE, op)),
14311                     NULL_TREE);
14312     }
14313
14314   /* Any other casts are proven incorrect at compile time */
14315   t1 = xstrdup (lang_printable_name (op_type, 0));
14316   parse_error_context (wfl_op, "Invalid cast from `%s' to `%s'",
14317                        t1, lang_printable_name (cast_type, 0));
14318   free (t1);
14319   return error_mark_node;
14320 }
14321
14322 /* Build a null constant and give it the type TYPE.  */
14323
14324 static tree
14325 build_null_of_type (type)
14326      tree type;
14327 {
14328   tree node = build_int_2 (0, 0);
14329   TREE_TYPE (node) = promote_type (type);
14330   return node;
14331 }
14332
14333 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
14334    a list of indices. */
14335 static tree
14336 build_array_ref (location, array, index)
14337      int location;
14338      tree array, index;
14339 {
14340   tree node = build (ARRAY_REF, NULL_TREE, array, index);
14341   EXPR_WFL_LINECOL (node) = location;
14342   return node;
14343 }
14344
14345 /* 15.12 Array Access Expression */
14346
14347 static tree
14348 patch_array_ref (node)
14349      tree node;
14350 {
14351   tree array = TREE_OPERAND (node, 0);
14352   tree array_type  = TREE_TYPE (array);
14353   tree index = TREE_OPERAND (node, 1);
14354   tree index_type = TREE_TYPE (index);
14355   int error_found = 0;
14356
14357   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14358
14359   if (TREE_CODE (array_type) == POINTER_TYPE)
14360     array_type = TREE_TYPE (array_type);
14361
14362   /* The array reference must be an array */
14363   if (!TYPE_ARRAY_P (array_type))
14364     {
14365       parse_error_context 
14366         (wfl_operator,
14367          "`[]' can only be applied to arrays. It can't be applied to `%s'",
14368          lang_printable_name (array_type, 0));
14369       TREE_TYPE (node) = error_mark_node;
14370       error_found = 1;
14371     }
14372
14373   /* The array index undergoes unary numeric promotion. The promoted
14374      type must be int */
14375   index = do_unary_numeric_promotion (index);
14376   if (TREE_TYPE (index) != int_type_node)
14377     {
14378       if (valid_cast_to_p (index_type, int_type_node))
14379         parse_error_context (wfl_operator,
14380    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
14381                              lang_printable_name (index_type, 0));
14382       else
14383         parse_error_context (wfl_operator,
14384           "Incompatible type for `[]'. Can't convert `%s' to `int'",
14385                              lang_printable_name (index_type, 0));
14386       TREE_TYPE (node) = error_mark_node;
14387       error_found = 1;
14388     }
14389
14390   if (error_found)
14391     return error_mark_node;
14392
14393   array_type = TYPE_ARRAY_ELEMENT (array_type);
14394
14395   if (flag_emit_class_files || flag_emit_xref)
14396     {
14397       TREE_OPERAND (node, 0) = array;
14398       TREE_OPERAND (node, 1) = index;
14399     }
14400   else
14401     node = build_java_arrayaccess (array, array_type, index);
14402   TREE_TYPE (node) = array_type;
14403   return node;
14404 }
14405
14406 /* 15.9 Array Creation Expressions */
14407
14408 static tree
14409 build_newarray_node (type, dims, extra_dims)
14410      tree type;
14411      tree dims;
14412      int extra_dims;
14413 {
14414   tree node =
14415     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
14416            build_int_2 (extra_dims, 0));
14417   return node;
14418 }
14419
14420 static tree
14421 patch_newarray (node)
14422      tree node;
14423 {
14424   tree type = TREE_OPERAND (node, 0);
14425   tree dims = TREE_OPERAND (node, 1);
14426   tree cdim, array_type;
14427   int error_found = 0;
14428   int ndims = 0;
14429   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
14430
14431   /* Dimension types are verified. It's better for the types to be
14432      verified in order. */
14433   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
14434     {
14435       int dim_error = 0;
14436       tree dim = TREE_VALUE (cdim);
14437
14438       /* Dim might have been saved during its evaluation */
14439       dim = (TREE_CODE (dim) == SAVE_EXPR ? TREE_OPERAND (dim, 0) : dim);
14440
14441       /* The type of each specified dimension must be an integral type. */
14442       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
14443         dim_error = 1;
14444
14445       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
14446          promoted type must be int. */
14447       else
14448         {
14449           dim = do_unary_numeric_promotion (dim);
14450           if (TREE_TYPE (dim) != int_type_node)
14451             dim_error = 1;
14452         }
14453
14454       /* Report errors on types here */
14455       if (dim_error)
14456         {
14457           parse_error_context 
14458             (TREE_PURPOSE (cdim), 
14459              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
14460              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
14461               "Explicit cast needed to" : "Can't"),
14462              lang_printable_name (TREE_TYPE (dim), 0));
14463           error_found = 1;
14464         }
14465
14466       TREE_PURPOSE (cdim) = NULL_TREE;
14467     }
14468
14469   /* Resolve array base type if unresolved */
14470   if (!(type = resolve_type_during_patch (type)))
14471     error_found = 1;
14472
14473   if (error_found)
14474     {
14475       /* We don't want further evaluation of this bogus array creation
14476          operation */
14477       TREE_TYPE (node) = error_mark_node;
14478       return error_mark_node;
14479     }
14480
14481   /* Set array_type to the actual (promoted) array type of the result. */
14482   if (TREE_CODE (type) == RECORD_TYPE)
14483     type = build_pointer_type (type);
14484   while (--xdims >= 0)
14485     {
14486       type = promote_type (build_java_array_type (type, -1));
14487     }
14488   dims = nreverse (dims);
14489   array_type = type;
14490   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
14491     {
14492       type = array_type;
14493       array_type
14494         = build_java_array_type (type,
14495                                  TREE_CODE (cdim) == INTEGER_CST
14496                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
14497                                  : -1);
14498       array_type = promote_type (array_type);
14499     }
14500   dims = nreverse (dims);
14501
14502   /* The node is transformed into a function call. Things are done
14503      differently according to the number of dimensions. If the number
14504      of dimension is equal to 1, then the nature of the base type
14505      (primitive or not) matters. */
14506   if (ndims == 1)
14507     return build_new_array (type, TREE_VALUE (dims));
14508   
14509   /* Can't reuse what's already written in expr.c because it uses the
14510      JVM stack representation. Provide a build_multianewarray. FIXME */
14511   return build (CALL_EXPR, array_type,
14512                 build_address_of (soft_multianewarray_node),
14513                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
14514                            tree_cons (NULL_TREE, 
14515                                       build_int_2 (ndims, 0), dims )),
14516                 NULL_TREE);
14517 }
14518
14519 /* 10.6 Array initializer.  */
14520
14521 /* Build a wfl for array element that don't have one, so we can
14522    pin-point errors.  */
14523
14524 static tree
14525 maybe_build_array_element_wfl (node)
14526      tree node;
14527 {
14528   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
14529     return build_expr_wfl (NULL_TREE, ctxp->filename,
14530                            ctxp->elc.line, ctxp->elc.prev_col);
14531   else
14532     return NULL_TREE;
14533 }
14534
14535 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
14536    identification of initialized arrays easier to detect during walk
14537    and expansion.  */
14538
14539 static tree
14540 build_new_array_init (location, values)
14541      int location;
14542      tree values;
14543 {
14544   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
14545   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
14546   EXPR_WFL_LINECOL (to_return) = location;
14547   return to_return;
14548 }
14549
14550 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
14551    occurred.  Otherwise return NODE after having set its type
14552    appropriately.  */
14553
14554 static tree
14555 patch_new_array_init (type, node)
14556      tree type, node;
14557 {
14558   int error_seen = 0;
14559   tree current, element_type;
14560   HOST_WIDE_INT length;
14561   int all_constant = 1;
14562   tree init = TREE_OPERAND (node, 0);
14563
14564   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
14565     {
14566       parse_error_context (node,
14567                            "Invalid array initializer for non-array type `%s'",
14568                            lang_printable_name (type, 1));
14569       return error_mark_node;
14570     }
14571   type = TREE_TYPE (type);
14572   element_type = TYPE_ARRAY_ELEMENT (type);
14573
14574   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
14575
14576   for (length = 0, current = CONSTRUCTOR_ELTS (init);
14577        current;  length++, current = TREE_CHAIN (current))
14578     {
14579       tree elt = TREE_VALUE (current);
14580       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
14581         {
14582           error_seen |= array_constructor_check_entry (element_type, current);
14583           elt = TREE_VALUE (current);
14584           /* When compiling to native code, STRING_CST is converted to
14585              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
14586           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
14587             all_constant = 0;
14588         }
14589       else
14590         {
14591           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
14592           TREE_PURPOSE (current) = NULL_TREE;
14593           all_constant = 0;
14594         }
14595       if (elt && TREE_CODE (elt) == TREE_LIST 
14596           && TREE_VALUE (elt) == error_mark_node)
14597         error_seen = 1;
14598     }
14599
14600   if (error_seen)
14601     return error_mark_node;
14602
14603   /* Create a new type. We can't reuse the one we have here by
14604      patching its dimension because it originally is of dimension -1
14605      hence reused by gcc. This would prevent triangular arrays. */
14606   type = build_java_array_type (element_type, length);
14607   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
14608   TREE_TYPE (node) = promote_type (type);
14609   TREE_CONSTANT (init) = all_constant;
14610   TREE_CONSTANT (node) = all_constant;
14611   return node;
14612 }
14613
14614 /* Verify that one entry of the initializer element list can be
14615    assigned to the array base type. Report 1 if an error occurred, 0
14616    otherwise.  */
14617
14618 static int
14619 array_constructor_check_entry (type, entry)
14620      tree type, entry;
14621 {
14622   char *array_type_string = NULL;       /* For error reports */
14623   tree value, type_value, new_value, wfl_value, patched;
14624   int error_seen = 0;
14625
14626   new_value = NULL_TREE;
14627   wfl_value = TREE_VALUE (entry);
14628
14629   value = java_complete_tree (TREE_VALUE (entry));
14630   /* patch_string return error_mark_node if arg is error_mark_node */
14631   if ((patched = patch_string (value)))
14632     value = patched;
14633   if (value == error_mark_node)
14634     return 1;
14635   
14636   type_value = TREE_TYPE (value);
14637   
14638   /* At anytime, try_builtin_assignconv can report a warning on
14639      constant overflow during narrowing. */
14640   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
14641   new_value = try_builtin_assignconv (wfl_operator, type, value);
14642   if (!new_value && (new_value = try_reference_assignconv (type, value)))
14643     type_value = promote_type (type);
14644
14645   /* Check and report errors */
14646   if (!new_value)
14647     {
14648       const char *const msg = (!valid_cast_to_p (type_value, type) ?
14649                    "Can't" : "Explicit cast needed to");
14650       if (!array_type_string)
14651         array_type_string = xstrdup (lang_printable_name (type, 1));
14652       parse_error_context 
14653         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
14654          msg, lang_printable_name (type_value, 1), array_type_string);
14655       error_seen = 1;
14656     }
14657   
14658   if (new_value)
14659     TREE_VALUE (entry) = new_value;
14660
14661   if (array_type_string)
14662     free (array_type_string);
14663
14664   TREE_PURPOSE (entry) = NULL_TREE;
14665   return error_seen;
14666 }
14667
14668 static tree
14669 build_this (location)
14670      int location;
14671 {
14672   tree node = build_wfl_node (this_identifier_node);
14673   TREE_SET_CODE (node, THIS_EXPR);
14674   EXPR_WFL_LINECOL (node) = location;
14675   return node;
14676 }
14677
14678 /* 14.15 The return statement. It builds a modify expression that
14679    assigns the returned value to the RESULT_DECL that hold the value
14680    to be returned. */
14681
14682 static tree
14683 build_return (location, op)
14684      int location;
14685      tree op;
14686 {
14687   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
14688   EXPR_WFL_LINECOL (node) = location;
14689   node = build_debugable_stmt (location, node);
14690   return node;
14691 }
14692
14693 static tree
14694 patch_return (node)
14695      tree node;
14696 {
14697   tree return_exp = TREE_OPERAND (node, 0);
14698   tree meth = current_function_decl;
14699   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
14700   int error_found = 0;
14701
14702   TREE_TYPE (node) = error_mark_node;
14703   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14704
14705   /* It's invalid to have a return value within a function that is
14706      declared with the keyword void or that is a constructor */
14707   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
14708     error_found = 1;
14709
14710   /* It's invalid to use a return statement in a static block */
14711   if (DECL_CLINIT_P (current_function_decl))
14712     error_found = 1;
14713
14714   /* It's invalid to have a no return value within a function that
14715      isn't declared with the keyword `void' */
14716   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
14717     error_found = 2;
14718   
14719   if (DECL_INSTINIT_P (current_function_decl))
14720     error_found = 1;
14721
14722   if (error_found)
14723     {
14724       if (DECL_INSTINIT_P (current_function_decl))
14725         parse_error_context (wfl_operator,
14726                              "`return' inside instance initializer");
14727         
14728       else if (DECL_CLINIT_P (current_function_decl))
14729         parse_error_context (wfl_operator,
14730                              "`return' inside static initializer");
14731
14732       else if (!DECL_CONSTRUCTOR_P (meth))
14733         {
14734           char *t = xstrdup (lang_printable_name (mtype, 0));
14735           parse_error_context (wfl_operator, 
14736                                "`return' with%s value from `%s %s'",
14737                                (error_found == 1 ? "" : "out"), 
14738                                t, lang_printable_name (meth, 0));
14739           free (t);
14740         }
14741       else
14742         parse_error_context (wfl_operator, 
14743                              "`return' with value from constructor `%s'",
14744                              lang_printable_name (meth, 0));
14745       return error_mark_node;
14746     }
14747
14748   /* If we have a return_exp, build a modify expression and expand
14749      it. Note: at that point, the assignment is declared valid, but we
14750      may want to carry some more hacks */
14751   if (return_exp)
14752     {
14753       tree exp = java_complete_tree (return_exp);
14754       tree modify, patched;
14755
14756       if ((patched = patch_string (exp)))
14757         exp = patched;
14758       
14759       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
14760       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
14761       modify = java_complete_tree (modify);
14762
14763       if (modify != error_mark_node)
14764         {
14765           TREE_SIDE_EFFECTS (modify) = 1;
14766           TREE_OPERAND (node, 0) = modify;
14767         }
14768       else
14769         return error_mark_node;
14770     }
14771   TREE_TYPE (node) = void_type_node;
14772   TREE_SIDE_EFFECTS (node) = 1;
14773   return node;
14774 }
14775
14776 /* 14.8 The if Statement */
14777
14778 static tree
14779 build_if_else_statement (location, expression, if_body, else_body)
14780      int location;
14781      tree expression, if_body, else_body;
14782 {
14783   tree node;
14784   if (!else_body)
14785     else_body = empty_stmt_node;
14786   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
14787   EXPR_WFL_LINECOL (node) = location;
14788   node = build_debugable_stmt (location, node);
14789   return node;
14790 }
14791
14792 static tree
14793 patch_if_else_statement (node)
14794      tree node;
14795 {
14796   tree expression = TREE_OPERAND (node, 0);
14797   int can_complete_normally
14798     = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
14799        | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2)));
14800
14801   TREE_TYPE (node) = error_mark_node;
14802   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14803
14804   /* The type of expression must be boolean */
14805   if (TREE_TYPE (expression) != boolean_type_node
14806       && TREE_TYPE (expression) != promoted_boolean_type_node)
14807     {
14808       parse_error_context 
14809         (wfl_operator, 
14810          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
14811          lang_printable_name (TREE_TYPE (expression), 0));
14812       return error_mark_node;
14813     }
14814   
14815   if (TREE_CODE (expression) == INTEGER_CST)
14816     {
14817       if (integer_zerop (expression))
14818         node = TREE_OPERAND (node, 2);
14819       else
14820         node = TREE_OPERAND (node, 1);
14821       if (CAN_COMPLETE_NORMALLY (node) != can_complete_normally)
14822         {
14823           node = build (COMPOUND_EXPR, void_type_node, node, empty_stmt_node);
14824           CAN_COMPLETE_NORMALLY (node) = can_complete_normally;
14825         }
14826       return node;
14827     }
14828   TREE_TYPE (node) = void_type_node;
14829   TREE_SIDE_EFFECTS (node) = 1;
14830   CAN_COMPLETE_NORMALLY (node) = can_complete_normally;
14831   return node;
14832 }
14833
14834 /* 14.6 Labeled Statements */
14835
14836 /* Action taken when a lableled statement is parsed. a new
14837    LABELED_BLOCK_EXPR is created. No statement is attached to the
14838    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
14839
14840 static tree
14841 build_labeled_block (location, label)
14842      int location;
14843      tree label;
14844 {
14845   tree label_name ;
14846   tree label_decl, node;
14847   if (label == NULL_TREE || label == continue_identifier_node)
14848     label_name = label;
14849   else
14850     {
14851       label_name = merge_qualified_name (label_id, label);
14852       /* Issue an error if we try to reuse a label that was previously
14853          declared */
14854       if (IDENTIFIER_LOCAL_VALUE (label_name))
14855         {
14856           EXPR_WFL_LINECOL (wfl_operator) = location;
14857           parse_error_context (wfl_operator,
14858             "Declaration of `%s' shadows a previous label declaration",
14859                                IDENTIFIER_POINTER (label));
14860           EXPR_WFL_LINECOL (wfl_operator) = 
14861             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
14862           parse_error_context (wfl_operator,
14863             "This is the location of the previous declaration of label `%s'",
14864                                IDENTIFIER_POINTER (label));
14865           java_error_count--;
14866         }
14867     }
14868
14869   label_decl = create_label_decl (label_name);
14870   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
14871   EXPR_WFL_LINECOL (node) = location;
14872   TREE_SIDE_EFFECTS (node) = 1;
14873   return node;
14874 }
14875
14876 /* A labeled statement LBE is attached a statement.  */
14877
14878 static tree
14879 finish_labeled_statement (lbe, statement)
14880      tree lbe;                  /* Labeled block expr */
14881      tree statement;
14882 {
14883   /* In anyways, tie the loop to its statement */
14884   LABELED_BLOCK_BODY (lbe) = statement;
14885   pop_labeled_block ();
14886   POP_LABELED_BLOCK ();
14887   return lbe;
14888 }
14889
14890 /* 14.10, 14.11, 14.12 Loop Statements */
14891
14892 /* Create an empty LOOP_EXPR and make it the last in the nested loop
14893    list. */
14894
14895 static tree
14896 build_new_loop (loop_body)
14897      tree loop_body;
14898 {
14899   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
14900   TREE_SIDE_EFFECTS (loop) = 1;
14901   PUSH_LOOP (loop);
14902   return loop;
14903 }
14904
14905 /* Create a loop body according to the following structure:
14906      COMPOUND_EXPR
14907        COMPOUND_EXPR            (loop main body)
14908          EXIT_EXPR              (this order is for while/for loops.
14909          LABELED_BLOCK_EXPR      the order is reversed for do loops)
14910            LABEL_DECL           (a continue occurring here branches at the 
14911            BODY                  end of this labeled block)
14912        INCREMENT                (if any)
14913
14914   REVERSED, if non zero, tells that the loop condition expr comes
14915   after the body, like in the do-while loop.
14916
14917   To obtain a loop, the loop body structure described above is
14918   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
14919
14920    LABELED_BLOCK_EXPR
14921      LABEL_DECL                   (use this label to exit the loop)
14922      LOOP_EXPR
14923        <structure described above> */
14924
14925 static tree
14926 build_loop_body (location, condition, reversed)
14927      int location;
14928      tree condition;
14929      int reversed;
14930 {
14931   tree first, second, body;
14932
14933   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
14934   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
14935   condition = build_debugable_stmt (location, condition);
14936   TREE_SIDE_EFFECTS (condition) = 1;
14937
14938   body = build_labeled_block (0, continue_identifier_node);
14939   first = (reversed ? body : condition);
14940   second = (reversed ? condition : body);
14941   return 
14942     build (COMPOUND_EXPR, NULL_TREE, 
14943            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
14944 }
14945
14946 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
14947    their order) on the current loop. Unlink the current loop from the
14948    loop list.  */
14949
14950 static tree
14951 finish_loop_body (location, condition, body, reversed)
14952      int location;
14953      tree condition, body;
14954      int reversed;
14955 {
14956   tree to_return = ctxp->current_loop;
14957   tree loop_body = LOOP_EXPR_BODY (to_return);
14958   if (condition)
14959     {
14960       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
14961       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
14962          The real EXIT_EXPR is one operand further. */
14963       EXPR_WFL_LINECOL (cnode) = location;
14964       /* This one is for accurate error reports */
14965       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
14966       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
14967     }
14968   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
14969   POP_LOOP ();
14970   return to_return;
14971 }
14972
14973 /* Tailored version of finish_loop_body for FOR loops, when FOR
14974    loops feature the condition part */
14975
14976 static tree
14977 finish_for_loop (location, condition, update, body)
14978     int location;
14979     tree condition, update, body;
14980 {
14981   /* Put the condition and the loop body in place */
14982   tree loop = finish_loop_body (location, condition, body, 0);
14983   /* LOOP is the current loop which has been now popped of the loop
14984      stack. Install the update block */
14985   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
14986   return loop;
14987 }
14988
14989 /* Try to find the loop a block might be related to. This comprises
14990    the case where the LOOP_EXPR is found as the second operand of a
14991    COMPOUND_EXPR, because the loop happens to have an initialization
14992    part, then expressed as the first operand of the COMPOUND_EXPR. If
14993    the search finds something, 1 is returned. Otherwise, 0 is
14994    returned. The search is assumed to start from a
14995    LABELED_BLOCK_EXPR's block.  */
14996
14997 static tree
14998 search_loop (statement)
14999     tree statement;
15000 {
15001   if (TREE_CODE (statement) == LOOP_EXPR)
15002     return statement;
15003
15004   if (TREE_CODE (statement) == BLOCK)
15005     statement = BLOCK_SUBBLOCKS (statement);
15006   else
15007     return NULL_TREE;
15008
15009   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
15010     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
15011       statement = TREE_OPERAND (statement, 1);
15012
15013   return (TREE_CODE (statement) == LOOP_EXPR
15014           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
15015 }
15016
15017 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
15018    returned otherwise.  */
15019
15020 static int
15021 labeled_block_contains_loop_p (block, loop)
15022     tree block, loop;
15023 {
15024   if (!block)
15025     return 0;
15026
15027   if (LABELED_BLOCK_BODY (block) == loop)
15028     return 1;
15029
15030   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
15031     return 1;
15032
15033   return 0;
15034 }
15035
15036 /* If the loop isn't surrounded by a labeled statement, create one and
15037    insert LOOP as its body.  */
15038
15039 static tree
15040 patch_loop_statement (loop)
15041      tree loop;
15042 {
15043   tree loop_label;
15044
15045   TREE_TYPE (loop) = void_type_node;
15046   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
15047     return loop;
15048
15049   loop_label = build_labeled_block (0, NULL_TREE);
15050   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
15051      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
15052   LABELED_BLOCK_BODY (loop_label) = loop;
15053   PUSH_LABELED_BLOCK (loop_label);
15054   return loop_label;
15055 }
15056
15057 /* 14.13, 14.14: break and continue Statements */
15058
15059 /* Build a break or a continue statement. a null NAME indicates an
15060    unlabeled break/continue statement.  */
15061
15062 static tree
15063 build_bc_statement (location, is_break, name)
15064      int location, is_break;
15065      tree name;
15066 {
15067   tree break_continue, label_block_expr = NULL_TREE;
15068
15069   if (name)
15070     {
15071       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
15072             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
15073         /* Null means that we don't have a target for this named
15074            break/continue. In this case, we make the target to be the
15075            label name, so that the error can be reported accuratly in
15076            patch_bc_statement. */
15077         label_block_expr = EXPR_WFL_NODE (name);
15078     }
15079   /* Unlabeled break/continue will be handled during the
15080      break/continue patch operation */
15081   break_continue 
15082     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
15083
15084   IS_BREAK_STMT_P (break_continue) = is_break;
15085   TREE_SIDE_EFFECTS (break_continue) = 1;
15086   EXPR_WFL_LINECOL (break_continue) = location;
15087   break_continue = build_debugable_stmt (location, break_continue);
15088   return break_continue;
15089 }
15090
15091 /* Verification of a break/continue statement. */
15092
15093 static tree
15094 patch_bc_statement (node)
15095      tree node;
15096 {
15097   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
15098   tree labeled_block = ctxp->current_labeled_block;
15099   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15100  
15101   /* Having an identifier here means that the target is unknown. */
15102   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
15103     {
15104       parse_error_context (wfl_operator, "No label definition found for `%s'",
15105                            IDENTIFIER_POINTER (bc_label));
15106       return error_mark_node;
15107     }
15108   if (! IS_BREAK_STMT_P (node))
15109     {
15110       /* It's a continue statement. */
15111       for (;; labeled_block = TREE_CHAIN (labeled_block))
15112         {
15113           if (labeled_block == NULL_TREE)
15114             {
15115               if (bc_label == NULL_TREE)
15116                 parse_error_context (wfl_operator,
15117                                      "`continue' must be in loop");
15118               else
15119                 parse_error_context 
15120                   (wfl_operator, "continue label `%s' does not name a loop",
15121                    IDENTIFIER_POINTER (bc_label));
15122               return error_mark_node;
15123             }
15124           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
15125                == continue_identifier_node)
15126               && (bc_label == NULL_TREE
15127                   || TREE_CHAIN (labeled_block) == bc_label))
15128             {
15129               bc_label = labeled_block;
15130               break;
15131             }
15132         }
15133     }
15134   else if (!bc_label)
15135     { 
15136       for (;; labeled_block = TREE_CHAIN (labeled_block))
15137         {
15138           if (labeled_block == NULL_TREE)
15139             {
15140               parse_error_context (wfl_operator,
15141                                      "`break' must be in loop or switch");
15142               return error_mark_node;
15143             }
15144           target_stmt = LABELED_BLOCK_BODY (labeled_block);
15145           if (TREE_CODE (target_stmt) == SWITCH_EXPR
15146               || search_loop (target_stmt))
15147             {
15148               bc_label = labeled_block;
15149               break;
15150             }
15151         }
15152     }
15153
15154   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
15155   CAN_COMPLETE_NORMALLY (bc_label) = 1;
15156
15157   /* Our break/continue don't return values. */
15158   TREE_TYPE (node) = void_type_node;
15159   /* Encapsulate the break within a compound statement so that it's
15160      expanded all the times by expand_expr (and not clobbered
15161      sometimes, like after a if statement) */
15162   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
15163   TREE_SIDE_EFFECTS (node) = 1;
15164   return node;
15165 }
15166
15167 /* Process the exit expression belonging to a loop. Its type must be
15168    boolean.  */
15169
15170 static tree
15171 patch_exit_expr (node)
15172      tree node;
15173 {
15174   tree expression = TREE_OPERAND (node, 0);
15175   TREE_TYPE (node) = error_mark_node;
15176   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15177
15178   /* The type of expression must be boolean */
15179   if (TREE_TYPE (expression) != boolean_type_node)
15180     {
15181       parse_error_context 
15182         (wfl_operator, 
15183     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
15184          lang_printable_name (TREE_TYPE (expression), 0));
15185       return error_mark_node;
15186     }
15187   /* Now we know things are allright, invert the condition, fold and
15188      return */
15189   TREE_OPERAND (node, 0) = 
15190     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
15191
15192   if (! integer_zerop (TREE_OPERAND (node, 0))
15193       && ctxp->current_loop != NULL_TREE
15194       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
15195     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
15196   if (! integer_onep (TREE_OPERAND (node, 0)))
15197     CAN_COMPLETE_NORMALLY (node) = 1;
15198
15199
15200   TREE_TYPE (node) = void_type_node;
15201   return node;
15202 }
15203
15204 /* 14.9 Switch statement */
15205
15206 static tree
15207 patch_switch_statement (node)
15208      tree node;
15209 {
15210   tree se = TREE_OPERAND (node, 0), se_type;
15211   tree save, iter;
15212
15213   /* Complete the switch expression */
15214   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
15215   se_type = TREE_TYPE (se);
15216   /* The type of the switch expression must be char, byte, short or
15217      int */
15218   if (! JINTEGRAL_TYPE_P (se_type) || se_type == long_type_node)
15219     {
15220       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
15221       parse_error_context (wfl_operator,
15222           "Incompatible type for `switch'. Can't convert `%s' to `int'",
15223                            lang_printable_name (se_type, 0));
15224       /* This is what java_complete_tree will check */
15225       TREE_OPERAND (node, 0) = error_mark_node;
15226       return error_mark_node;
15227     }
15228
15229   /* Save and restore the outer case label list.  */
15230   save = case_label_list;
15231   case_label_list = NULL_TREE;
15232
15233   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
15234
15235   /* See if we've found a duplicate label.  We can't leave this until
15236      code generation, because in `--syntax-only' and `-C' modes we
15237      don't do ordinary code generation.  */
15238   for (iter = case_label_list; iter != NULL_TREE; iter = TREE_CHAIN (iter))
15239     {
15240       HOST_WIDE_INT val = TREE_INT_CST_LOW (TREE_VALUE (iter));
15241       tree subiter;
15242       for (subiter = TREE_CHAIN (iter);
15243            subiter != NULL_TREE;
15244            subiter = TREE_CHAIN (subiter))
15245         {
15246           HOST_WIDE_INT subval = TREE_INT_CST_LOW (TREE_VALUE (subiter));
15247           if (val == subval)
15248             {
15249               EXPR_WFL_LINECOL (wfl_operator)
15250                 = EXPR_WFL_LINECOL (TREE_PURPOSE (iter));
15251               /* The case_label_list is in reverse order, so print the
15252                  outer label first.  */
15253               parse_error_context (wfl_operator, "duplicate case label: `"
15254                                    HOST_WIDE_INT_PRINT_DEC "'", subval);
15255               EXPR_WFL_LINECOL (wfl_operator)
15256                 = EXPR_WFL_LINECOL (TREE_PURPOSE (subiter));
15257               parse_error_context (wfl_operator, "original label is here");
15258
15259               break;
15260             }
15261         }
15262     }
15263
15264   case_label_list = save;
15265
15266   /* Ready to return */
15267   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
15268     {
15269       TREE_TYPE (node) = error_mark_node;
15270       return error_mark_node;
15271     }
15272   TREE_TYPE (node) = void_type_node;
15273   TREE_SIDE_EFFECTS (node) = 1;
15274   CAN_COMPLETE_NORMALLY (node)
15275     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
15276       || ! SWITCH_HAS_DEFAULT (node);
15277   return node;
15278 }
15279
15280 /* 14.18 The try/catch statements */
15281
15282 /* Encapsulate TRY_STMTS' in a try catch sequence. The catch clause
15283    catches TYPE and executes CATCH_STMTS.  */
15284
15285 static tree
15286 encapsulate_with_try_catch (location, type, try_stmts, catch_stmts)
15287      int location;
15288      tree type, try_stmts, catch_stmts;
15289 {
15290   tree try_block, catch_clause_param, catch_block, catch;
15291
15292   /* First build a try block */
15293   try_block = build_expr_block (try_stmts, NULL_TREE);
15294
15295   /* Build a catch block: we need a catch clause parameter */
15296   catch_clause_param = build_decl (VAR_DECL, 
15297                                    wpv_id, build_pointer_type (type));
15298   /* And a block */
15299   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
15300   
15301   /* Initialize the variable and store in the block */
15302   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
15303                  build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
15304   add_stmt_to_block (catch_block, NULL_TREE, catch);
15305
15306   /* Add the catch statements */
15307   add_stmt_to_block (catch_block, NULL_TREE, catch_stmts);
15308
15309   /* Now we can build a CATCH_EXPR */
15310   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
15311
15312   return build_try_statement (location, try_block, catch_block);
15313 }
15314
15315 static tree
15316 build_try_statement (location, try_block, catches)
15317      int location;
15318      tree try_block, catches;
15319 {
15320   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
15321   EXPR_WFL_LINECOL (node) = location;
15322   return node;
15323 }
15324
15325 static tree
15326 build_try_finally_statement (location, try_block, finally)
15327      int location;
15328      tree try_block, finally;
15329 {
15330   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
15331   EXPR_WFL_LINECOL (node) = location;
15332   return node;
15333 }
15334
15335 static tree
15336 patch_try_statement (node)
15337      tree node;
15338 {
15339   int error_found = 0;
15340   tree try = TREE_OPERAND (node, 0);
15341   /* Exception handlers are considered in left to right order */
15342   tree catch = nreverse (TREE_OPERAND (node, 1));
15343   tree current, caught_type_list = NULL_TREE;
15344
15345   /* Check catch clauses, if any. Every time we find an error, we try
15346      to process the next catch clause. We process the catch clause before
15347      the try block so that when processing the try block we can check thrown
15348      exceptions againts the caught type list. */
15349   for (current = catch; current; current = TREE_CHAIN (current))
15350     {
15351       tree carg_decl, carg_type;
15352       tree sub_current, catch_block, catch_clause;
15353       int unreachable;
15354
15355       /* At this point, the structure of the catch clause is
15356            CATCH_EXPR           (catch node)
15357              BLOCK              (with the decl of the parameter)
15358                COMPOUND_EXPR
15359                  MODIFY_EXPR   (assignment of the catch parameter)
15360                  BLOCK          (catch clause block)
15361        */
15362       catch_clause = TREE_OPERAND (current, 0);
15363       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
15364       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
15365
15366       /* Catch clauses can't have more than one parameter declared,
15367          but it's already enforced by the grammar. Make sure that the
15368          only parameter of the clause statement in of class Throwable
15369          or a subclass of Throwable, but that was done earlier. The
15370          catch clause parameter type has also been resolved. */
15371       
15372       /* Just make sure that the catch clause parameter type inherits
15373          from java.lang.Throwable */
15374       if (!inherits_from_p (carg_type, throwable_type_node))
15375         {
15376           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15377           parse_error_context (wfl_operator,
15378                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
15379                                lang_printable_name (carg_type, 0));
15380           error_found = 1;
15381           continue;
15382         }
15383       
15384       /* Partial check for unreachable catch statement: The catch
15385          clause is reachable iff is no earlier catch block A in
15386          the try statement such that the type of the catch
15387          clause's parameter is the same as or a subclass of the
15388          type of A's parameter */
15389       unreachable = 0;
15390       for (sub_current = catch;
15391            sub_current != current; sub_current = TREE_CHAIN (sub_current))
15392         {
15393           tree sub_catch_clause, decl;
15394           sub_catch_clause = TREE_OPERAND (sub_current, 0);
15395           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
15396
15397           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
15398             {
15399               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15400               parse_error_context 
15401                 (wfl_operator,
15402                  "`catch' not reached because of the catch clause at line %d",
15403                  EXPR_WFL_LINENO (sub_current));
15404               unreachable = error_found = 1;
15405               break;
15406             }
15407         }
15408       /* Complete the catch clause block */
15409       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
15410       if (catch_block == error_mark_node)
15411         {
15412           error_found = 1;
15413           continue;
15414         }
15415       if (CAN_COMPLETE_NORMALLY (catch_block))
15416         CAN_COMPLETE_NORMALLY (node) = 1;
15417       TREE_OPERAND (current, 0) = catch_block;
15418
15419       if (unreachable)
15420         continue;
15421
15422       /* Things to do here: the exception must be thrown */
15423
15424       /* Link this type to the caught type list */
15425       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
15426     }
15427
15428   PUSH_EXCEPTIONS (caught_type_list);
15429   if ((try = java_complete_tree (try)) == error_mark_node)
15430     error_found = 1;
15431   if (CAN_COMPLETE_NORMALLY (try))
15432     CAN_COMPLETE_NORMALLY (node) = 1;
15433   POP_EXCEPTIONS ();
15434
15435   /* Verification ends here */
15436   if (error_found) 
15437     return error_mark_node;
15438
15439   TREE_OPERAND (node, 0) = try;
15440   TREE_OPERAND (node, 1) = catch;
15441   TREE_TYPE (node) = void_type_node;
15442   return node;
15443 }
15444
15445 /* 14.17 The synchronized Statement */
15446
15447 static tree
15448 patch_synchronized_statement (node, wfl_op1)
15449     tree node, wfl_op1;
15450 {
15451   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
15452   tree block = TREE_OPERAND (node, 1);
15453
15454   tree tmp, enter, exit, expr_decl, assignment;
15455
15456   if (expr == error_mark_node)
15457     {
15458       block = java_complete_tree (block);
15459       return expr;
15460     }
15461
15462   /* We might be trying to synchronize on a STRING_CST */
15463   if ((tmp = patch_string (expr)))
15464     expr = tmp;
15465
15466   /* The TYPE of expr must be a reference type */
15467   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
15468     {
15469       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15470       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
15471                            lang_printable_name (TREE_TYPE (expr), 0));
15472       return error_mark_node;
15473     }
15474
15475   if (flag_emit_xref)
15476     {
15477       TREE_OPERAND (node, 0) = expr;
15478       TREE_OPERAND (node, 1) = java_complete_tree (block);
15479       CAN_COMPLETE_NORMALLY (node) = 1;
15480       return node;
15481     }
15482
15483   /* Generate a try-finally for the synchronized statement, except
15484      that the handler that catches all throw exception calls
15485      _Jv_MonitorExit and then rethrow the exception.
15486      The synchronized statement is then implemented as:
15487      TRY 
15488        {
15489          _Jv_MonitorEnter (expression)
15490          synchronized_block
15491          _Jv_MonitorExit (expression)
15492        }
15493      CATCH_ALL
15494        {
15495          e = _Jv_exception_info ();
15496          _Jv_MonitorExit (expression)
15497          Throw (e);
15498        } */
15499
15500   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
15501   BUILD_MONITOR_ENTER (enter, expr_decl);
15502   BUILD_MONITOR_EXIT (exit, expr_decl);
15503   CAN_COMPLETE_NORMALLY (enter) = 1;
15504   CAN_COMPLETE_NORMALLY (exit) = 1;
15505   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
15506   TREE_SIDE_EFFECTS (assignment) = 1;
15507   node = build (COMPOUND_EXPR, NULL_TREE,
15508                 build (COMPOUND_EXPR, NULL_TREE, assignment, enter),
15509                 build (TRY_FINALLY_EXPR, NULL_TREE, block, exit));
15510   node = build_expr_block (node, expr_decl);
15511
15512   return java_complete_tree (node);
15513 }
15514
15515 /* 14.16 The throw Statement */
15516
15517 static tree
15518 patch_throw_statement (node, wfl_op1)
15519     tree node, wfl_op1;
15520 {
15521   tree expr = TREE_OPERAND (node, 0);
15522   tree type = TREE_TYPE (expr);
15523   int unchecked_ok = 0, tryblock_throws_ok = 0;
15524
15525   /* Thrown expression must be assignable to java.lang.Throwable */
15526   if (!try_reference_assignconv (throwable_type_node, expr))
15527     {
15528       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15529       parse_error_context (wfl_operator,
15530     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
15531                            lang_printable_name (type, 0));
15532       /* If the thrown expression was a reference, we further the
15533          compile-time check. */
15534       if (!JREFERENCE_TYPE_P (type))
15535         return error_mark_node;
15536     }
15537
15538   /* At least one of the following must be true */
15539
15540   /* The type of the throw expression is a not checked exception,
15541      i.e. is a unchecked expression. */
15542   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
15543
15544   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15545   /* An instance can't throw a checked exception unless that exception
15546      is explicitly declared in the `throws' clause of each
15547      constructor. This doesn't apply to anonymous classes, since they
15548      don't have declared constructors. */
15549   if (!unchecked_ok 
15550       && DECL_INSTINIT_P (current_function_decl)
15551       && !ANONYMOUS_CLASS_P (current_class))
15552     {
15553       tree current;
15554       for (current = TYPE_METHODS (current_class); current; 
15555            current = TREE_CHAIN (current))
15556         if (DECL_CONSTRUCTOR_P (current) 
15557             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
15558           {
15559             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)", 
15560                                  lang_printable_name (TREE_TYPE (expr), 0));
15561             return error_mark_node;
15562           }
15563     }
15564
15565   /* Throw is contained in a try statement and at least one catch
15566      clause can receive the thrown expression or the current method is
15567      declared to throw such an exception. Or, the throw statement is
15568      contained in a method or constructor declaration and the type of
15569      the Expression is assignable to at least one type listed in the
15570      throws clause the declaration. */
15571   if (!unchecked_ok)
15572     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
15573   if (!(unchecked_ok || tryblock_throws_ok))
15574     {
15575       /* If there is a surrounding try block that has no matching
15576          clatch clause, report it first. A surrounding try block exits
15577          only if there is something after the list of checked
15578          exception thrown by the current function (if any). */
15579       if (IN_TRY_BLOCK_P ())
15580         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
15581                              lang_printable_name (type, 0));
15582       /* If we have no surrounding try statement and the method doesn't have
15583          any throws, report it now. FIXME */
15584
15585       /* We report that the exception can't be throw from a try block
15586          in all circumstances but when the `throw' is inside a static
15587          block. */
15588       else if (!EXCEPTIONS_P (currently_caught_type_list) 
15589                && !tryblock_throws_ok)
15590         {
15591           if (DECL_CLINIT_P (current_function_decl))
15592             parse_error_context (wfl_operator,
15593                    "Checked exception `%s' can't be thrown in initializer",
15594                                  lang_printable_name (type, 0));
15595           else
15596             parse_error_context (wfl_operator,
15597                    "Checked exception `%s' isn't thrown from a `try' block", 
15598                                  lang_printable_name (type, 0));
15599         }
15600       /* Otherwise, the current method doesn't have the appropriate
15601          throws declaration */
15602       else
15603         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
15604                              lang_printable_name (type, 0));
15605       return error_mark_node;
15606     }
15607
15608   if (! flag_emit_class_files && ! flag_emit_xref)
15609     BUILD_THROW (node, expr);
15610
15611   /* If doing xrefs, keep the location where the `throw' was seen. */
15612   if (flag_emit_xref)
15613     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
15614   return node;
15615 }
15616
15617 /* Check that exception said to be thrown by method DECL can be
15618    effectively caught from where DECL is invoked.  */
15619
15620 static void
15621 check_thrown_exceptions (location, decl)
15622      int location;
15623      tree decl;
15624 {
15625   tree throws;
15626   /* For all the unchecked exceptions thrown by DECL */
15627   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
15628        throws = TREE_CHAIN (throws)) 
15629     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
15630       {
15631 #if 1
15632         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
15633         if (DECL_NAME (decl) == get_identifier ("clone"))
15634           continue;
15635 #endif
15636         EXPR_WFL_LINECOL (wfl_operator) = location;
15637         if (DECL_FINIT_P (current_function_decl))
15638           parse_error_context
15639             (wfl_operator, "Exception `%s' can't be thrown in initializer",
15640              lang_printable_name (TREE_VALUE (throws), 0));
15641         else 
15642           {
15643             parse_error_context 
15644               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
15645                lang_printable_name (TREE_VALUE (throws), 0),
15646                (DECL_INIT_P (current_function_decl) ?
15647                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
15648                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
15649           }
15650       }
15651 }
15652
15653 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
15654    try-catch blocks, OR is listed in the `throws' clause of the
15655    current method.  */
15656
15657 static int
15658 check_thrown_exceptions_do (exception)
15659      tree exception;
15660 {
15661   tree list = currently_caught_type_list;
15662   resolve_and_layout (exception, NULL_TREE);
15663   /* First, all the nested try-catch-finally at that stage. The
15664      last element contains `throws' clause exceptions, if any. */
15665   if (IS_UNCHECKED_EXCEPTION_P (exception))
15666     return 1;
15667   while (list)
15668     {
15669       tree caught;
15670       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
15671         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
15672           return 1;
15673       list = TREE_CHAIN (list);
15674     }
15675   return 0;
15676 }
15677
15678 static void
15679 purge_unchecked_exceptions (mdecl)
15680      tree mdecl;
15681 {
15682   tree throws = DECL_FUNCTION_THROWS (mdecl);
15683   tree new = NULL_TREE;
15684
15685   while (throws)
15686     {
15687       tree next = TREE_CHAIN (throws);
15688       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
15689         {
15690           TREE_CHAIN (throws) = new;
15691           new = throws;
15692         }
15693       throws = next;
15694     }
15695   /* List is inverted here, but it doesn't matter */
15696   DECL_FUNCTION_THROWS (mdecl) = new;
15697 }
15698
15699 /* This function goes over all of CLASS_TYPE ctors and checks whether
15700    each of them features at least one unchecked exception in its
15701    `throws' clause. If it's the case, it returns `true', `false'
15702    otherwise.  */
15703
15704 static bool
15705 ctors_unchecked_throws_clause_p (class_type)
15706      tree class_type;
15707 {
15708   tree current;
15709
15710   for (current = TYPE_METHODS (class_type); current;
15711        current = TREE_CHAIN (current))
15712     {
15713       bool ctu = false; /* Ctor Throws Unchecked */
15714       if (DECL_CONSTRUCTOR_P (current))
15715         {
15716           tree throws;
15717           for (throws = DECL_FUNCTION_THROWS (current); throws && !ctu;
15718                throws = TREE_CHAIN (throws))
15719             if (inherits_from_p (TREE_VALUE (throws), exception_type_node))
15720               ctu = true;
15721         }
15722       /* We return false as we found one ctor that is unfit. */
15723       if (!ctu && DECL_CONSTRUCTOR_P (current))
15724         return false;
15725     }
15726   /* All ctors feature at least one unchecked exception in their
15727      `throws' clause. */
15728   return true;
15729 }
15730
15731 /* 15.24 Conditional Operator ?: */
15732
15733 static tree
15734 patch_conditional_expr (node, wfl_cond, wfl_op1)
15735      tree node, wfl_cond, wfl_op1;
15736 {
15737   tree cond = TREE_OPERAND (node, 0);
15738   tree op1 = TREE_OPERAND (node, 1);
15739   tree op2 = TREE_OPERAND (node, 2);
15740   tree resulting_type = NULL_TREE;
15741   tree t1, t2, patched;
15742   int error_found = 0;
15743
15744   /* Operands of ?: might be StringBuffers crafted as a result of a
15745      string concatenation. Obtain a descent operand here.  */
15746   if ((patched = patch_string (op1)))
15747     TREE_OPERAND (node, 1) = op1 = patched;
15748   if ((patched = patch_string (op2)))
15749     TREE_OPERAND (node, 2) = op2 = patched;
15750
15751   t1 = TREE_TYPE (op1);
15752   t2 = TREE_TYPE (op2);
15753
15754   /* The first expression must be a boolean */
15755   if (TREE_TYPE (cond) != boolean_type_node)
15756     {
15757       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
15758       parse_error_context (wfl_operator,
15759                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
15760                            lang_printable_name (TREE_TYPE (cond), 0));
15761       error_found = 1;
15762     }
15763
15764   /* Second and third can be numeric, boolean (i.e. primitive),
15765      references or null. Anything else results in an error */
15766   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
15767         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
15768             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
15769         || (t1 == boolean_type_node && t2 == boolean_type_node)))
15770     error_found = 1;
15771
15772   /* Determine the type of the conditional expression. Same types are
15773      easy to deal with */
15774   else if (t1 == t2)
15775     resulting_type = t1;
15776
15777   /* There are different rules for numeric types */
15778   else if (JNUMERIC_TYPE_P (t1))
15779     {
15780       /* if byte/short found, the resulting type is short */
15781       if ((t1 == byte_type_node && t2 == short_type_node)
15782           || (t1 == short_type_node && t2 == byte_type_node))
15783         resulting_type = short_type_node;
15784
15785       /* If t1 is a constant int and t2 is of type byte, short or char
15786          and t1's value fits in t2, then the resulting type is t2 */
15787       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
15788           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
15789         resulting_type = t2;
15790
15791       /* If t2 is a constant int and t1 is of type byte, short or char
15792          and t2's value fits in t1, then the resulting type is t1 */
15793       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
15794           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
15795         resulting_type = t1;
15796
15797       /* Otherwise, binary numeric promotion is applied and the
15798          resulting type is the promoted type of operand 1 and 2 */
15799       else 
15800         resulting_type = binary_numeric_promotion (t1, t2, 
15801                                                    &TREE_OPERAND (node, 1), 
15802                                                    &TREE_OPERAND (node, 2));
15803     }
15804
15805   /* Cases of a reference and a null type */
15806   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
15807     resulting_type = t1;
15808
15809   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
15810     resulting_type = t2;
15811
15812   /* Last case: different reference types. If a type can be converted
15813      into the other one by assignment conversion, the latter
15814      determines the type of the expression */
15815   else if ((resulting_type = try_reference_assignconv (t1, op2)))
15816     resulting_type = promote_type (t1);
15817
15818   else if ((resulting_type = try_reference_assignconv (t2, op1)))
15819     resulting_type = promote_type (t2);
15820
15821   /* If we don't have any resulting type, we're in trouble */
15822   if (!resulting_type)
15823     {
15824       char *t = xstrdup (lang_printable_name (t1, 0));
15825       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15826       parse_error_context (wfl_operator,
15827                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
15828                            t, lang_printable_name (t2, 0));
15829       free (t);
15830       error_found = 1;
15831     }
15832
15833   if (error_found)
15834     {
15835       TREE_TYPE (node) = error_mark_node;
15836       return error_mark_node;
15837     }
15838
15839   TREE_TYPE (node) = resulting_type;
15840   TREE_SET_CODE (node, COND_EXPR);
15841   CAN_COMPLETE_NORMALLY (node) = 1;
15842   return node;
15843 }
15844
15845 /* Wrap EXPR with code to initialize DECL's class, if appropriate. */
15846
15847 static tree
15848 maybe_build_class_init_for_field (decl, expr)
15849     tree decl, expr;
15850 {
15851   tree clas = DECL_CONTEXT (decl);
15852   if (flag_emit_class_files || flag_emit_xref)
15853     return expr;
15854
15855   if (TREE_CODE (decl) == VAR_DECL && FIELD_STATIC (decl)
15856       && FIELD_FINAL (decl))
15857     {
15858       tree init = DECL_INITIAL (decl);
15859       if (init != NULL_TREE)
15860         init = fold_constant_for_init (init, decl);
15861       if (init != NULL_TREE && CONSTANT_VALUE_P (init))
15862         return expr;
15863     }
15864
15865   return build_class_init (clas, expr);
15866 }
15867
15868 /* Try to constant fold NODE.
15869    If NODE is not a constant expression, return NULL_EXPR.
15870    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
15871
15872 static tree
15873 fold_constant_for_init (node, context)
15874      tree node;
15875      tree context;
15876 {
15877   tree op0, op1, val;
15878   enum tree_code code = TREE_CODE (node);
15879
15880   switch (code)
15881     {
15882     case STRING_CST:
15883     case INTEGER_CST:
15884     case REAL_CST:
15885       return node;
15886
15887     case PLUS_EXPR:
15888     case MINUS_EXPR:
15889     case MULT_EXPR:
15890     case TRUNC_MOD_EXPR:
15891     case RDIV_EXPR:
15892     case LSHIFT_EXPR:
15893     case RSHIFT_EXPR:
15894     case URSHIFT_EXPR:
15895     case BIT_AND_EXPR:
15896     case BIT_XOR_EXPR:
15897     case BIT_IOR_EXPR:
15898     case TRUTH_ANDIF_EXPR:
15899     case TRUTH_ORIF_EXPR:
15900     case EQ_EXPR: 
15901     case NE_EXPR:
15902     case GT_EXPR:
15903     case GE_EXPR:
15904     case LT_EXPR:
15905     case LE_EXPR:
15906       op0 = TREE_OPERAND (node, 0);
15907       op1 = TREE_OPERAND (node, 1);
15908       val = fold_constant_for_init (op0, context);
15909       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15910         return NULL_TREE;
15911       TREE_OPERAND (node, 0) = val;
15912       val = fold_constant_for_init (op1, context);
15913       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15914         return NULL_TREE;
15915       TREE_OPERAND (node, 1) = val;
15916       return patch_binop (node, op0, op1);
15917
15918     case UNARY_PLUS_EXPR:
15919     case NEGATE_EXPR:
15920     case TRUTH_NOT_EXPR:
15921     case BIT_NOT_EXPR:
15922     case CONVERT_EXPR:
15923       op0 = TREE_OPERAND (node, 0);
15924       val = fold_constant_for_init (op0, context);
15925       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15926         return NULL_TREE;
15927       TREE_OPERAND (node, 0) = val;
15928       return patch_unaryop (node, op0);
15929       break;
15930
15931     case COND_EXPR:
15932       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
15933       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15934         return NULL_TREE;
15935       TREE_OPERAND (node, 0) = val;
15936       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
15937       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15938         return NULL_TREE;
15939       TREE_OPERAND (node, 1) = val;
15940       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
15941       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15942         return NULL_TREE;
15943       TREE_OPERAND (node, 2) = val;
15944       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
15945         : TREE_OPERAND (node, 2);
15946
15947     case VAR_DECL:
15948     case FIELD_DECL:
15949       if (! FIELD_FINAL (node)
15950           || DECL_INITIAL (node) == NULL_TREE)
15951         return NULL_TREE;
15952       val = DECL_INITIAL (node);
15953       /* Guard against infinite recursion. */
15954       DECL_INITIAL (node) = NULL_TREE;
15955       val = fold_constant_for_init (val, node);
15956       DECL_INITIAL (node) = val;
15957       return val;
15958
15959     case EXPR_WITH_FILE_LOCATION:
15960       /* Compare java_complete_tree and resolve_expression_name. */
15961       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
15962           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
15963         {
15964           tree name = EXPR_WFL_NODE (node);
15965           tree decl;
15966           if (PRIMARY_P (node))
15967             return NULL_TREE;
15968           else if (! QUALIFIED_P (name))
15969             {
15970               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
15971               if (decl == NULL_TREE 
15972                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
15973                 return NULL_TREE;
15974               return fold_constant_for_init (decl, decl);
15975             }
15976           else
15977             {
15978               /* Install the proper context for the field resolution.
15979                  The prior context is restored once the name is
15980                  properly qualified. */
15981               tree saved_current_class = current_class;
15982               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
15983               current_class = DECL_CONTEXT (context);
15984               qualify_ambiguous_name (node);
15985               current_class = saved_current_class;
15986               if (resolve_field_access (node, &decl, NULL)
15987                   && decl != NULL_TREE)
15988                 return fold_constant_for_init (decl, decl);
15989               return NULL_TREE;
15990             }
15991         }
15992       else
15993         {
15994           op0 = TREE_OPERAND (node, 0);
15995           val = fold_constant_for_init (op0, context);
15996           if (val == NULL_TREE || ! TREE_CONSTANT (val))
15997             return NULL_TREE;
15998           TREE_OPERAND (node, 0) = val;
15999           return val;
16000         }
16001
16002 #ifdef USE_COMPONENT_REF
16003     case IDENTIFIER:
16004     case COMPONENT_REF:
16005       ?;
16006 #endif
16007
16008     default:
16009       return NULL_TREE;
16010     }
16011 }
16012
16013 #ifdef USE_COMPONENT_REF
16014 /* Context is 'T' for TypeName, 'P' for PackageName,
16015    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
16016
16017 tree
16018 resolve_simple_name (name, context)
16019      tree name;
16020      int context;
16021 {
16022 }
16023
16024 tree
16025 resolve_qualified_name (name, context)
16026      tree name;
16027      int context;
16028 {
16029 }
16030 #endif
16031
16032 /* Mark P, which is really a `struct parser_ctxt **' for GC.  */
16033
16034 static void
16035 mark_parser_ctxt (p)
16036      void *p;
16037 {
16038   struct parser_ctxt *pc = *((struct parser_ctxt **) p);
16039   int i;
16040
16041   if (!pc)
16042     return;
16043
16044 #ifndef JC1_LITE
16045   for (i = 0; i < 11; ++i)
16046     ggc_mark_tree (pc->modifier_ctx[i]);
16047   ggc_mark_tree (pc->class_type);
16048   ggc_mark_tree (pc->function_decl);
16049   ggc_mark_tree (pc->package);
16050   ggc_mark_tree (pc->class_list);
16051   ggc_mark_tree (pc->current_parsed_class);
16052   ggc_mark_tree (pc->current_parsed_class_un);
16053   ggc_mark_tree (pc->non_static_initialized);
16054   ggc_mark_tree (pc->static_initialized);
16055   ggc_mark_tree (pc->instance_initializers);
16056   ggc_mark_tree (pc->import_list);
16057   ggc_mark_tree (pc->import_demand_list);
16058   ggc_mark_tree (pc->current_loop);
16059   ggc_mark_tree (pc->current_labeled_block);
16060 #endif /* JC1_LITE */
16061
16062   if (pc->next)
16063     mark_parser_ctxt (&pc->next);
16064 }
16065
16066 void
16067 init_src_parse ()
16068 {
16069   /* Register roots with the garbage collector.  */
16070   ggc_add_tree_root (src_parse_roots, ARRAY_SIZE (src_parse_roots));
16071
16072   /* Sanity check; we've been bit by this before.  */
16073   if (ARRAY_SIZE (ctxp->modifier_ctx) != MODIFIER_TK - PUBLIC_TK)
16074     abort ();
16075 }
16076
16077 \f
16078
16079 /* This section deals with the functions that are called when tables
16080    recording class initialization information are traversed.  */
16081
16082 /* Attach to PTR (a block) the declaration found in ENTRY. */
16083
16084 static bool
16085 attach_init_test_initialization_flags (entry, ptr)
16086      struct hash_entry *entry;
16087      PTR ptr;
16088 {
16089   tree block = (tree)ptr;
16090   struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
16091   
16092   TREE_CHAIN (ite->init_test_decl) = BLOCK_EXPR_DECLS (block);
16093   BLOCK_EXPR_DECLS (block) = ite->init_test_decl;
16094   return true;
16095 }
16096
16097 /* This function is called for each classes that is known definitely
16098    assigned when a given static method was called. This function
16099    augments a compound expression (INFO) storing all assignment to
16100    initialized static class flags if a flag already existed, otherwise
16101    a new one is created.  */
16102
16103 static bool
16104 emit_test_initialization (entry, info)
16105      struct hash_entry *entry;
16106      PTR info;
16107 {
16108   tree l = (tree) info;
16109   tree decl, init;
16110
16111   struct init_test_hash_entry *ite = (struct init_test_hash_entry *)
16112     hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
16113                  entry->key,
16114                  current_function_decl != TREE_PURPOSE (l), NULL);
16115
16116   /* If we haven't found a flag and we're dealing with self registered
16117      with current_function_decl, then don't do anything. Self is
16118      always added as definitely initialized but this information is
16119      valid only if used outside the current function. */
16120   if (! ite)
16121     return true;
16122
16123   /* If we don't have a variable, create one and install it. */
16124   if (! ite->init_test_decl)
16125     {
16126       tree block;
16127       
16128       decl = build_decl (VAR_DECL, NULL_TREE, boolean_type_node);
16129       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
16130       LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
16131       DECL_CONTEXT (decl) = current_function_decl;
16132       DECL_INITIAL (decl) = boolean_true_node;
16133
16134       /* The trick is to find the right context for it. */
16135       block = BLOCK_SUBBLOCKS (GET_CURRENT_BLOCK (current_function_decl));
16136       TREE_CHAIN (decl) = BLOCK_EXPR_DECLS (block);
16137       BLOCK_EXPR_DECLS (block) = decl;
16138       ite->init_test_decl = decl;
16139     }
16140   else
16141     decl = ite->init_test_decl;
16142
16143   /* Now simply augment the compound that holds all the assignments
16144      pertaining to this method invocation. */
16145   init = build (MODIFY_EXPR, boolean_type_node, decl, boolean_true_node);
16146   TREE_SIDE_EFFECTS (init) = 1;
16147   TREE_VALUE (l) = add_stmt_to_compound (TREE_VALUE (l), void_type_node, init);
16148   TREE_SIDE_EFFECTS (TREE_VALUE (l)) = 1;
16149
16150   return true;
16151 }