OSDN Git Service

2001-05-07 Alexandre Petit-Bianco <apbianco@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / parse.y
1 /* Source code parsing and tree node generation for the GNU compiler
2    for the Java(TM) language.
3    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
26
27 /* This file parses java source code and issues a tree node image
28 suitable for code generation (byte code and targeted CPU assembly
29 language).
30
31 The grammar conforms to the Java grammar described in "The Java(TM)
32 Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
33 1996, ISBN 0-201-63451-1"
34
35 The following modifications were brought to the original grammar:
36
37 method_body: added the rule '| block SC_TK'
38 static_initializer: added the rule 'static block SC_TK'. 
39
40 Note: All the extra rules described above should go away when the
41       empty_statement rule will work.
42
43 statement_nsi: 'nsi' should be read no_short_if.
44
45 Some rules have been modified to support JDK1.1 inner classes
46 definitions and other extensions.  */
47
48 %{
49 #include "config.h"
50 #include "system.h"
51 #include <dirent.h>
52 #include "tree.h"
53 #include "rtl.h"
54 #include "obstack.h"
55 #include "toplev.h"
56 #include "flags.h"
57 #include "java-tree.h"
58 #include "jcf.h"
59 #include "lex.h"
60 #include "parse.h"
61 #include "zipfile.h"
62 #include "convert.h"
63 #include "buffer.h"
64 #include "xref.h"
65 #include "function.h"
66 #include "except.h"
67 #include "ggc.h"
68
69 #ifndef DIR_SEPARATOR
70 #define DIR_SEPARATOR '/'
71 #endif
72
73 /* Local function prototypes */
74 static char *java_accstring_lookup PARAMS ((int));
75 static void  classitf_redefinition_error PARAMS ((const char *,tree, tree, tree));
76 static void  variable_redefinition_error PARAMS ((tree, tree, tree, int));
77 static tree  create_class PARAMS ((int, tree, tree, tree));
78 static tree  create_interface PARAMS ((int, tree, tree));
79 static void  end_class_declaration PARAMS ((int));
80 static tree  find_field PARAMS ((tree, tree));
81 static tree lookup_field_wrapper PARAMS ((tree, tree));
82 static int   duplicate_declaration_error_p PARAMS ((tree, tree, tree));
83 static void  register_fields PARAMS ((int, tree, tree));
84 static tree parser_qualified_classname PARAMS ((tree));
85 static int  parser_check_super PARAMS ((tree, tree, tree));
86 static int  parser_check_super_interface PARAMS ((tree, tree, tree));
87 static void check_modifiers_consistency PARAMS ((int));
88 static tree lookup_cl PARAMS ((tree));
89 static tree lookup_java_method2 PARAMS ((tree, tree, int));
90 static tree method_header PARAMS ((int, tree, tree, tree));
91 static void fix_method_argument_names PARAMS ((tree ,tree));
92 static tree method_declarator PARAMS ((tree, tree));
93 static void parse_warning_context PARAMS ((tree cl, const char *msg, ...))
94   ATTRIBUTE_PRINTF_2;
95 static void issue_warning_error_from_context PARAMS ((tree, const char *msg, va_list))
96   ATTRIBUTE_PRINTF (2, 0);
97 static void parse_ctor_invocation_error PARAMS ((void));
98 static tree parse_jdk1_1_error PARAMS ((const char *));
99 static void complete_class_report_errors PARAMS ((jdep *));
100 static int process_imports PARAMS ((void));
101 static void read_import_dir PARAMS ((tree));
102 static int find_in_imports_on_demand PARAMS ((tree));
103 static void find_in_imports PARAMS ((tree));
104 static void check_static_final_variable_assignment_flag PARAMS ((tree));
105 static void reset_static_final_variable_assignment_flag PARAMS ((tree));
106 static void check_final_variable_local_assignment_flag PARAMS ((tree, tree));
107 static void reset_final_variable_local_assignment_flag PARAMS ((tree));
108 static int  check_final_variable_indirect_assignment PARAMS ((tree));
109 static void check_final_variable_global_assignment_flag PARAMS ((tree));
110 static void check_inner_class_access PARAMS ((tree, tree, tree));
111 static int check_pkg_class_access PARAMS ((tree, tree));
112 static void register_package PARAMS ((tree));
113 static tree resolve_package PARAMS ((tree, tree *));
114 static tree lookup_package_type PARAMS ((const char *, int));
115 static tree resolve_class PARAMS ((tree, tree, tree, tree));
116 static void declare_local_variables PARAMS ((int, tree, tree));
117 static void source_start_java_method PARAMS ((tree));
118 static void source_end_java_method PARAMS ((void));
119 static tree find_name_in_single_imports PARAMS ((tree));
120 static void check_abstract_method_header PARAMS ((tree));
121 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
122 static tree resolve_expression_name PARAMS ((tree, tree *));
123 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
124 static int check_class_interface_creation PARAMS ((int, int, tree, 
125                                                   tree, tree, tree));
126 static tree patch_method_invocation PARAMS ((tree, tree, tree, int,
127                                             int *, tree *));
128 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
129 static int in_same_package PARAMS ((tree, tree));
130 static tree resolve_and_layout PARAMS ((tree, tree));
131 static tree qualify_and_find PARAMS ((tree, tree, tree));
132 static tree resolve_no_layout PARAMS ((tree, tree));
133 static int invocation_mode PARAMS ((tree, int));
134 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
135                                                             tree, tree));
136 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
137                                                    tree *, tree *));
138 static tree find_most_specific_methods_list PARAMS ((tree));
139 static int argument_types_convertible PARAMS ((tree, tree));
140 static tree patch_invoke PARAMS ((tree, tree, tree));
141 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
142 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
143 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
144 static tree obtain_incomplete_type PARAMS ((tree));
145 static tree java_complete_lhs PARAMS ((tree));
146 static tree java_complete_tree PARAMS ((tree));
147 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
148 static int analyze_clinit_body PARAMS ((tree));
149 static int maybe_yank_clinit PARAMS ((tree));
150 static void java_complete_expand_method PARAMS ((tree));
151 static int  unresolved_type_p PARAMS ((tree, tree *));
152 static void create_jdep_list PARAMS ((struct parser_ctxt *));
153 static tree build_expr_block PARAMS ((tree, tree));
154 static tree enter_block PARAMS ((void));
155 static tree exit_block PARAMS ((void));
156 static tree lookup_name_in_blocks PARAMS ((tree));
157 static void maybe_absorb_scoping_blocks PARAMS ((void));
158 static tree build_method_invocation PARAMS ((tree, tree));
159 static tree build_new_invocation PARAMS ((tree, tree));
160 static tree build_assignment PARAMS ((int, int, tree, tree));
161 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
162 static int check_final_assignment PARAMS ((tree ,tree));
163 static tree patch_assignment PARAMS ((tree, tree, tree ));
164 static tree patch_binop PARAMS ((tree, tree, tree));
165 static tree build_unaryop PARAMS ((int, int, tree));
166 static tree build_incdec PARAMS ((int, int, tree, int));
167 static tree patch_unaryop PARAMS ((tree, tree));
168 static tree build_cast PARAMS ((int, tree, tree));
169 static tree build_null_of_type PARAMS ((tree));
170 static tree patch_cast PARAMS ((tree, tree));
171 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
172 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
173 static int valid_cast_to_p PARAMS ((tree, tree));
174 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
175 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
176 static tree try_reference_assignconv PARAMS ((tree, tree));
177 static tree build_unresolved_array_type PARAMS ((tree));
178 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
179 static tree build_array_ref PARAMS ((int, tree, tree));
180 static tree patch_array_ref PARAMS ((tree));
181 static tree make_qualified_name PARAMS ((tree, tree, int));
182 static tree merge_qualified_name PARAMS ((tree, tree));
183 static tree make_qualified_primary PARAMS ((tree, tree, int));
184 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
185                                                      tree *, tree *));
186 static void qualify_ambiguous_name PARAMS ((tree));
187 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
188 static tree build_newarray_node PARAMS ((tree, tree, int));
189 static tree patch_newarray PARAMS ((tree));
190 static tree resolve_type_during_patch PARAMS ((tree));
191 static tree build_this PARAMS ((int));
192 static tree build_wfl_wrap PARAMS ((tree, int));
193 static tree build_return PARAMS ((int, tree));
194 static tree patch_return PARAMS ((tree));
195 static tree maybe_access_field PARAMS ((tree, tree, tree));
196 static int complete_function_arguments PARAMS ((tree));
197 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
198                                                       tree, tree));
199 static int not_accessible_p PARAMS ((tree, tree, tree, int));
200 static void check_deprecation PARAMS ((tree, tree));
201 static int class_in_current_package PARAMS ((tree));
202 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
203 static tree patch_if_else_statement PARAMS ((tree));
204 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
205 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
206 static tree patch_exit_expr PARAMS ((tree));
207 static tree build_labeled_block PARAMS ((int, tree));
208 static tree finish_labeled_statement PARAMS ((tree, tree));
209 static tree build_bc_statement PARAMS ((int, int, tree));
210 static tree patch_bc_statement PARAMS ((tree));
211 static tree patch_loop_statement PARAMS ((tree));
212 static tree build_new_loop PARAMS ((tree));
213 static tree build_loop_body PARAMS ((int, tree, int));
214 static tree finish_loop_body PARAMS ((int, tree, tree, int));
215 static tree build_debugable_stmt PARAMS ((int, tree));
216 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
217 static tree patch_switch_statement PARAMS ((tree));
218 static tree string_constant_concatenation PARAMS ((tree, tree));
219 static tree build_string_concatenation PARAMS ((tree, tree));
220 static tree patch_string_cst PARAMS ((tree));
221 static tree patch_string PARAMS ((tree));
222 static tree build_try_statement PARAMS ((int, tree, tree));
223 static tree build_try_finally_statement PARAMS ((int, tree, tree));
224 static tree patch_try_statement PARAMS ((tree));
225 static tree patch_synchronized_statement PARAMS ((tree, tree));
226 static tree patch_throw_statement PARAMS ((tree, tree));
227 static void check_thrown_exceptions PARAMS ((int, tree));
228 static int check_thrown_exceptions_do PARAMS ((tree));
229 static void purge_unchecked_exceptions PARAMS ((tree));
230 static void check_throws_clauses PARAMS ((tree, tree, tree));
231 static void finish_method_declaration PARAMS ((tree));
232 static tree build_super_invocation PARAMS ((tree));
233 static int verify_constructor_circularity PARAMS ((tree, tree));
234 static char *constructor_circularity_msg PARAMS ((tree, tree));
235 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
236                                                           int, int));
237 static const char *get_printable_method_name PARAMS ((tree));
238 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
239 static tree generate_finit PARAMS ((tree));
240 static void add_instance_initializer PARAMS ((tree));
241 static tree build_instance_initializer PARAMS ((tree));
242 static void fix_constructors PARAMS ((tree));
243 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
244                                                             tree, int *));
245 static void craft_constructor PARAMS ((tree, tree));
246 static int verify_constructor_super PARAMS ((tree));
247 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
248 static void start_artificial_method_body PARAMS ((tree));
249 static void end_artificial_method_body PARAMS ((tree));
250 static int check_method_redefinition PARAMS ((tree, tree));
251 static int check_method_types_complete PARAMS ((tree));
252 static void java_check_regular_methods PARAMS ((tree));
253 static void java_check_abstract_methods PARAMS ((tree));
254 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
255 static void unreachable_stmt_error PARAMS ((tree));
256 static tree find_expr_with_wfl PARAMS ((tree));
257 static void missing_return_error PARAMS ((tree));
258 static tree build_new_array_init PARAMS ((int, tree));
259 static tree patch_new_array_init PARAMS ((tree, tree));
260 static tree maybe_build_array_element_wfl PARAMS ((tree));
261 static int array_constructor_check_entry PARAMS ((tree, tree));
262 static const char *purify_type_name PARAMS ((const char *));
263 static tree fold_constant_for_init PARAMS ((tree, tree));
264 static tree strip_out_static_field_access_decl PARAMS ((tree));
265 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
266 static void static_ref_err PARAMS ((tree, tree, tree));
267 static void parser_add_interface PARAMS ((tree, tree, tree));
268 static void add_superinterfaces PARAMS ((tree, tree));
269 static tree jdep_resolve_class PARAMS ((jdep *));
270 static int note_possible_classname PARAMS ((const char *, int));
271 static void java_complete_expand_classes PARAMS ((void));
272 static void java_complete_expand_class PARAMS ((tree));
273 static void java_complete_expand_methods PARAMS ((tree));
274 static tree cut_identifier_in_qualified PARAMS ((tree));
275 static tree java_stabilize_reference PARAMS ((tree));
276 static tree do_unary_numeric_promotion PARAMS ((tree));
277 static char * operator_string PARAMS ((tree));
278 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
279 static tree merge_string_cste PARAMS ((tree, tree, int));
280 static tree java_refold PARAMS ((tree));
281 static int java_decl_equiv PARAMS ((tree, tree));
282 static int binop_compound_p PARAMS ((enum tree_code));
283 static tree search_loop PARAMS ((tree));
284 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
285 static int check_abstract_method_definitions PARAMS ((int, tree, tree));
286 static void java_check_abstract_method_definitions PARAMS ((tree));
287 static void java_debug_context_do PARAMS ((int));
288 static void java_parser_context_push_initialized_field PARAMS ((void));
289 static void java_parser_context_pop_initialized_field PARAMS ((void));
290 static tree reorder_static_initialized PARAMS ((tree));
291 static void java_parser_context_suspend PARAMS ((void));
292 static void java_parser_context_resume PARAMS ((void));
293 static int pop_current_osb PARAMS ((struct parser_ctxt *));
294
295 /* JDK 1.1 work. FIXME */
296
297 static tree maybe_make_nested_class_name PARAMS ((tree));
298 static void make_nested_class_name PARAMS ((tree));
299 static void set_nested_class_simple_name_value PARAMS ((tree, int));
300 static void link_nested_class_to_enclosing PARAMS ((void));
301 static tree find_as_inner_class PARAMS ((tree, tree, tree));
302 static tree find_as_inner_class_do PARAMS ((tree, tree));
303 static int check_inner_class_redefinition PARAMS ((tree, tree));
304
305 static tree build_thisn_assign PARAMS ((void));
306 static tree build_current_thisn PARAMS ((tree));
307 static tree build_access_to_thisn PARAMS ((tree, tree, int));
308 static tree maybe_build_thisn_access_method PARAMS ((tree));
309
310 static tree build_outer_field_access PARAMS ((tree, tree));
311 static tree build_outer_field_access_methods PARAMS ((tree));
312 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
313                                                   tree, tree));
314 static tree build_outer_method_access_method PARAMS ((tree));
315 static tree build_new_access_id PARAMS ((void));
316 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
317                                                     tree, tree));
318
319 static int outer_field_access_p PARAMS ((tree, tree));
320 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
321                                                  tree *, tree *));
322 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
323 static tree build_incomplete_class_ref PARAMS ((int, tree));
324 static tree patch_incomplete_class_ref PARAMS ((tree));
325 static tree create_anonymous_class PARAMS ((int, tree));
326 static void patch_anonymous_class PARAMS ((tree, tree, tree));
327 static void add_inner_class_fields PARAMS ((tree, tree));
328
329 static tree build_dot_class_method PARAMS ((tree));
330 static tree build_dot_class_method_invocation PARAMS ((tree));
331 static void create_new_parser_context PARAMS ((int));
332 static void mark_parser_ctxt PARAMS ((void *));
333 static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
334
335 /* Number of error found so far. */
336 int java_error_count; 
337 /* Number of warning found so far. */
338 int java_warning_count;
339 /* Tell when not to fold, when doing xrefs */
340 int do_not_fold;
341 /* Cyclic inheritance report, as it can be set by layout_class */
342 const char *cyclic_inheritance_report;
343  
344 /* Tell when we're within an instance initializer */
345 static int in_instance_initializer;
346
347 /* The current parser context */
348 struct parser_ctxt *ctxp;
349
350 /* List of things that were analyzed for which code will be generated */
351 struct parser_ctxt *ctxp_for_generation = NULL;
352
353 /* binop_lookup maps token to tree_code. It is used where binary
354    operations are involved and required by the parser. RDIV_EXPR
355    covers both integral/floating point division. The code is changed
356    once the type of both operator is worked out.  */
357
358 static enum tree_code binop_lookup[19] = 
359   { 
360     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
361     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
362     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
363     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
364     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
365    };
366 #define BINOP_LOOKUP(VALUE)                                             \
367   binop_lookup [((VALUE) - PLUS_TK) % ARRAY_SIZE (binop_lookup)]
368
369 /* This is the end index for binary operators that can also be used
370    in compound assignements. */
371 #define BINOP_COMPOUND_CANDIDATES 11
372
373 /* The "$L" identifier we use to create labels.  */
374 static tree label_id = NULL_TREE;
375
376 /* The "StringBuffer" identifier used for the String `+' operator. */
377 static tree wfl_string_buffer = NULL_TREE; 
378
379 /* The "append" identifier used for String `+' operator.  */
380 static tree wfl_append = NULL_TREE;
381
382 /* The "toString" identifier used for String `+' operator. */
383 static tree wfl_to_string = NULL_TREE;
384
385 /* The "java.lang" import qualified name.  */
386 static tree java_lang_id = NULL_TREE;
387
388 /* The generated `inst$' identifier used for generated enclosing
389    instance/field access functions.  */
390 static tree inst_id = NULL_TREE;
391
392 /* The "java.lang.Cloneable" qualified name.  */
393 static tree java_lang_cloneable = NULL_TREE;
394
395 /* The "java.io.Serializable" qualified name.  */
396 static tree java_io_serializable = NULL_TREE; 
397
398 /* Context and flag for static blocks */
399 static tree current_static_block = NULL_TREE;
400
401 /* The generated `write_parm_value$' identifier.  */
402 static tree wpv_id;
403
404 /* The list of all packages we've seen so far */
405 static tree package_list = NULL_TREE;
406  
407 /* Hold THIS for the scope of the current public method decl.  */
408 static tree current_this;
409
410 /* Hold a list of catch clauses list. The first element of this list is
411    the list of the catch clauses of the currently analysed try block. */
412 static tree currently_caught_type_list;
413
414 static tree src_parse_roots[1] = { NULL_TREE };
415
416 /* All classes seen from source code */
417 #define gclass_list src_parse_roots[0]
418
419 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
420    line and point it out.  */
421 /* Should point out the one that don't fit. ASCII/unicode, going
422    backward. FIXME */
423
424 #define check_modifiers(__message, __value, __mask) do {        \
425   if ((__value) & ~(__mask))                                    \
426     {                                                           \
427       int i, remainder = (__value) & ~(__mask);                 \
428       for (i = 0; i <= 10; i++)                                 \
429         if ((1 << i) & remainder)                               \
430           parse_error_context (ctxp->modifier_ctx [i], (__message), \
431                                java_accstring_lookup (1 << i)); \
432     }                                                           \
433 } while (0)
434
435 %}
436
437 %union {
438   tree node;
439   int sub_token;
440   struct {
441     int token;
442     int location;
443   } operator;
444   int value;
445 }
446
447 %{
448 #include "lex.c"
449 %}
450
451 %pure_parser
452
453 /* Things defined here have to match the order of what's in the
454    binop_lookup table.  */
455
456 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
457 %token   LS_TK           SRS_TK          ZRS_TK
458 %token   AND_TK          XOR_TK          OR_TK
459 %token   BOOL_AND_TK BOOL_OR_TK 
460 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
461
462 /* This maps to the same binop_lookup entry than the token above */
463
464 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
465 %token   REM_ASSIGN_TK   
466 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
467 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
468
469
470 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
471
472 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
473 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
474 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
475 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
476 %token   STRICT_TK
477
478 /* Keep those two in order, too */
479 %token   DECR_TK INCR_TK
480
481 /* From now one, things can be in any order */
482
483 %token   DEFAULT_TK      IF_TK              THROW_TK
484 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
485 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
486 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
487 %token   VOID_TK         CATCH_TK           INTERFACE_TK
488 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
489 %token   SUPER_TK        WHILE_TK           CLASS_TK
490 %token   SWITCH_TK       CONST_TK           TRY_TK
491 %token   FOR_TK          NEW_TK             CONTINUE_TK
492 %token   GOTO_TK         PACKAGE_TK         THIS_TK
493
494 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
495 %token   CHAR_TK         INTEGRAL_TK
496
497 %token   FLOAT_TK        DOUBLE_TK          FP_TK
498
499 %token   ID_TK
500
501 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
502
503 %token   ASSIGN_ANY_TK   ASSIGN_TK
504 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
505
506 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
507 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
508
509 %type    <value>        modifiers MODIFIER_TK final synchronized
510
511 %type    <node>         super ID_TK identifier
512 %type    <node>         name simple_name qualified_name
513 %type    <node>         type_declaration compilation_unit
514                         field_declaration method_declaration extends_interfaces
515                         interfaces interface_type_list
516                         class_member_declaration
517                         import_declarations package_declaration 
518                         type_declarations interface_body
519                         interface_member_declaration constant_declaration
520                         interface_member_declarations interface_type
521                         abstract_method_declaration interface_type_list
522 %type    <node>         class_body_declaration class_member_declaration
523                         static_initializer constructor_declaration block
524 %type    <node>         class_body_declarations constructor_header
525 %type    <node>         class_or_interface_type class_type class_type_list
526                         constructor_declarator explicit_constructor_invocation
527 %type    <node>         dim_expr dim_exprs this_or_super throws
528
529 %type    <node>         variable_declarator_id variable_declarator
530                         variable_declarators variable_initializer
531                         variable_initializers constructor_body
532                         array_initializer
533
534 %type    <node>         class_body block_end constructor_block_end
535 %type    <node>         statement statement_without_trailing_substatement
536                         labeled_statement if_then_statement label_decl
537                         if_then_else_statement while_statement for_statement
538                         statement_nsi labeled_statement_nsi do_statement
539                         if_then_else_statement_nsi while_statement_nsi
540                         for_statement_nsi statement_expression_list for_init
541                         for_update statement_expression expression_statement
542                         primary_no_new_array expression primary
543                         array_creation_expression array_type
544                         class_instance_creation_expression field_access
545                         method_invocation array_access something_dot_new
546                         argument_list postfix_expression while_expression 
547                         post_increment_expression post_decrement_expression
548                         unary_expression_not_plus_minus unary_expression
549                         pre_increment_expression pre_decrement_expression
550                         unary_expression_not_plus_minus cast_expression
551                         multiplicative_expression additive_expression
552                         shift_expression relational_expression 
553                         equality_expression and_expression 
554                         exclusive_or_expression inclusive_or_expression
555                         conditional_and_expression conditional_or_expression
556                         conditional_expression assignment_expression
557                         left_hand_side assignment for_header for_begin
558                         constant_expression do_statement_begin empty_statement
559                         switch_statement synchronized_statement throw_statement
560                         try_statement switch_expression switch_block
561                         catches catch_clause catch_clause_parameter finally
562                         anonymous_class_creation
563 %type    <node>         return_statement break_statement continue_statement
564
565 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
566 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
567 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
568 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
569 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
570 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
571 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
572 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
573 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
574 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
575 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
576 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
577 %type    <operator>     NEW_TK
578
579 %type    <node>         method_body 
580         
581 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
582                         STRING_LIT_TK NULL_TK VOID_TK
583
584 %type    <node>         IF_TK WHILE_TK FOR_TK
585
586 %type    <node>         formal_parameter_list formal_parameter
587                         method_declarator method_header
588
589 %type    <node>         primitive_type reference_type type 
590                         BOOLEAN_TK INTEGRAL_TK FP_TK
591
592 /* Added or modified JDK 1.1 rule types  */
593 %type    <node>         type_literals
594
595 %%
596 /* 19.2 Production from 2.3: The Syntactic Grammar  */
597 goal:
598                 {
599                   /* Register static variables with the garbage
600                      collector.  */
601                   ggc_add_tree_root (&label_id, 1);
602                   ggc_add_tree_root (&wfl_string_buffer, 1);
603                   ggc_add_tree_root (&wfl_append, 1);
604                   ggc_add_tree_root (&wfl_to_string, 1);
605                   ggc_add_tree_root (&java_lang_id, 1);
606                   ggc_add_tree_root (&inst_id, 1);
607                   ggc_add_tree_root (&java_lang_cloneable, 1);
608                   ggc_add_tree_root (&java_io_serializable, 1);
609                   ggc_add_tree_root (&current_static_block, 1);
610                   ggc_add_tree_root (&wpv_id, 1);
611                   ggc_add_tree_root (&package_list, 1);
612                   ggc_add_tree_root (&current_this, 1);
613                   ggc_add_tree_root (&currently_caught_type_list, 1);
614                   ggc_add_root (&ctxp, 1, 
615                                 sizeof (struct parser_ctxt *),
616                                 mark_parser_ctxt);
617                   ggc_add_root (&ctxp_for_generation, 1, 
618                                 sizeof (struct parser_ctxt *),
619                                 mark_parser_ctxt);
620                 }
621         compilation_unit
622                 {}
623 ;
624
625 /* 19.3 Productions from 3: Lexical structure  */
626 literal:
627         INT_LIT_TK
628 |       FP_LIT_TK
629 |       BOOL_LIT_TK
630 |       CHAR_LIT_TK
631 |       STRING_LIT_TK
632 |       NULL_TK
633 ;
634
635 /* 19.4 Productions from 4: Types, Values and Variables  */
636 type:
637         primitive_type
638 |       reference_type
639 ;
640
641 primitive_type:
642         INTEGRAL_TK
643 |       FP_TK
644 |       BOOLEAN_TK
645 ;
646
647 reference_type:
648         class_or_interface_type
649 |       array_type
650 ;
651
652 class_or_interface_type:
653         name
654 ;
655
656 class_type:
657         class_or_interface_type /* Default rule */
658 ;
659
660 interface_type:
661          class_or_interface_type
662 ;
663
664 array_type:
665         primitive_type dims
666                 { 
667                   int osb = pop_current_osb (ctxp);
668                   tree t = build_java_array_type (($1), -1);
669                   while (--osb)
670                     t = build_unresolved_array_type (t);
671                   $$ = t;
672                 }
673 |       name dims
674                 { 
675                   int osb = pop_current_osb (ctxp);
676                   tree t = $1;
677                   while (osb--)
678                     t = build_unresolved_array_type (t);
679                   $$ = t;
680                 }
681 ;
682
683 /* 19.5 Productions from 6: Names  */
684 name:
685         simple_name             /* Default rule */
686 |       qualified_name          /* Default rule */
687 ;
688
689 simple_name:
690         identifier              /* Default rule */
691 ;
692
693 qualified_name:
694         name DOT_TK identifier
695                 { $$ = make_qualified_name ($1, $3, $2.location); }
696 ;
697
698 identifier:
699         ID_TK
700 ;
701
702 /* 19.6: Production from 7: Packages  */
703 compilation_unit:
704                 {$$ = NULL;}
705 |       package_declaration
706 |       import_declarations
707 |       type_declarations
708 |       package_declaration import_declarations
709 |       package_declaration type_declarations
710 |       import_declarations type_declarations
711 |       package_declaration import_declarations type_declarations
712 ;
713
714 import_declarations:
715         import_declaration
716                 {
717                   $$ = NULL;
718                 }
719 |       import_declarations import_declaration
720                 {
721                   $$ = NULL;
722                 }
723 ;
724
725 type_declarations:
726         type_declaration
727 |       type_declarations type_declaration
728 ;
729
730 package_declaration:
731         PACKAGE_TK name SC_TK
732                 { 
733                   ctxp->package = EXPR_WFL_NODE ($2);
734                   register_package (ctxp->package);
735                 }
736 |       PACKAGE_TK error
737                 {yyerror ("Missing name"); RECOVER;}
738 |       PACKAGE_TK name error
739                 {yyerror ("';' expected"); RECOVER;}
740 ;
741
742 import_declaration:
743         single_type_import_declaration
744 |       type_import_on_demand_declaration
745 ;
746
747 single_type_import_declaration:
748         IMPORT_TK name SC_TK
749                 {
750                   tree name = EXPR_WFL_NODE ($2), last_name;
751                   int   i = IDENTIFIER_LENGTH (name)-1;
752                   const char *last = &IDENTIFIER_POINTER (name)[i];
753                   while (last != IDENTIFIER_POINTER (name))
754                     {
755                       if (last [0] == '.')
756                         break;
757                       last--;
758                     }
759                   last_name = get_identifier (++last);
760                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
761                     {
762                       tree err = find_name_in_single_imports (last_name);
763                       if (err && err != name)
764                         parse_error_context
765                           ($2, "Ambiguous class: `%s' and `%s'",
766                            IDENTIFIER_POINTER (name), 
767                            IDENTIFIER_POINTER (err));
768                       else
769                         REGISTER_IMPORT ($2, last_name);
770                     }
771                   else
772                     REGISTER_IMPORT ($2, last_name);
773                 }
774 |       IMPORT_TK error
775                 {yyerror ("Missing name"); RECOVER;}
776 |       IMPORT_TK name error
777                 {yyerror ("';' expected"); RECOVER;}
778 ;
779
780 type_import_on_demand_declaration:
781         IMPORT_TK name DOT_TK MULT_TK SC_TK
782                 {
783                   tree name = EXPR_WFL_NODE ($2);
784                   /* Don't import java.lang.* twice. */
785                   if (name != java_lang_id)
786                     {
787                       read_import_dir ($2);
788                       ctxp->import_demand_list = 
789                         chainon (ctxp->import_demand_list,
790                                  build_tree_list ($2, NULL_TREE));
791                     }
792                 }
793 |       IMPORT_TK name DOT_TK error
794                 {yyerror ("'*' expected"); RECOVER;}
795 |       IMPORT_TK name DOT_TK MULT_TK error
796                 {yyerror ("';' expected"); RECOVER;}
797 ;
798
799 type_declaration:
800         class_declaration
801                 { end_class_declaration (0); }
802 |       interface_declaration
803                 { end_class_declaration (0); }
804 |       empty_statement
805 |       error
806                 {
807                   YYERROR_NOW;
808                   yyerror ("Class or interface declaration expected");
809                 }
810 ;
811
812 /* 19.7 Shortened from the original:
813    modifiers: modifier | modifiers modifier
814    modifier: any of public...  */
815 modifiers:
816         MODIFIER_TK
817                 {
818                   $$ = (1 << $1);
819                 }
820 |       modifiers MODIFIER_TK
821                 {
822                   int acc = (1 << $2);
823                   if ($$ & acc)
824                     parse_error_context 
825                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
826                        java_accstring_lookup (acc));
827                   else
828                     {
829                       $$ |= acc;
830                     }
831                 }
832 ;
833
834 /* 19.8.1 Production from $8.1: Class Declaration */
835 class_declaration:
836         modifiers CLASS_TK identifier super interfaces
837                 { create_class ($1, $3, $4, $5); }
838         class_body
839 |       CLASS_TK identifier super interfaces 
840                 { create_class (0, $2, $3, $4); }
841         class_body
842 |       modifiers CLASS_TK error
843                 {yyerror ("Missing class name"); RECOVER;}
844 |       CLASS_TK error
845                 {yyerror ("Missing class name"); RECOVER;}
846 |       CLASS_TK identifier error
847                 {
848                   if (!ctxp->class_err) yyerror ("'{' expected"); 
849                   DRECOVER(class1);
850                 }
851 |       modifiers CLASS_TK identifier error
852                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
853 ;
854
855 super:
856                 { $$ = NULL; }
857 |       EXTENDS_TK class_type
858                 { $$ = $2; }
859 |       EXTENDS_TK class_type error
860                 {yyerror ("'{' expected"); ctxp->class_err=1;}
861 |       EXTENDS_TK error
862                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
863 ;
864
865 interfaces:
866                 { $$ = NULL_TREE; }
867 |       IMPLEMENTS_TK interface_type_list
868                 { $$ = $2; }
869 |       IMPLEMENTS_TK error
870                 {
871                   ctxp->class_err=1;
872                   yyerror ("Missing interface name"); 
873                 }
874 ;
875
876 interface_type_list:
877         interface_type
878                 { 
879                   ctxp->interface_number = 1;
880                   $$ = build_tree_list ($1, NULL_TREE);
881                 }
882 |       interface_type_list C_TK interface_type
883                 { 
884                   ctxp->interface_number++;
885                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
886                 }
887 |       interface_type_list C_TK error
888                 {yyerror ("Missing interface name"); RECOVER;}
889 ;
890
891 class_body:
892         OCB_TK CCB_TK
893                 { 
894                   /* Store the location of the `}' when doing xrefs */
895                   if (flag_emit_xref)
896                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
897                       EXPR_WFL_ADD_COL ($2.location, 1);
898                   $$ = GET_CPC ();
899                 }
900 |       OCB_TK class_body_declarations CCB_TK
901                 { 
902                   /* Store the location of the `}' when doing xrefs */
903                   if (flag_emit_xref)
904                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
905                       EXPR_WFL_ADD_COL ($3.location, 1);
906                   $$ = GET_CPC ();
907                 }
908 ;
909
910 class_body_declarations:
911         class_body_declaration
912 |       class_body_declarations class_body_declaration
913 ;
914
915 class_body_declaration:
916         class_member_declaration
917 |       static_initializer
918 |       constructor_declaration
919 |       block                   /* Added, JDK1.1, instance initializer */
920                 {
921                   TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
922                   SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
923                 }
924 ;
925
926 class_member_declaration:
927         field_declaration
928 |       method_declaration
929 |       class_declaration       /* Added, JDK1.1 inner classes */
930                 { end_class_declaration (1); }
931 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
932                 { end_class_declaration (1); }
933 |       empty_statement
934 ;
935
936 /* 19.8.2 Productions from 8.3: Field Declarations  */
937 field_declaration:
938         type variable_declarators SC_TK
939                 { register_fields (0, $1, $2); }
940 |       modifiers type variable_declarators SC_TK
941                 {
942                   check_modifiers 
943                     ("Illegal modifier `%s' for field declaration",
944                      $1, FIELD_MODIFIERS);
945                   check_modifiers_consistency ($1);
946                   register_fields ($1, $2, $3);
947                 }
948 ;
949
950 variable_declarators:
951         /* Should we use build_decl_list () instead ? FIXME */
952         variable_declarator     /* Default rule */
953 |       variable_declarators C_TK variable_declarator
954                 { $$ = chainon ($1, $3); }
955 |       variable_declarators C_TK error
956                 {yyerror ("Missing term"); RECOVER;}
957 ;
958
959 variable_declarator:
960         variable_declarator_id
961                 { $$ = build_tree_list ($1, NULL_TREE); }
962 |       variable_declarator_id ASSIGN_TK variable_initializer
963                 { 
964                   if (java_error_count)
965                     $3 = NULL_TREE;
966                   $$ = build_tree_list 
967                     ($1, build_assignment ($2.token, $2.location, $1, $3));
968                 }
969 |       variable_declarator_id ASSIGN_TK error
970                 {
971                   yyerror ("Missing variable initializer");
972                   $$ = build_tree_list ($1, NULL_TREE);
973                   RECOVER;
974                 }
975 |       variable_declarator_id ASSIGN_TK variable_initializer error
976                 {
977                   yyerror ("';' expected");
978                   $$ = build_tree_list ($1, NULL_TREE);
979                   RECOVER;
980                 }
981 ;
982
983 variable_declarator_id:
984         identifier
985 |       variable_declarator_id OSB_TK CSB_TK
986                 { $$ = build_unresolved_array_type ($1); }
987 |       identifier error
988                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
989 |       variable_declarator_id OSB_TK error
990                 { 
991                   tree node = java_lval.node;
992                   if (node && (TREE_CODE (node) == INTEGER_CST
993                                || TREE_CODE (node) == EXPR_WITH_FILE_LOCATION))
994                     yyerror ("Can't specify array dimension in a declaration");
995                   else
996                     yyerror ("']' expected");
997                   DRECOVER(vdi);
998                 }
999 |       variable_declarator_id CSB_TK error
1000                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
1001 ;
1002
1003 variable_initializer:
1004         expression
1005 |       array_initializer
1006 ;
1007
1008 /* 19.8.3 Productions from 8.4: Method Declarations  */
1009 method_declaration:
1010         method_header 
1011                 {
1012                   current_function_decl = $1;
1013                   if (current_function_decl
1014                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
1015                     source_start_java_method (current_function_decl);
1016                   else
1017                     current_function_decl = NULL_TREE;
1018                 }
1019         method_body
1020                 { finish_method_declaration ($3); }
1021 |       method_header error
1022                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
1023 ;
1024
1025 method_header:  
1026         type method_declarator throws
1027                 { $$ = method_header (0, $1, $2, $3); }
1028 |       VOID_TK method_declarator throws
1029                 { $$ = method_header (0, void_type_node, $2, $3); }
1030 |       modifiers type method_declarator throws
1031                 { $$ = method_header ($1, $2, $3, $4); }
1032 |       modifiers VOID_TK method_declarator throws
1033                 { $$ = method_header ($1, void_type_node, $3, $4); }
1034 |       type error
1035                 {
1036                   yyerror ("Invalid method declaration, method name required");
1037                   RECOVER;
1038                 }
1039 |       modifiers type error
1040                 {RECOVER;}
1041 |       VOID_TK error
1042                 {yyerror ("Identifier expected"); RECOVER;}
1043 |       modifiers VOID_TK error
1044                 {yyerror ("Identifier expected"); RECOVER;}
1045 |       modifiers error
1046                 {
1047                   yyerror ("Invalid method declaration, return type required");
1048                   RECOVER;
1049                 }
1050 ;
1051
1052 method_declarator:
1053         identifier OP_TK CP_TK
1054                 { 
1055                   ctxp->formal_parameter_number = 0;
1056                   $$ = method_declarator ($1, NULL_TREE);
1057                 }
1058 |       identifier OP_TK formal_parameter_list CP_TK
1059                 { $$ = method_declarator ($1, $3); }
1060 |       method_declarator OSB_TK CSB_TK
1061                 {
1062                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1063                   TREE_PURPOSE ($1) = 
1064                     build_unresolved_array_type (TREE_PURPOSE ($1));
1065                   parse_warning_context 
1066                     (wfl_operator, 
1067                      "Discouraged form of returned type specification");
1068                 }
1069 |       identifier OP_TK error
1070                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1071 |       method_declarator OSB_TK error
1072                 {yyerror ("']' expected"); RECOVER;}
1073 ;
1074
1075 formal_parameter_list:
1076         formal_parameter
1077                 {
1078                   ctxp->formal_parameter_number = 1;
1079                 }
1080 |       formal_parameter_list C_TK formal_parameter
1081                 {
1082                   ctxp->formal_parameter_number += 1;
1083                   $$ = chainon ($1, $3);
1084                 }
1085 |       formal_parameter_list C_TK error
1086                 { yyerror ("Missing formal parameter term"); RECOVER; }
1087 ;
1088
1089 formal_parameter:
1090         type variable_declarator_id
1091                 {
1092                   $$ = build_tree_list ($2, $1);
1093                 }
1094 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1095                 { 
1096                   $$ = build_tree_list ($3, $2);
1097                   ARG_FINAL_P ($$) = 1;
1098                 }
1099 |       type error
1100                 {
1101                   yyerror ("Missing identifier"); RECOVER;
1102                   $$ = NULL_TREE;
1103                 }
1104 |       final type error
1105                 {
1106                   yyerror ("Missing identifier"); RECOVER;
1107                   $$ = NULL_TREE;
1108                 }
1109 ;
1110
1111 final:
1112         modifiers
1113                 {
1114                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1115                                    $1, ACC_FINAL);
1116                   if ($1 != ACC_FINAL)
1117                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1118                 }
1119 ;
1120
1121 throws:
1122                 { $$ = NULL_TREE; }
1123 |       THROWS_TK class_type_list
1124                 { $$ = $2; }
1125 |       THROWS_TK error
1126                 {yyerror ("Missing class type term"); RECOVER;}
1127 ;
1128
1129 class_type_list:
1130         class_type
1131                 { $$ = build_tree_list ($1, $1); }
1132 |       class_type_list C_TK class_type
1133                 { $$ = tree_cons ($3, $3, $1); }
1134 |       class_type_list C_TK error
1135                 {yyerror ("Missing class type term"); RECOVER;}
1136 ;
1137
1138 method_body:
1139         block
1140 |       SC_TK { $$ = NULL_TREE; }
1141 ;
1142
1143 /* 19.8.4 Productions from 8.5: Static Initializers  */
1144 static_initializer:
1145         static block
1146                 {
1147                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1148                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1149                   current_static_block = NULL_TREE;
1150                 }
1151 ;
1152
1153 static:                         /* Test lval.sub_token here */
1154         modifiers
1155                 {
1156                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1157                   /* Can't have a static initializer in an innerclass */
1158                   if ($1 | ACC_STATIC &&
1159                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1160                     parse_error_context 
1161                       (MODIFIER_WFL (STATIC_TK),
1162                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1163                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1164                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1165                 }
1166 ;
1167
1168 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1169 constructor_declaration:
1170         constructor_header
1171                 {
1172                   current_function_decl = $1;
1173                   source_start_java_method (current_function_decl);
1174                 }
1175         constructor_body
1176                 { finish_method_declaration ($3); }
1177 ;
1178
1179 constructor_header:
1180         constructor_declarator throws
1181                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1182 |       modifiers constructor_declarator throws
1183                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1184 ;
1185
1186 constructor_declarator:
1187         simple_name OP_TK CP_TK
1188                 { 
1189                   ctxp->formal_parameter_number = 0;  
1190                   $$ = method_declarator ($1, NULL_TREE);
1191                 }
1192 |       simple_name OP_TK formal_parameter_list CP_TK
1193                 { $$ = method_declarator ($1, $3); }
1194 ;
1195
1196 constructor_body:
1197         /* Unlike regular method, we always need a complete (empty)
1198            body so we can safely perform all the required code
1199            addition (super invocation and field initialization) */
1200         block_begin constructor_block_end
1201                 { 
1202                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1203                   $$ = $2;
1204                 }
1205 |       block_begin explicit_constructor_invocation constructor_block_end
1206                 { $$ = $3; }
1207 |       block_begin block_statements constructor_block_end
1208                 { $$ = $3; }
1209 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1210                 { $$ = $4; }
1211 ;
1212
1213 constructor_block_end:
1214         block_end
1215 ;
1216
1217 /* Error recovery for that rule moved down expression_statement: rule.  */
1218 explicit_constructor_invocation:
1219         this_or_super OP_TK CP_TK SC_TK
1220                 { 
1221                   $$ = build_method_invocation ($1, NULL_TREE); 
1222                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1223                   $$ = java_method_add_stmt (current_function_decl, $$);
1224                 }
1225 |       this_or_super OP_TK argument_list CP_TK SC_TK
1226                 { 
1227                   $$ = build_method_invocation ($1, $3); 
1228                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1229                   $$ = java_method_add_stmt (current_function_decl, $$);
1230                 }
1231         /* Added, JDK1.1 inner classes. Modified because the rule
1232            'primary' couldn't work.  */
1233 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1234                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1235 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1236                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1237 ;
1238
1239 this_or_super:                  /* Added, simplifies error diagnostics */
1240         THIS_TK
1241                 {
1242                   tree wfl = build_wfl_node (this_identifier_node);
1243                   EXPR_WFL_LINECOL (wfl) = $1.location;
1244                   $$ = wfl;
1245                 }
1246 |       SUPER_TK
1247                 {
1248                   tree wfl = build_wfl_node (super_identifier_node);
1249                   EXPR_WFL_LINECOL (wfl) = $1.location;
1250                   $$ = wfl;
1251                 }
1252 ;
1253
1254 /* 19.9 Productions from 9: Interfaces  */
1255 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1256 interface_declaration:
1257         INTERFACE_TK identifier
1258                 { create_interface (0, $2, NULL_TREE); }
1259         interface_body
1260 |       modifiers INTERFACE_TK identifier
1261                 { create_interface ($1, $3, NULL_TREE); }
1262         interface_body
1263 |       INTERFACE_TK identifier extends_interfaces
1264                 { create_interface (0, $2, $3); }
1265         interface_body
1266 |       modifiers INTERFACE_TK identifier extends_interfaces
1267                 { create_interface ($1, $3, $4); }
1268         interface_body
1269 |       INTERFACE_TK identifier error
1270                 {yyerror ("'{' expected"); RECOVER;}
1271 |       modifiers INTERFACE_TK identifier error
1272                 {yyerror ("'{' expected"); RECOVER;}
1273 ;
1274
1275 extends_interfaces:
1276         EXTENDS_TK interface_type
1277                 { 
1278                   ctxp->interface_number = 1;
1279                   $$ = build_tree_list ($2, NULL_TREE);
1280                 }
1281 |       extends_interfaces C_TK interface_type
1282                 { 
1283                   ctxp->interface_number++;
1284                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1285                 }
1286 |       EXTENDS_TK error
1287                 {yyerror ("Invalid interface type"); RECOVER;}
1288 |       extends_interfaces C_TK error
1289                 {yyerror ("Missing term"); RECOVER;}
1290 ;
1291
1292 interface_body:
1293         OCB_TK CCB_TK
1294                 { $$ = NULL_TREE; }
1295 |       OCB_TK interface_member_declarations CCB_TK
1296                 { $$ = NULL_TREE; }
1297 ;
1298
1299 interface_member_declarations:
1300         interface_member_declaration
1301 |       interface_member_declarations interface_member_declaration
1302 ;
1303
1304 interface_member_declaration:
1305         constant_declaration
1306 |       abstract_method_declaration
1307 |       class_declaration       /* Added, JDK1.1 inner classes */
1308                 { end_class_declaration (1); }
1309 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1310                 { end_class_declaration (1); }
1311 ;
1312
1313 constant_declaration:
1314         field_declaration
1315 ;
1316
1317 abstract_method_declaration:
1318         method_header SC_TK
1319                 { 
1320                   check_abstract_method_header ($1);
1321                   current_function_decl = NULL_TREE; /* FIXME ? */
1322                 }
1323 |       method_header error
1324                 {yyerror ("';' expected"); RECOVER;}
1325 ;
1326
1327 /* 19.10 Productions from 10: Arrays  */
1328 array_initializer:
1329         OCB_TK CCB_TK
1330                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1331 |       OCB_TK variable_initializers CCB_TK
1332                 { $$ = build_new_array_init ($1.location, $2); }
1333 |       OCB_TK variable_initializers C_TK CCB_TK
1334                 { $$ = build_new_array_init ($1.location, $2); }
1335 ;
1336
1337 variable_initializers:
1338         variable_initializer
1339                 { 
1340                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1341                                   $1, NULL_TREE);
1342                 }
1343 |       variable_initializers C_TK variable_initializer
1344                 {
1345                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1346                 }
1347 |       variable_initializers C_TK error
1348                 {yyerror ("Missing term"); RECOVER;}
1349 ;
1350
1351 /* 19.11 Production from 14: Blocks and Statements  */
1352 block:
1353         OCB_TK CCB_TK
1354                 { 
1355                   /* Store the location of the `}' when doing xrefs */
1356                   if (current_function_decl && flag_emit_xref)
1357                     DECL_END_SOURCE_LINE (current_function_decl) = 
1358                       EXPR_WFL_ADD_COL ($2.location, 1);
1359                   $$ = empty_stmt_node; 
1360                 }
1361 |       block_begin block_statements block_end
1362                 { $$ = $3; }
1363 ;
1364
1365 block_begin:
1366         OCB_TK
1367                 { enter_block (); }
1368 ;
1369
1370 block_end:
1371         CCB_TK
1372                 { 
1373                   maybe_absorb_scoping_blocks ();
1374                   /* Store the location of the `}' when doing xrefs */
1375                   if (current_function_decl && flag_emit_xref)
1376                     DECL_END_SOURCE_LINE (current_function_decl) = 
1377                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1378                   $$ = exit_block ();
1379                   if (!BLOCK_SUBBLOCKS ($$))
1380                     BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
1381                 }
1382 ;
1383
1384 block_statements:
1385         block_statement
1386 |       block_statements block_statement
1387 ;
1388
1389 block_statement:
1390         local_variable_declaration_statement
1391 |       statement
1392                 { java_method_add_stmt (current_function_decl, $1); }
1393 |       class_declaration       /* Added, JDK1.1 local classes */
1394                 { 
1395                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1396                   end_class_declaration (1);
1397                 }
1398 ;
1399
1400 local_variable_declaration_statement:
1401         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1402 ;
1403
1404 local_variable_declaration:
1405         type variable_declarators
1406                 { declare_local_variables (0, $1, $2); }
1407 |       final type variable_declarators /* Added, JDK1.1 final locals */
1408                 { declare_local_variables ($1, $2, $3); }
1409 ;
1410
1411 statement:
1412         statement_without_trailing_substatement
1413 |       labeled_statement
1414 |       if_then_statement
1415 |       if_then_else_statement
1416 |       while_statement
1417 |       for_statement
1418                 { $$ = exit_block (); }
1419 ;
1420
1421 statement_nsi:
1422         statement_without_trailing_substatement
1423 |       labeled_statement_nsi
1424 |       if_then_else_statement_nsi
1425 |       while_statement_nsi
1426 |       for_statement_nsi
1427                 { $$ = exit_block (); }
1428 ;
1429
1430 statement_without_trailing_substatement:
1431         block
1432 |       empty_statement
1433 |       expression_statement
1434 |       switch_statement
1435 |       do_statement
1436 |       break_statement
1437 |       continue_statement
1438 |       return_statement
1439 |       synchronized_statement
1440 |       throw_statement
1441 |       try_statement
1442 ;
1443
1444 empty_statement:
1445         SC_TK
1446                 { 
1447                   if (flag_extraneous_semicolon)
1448                     {
1449                       EXPR_WFL_SET_LINECOL (wfl_operator, lineno, -1);
1450                       parse_warning_context (wfl_operator, "An empty declaration is a deprecated feature that should not be used");
1451                     }
1452                   $$ = empty_stmt_node;
1453                 }
1454 ;
1455
1456 label_decl:
1457         identifier REL_CL_TK
1458                 {
1459                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1460                                             EXPR_WFL_NODE ($1));
1461                   pushlevel (2);
1462                   push_labeled_block ($$);
1463                   PUSH_LABELED_BLOCK ($$);
1464                 }
1465 ;
1466
1467 labeled_statement:
1468         label_decl statement
1469                 { $$ = finish_labeled_statement ($1, $2); }
1470 |       identifier error
1471                 {yyerror ("':' expected"); RECOVER;}
1472 ;
1473
1474 labeled_statement_nsi:
1475         label_decl statement_nsi
1476                 { $$ = finish_labeled_statement ($1, $2); }
1477 ;
1478
1479 /* We concentrate here a bunch of error handling rules that we couldn't write
1480    earlier, because expression_statement catches a missing ';'.  */
1481 expression_statement:
1482         statement_expression SC_TK
1483                 {
1484                   /* We have a statement. Generate a WFL around it so
1485                      we can debug it */
1486                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1487                   /* We know we have a statement, so set the debug
1488                      info to be eventually generate here. */
1489                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1490                 }
1491 |       error SC_TK 
1492                 {
1493                   YYNOT_TWICE yyerror ("Invalid expression statement");
1494                   DRECOVER (expr_stmt);
1495                 }
1496 |       error OCB_TK
1497                 {
1498                   YYNOT_TWICE yyerror ("Invalid expression statement");
1499                   DRECOVER (expr_stmt);
1500                 }
1501 |       error CCB_TK
1502                 {
1503                   YYNOT_TWICE yyerror ("Invalid expression statement");
1504                   DRECOVER (expr_stmt);
1505                 }
1506 |       this_or_super OP_TK error
1507                 {yyerror ("')' expected"); RECOVER;}
1508 |       this_or_super OP_TK CP_TK error
1509                 {
1510                   parse_ctor_invocation_error ();
1511                   RECOVER;
1512                 }
1513 |       this_or_super OP_TK argument_list error
1514                 {yyerror ("')' expected"); RECOVER;}
1515 |       this_or_super OP_TK argument_list CP_TK error
1516                 {
1517                   parse_ctor_invocation_error ();
1518                   RECOVER;
1519                 }
1520 |       name DOT_TK SUPER_TK error
1521                 {yyerror ("'(' expected"); RECOVER;}
1522 |       name DOT_TK SUPER_TK OP_TK error
1523                 {yyerror ("')' expected"); RECOVER;}
1524 |       name DOT_TK SUPER_TK OP_TK argument_list error
1525                 {yyerror ("')' expected"); RECOVER;}
1526 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1527                 {yyerror ("';' expected"); RECOVER;}
1528 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1529                 {yyerror ("';' expected"); RECOVER;}
1530 ;
1531
1532 statement_expression: 
1533         assignment
1534 |       pre_increment_expression
1535 |       pre_decrement_expression
1536 |       post_increment_expression
1537 |       post_decrement_expression
1538 |       method_invocation
1539 |       class_instance_creation_expression
1540 ;
1541
1542 if_then_statement:
1543         IF_TK OP_TK expression CP_TK statement
1544                 { 
1545                   $$ = build_if_else_statement ($2.location, $3, 
1546                                                 $5, NULL_TREE);
1547                 }
1548 |       IF_TK error
1549                 {yyerror ("'(' expected"); RECOVER;}
1550 |       IF_TK OP_TK error
1551                 {yyerror ("Missing term"); RECOVER;}
1552 |       IF_TK OP_TK expression error
1553                 {yyerror ("')' expected"); RECOVER;}
1554 ;
1555
1556 if_then_else_statement:
1557         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1558                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1559 ;
1560
1561 if_then_else_statement_nsi:
1562         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1563                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1564 ;
1565
1566 switch_statement:
1567         switch_expression
1568                 {
1569                   enter_block ();
1570                 }
1571         switch_block
1572                 { 
1573                   /* Make into "proper list" of COMPOUND_EXPRs.
1574                      I.e. make the last statment also have its own
1575                      COMPOUND_EXPR. */
1576                   maybe_absorb_scoping_blocks ();
1577                   TREE_OPERAND ($1, 1) = exit_block ();
1578                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1579                 }
1580 ;
1581
1582 switch_expression:
1583         SWITCH_TK OP_TK expression CP_TK
1584                 { 
1585                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1586                   EXPR_WFL_LINECOL ($$) = $2.location;
1587                 }
1588 |       SWITCH_TK error
1589                 {yyerror ("'(' expected"); RECOVER;}
1590 |       SWITCH_TK OP_TK error
1591                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1592 |       SWITCH_TK OP_TK expression CP_TK error
1593                 {yyerror ("'{' expected"); RECOVER;}
1594 ;
1595
1596 /* Default assignment is there to avoid type node on switch_block
1597    node. */
1598
1599 switch_block:
1600         OCB_TK CCB_TK
1601                 { $$ = NULL_TREE; }
1602 |       OCB_TK switch_labels CCB_TK
1603                 { $$ = NULL_TREE; }
1604 |       OCB_TK switch_block_statement_groups CCB_TK
1605                 { $$ = NULL_TREE; }
1606 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1607                 { $$ = NULL_TREE; }
1608 ;
1609
1610 switch_block_statement_groups: 
1611         switch_block_statement_group
1612 |       switch_block_statement_groups switch_block_statement_group
1613 ;
1614
1615 switch_block_statement_group:
1616         switch_labels block_statements
1617 ;
1618
1619 switch_labels:
1620         switch_label
1621 |       switch_labels switch_label
1622 ;
1623
1624 switch_label:
1625         CASE_TK constant_expression REL_CL_TK
1626                 { 
1627                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1628                   EXPR_WFL_LINECOL (lab) = $1.location;
1629                   java_method_add_stmt (current_function_decl, lab);
1630                 }
1631 |       DEFAULT_TK REL_CL_TK
1632                 { 
1633                   tree lab = build (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1634                   EXPR_WFL_LINECOL (lab) = $1.location;
1635                   java_method_add_stmt (current_function_decl, lab);
1636                 }
1637 |       CASE_TK error
1638                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1639 |       CASE_TK constant_expression error
1640                 {yyerror ("':' expected"); RECOVER;}
1641 |       DEFAULT_TK error
1642                 {yyerror ("':' expected"); RECOVER;}
1643 ;
1644
1645 while_expression:
1646         WHILE_TK OP_TK expression CP_TK
1647                 { 
1648                   tree body = build_loop_body ($2.location, $3, 0);
1649                   $$ = build_new_loop (body);
1650                 }
1651 ;
1652
1653 while_statement:
1654         while_expression statement
1655                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1656 |       WHILE_TK error
1657                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1658 |       WHILE_TK OP_TK error
1659                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1660 |       WHILE_TK OP_TK expression error
1661                 {yyerror ("')' expected"); RECOVER;}
1662 ;
1663
1664 while_statement_nsi:
1665         while_expression statement_nsi
1666                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1667 ;
1668
1669 do_statement_begin:
1670         DO_TK
1671                 { 
1672                   tree body = build_loop_body (0, NULL_TREE, 1);
1673                   $$ = build_new_loop (body);
1674                 }
1675         /* Need error handing here. FIXME */
1676 ;
1677
1678 do_statement: 
1679         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1680                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1681 ;
1682
1683 for_statement:
1684         for_begin SC_TK expression SC_TK for_update CP_TK statement
1685                 {
1686                   if (TREE_CODE_CLASS (TREE_CODE ($3)) == 'c')
1687                     $3 = build_wfl_node ($3);
1688                   $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);
1689                 }
1690 |       for_begin SC_TK SC_TK for_update CP_TK statement
1691                 { 
1692                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1693                   /* We have not condition, so we get rid of the EXIT_EXPR */
1694                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1695                     empty_stmt_node;
1696                 }
1697 |       for_begin SC_TK error
1698                 {yyerror ("Invalid control expression"); RECOVER;}
1699 |       for_begin SC_TK expression SC_TK error
1700                 {yyerror ("Invalid update expression"); RECOVER;}
1701 |       for_begin SC_TK SC_TK error
1702                 {yyerror ("Invalid update expression"); RECOVER;}
1703 ;
1704
1705 for_statement_nsi:
1706         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1707                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1708 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1709                 { 
1710                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1711                   /* We have not condition, so we get rid of the EXIT_EXPR */
1712                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1713                     empty_stmt_node;
1714                 }
1715 ;
1716
1717 for_header:
1718         FOR_TK OP_TK
1719                 { 
1720                   /* This scope defined for local variable that may be
1721                      defined within the scope of the for loop */
1722                   enter_block (); 
1723                 }
1724 |       FOR_TK error
1725                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1726 |       FOR_TK OP_TK error
1727                 {yyerror ("Invalid init statement"); RECOVER;}
1728 ;
1729
1730 for_begin:
1731         for_header for_init
1732                 { 
1733                   /* We now declare the loop body. The loop is
1734                      declared as a for loop. */
1735                   tree body = build_loop_body (0, NULL_TREE, 0);
1736                   $$ =  build_new_loop (body);
1737                   FOR_LOOP_P ($$) = 1;
1738                   /* The loop is added to the current block the for
1739                      statement is defined within */
1740                   java_method_add_stmt (current_function_decl, $$);
1741                 }
1742 ;
1743 for_init:                       /* Can be empty */
1744                 { $$ = empty_stmt_node; }
1745 |       statement_expression_list
1746                 { 
1747                   /* Init statement recorded within the previously
1748                      defined block scope */
1749                   $$ = java_method_add_stmt (current_function_decl, $1);
1750                 }
1751 |       local_variable_declaration
1752                 { 
1753                   /* Local variable are recorded within the previously
1754                      defined block scope */
1755                   $$ = NULL_TREE;
1756                 }
1757 |       statement_expression_list error
1758                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1759 ;
1760
1761 for_update:                     /* Can be empty */
1762                 {$$ = empty_stmt_node;}
1763 |       statement_expression_list
1764                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1765 ;
1766
1767 statement_expression_list:
1768         statement_expression
1769                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1770 |       statement_expression_list C_TK statement_expression
1771                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1772 |       statement_expression_list C_TK error
1773                 {yyerror ("Missing term"); RECOVER;}
1774 ;
1775
1776 break_statement:
1777         BREAK_TK SC_TK
1778                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1779 |       BREAK_TK identifier SC_TK
1780                 { $$ = build_bc_statement ($1.location, 1, $2); }
1781 |       BREAK_TK error
1782                 {yyerror ("Missing term"); RECOVER;}
1783 |       BREAK_TK identifier error
1784                 {yyerror ("';' expected"); RECOVER;}
1785 ;
1786
1787 continue_statement:
1788         CONTINUE_TK SC_TK
1789                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1790 |       CONTINUE_TK identifier SC_TK
1791                 { $$ = build_bc_statement ($1.location, 0, $2); }
1792 |       CONTINUE_TK error
1793                 {yyerror ("Missing term"); RECOVER;}
1794 |       CONTINUE_TK identifier error
1795                 {yyerror ("';' expected"); RECOVER;}
1796 ;
1797
1798 return_statement:
1799         RETURN_TK SC_TK
1800                 { $$ = build_return ($1.location, NULL_TREE); }
1801 |       RETURN_TK expression SC_TK
1802                 { $$ = build_return ($1.location, $2); }
1803 |       RETURN_TK error
1804                 {yyerror ("Missing term"); RECOVER;}
1805 |       RETURN_TK expression error
1806                 {yyerror ("';' expected"); RECOVER;}
1807 ;
1808
1809 throw_statement:
1810         THROW_TK expression SC_TK
1811                 { 
1812                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1813                   EXPR_WFL_LINECOL ($$) = $1.location;
1814                 }
1815 |       THROW_TK error
1816                 {yyerror ("Missing term"); RECOVER;}
1817 |       THROW_TK expression error
1818                 {yyerror ("';' expected"); RECOVER;}
1819 ;
1820
1821 synchronized_statement:
1822         synchronized OP_TK expression CP_TK block
1823                 { 
1824                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1825                   EXPR_WFL_LINECOL ($$) = 
1826                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1827                 }
1828 |       synchronized OP_TK expression CP_TK error
1829                 {yyerror ("'{' expected"); RECOVER;}
1830 |       synchronized error
1831                 {yyerror ("'(' expected"); RECOVER;}
1832 |       synchronized OP_TK error CP_TK
1833                 {yyerror ("Missing term"); RECOVER;}
1834 |       synchronized OP_TK error
1835                 {yyerror ("Missing term"); RECOVER;}
1836 ;
1837
1838 synchronized:
1839         modifiers
1840                 {
1841                   check_modifiers (
1842              "Illegal modifier `%s'. Only `synchronized' was expected here",
1843                                    $1, ACC_SYNCHRONIZED);
1844                   if ($1 != ACC_SYNCHRONIZED)
1845                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1846                       build_wfl_node (NULL_TREE);
1847                 }
1848 ;
1849
1850 try_statement:
1851         TRY_TK block catches
1852                 { $$ = build_try_statement ($1.location, $2, $3); }
1853 |       TRY_TK block finally
1854                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1855 |       TRY_TK block catches finally
1856                 { $$ = build_try_finally_statement 
1857                     ($1.location, build_try_statement ($1.location,
1858                                                        $2, $3), $4);
1859                 }
1860 |       TRY_TK error
1861                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1862 ;
1863
1864 catches:
1865         catch_clause
1866 |       catches catch_clause
1867                 { 
1868                   TREE_CHAIN ($2) = $1;
1869                   $$ = $2;
1870                 }
1871 ;
1872
1873 catch_clause:
1874         catch_clause_parameter block
1875                 { 
1876                   java_method_add_stmt (current_function_decl, $2);
1877                   exit_block ();
1878                   $$ = $1;
1879                 }
1880
1881 catch_clause_parameter:
1882         CATCH_TK OP_TK formal_parameter CP_TK
1883                 { 
1884                   /* We add a block to define a scope for
1885                      formal_parameter (CCBP). The formal parameter is
1886                      declared initialized by the appropriate function
1887                      call */
1888                   tree ccpb = enter_block ();
1889                   tree init = build_assignment
1890                     (ASSIGN_TK, $2.location, TREE_PURPOSE ($3), 
1891                      build_exception_object_ref (ptr_type_node));
1892                   declare_local_variables (0, TREE_VALUE ($3),
1893                                            build_tree_list (TREE_PURPOSE ($3),
1894                                                             init));
1895                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1896                   EXPR_WFL_LINECOL ($$) = $1.location;
1897                 }
1898 |       CATCH_TK error
1899                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1900 |       CATCH_TK OP_TK error 
1901                 {
1902                   yyerror ("Missing term or ')' expected"); 
1903                   RECOVER; $$ = NULL_TREE;
1904                 }
1905 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1906                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1907 ;
1908
1909 finally:
1910         FINALLY_TK block
1911                 { $$ = $2; }
1912 |       FINALLY_TK error
1913                 {yyerror ("'{' expected"); RECOVER; }
1914 ;
1915
1916 /* 19.12 Production from 15: Expressions  */
1917 primary:
1918         primary_no_new_array
1919 |       array_creation_expression
1920 ;
1921
1922 primary_no_new_array:
1923         literal
1924 |       THIS_TK
1925                 { $$ = build_this ($1.location); }
1926 |       OP_TK expression CP_TK
1927                 {$$ = $2;}
1928 |       class_instance_creation_expression
1929 |       field_access
1930 |       method_invocation
1931 |       array_access
1932 |       type_literals
1933         /* Added, JDK1.1 inner classes. Documentation is wrong
1934            refering to a 'ClassName' (class_name) rule that doesn't
1935            exist. Used name: instead.  */
1936 |       name DOT_TK THIS_TK
1937                 { 
1938                   tree wfl = build_wfl_node (this_identifier_node);
1939                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1940                 }
1941 |       OP_TK expression error 
1942                 {yyerror ("')' expected"); RECOVER;}
1943 |       name DOT_TK error
1944                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1945 |       primitive_type DOT_TK error
1946                 {yyerror ("'class' expected" ); RECOVER;}
1947 |       VOID_TK DOT_TK error
1948                 {yyerror ("'class' expected" ); RECOVER;}
1949 ;
1950
1951 type_literals:
1952         name DOT_TK CLASS_TK
1953                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1954 |       array_type DOT_TK CLASS_TK
1955                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1956 |       primitive_type DOT_TK CLASS_TK
1957                 { $$ = build_class_ref ($1); }
1958 |       VOID_TK DOT_TK CLASS_TK
1959                 { $$ = build_class_ref (void_type_node); }
1960 ;
1961
1962 class_instance_creation_expression:
1963         NEW_TK class_type OP_TK argument_list CP_TK
1964                 { $$ = build_new_invocation ($2, $4); }
1965 |       NEW_TK class_type OP_TK CP_TK
1966                 { $$ = build_new_invocation ($2, NULL_TREE); }
1967 |       anonymous_class_creation
1968         /* Added, JDK1.1 inner classes, modified to use name or
1969            primary instead of primary solely which couldn't work in
1970            all situations.  */
1971 |       something_dot_new identifier OP_TK CP_TK
1972                 { 
1973                   tree ctor = build_new_invocation ($2, NULL_TREE);
1974                   $$ = make_qualified_primary ($1, ctor, 
1975                                                EXPR_WFL_LINECOL ($1));
1976                 }
1977 |       something_dot_new identifier OP_TK CP_TK class_body
1978 |       something_dot_new identifier OP_TK argument_list CP_TK
1979                 { 
1980                   tree ctor = build_new_invocation ($2, $4);
1981                   $$ = make_qualified_primary ($1, ctor, 
1982                                                EXPR_WFL_LINECOL ($1));
1983                 }
1984 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
1985 |       NEW_TK error SC_TK 
1986                 {yyerror ("'(' expected"); DRECOVER(new_1);}
1987 |       NEW_TK class_type error
1988                 {yyerror ("'(' expected"); RECOVER;}
1989 |       NEW_TK class_type OP_TK error
1990                 {yyerror ("')' or term expected"); RECOVER;}
1991 |       NEW_TK class_type OP_TK argument_list error
1992                 {yyerror ("')' expected"); RECOVER;}
1993 |       something_dot_new error
1994                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1995 |       something_dot_new identifier error
1996                 {yyerror ("'(' expected"); RECOVER;}
1997 ;
1998
1999 /* Created after JDK1.1 rules originally added to
2000    class_instance_creation_expression, but modified to use
2001    'class_type' instead of 'TypeName' (type_name) which is mentionned
2002    in the documentation but doesn't exist. */
2003
2004 anonymous_class_creation:
2005         NEW_TK class_type OP_TK argument_list CP_TK 
2006                 { create_anonymous_class ($1.location, $2); }
2007         class_body
2008                 { 
2009                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2010                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2011
2012                   end_class_declaration (1);
2013
2014                   /* Now we can craft the new expression */
2015                   $$ = build_new_invocation (id, $4);
2016
2017                   /* Note that we can't possibly be here if
2018                      `class_type' is an interface (in which case the
2019                      anonymous class extends Object and implements
2020                      `class_type', hence its constructor can't have
2021                      arguments.) */
2022
2023                   /* Otherwise, the innerclass must feature a
2024                      constructor matching `argument_list'. Anonymous
2025                      classes are a bit special: it's impossible to
2026                      define constructor for them, hence constructors
2027                      must be generated following the hints provided by
2028                      the `new' expression. Whether a super constructor
2029                      of that nature exists or not is to be verified
2030                      later on in verify_constructor_super. 
2031
2032                      It's during the expansion of a `new' statement
2033                      refering to an anonymous class that a ctor will
2034                      be generated for the anonymous class, with the
2035                      right arguments. */
2036
2037                 }
2038 |       NEW_TK class_type OP_TK CP_TK 
2039                 { create_anonymous_class ($1.location, $2); }
2040         class_body         
2041                 { 
2042                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2043                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2044
2045                   end_class_declaration (1);
2046
2047                   /* Now we can craft the new expression. The
2048                      statement doesn't need to be remember so that a
2049                      constructor can be generated, since its signature
2050                      is already known. */
2051                   $$ = build_new_invocation (id, NULL_TREE);
2052                 }
2053 ;
2054
2055 something_dot_new:              /* Added, not part of the specs. */
2056         name DOT_TK NEW_TK
2057                 { $$ = $1; }
2058 |       primary DOT_TK NEW_TK
2059                 { $$ = $1; }
2060 ;
2061
2062 argument_list:
2063         expression
2064                 { 
2065                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2066                   ctxp->formal_parameter_number = 1; 
2067                 }
2068 |       argument_list C_TK expression
2069                 {
2070                   ctxp->formal_parameter_number += 1;
2071                   $$ = tree_cons (NULL_TREE, $3, $1);
2072                 }
2073 |       argument_list C_TK error
2074                 {yyerror ("Missing term"); RECOVER;}
2075 ;
2076
2077 array_creation_expression:
2078         NEW_TK primitive_type dim_exprs
2079                 { $$ = build_newarray_node ($2, $3, 0); }
2080 |       NEW_TK class_or_interface_type dim_exprs
2081                 { $$ = build_newarray_node ($2, $3, 0); }
2082 |       NEW_TK primitive_type dim_exprs dims
2083                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2084 |       NEW_TK class_or_interface_type dim_exprs dims
2085                 { $$ = build_newarray_node ($2, $3, pop_current_osb (ctxp));}
2086         /* Added, JDK1.1 anonymous array. Initial documentation rule
2087            modified */
2088 |       NEW_TK class_or_interface_type dims array_initializer
2089                 {
2090                   char *sig;
2091                   int osb = pop_current_osb (ctxp);
2092                   while (osb--)
2093                     obstack_1grow (&temporary_obstack, '[');
2094                   sig = obstack_finish (&temporary_obstack);
2095                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2096                               $2, get_identifier (sig), $4);
2097                 }
2098 |       NEW_TK primitive_type dims array_initializer
2099                 { 
2100                   int osb = pop_current_osb (ctxp);
2101                   tree type = $2;
2102                   while (osb--)
2103                     type = build_java_array_type (type, -1);
2104                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2105                               build_pointer_type (type), NULL_TREE, $4);
2106                 }
2107 |       NEW_TK error CSB_TK
2108                 {yyerror ("'[' expected"); DRECOVER ("]");}
2109 |       NEW_TK error OSB_TK
2110                 {yyerror ("']' expected"); RECOVER;}
2111 ;
2112
2113 dim_exprs:
2114         dim_expr
2115                 { $$ = build_tree_list (NULL_TREE, $1); }
2116 |       dim_exprs dim_expr
2117                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2118 ;
2119
2120 dim_expr:
2121         OSB_TK expression CSB_TK
2122                 { 
2123                   if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
2124                     {
2125                       $2 = build_wfl_node ($2);
2126                       TREE_TYPE ($2) = NULL_TREE;
2127                     }
2128                   EXPR_WFL_LINECOL ($2) = $1.location;
2129                   $$ = $2;
2130                 }
2131 |       OSB_TK expression error
2132                 {yyerror ("']' expected"); RECOVER;}
2133 |       OSB_TK error
2134                 {
2135                   yyerror ("Missing term");
2136                   yyerror ("']' expected");
2137                   RECOVER;
2138                 }
2139 ;
2140
2141 dims:                           
2142         OSB_TK CSB_TK
2143                 { 
2144                   int allocate = 0;
2145                   /* If not initialized, allocate memory for the osb
2146                      numbers stack */
2147                   if (!ctxp->osb_limit)
2148                     {
2149                       allocate = ctxp->osb_limit = 32;
2150                       ctxp->osb_depth = -1;
2151                     }
2152                   /* If capacity overflown, reallocate a bigger chunk */
2153                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2154                     allocate = ctxp->osb_limit << 1;
2155                   
2156                   if (allocate)
2157                     {
2158                       allocate *= sizeof (int);
2159                       if (ctxp->osb_number)
2160                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2161                                                             allocate);
2162                       else
2163                         ctxp->osb_number = (int *)xmalloc (allocate);
2164                     }
2165                   ctxp->osb_depth++;
2166                   CURRENT_OSB (ctxp) = 1;
2167                 }
2168 |       dims OSB_TK CSB_TK
2169                 { CURRENT_OSB (ctxp)++; }
2170 |       dims OSB_TK error
2171                 { yyerror ("']' expected"); RECOVER;}
2172 ;
2173
2174 field_access:
2175         primary DOT_TK identifier
2176                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2177                 /*  FIXME - REWRITE TO: 
2178                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2179 |       SUPER_TK DOT_TK identifier
2180                 {
2181                   tree super_wfl = build_wfl_node (super_identifier_node);
2182                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2183                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2184                 }
2185 |       SUPER_TK error
2186                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2187 ;
2188
2189 method_invocation:
2190         name OP_TK CP_TK
2191                 { $$ = build_method_invocation ($1, NULL_TREE); }
2192 |       name OP_TK argument_list CP_TK
2193                 { $$ = build_method_invocation ($1, $3); }
2194 |       primary DOT_TK identifier OP_TK CP_TK
2195                 { 
2196                   if (TREE_CODE ($1) == THIS_EXPR)
2197                     $$ = build_this_super_qualified_invocation 
2198                       (1, $3, NULL_TREE, 0, $2.location);
2199                   else
2200                     {
2201                       tree invok = build_method_invocation ($3, NULL_TREE);
2202                       $$ = make_qualified_primary ($1, invok, $2.location);
2203                     }
2204                 }
2205 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2206                 { 
2207                   if (TREE_CODE ($1) == THIS_EXPR)
2208                     $$ = build_this_super_qualified_invocation 
2209                       (1, $3, $5, 0, $2.location);
2210                   else
2211                     {
2212                       tree invok = build_method_invocation ($3, $5);
2213                       $$ = make_qualified_primary ($1, invok, $2.location);
2214                     }
2215                 }
2216 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2217                 { 
2218                   $$ = build_this_super_qualified_invocation 
2219                     (0, $3, NULL_TREE, $1.location, $2.location);
2220                 }
2221 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2222                 {
2223                   $$ = build_this_super_qualified_invocation 
2224                     (0, $3, $5, $1.location, $2.location);
2225                 }
2226         /* Screws up thing. I let it here until I'm convinced it can
2227            be removed. FIXME
2228 |       primary DOT_TK error
2229                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2230 |       SUPER_TK DOT_TK error CP_TK
2231                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2232 |       SUPER_TK DOT_TK error DOT_TK
2233                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2234 ;
2235
2236 array_access:
2237         name OSB_TK expression CSB_TK
2238                 { $$ = build_array_ref ($2.location, $1, $3); }
2239 |       primary_no_new_array OSB_TK expression CSB_TK
2240                 { $$ = build_array_ref ($2.location, $1, $3); }
2241 |       name OSB_TK error
2242                 {
2243                   yyerror ("Missing term and ']' expected");
2244                   DRECOVER(array_access);
2245                 }
2246 |       name OSB_TK expression error
2247                 {
2248                   yyerror ("']' expected");
2249                   DRECOVER(array_access);
2250                 }
2251 |       primary_no_new_array OSB_TK error
2252                 {
2253                   yyerror ("Missing term and ']' expected");
2254                   DRECOVER(array_access);
2255                 }
2256 |       primary_no_new_array OSB_TK expression error
2257                 {
2258                   yyerror ("']' expected");
2259                   DRECOVER(array_access);
2260                 }
2261 ;
2262
2263 postfix_expression:
2264         primary
2265 |       name
2266 |       post_increment_expression
2267 |       post_decrement_expression
2268 ;
2269
2270 post_increment_expression:
2271         postfix_expression INCR_TK
2272                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2273 ;
2274
2275 post_decrement_expression:
2276         postfix_expression DECR_TK
2277                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2278 ;
2279
2280 unary_expression:
2281         pre_increment_expression
2282 |       pre_decrement_expression
2283 |       PLUS_TK unary_expression
2284                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2285 |       MINUS_TK unary_expression
2286                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2287 |       unary_expression_not_plus_minus
2288 |       PLUS_TK error
2289                 {yyerror ("Missing term"); RECOVER}
2290 |       MINUS_TK error
2291                 {yyerror ("Missing term"); RECOVER}
2292 ;
2293
2294 pre_increment_expression:
2295         INCR_TK unary_expression
2296                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2297 |       INCR_TK error
2298                 {yyerror ("Missing term"); RECOVER}
2299 ;
2300
2301 pre_decrement_expression:
2302         DECR_TK unary_expression
2303                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2304 |       DECR_TK error
2305                 {yyerror ("Missing term"); RECOVER}
2306 ;
2307
2308 unary_expression_not_plus_minus:
2309         postfix_expression
2310 |       NOT_TK unary_expression
2311                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2312 |       NEG_TK unary_expression
2313                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2314 |       cast_expression
2315 |       NOT_TK error
2316                 {yyerror ("Missing term"); RECOVER}
2317 |       NEG_TK error
2318                 {yyerror ("Missing term"); RECOVER}
2319 ;
2320
2321 cast_expression:                /* Error handling here is potentially weak */
2322         OP_TK primitive_type dims CP_TK unary_expression
2323                 { 
2324                   tree type = $2;
2325                   int osb = pop_current_osb (ctxp);
2326                   while (osb--)
2327                     type = build_java_array_type (type, -1);
2328                   $$ = build_cast ($1.location, type, $5); 
2329                 }
2330 |       OP_TK primitive_type CP_TK unary_expression
2331                 { $$ = build_cast ($1.location, $2, $4); }
2332 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2333                 { $$ = build_cast ($1.location, $2, $4); }
2334 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2335                 { 
2336                   const char *ptr;
2337                   int osb = pop_current_osb (ctxp); 
2338                   while (osb--)
2339                     obstack_1grow (&temporary_obstack, '[');
2340                   obstack_grow0 (&temporary_obstack, 
2341                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2342                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2343                   ptr = obstack_finish (&temporary_obstack);
2344                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2345                   $$ = build_cast ($1.location, $2, $5);
2346                 }
2347 |       OP_TK primitive_type OSB_TK error
2348                 {yyerror ("']' expected, invalid type expression");}
2349 |       OP_TK error
2350                 {
2351                   YYNOT_TWICE yyerror ("Invalid type expression"); RECOVER;
2352                   RECOVER;
2353                 }
2354 |       OP_TK primitive_type dims CP_TK error
2355                 {yyerror ("Missing term"); RECOVER;}
2356 |       OP_TK primitive_type CP_TK error
2357                 {yyerror ("Missing term"); RECOVER;}
2358 |       OP_TK name dims CP_TK error
2359                 {yyerror ("Missing term"); RECOVER;}
2360 ;
2361
2362 multiplicative_expression:
2363         unary_expression
2364 |       multiplicative_expression MULT_TK unary_expression
2365                 { 
2366                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2367                                     $2.location, $1, $3);
2368                 }
2369 |       multiplicative_expression DIV_TK unary_expression
2370                 {
2371                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2372                                     $1, $3); 
2373                 }
2374 |       multiplicative_expression REM_TK unary_expression
2375                 {
2376                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2377                                     $1, $3); 
2378                 }
2379 |       multiplicative_expression MULT_TK error
2380                 {yyerror ("Missing term"); RECOVER;}
2381 |       multiplicative_expression DIV_TK error
2382                 {yyerror ("Missing term"); RECOVER;}
2383 |       multiplicative_expression REM_TK error
2384                 {yyerror ("Missing term"); RECOVER;}
2385 ;
2386
2387 additive_expression:
2388         multiplicative_expression
2389 |       additive_expression PLUS_TK multiplicative_expression
2390                 {
2391                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2392                                     $1, $3); 
2393                 }
2394 |       additive_expression MINUS_TK multiplicative_expression
2395                 {
2396                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2397                                     $1, $3); 
2398                 }
2399 |       additive_expression PLUS_TK error
2400                 {yyerror ("Missing term"); RECOVER;}
2401 |       additive_expression MINUS_TK error
2402                 {yyerror ("Missing term"); RECOVER;}
2403 ;
2404
2405 shift_expression:
2406         additive_expression
2407 |       shift_expression LS_TK additive_expression
2408                 {
2409                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2410                                     $1, $3); 
2411                 }
2412 |       shift_expression SRS_TK additive_expression
2413                 {
2414                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2415                                     $1, $3); 
2416                 }
2417 |       shift_expression ZRS_TK additive_expression
2418                 {
2419                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2420                                     $1, $3); 
2421                 }
2422 |       shift_expression LS_TK error
2423                 {yyerror ("Missing term"); RECOVER;}
2424 |       shift_expression SRS_TK error
2425                 {yyerror ("Missing term"); RECOVER;}
2426 |       shift_expression ZRS_TK error
2427                 {yyerror ("Missing term"); RECOVER;}
2428 ;
2429
2430 relational_expression:
2431         shift_expression
2432 |       relational_expression LT_TK shift_expression
2433                 {
2434                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2435                                     $1, $3); 
2436                 }
2437 |       relational_expression GT_TK shift_expression
2438                 {
2439                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2440                                     $1, $3); 
2441                 }
2442 |       relational_expression LTE_TK shift_expression
2443                 {
2444                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2445                                     $1, $3); 
2446                 }
2447 |       relational_expression GTE_TK shift_expression
2448                 {
2449                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2450                                     $1, $3); 
2451                 }
2452 |       relational_expression INSTANCEOF_TK reference_type
2453                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2454 |       relational_expression LT_TK error
2455                 {yyerror ("Missing term"); RECOVER;}
2456 |       relational_expression GT_TK error
2457                 {yyerror ("Missing term"); RECOVER;}
2458 |       relational_expression LTE_TK error
2459                 {yyerror ("Missing term"); RECOVER;}
2460 |       relational_expression GTE_TK error
2461                 {yyerror ("Missing term"); RECOVER;}
2462 |       relational_expression INSTANCEOF_TK error
2463                 {yyerror ("Invalid reference type"); RECOVER;}
2464 ;
2465
2466 equality_expression:
2467         relational_expression
2468 |       equality_expression EQ_TK relational_expression
2469                 {
2470                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2471                                     $1, $3); 
2472                 }
2473 |       equality_expression NEQ_TK relational_expression
2474                 {
2475                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2476                                     $1, $3); 
2477                 }
2478 |       equality_expression EQ_TK error
2479                 {yyerror ("Missing term"); RECOVER;}
2480 |       equality_expression NEQ_TK error
2481                 {yyerror ("Missing term"); RECOVER;}
2482 ;
2483
2484 and_expression:
2485         equality_expression
2486 |       and_expression AND_TK equality_expression
2487                 {
2488                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2489                                     $1, $3); 
2490                 }
2491 |       and_expression AND_TK error
2492                 {yyerror ("Missing term"); RECOVER;}
2493 ;
2494
2495 exclusive_or_expression:
2496         and_expression
2497 |       exclusive_or_expression XOR_TK and_expression
2498                 {
2499                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2500                                     $1, $3); 
2501                 }
2502 |       exclusive_or_expression XOR_TK error
2503                 {yyerror ("Missing term"); RECOVER;}
2504 ;
2505
2506 inclusive_or_expression:
2507         exclusive_or_expression
2508 |       inclusive_or_expression OR_TK exclusive_or_expression
2509                 {
2510                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2511                                     $1, $3); 
2512                 }
2513 |       inclusive_or_expression OR_TK error
2514                 {yyerror ("Missing term"); RECOVER;}
2515 ;
2516
2517 conditional_and_expression:
2518         inclusive_or_expression
2519 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2520                 {
2521                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2522                                     $1, $3); 
2523                 }
2524 |       conditional_and_expression BOOL_AND_TK error
2525                 {yyerror ("Missing term"); RECOVER;}
2526 ;
2527
2528 conditional_or_expression:
2529         conditional_and_expression
2530 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2531                 {
2532                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2533                                     $1, $3); 
2534                 }
2535 |       conditional_or_expression BOOL_OR_TK error
2536                 {yyerror ("Missing term"); RECOVER;}
2537 ;
2538
2539 conditional_expression:         /* Error handling here is weak */
2540         conditional_or_expression
2541 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2542                 {
2543                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2544                   EXPR_WFL_LINECOL ($$) = $2.location;
2545                 }
2546 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2547                 {
2548                   YYERROR_NOW;
2549                   yyerror ("Missing term");
2550                   DRECOVER (1);
2551                 }
2552 |       conditional_or_expression REL_QM_TK error
2553                 {yyerror ("Missing term"); DRECOVER (2);}
2554 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2555                 {yyerror ("Missing term"); DRECOVER (3);}
2556 ;
2557
2558 assignment_expression:
2559         conditional_expression
2560 |       assignment
2561 ;
2562
2563 assignment:
2564         left_hand_side assignment_operator assignment_expression
2565                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2566 |       left_hand_side assignment_operator error
2567                 {
2568                   YYNOT_TWICE yyerror ("Missing term");
2569                   DRECOVER (assign);
2570                 }
2571 ;
2572
2573 left_hand_side:
2574         name
2575 |       field_access
2576 |       array_access
2577 ;
2578
2579 assignment_operator:
2580         ASSIGN_ANY_TK
2581 |       ASSIGN_TK
2582 ;
2583
2584 expression:
2585         assignment_expression
2586 ;
2587
2588 constant_expression:
2589         expression
2590 ;
2591
2592 %%
2593
2594 /* Helper function to retrieve an OSB count. Should be used when the
2595    `dims:' rule is being used.  */
2596
2597 static int
2598 pop_current_osb (ctxp)
2599      struct parser_ctxt *ctxp;
2600 {
2601   int to_return;
2602
2603   if (ctxp->osb_depth < 0)
2604     abort ();
2605   
2606   to_return = CURRENT_OSB (ctxp);
2607   ctxp->osb_depth--;
2608   
2609   return to_return;
2610 }
2611
2612 \f
2613
2614 /* This section of the code deal with save/restoring parser contexts.
2615    Add mode documentation here. FIXME */
2616
2617 /* Helper function. Create a new parser context. With
2618    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2619    context is copied, otherwise, the new context is zeroed. The newly
2620    created context becomes the current one.  */
2621
2622 static void
2623 create_new_parser_context (copy_from_previous)
2624     int copy_from_previous;
2625 {
2626   struct parser_ctxt *new;
2627
2628   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2629   if (copy_from_previous)
2630     {
2631       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2632       new->saved_data_ctx = 1;
2633     }
2634   else
2635     memset ((PTR) new, 0, sizeof (struct parser_ctxt));
2636       
2637   new->next = ctxp;
2638   ctxp = new;
2639 }
2640
2641 /* Create a new parser context and make it the current one. */
2642
2643 void
2644 java_push_parser_context ()
2645 {
2646   create_new_parser_context (0);
2647 }  
2648
2649 void 
2650 java_pop_parser_context (generate)
2651      int generate;
2652 {
2653   tree current;
2654   struct parser_ctxt *toFree, *next;
2655
2656   if (!ctxp)
2657     return;
2658
2659   toFree = ctxp;
2660   next = ctxp->next;
2661   if (next)
2662     {
2663       lineno = ctxp->lineno;
2664       current_class = ctxp->class_type;
2665     }
2666
2667   /* If the old and new lexers differ, then free the old one.  */
2668   if (ctxp->lexer && next && ctxp->lexer != next->lexer)
2669     java_destroy_lexer (ctxp->lexer);
2670
2671   /* Set the single import class file flag to 0 for the current list
2672      of imported things */
2673   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2674     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 0;
2675
2676   /* And restore those of the previous context */
2677   if ((ctxp = next))            /* Assignment is really meant here */
2678     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2679       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1;
2680   
2681   /* If we pushed a context to parse a class intended to be generated,
2682      we keep it so we can remember the class. What we could actually
2683      do is to just update a list of class names.  */
2684   if (generate)
2685     {
2686       toFree->next = ctxp_for_generation;
2687       ctxp_for_generation = toFree;
2688     }
2689   else
2690     free (toFree);
2691 }
2692
2693 /* Create a parser context for the use of saving some global
2694    variables.  */
2695
2696 void
2697 java_parser_context_save_global ()
2698 {
2699   if (!ctxp)
2700     {
2701       java_push_parser_context ();
2702       ctxp->saved_data_ctx = 1;
2703     }
2704
2705   /* If this context already stores data, create a new one suitable
2706      for data storage. */
2707   else if (ctxp->saved_data)
2708     create_new_parser_context (1);
2709
2710   ctxp->lineno = lineno;
2711   ctxp->class_type = current_class;
2712   ctxp->filename = input_filename;
2713   ctxp->function_decl = current_function_decl;
2714   ctxp->saved_data = 1;
2715 }
2716
2717 /* Restore some global variables from the previous context. Make the
2718    previous context the current one.  */
2719
2720 void
2721 java_parser_context_restore_global ()
2722 {
2723   lineno = ctxp->lineno;
2724   current_class = ctxp->class_type;
2725   input_filename = ctxp->filename;
2726   if (wfl_operator)
2727     {
2728       tree s;
2729       BUILD_FILENAME_IDENTIFIER_NODE (s, input_filename);
2730       EXPR_WFL_FILENAME_NODE (wfl_operator) = s;
2731     }
2732   current_function_decl = ctxp->function_decl;
2733   ctxp->saved_data = 0;
2734   if (ctxp->saved_data_ctx)
2735     java_pop_parser_context (0);
2736 }
2737
2738 /* Suspend vital data for the current class/function being parsed so
2739    that an other class can be parsed. Used to let local/anonymous
2740    classes be parsed.  */
2741
2742 static void
2743 java_parser_context_suspend ()
2744 {
2745   /* This makes debugging through java_debug_context easier */
2746   static const char *name = "<inner buffer context>";
2747
2748   /* Duplicate the previous context, use it to save the globals we're
2749      interested in */
2750   create_new_parser_context (1);
2751   ctxp->function_decl = current_function_decl;
2752   ctxp->class_type = current_class;
2753
2754   /* Then create a new context which inherits all data from the
2755      previous one. This will be the new current context  */
2756   create_new_parser_context (1);
2757
2758   /* Help debugging */
2759   ctxp->next->filename = name;
2760 }
2761
2762 /* Resume vital data for the current class/function being parsed so
2763    that an other class can be parsed. Used to let local/anonymous
2764    classes be parsed.  The trick is the data storing file position
2765    informations must be restored to their current value, so parsing
2766    can resume as if no context was ever saved. */
2767
2768 static void
2769 java_parser_context_resume ()
2770 {
2771   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2772   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2773   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2774
2775   /* We need to inherit the list of classes to complete/generate */
2776   restored->classd_list = old->classd_list;
2777   restored->class_list = old->class_list;
2778
2779   /* Restore the current class and function from the saver */
2780   current_class = saver->class_type;
2781   current_function_decl = saver->function_decl;
2782
2783   /* Retrive the restored context */
2784   ctxp = restored;
2785
2786   /* Re-installed the data for the parsing to carry on */
2787   memcpy (&ctxp->marker_begining, &old->marker_begining, 
2788           (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2789
2790   /* Buffer context can now be discarded */
2791   free (saver);
2792   free (old);
2793 }
2794
2795 /* Add a new anchor node to which all statement(s) initializing static
2796    and non static initialized upon declaration field(s) will be
2797    linked.  */
2798
2799 static void
2800 java_parser_context_push_initialized_field ()
2801 {
2802   tree node;
2803
2804   node = build_tree_list (NULL_TREE, NULL_TREE);
2805   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2806   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2807
2808   node = build_tree_list (NULL_TREE, NULL_TREE);
2809   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2810   CPC_INITIALIZER_LIST (ctxp) = node;
2811
2812   node = build_tree_list (NULL_TREE, NULL_TREE);
2813   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2814   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2815 }
2816
2817 /* Pop the lists of initialized field. If this lists aren't empty,
2818    remember them so we can use it to create and populate the finit$
2819    or <clinit> functions. */
2820
2821 static void
2822 java_parser_context_pop_initialized_field ()
2823 {
2824   tree stmts;
2825   tree class_type = TREE_TYPE (GET_CPC ());
2826
2827   if (CPC_INITIALIZER_LIST (ctxp))
2828     {
2829       stmts = CPC_INITIALIZER_STMT (ctxp);
2830       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2831       if (stmts && !java_error_count)
2832         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2833     }
2834
2835   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2836     {
2837       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2838       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2839         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2840       /* Keep initialization in order to enforce 8.5 */
2841       if (stmts && !java_error_count)
2842         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2843     }
2844
2845   /* JDK 1.1 instance initializers */
2846   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2847     {
2848       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2849       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2850         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2851       if (stmts && !java_error_count)
2852         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2853     }
2854 }
2855
2856 static tree
2857 reorder_static_initialized (list)
2858      tree list;
2859 {
2860   /* We have to keep things in order. The alias initializer have to
2861      come first, then the initialized regular field, in reverse to
2862      keep them in lexical order. */
2863   tree marker, previous = NULL_TREE;
2864   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2865     if (TREE_CODE (marker) == TREE_LIST 
2866         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2867       break;
2868   
2869   /* No static initialized, the list is fine as is */
2870   if (!previous)
2871     list = TREE_CHAIN (marker);
2872
2873   /* No marker? reverse the whole list */
2874   else if (!marker)
2875     list = nreverse (list);
2876
2877   /* Otherwise, reverse what's after the marker and the new reordered
2878      sublist will replace the marker. */
2879   else
2880     {
2881       TREE_CHAIN (previous) = NULL_TREE;
2882       list = nreverse (list);
2883       list = chainon (TREE_CHAIN (marker), list);
2884     }
2885   return list;
2886 }
2887
2888 /* Helper functions to dump the parser context stack.  */
2889
2890 #define TAB_CONTEXT(C) \
2891   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2892
2893 static void
2894 java_debug_context_do (tab)
2895      int tab;
2896 {
2897   struct parser_ctxt *copy = ctxp;
2898   while (copy)
2899     {
2900       TAB_CONTEXT (tab);
2901       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2902       TAB_CONTEXT (tab);
2903       fprintf (stderr, "filename: %s\n", copy->filename);
2904       TAB_CONTEXT (tab);
2905       fprintf (stderr, "lineno: %d\n", copy->lineno);
2906       TAB_CONTEXT (tab);
2907       fprintf (stderr, "package: %s\n",
2908                (copy->package ? 
2909                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2910       TAB_CONTEXT (tab);
2911       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2912       TAB_CONTEXT (tab);
2913       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2914       copy = copy->next;
2915       tab += 2;
2916     }
2917 }
2918
2919 /* Dump the stacked up parser contexts. Intended to be called from a
2920    debugger.  */
2921
2922 void
2923 java_debug_context ()
2924 {
2925   java_debug_context_do (0);
2926 }
2927
2928 \f
2929
2930 /* Flag for the error report routine to issue the error the first time
2931    it's called (overriding the default behavior which is to drop the
2932    first invocation and honor the second one, taking advantage of a
2933    richer context.  */
2934 static int force_error = 0;
2935
2936 /* Reporting an constructor invocation error.  */
2937 static void
2938 parse_ctor_invocation_error ()
2939 {
2940   if (DECL_CONSTRUCTOR_P (current_function_decl))
2941     yyerror ("Constructor invocation must be first thing in a constructor"); 
2942   else
2943     yyerror ("Only constructors can invoke constructors");
2944 }
2945
2946 /* Reporting JDK1.1 features not implemented.  */
2947
2948 static tree
2949 parse_jdk1_1_error (msg)
2950     const char *msg;
2951 {
2952   sorry (": `%s' JDK1.1(TM) feature", msg);
2953   java_error_count++;
2954   return empty_stmt_node;
2955 }
2956
2957 static int do_warning = 0;
2958
2959 void
2960 yyerror (msg)
2961      const char *msg;
2962 {
2963   static java_lc elc;
2964   static int  prev_lineno;
2965   static const char *prev_msg;
2966
2967   int save_lineno;
2968   char *remainder, *code_from_source;
2969   
2970   if (!force_error && prev_lineno == lineno)
2971     return;
2972
2973   /* Save current error location but report latter, when the context is
2974      richer.  */
2975   if (ctxp->java_error_flag == 0)
2976     {
2977       ctxp->java_error_flag = 1;
2978       elc = ctxp->elc;
2979       /* Do something to use the previous line if we're reaching the
2980          end of the file... */
2981 #ifdef VERBOSE_SKELETON
2982       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2983 #endif
2984       return;
2985     }
2986
2987   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2988   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2989     return;
2990
2991   ctxp->java_error_flag = 0;
2992   if (do_warning)
2993     java_warning_count++;
2994   else
2995     java_error_count++;
2996   
2997   if (elc.col == 0 && msg && msg[1] == ';')
2998     {
2999       elc.col  = ctxp->p_line->char_col-1;
3000       elc.line = ctxp->p_line->lineno;
3001     }
3002
3003   save_lineno = lineno;
3004   prev_lineno = lineno = elc.line;
3005   prev_msg = msg;
3006
3007   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
3008   obstack_grow0 (&temporary_obstack, 
3009                  code_from_source, strlen (code_from_source));
3010   remainder = obstack_finish (&temporary_obstack);
3011   if (do_warning)
3012     warning ("%s.\n%s", msg, remainder);
3013   else
3014     error ("%s.\n%s", msg, remainder);
3015
3016   /* This allow us to cheaply avoid an extra 'Invalid expression
3017      statement' error report when errors have been already reported on
3018      the same line. This occurs when we report an error but don't have
3019      a synchronization point other than ';', which
3020      expression_statement is the only one to take care of.  */
3021   ctxp->prevent_ese = lineno = save_lineno;
3022 }
3023
3024 static void
3025 issue_warning_error_from_context (cl, msg, ap)
3026      tree cl;
3027      const char *msg;
3028      va_list ap;
3029 {
3030   const char *saved, *saved_input_filename;
3031   char buffer [4096];
3032   vsprintf (buffer, msg, ap);
3033   force_error = 1;
3034
3035   ctxp->elc.line = EXPR_WFL_LINENO (cl);
3036   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
3037                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
3038
3039   /* We have a CL, that's a good reason for using it if it contains data */
3040   saved = ctxp->filename;
3041   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
3042     ctxp->filename = EXPR_WFL_FILENAME (cl);
3043   saved_input_filename = input_filename;
3044   input_filename = ctxp->filename;
3045   java_error (NULL);
3046   java_error (buffer);
3047   ctxp->filename = saved;
3048   input_filename = saved_input_filename;
3049   force_error = 0;
3050 }
3051
3052 /* Issue an error message at a current source line CL */
3053
3054 void
3055 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
3056 {
3057 #ifndef ANSI_PROTOTYPES
3058   tree cl;
3059   const char *msg;
3060 #endif
3061   va_list ap;
3062
3063   VA_START (ap, msg);
3064 #ifndef ANSI_PROTOTYPES
3065   cl = va_arg (ap, tree);
3066   msg = va_arg (ap, const char *);
3067 #endif
3068   issue_warning_error_from_context (cl, msg, ap);
3069   va_end (ap);
3070 }
3071
3072 /* Issue a warning at a current source line CL */
3073
3074 static void
3075 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3076 {
3077 #ifndef ANSI_PROTOTYPES
3078   tree cl;
3079   const char *msg;
3080 #endif
3081   va_list ap;
3082
3083   VA_START (ap, msg);
3084 #ifndef ANSI_PROTOTYPES
3085   cl = va_arg (ap, tree);
3086   msg = va_arg (ap, const char *);
3087 #endif
3088
3089   force_error = do_warning = 1;
3090   issue_warning_error_from_context (cl, msg, ap);
3091   do_warning = force_error = 0;
3092   va_end (ap);
3093 }
3094
3095 static tree
3096 find_expr_with_wfl (node)
3097      tree node;
3098 {
3099   while (node)
3100     {
3101       char code;
3102       tree to_return;
3103
3104       switch (TREE_CODE (node))
3105         {
3106         case BLOCK:
3107           node = BLOCK_EXPR_BODY (node);
3108           continue;
3109
3110         case COMPOUND_EXPR:
3111           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3112           if (to_return)
3113             return to_return;
3114           node = TREE_OPERAND (node, 1);
3115           continue;
3116
3117         case LOOP_EXPR:
3118           node = TREE_OPERAND (node, 0);
3119           continue;
3120           
3121         case LABELED_BLOCK_EXPR:
3122           node = TREE_OPERAND (node, 1);
3123           continue;
3124
3125         default:
3126           code = TREE_CODE_CLASS (TREE_CODE (node));
3127           if (((code == '1') || (code == '2') || (code == 'e'))
3128               && EXPR_WFL_LINECOL (node))
3129             return node;
3130           return NULL_TREE;
3131         }
3132     }
3133   return NULL_TREE;
3134 }
3135
3136 /* Issue a missing return statement error. Uses METHOD to figure the
3137    last line of the method the error occurs in.  */
3138
3139 static void
3140 missing_return_error (method)
3141      tree method;
3142 {
3143   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3144   parse_error_context (wfl_operator, "Missing return statement");
3145 }
3146
3147 /* Issue an unreachable statement error. From NODE, find the next
3148    statement to report appropriately.  */
3149 static void
3150 unreachable_stmt_error (node)
3151      tree node;
3152 {
3153   /* Browse node to find the next expression node that has a WFL. Use
3154      the location to report the error */
3155   if (TREE_CODE (node) == COMPOUND_EXPR)
3156     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3157   else
3158     node = find_expr_with_wfl (node);
3159
3160   if (node)
3161     {
3162       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3163       parse_error_context (wfl_operator, "Unreachable statement");
3164     }
3165   else
3166     abort ();
3167 }
3168
3169 int
3170 java_report_errors ()
3171 {
3172   if (java_error_count)
3173     fprintf (stderr, "%d error%s", 
3174              java_error_count, (java_error_count == 1 ? "" : "s"));
3175   if (java_warning_count)
3176     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3177              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3178   if (java_error_count || java_warning_count)
3179     putc ('\n', stderr);
3180   return java_error_count;
3181 }
3182
3183 static char *
3184 java_accstring_lookup (flags)
3185      int flags;
3186 {
3187   static char buffer [80];
3188 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3189
3190   /* Access modifier looked-up first for easier report on forbidden
3191      access. */
3192   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3193   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3194   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3195   if (flags & ACC_STATIC) COPY_RETURN ("static");
3196   if (flags & ACC_FINAL) COPY_RETURN ("final");
3197   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3198   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3199   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3200   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3201   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3202   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3203
3204   buffer [0] = '\0';
3205   return buffer;
3206 #undef COPY_RETURN
3207 }
3208
3209 /* Issuing error messages upon redefinition of classes, interfaces or
3210    variables. */
3211
3212 static void
3213 classitf_redefinition_error (context, id, decl, cl)
3214      const char *context;
3215      tree id, decl, cl;
3216 {
3217   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3218                        context, IDENTIFIER_POINTER (id), 
3219                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3220   /* Here we should point out where its redefined. It's a unicode. FIXME */
3221 }
3222
3223 static void
3224 variable_redefinition_error (context, name, type, line)
3225      tree context, name, type;
3226      int line;
3227 {
3228   const char *type_name;
3229
3230   /* Figure a proper name for type. We might haven't resolved it */
3231   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3232     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3233   else
3234     type_name = lang_printable_name (type, 0);
3235
3236   parse_error_context (context,
3237                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3238                        IDENTIFIER_POINTER (name),
3239                        type_name, IDENTIFIER_POINTER (name), line);
3240 }
3241
3242 static tree
3243 build_array_from_name (type, type_wfl, name, ret_name)
3244      tree type, type_wfl, name, *ret_name;
3245 {
3246   int more_dims = 0;
3247   const char *string;
3248
3249   /* Eventually get more dims */
3250   string = IDENTIFIER_POINTER (name);
3251   while (string [more_dims] == '[')
3252     more_dims++;
3253   
3254   /* If we have, then craft a new type for this variable */
3255   if (more_dims)
3256     {
3257       tree save = type;
3258
3259       name = get_identifier (&string [more_dims]);
3260
3261       /* If we have a pointer, use its type */
3262       if (TREE_CODE (type) == POINTER_TYPE)
3263         type = TREE_TYPE (type);
3264
3265       /* Building the first dimension of a primitive type uses this
3266          function */
3267       if (JPRIMITIVE_TYPE_P (type))
3268         {
3269           type = build_java_array_type (type, -1);
3270           more_dims--;
3271         }
3272       /* Otherwise, if we have a WFL for this type, use it (the type
3273          is already an array on an unresolved type, and we just keep
3274          on adding dimensions) */
3275       else if (type_wfl)
3276         {
3277           int i = 0;
3278           type = type_wfl;
3279           string = IDENTIFIER_POINTER (TYPE_NAME (save));
3280           while (string[i]  == '[')
3281             ++i;
3282           more_dims += i;
3283         }
3284
3285       /* Add all the dimensions */
3286       while (more_dims--)
3287         type = build_unresolved_array_type (type);
3288
3289       /* The type may have been incomplete in the first place */
3290       if (type_wfl)
3291         type = obtain_incomplete_type (type);
3292     }
3293
3294   if (ret_name)
3295     *ret_name = name;
3296   return type;
3297 }
3298
3299 /* Build something that the type identifier resolver will identify as
3300    being an array to an unresolved type. TYPE_WFL is a WFL on a
3301    identifier. */
3302
3303 static tree
3304 build_unresolved_array_type (type_or_wfl)
3305      tree type_or_wfl;
3306 {
3307   const char *ptr;
3308
3309   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3310      just create a array type */
3311   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3312     return build_java_array_type (type_or_wfl, -1);
3313
3314   obstack_1grow (&temporary_obstack, '[');
3315   obstack_grow0 (&temporary_obstack,
3316                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3317                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3318   ptr = obstack_finish (&temporary_obstack);
3319   return build_expr_wfl (get_identifier (ptr),
3320                          EXPR_WFL_FILENAME (type_or_wfl),
3321                          EXPR_WFL_LINENO (type_or_wfl),
3322                          EXPR_WFL_COLNO (type_or_wfl));
3323 }
3324
3325 static void
3326 parser_add_interface (class_decl, interface_decl, wfl)
3327      tree class_decl, interface_decl, wfl;
3328 {
3329   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3330     parse_error_context (wfl, "Interface `%s' repeated",
3331                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3332 }
3333
3334 /* Bulk of common class/interface checks. Return 1 if an error was
3335    encountered. TAG is 0 for a class, 1 for an interface.  */
3336
3337 static int
3338 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3339      int is_interface, flags;
3340      tree raw_name, qualified_name, decl, cl;
3341 {
3342   tree node;
3343   int sca = 0;                  /* Static class allowed */
3344   int icaf = 0;                 /* Inner class allowed flags */
3345   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3346
3347   if (!quiet_flag)
3348     fprintf (stderr, " %s%s %s", 
3349              (CPC_INNER_P () ? "inner" : ""),
3350              (is_interface ? "interface" : "class"), 
3351              IDENTIFIER_POINTER (qualified_name));
3352
3353   /* Scope of an interface/class type name:
3354        - Can't be imported by a single type import
3355        - Can't already exists in the package */
3356   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3357       && (node = find_name_in_single_imports (raw_name))
3358       && !CPC_INNER_P ())
3359     {
3360       parse_error_context 
3361         (cl, "%s name `%s' clashes with imported type `%s'",
3362          (is_interface ? "Interface" : "Class"),
3363          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3364       return 1;
3365     }
3366   if (decl && CLASS_COMPLETE_P (decl))
3367     {
3368       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3369                                    qualified_name, decl, cl);
3370       return 1;
3371     }
3372
3373   if (check_inner_class_redefinition (raw_name, cl))
3374     return 1;
3375
3376   /* If public, file name should match class/interface name, except
3377      when dealing with an inner class */
3378   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3379     {
3380       const char *f;
3381
3382       /* Contains OS dependent assumption on path separator. FIXME */
3383       for (f = &input_filename [strlen (input_filename)]; 
3384            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3385            f--)
3386         ;
3387       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3388         f++;
3389       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3390                    f , IDENTIFIER_LENGTH (raw_name)) ||
3391           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3392         parse_error_context
3393           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3394                              (is_interface ? "interface" : "class"),
3395                              IDENTIFIER_POINTER (qualified_name),
3396                              IDENTIFIER_POINTER (raw_name));
3397     }
3398
3399   /* Static classes can be declared only in top level classes. Note:
3400      once static, a inner class is a top level class. */
3401   if (flags & ACC_STATIC)
3402     {
3403       /* Catch the specific error of declaring an class inner class
3404          with no toplevel enclosing class. Prevent check_modifiers from
3405          complaining a second time */
3406       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3407         {
3408           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3409                                IDENTIFIER_POINTER (qualified_name));
3410           sca = ACC_STATIC;
3411         }
3412       /* Else, in the context of a top-level class declaration, let
3413          `check_modifiers' do its job, otherwise, give it a go */
3414       else
3415         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3416     }
3417
3418   /* Inner classes can be declared private or protected
3419      within their enclosing classes. */
3420   if (CPC_INNER_P ())
3421     {
3422       /* A class which is local to a block can't be public, private,
3423          protected or static. But it is created final, so allow this
3424          one. */
3425       if (current_function_decl)
3426         icaf = sca = uaaf = ACC_FINAL;
3427       else
3428         {
3429           check_modifiers_consistency (flags);
3430           icaf = ACC_PRIVATE|ACC_PROTECTED;
3431         }
3432     }
3433
3434   if (is_interface) 
3435     {
3436       if (CPC_INNER_P ())
3437         uaaf = INTERFACE_INNER_MODIFIERS;
3438       else
3439         uaaf = INTERFACE_MODIFIERS;
3440       
3441       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3442                        flags, uaaf);
3443     }
3444   else
3445     check_modifiers ((current_function_decl ?
3446                       "Illegal modifier `%s' for local class declaration" :
3447                       "Illegal modifier `%s' for class declaration"),
3448                      flags, uaaf|sca|icaf);
3449   return 0;
3450 }
3451
3452 static void
3453 make_nested_class_name (cpc_list)
3454      tree cpc_list;
3455 {
3456   tree name;
3457
3458   if (!cpc_list)
3459     return;
3460   else
3461     make_nested_class_name (TREE_CHAIN (cpc_list));
3462
3463   /* Pick the qualified name when dealing with the first upmost
3464      enclosing class */
3465   name = (TREE_CHAIN (cpc_list) ? 
3466           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3467   obstack_grow (&temporary_obstack,
3468                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3469   /* Why is NO_DOLLAR_IN_LABEL defined? */
3470 #if 0
3471 #ifdef NO_DOLLAR_IN_LABEL
3472   internal_error ("Can't use '$' as a separator for inner classes");
3473 #endif
3474 #endif
3475   obstack_1grow (&temporary_obstack, '$');
3476 }
3477
3478 /* Can't redefine a class already defined in an earlier scope. */
3479
3480 static int
3481 check_inner_class_redefinition (raw_name, cl)
3482      tree raw_name, cl;
3483 {
3484   tree scope_list;
3485
3486   for (scope_list = GET_CPC_LIST (); scope_list; 
3487        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3488     if (raw_name == GET_CPC_UN_NODE (scope_list))
3489       {
3490         parse_error_context 
3491           (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",
3492            IDENTIFIER_POINTER (raw_name));
3493         return 1;
3494       }
3495   return 0;
3496 }
3497
3498 static tree
3499 find_as_inner_class (enclosing, name, cl)
3500      tree enclosing, name, cl;
3501 {
3502   tree qual, to_return;
3503   if (!enclosing)
3504     return NULL_TREE;
3505
3506   name = TYPE_NAME (name);
3507
3508   /* First search: within the scope of `enclosing', search for name */
3509   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3510     qual = EXPR_WFL_QUALIFICATION (cl);
3511   else if (cl)
3512     qual = build_tree_list (cl, NULL_TREE);
3513   else
3514     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3515   
3516   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3517     return to_return;
3518
3519   /* We're dealing with a qualified name. Try to resolve thing until
3520      we get something that is an enclosing class. */
3521   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3522     {
3523       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3524
3525       for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3526            qual = TREE_CHAIN (qual))
3527         {
3528           acc = merge_qualified_name (acc, 
3529                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3530           BUILD_PTR_FROM_NAME (ptr, acc);
3531
3532           /* Don't try to resolve ACC as a class name if it follows
3533              the current package name. We don't want to pick something
3534              that's accidentally there: for example `a.b.c' in package
3535              `a.b' shouldn't trigger loading `a' if it's there by
3536              itself. */
3537           if (ctxp->package
3538               && strstr (IDENTIFIER_POINTER (ctxp->package),
3539                          IDENTIFIER_POINTER (acc)))
3540             decl = NULL;
3541           else
3542             decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3543         }
3544
3545       /* A NULL qual and a decl means that the search ended
3546          successfully?!? We have to do something then. FIXME */
3547       
3548       if (decl)
3549         enclosing = decl;
3550       else
3551         qual = EXPR_WFL_QUALIFICATION (cl);
3552     }
3553   /* Otherwise, create a qual for the other part of the resolution. */
3554   else
3555     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3556
3557   return find_as_inner_class_do (qual, enclosing);
3558 }
3559
3560 /* We go inside the list of sub classes and try to find a way
3561    through. */
3562
3563 static tree
3564 find_as_inner_class_do (qual, enclosing)
3565      tree qual, enclosing;
3566 {
3567   if (!qual)
3568     return NULL_TREE;
3569
3570   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3571     {
3572       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3573       tree next_enclosing = NULL_TREE;
3574       tree inner_list;
3575
3576       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3577            inner_list; inner_list = TREE_CHAIN (inner_list))
3578         {
3579           if (TREE_VALUE (inner_list) == name_to_match)
3580             {
3581               next_enclosing = TREE_PURPOSE (inner_list);
3582               break;
3583             }
3584         }
3585       enclosing = next_enclosing;
3586     }
3587
3588   return (!qual && enclosing ? enclosing : NULL_TREE);
3589 }
3590
3591 /* Reach all inner classes and tie their unqualified name to a
3592    DECL. */
3593
3594 static void
3595 set_nested_class_simple_name_value (outer, set)
3596      tree outer;
3597      int set;
3598 {
3599   tree l;
3600
3601   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3602     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3603                                                 TREE_PURPOSE (l) : NULL_TREE);
3604 }
3605
3606 static void
3607 link_nested_class_to_enclosing ()
3608 {
3609   if (GET_ENCLOSING_CPC ())
3610     {
3611       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3612       DECL_INNER_CLASS_LIST (enclosing) = 
3613         tree_cons (GET_CPC (), GET_CPC_UN (),
3614                    DECL_INNER_CLASS_LIST (enclosing));
3615       enclosing = enclosing;
3616     }
3617 }
3618
3619 static tree
3620 maybe_make_nested_class_name (name)
3621      tree name;
3622 {
3623   tree id = NULL_TREE;
3624
3625   if (CPC_INNER_P ())
3626     {
3627       make_nested_class_name (GET_CPC_LIST ());
3628       obstack_grow0 (&temporary_obstack,
3629                      IDENTIFIER_POINTER (name), 
3630                      IDENTIFIER_LENGTH (name));
3631       id = get_identifier (obstack_finish (&temporary_obstack));
3632       if (ctxp->package)
3633         QUALIFIED_P (id) = 1;
3634     }
3635   return id;
3636 }
3637
3638 /* If DECL is NULL, create and push a new DECL, record the current
3639    line CL and do other maintenance things.  */
3640
3641 static tree
3642 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3643      tree decl, raw_name, qualified_name, cl;
3644 {
3645   if (!decl)
3646     decl = push_class (make_class (), qualified_name);
3647
3648   /* Take care of the file and line business */
3649   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3650   /* If we're emiting xrefs, store the line/col number information */
3651   if (flag_emit_xref)
3652     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3653   else
3654     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3655   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3656   CLASS_PARSED_P (TREE_TYPE (decl)) = 1;
3657   CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) =
3658     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3659
3660   PUSH_CPC (decl, raw_name);
3661   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3662
3663   /* Link the declaration to the already seen ones */
3664   TREE_CHAIN (decl) = ctxp->class_list;
3665   ctxp->class_list = decl;
3666
3667   /* Create a new nodes in the global lists */
3668   gclass_list = tree_cons (NULL_TREE, decl, gclass_list);
3669   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3670
3671   /* Install a new dependency list element */
3672   create_jdep_list (ctxp);
3673
3674   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3675                           IDENTIFIER_POINTER (qualified_name)));
3676   return decl;
3677 }
3678
3679 static void
3680 add_superinterfaces (decl, interface_list)
3681      tree decl, interface_list;
3682 {
3683   tree node;
3684   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3685      takes care of ensuring that:
3686        - This is an accessible interface type,
3687        - Circularity detection.
3688    parser_add_interface is then called. If present but not defined,
3689    the check operation is delayed until the super interface gets
3690    defined.  */
3691   for (node = interface_list; node; node = TREE_CHAIN (node))
3692     {
3693       tree current = TREE_PURPOSE (node);
3694       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3695       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3696         {
3697           if (!parser_check_super_interface (idecl, decl, current))
3698             parser_add_interface (decl, idecl, current);
3699         }
3700       else
3701         register_incomplete_type (JDEP_INTERFACE,
3702                                   current, decl, NULL_TREE);
3703     }
3704 }
3705
3706 /* Create an interface in pass1 and return its decl. Return the
3707    interface's decl in pass 2.  */
3708
3709 static tree
3710 create_interface (flags, id, super)
3711      int flags;
3712      tree id, super;
3713 {
3714   tree raw_name = EXPR_WFL_NODE (id);
3715   tree q_name = parser_qualified_classname (raw_name);
3716   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3717
3718   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3719
3720   /* Basic checks: scope, redefinition, modifiers */ 
3721   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3722     {
3723       PUSH_ERROR ();
3724       return NULL_TREE;
3725     }
3726
3727   /* Suspend the current parsing context if we're parsing an inner
3728      interface */
3729   if (CPC_INNER_P ())
3730     java_parser_context_suspend ();
3731
3732   /* Push a new context for (static) initialized upon declaration fields */
3733   java_parser_context_push_initialized_field ();
3734
3735   /* Interface modifiers check
3736        - public/abstract allowed (already done at that point)
3737        - abstract is obsolete (comes first, it's a warning, or should be)
3738        - Can't use twice the same (checked in the modifier rule) */
3739   if ((flags & ACC_ABSTRACT) && flag_redundant)
3740     parse_warning_context 
3741       (MODIFIER_WFL (ABSTRACT_TK),
3742        "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3743
3744   /* Create a new decl if DECL is NULL, otherwise fix it */
3745   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3746
3747   /* Set super info and mark the class a complete */
3748   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3749                   object_type_node, ctxp->interface_number);
3750   ctxp->interface_number = 0;
3751   CLASS_COMPLETE_P (decl) = 1;
3752   add_superinterfaces (decl, super);
3753
3754   return decl;
3755 }
3756
3757 /* Anonymous class counter. Will be reset to 1 every time a non
3758    anonymous class gets created. */
3759 static int anonymous_class_counter = 1;
3760
3761 /* Patch anonymous class CLASS, by either extending or implementing
3762    DEP.  */
3763
3764 static void
3765 patch_anonymous_class (type_decl, class_decl, wfl)
3766     tree type_decl, class_decl, wfl;
3767 {
3768   tree class = TREE_TYPE (class_decl);
3769   tree type =  TREE_TYPE (type_decl);
3770   tree binfo = TYPE_BINFO (class);
3771
3772   /* If it's an interface, implement it */
3773   if (CLASS_INTERFACE (type_decl))
3774     {
3775       tree s_binfo;
3776       int length;
3777
3778       if (parser_check_super_interface (type_decl, class_decl, wfl))
3779         return;
3780
3781       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3782       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3783       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3784       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3785       /* And add the interface */
3786       parser_add_interface (class_decl, type_decl, wfl);
3787     }
3788   /* Otherwise, it's a type we want to extend */
3789   else
3790     {
3791       if (parser_check_super (type_decl, class_decl, wfl))
3792         return;
3793       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3794     }
3795 }
3796
3797 static tree
3798 create_anonymous_class (location, type_name)
3799     int location;
3800     tree type_name;
3801 {
3802   char buffer [80];
3803   tree super = NULL_TREE, itf = NULL_TREE;
3804   tree id, type_decl, class;
3805
3806   /* The unqualified name of the anonymous class. It's just a number. */
3807   sprintf (buffer, "%d", anonymous_class_counter++);
3808   id = build_wfl_node (get_identifier (buffer));
3809   EXPR_WFL_LINECOL (id) = location;
3810
3811   /* We know about the type to extend/implement. We go ahead */
3812   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3813     {
3814       /* Create a class which either implements on extends the designated
3815          class. The class bears an innacessible name. */
3816       if (CLASS_INTERFACE (type_decl))
3817         {
3818           /* It's OK to modify it here. It's been already used and
3819              shouldn't be reused */
3820           ctxp->interface_number = 1;
3821           /* Interfaces should presented as a list of WFLs */
3822           itf = build_tree_list (type_name, NULL_TREE);
3823         }
3824       else
3825         super = type_name;
3826     }
3827
3828   class = create_class (ACC_FINAL, id, super, itf);
3829
3830   /* We didn't know anything about the stuff. We register a dependence. */
3831   if (!type_decl)
3832     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3833
3834   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3835   return class;
3836 }
3837
3838 /* Create a class in pass1 and return its decl. Return class
3839    interface's decl in pass 2.  */
3840
3841 static tree
3842 create_class (flags, id, super, interfaces)
3843      int flags;
3844      tree id, super, interfaces;
3845 {
3846   tree raw_name = EXPR_WFL_NODE (id);
3847   tree class_id, decl;
3848   tree super_decl_type;
3849
3850   class_id = parser_qualified_classname (raw_name);
3851   decl = IDENTIFIER_CLASS_VALUE (class_id);
3852   EXPR_WFL_NODE (id) = class_id;
3853
3854   /* Basic check: scope, redefinition, modifiers */
3855   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3856     {
3857       PUSH_ERROR ();
3858       return NULL_TREE;
3859     }
3860   
3861   /* Suspend the current parsing context if we're parsing an inner
3862      class or an anonymous class. */
3863   if (CPC_INNER_P ())
3864     java_parser_context_suspend ();
3865   /* Push a new context for (static) initialized upon declaration fields */
3866   java_parser_context_push_initialized_field ();
3867
3868   /* Class modifier check: 
3869        - Allowed modifier (already done at that point)
3870        - abstract AND final forbidden 
3871        - Public classes defined in the correct file */
3872   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3873     parse_error_context
3874       (id, "Class `%s' can't be declared both abstract and final",
3875        IDENTIFIER_POINTER (raw_name));
3876
3877   /* Create a new decl if DECL is NULL, otherwise fix it */
3878   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3879
3880   /* If SUPER exists, use it, otherwise use Object */
3881   if (super)
3882     {
3883       /* Can't extend java.lang.Object */
3884       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3885         {
3886           parse_error_context (id, "Can't extend `java.lang.Object'");
3887           return NULL_TREE;
3888         }
3889
3890       super_decl_type = 
3891         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3892     }
3893   else if (TREE_TYPE (decl) != object_type_node)
3894     super_decl_type = object_type_node;
3895   /* We're defining java.lang.Object */
3896   else
3897     super_decl_type = NULL_TREE;
3898
3899   /* A class nested in an interface is implicitly static. */
3900   if (INNER_CLASS_DECL_P (decl)
3901       && CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (DECL_CONTEXT (decl)))))
3902     {
3903       flags |= ACC_STATIC;
3904     }
3905
3906   /* Set super info and mark the class as complete. */
3907   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
3908                   ctxp->interface_number);
3909   ctxp->interface_number = 0;
3910   CLASS_COMPLETE_P (decl) = 1;
3911   add_superinterfaces (decl, interfaces);
3912
3913   /* Add the private this$<n> field, Replicate final locals still in
3914      scope as private final fields mangled like val$<local_name>.
3915      This doesn't not occur for top level (static) inner classes. */
3916   if (PURE_INNER_CLASS_DECL_P (decl))
3917     add_inner_class_fields (decl, current_function_decl);
3918
3919   /* If doing xref, store the location at which the inherited class
3920      (if any) was seen. */
3921   if (flag_emit_xref && super)
3922     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3923
3924   /* Eventually sets the @deprecated tag flag */
3925   CHECK_DEPRECATED (decl);
3926
3927   /* Reset the anonymous class counter when declaring non inner classes */
3928   if (!INNER_CLASS_DECL_P (decl))
3929     anonymous_class_counter = 1;
3930
3931   return decl;
3932 }
3933
3934 /* End a class declaration: register the statements used to create
3935    finit$ and <clinit>, pop the current class and resume the prior
3936    parser context if necessary.  */
3937
3938 static void
3939 end_class_declaration (resume)
3940      int resume;
3941 {
3942   /* If an error occured, context weren't pushed and won't need to be
3943      popped by a resume. */
3944   int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
3945
3946   java_parser_context_pop_initialized_field ();
3947   POP_CPC ();
3948   if (resume && no_error_occured)
3949     java_parser_context_resume ();
3950
3951   /* We're ending a class declaration, this is a good time to reset
3952      the interface cout. Note that might have been already done in
3953      create_interface, but if at that time an inner class was being
3954      dealt with, the interface count was reset in a context created
3955      for the sake of handling inner classes declaration. */
3956   ctxp->interface_number = 0;
3957 }
3958
3959 static void
3960 add_inner_class_fields (class_decl, fct_decl)
3961      tree class_decl;
3962      tree fct_decl;
3963 {
3964   tree block, marker, f;
3965
3966   f = add_field (TREE_TYPE (class_decl),
3967                  build_current_thisn (TREE_TYPE (class_decl)),
3968                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
3969                  ACC_PRIVATE);
3970   FIELD_THISN (f) = 1;
3971
3972   if (!fct_decl)
3973     return;
3974     
3975   for (block = GET_CURRENT_BLOCK (fct_decl); 
3976        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
3977     {
3978       tree decl;
3979       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
3980         {
3981           tree name, pname;
3982           tree wfl, init, list;
3983           
3984           /* Avoid non final arguments. */
3985           if (!LOCAL_FINAL_P (decl))
3986             continue;
3987           
3988           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
3989           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
3990           wfl = build_wfl_node (name);
3991           init = build_wfl_node (pname);
3992           /* Build an initialization for the field: it will be
3993              initialized by a parameter added to finit$, bearing a
3994              mangled name of the field itself (param$<n>.) The
3995              parameter is provided to finit$ by the constructor
3996              invoking it (hence the constructor will also feature a
3997              hidden parameter, set to the value of the outer context
3998              local at the time the inner class is created.)
3999              
4000              Note: we take into account all possible locals that can
4001              be accessed by the inner class. It's actually not trivial
4002              to minimize these aliases down to the ones really
4003              used. One way to do that would be to expand all regular
4004              methods first, then finit$ to get a picture of what's
4005              used.  It works with the exception that we would have to
4006              go back on all constructor invoked in regular methods to
4007              have their invokation reworked (to include the right amount
4008              of alias initializer parameters.)
4009
4010              The only real way around, I think, is a first pass to
4011              identify locals really used in the inner class. We leave
4012              the flag FIELD_LOCAL_ALIAS_USED around for that future
4013              use.
4014              
4015              On the other hand, it only affect local inner classes,
4016              whose constructors (and finit$ call) will be featuring
4017              unecessary arguments. It's easy for a developper to keep
4018              this number of parameter down by using the `final'
4019              keyword only when necessary. For the time being, we can
4020              issue a warning on unecessary finals. FIXME */
4021           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
4022                                    wfl, init);
4023
4024           /* Register the field. The TREE_LIST holding the part
4025              initialized/initializer will be marked ARG_FINAL_P so
4026              that the created field can be marked
4027              FIELD_LOCAL_ALIAS. */
4028           list = build_tree_list (wfl, init);
4029           ARG_FINAL_P (list) = 1;
4030           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
4031         }
4032     }
4033
4034   if (!CPC_INITIALIZER_STMT (ctxp))
4035     return;
4036
4037   /* If we ever registered an alias field, insert and marker to
4038      remeber where the list ends. The second part of the list (the one
4039      featuring initialized fields) so it can be later reversed to
4040      enforce 8.5. The marker will be removed during that operation. */
4041   marker = build_tree_list (NULL_TREE, NULL_TREE);
4042   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
4043   SET_CPC_INITIALIZER_STMT (ctxp, marker);
4044 }
4045
4046 /* Can't use lookup_field () since we don't want to load the class and
4047    can't set the CLASS_LOADED_P flag */
4048
4049 static tree
4050 find_field (class, name)
4051      tree class;
4052      tree name;
4053 {
4054   tree decl;
4055   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
4056     {
4057       if (DECL_NAME (decl) == name)
4058         return decl;
4059     }
4060   return NULL_TREE;
4061 }
4062
4063 /* Wrap around lookup_field that doesn't potentially upset the value
4064    of CLASS */
4065
4066 static tree
4067 lookup_field_wrapper (class, name)
4068      tree class, name;
4069 {
4070   tree type = class;
4071   tree decl = NULL_TREE;
4072   java_parser_context_save_global ();
4073
4074   /* Last chance: if we're within the context of an inner class, we
4075      might be trying to access a local variable defined in an outer
4076      context. We try to look for it now. */
4077   if (INNER_CLASS_TYPE_P (class))
4078     {
4079       tree new_name;
4080       MANGLE_OUTER_LOCAL_VARIABLE_NAME (new_name, name);
4081       decl = lookup_field (&type, new_name);
4082       if (decl && decl != error_mark_node)
4083         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4084     }
4085   if (!decl || decl == error_mark_node)
4086     {
4087       type = class;
4088       decl = lookup_field (&type, name);
4089     }
4090
4091   java_parser_context_restore_global ();
4092   return decl == error_mark_node ? NULL : decl;
4093 }
4094
4095 /* Find duplicate field within the same class declarations and report
4096    the error. Returns 1 if a duplicated field was found, 0
4097    otherwise.  */
4098
4099 static int
4100 duplicate_declaration_error_p (new_field_name, new_type, cl)
4101      tree new_field_name, new_type, cl;
4102 {
4103   /* This might be modified to work with method decl as well */
4104   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4105   if (decl)
4106     {
4107       char *t1 = xstrdup (purify_type_name
4108                          ((TREE_CODE (new_type) == POINTER_TYPE 
4109                            && TREE_TYPE (new_type) == NULL_TREE) ?
4110                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4111                           lang_printable_name (new_type, 1)));
4112       /* The type may not have been completed by the time we report
4113          the error */
4114       char *t2 = xstrdup (purify_type_name
4115                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4116                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4117                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4118                           lang_printable_name (TREE_TYPE (decl), 1)));
4119       parse_error_context 
4120         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4121          t1, IDENTIFIER_POINTER (new_field_name),
4122          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4123          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4124       free (t1);
4125       free (t2);
4126       return 1;
4127     }
4128   return 0;
4129 }
4130
4131 /* Field registration routine. If TYPE doesn't exist, field
4132    declarations are linked to the undefined TYPE dependency list, to
4133    be later resolved in java_complete_class () */
4134
4135 static void
4136 register_fields (flags, type, variable_list)
4137      int flags;
4138      tree type, variable_list;
4139 {
4140   tree current, saved_type;
4141   tree class_type = NULL_TREE;
4142   int saved_lineno = lineno;
4143   int must_chain = 0;
4144   tree wfl = NULL_TREE;
4145
4146   if (GET_CPC ())
4147     class_type = TREE_TYPE (GET_CPC ());
4148
4149   if (!class_type || class_type == error_mark_node)
4150     return;
4151
4152   /* If we're adding fields to interfaces, those fields are public,
4153      static, final */
4154   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4155     {
4156       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4157                                  flags, ACC_PUBLIC, "interface field(s)");
4158       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4159                                  flags, ACC_STATIC, "interface field(s)");
4160       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4161                                  flags, ACC_FINAL, "interface field(s)");
4162       check_modifiers ("Illegal interface member modifier `%s'", flags,
4163                        INTERFACE_FIELD_MODIFIERS);
4164       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4165     }
4166
4167   /* Obtain a suitable type for resolution, if necessary */
4168   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4169
4170   /* If TYPE is fully resolved and we don't have a reference, make one */
4171   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4172
4173   for (current = variable_list, saved_type = type; current; 
4174        current = TREE_CHAIN (current), type = saved_type)
4175     {
4176       tree real_type;
4177       tree field_decl;
4178       tree cl = TREE_PURPOSE (current);
4179       tree init = TREE_VALUE (current);
4180       tree current_name = EXPR_WFL_NODE (cl);
4181
4182       /* Can't declare non-final static fields in inner classes */
4183       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4184           && !(flags & ACC_FINAL))
4185         parse_error_context 
4186           (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
4187            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4188            lang_printable_name (class_type, 0));
4189
4190       /* Process NAME, as it may specify extra dimension(s) for it */
4191       type = build_array_from_name (type, wfl, current_name, &current_name);
4192
4193       /* Type adjustment. We may have just readjusted TYPE because
4194          the variable specified more dimensions. Make sure we have
4195          a reference if we can and don't have one already. Also
4196          change the name if we have an init. */
4197       if (type != saved_type)
4198         {
4199           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4200           if (init)
4201             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4202         }
4203
4204       real_type = GET_REAL_TYPE (type);
4205       /* Check for redeclarations */
4206       if (duplicate_declaration_error_p (current_name, real_type, cl))
4207         continue;
4208
4209       /* Set lineno to the line the field was found and create a
4210          declaration for it. Eventually sets the @deprecated tag flag. */
4211       if (flag_emit_xref)
4212         lineno = EXPR_WFL_LINECOL (cl);
4213       else
4214         lineno = EXPR_WFL_LINENO (cl);
4215       field_decl = add_field (class_type, current_name, real_type, flags);
4216       CHECK_DEPRECATED (field_decl);
4217
4218       /* If the field denotes a final instance variable, then we
4219          allocate a LANG_DECL_SPECIFIC part to keep track of its
4220          initialization. We also mark whether the field was
4221          initialized upon it's declaration. We don't do that if the
4222          created field is an alias to a final local. */
4223       if (!ARG_FINAL_P (current) && (flags & ACC_FINAL))
4224         {
4225           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field_decl);
4226           DECL_FIELD_FINAL_WFL (field_decl) = cl;
4227           if ((flags & ACC_STATIC) && init)
4228             DECL_FIELD_FINAL_IUD (field_decl) = 1;
4229         }
4230
4231       /* If the couple initializer/initialized is marked ARG_FINAL_P,
4232          we mark the created field FIELD_LOCAL_ALIAS, so that we can
4233          hide parameters to this inner class finit$ and
4234          constructors. It also means that the field isn't final per
4235          say. */
4236       if (ARG_FINAL_P (current))
4237         {
4238           FIELD_LOCAL_ALIAS (field_decl) = 1;
4239           FIELD_FINAL (field_decl) = 0;
4240         }
4241       
4242       /* Check if we must chain. */
4243       if (must_chain)
4244         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4245           
4246       /* If we have an initialization value tied to the field */
4247       if (init)
4248         {
4249           /* The field is declared static */
4250           if (flags & ACC_STATIC)
4251             {
4252               /* We include the field and its initialization part into
4253                  a list used to generate <clinit>. After <clinit> is
4254                  walked, field initializations will be processed and
4255                  fields initialized with known constants will be taken
4256                  out of <clinit> and have their DECL_INITIAL set
4257                  appropriately. */
4258               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4259               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4260               if (TREE_OPERAND (init, 1) 
4261                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4262                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4263             }
4264           /* A non-static field declared with an immediate initialization is
4265              to be initialized in <init>, if any.  This field is remembered
4266              to be processed at the time of the generation of <init>. */
4267           else
4268             {
4269               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4270               SET_CPC_INITIALIZER_STMT (ctxp, init);
4271             }
4272           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4273           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4274         }
4275     }
4276   lineno = saved_lineno;
4277 }
4278
4279 /* Generate finit$, using the list of initialized fields to populate
4280    its body. finit$'s parameter(s) list is adjusted to include the
4281    one(s) used to initialized the field(s) caching outer context
4282    local(s). */
4283
4284 static tree
4285 generate_finit (class_type)
4286      tree class_type;
4287 {
4288   int count = 0;
4289   tree list = TYPE_FINIT_STMT_LIST (class_type);
4290   tree mdecl, current, parms;
4291
4292   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4293                                                   class_type, NULL_TREE, 
4294                                                   &count);
4295   CRAFTED_PARAM_LIST_FIXUP (parms);
4296   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4297                                     finit_identifier_node, parms);
4298   fix_method_argument_names (parms, mdecl);
4299   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4300                        mdecl, NULL_TREE);
4301   DECL_FUNCTION_NAP (mdecl) = count;
4302   start_artificial_method_body (mdecl);
4303
4304   for (current = list; current; current = TREE_CHAIN (current))
4305     java_method_add_stmt (mdecl, 
4306                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4307                                                 current));
4308   end_artificial_method_body (mdecl);
4309   return mdecl;
4310 }
4311
4312 static tree
4313 build_instance_initializer (mdecl)
4314      tree mdecl;
4315 {
4316   tree compound = NULL_TREE;
4317   tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
4318   tree current;
4319
4320   for (current = stmt_list; current; current = TREE_CHAIN (current))
4321     compound = add_stmt_to_compound (compound, NULL_TREE, current);
4322
4323   return compound;
4324 }
4325
4326 static void
4327 add_instance_initializer (mdecl)
4328      tree mdecl;
4329 {
4330   tree compound = build_instance_initializer (mdecl);
4331
4332   if (compound)
4333     java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
4334                                          NULL_TREE, compound));
4335 }
4336
4337 /* Shared accros method_declarator and method_header to remember the
4338    patch stage that was reached during the declaration of the method.
4339    A method DECL is built differently is there is no patch
4340    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4341    pending on the currently defined method.  */
4342
4343 static int patch_stage;
4344
4345 /* Check the method declaration and add the method to its current
4346    class.  If the argument list is known to contain incomplete types,
4347    the method is partially added and the registration will be resume
4348    once the method arguments resolved. If TYPE is NULL, we're dealing
4349    with a constructor.  */
4350
4351 static tree
4352 method_header (flags, type, mdecl, throws)
4353      int flags;
4354      tree type, mdecl, throws;
4355 {
4356   tree type_wfl = NULL_TREE;
4357   tree meth_name = NULL_TREE;
4358   tree current, orig_arg, this_class = NULL;
4359   tree id, meth;
4360   int saved_lineno;
4361   int constructor_ok = 0, must_chain;
4362   int count;
4363
4364   if (mdecl == error_mark_node)
4365     return error_mark_node;
4366   meth = TREE_VALUE (mdecl);
4367   id = TREE_PURPOSE (mdecl);
4368   
4369   check_modifiers_consistency (flags);
4370
4371   if (GET_CPC ())
4372     this_class = TREE_TYPE (GET_CPC ());
4373
4374   if (!this_class || this_class == error_mark_node)
4375     return NULL_TREE;
4376   
4377   /* There are some forbidden modifiers for an abstract method and its
4378      class must be abstract as well.  */
4379   if (type && (flags & ACC_ABSTRACT))
4380     {
4381       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4382       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4383       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4384       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4385       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4386       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4387           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4388         parse_error_context 
4389           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4390            IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())),
4391            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4392     }
4393
4394   /* Things to be checked when declaring a constructor */
4395   if (!type)
4396     {
4397       int ec = java_error_count;
4398       /* 8.6: Constructor declarations: we might be trying to define a
4399          method without specifying a return type. */
4400       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4401         parse_error_context 
4402           (id, "Invalid method declaration, return type required");
4403       /* 8.6.3: Constructor modifiers */
4404       else
4405         {
4406           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4407           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4408           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4409           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4410           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4411         }
4412       /* If we found error here, we don't consider it's OK to tread
4413          the method definition as a constructor, for the rest of this
4414          function */
4415       if (ec == java_error_count)
4416         constructor_ok = 1;
4417     }
4418
4419   /* Method declared within the scope of an interface are implicitly
4420      abstract and public. Conflicts with other erroneously provided
4421      modifiers are checked right after. */
4422
4423   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4424     {
4425       /* If FLAGS isn't set because of a modifier, turn the
4426          corresponding modifier WFL to NULL so we issue a warning on
4427          the obsolete use of the modifier */
4428       if (!(flags & ACC_PUBLIC))
4429         MODIFIER_WFL (PUBLIC_TK) = NULL;
4430       if (!(flags & ACC_ABSTRACT))
4431         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4432       flags |= ACC_PUBLIC;
4433       flags |= ACC_ABSTRACT;
4434     }
4435
4436   /* Inner class can't declare static methods */
4437   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4438     {
4439       parse_error_context 
4440         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4441          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4442          lang_printable_name (this_class, 0));
4443     }
4444
4445   /* Modifiers context reset moved up, so abstract method declaration
4446      modifiers can be later checked.  */
4447
4448   /* Set constructor returned type to void and method name to <init>,
4449      unless we found an error identifier the constructor (in which
4450      case we retain the original name) */
4451   if (!type)
4452     {
4453       type = void_type_node;
4454       if (constructor_ok)
4455         meth_name = init_identifier_node;
4456     }
4457   else
4458     meth_name = EXPR_WFL_NODE (id);
4459
4460   /* Do the returned type resolution and registration if necessary */
4461   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4462
4463   if (meth_name)
4464     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4465   EXPR_WFL_NODE (id) = meth_name;
4466   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4467
4468   if (must_chain)
4469     {
4470       patch_stage = JDEP_METHOD_RETURN;
4471       register_incomplete_type (patch_stage, type_wfl, id, type);
4472       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4473     }
4474   else
4475     TREE_TYPE (meth) = type;
4476
4477   saved_lineno = lineno;
4478   /* When defining an abstract or interface method, the curly
4479      bracket at level 1 doesn't exist because there is no function
4480      body */
4481   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4482             EXPR_WFL_LINENO (id));
4483
4484   /* Remember the original argument list */
4485   orig_arg = TYPE_ARG_TYPES (meth);
4486
4487   if (patch_stage)              /* includes ret type and/or all args */
4488     {
4489       jdep *jdep;
4490       meth = add_method_1 (this_class, flags, meth_name, meth);
4491       /* Patch for the return type */
4492       if (patch_stage == JDEP_METHOD_RETURN)
4493         {
4494           jdep = CLASSD_LAST (ctxp->classd_list);
4495           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4496         }
4497       /* This is the stop JDEP. METH allows the function's signature
4498          to be computed. */
4499       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4500     }
4501   else
4502     meth = add_method (this_class, flags, meth_name, 
4503                        build_java_signature (meth));
4504
4505   /* Remember final parameters */
4506   MARK_FINAL_PARMS (meth, orig_arg);
4507
4508   /* Fix the method argument list so we have the argument name
4509      information */
4510   fix_method_argument_names (orig_arg, meth);
4511
4512   /* Register the parameter number and re-install the current line
4513      number */
4514   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4515   lineno = saved_lineno;
4516
4517   /* Register exception specified by the `throws' keyword for
4518      resolution and set the method decl appropriate field to the list.
4519      Note: the grammar ensures that what we get here are class
4520      types. */
4521   if (throws)
4522     {
4523       throws = nreverse (throws);
4524       for (current = throws; current; current = TREE_CHAIN (current))
4525         {
4526           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4527                                     NULL_TREE, NULL_TREE);
4528           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4529             &TREE_VALUE (current);
4530         }
4531       DECL_FUNCTION_THROWS (meth) = throws;
4532     }
4533
4534   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4535     DECL_FUNCTION_WFL (meth) = id;
4536
4537   /* Set the flag if we correctly processed a constructor */
4538   if (constructor_ok)
4539     {
4540       DECL_CONSTRUCTOR_P (meth) = 1;
4541       /* Compute and store the number of artificial parameters declared
4542          for this constructor */
4543       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4544            current = TREE_CHAIN (current))
4545         if (FIELD_LOCAL_ALIAS (current))
4546           count++;
4547       DECL_FUNCTION_NAP (meth) = count;
4548     }
4549
4550   /* Eventually set the @deprecated tag flag */
4551   CHECK_DEPRECATED (meth);
4552
4553   /* If doing xref, store column and line number information instead
4554      of the line number only. */
4555   if (flag_emit_xref)
4556     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4557
4558   return meth;
4559 }
4560
4561 static void
4562 fix_method_argument_names (orig_arg, meth)
4563     tree orig_arg, meth;
4564 {
4565   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4566   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4567     {
4568       TREE_PURPOSE (arg) = this_identifier_node;
4569       arg = TREE_CHAIN (arg);
4570     }
4571   while (orig_arg != end_params_node)
4572     {
4573       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4574       orig_arg = TREE_CHAIN (orig_arg);
4575       arg = TREE_CHAIN (arg);
4576     }
4577 }
4578
4579 /* Complete the method declaration with METHOD_BODY.  */
4580
4581 static void
4582 finish_method_declaration (method_body)
4583      tree method_body;
4584 {
4585   int flags;
4586
4587   if (!current_function_decl)
4588     return;
4589
4590   flags = get_access_flags_from_decl (current_function_decl);
4591
4592   /* 8.4.5 Method Body */
4593   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4594     {
4595       tree name = DECL_NAME (current_function_decl);
4596       parse_error_context (DECL_FUNCTION_WFL (current_function_decl), 
4597                            "%s method `%s' can't have a body defined",
4598                            (METHOD_NATIVE (current_function_decl) ?
4599                             "Native" : "Abstract"),
4600                            IDENTIFIER_POINTER (name));
4601       method_body = NULL_TREE;
4602     }
4603   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4604     {
4605       tree name = DECL_NAME (current_function_decl);
4606       parse_error_context
4607         (DECL_FUNCTION_WFL (current_function_decl), 
4608          "Non native and non abstract method `%s' must have a body defined",
4609          IDENTIFIER_POINTER (name));
4610       method_body = NULL_TREE;
4611     }
4612
4613   if (flag_emit_class_files && method_body 
4614       && TREE_CODE (method_body) == NOP_EXPR 
4615       && TREE_TYPE (current_function_decl) 
4616       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4617     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4618
4619   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4620   maybe_absorb_scoping_blocks ();
4621   /* Exit function's body */
4622   exit_block ();
4623   /* Merge last line of the function with first line, directly in the
4624      function decl. It will be used to emit correct debug info. */
4625   if (!flag_emit_xref)
4626     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4627
4628   /* Since function's argument's list are shared, reset the
4629      ARG_FINAL_P parameter that might have been set on some of this
4630      function parameters. */
4631   UNMARK_FINAL_PARMS (current_function_decl);
4632   
4633   /* So we don't have an irrelevant function declaration context for
4634      the next static block we'll see. */
4635   current_function_decl = NULL_TREE;
4636 }
4637
4638 /* Build a an error message for constructor circularity errors.  */
4639
4640 static char *
4641 constructor_circularity_msg (from, to)
4642      tree from, to;
4643 {
4644   static char string [4096];
4645   char *t = xstrdup (lang_printable_name (from, 0));
4646   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4647   free (t);
4648   return string;
4649 }
4650
4651 /* Verify a circular call to METH. Return 1 if an error is found, 0
4652    otherwise.  */
4653
4654 static int
4655 verify_constructor_circularity (meth, current)
4656      tree meth, current;
4657 {
4658   static tree list = NULL_TREE;
4659   static int initialized_p;
4660   tree c;
4661
4662   /* If we haven't already registered LIST with the garbage collector,
4663      do so now.  */
4664   if (!initialized_p)
4665     {
4666       ggc_add_tree_root (&list, 1);
4667       initialized_p = 1;
4668     }
4669
4670   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4671     {
4672       if (TREE_VALUE (c) == meth)
4673         {
4674           char *t;
4675           if (list)
4676             {
4677               tree liste;
4678               list = nreverse (list);
4679               for (liste = list; liste; liste = TREE_CHAIN (liste))
4680                 {
4681                   parse_error_context 
4682                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4683                      constructor_circularity_msg
4684                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4685                   java_error_count--;
4686                 }
4687             }
4688           t = xstrdup (lang_printable_name (meth, 0));
4689           parse_error_context (TREE_PURPOSE (c), 
4690                                "%s: recursive invocation of constructor `%s'",
4691                                constructor_circularity_msg (current, meth), t);
4692           free (t);
4693           list = NULL_TREE;
4694           return 1;
4695         }
4696     }
4697   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4698     {
4699       list = tree_cons (c, current, list);
4700       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4701         return 1;
4702       list = TREE_CHAIN (list);
4703     }
4704   return 0;
4705 }
4706
4707 /* Check modifiers that can be declared but exclusively */
4708
4709 static void
4710 check_modifiers_consistency (flags)
4711      int flags;
4712 {
4713   int acc_count = 0;
4714   tree cl = NULL_TREE;
4715
4716   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4717   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4718   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4719   if (acc_count > 1)
4720     parse_error_context
4721       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4722
4723   acc_count = 0;
4724   cl = NULL_TREE;
4725   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
4726   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
4727   if (acc_count > 1)
4728     parse_error_context (cl,
4729                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4730 }
4731
4732 /* Check the methode header METH for abstract specifics features */
4733
4734 static void
4735 check_abstract_method_header (meth)
4736      tree meth;
4737 {
4738   int flags = get_access_flags_from_decl (meth);
4739
4740   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4741                               ACC_ABSTRACT, "abstract method",
4742                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4743   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4744                               ACC_PUBLIC, "abstract method",
4745                               IDENTIFIER_POINTER (DECL_NAME (meth)));
4746
4747   check_modifiers ("Illegal modifier `%s' for interface method",
4748                   flags, INTERFACE_METHOD_MODIFIERS);
4749 }
4750
4751 /* Create a FUNCTION_TYPE node and start augmenting it with the
4752    declared function arguments. Arguments type that can't be resolved
4753    are left as they are, but the returned node is marked as containing
4754    incomplete types.  */
4755
4756 static tree
4757 method_declarator (id, list)
4758      tree id, list;
4759 {
4760   tree arg_types = NULL_TREE, current, node;
4761   tree meth = make_node (FUNCTION_TYPE);
4762   jdep *jdep;
4763
4764   patch_stage = JDEP_NO_PATCH;
4765
4766   if (GET_CPC () == error_mark_node)
4767     return error_mark_node;
4768
4769   /* If we're dealing with an inner class constructor, we hide the
4770      this$<n> decl in the name field of its parameter declaration.  We
4771      also might have to hide the outer context local alias
4772      initializers. Not done when the class is a toplevel class. */
4773   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4774       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4775     {
4776       tree aliases_list, type, thisn;
4777       /* First the aliases, linked to the regular parameters */
4778       aliases_list =
4779         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4780                                                 TREE_TYPE (GET_CPC ()),
4781                                                 NULL_TREE, NULL);
4782       list = chainon (nreverse (aliases_list), list);
4783
4784       /* Then this$<n> */
4785       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4786       thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
4787       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4788                         list);
4789     }
4790   
4791   for (current = list; current; current = TREE_CHAIN (current))
4792     {
4793       int must_chain = 0;
4794       tree wfl_name = TREE_PURPOSE (current);
4795       tree type = TREE_VALUE (current);
4796       tree name = EXPR_WFL_NODE (wfl_name);
4797       tree already, arg_node;
4798       tree type_wfl = NULL_TREE;
4799       tree real_type;
4800
4801       /* Obtain a suitable type for resolution, if necessary */
4802       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4803
4804       /* Process NAME, as it may specify extra dimension(s) for it */
4805       type = build_array_from_name (type, type_wfl, name, &name);
4806       EXPR_WFL_NODE (wfl_name) = name;
4807
4808       real_type = GET_REAL_TYPE (type);
4809       if (TREE_CODE (real_type) == RECORD_TYPE)
4810         {
4811           real_type = promote_type (real_type);
4812           if (TREE_CODE (type) == TREE_LIST)
4813             TREE_PURPOSE (type) = real_type;
4814         }
4815
4816       /* Check redefinition */
4817       for (already = arg_types; already; already = TREE_CHAIN (already))
4818         if (TREE_PURPOSE (already) == name)
4819           {
4820             parse_error_context
4821               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4822                IDENTIFIER_POINTER (name),
4823                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4824             break;
4825           }
4826
4827       /* If we've an incomplete argument type, we know there is a location
4828          to patch when the type get resolved, later.  */
4829       jdep = NULL;
4830       if (must_chain)
4831         {
4832           patch_stage = JDEP_METHOD;
4833           type = register_incomplete_type (patch_stage, 
4834                                            type_wfl, wfl_name, type);
4835           jdep = CLASSD_LAST (ctxp->classd_list);
4836           JDEP_MISC (jdep) = id;
4837         }
4838
4839       /* The argument node: a name and a (possibly) incomplete type.  */
4840       arg_node = build_tree_list (name, real_type);
4841       /* Remeber arguments declared final. */
4842       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
4843       
4844       if (jdep)
4845         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
4846       TREE_CHAIN (arg_node) = arg_types;
4847       arg_types = arg_node;
4848     }
4849   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
4850   node = build_tree_list (id, meth);
4851   return node;
4852 }
4853
4854 static int
4855 unresolved_type_p (wfl, returned)
4856      tree wfl;
4857      tree *returned;
4858      
4859 {
4860   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
4861     {
4862       if (returned)
4863         {
4864           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
4865           if (decl && current_class && (decl == TYPE_NAME (current_class)))
4866             *returned = TREE_TYPE (decl);
4867           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
4868             *returned = TREE_TYPE (GET_CPC ());
4869           else
4870             *returned = NULL_TREE;
4871         }
4872       return 1;
4873     }
4874   if (returned)
4875     *returned = wfl;
4876   return 0;
4877 }
4878
4879 /* From NAME, build a qualified identifier node using the
4880    qualification from the current package definition. */
4881
4882 static tree
4883 parser_qualified_classname (name)
4884      tree name;
4885 {
4886   tree nested_class_name;
4887
4888   if ((nested_class_name = maybe_make_nested_class_name (name)))
4889     return nested_class_name;
4890
4891   if (ctxp->package)
4892     return merge_qualified_name (ctxp->package, name);
4893   else 
4894     return name;
4895 }
4896
4897 /* Called once the type a interface extends is resolved. Returns 0 if
4898    everything is OK.  */
4899
4900 static int
4901 parser_check_super_interface (super_decl, this_decl, this_wfl)
4902      tree super_decl, this_decl, this_wfl;
4903 {
4904   tree super_type = TREE_TYPE (super_decl);
4905
4906   /* Has to be an interface */
4907   if (!CLASS_INTERFACE (super_decl))
4908     {
4909       parse_error_context 
4910         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
4911          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
4912          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
4913          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
4914           "interface" : "class"),
4915          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
4916       return 1;
4917     }
4918
4919   /* Check top-level interface access. Inner classes are subject to member 
4920      access rules (6.6.1). */
4921   if (! INNER_CLASS_P (super_type)
4922       && check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
4923     return 1;
4924
4925   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
4926                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4927                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4928   return 0;
4929 }
4930
4931 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
4932    0 if everthing is OK.  */
4933
4934 static int
4935 parser_check_super (super_decl, this_decl, wfl)
4936      tree super_decl, this_decl, wfl;
4937 {
4938   tree super_type = TREE_TYPE (super_decl);
4939
4940   /* SUPER should be a CLASS (neither an array nor an interface) */
4941   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
4942     {
4943       parse_error_context 
4944         (wfl, "Class `%s' can't subclass %s `%s'",
4945          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4946          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
4947          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4948       return 1;
4949     }
4950
4951   if (CLASS_FINAL (TYPE_NAME (super_type)))
4952     {
4953       parse_error_context (wfl, "Can't subclass final classes: %s",
4954                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4955       return 1;
4956     }
4957
4958   /* Check top-level class scope. Inner classes are subject to member access
4959      rules (6.6.1). */
4960   if (! INNER_CLASS_P (super_type)
4961       && (check_pkg_class_access (DECL_NAME (super_decl), wfl)))
4962     return 1;
4963   
4964   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
4965                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4966                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4967   return 0;
4968 }
4969
4970 /* Create a new dependency list and link it (in a LIFO manner) to the
4971    CTXP list of type dependency list.  */
4972
4973 static void
4974 create_jdep_list (ctxp)
4975      struct parser_ctxt *ctxp;
4976 {
4977   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
4978   new->first = new->last = NULL;
4979   new->next = ctxp->classd_list;
4980   ctxp->classd_list = new;
4981 }
4982
4983 static jdeplist *
4984 reverse_jdep_list (ctxp)
4985      struct parser_ctxt *ctxp;
4986 {
4987   register jdeplist *prev = NULL, *current, *next;
4988   for (current = ctxp->classd_list; current; current = next)
4989     {
4990       next = current->next;
4991       current->next = prev;
4992       prev = current;
4993     }
4994   return prev;
4995 }
4996
4997 /* Create a fake pointer based on the ID stored in
4998    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
4999    registered again. */
5000
5001 static tree
5002 obtain_incomplete_type (type_name)
5003      tree type_name;
5004 {
5005   tree ptr = NULL_TREE, name;
5006
5007   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
5008     name = EXPR_WFL_NODE (type_name);
5009   else if (INCOMPLETE_TYPE_P (type_name))
5010     name = TYPE_NAME (type_name);
5011   else
5012     abort ();
5013
5014   BUILD_PTR_FROM_NAME (ptr, name);
5015   layout_type (ptr);
5016
5017   return ptr;
5018 }
5019
5020 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
5021    non NULL instead of computing a new fake type based on WFL. The new
5022    dependency is inserted in the current type dependency list, in FIFO
5023    manner.  */
5024
5025 static tree
5026 register_incomplete_type (kind, wfl, decl, ptr)
5027      int kind;
5028      tree wfl, decl, ptr;
5029 {
5030   jdep *new = (jdep *)xmalloc (sizeof (jdep));
5031
5032   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
5033     ptr = obtain_incomplete_type (wfl);
5034
5035   JDEP_KIND (new) = kind;
5036   JDEP_DECL (new) = decl;
5037   JDEP_TO_RESOLVE (new) = ptr;
5038   JDEP_WFL (new) = wfl;
5039   JDEP_CHAIN (new) = NULL;
5040   JDEP_MISC (new) = NULL_TREE;
5041   /* For some dependencies, set the enclosing class of the current
5042      class to be the enclosing context */
5043   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE 
5044        || kind == JDEP_ANONYMOUS || kind == JDEP_FIELD)
5045       && GET_ENCLOSING_CPC ())
5046     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
5047   else
5048     JDEP_ENCLOSING (new) = GET_CPC ();
5049   JDEP_GET_PATCH (new) = (tree *)NULL;
5050
5051   JDEP_INSERT (ctxp->classd_list, new);
5052
5053   return ptr;
5054 }
5055
5056 void
5057 java_check_circular_reference ()
5058 {
5059   tree current;
5060   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5061     {
5062       tree type = TREE_TYPE (current);
5063       if (CLASS_INTERFACE (current))
5064         {
5065           /* Check all interfaces this class extends */
5066           tree basetype_vec = TYPE_BINFO_BASETYPES (type);
5067           int n, i;
5068
5069           if (!basetype_vec)
5070             return;
5071           n = TREE_VEC_LENGTH (basetype_vec);
5072           for (i = 0; i < n; i++)
5073             {
5074               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
5075               if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node 
5076                   && interface_of_p (type, BINFO_TYPE (vec_elt)))
5077                 parse_error_context (lookup_cl (current),
5078                                      "Cyclic interface inheritance");
5079             }
5080         }
5081       else
5082         if (inherits_from_p (CLASSTYPE_SUPER (type), type))
5083           parse_error_context (lookup_cl (current), 
5084                                "Cyclic class inheritance%s",
5085                                (cyclic_inheritance_report ?
5086                                 cyclic_inheritance_report : ""));
5087     }
5088 }
5089
5090 /* Augment the parameter list PARM with parameters crafted to
5091    initialize outer context locals aliases. Through ARTIFICIAL, a
5092    count is kept of the number of crafted parameters. MODE governs
5093    what eventually gets created: something suitable for a function
5094    creation or a function invocation, either the constructor or
5095    finit$.  */
5096
5097 static tree
5098 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
5099     int mode;
5100     tree class_type, parm;
5101     int *artificial;
5102 {
5103   tree field;
5104   tree additional_parms = NULL_TREE;
5105
5106   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5107     if (FIELD_LOCAL_ALIAS (field))
5108       {
5109         const char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5110         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5111         tree mangled_id;
5112
5113         switch (mode)
5114           {
5115           case AIPL_FUNCTION_DECLARATION:
5116             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5117                                                          &buffer [4]);
5118             purpose = build_wfl_node (mangled_id);
5119             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5120               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5121             else
5122               value = TREE_TYPE (field);
5123             break;
5124
5125           case AIPL_FUNCTION_CREATION:
5126             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (purpose,
5127                                                          &buffer [4]);
5128             value = TREE_TYPE (field);
5129             break;
5130
5131           case AIPL_FUNCTION_FINIT_INVOCATION:
5132             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
5133                                                          &buffer [4]);
5134             /* Now, this is wrong. purpose should always be the NAME
5135                of something and value its matching value (decl, type,
5136                etc...) FIXME -- but there is a lot to fix. */
5137
5138             /* When invoked for this kind of operation, we already
5139                know whether a field is used or not. */
5140             purpose = TREE_TYPE (field);
5141             value = build_wfl_node (mangled_id);
5142             break;
5143
5144           case AIPL_FUNCTION_CTOR_INVOCATION:
5145             /* There are two case: the constructor invokation happends
5146                outside the local inner, in which case, locales from the outer
5147                context are directly used.
5148
5149                Otherwise, we fold to using the alias directly. */
5150             if (class_type == current_class)
5151               value = field;
5152             else
5153               {
5154                 name = get_identifier (&buffer[4]);
5155                 value = IDENTIFIER_LOCAL_VALUE (name);
5156               }
5157             break;
5158           }
5159         additional_parms = tree_cons (purpose, value, additional_parms);
5160         if (artificial)
5161           *artificial +=1;
5162       }
5163   if (additional_parms)
5164     {
5165       if (ANONYMOUS_CLASS_P (class_type) 
5166           && mode == AIPL_FUNCTION_CTOR_INVOCATION)
5167         additional_parms = nreverse (additional_parms);
5168       parm = chainon (additional_parms, parm);
5169     }
5170
5171    return parm;
5172 }
5173
5174 /* Craft a constructor for CLASS_DECL -- what we should do when none
5175    where found. ARGS is non NULL when a special signature must be
5176    enforced. This is the case for anonymous classes.  */
5177
5178 static void
5179 craft_constructor (class_decl, args)
5180      tree class_decl, args;
5181 {
5182   tree class_type = TREE_TYPE (class_decl);
5183   tree parm = NULL_TREE;
5184   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5185                ACC_PUBLIC : 0);
5186   int i = 0, artificial = 0;
5187   tree decl, ctor_name;
5188   char buffer [80];
5189   
5190   /* The constructor name is <init> unless we're dealing with an
5191      anonymous class, in which case the name will be fixed after having
5192      be expanded. */
5193   if (ANONYMOUS_CLASS_P (class_type))
5194     ctor_name = DECL_NAME (class_decl);
5195   else
5196     ctor_name = init_identifier_node;
5197
5198   /* If we're dealing with an inner class constructor, we hide the
5199      this$<n> decl in the name field of its parameter declaration. */
5200   if (PURE_INNER_CLASS_TYPE_P (class_type))
5201     {
5202       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5203       parm = tree_cons (build_current_thisn (class_type),
5204                         build_pointer_type (type), parm);
5205
5206       /* Some more arguments to be hidden here. The values of the local
5207          variables of the outer context that the inner class needs to see. */
5208       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5209                                                      class_type, parm, 
5210                                                      &artificial);
5211     }
5212
5213   /* Then if there are any args to be enforced, enforce them now */
5214   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5215     {
5216       sprintf (buffer, "parm%d", i++);
5217       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5218     }
5219
5220   CRAFTED_PARAM_LIST_FIXUP (parm);
5221   decl = create_artificial_method (class_type, flags, void_type_node, 
5222                                    ctor_name, parm);
5223   fix_method_argument_names (parm, decl);
5224   /* Now, mark the artificial parameters. */
5225   DECL_FUNCTION_NAP (decl) = artificial;
5226   DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
5227 }
5228
5229
5230 /* Fix the constructors. This will be called right after circular
5231    references have been checked. It is necessary to fix constructors
5232    early even if no code generation will take place for that class:
5233    some generated constructor might be required by the class whose
5234    compilation triggered this one to be simply loaded.  */
5235
5236 void
5237 java_fix_constructors ()
5238 {
5239   tree current;
5240
5241   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5242     {
5243       tree class_type = TREE_TYPE (current);
5244       int saw_ctor = 0;
5245       tree decl;
5246
5247       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5248         continue;
5249
5250       current_class = class_type;
5251       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5252         {
5253           if (DECL_CONSTRUCTOR_P (decl))
5254             {
5255               fix_constructors (decl);
5256               saw_ctor = 1;
5257             }
5258         }
5259
5260       /* Anonymous class constructor can't be generated that early. */
5261       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5262         craft_constructor (current, NULL_TREE);
5263     }
5264 }
5265
5266 /* safe_layout_class just makes sure that we can load a class without
5267    disrupting the current_class, input_file, lineno, etc, information
5268    about the class processed currently.  */
5269
5270 void
5271 safe_layout_class (class)
5272      tree class;
5273 {
5274   tree save_current_class = current_class;
5275   const char *save_input_filename = input_filename;
5276   int save_lineno = lineno;
5277
5278   layout_class (class);
5279
5280   current_class = save_current_class;
5281   input_filename = save_input_filename;
5282   lineno = save_lineno;
5283 }
5284
5285 static tree
5286 jdep_resolve_class (dep)
5287      jdep *dep;
5288 {
5289   tree decl;
5290
5291   if (JDEP_RESOLVED_P (dep))
5292     decl = JDEP_RESOLVED_DECL (dep);
5293   else
5294     {
5295       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5296                             JDEP_DECL (dep), JDEP_WFL (dep));
5297       JDEP_RESOLVED (dep, decl);
5298     }
5299     
5300   if (!decl)
5301     complete_class_report_errors (dep);
5302   else if (PURE_INNER_CLASS_DECL_P (decl))
5303     {
5304       tree inner = TREE_TYPE (decl);
5305       if (! CLASS_LOADED_P (inner))
5306         {
5307           safe_layout_class (inner);
5308           if (TYPE_SIZE (inner) == error_mark_node)
5309             TYPE_SIZE (inner) = NULL_TREE;
5310         }
5311       check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
5312     }
5313   return decl;
5314 }
5315
5316 /* Complete unsatisfied class declaration and their dependencies */
5317
5318 void
5319 java_complete_class ()
5320 {
5321   tree cclass;
5322   jdeplist *cclassd;
5323   int error_found;
5324   tree type;
5325
5326   /* Process imports */
5327   process_imports ();
5328
5329   /* Rever things so we have the right order */
5330   ctxp->class_list = nreverse (ctxp->class_list);
5331   ctxp->classd_list = reverse_jdep_list (ctxp);
5332
5333   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5334        cclass && cclassd; 
5335        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5336     {
5337       jdep *dep;
5338       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5339         {
5340           tree decl;
5341           if (!(decl = jdep_resolve_class (dep)))
5342             continue;
5343
5344           /* Now it's time to patch */
5345           switch (JDEP_KIND (dep))
5346             {
5347             case JDEP_SUPER:
5348               /* Simply patch super */
5349               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5350                 continue;
5351               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5352                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5353               break;
5354
5355             case JDEP_FIELD:
5356               {
5357                 /* We do part of the job done in add_field */
5358                 tree field_decl = JDEP_DECL (dep);
5359                 tree field_type = TREE_TYPE (decl);
5360                 if (TREE_CODE (field_type) == RECORD_TYPE)
5361                   field_type = promote_type (field_type);
5362                 TREE_TYPE (field_decl) = field_type;
5363                 DECL_ALIGN (field_decl) = 0;
5364                 DECL_USER_ALIGN (field_decl) = 0;
5365                 layout_decl (field_decl, 0);
5366                 SOURCE_FRONTEND_DEBUG 
5367                   (("Completed field/var decl `%s' with `%s'",
5368                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5369                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5370                 break;
5371               }
5372             case JDEP_METHOD:   /* We start patching a method */
5373             case JDEP_METHOD_RETURN:
5374               error_found = 0;
5375               while (1)
5376                 {
5377                   if (decl)
5378                     {
5379                       type = TREE_TYPE(decl);
5380                       if (TREE_CODE (type) == RECORD_TYPE)
5381                         type = promote_type (type);
5382                       JDEP_APPLY_PATCH (dep, type);
5383                       SOURCE_FRONTEND_DEBUG 
5384                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5385                            "Completing fct `%s' with ret type `%s'":
5386                            "Completing arg `%s' with type `%s'"),
5387                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5388                                               (JDEP_DECL_WFL (dep))),
5389                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5390                     }
5391                   else
5392                     error_found = 1;
5393                   dep = JDEP_CHAIN (dep);
5394                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5395                     break;
5396                   else
5397                     decl = jdep_resolve_class (dep);
5398                 }
5399               if (!error_found)
5400                 {
5401                   tree mdecl = JDEP_DECL (dep), signature;
5402                   /* Recompute and reset the signature, check first that
5403                      all types are now defined. If they're not,
5404                      dont build the signature. */
5405                   if (check_method_types_complete (mdecl))
5406                     {
5407                       signature = build_java_signature (TREE_TYPE (mdecl));
5408                       set_java_signature (TREE_TYPE (mdecl), signature);
5409                     }
5410                 }
5411               else
5412                 continue;
5413               break;
5414
5415             case JDEP_INTERFACE:
5416               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5417                                                 JDEP_WFL (dep)))
5418                 continue;
5419               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5420               break;
5421
5422             case JDEP_PARM:
5423             case JDEP_VARIABLE:
5424               type = TREE_TYPE(decl);
5425               if (TREE_CODE (type) == RECORD_TYPE)
5426                 type = promote_type (type);
5427               JDEP_APPLY_PATCH (dep, type);
5428               break;
5429
5430             case JDEP_TYPE:
5431               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5432               SOURCE_FRONTEND_DEBUG 
5433                 (("Completing a random type dependency on a '%s' node",
5434                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5435               break;
5436
5437             case JDEP_EXCEPTION:
5438               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5439               SOURCE_FRONTEND_DEBUG 
5440                 (("Completing `%s' `throws' argument node",
5441                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5442               break;
5443
5444             case JDEP_ANONYMOUS:
5445               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5446               break;
5447
5448             default:
5449               abort ();
5450             }
5451         }
5452     }
5453   return;
5454 }
5455
5456 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5457    array.  */
5458
5459 static tree
5460 resolve_class (enclosing, class_type, decl, cl)
5461      tree enclosing, class_type, decl, cl;
5462 {
5463   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5464   const char *base = name;
5465   tree resolved_type = TREE_TYPE (class_type);
5466   tree resolved_type_decl;
5467   
5468   if (resolved_type != NULL_TREE)
5469     {
5470       tree resolved_type_decl = TYPE_NAME (resolved_type);
5471       if (resolved_type_decl == NULL_TREE
5472           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5473         {
5474           resolved_type_decl = build_decl (TYPE_DECL,
5475                                            TYPE_NAME (class_type),
5476                                            resolved_type);
5477         }
5478       return resolved_type_decl;
5479     }
5480
5481   /* 1- Check to see if we have an array. If true, find what we really
5482      want to resolve  */
5483   while (name[0] == '[')
5484     name++;
5485   if (base != name)
5486     {
5487       TYPE_NAME (class_type) = get_identifier (name);
5488       WFL_STRIP_BRACKET (cl, cl);
5489     }
5490
5491   /* 2- Resolve the bare type */
5492   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5493                                                decl, cl)))
5494     return NULL_TREE;
5495   resolved_type = TREE_TYPE (resolved_type_decl);
5496
5497   /* 3- If we have and array, reconstruct the array down to its nesting */
5498   if (base != name)
5499     {
5500       while (base != name)
5501         {
5502           resolved_type = build_java_array_type (resolved_type, -1);
5503           name--;
5504         }
5505       /* A TYPE_NAME that is a TYPE_DECL was set in
5506          build_java_array_type, return it. */
5507       resolved_type_decl = TYPE_NAME (resolved_type);
5508     }
5509   TREE_TYPE (class_type) = resolved_type;
5510   return resolved_type_decl;
5511 }
5512
5513 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5514    are used to report error messages.  */
5515
5516 tree
5517 do_resolve_class (enclosing, class_type, decl, cl)
5518      tree enclosing, class_type, decl, cl;
5519 {
5520   tree new_class_decl;
5521
5522   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
5523      it is changed by find_in_imports{_on_demand} and (but it doesn't
5524      really matter) qualify_and_find */
5525
5526   /* 0- Search in the current class as an inner class */
5527
5528   /* Maybe some code here should be added to load the class or
5529      something, at least if the class isn't an inner class and ended
5530      being loaded from class file. FIXME. */
5531   while (enclosing)
5532     {
5533       tree intermediate;
5534
5535       if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
5536         return new_class_decl;
5537
5538       intermediate = enclosing;
5539       /* Explore enclosing contexts. */
5540       while (INNER_CLASS_DECL_P (intermediate))
5541         {
5542           intermediate = DECL_CONTEXT (intermediate);
5543           if ((new_class_decl = find_as_inner_class (intermediate, 
5544                                                      class_type, cl)))
5545             return new_class_decl;
5546         }
5547
5548       /* Now go to the upper classes, bail out if necessary. */
5549       enclosing = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
5550       if (!enclosing || enclosing == object_type_node)
5551         break;
5552
5553       if (TREE_CODE (enclosing) == POINTER_TYPE)
5554         enclosing = do_resolve_class (NULL, enclosing, NULL, NULL);
5555       else
5556         enclosing = TYPE_NAME (enclosing);
5557     }
5558
5559   /* 1- Check for the type in single imports. This will change
5560      TYPE_NAME() if something relevant is found */
5561   find_in_imports (class_type);
5562
5563   /* 2- And check for the type in the current compilation unit */
5564   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5565     {
5566       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5567           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5568         load_class (TYPE_NAME (class_type), 0);
5569       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5570     }
5571
5572   /* 3- Search according to the current package definition */
5573   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5574     {
5575       if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
5576                                              TYPE_NAME (class_type))))
5577         return new_class_decl;
5578     }
5579
5580   /* 4- Check the import on demands. Don't allow bar.baz to be
5581      imported from foo.* */
5582   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5583     if (find_in_imports_on_demand (class_type))
5584       return NULL_TREE;
5585
5586   /* If found in find_in_imports_on_demant, the type has already been
5587      loaded. */
5588   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5589     return new_class_decl;
5590
5591   /* 5- Try with a name qualified with the package name we've seen so far */
5592   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5593     {
5594       tree package;
5595
5596       /* If there is a current package (ctxp->package), it's the first
5597          element of package_list and we can skip it. */
5598       for (package = (ctxp->package ? 
5599                       TREE_CHAIN (package_list) : package_list);
5600            package; package = TREE_CHAIN (package))
5601         if ((new_class_decl = qualify_and_find (class_type,
5602                                                TREE_PURPOSE (package), 
5603                                                TYPE_NAME (class_type))))
5604           return new_class_decl;
5605     }
5606
5607   /* 5- Check an other compilation unit that bears the name of type */
5608   load_class (TYPE_NAME (class_type), 0);
5609   
5610   if (!cl)
5611     cl = lookup_cl (decl);
5612   
5613   /* If we don't have a value for CL, then we're being called recursively. 
5614      We can't check package access just yet, but it will be taken care of
5615      by the caller. */
5616   if (cl)
5617     {
5618       if (check_pkg_class_access (TYPE_NAME (class_type), cl))
5619         return NULL_TREE;
5620     }
5621   
5622   /* 6- Last call for a resolution */
5623   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5624 }
5625
5626 static tree
5627 qualify_and_find (class_type, package, name)
5628      tree class_type, package, name;
5629 {
5630   tree new_qualified = merge_qualified_name (package, name);
5631   tree new_class_decl;
5632
5633   if (!IDENTIFIER_CLASS_VALUE (new_qualified))
5634     load_class (new_qualified, 0);
5635   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
5636     {
5637       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5638           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5639         load_class (new_qualified, 0);
5640       TYPE_NAME (class_type) = new_qualified;
5641       return IDENTIFIER_CLASS_VALUE (new_qualified);
5642     }
5643   return NULL_TREE;
5644 }
5645
5646 /* Resolve NAME and lay it out (if not done and if not the current
5647    parsed class). Return a decl node. This function is meant to be
5648    called when type resolution is necessary during the walk pass.  */
5649
5650 static tree
5651 resolve_and_layout (something, cl)
5652      tree something;
5653      tree cl;
5654 {
5655   tree decl, decl_type;
5656
5657   /* Don't do that on the current class */
5658   if (something == current_class)
5659     return TYPE_NAME (current_class);
5660
5661   /* Don't do anything for void and other primitive types */
5662   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5663     return NULL_TREE;
5664
5665   /* Pointer types can be reall pointer types or fake pointers. When
5666      finding a real pointer, recheck for primitive types */
5667   if (TREE_CODE (something) == POINTER_TYPE)
5668     {
5669       if (TREE_TYPE (something))
5670         {
5671           something = TREE_TYPE (something);
5672           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5673             return NULL_TREE;
5674         }
5675       else
5676         something = TYPE_NAME (something);
5677     }
5678
5679   /* Don't do anything for arrays of primitive types */
5680   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5681       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5682     return NULL_TREE;
5683
5684   /* Something might be a WFL */
5685   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5686     something = EXPR_WFL_NODE (something);
5687
5688   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5689      TYPE_DECL or a real TYPE */
5690   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5691     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5692             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5693
5694   if (!(decl = resolve_no_layout (something, cl)))
5695     return NULL_TREE;
5696
5697   /* Resolve and layout if necessary */
5698   decl_type = TREE_TYPE (decl);
5699   layout_class_methods (decl_type);
5700   /* Check methods */
5701   if (CLASS_FROM_SOURCE_P (decl_type))
5702     java_check_methods (decl);
5703   /* Layout the type if necessary */ 
5704   if (decl_type != current_class && !CLASS_LOADED_P (decl_type))
5705     safe_layout_class (decl_type);
5706
5707   return decl;
5708 }
5709
5710 /* Resolve a class, returns its decl but doesn't perform any
5711    layout. The current parsing context is saved and restored */
5712
5713 static tree
5714 resolve_no_layout (name, cl)
5715      tree name, cl;
5716 {
5717   tree ptr, decl;
5718   BUILD_PTR_FROM_NAME (ptr, name);
5719   java_parser_context_save_global ();
5720   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5721   java_parser_context_restore_global ();
5722   
5723   return decl;
5724 }
5725
5726 /* Called when reporting errors. Skip leader '[' in a complex array
5727    type description that failed to be resolved.  */
5728
5729 static const char *
5730 purify_type_name (name)
5731      const char *name;
5732 {
5733   while (*name && *name == '[')
5734     name++;
5735   return name;
5736 }
5737
5738 /* The type CURRENT refers to can't be found. We print error messages.  */
5739
5740 static void
5741 complete_class_report_errors (dep)
5742      jdep *dep;
5743 {
5744   const char *name;
5745
5746   if (!JDEP_WFL (dep))
5747     return;
5748
5749   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5750   switch (JDEP_KIND (dep))
5751     {
5752     case JDEP_SUPER:
5753       parse_error_context  
5754         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5755          purify_type_name (name),
5756          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5757       break;
5758     case JDEP_FIELD:
5759       parse_error_context
5760         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5761          purify_type_name (name),
5762          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5763       break;
5764     case JDEP_METHOD:           /* Covers arguments */
5765       parse_error_context
5766         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5767          purify_type_name (name),
5768          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5769          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5770       break;
5771     case JDEP_METHOD_RETURN:    /* Covers return type */
5772       parse_error_context
5773         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
5774          purify_type_name (name),
5775          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
5776       break;
5777     case JDEP_INTERFACE:
5778       parse_error_context
5779         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
5780          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
5781          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
5782          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5783       break;
5784     case JDEP_VARIABLE:
5785       parse_error_context
5786         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
5787          purify_type_name (IDENTIFIER_POINTER 
5788                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
5789          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5790       break;
5791     case JDEP_EXCEPTION:        /* As specified by `throws' */
5792       parse_error_context 
5793           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
5794          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
5795       break;
5796     default:
5797       /* Fix for -Wall. Just break doing nothing. The error will be
5798          caught later */
5799       break;
5800     }
5801 }
5802
5803 /* Return a static string containing the DECL prototype string. If
5804    DECL is a constructor, use the class name instead of the form
5805    <init> */
5806
5807 static const char *
5808 get_printable_method_name (decl)
5809      tree decl;
5810 {
5811   const char *to_return;
5812   tree name = NULL_TREE;
5813
5814   if (DECL_CONSTRUCTOR_P (decl))
5815     {
5816       name = DECL_NAME (decl);
5817       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
5818     }
5819       
5820   to_return = lang_printable_name (decl, 0);
5821   if (DECL_CONSTRUCTOR_P (decl))
5822     DECL_NAME (decl) = name;
5823   
5824   return to_return;
5825 }
5826
5827 /* Track method being redefined inside the same class. As a side
5828    effect, set DECL_NAME to an IDENTIFIER (prior entering this
5829    function it's a FWL, so we can track errors more accurately.)  */
5830
5831 static int
5832 check_method_redefinition (class, method)
5833      tree class, method;
5834 {
5835   tree redef, sig;
5836
5837   /* There's no need to verify <clinit> and finit$ */
5838   if (DECL_CLINIT_P (method) || DECL_FINIT_P (method))
5839     return 0;
5840
5841   sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
5842   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
5843     {
5844       if (redef == method)
5845         break;
5846       if (DECL_NAME (redef) == DECL_NAME (method)
5847           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef))
5848           && !DECL_ARTIFICIAL (method))
5849         {
5850           parse_error_context 
5851             (DECL_FUNCTION_WFL (method), "Duplicate %s declaration `%s'",
5852              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
5853              get_printable_method_name (redef));
5854           return 1;
5855         }
5856     }
5857   return 0;
5858 }
5859
5860 /* Return 1 if check went ok, 0 otherwise.  */
5861 static int
5862 check_abstract_method_definitions (do_interface, class_decl, type)
5863      int do_interface;
5864      tree class_decl, type;
5865 {
5866   tree class = TREE_TYPE (class_decl);
5867   tree method, end_type;
5868   int ok = 1;
5869
5870   end_type = (do_interface ? object_type_node : type);
5871   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
5872     {
5873       tree other_super, other_method, method_sig, method_name;
5874       int found = 0;
5875       int end_type_reached = 0;
5876       
5877       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
5878         continue;
5879       
5880       /* Now verify that somewhere in between TYPE and CLASS,
5881          abstract method METHOD gets a non abstract definition
5882          that is inherited by CLASS.  */
5883       
5884       method_sig = build_java_signature (TREE_TYPE (method));
5885       method_name = DECL_NAME (method);
5886       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
5887         method_name = EXPR_WFL_NODE (method_name);
5888
5889       other_super = class;
5890       do {
5891         if (other_super == end_type)
5892           end_type_reached = 1;
5893         
5894         /* Method search */
5895         for (other_method = TYPE_METHODS (other_super); other_method;
5896             other_method = TREE_CHAIN (other_method))
5897           {
5898             tree s = build_java_signature (TREE_TYPE (other_method));
5899             tree other_name = DECL_NAME (other_method);
5900             
5901             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
5902               other_name = EXPR_WFL_NODE (other_name);
5903             if (!DECL_CLINIT_P (other_method)
5904                 && !DECL_CONSTRUCTOR_P (other_method)
5905                 && method_name == other_name
5906                 && method_sig == s
5907                 && !METHOD_ABSTRACT (other_method))
5908              {
5909                found = 1;
5910                break;
5911              }
5912           }
5913         other_super = CLASSTYPE_SUPER (other_super);
5914       } while (!end_type_reached);
5915  
5916       /* Report that abstract METHOD didn't find an implementation
5917          that CLASS can use. */
5918       if (!found)
5919         {
5920           char *t = xstrdup (lang_printable_name 
5921                             (TREE_TYPE (TREE_TYPE (method)), 0));
5922           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
5923           
5924           parse_error_context 
5925             (lookup_cl (class_decl),
5926              "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",
5927              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5928              t, lang_printable_name (method, 0), 
5929              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
5930               "interface" : "class"),
5931              IDENTIFIER_POINTER (ccn),
5932              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
5933              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
5934           ok = 0;
5935           free (t);
5936         }
5937     }
5938
5939   if (ok && do_interface)
5940     {
5941       /* Check for implemented interfaces. */
5942       int i;
5943       tree vector = TYPE_BINFO_BASETYPES (type);
5944       for (i = 1; ok && vector && i < TREE_VEC_LENGTH (vector); i++)
5945         {
5946           tree super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5947           ok = check_abstract_method_definitions (1, class_decl, super);
5948         }
5949     }
5950
5951   return ok;
5952 }
5953
5954 /* Check that CLASS_DECL somehow implements all inherited abstract
5955    methods.  */
5956
5957 static void
5958 java_check_abstract_method_definitions (class_decl)
5959      tree class_decl;
5960 {
5961   tree class = TREE_TYPE (class_decl);
5962   tree super, vector;
5963   int i;
5964
5965   if (CLASS_ABSTRACT (class_decl))
5966     return;
5967
5968   /* Check for inherited types */
5969   super = class;
5970   do {
5971     super = CLASSTYPE_SUPER (super);
5972     check_abstract_method_definitions (0, class_decl, super);
5973   } while (super != object_type_node);
5974
5975   /* Check for implemented interfaces. */
5976   vector = TYPE_BINFO_BASETYPES (class);
5977   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
5978     {
5979       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5980       check_abstract_method_definitions (1, class_decl, super);
5981     }
5982 }
5983
5984 /* Check all the types method DECL uses and return 1 if all of them
5985    are now complete, 0 otherwise. This is used to check whether its
5986    safe to build a method signature or not.  */
5987
5988 static int
5989 check_method_types_complete (decl)
5990      tree decl;
5991 {
5992   tree type = TREE_TYPE (decl);
5993   tree args;
5994
5995   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
5996     return 0;
5997   
5998   args = TYPE_ARG_TYPES (type);
5999   if (TREE_CODE (type) == METHOD_TYPE)
6000     args = TREE_CHAIN (args);
6001   for (; args != end_params_node; args = TREE_CHAIN (args))
6002     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
6003       return 0;
6004
6005   return 1;
6006 }
6007
6008 /* Visible interface to check methods contained in CLASS_DECL */
6009
6010 void
6011 java_check_methods (class_decl)
6012      tree class_decl;
6013 {
6014   if (CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)))
6015     return;
6016
6017   if (CLASS_INTERFACE (class_decl))
6018     java_check_abstract_methods (class_decl);
6019   else
6020     java_check_regular_methods (class_decl);
6021   
6022   CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)) = 1;
6023 }
6024
6025 /* Check all the methods of CLASS_DECL. Methods are first completed
6026    then checked according to regular method existance rules.  If no
6027    constructor for CLASS_DECL were encountered, then build its
6028    declaration.  */
6029
6030 static void
6031 java_check_regular_methods (class_decl)
6032      tree class_decl;
6033 {
6034   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
6035   tree method;
6036   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
6037   tree found = NULL_TREE;
6038   tree mthrows;
6039
6040   /* It is not necessary to check methods defined in java.lang.Object */
6041   if (class == object_type_node)
6042     return;
6043
6044   if (!TYPE_NVIRTUALS (class))
6045     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6046
6047   /* Should take interfaces into account. FIXME */
6048   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
6049     {
6050       tree sig;
6051       tree method_wfl = DECL_FUNCTION_WFL (method);
6052       int aflags;
6053
6054       /* Check for redefinitions */
6055       if (check_method_redefinition (class, method))
6056         continue;
6057
6058       /* If we see one constructor a mark so we don't generate the
6059          default one. Also skip other verifications: constructors
6060          can't be inherited hence hiden or overriden */
6061      if (DECL_CONSTRUCTOR_P (method))
6062        {
6063          saw_constructor = 1;
6064          continue;
6065        }
6066
6067       /* We verify things thrown by the method. They must inherits from
6068          java.lang.Throwable */
6069       for (mthrows = DECL_FUNCTION_THROWS (method);
6070            mthrows; mthrows = TREE_CHAIN (mthrows))
6071         {
6072           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
6073             parse_error_context 
6074               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
6075                IDENTIFIER_POINTER 
6076                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
6077         }
6078
6079       sig = build_java_argument_signature (TREE_TYPE (method));
6080       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
6081
6082       /* Inner class can't declare static methods */
6083       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
6084         {
6085           char *t = xstrdup (lang_printable_name (class, 0));
6086           parse_error_context 
6087             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
6088              lang_printable_name (method, 0), t);
6089           free (t);
6090         }
6091
6092       /* Nothing overrides or it's a private method. */
6093       if (!found)
6094         continue;
6095       if (METHOD_PRIVATE (found))
6096         {
6097           found = NULL_TREE;
6098           continue;
6099         }
6100
6101       /* If `found' is declared in an interface, make sure the
6102          modifier matches. */
6103       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6104           && clinit_identifier_node != DECL_NAME (found)
6105           && !METHOD_PUBLIC (method))
6106         {
6107           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6108           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6109                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6110                                lang_printable_name (method, 0),
6111                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6112         }
6113
6114       /* Can't override a method with the same name and different return
6115          types. */
6116       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6117         {
6118           char *t = xstrdup 
6119             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6120           parse_error_context 
6121             (method_wfl,
6122              "Method `%s' was defined with return type `%s' in class `%s'", 
6123              lang_printable_name (found, 0), t,
6124              IDENTIFIER_POINTER 
6125                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6126           free (t);
6127         }
6128
6129       aflags = get_access_flags_from_decl (found);
6130
6131       /* Can't override final. Can't override static. */
6132       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6133         {
6134           /* Static *can* override static */
6135           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6136             continue;
6137           parse_error_context 
6138             (method_wfl,
6139              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6140              (METHOD_FINAL (found) ? "Final" : "Static"),
6141              lang_printable_name (found, 0),
6142              (METHOD_FINAL (found) ? "final" : "static"),
6143              IDENTIFIER_POINTER
6144                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6145           continue;
6146         }
6147
6148       /* Static method can't override instance method. */
6149       if (METHOD_STATIC (method))
6150         {
6151           parse_error_context 
6152             (method_wfl,
6153              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6154              lang_printable_name (found, 0),
6155              IDENTIFIER_POINTER
6156                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6157           continue;
6158         }
6159
6160       /* - Overriding/hiding public must be public
6161          - Overriding/hiding protected must be protected or public
6162          - If the overriden or hidden method has default (package)
6163            access, then the overriding or hiding method must not be
6164            private; otherwise, a compile-time error occurs.  If
6165            `found' belongs to an interface, things have been already
6166            taken care of.  */
6167       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6168           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6169               || (METHOD_PROTECTED (found) 
6170                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6171               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6172                   && METHOD_PRIVATE (method))))
6173         {
6174           parse_error_context 
6175             (method_wfl,
6176              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6177              (METHOD_PUBLIC (method) ? "public" : 
6178               (METHOD_PRIVATE (method) ? "private" : "protected")),
6179              IDENTIFIER_POINTER (DECL_NAME 
6180                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6181           continue;
6182         }
6183
6184       /* Overriding methods must have compatible `throws' clauses on checked
6185          exceptions, if any */
6186       check_throws_clauses (method, method_wfl, found);
6187
6188       /* Inheriting multiple methods with the same signature. FIXME */
6189     }
6190   
6191   if (!TYPE_NVIRTUALS (class))
6192     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6193
6194   /* Search for inherited abstract method not yet implemented in this
6195      class.  */
6196   java_check_abstract_method_definitions (class_decl);
6197
6198   if (!saw_constructor)
6199     abort ();
6200 }
6201
6202 /* Return a non zero value if the `throws' clause of METHOD (if any)
6203    is incompatible with the `throws' clause of FOUND (if any).  */
6204
6205 static void
6206 check_throws_clauses (method, method_wfl, found)
6207      tree method, method_wfl, found;
6208 {
6209   tree mthrows, fthrows;
6210
6211   /* Can't check these things with class loaded from bytecode. FIXME */
6212   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6213     return;
6214
6215   for (mthrows = DECL_FUNCTION_THROWS (method);
6216        mthrows; mthrows = TREE_CHAIN (mthrows))
6217     {
6218       /* We don't verify unchecked expressions */
6219       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6220         continue;
6221       /* Checked expression must be compatible */
6222       for (fthrows = DECL_FUNCTION_THROWS (found); 
6223            fthrows; fthrows = TREE_CHAIN (fthrows))
6224         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6225           break;
6226       if (!fthrows)
6227         {
6228           parse_error_context 
6229             (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'",
6230              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6231              lang_printable_name (found, 0),
6232              IDENTIFIER_POINTER 
6233                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6234         }
6235     }
6236 }
6237
6238 /* Check abstract method of interface INTERFACE */
6239
6240 static void
6241 java_check_abstract_methods (interface_decl)
6242      tree interface_decl;
6243 {
6244   int i, n;
6245   tree method, basetype_vec, found;
6246   tree interface = TREE_TYPE (interface_decl);
6247
6248   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6249     {
6250       /* 2- Check for double definition inside the defining interface */
6251       if (check_method_redefinition (interface, method))
6252         continue;
6253
6254       /* 3- Overriding is OK as far as we preserve the return type and
6255          the thrown exceptions (FIXME) */
6256       found = lookup_java_interface_method2 (interface, method);
6257       if (found)
6258         {
6259           char *t;
6260           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6261           parse_error_context 
6262             (DECL_FUNCTION_WFL (found),
6263              "Method `%s' was defined with return type `%s' in class `%s'",
6264              lang_printable_name (found, 0), t,
6265              IDENTIFIER_POINTER 
6266                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6267           free (t);
6268           continue;
6269         }
6270     }
6271
6272   /* 4- Inherited methods can't differ by their returned types */
6273   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6274     return;
6275   n = TREE_VEC_LENGTH (basetype_vec);
6276   for (i = 0; i < n; i++)
6277     {
6278       tree sub_interface_method, sub_interface;
6279       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6280       if (!vec_elt)
6281         continue;
6282       sub_interface = BINFO_TYPE (vec_elt);
6283       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6284            sub_interface_method;
6285            sub_interface_method = TREE_CHAIN (sub_interface_method))
6286         {
6287           found = lookup_java_interface_method2 (interface, 
6288                                                  sub_interface_method);
6289           if (found && (found != sub_interface_method))
6290             {
6291               parse_error_context 
6292                 (lookup_cl (sub_interface_method),
6293                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6294                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6295                  lang_printable_name (found, 0),
6296                  IDENTIFIER_POINTER 
6297                    (DECL_NAME (TYPE_NAME 
6298                                (DECL_CONTEXT (sub_interface_method)))),
6299                  IDENTIFIER_POINTER 
6300                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6301             }
6302         }
6303     }
6304 }
6305
6306 /* Lookup methods in interfaces using their name and partial
6307    signature. Return a matching method only if their types differ.  */
6308
6309 static tree
6310 lookup_java_interface_method2 (class, method_decl)
6311      tree class, method_decl;
6312 {
6313   int i, n;
6314   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6315
6316   if (!basetype_vec)
6317     return NULL_TREE;
6318
6319   n = TREE_VEC_LENGTH (basetype_vec);
6320   for (i = 0; i < n; i++)
6321     {
6322       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6323       if ((BINFO_TYPE (vec_elt) != object_type_node)
6324           && (to_return = 
6325               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6326         return to_return;
6327     }
6328   for (i = 0; i < n; i++)
6329     {
6330       to_return = lookup_java_interface_method2 
6331         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6332       if (to_return)
6333         return to_return;
6334     }
6335
6336   return NULL_TREE;
6337 }
6338
6339 /* Lookup method using their name and partial signature. Return a
6340    matching method only if their types differ.  */
6341
6342 static tree
6343 lookup_java_method2 (clas, method_decl, do_interface)
6344      tree clas, method_decl;
6345      int do_interface;
6346 {
6347   tree method, method_signature, method_name, method_type, name;
6348
6349   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6350   name = DECL_NAME (method_decl);
6351   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6352                  EXPR_WFL_NODE (name) : name);
6353   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6354
6355   while (clas != NULL_TREE)
6356     {
6357       for (method = TYPE_METHODS (clas);
6358            method != NULL_TREE;  method = TREE_CHAIN (method))
6359         {
6360           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6361           tree name = DECL_NAME (method);
6362           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6363                EXPR_WFL_NODE (name) : name) == method_name
6364               && method_sig == method_signature 
6365               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6366             return method;
6367         }
6368       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6369     }
6370   return NULL_TREE;
6371 }
6372
6373 /* Return the line that matches DECL line number, and try its best to
6374    position the column number. Used during error reports.  */
6375
6376 static tree
6377 lookup_cl (decl)
6378      tree decl;
6379 {
6380   static tree cl = NULL_TREE;
6381   char *line, *found;
6382   
6383   if (!decl)
6384     return NULL_TREE;
6385
6386   if (cl == NULL_TREE)
6387     {
6388       cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6389       ggc_add_tree_root (&cl, 1);
6390     }
6391
6392   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6393   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6394
6395   line = java_get_line_col (EXPR_WFL_FILENAME (cl), 
6396                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6397
6398   found = strstr ((const char *)line, 
6399                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6400   if (found)
6401     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6402
6403   return cl;
6404 }
6405
6406 /* Look for a simple name in the single-type import list */
6407
6408 static tree
6409 find_name_in_single_imports (name)
6410      tree name;
6411 {
6412   tree node;
6413
6414   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6415     if (TREE_VALUE (node) == name)
6416       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6417
6418   return NULL_TREE;
6419 }
6420
6421 /* Process all single-type import. */
6422
6423 static int
6424 process_imports ()
6425 {
6426   tree import;
6427   int error_found;
6428
6429   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6430     {
6431       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6432       char *original_name;
6433
6434       obstack_grow0 (&temporary_obstack,
6435                      IDENTIFIER_POINTER (to_be_found),
6436                      IDENTIFIER_LENGTH (to_be_found));
6437       original_name = obstack_finish (&temporary_obstack);
6438
6439       /* Don't load twice something already defined. */
6440       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6441         continue;
6442       
6443       while (1)
6444         {
6445           tree left;
6446
6447           QUALIFIED_P (to_be_found) = 1;
6448           load_class (to_be_found, 0);
6449           error_found =
6450             check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6451           
6452           /* We found it, we can bail out */
6453           if (IDENTIFIER_CLASS_VALUE (to_be_found))
6454             break;
6455
6456           /* We haven't found it. Maybe we're trying to access an
6457              inner class.  The only way for us to know is to try again
6458              after having dropped a qualifier. If we can't break it further,
6459              we have an error. */
6460           if (breakdown_qualified (&left, NULL, to_be_found))
6461             break;
6462
6463           to_be_found = left;
6464         }
6465       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6466         {
6467           parse_error_context (TREE_PURPOSE (import),
6468                                "Class or interface `%s' not found in import",
6469                                original_name);
6470           error_found = 1;
6471         }
6472
6473       obstack_free (&temporary_obstack, original_name);
6474       if (error_found)
6475         return 1;
6476     }
6477   return 0;
6478 }
6479
6480 /* Possibly find and mark a class imported by a single-type import
6481    statement.  */
6482
6483 static void
6484 find_in_imports (class_type)
6485      tree class_type;
6486 {
6487   tree import;
6488
6489   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6490     if (TREE_VALUE (import) == TYPE_NAME (class_type))
6491       {
6492         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6493         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6494       }
6495 }
6496
6497 static int
6498 note_possible_classname (name, len)
6499      const char *name;
6500      int len;
6501 {
6502   tree node;
6503   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6504     len = len - 5;
6505   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6506     len = len - 6;
6507   else
6508     return 0;
6509   node = ident_subst (name, len, "", '/', '.', "");
6510   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6511   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6512   return 1;
6513 }
6514
6515 /* Read a import directory, gathering potential match for further type
6516    references. Indifferently reads a filesystem or a ZIP archive
6517    directory.  */
6518
6519 static void
6520 read_import_dir (wfl)
6521      tree wfl;
6522 {
6523   tree package_id = EXPR_WFL_NODE (wfl);
6524   const char *package_name = IDENTIFIER_POINTER (package_id);
6525   int package_length = IDENTIFIER_LENGTH (package_id);
6526   DIR *dirp = NULL;
6527   JCF *saved_jcf = current_jcf;
6528
6529   int found = 0;
6530   int k;
6531   void *entry;
6532   struct buffer filename[1];
6533
6534
6535   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6536     return;
6537   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6538
6539   BUFFER_INIT (filename);
6540   buffer_grow (filename, package_length + 100);
6541
6542   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6543     {
6544       const char *entry_name = jcf_path_name (entry);
6545       int entry_length = strlen (entry_name);
6546       if (jcf_path_is_zipfile (entry))
6547         {
6548           ZipFile *zipf;
6549           buffer_grow (filename, entry_length);
6550           memcpy (filename->data, entry_name, entry_length - 1);
6551           filename->data[entry_length-1] = '\0';
6552           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6553           if (zipf == NULL)
6554             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6555           else
6556             {
6557               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6558               BUFFER_RESET (filename);
6559               for (k = 0; k < package_length; k++)
6560                 {
6561                   char ch = package_name[k];
6562                   *filename->ptr++ = ch == '.' ? '/' : ch;
6563                 }
6564               *filename->ptr++ = '/';
6565
6566               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6567                 {
6568                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6569                   int current_entry_len = zipd->filename_length;
6570
6571                   if (current_entry_len >= BUFFER_LENGTH (filename)
6572                       && strncmp (filename->data, current_entry, 
6573                                   BUFFER_LENGTH (filename)) != 0)
6574                     continue;
6575                   found |= note_possible_classname (current_entry,
6576                                                     current_entry_len);
6577                 }
6578             }
6579         }
6580       else
6581         {
6582           BUFFER_RESET (filename);
6583           buffer_grow (filename, entry_length + package_length + 4);
6584           strcpy (filename->data, entry_name);
6585           filename->ptr = filename->data + entry_length;
6586           for (k = 0; k < package_length; k++)
6587             {
6588               char ch = package_name[k];
6589               *filename->ptr++ = ch == '.' ? '/' : ch;
6590             }
6591           *filename->ptr = '\0';
6592
6593           dirp = opendir (filename->data);
6594           if (dirp == NULL)
6595             continue;
6596           *filename->ptr++ = '/';
6597           for (;;)
6598             {
6599               int len; 
6600               const char *d_name;
6601               struct dirent *direntp = readdir (dirp);
6602               if (!direntp)
6603                 break;
6604               d_name = direntp->d_name;
6605               len = strlen (direntp->d_name);
6606               buffer_grow (filename, len+1);
6607               strcpy (filename->ptr, d_name);
6608               found |= note_possible_classname (filename->data + entry_length,
6609                                                 package_length+len+1);
6610             }
6611           if (dirp)
6612             closedir (dirp);
6613         }
6614     }
6615
6616   free (filename->data);
6617
6618   /* Here we should have a unified way of retrieving an entry, to be
6619      indexed. */
6620   if (!found)
6621     {
6622       static int first = 1;
6623       if (first)
6624         {
6625           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6626           java_error_count++;
6627           first = 0;
6628         }
6629       else
6630         parse_error_context (wfl, "Package `%s' not found in import",
6631                              package_name);
6632       current_jcf = saved_jcf;
6633       return;
6634     }
6635   current_jcf = saved_jcf;
6636 }
6637
6638 /* Possibly find a type in the import on demands specified
6639    types. Returns 1 if an error occured, 0 otherwise. Run throught the
6640    entire list, to detected potential double definitions.  */
6641                  
6642 static int
6643 find_in_imports_on_demand (class_type)
6644      tree class_type;
6645 {
6646   tree node, import, node_to_use = NULL_TREE;
6647   int seen_once = -1;
6648   tree cl = NULL_TREE;
6649
6650   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6651     {
6652       const char *id_name;
6653       obstack_grow (&temporary_obstack, 
6654                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6655                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6656       obstack_1grow (&temporary_obstack, '.');
6657       obstack_grow0 (&temporary_obstack, 
6658                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6659                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6660       id_name = obstack_finish (&temporary_obstack);
6661               
6662       node = maybe_get_identifier (id_name);
6663       if (node && IS_A_CLASSFILE_NAME (node))
6664         {
6665           if (seen_once < 0)
6666             {
6667               cl = TREE_PURPOSE (import);
6668               seen_once = 1;
6669               node_to_use = node;
6670             }
6671           else
6672             {
6673               seen_once++;
6674               parse_error_context 
6675                 (TREE_PURPOSE (import), 
6676                  "Type `%s' also potentially defined in package `%s'",
6677                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6678                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6679             }
6680         }
6681     }
6682
6683   if (seen_once == 1)
6684     {
6685       /* Setup lineno so that it refers to the line of the import (in
6686          case we parse a class file and encounter errors */
6687       tree decl;
6688       int saved_lineno = lineno;
6689       lineno = EXPR_WFL_LINENO (cl);
6690       TYPE_NAME (class_type) = node_to_use;
6691       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6692       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6693       /* If there is no DECL set for the class or if the class isn't
6694          loaded and not seen in source yet, the load */
6695       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6696                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6697         {
6698           load_class (node_to_use, 0);
6699           decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6700         }
6701       lineno = saved_lineno;
6702       if (! INNER_CLASS_P (TREE_TYPE (decl)))
6703         return check_pkg_class_access (TYPE_NAME (class_type), cl);
6704       else
6705         /* 6.6.1: Inner classes are subject to member access rules. */
6706         return 0;
6707     }
6708   else
6709     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6710 }
6711
6712 /* Add package NAME to the list of package encountered so far. To
6713    speed up class lookup in do_resolve_class, we make sure a
6714    particular package is added only once.  */
6715
6716 static void
6717 register_package (name)
6718      tree name;
6719 {
6720   static struct hash_table _pht, *pht = NULL;
6721
6722   if (!pht)
6723     {
6724       hash_table_init (&_pht, hash_newfunc, 
6725                        java_hash_hash_tree_node, java_hash_compare_tree_node);
6726       pht = &_pht;
6727     }
6728   
6729   if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
6730     {
6731       package_list = chainon (package_list, build_tree_list (name, NULL));
6732       hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
6733     }
6734 }
6735
6736 static tree
6737 resolve_package (pkg, next)
6738      tree pkg, *next;
6739 {
6740   tree current, acc;
6741   tree type_name = NULL_TREE;
6742   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6743
6744   /* The trick is to determine when the package name stops and were
6745      the name of something contained in the package starts. Then we
6746      return a fully qualified name of what we want to get. */
6747
6748   /* Do a quick search on well known package names */
6749   if (!strncmp (name, "java.lang.reflect", 17))
6750     {
6751       *next = 
6752         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6753       type_name = lookup_package_type (name, 17);
6754     }
6755   else if (!strncmp (name, "java.lang", 9))
6756     {
6757       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6758       type_name = lookup_package_type (name, 9);
6759     }
6760
6761   /* If we found something here, return */
6762   if (type_name)
6763     return type_name; 
6764
6765   *next = EXPR_WFL_QUALIFICATION (pkg);
6766
6767   /* Try to progressively construct a type name */
6768   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6769     for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
6770          current; current = TREE_CHAIN (current))
6771       {
6772         acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
6773         if ((type_name = resolve_no_layout (acc, NULL_TREE)))
6774           {
6775             type_name = acc;
6776             /* resolve_package should be used in a loop, hence we
6777                point at this one to naturally process the next one at
6778                the next iteration. */
6779             *next = current;
6780             break;
6781           }
6782       }
6783   return type_name;
6784 }
6785
6786 static tree
6787 lookup_package_type (name, from)
6788      const char *name;
6789      int from;
6790 {
6791   char subname [128];
6792   const char *sub = &name[from+1];
6793   while (*sub != '.' && *sub)
6794     sub++;
6795   strncpy (subname, name, sub-name);
6796   subname [sub-name] = '\0';
6797   return get_identifier (subname);
6798 }
6799
6800 /* Check accessibility of inner classes according to member access rules. 
6801    DECL is the inner class, ENCLOSING_DECL is the class from which the
6802    access is being attempted. */
6803
6804 static void
6805 check_inner_class_access (decl, enclosing_decl, cl)
6806      tree decl, enclosing_decl, cl;
6807 {
6808   const char *access;
6809   tree enclosing_decl_type;
6810
6811   /* We don't issue an error message when CL is null. CL can be null
6812      as a result of processing a JDEP crafted by source_start_java_method
6813      for the purpose of patching its parm decl. But the error would
6814      have been already trapped when fixing the method's signature.
6815      DECL can also be NULL in case of earlier errors. */
6816   if (!decl || !cl)
6817     return;
6818
6819   enclosing_decl_type = TREE_TYPE (enclosing_decl);
6820
6821   if (CLASS_PRIVATE (decl))
6822     {
6823       /* Access is permitted only within the body of the top-level
6824          class in which DECL is declared. */
6825       tree top_level = decl;
6826       while (DECL_CONTEXT (top_level))
6827         top_level = DECL_CONTEXT (top_level);      
6828       while (DECL_CONTEXT (enclosing_decl))
6829         enclosing_decl = DECL_CONTEXT (enclosing_decl);
6830       if (top_level == enclosing_decl)
6831         return;      
6832       access = "private";
6833     }
6834   else if (CLASS_PROTECTED (decl))
6835     {
6836       tree decl_context;
6837       /* Access is permitted from within the same package... */
6838       if (in_same_package (decl, enclosing_decl))
6839         return;
6840       
6841       /* ... or from within the body of a subtype of the context in which
6842          DECL is declared. */
6843       decl_context = DECL_CONTEXT (decl);
6844       while (enclosing_decl)
6845         {
6846           if (CLASS_INTERFACE (decl))
6847             {
6848               if (interface_of_p (TREE_TYPE (decl_context), 
6849                                   enclosing_decl_type))
6850                 return;
6851             }
6852           else
6853             {
6854               /* Eww. The order of the arguments is different!! */
6855               if (inherits_from_p (enclosing_decl_type, 
6856                                    TREE_TYPE (decl_context)))
6857                 return;
6858             }
6859           enclosing_decl = DECL_CONTEXT (enclosing_decl);
6860         }      
6861       access = "protected";
6862     }
6863   else if (! CLASS_PUBLIC (decl))
6864     {
6865       /* Access is permitted only from within the same package as DECL. */
6866       if (in_same_package (decl, enclosing_decl))
6867         return;
6868       access = "non-public";
6869     }
6870   else
6871     /* Class is public. */
6872     return;
6873
6874   parse_error_context (cl, "Nested %s %s is %s; cannot be accessed from here",
6875                        (CLASS_INTERFACE (decl) ? "interface" : "class"),
6876                        lang_printable_name (decl, 0), access);
6877 }
6878
6879 /* Accessibility check for top-level classes. If CLASS_NAME is in a foreign 
6880    package, it must be PUBLIC. Return 0 if no access violations were found, 
6881    1 otherwise.  */
6882
6883 static int
6884 check_pkg_class_access (class_name, cl)
6885      tree class_name;
6886      tree cl;
6887 {
6888   tree type;
6889
6890   if (!IDENTIFIER_CLASS_VALUE (class_name))
6891     return 0;
6892
6893   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
6894     return 0;
6895
6896   if (!CLASS_PUBLIC (TYPE_NAME (type)))
6897     {
6898       /* Access to a private class within the same package is
6899          allowed. */
6900       tree l, r;
6901       breakdown_qualified (&l, &r, class_name);
6902       if (!QUALIFIED_P (class_name) && !ctxp->package)
6903         /* Both in the empty package. */
6904         return 0;
6905       if (l == ctxp->package)
6906         /* Both in the same package. */
6907         return 0;
6908
6909       parse_error_context 
6910         (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
6911          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
6912          IDENTIFIER_POINTER (class_name));
6913       return 1;
6914     }
6915   return 0;
6916 }
6917
6918 /* Local variable declaration. */
6919
6920 static void
6921 declare_local_variables (modifier, type, vlist)
6922      int modifier;
6923      tree type;
6924      tree vlist;
6925 {
6926   tree decl, current, saved_type;
6927   tree type_wfl = NULL_TREE;
6928   int must_chain = 0;
6929   int final_p = 0;
6930
6931   /* Push a new block if statements were seen between the last time we
6932      pushed a block and now. Keep a count of blocks to close */
6933   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
6934     {
6935       tree b = enter_block ();
6936       BLOCK_IS_IMPLICIT (b) = 1;
6937     }
6938
6939   if (modifier)
6940     {
6941       int i;
6942       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
6943       if (modifier == ACC_FINAL)
6944         final_p = 1;
6945       else 
6946         {
6947           parse_error_context 
6948             (ctxp->modifier_ctx [i], 
6949              "Only `final' is allowed as a local variables modifier");
6950           return;
6951         }
6952     }
6953
6954   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
6955      hold the TYPE value if a new incomplete has to be created (as
6956      opposed to being found already existing and reused). */
6957   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
6958
6959   /* If TYPE is fully resolved and we don't have a reference, make one */
6960   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6961
6962   /* Go through all the declared variables */
6963   for (current = vlist, saved_type = type; current;
6964        current = TREE_CHAIN (current), type = saved_type)
6965     {
6966       tree other, real_type;
6967       tree wfl  = TREE_PURPOSE (current);
6968       tree name = EXPR_WFL_NODE (wfl);
6969       tree init = TREE_VALUE (current);
6970
6971       /* Process NAME, as it may specify extra dimension(s) for it */
6972       type = build_array_from_name (type, type_wfl, name, &name);
6973
6974       /* Variable redefinition check */
6975       if ((other = lookup_name_in_blocks (name)))
6976         {
6977           variable_redefinition_error (wfl, name, TREE_TYPE (other),
6978                                        DECL_SOURCE_LINE (other));
6979           continue;
6980         }
6981
6982       /* Type adjustment. We may have just readjusted TYPE because
6983          the variable specified more dimensions. Make sure we have
6984          a reference if we can and don't have one already. */
6985       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6986
6987       real_type = GET_REAL_TYPE (type);
6988       /* Never layout this decl. This will be done when its scope
6989          will be entered */
6990       decl = build_decl (VAR_DECL, name, real_type);
6991       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
6992       LOCAL_FINAL (decl) = final_p;
6993       BLOCK_CHAIN_DECL (decl);
6994       
6995       /* If doing xreferencing, replace the line number with the WFL
6996          compound value */
6997       if (flag_emit_xref)
6998         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
6999       
7000       /* Don't try to use an INIT statement when an error was found */
7001       if (init && java_error_count)
7002         init = NULL_TREE;
7003       
7004       /* Add the initialization function to the current function's code */
7005       if (init)
7006         {
7007           /* Name might have been readjusted */
7008           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
7009           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
7010           java_method_add_stmt (current_function_decl,
7011                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
7012                                                       init));
7013         }
7014     
7015       /* Setup dependency the type of the decl */
7016       if (must_chain)
7017         {
7018           jdep *dep;
7019           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
7020           dep = CLASSD_LAST (ctxp->classd_list);
7021           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
7022         }
7023     }
7024   SOURCE_FRONTEND_DEBUG (("Defined locals"));
7025 }
7026
7027 /* Called during parsing. Build decls from argument list.  */
7028
7029 static void
7030 source_start_java_method (fndecl)
7031      tree fndecl;
7032 {
7033   tree tem;
7034   tree parm_decl;
7035   int i;
7036
7037   if (!fndecl)
7038     return;
7039
7040   current_function_decl = fndecl;
7041
7042   /* New scope for the function */
7043   enter_block ();
7044   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
7045        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
7046     {
7047       tree type = TREE_VALUE (tem);
7048       tree name = TREE_PURPOSE (tem);
7049       
7050       /* If type is incomplete. Create an incomplete decl and ask for
7051          the decl to be patched later */
7052       if (INCOMPLETE_TYPE_P (type))
7053         {
7054           jdep *jdep;
7055           tree real_type = GET_REAL_TYPE (type);
7056           parm_decl = build_decl (PARM_DECL, name, real_type);
7057           type = obtain_incomplete_type (type);
7058           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
7059           jdep = CLASSD_LAST (ctxp->classd_list);
7060           JDEP_MISC (jdep) = name;
7061           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
7062         }
7063       else
7064         parm_decl = build_decl (PARM_DECL, name, type);
7065
7066       /* Remember if a local variable was declared final (via its
7067          TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
7068       if (ARG_FINAL_P (tem))
7069         {
7070           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (parm_decl);
7071           LOCAL_FINAL (parm_decl) = 1;
7072         }
7073
7074       BLOCK_CHAIN_DECL (parm_decl);
7075     }
7076   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7077   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
7078     nreverse (tem);
7079   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
7080   DECL_MAX_LOCALS (current_function_decl) = i;
7081 }
7082
7083 /* Called during parsing. Creates an artificial method declaration.  */
7084
7085 static tree
7086 create_artificial_method (class, flags, type, name, args)
7087      tree class;
7088      int flags;
7089      tree type, name, args;
7090 {
7091   tree mdecl;
7092
7093   java_parser_context_save_global ();
7094   lineno = 0;                                                               
7095   mdecl = make_node (FUNCTION_TYPE);                                
7096   TREE_TYPE (mdecl) = type;
7097   TYPE_ARG_TYPES (mdecl) = args;
7098   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
7099   java_parser_context_restore_global ();
7100   DECL_ARTIFICIAL (mdecl) = 1;                                      
7101   return mdecl;
7102 }
7103
7104 /* Starts the body if an artifical method.  */
7105
7106 static void
7107 start_artificial_method_body (mdecl)
7108      tree mdecl;
7109 {
7110   DECL_SOURCE_LINE (mdecl) = 1;
7111   DECL_SOURCE_LINE_MERGE (mdecl, 1);
7112   source_start_java_method (mdecl);
7113   enter_block ();
7114 }
7115
7116 static void
7117 end_artificial_method_body (mdecl)
7118      tree mdecl;
7119 {
7120   /* exit_block modifies DECL_FUNCTION_BODY (current_function_decl).
7121      It has to be evaluated first. (if mdecl is current_function_decl,
7122      we have an undefined behavior if no temporary variable is used.) */
7123   tree b = exit_block ();
7124   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = b;
7125   exit_block ();
7126 }
7127
7128 /* Terminate a function and expand its body.  */
7129
7130 static void
7131 source_end_java_method ()
7132 {
7133   tree fndecl = current_function_decl;
7134
7135   if (!fndecl)
7136     return;
7137
7138   java_parser_context_save_global ();
7139   lineno = ctxp->last_ccb_indent1;
7140
7141   /* Turn function bodies with only a NOP expr null, so they don't get
7142      generated at all and we won't get warnings when using the -W
7143      -Wall flags. */
7144   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7145     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7146
7147   /* Generate function's code */
7148   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7149       && ! flag_emit_class_files
7150       && ! flag_emit_xref)
7151     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7152
7153   /* pop out of its parameters */
7154   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7155   poplevel (1, 0, 1);
7156   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7157
7158   /* Generate rtl for function exit.  */
7159   if (! flag_emit_class_files && ! flag_emit_xref)
7160     {
7161       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7162       expand_function_end (input_filename, lineno, 0);
7163
7164       /* Run the optimizers and output assembler code for this function. */
7165       rest_of_compilation (fndecl);
7166     }
7167
7168   current_function_decl = NULL_TREE;
7169   java_parser_context_restore_global ();
7170 }
7171
7172 /* Record EXPR in the current function block. Complements compound
7173    expression second operand if necessary.  */
7174
7175 tree
7176 java_method_add_stmt (fndecl, expr)
7177      tree fndecl, expr;
7178 {
7179   if (!GET_CURRENT_BLOCK (fndecl))
7180     return NULL_TREE;
7181   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7182 }
7183
7184 static tree
7185 add_stmt_to_block (b, type, stmt)
7186      tree b, type, stmt;
7187 {
7188   tree body = BLOCK_EXPR_BODY (b), c;
7189   
7190   if (java_error_count)
7191     return body;
7192     
7193   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7194     return body;
7195
7196   BLOCK_EXPR_BODY (b) = c;
7197   TREE_SIDE_EFFECTS (c) = 1;
7198   return c;
7199 }
7200
7201 /* Add STMT to EXISTING if possible, otherwise create a new
7202    COMPOUND_EXPR and add STMT to it. */
7203
7204 static tree
7205 add_stmt_to_compound (existing, type, stmt)
7206      tree existing, type, stmt;
7207 {
7208   if (existing)
7209     return build (COMPOUND_EXPR, type, existing, stmt);
7210   else
7211     return stmt;
7212 }
7213
7214 void java_layout_seen_class_methods ()
7215 {
7216   tree previous_list = all_class_list;
7217   tree end = NULL_TREE;
7218   tree current;
7219
7220   while (1)
7221     {
7222       for (current = previous_list; 
7223            current != end; current = TREE_CHAIN (current))
7224         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7225       
7226       if (previous_list != all_class_list)
7227         {
7228           end = previous_list;
7229           previous_list = all_class_list;
7230         }
7231       else
7232         break;
7233     }
7234 }
7235
7236 void
7237 java_reorder_fields ()
7238 {
7239   static tree stop_reordering = NULL_TREE;
7240   static int initialized_p;
7241   tree current;
7242
7243   /* Register STOP_REORDERING with the garbage collector.  */
7244   if (!initialized_p)
7245     {
7246       ggc_add_tree_root (&stop_reordering, 1);
7247       initialized_p = 1;
7248     }
7249
7250   for (current = gclass_list; current; current = TREE_CHAIN (current))
7251     {
7252       current_class = TREE_TYPE (TREE_VALUE (current));
7253
7254       if (current_class == stop_reordering)
7255         break;
7256
7257       /* Reverse the fields, but leave the dummy field in front.
7258          Fields are already ordered for Object and Class */
7259       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7260           && current_class != class_type_node)
7261       {
7262         /* If the dummy field is there, reverse the right fields and
7263            just layout the type for proper fields offset */
7264         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7265           {
7266             tree fields = TYPE_FIELDS (current_class);
7267             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7268             TYPE_SIZE (current_class) = NULL_TREE;
7269           }
7270         /* We don't have a dummy field, we need to layout the class,
7271            after having reversed the fields */
7272         else
7273           {
7274             TYPE_FIELDS (current_class) = 
7275               nreverse (TYPE_FIELDS (current_class));
7276             TYPE_SIZE (current_class) = NULL_TREE;
7277           }
7278       }
7279     }
7280   stop_reordering = TREE_TYPE (TREE_VALUE (gclass_list));
7281 }
7282
7283 /* Layout the methods of all classes loaded in one way or another.
7284    Check methods of source parsed classes. Then reorder the
7285    fields and layout the classes or the type of all source parsed
7286    classes */
7287
7288 void
7289 java_layout_classes ()
7290 {
7291   tree current;
7292   int save_error_count = java_error_count;
7293
7294   /* Layout the methods of all classes seen so far */
7295   java_layout_seen_class_methods ();
7296   java_parse_abort_on_error ();
7297   all_class_list = NULL_TREE;
7298
7299   /* Then check the methods of all parsed classes */
7300   for (current = gclass_list; current; current = TREE_CHAIN (current))
7301     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7302       java_check_methods (TREE_VALUE (current));
7303   java_parse_abort_on_error ();
7304
7305   for (current = gclass_list; current; current = TREE_CHAIN (current))
7306     {
7307       current_class = TREE_TYPE (TREE_VALUE (current));
7308       layout_class (current_class);
7309
7310       /* Error reported by the caller */
7311       if (java_error_count)
7312         return;
7313     }
7314
7315   /* We might have reloaded classes durign the process of laying out
7316      classes for code generation. We must layout the methods of those
7317      late additions, as constructor checks might use them */
7318   java_layout_seen_class_methods ();
7319   java_parse_abort_on_error ();
7320 }
7321
7322 /* Expand methods in the current set of classes rememebered for
7323    generation.  */
7324
7325 static void
7326 java_complete_expand_classes ()
7327 {
7328   tree current;
7329
7330   do_not_fold = flag_emit_xref;
7331
7332   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7333     if (!INNER_CLASS_DECL_P (current))
7334       java_complete_expand_class (current);
7335 }
7336
7337 /* Expand the methods found in OUTER, starting first by OUTER's inner
7338    classes, if any.  */
7339
7340 static void
7341 java_complete_expand_class (outer)
7342      tree outer;
7343 {
7344   tree inner_list;
7345
7346   set_nested_class_simple_name_value (outer, 1); /* Set */
7347
7348   /* We need to go after all inner classes and start expanding them,
7349      starting with most nested ones. We have to do that because nested
7350      classes might add functions to outer classes */
7351
7352   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7353        inner_list; inner_list = TREE_CHAIN (inner_list))
7354     java_complete_expand_class (TREE_PURPOSE (inner_list));
7355
7356   java_complete_expand_methods (outer);
7357   set_nested_class_simple_name_value (outer, 0); /* Reset */
7358 }
7359
7360 /* Expand methods registered in CLASS_DECL. The general idea is that
7361    we expand regular methods first. This allows us get an estimate on
7362    how outer context local alias fields are really used so we can add
7363    to the constructor just enough code to initialize them properly (it
7364    also lets us generate finit$ correctly.) Then we expand the
7365    constructors and then <clinit>.  */
7366
7367 static void
7368 java_complete_expand_methods (class_decl)
7369      tree class_decl;
7370 {
7371   tree clinit, finit, decl, first_decl;
7372
7373   current_class = TREE_TYPE (class_decl);
7374
7375   /* Find whether the class has final variables */
7376   for (decl = TYPE_FIELDS (current_class); decl; decl = TREE_CHAIN (decl))
7377     if (FIELD_FINAL (decl))
7378       {
7379         TYPE_HAS_FINAL_VARIABLE (current_class) = 1;
7380         break;
7381       }
7382
7383   /* Initialize a new constant pool */
7384   init_outgoing_cpool ();
7385
7386   /* Pre-expand <clinit> to figure whether we really need it or
7387      not. If we do need it, we pre-expand the static fields so they're
7388      ready to be used somewhere else. <clinit> will be fully expanded
7389      after we processed the constructors. */
7390   first_decl = TYPE_METHODS (current_class);
7391   clinit = maybe_generate_pre_expand_clinit (current_class);
7392
7393   /* Then generate finit$ (if we need to) because constructor will
7394    try to use it.*/
7395   if (TYPE_FINIT_STMT_LIST (current_class))
7396     {
7397       finit = generate_finit (current_class);
7398       java_complete_expand_method (finit);
7399     }
7400
7401   /* Now do the constructors */
7402   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7403     {
7404       int no_body;
7405
7406       if (!DECL_CONSTRUCTOR_P (decl))
7407         continue;
7408       
7409       no_body = !DECL_FUNCTION_BODY (decl);
7410       /* Don't generate debug info on line zero when expanding a
7411          generated constructor. */
7412       if (no_body)
7413         restore_line_number_status (1);
7414
7415       /* Reset the final local variable assignment flags */
7416       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7417         reset_final_variable_local_assignment_flag (current_class);
7418
7419       java_complete_expand_method (decl);
7420
7421       /* Check for missed out final variable assignment */
7422       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7423         check_final_variable_local_assignment_flag (current_class, decl);
7424       
7425       if (no_body)
7426         restore_line_number_status (0);
7427     }
7428
7429   /* First, do the ordinary methods. */
7430   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7431     {
7432       /* Skip abstract or native methods -- but do handle native
7433          methods when generating JNI stubs.  */
7434       if (METHOD_ABSTRACT (decl)
7435           || (! flag_jni && METHOD_NATIVE (decl))
7436           || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7437         continue;
7438
7439       if (METHOD_NATIVE (decl))
7440         {
7441           tree body = build_jni_stub (decl);
7442           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7443         }
7444
7445       java_complete_expand_method (decl);
7446     }
7447
7448   /* If there is indeed a <clinit>, fully expand it now */
7449   if (clinit)
7450     {
7451       /* Reset the final local variable assignment flags */
7452       if (TYPE_HAS_FINAL_VARIABLE (current_class))
7453         reset_static_final_variable_assignment_flag (current_class);
7454       /* Prevent the use of `this' inside <clinit> */
7455       ctxp->explicit_constructor_p = 1;
7456       java_complete_expand_method (clinit);
7457       ctxp->explicit_constructor_p = 0;
7458       /* Check for missed out static final variable assignment */
7459       if (TYPE_HAS_FINAL_VARIABLE (current_class)
7460           && !CLASS_INTERFACE (class_decl))
7461         check_static_final_variable_assignment_flag (current_class);
7462     }
7463   
7464   /* We might have generated a class$ that we now want to expand */
7465   if (TYPE_DOT_CLASS (current_class))
7466     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7467
7468   /* Now verify constructor circularity (stop after the first one we
7469      prove wrong.) */
7470   if (!CLASS_INTERFACE (class_decl))
7471     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7472       if (DECL_CONSTRUCTOR_P (decl) 
7473           && verify_constructor_circularity (decl, decl))
7474         break;
7475
7476   /* Final check on the initialization of final variables. */
7477   if (TYPE_HAS_FINAL_VARIABLE (current_class))
7478     {
7479       check_final_variable_global_assignment_flag (current_class);
7480       /* If we have an interface, check for uninitialized fields. */
7481       if (CLASS_INTERFACE (class_decl))
7482         check_static_final_variable_assignment_flag (current_class);
7483     }
7484
7485   /* Save the constant pool. We'll need to restore it later. */
7486   TYPE_CPOOL (current_class) = outgoing_cpool;
7487 }
7488
7489 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7490    safely used in some other methods/constructors.  */
7491
7492 static tree
7493 maybe_generate_pre_expand_clinit (class_type)
7494      tree class_type;
7495 {
7496   tree current, mdecl;
7497
7498   if (!TYPE_CLINIT_STMT_LIST (class_type))
7499     return NULL_TREE;
7500
7501   /* Go through all static fields and pre expand them */
7502   for (current = TYPE_FIELDS (class_type); current; 
7503        current = TREE_CHAIN (current))
7504     if (FIELD_STATIC (current))
7505       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7506
7507   /* Then build the <clinit> method */
7508   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7509                                     clinit_identifier_node, end_params_node);
7510   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7511                        mdecl, NULL_TREE);
7512   start_artificial_method_body (mdecl);
7513
7514   /* We process the list of assignment we produced as the result of
7515      the declaration of initialized static field and add them as
7516      statement to the <clinit> method. */
7517   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7518        current = TREE_CHAIN (current))
7519     {
7520       tree stmt = current;
7521       /* We build the assignment expression that will initialize the
7522          field to its value. There are strict rules on static
7523          initializers (8.5). FIXME */
7524       if (TREE_CODE (stmt) != BLOCK && stmt != empty_stmt_node)
7525         stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
7526       java_method_add_stmt (mdecl, stmt);
7527     }
7528
7529   end_artificial_method_body (mdecl);
7530
7531   /* Now we want to place <clinit> as the last method (because we need
7532      it at least for interface so that it doesn't interfere with the
7533      dispatch table based lookup. */
7534   if (TREE_CHAIN (TYPE_METHODS (class_type)))
7535     {
7536       current = TREE_CHAIN (TYPE_METHODS (class_type));
7537       TYPE_METHODS (class_type) = current;
7538
7539       while (TREE_CHAIN (current))
7540         current = TREE_CHAIN (current);
7541
7542       TREE_CHAIN (current) = mdecl;
7543       TREE_CHAIN (mdecl) = NULL_TREE;
7544     }
7545
7546   return mdecl;
7547 }
7548
7549 /* Analyzes a method body and look for something that isn't a
7550    MODIFY_EXPR with a constant value.  */
7551
7552 static int
7553 analyze_clinit_body (bbody)
7554      tree bbody;
7555 {
7556   while (bbody)
7557     switch (TREE_CODE (bbody))
7558       {
7559       case BLOCK:
7560         bbody = BLOCK_EXPR_BODY (bbody);
7561         break;
7562         
7563       case EXPR_WITH_FILE_LOCATION:
7564         bbody = EXPR_WFL_NODE (bbody);
7565         break;
7566         
7567       case COMPOUND_EXPR:
7568         if (analyze_clinit_body (TREE_OPERAND (bbody, 0)))
7569           return 1;
7570         bbody = TREE_OPERAND (bbody, 1);
7571         break;
7572         
7573       case MODIFY_EXPR:
7574         /* Return 0 if the operand is constant, 1 otherwise.  */
7575         return ! TREE_CONSTANT (TREE_OPERAND (bbody, 1));
7576
7577       default:
7578         return 1;
7579       }
7580   return 0;
7581 }
7582
7583
7584 /* See whether we could get rid of <clinit>. Criteria are: all static
7585    final fields have constant initial values and the body of <clinit>
7586    is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
7587
7588 static int
7589 maybe_yank_clinit (mdecl)
7590      tree mdecl;
7591 {
7592   tree type, current;
7593   tree fbody, bbody;
7594   int found = 0;
7595   
7596   if (!DECL_CLINIT_P (mdecl))
7597     return 0;
7598
7599   /* If the body isn't empty, then we keep <clinit>. Note that if
7600      we're emitting classfiles, this isn't enough not to rule it
7601      out. */
7602   fbody = DECL_FUNCTION_BODY (mdecl);
7603   bbody = BLOCK_EXPR_BODY (fbody);
7604   if (bbody && bbody != error_mark_node)
7605     bbody = BLOCK_EXPR_BODY (bbody);
7606   else
7607     return 0;
7608   if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
7609     return 0;
7610   
7611   type = DECL_CONTEXT (mdecl);
7612   current = TYPE_FIELDS (type);
7613
7614   for (current = (current ? TREE_CHAIN (current) : current); 
7615        current; current = TREE_CHAIN (current))
7616     {
7617       tree f_init;
7618
7619       /* We're not interested in non static field */
7620       if (!FIELD_STATIC (current))
7621         continue;
7622
7623       /* Anything that isn't String or a basic type is ruled out -- or
7624          if we know how to deal with it (when doing things natively) we
7625          should generated an empty <clinit> so that SUID are computed
7626          correctly. */
7627       if (! JSTRING_TYPE_P (TREE_TYPE (current))
7628           && ! JNUMERIC_TYPE_P (TREE_TYPE (current)))
7629         break;
7630           
7631       f_init = DECL_INITIAL (current);
7632       /* If we're emitting native code, we want static final fields to
7633          have constant initializers. If we don't meet these
7634          conditions, we keep <clinit> */
7635       if (!flag_emit_class_files
7636           && !(FIELD_FINAL (current) && f_init && TREE_CONSTANT (f_init)))
7637         break;
7638       /* If we're emitting bytecode, we want static fields to have
7639          constant initializers or no initializer. If we don't meet
7640          these conditions, we keep <clinit> */
7641       if (flag_emit_class_files && f_init && !TREE_CONSTANT (f_init))
7642         break;
7643     }
7644
7645   /* Now we analyze the method body and look for something that
7646      isn't a MODIFY_EXPR */
7647   if (bbody == empty_stmt_node)
7648     found = 0;
7649   else
7650     found = analyze_clinit_body (bbody);
7651
7652   if (current || found)
7653     return 0;
7654
7655   /* Get rid of <clinit> in the class' list of methods */
7656   if (TYPE_METHODS (type) == mdecl)
7657     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
7658   else
7659     for (current = TYPE_METHODS (type); current; 
7660          current = TREE_CHAIN (current))
7661       if (TREE_CHAIN (current) == mdecl)
7662         {
7663           TREE_CHAIN (current) = TREE_CHAIN (mdecl);
7664           break;
7665         }
7666
7667   return 1;
7668 }
7669
7670
7671 /* Complete and expand a method.  */
7672
7673 static void
7674 java_complete_expand_method (mdecl)
7675      tree mdecl;
7676 {
7677   int yank_clinit = 0;
7678
7679   current_function_decl = mdecl;
7680   /* Fix constructors before expanding them */
7681   if (DECL_CONSTRUCTOR_P (mdecl))
7682     fix_constructors (mdecl);
7683   
7684   /* Expand functions that have a body */
7685   if (DECL_FUNCTION_BODY (mdecl))
7686     {
7687       tree fbody = DECL_FUNCTION_BODY (mdecl);
7688       tree block_body = BLOCK_EXPR_BODY (fbody);
7689       tree exception_copy = NULL_TREE;
7690       tree tem, *ptr;
7691
7692       current_function_decl = mdecl;
7693
7694       if (! quiet_flag)
7695         fprintf (stderr, " [%s.",
7696                  lang_printable_name (DECL_CONTEXT (mdecl), 0));
7697       announce_function (mdecl);
7698       if (! quiet_flag)
7699         fprintf (stderr, "]");
7700
7701       pushlevel (1);            /* Prepare for a parameter push */
7702       ptr = &DECL_ARGUMENTS (mdecl);
7703       tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7704       while (tem)
7705         {
7706           tree next = TREE_CHAIN (tem);
7707           tree type = TREE_TYPE (tem);
7708           if (PROMOTE_PROTOTYPES
7709               && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
7710               && INTEGRAL_TYPE_P (type))
7711             type = integer_type_node;
7712           DECL_ARG_TYPE (tem) = type;
7713           layout_decl (tem, 0);
7714           pushdecl (tem);
7715           *ptr = tem;
7716           ptr = &TREE_CHAIN (tem);
7717           tem = next;
7718         }
7719       *ptr = NULL_TREE;
7720       pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7721       lineno = DECL_SOURCE_LINE_FIRST (mdecl);
7722
7723       build_result_decl (mdecl);
7724
7725       current_this 
7726         = (!METHOD_STATIC (mdecl) ? 
7727            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7728
7729       /* Purge the `throws' list of unchecked exceptions. If we're
7730          doing xref, save a copy of the list and re-install it
7731          later. */
7732       if (flag_emit_xref)
7733         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7734
7735       purge_unchecked_exceptions (mdecl);
7736
7737       /* Install exceptions thrown with `throws' */
7738       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7739
7740       if (block_body != NULL_TREE)
7741         {
7742           block_body = java_complete_tree (block_body);
7743
7744           if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
7745             check_for_initialization (block_body);
7746           ctxp->explicit_constructor_p = 0;
7747         }
7748
7749       BLOCK_EXPR_BODY (fbody) = block_body;
7750
7751       /* If we saw a return but couldn't evaluate it properly, we'll
7752          have an error_mark_node here. */
7753       if (block_body != error_mark_node
7754           && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7755           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7756           && !flag_emit_xref)
7757         missing_return_error (current_function_decl);
7758
7759       /* Check wether we could just get rid of clinit, now the picture
7760          is complete. */
7761       if (!(yank_clinit = maybe_yank_clinit (mdecl)))
7762         complete_start_java_method (mdecl); 
7763       
7764       /* Don't go any further if we've found error(s) during the
7765          expansion */
7766       if (!java_error_count && !yank_clinit)
7767         source_end_java_method ();
7768       else
7769         {
7770           if (java_error_count)
7771             pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7772           poplevel (1, 0, 1);
7773         }
7774
7775       /* Pop the exceptions and sanity check */
7776       POP_EXCEPTIONS();
7777       if (currently_caught_type_list)
7778         abort ();
7779
7780       if (flag_emit_xref)
7781         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7782     }
7783 }
7784
7785 \f
7786
7787 /* This section of the code deals with accessing enclosing context
7788    fields either directly by using the relevant access to this$<n> or
7789    by invoking an access method crafted for that purpose.  */
7790
7791 /* Build the necessary access from an inner class to an outer
7792    class. This routine could be optimized to cache previous result
7793    (decl, current_class and returned access).  When an access method
7794    needs to be generated, it always takes the form of a read. It might
7795    be later turned into a write by calling outer_field_access_fix.  */
7796
7797 static tree
7798 build_outer_field_access (id, decl)
7799      tree id, decl;
7800 {
7801   tree access = NULL_TREE;
7802   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7803   tree decl_ctx = DECL_CONTEXT (decl);
7804
7805   /* If the immediate enclosing context of the current class is the
7806      field decl's class or inherits from it; build the access as
7807      `this$<n>.<field>'. Note that we will break the `private' barrier
7808      if we're not emitting bytecodes. */
7809   if ((ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
7810       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7811     {
7812       tree thisn = build_current_thisn (current_class);
7813       access = make_qualified_primary (build_wfl_node (thisn), 
7814                                        id, EXPR_WFL_LINECOL (id));
7815     }
7816   /* Otherwise, generate access methods to outer this and access the
7817      field (either using an access method or by direct access.) */
7818   else
7819     {
7820       int lc = EXPR_WFL_LINECOL (id);
7821
7822       /* Now we chain the required number of calls to the access$0 to
7823          get a hold to the enclosing instance we need, and then we
7824          build the field access. */
7825       access = build_access_to_thisn (current_class, decl_ctx, lc);
7826
7827       /* If the field is private and we're generating bytecode, then
7828          we generate an access method */
7829       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7830         {
7831           tree name = build_outer_field_access_methods (decl);
7832           access = build_outer_field_access_expr (lc, decl_ctx,
7833                                                   name, access, NULL_TREE);
7834         }
7835       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7836          Once again we break the `private' access rule from a foreign
7837          class. */
7838       else
7839         access = make_qualified_primary (access, id, lc);
7840     }
7841   return resolve_expression_name (access, NULL);
7842 }
7843
7844 /* Return a non zero value if NODE describes an outer field inner
7845    access.  */
7846
7847 static int
7848 outer_field_access_p (type, decl)
7849     tree type, decl;
7850 {
7851   if (!INNER_CLASS_TYPE_P (type) 
7852       || TREE_CODE (decl) != FIELD_DECL
7853       || DECL_CONTEXT (decl) == type)
7854     return 0;
7855   
7856   /* If the inner class extends the declaration context of the field
7857      we're try to acces, then this isn't an outer field access */
7858   if (inherits_from_p (type, DECL_CONTEXT (decl)))
7859     return 0;
7860
7861   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7862        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7863     {
7864       if (type == DECL_CONTEXT (decl))
7865         return 1;
7866
7867       if (!DECL_CONTEXT (TYPE_NAME (type)))
7868         {
7869           /* Before we give up, see whether the field is inherited from
7870              the enclosing context we're considering. */
7871           if (inherits_from_p (type, DECL_CONTEXT (decl)))
7872             return 1;
7873           break;
7874         }
7875     }
7876
7877   return 0;
7878 }
7879
7880 /* Return a non zero value if NODE represents an outer field inner
7881    access that was been already expanded. As a side effect, it returns
7882    the name of the field being accessed and the argument passed to the
7883    access function, suitable for a regeneration of the access method
7884    call if necessary. */
7885
7886 static int
7887 outer_field_expanded_access_p (node, name, arg_type, arg)
7888     tree node, *name, *arg_type, *arg;
7889 {
7890   int identified = 0;
7891
7892   if (TREE_CODE (node) != CALL_EXPR)
7893     return 0;
7894
7895   /* Well, gcj generates slightly different tree nodes when compiling
7896      to native or bytecodes. It's the case for function calls. */
7897
7898   if (flag_emit_class_files 
7899       && TREE_CODE (node) == CALL_EXPR
7900       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7901     identified = 1;
7902   else if (!flag_emit_class_files)
7903     {
7904       node = TREE_OPERAND (node, 0);
7905       
7906       if (node && TREE_OPERAND (node, 0)
7907           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7908         {
7909           node = TREE_OPERAND (node, 0);
7910           if (TREE_OPERAND (node, 0)
7911               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7912               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
7913                   (DECL_NAME (TREE_OPERAND (node, 0)))))
7914             identified = 1;
7915         }
7916     }
7917
7918   if (identified && name && arg_type && arg)
7919     {
7920       tree argument = TREE_OPERAND (node, 1);
7921       *name = DECL_NAME (TREE_OPERAND (node, 0));
7922       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7923       *arg = TREE_VALUE (argument);
7924     }
7925   return identified;
7926 }
7927
7928 /* Detect in NODE an outer field read access from an inner class and
7929    transform it into a write with RHS as an argument. This function is
7930    called from the java_complete_lhs when an assignment to a LHS can
7931    be identified. */
7932
7933 static tree
7934 outer_field_access_fix (wfl, node, rhs)
7935     tree wfl, node, rhs;
7936 {
7937   tree name, arg_type, arg;
7938   
7939   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7940     {
7941       /* At any rate, check whether we're trying to assign a value to
7942          a final. */
7943       tree accessed = (JDECL_P (node) ? node : 
7944                        (TREE_CODE (node) == COMPONENT_REF ? 
7945                         TREE_OPERAND (node, 1) : node));
7946       if (check_final_assignment (accessed, wfl))
7947         return error_mark_node;
7948   
7949       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
7950                                             arg_type, name, arg, rhs);
7951       return java_complete_tree (node);
7952     }
7953   return NULL_TREE;
7954 }
7955
7956 /* Construct the expression that calls an access method:
7957      <type>.access$<n>(<arg1> [, <arg2>]); 
7958
7959    ARG2 can be NULL and will be omitted in that case. It will denote a
7960    read access.  */
7961
7962 static tree
7963 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
7964     int lc;
7965     tree type, access_method_name, arg1, arg2;
7966 {
7967   tree args, cn, access;
7968
7969   args = arg1 ? arg1 : 
7970     build_wfl_node (build_current_thisn (current_class));
7971   args = build_tree_list (NULL_TREE, args);
7972
7973   if (arg2)
7974     args = tree_cons (NULL_TREE, arg2, args);
7975
7976   access = build_method_invocation (build_wfl_node (access_method_name), args);
7977   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
7978   return make_qualified_primary (cn, access, lc);
7979 }
7980
7981 static tree
7982 build_new_access_id ()
7983 {
7984   static int access_n_counter = 1;
7985   char buffer [128];
7986
7987   sprintf (buffer, "access$%d", access_n_counter++);
7988   return get_identifier (buffer);
7989 }
7990
7991 /* Create the static access functions for the outer field DECL. We define a
7992    read:
7993      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
7994        return inst$.field;
7995      }
7996    and a write access:
7997      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
7998                                      TREE_TYPE (<field>) value$) {
7999        return inst$.field = value$;
8000      }
8001    We should have a usage flags on the DECL so we can lazily turn the ones
8002    we're using for code generation. FIXME.
8003 */
8004
8005 static tree
8006 build_outer_field_access_methods (decl)
8007     tree decl;
8008 {
8009   tree id, args, stmt, mdecl;
8010   
8011   if (FIELD_INNER_ACCESS_P (decl))
8012     return FIELD_INNER_ACCESS (decl);
8013
8014   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
8015  
8016   /* Create the identifier and a function named after it. */
8017   id = build_new_access_id ();
8018
8019   /* The identifier is marked as bearing the name of a generated write
8020      access function for outer field accessed from inner classes. */
8021   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8022
8023   /* Create the read access */
8024   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
8025   TREE_CHAIN (args) = end_params_node;
8026   stmt = make_qualified_primary (build_wfl_node (inst_id),
8027                                  build_wfl_node (DECL_NAME (decl)), 0);
8028   stmt = build_return (0, stmt);
8029   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8030                                            TREE_TYPE (decl), id, args, stmt);
8031   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8032
8033   /* Create the write access method. No write access for final variable */
8034   if (!FIELD_FINAL (decl))
8035     {
8036       args = build_tree_list (inst_id, 
8037                               build_pointer_type (DECL_CONTEXT (decl)));
8038       TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
8039       TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
8040       stmt = make_qualified_primary (build_wfl_node (inst_id),
8041                                      build_wfl_node (DECL_NAME (decl)), 0);
8042       stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
8043                                                 build_wfl_node (wpv_id)));
8044       mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
8045                                                TREE_TYPE (decl), id, 
8046                                                args, stmt);
8047     }
8048   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
8049
8050   /* Return the access name */
8051   return FIELD_INNER_ACCESS (decl) = id;
8052 }
8053
8054 /* Build an field access method NAME.  */
8055
8056 static tree 
8057 build_outer_field_access_method (class, type, name, args, body)
8058     tree class, type, name, args, body;
8059 {
8060   tree saved_current_function_decl, mdecl;
8061
8062   /* Create the method */
8063   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
8064   fix_method_argument_names (args, mdecl);
8065   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8066
8067   /* Attach the method body. */
8068   saved_current_function_decl = current_function_decl;
8069   start_artificial_method_body (mdecl);
8070   java_method_add_stmt (mdecl, body);
8071   end_artificial_method_body (mdecl);
8072   current_function_decl = saved_current_function_decl;
8073
8074   return mdecl;
8075 }
8076
8077 \f
8078 /* This section deals with building access function necessary for
8079    certain kinds of method invocation from inner classes.  */
8080
8081 static tree
8082 build_outer_method_access_method (decl)
8083     tree decl;
8084 {
8085   tree saved_current_function_decl, mdecl;
8086   tree args = NULL_TREE, call_args = NULL_TREE;
8087   tree carg, id, body, class;
8088   char buffer [80];
8089   int parm_id_count = 0;
8090
8091   /* Test this abort with an access to a private field */
8092   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
8093     abort ();
8094
8095   /* Check the cache first */
8096   if (DECL_FUNCTION_INNER_ACCESS (decl))
8097     return DECL_FUNCTION_INNER_ACCESS (decl);
8098
8099   class = DECL_CONTEXT (decl);
8100
8101   /* Obtain an access identifier and mark it */
8102   id = build_new_access_id ();
8103   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
8104
8105   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
8106   /* Create the arguments, as much as the original */
8107   for (; carg && carg != end_params_node; 
8108        carg = TREE_CHAIN (carg))
8109     {
8110       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
8111       args = chainon (args, build_tree_list (get_identifier (buffer), 
8112                                              TREE_VALUE (carg)));
8113     }
8114   args = chainon (args, end_params_node);
8115
8116   /* Create the method */
8117   mdecl = create_artificial_method (class, ACC_STATIC, 
8118                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
8119   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8120   /* There is a potential bug here. We should be able to use
8121      fix_method_argument_names, but then arg names get mixed up and
8122      eventually a constructor will have its this$0 altered and the
8123      outer context won't be assignment properly. The test case is
8124      stub.java FIXME */
8125   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
8126
8127   /* Attach the method body. */
8128   saved_current_function_decl = current_function_decl;
8129   start_artificial_method_body (mdecl);
8130
8131   /* The actual method invocation uses the same args. When invoking a
8132      static methods that way, we don't want to skip the first
8133      argument. */
8134   carg = args;
8135   if (!METHOD_STATIC (decl))
8136     carg = TREE_CHAIN (carg);
8137   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
8138     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
8139                            call_args);
8140
8141   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
8142                                   call_args);
8143   if (!METHOD_STATIC (decl))
8144     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
8145                                    body, 0);
8146   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
8147     body = build_return (0, body);
8148   java_method_add_stmt (mdecl,body);
8149   end_artificial_method_body (mdecl);
8150   current_function_decl = saved_current_function_decl;
8151
8152   /* Back tag the access function so it know what it accesses */
8153   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
8154
8155   /* Tag the current method so it knows it has an access generated */
8156   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
8157 }
8158
8159 \f
8160 /* This section of the code deals with building expressions to access
8161    the enclosing instance of an inner class. The enclosing instance is
8162    kept in a generated field called this$<n>, with <n> being the
8163    inner class nesting level (starting from 0.)  */
8164     
8165 /* Build an access to a given this$<n>, always chaining access call to
8166    others. Access methods to this$<n> are build on the fly if
8167    necessary. This CAN'T be used to solely access this$<n-1> from
8168    this$<n> (which alway yield to special cases and optimization, see
8169    for example build_outer_field_access).  */
8170
8171 static tree
8172 build_access_to_thisn (from, to, lc)
8173      tree from, to;
8174      int lc;
8175 {
8176   tree access = NULL_TREE;
8177
8178   while (from != to)
8179     {
8180       if (!access)
8181         {
8182           access = build_current_thisn (from);
8183           access = build_wfl_node (access);
8184         }
8185       else
8186         {
8187           tree access0_wfl, cn;
8188
8189           maybe_build_thisn_access_method (from);
8190           access0_wfl = build_wfl_node (access0_identifier_node);
8191           cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
8192           EXPR_WFL_LINECOL (access0_wfl) = lc;
8193           access = build_tree_list (NULL_TREE, access);
8194           access = build_method_invocation (access0_wfl, access);
8195           access = make_qualified_primary (cn, access, lc);
8196         }
8197
8198       /* if FROM isn't an inter class, that's fine, we've done
8199          enough. What we're looking for can be accessed from there. */
8200       from = DECL_CONTEXT (TYPE_NAME (from));
8201       if (!from)
8202         break;
8203       from = TREE_TYPE (from);
8204     }
8205   return access;
8206 }
8207
8208 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
8209    is returned if nothing needs to be generated. Otherwise, the method
8210    generated and a method decl is returned.  
8211
8212    NOTE: These generated methods should be declared in a class file
8213    attribute so that they can't be referred to directly.  */
8214
8215 static tree
8216 maybe_build_thisn_access_method (type)
8217     tree type;
8218 {
8219   tree mdecl, args, stmt, rtype;
8220   tree saved_current_function_decl;
8221
8222   /* If TYPE is a top-level class, no access method is required.
8223      If there already is such an access method, bail out. */
8224   if (CLASS_ACCESS0_GENERATED_P (type) || !PURE_INNER_CLASS_TYPE_P (type))
8225     return NULL_TREE;
8226
8227   /* We generate the method. The method looks like:
8228      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
8229   */
8230   args = build_tree_list (inst_id, build_pointer_type (type));
8231   TREE_CHAIN (args) = end_params_node;
8232   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
8233   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
8234                                     access0_identifier_node, args);
8235   fix_method_argument_names (args, mdecl);
8236   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
8237   stmt = build_current_thisn (type);
8238   stmt = make_qualified_primary (build_wfl_node (inst_id), 
8239                                  build_wfl_node (stmt), 0);
8240   stmt = build_return (0, stmt);
8241
8242   saved_current_function_decl = current_function_decl;
8243   start_artificial_method_body (mdecl);
8244   java_method_add_stmt (mdecl, stmt);
8245   end_artificial_method_body (mdecl);
8246   current_function_decl = saved_current_function_decl;
8247
8248   CLASS_ACCESS0_GENERATED_P (type) = 1;
8249
8250   return mdecl;
8251 }
8252
8253 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
8254    the first level of innerclassing. this$1 for the next one, etc...
8255    This function can be invoked with TYPE to NULL, available and then
8256    has to count the parser context.  */
8257
8258 static tree
8259 build_current_thisn (type)
8260     tree type;
8261 {
8262   static int saved_i = -1;
8263   static tree saved_thisn = NULL_TREE;
8264   static tree saved_type = NULL_TREE;
8265   static int saved_type_i = 0;
8266   static int initialized_p;
8267   tree decl;
8268   char buffer [80];
8269   int i = 0;
8270
8271   /* Register SAVED_THISN and SAVED_TYPE with the garbage collector.  */
8272   if (!initialized_p)
8273     {
8274       ggc_add_tree_root (&saved_thisn, 1);
8275       ggc_add_tree_root (&saved_type, 1);
8276       initialized_p = 1;
8277     }
8278
8279   if (type)
8280     {
8281       if (type == saved_type)
8282         i = saved_type_i;
8283       else
8284         {
8285           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
8286                decl; decl = DECL_CONTEXT (decl), i++)
8287             ;
8288       
8289           saved_type = type;
8290           saved_type_i = i;
8291         }
8292     }
8293   else
8294     i = list_length (GET_CPC_LIST ())-2;
8295
8296   if (i == saved_i)
8297     return saved_thisn;
8298     
8299   sprintf (buffer, "this$%d", i);
8300   saved_i = i;
8301   saved_thisn = get_identifier (buffer);
8302   return saved_thisn;
8303 }
8304
8305 /* Return the assignement to the hidden enclosing context `this$<n>'
8306    by the second incoming parameter to the innerclass constructor. The
8307    form used is `this.this$<n> = this$<n>;'.  */
8308
8309 static tree
8310 build_thisn_assign ()
8311 {
8312   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
8313     {
8314       tree thisn = build_current_thisn (current_class);
8315       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
8316                                          build_wfl_node (thisn), 0);
8317       tree rhs = build_wfl_node (thisn);
8318       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
8319       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
8320     }
8321   return NULL_TREE;
8322 }
8323
8324 \f
8325 /* Building the synthetic `class$' used to implement the `.class' 1.1
8326    extension for non primitive types. This method looks like:
8327
8328     static Class class$(String type) throws NoClassDefFoundError
8329     {
8330       try {return (java.lang.Class.forName (String));}
8331       catch (ClassNotFoundException e) {
8332         throw new NoClassDefFoundError(e.getMessage());}
8333     } */
8334
8335 static tree
8336 build_dot_class_method (class)
8337      tree class;
8338 {
8339 #define BWF(S) build_wfl_node (get_identifier ((S)))
8340 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8341   tree args, tmp, saved_current_function_decl, mdecl;
8342   tree stmt, throw_stmt, catch, catch_block, try_block;
8343   tree catch_clause_param;
8344   tree class_not_found_exception, no_class_def_found_error;
8345
8346   static tree get_message_wfl, type_parm_wfl;
8347
8348   if (!get_message_wfl)
8349     {
8350       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8351       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8352       ggc_add_tree_root (&get_message_wfl, 1);
8353       ggc_add_tree_root (&type_parm_wfl, 1);
8354     }
8355
8356   /* Build the arguments */
8357   args = build_tree_list (get_identifier ("type$"),
8358                           build_pointer_type (string_type_node));
8359   TREE_CHAIN (args) = end_params_node;
8360
8361   /* Build the qualified name java.lang.Class.forName */
8362   tmp = MQN (MQN (MQN (BWF ("java"), 
8363                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8364
8365   /* For things we have to catch and throw */
8366   class_not_found_exception = 
8367     lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8368   no_class_def_found_error = 
8369     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8370   load_class (class_not_found_exception, 1);
8371   load_class (no_class_def_found_error, 1);
8372
8373   /* Create the "class$" function */
8374   mdecl = create_artificial_method (class, ACC_STATIC, 
8375                                     build_pointer_type (class_type_node),
8376                                     classdollar_identifier_node, args);
8377   DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8378                                                   no_class_def_found_error);
8379   
8380   /* We start by building the try block. We need to build:
8381        return (java.lang.Class.forName (type)); */
8382   stmt = build_method_invocation (tmp, 
8383                                   build_tree_list (NULL_TREE, type_parm_wfl));
8384   stmt = build_return (0, stmt);
8385   /* Put it in a block. That's the try block */
8386   try_block = build_expr_block (stmt, NULL_TREE);
8387
8388   /* Now onto the catch block. We start by building the expression
8389      throwing a new exception: 
8390        throw new NoClassDefFoundError (_.getMessage); */
8391   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8392                                     get_message_wfl, 0);
8393   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8394   
8395   /* Build new NoClassDefFoundError (_.getMessage) */
8396   throw_stmt = build_new_invocation 
8397     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8398      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8399
8400   /* Build the throw, (it's too early to use BUILD_THROW) */
8401   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8402
8403   /* Build the catch block to encapsulate all this. We begin by
8404      building an decl for the catch clause parameter and link it to
8405      newly created block, the catch block. */
8406   catch_clause_param = 
8407     build_decl (VAR_DECL, wpv_id, 
8408                 build_pointer_type (class_not_found_exception));
8409   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8410   
8411   /* We initialize the variable with the exception handler. */
8412   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8413                  build_exception_object_ref (ptr_type_node));
8414   add_stmt_to_block (catch_block, NULL_TREE, catch);
8415
8416   /* We add the statement throwing the new exception */
8417   add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8418
8419   /* Build a catch expression for all this */
8420   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8421
8422   /* Build the try/catch sequence */
8423   stmt = build_try_statement (0, try_block, catch_block);
8424
8425   fix_method_argument_names (args, mdecl);
8426   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8427   saved_current_function_decl = current_function_decl;
8428   start_artificial_method_body (mdecl);
8429   java_method_add_stmt (mdecl, stmt);
8430   end_artificial_method_body (mdecl);
8431   current_function_decl = saved_current_function_decl;
8432   TYPE_DOT_CLASS (class) = mdecl;
8433
8434   return mdecl;
8435 }
8436
8437 static tree
8438 build_dot_class_method_invocation (type)
8439      tree type;
8440 {
8441   tree sig_id, s;
8442
8443   if (TYPE_ARRAY_P (type))
8444     sig_id = build_java_signature (type);
8445   else
8446     sig_id = DECL_NAME (TYPE_NAME (type));
8447
8448   s = build_string (IDENTIFIER_LENGTH (sig_id), 
8449                     IDENTIFIER_POINTER (sig_id));
8450   return build_method_invocation (build_wfl_node (classdollar_identifier_node),
8451                                   build_tree_list (NULL_TREE, s));
8452 }
8453
8454 /* This section of the code deals with constructor.  */
8455
8456 /* Craft a body for default constructor. Patch existing constructor
8457    bodies with call to super() and field initialization statements if
8458    necessary.  */
8459
8460 static void
8461 fix_constructors (mdecl)
8462      tree mdecl;
8463 {
8464   tree body = DECL_FUNCTION_BODY (mdecl);
8465   tree thisn_assign, compound = NULL_TREE;
8466   tree class_type = DECL_CONTEXT (mdecl);
8467
8468   if (DECL_FIXED_CONSTRUCTOR_P (mdecl))
8469     return;
8470   DECL_FIXED_CONSTRUCTOR_P (mdecl) = 1;
8471
8472   if (!body)
8473     {
8474       /* It is an error for the compiler to generate a default
8475          constructor if the superclass doesn't have a constructor that
8476          takes no argument, or the same args for an anonymous class */
8477       if (verify_constructor_super (mdecl))
8478         {
8479           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8480           tree save = DECL_NAME (mdecl);
8481           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8482           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8483           parse_error_context
8484             (lookup_cl (TYPE_NAME (class_type)), 
8485              "No constructor matching `%s' found in class `%s'",
8486              lang_printable_name (mdecl, 0), n);
8487           DECL_NAME (mdecl) = save;
8488         }
8489       
8490       /* The constructor body must be crafted by hand. It's the
8491          constructor we defined when we realize we didn't have the
8492          CLASSNAME() constructor */
8493       start_artificial_method_body (mdecl);
8494       
8495       /* Insert an assignment to the this$<n> hidden field, if
8496          necessary */
8497       if ((thisn_assign = build_thisn_assign ()))
8498         java_method_add_stmt (mdecl, thisn_assign);
8499
8500       /* We don't generate a super constructor invocation if we're
8501          compiling java.lang.Object. build_super_invocation takes care
8502          of that. */
8503       java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8504
8505       /* Insert the instance initializer block right here, after the
8506          super invocation. */
8507       add_instance_initializer (mdecl);
8508
8509       end_artificial_method_body (mdecl);
8510     }
8511   /* Search for an explicit constructor invocation */
8512   else 
8513     {
8514       int found = 0;
8515       tree found_call = NULL_TREE;
8516       tree main_block = BLOCK_EXPR_BODY (body);
8517       tree ii;                  /* Instance Initializer */
8518       
8519       while (body)
8520         switch (TREE_CODE (body))
8521           {
8522           case CALL_EXPR:
8523             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8524             body = NULL_TREE;
8525             break;
8526           case COMPOUND_EXPR:
8527           case EXPR_WITH_FILE_LOCATION:
8528             found_call = body;
8529             body = TREE_OPERAND (body, 0);
8530             break;
8531           case BLOCK:
8532             found_call = body;
8533             body = BLOCK_EXPR_BODY (body);
8534             break;
8535           default:
8536             found = 0;
8537             body = NULL_TREE;
8538           }
8539
8540       /* Generate the assignment to this$<n>, if necessary */
8541       if ((thisn_assign = build_thisn_assign ()))
8542         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8543
8544       /* The constructor is missing an invocation of super() */
8545       if (!found)
8546         compound = add_stmt_to_compound (compound, NULL_TREE,
8547                                          build_super_invocation (mdecl));
8548       /* Explicit super() invokation should take place before the
8549          instance initializer blocks. */
8550       else
8551         {
8552           compound = add_stmt_to_compound (compound, NULL_TREE,
8553                                            TREE_OPERAND (found_call, 0));
8554           TREE_OPERAND (found_call, 0) = empty_stmt_node;
8555         }
8556       
8557       /* Insert the instance initializer block right after. */
8558       if ((ii = build_instance_initializer (mdecl)))
8559         compound = add_stmt_to_compound (compound, NULL_TREE, ii);
8560
8561       /* Fix the constructor main block if we're adding extra stmts */
8562       if (compound)
8563         {
8564           compound = add_stmt_to_compound (compound, NULL_TREE,
8565                                            BLOCK_EXPR_BODY (main_block));
8566           BLOCK_EXPR_BODY (main_block) = compound;
8567         }
8568     }
8569 }
8570
8571 /* Browse constructors in the super class, searching for a constructor
8572    that doesn't take any argument. Return 0 if one is found, 1
8573    otherwise.  If the current class is an anonymous inner class, look
8574    for something that has the same signature. */
8575
8576 static int
8577 verify_constructor_super (mdecl)
8578      tree mdecl;
8579 {
8580   tree class = CLASSTYPE_SUPER (current_class);
8581   int super_inner = PURE_INNER_CLASS_TYPE_P (class);
8582   tree sdecl;
8583
8584   if (!class)
8585     return 0;
8586
8587   if (ANONYMOUS_CLASS_P (current_class))
8588     {
8589       tree mdecl_arg_type;
8590       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8591       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8592         if (DECL_CONSTRUCTOR_P (sdecl))
8593           {
8594             tree m_arg_type;
8595             tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8596             if (super_inner)
8597               arg_type = TREE_CHAIN (arg_type);
8598             for (m_arg_type = mdecl_arg_type; 
8599                  (arg_type != end_params_node 
8600                   && m_arg_type != end_params_node);
8601                  arg_type = TREE_CHAIN (arg_type), 
8602                    m_arg_type = TREE_CHAIN (m_arg_type))
8603               if (TREE_VALUE (arg_type) != TREE_VALUE (m_arg_type))
8604                 break;
8605
8606             if (arg_type == end_params_node && m_arg_type == end_params_node)
8607               return 0;
8608           }
8609     }
8610   else
8611     {
8612       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8613         {
8614           tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8615           if (super_inner)
8616             arg = TREE_CHAIN (arg);
8617           if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
8618             return 0;
8619         }
8620     }
8621   return 1;
8622 }
8623
8624 /* Generate code for all context remembered for code generation.  */
8625
8626 void
8627 java_expand_classes ()
8628 {
8629   int save_error_count = 0;
8630   static struct parser_ctxt *cur_ctxp = NULL;
8631
8632   java_parse_abort_on_error ();
8633   if (!(ctxp = ctxp_for_generation))
8634     return;
8635   java_layout_classes ();
8636   java_parse_abort_on_error ();
8637
8638   cur_ctxp = ctxp_for_generation;
8639   for (; cur_ctxp; cur_ctxp = cur_ctxp->next)
8640     {
8641       ctxp = cur_ctxp;
8642       input_filename = ctxp->filename;
8643       lang_init_source (2);            /* Error msgs have method prototypes */
8644       java_complete_expand_classes (); /* Complete and expand classes */
8645       java_parse_abort_on_error ();
8646     }
8647   input_filename = main_input_filename;
8648
8649   /* Find anonymous classes and expand their constructor, now they
8650      have been fixed. */
8651   for (cur_ctxp = ctxp_for_generation;  cur_ctxp;  cur_ctxp = cur_ctxp->next)
8652     {
8653       tree current;
8654       ctxp = cur_ctxp;
8655       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8656         {
8657           current_class = TREE_TYPE (current);
8658           if (ANONYMOUS_CLASS_P (current_class))
8659             {
8660               tree d;
8661               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8662                 {
8663                   if (DECL_CONSTRUCTOR_P (d))
8664                     {
8665                       restore_line_number_status (1);
8666                       java_complete_expand_method (d);
8667                       restore_line_number_status (0);
8668                       break;    /* We now there are no other ones */
8669                     }
8670                 }
8671             }
8672         }
8673     }
8674
8675   /* If we've found error at that stage, don't try to generate
8676      anything, unless we're emitting xrefs or checking the syntax only
8677      (but not using -fsyntax-only for the purpose of generating
8678      bytecode. */
8679   if (java_error_count && !flag_emit_xref 
8680       && (!flag_syntax_only && !flag_emit_class_files))
8681     return;
8682
8683   /* Now things are stable, go for generation of the class data. */
8684   for (cur_ctxp = ctxp_for_generation;  cur_ctxp;  cur_ctxp = cur_ctxp->next)
8685     {
8686       tree current;
8687       ctxp = cur_ctxp;
8688       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8689         {
8690           current_class = TREE_TYPE (current);
8691           outgoing_cpool = TYPE_CPOOL (current_class);
8692           if (flag_emit_class_files)
8693             write_classfile (current_class);
8694           if (flag_emit_xref)
8695             expand_xref (current_class);
8696           else if (! flag_syntax_only)
8697             finish_class ();
8698         }
8699     }
8700 }
8701
8702 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8703    a tree list node containing RIGHT. Fore coming RIGHTs will be
8704    chained to this hook. LOCATION contains the location of the
8705    separating `.' operator.  */
8706
8707 static tree
8708 make_qualified_primary (primary, right, location)
8709      tree primary, right;
8710      int location;
8711 {
8712   tree wfl;
8713
8714   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8715     wfl = build_wfl_wrap (primary, location);
8716   else
8717     {
8718       wfl = primary;
8719       /* If wfl wasn't qualified, we build a first anchor */
8720       if (!EXPR_WFL_QUALIFICATION (wfl))
8721         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8722     }
8723
8724   /* And chain them */
8725   EXPR_WFL_LINECOL (right) = location;
8726   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8727   PRIMARY_P (wfl) =  1;
8728   return wfl;
8729 }
8730
8731 /* Simple merge of two name separated by a `.' */
8732
8733 static tree
8734 merge_qualified_name (left, right)
8735      tree left, right;
8736 {
8737   tree node;
8738   if (!left && !right)
8739     return NULL_TREE;
8740
8741   if (!left)
8742     return right;
8743
8744   if (!right)
8745     return left;
8746
8747   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8748                 IDENTIFIER_LENGTH (left));
8749   obstack_1grow (&temporary_obstack, '.');
8750   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8751                  IDENTIFIER_LENGTH (right));
8752   node =  get_identifier (obstack_base (&temporary_obstack));
8753   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8754   QUALIFIED_P (node) = 1;
8755   return node;
8756 }
8757
8758 /* Merge the two parts of a qualified name into LEFT.  Set the
8759    location information of the resulting node to LOCATION, usually
8760    inherited from the location information of the `.' operator. */
8761
8762 static tree
8763 make_qualified_name (left, right, location)
8764      tree left, right;
8765      int location;
8766 {
8767 #ifdef USE_COMPONENT_REF
8768   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8769   EXPR_WFL_LINECOL (node) = location;
8770   return node;
8771 #else
8772   tree left_id = EXPR_WFL_NODE (left);
8773   tree right_id = EXPR_WFL_NODE (right);
8774   tree wfl, merge;
8775
8776   merge = merge_qualified_name (left_id, right_id);
8777
8778   /* Left wasn't qualified and is now qualified */
8779   if (!QUALIFIED_P (left_id))
8780     {
8781       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8782       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8783       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8784     }
8785   
8786   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8787   EXPR_WFL_LINECOL (wfl) = location;
8788   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8789
8790   EXPR_WFL_NODE (left) = merge;
8791   return left;
8792 #endif
8793 }
8794
8795 /* Extract the last identifier component of the qualified in WFL. The
8796    last identifier is removed from the linked list */
8797
8798 static tree
8799 cut_identifier_in_qualified (wfl)
8800      tree wfl;
8801 {
8802   tree q;
8803   tree previous = NULL_TREE;
8804   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8805     if (!TREE_CHAIN (q))
8806       {
8807         if (!previous)
8808           /* Operating on a non qualified qualified WFL.  */
8809           abort ();
8810
8811         TREE_CHAIN (previous) = NULL_TREE;
8812         return TREE_PURPOSE (q);
8813       }
8814 }
8815
8816 /* Resolve the expression name NAME. Return its decl.  */
8817
8818 static tree
8819 resolve_expression_name (id, orig)
8820      tree id;
8821      tree *orig;
8822 {
8823   tree name = EXPR_WFL_NODE (id);
8824   tree decl;
8825
8826   /* 6.5.5.1: Simple expression names */
8827   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8828     {
8829       /* 15.13.1: NAME can appear within the scope of a local variable
8830          declaration */
8831       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8832         return decl;
8833
8834       /* 15.13.1: NAME can appear within a class declaration */
8835       else 
8836         {
8837           decl = lookup_field_wrapper (current_class, name);
8838           if (decl)
8839             {
8840               tree access = NULL_TREE;
8841               int fs = FIELD_STATIC (decl);
8842
8843               /* If we're accessing an outer scope local alias, make
8844                  sure we change the name of the field we're going to
8845                  build access to. */
8846               if (FIELD_LOCAL_ALIAS_USED (decl))
8847                 name = DECL_NAME (decl);
8848
8849               /* Instance variable (8.3.1.1) can't appear within
8850                  static method, static initializer or initializer for
8851                  a static variable. */
8852               if (!fs && METHOD_STATIC (current_function_decl))
8853                 {
8854                   static_ref_err (id, name, current_class);
8855                   return error_mark_node;
8856                 }
8857               /* Instance variables can't appear as an argument of
8858                  an explicit constructor invocation */
8859               if (!fs && ctxp->explicit_constructor_p
8860                   && !enclosing_context_p (DECL_CONTEXT (decl), current_class))
8861                 {
8862                   parse_error_context
8863                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8864                   return error_mark_node;
8865                 }
8866
8867               /* If we're processing an inner class and we're trying
8868                  to access a field belonging to an outer class, build
8869                  the access to the field */
8870               if (!fs && outer_field_access_p (current_class, decl))
8871                 {
8872                   if (CLASS_STATIC (TYPE_NAME (current_class)))
8873                     {
8874                       static_ref_err (id, DECL_NAME (decl), current_class);
8875                       return error_mark_node;
8876                     }
8877                   return build_outer_field_access (id, decl);
8878                 }
8879
8880               /* Otherwise build what it takes to access the field */
8881               access = build_field_ref ((fs ? NULL_TREE : current_this),
8882                                         DECL_CONTEXT (decl), name);
8883               if (fs)
8884                 access = maybe_build_class_init_for_field (decl, access);
8885               /* We may be asked to save the real field access node */
8886               if (orig)
8887                 *orig = access;
8888               /* And we return what we got */
8889               return access;
8890             }
8891           /* Fall down to error report on undefined variable */
8892         }
8893     }
8894   /* 6.5.5.2 Qualified Expression Names */
8895   else
8896     {
8897       if (orig)
8898         *orig = NULL_TREE;
8899       qualify_ambiguous_name (id);
8900       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8901       /* 15.10.2: Accessing Superclass Members using super */
8902       return resolve_field_access (id, orig, NULL);
8903     }
8904
8905   /* We've got an error here */
8906   parse_error_context (id, "Undefined variable `%s'", 
8907                        IDENTIFIER_POINTER (name));
8908
8909   return error_mark_node;
8910 }
8911
8912 static void
8913 static_ref_err (wfl, field_id, class_type)
8914     tree wfl, field_id, class_type;
8915 {
8916   parse_error_context 
8917     (wfl, 
8918      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8919      IDENTIFIER_POINTER (field_id), 
8920      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8921 }
8922
8923 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8924    We return something suitable to generate the field access. We also
8925    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
8926    recipient's address can be null. */
8927
8928 static tree
8929 resolve_field_access (qual_wfl, field_decl, field_type)
8930      tree qual_wfl;
8931      tree *field_decl, *field_type;
8932 {
8933   int is_static = 0;
8934   tree field_ref;
8935   tree decl, where_found, type_found;
8936
8937   if (resolve_qualified_expression_name (qual_wfl, &decl,
8938                                          &where_found, &type_found))
8939     return error_mark_node;
8940
8941   /* Resolve the LENGTH field of an array here */
8942   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
8943       && type_found && TYPE_ARRAY_P (type_found) 
8944       && ! flag_emit_class_files && ! flag_emit_xref)
8945     {
8946       tree length = build_java_array_length_access (where_found);
8947       field_ref = length;
8948
8949       /* In case we're dealing with a static array, we need to
8950          initialize its class before the array length can be fetched.
8951          It's also a good time to create a DECL_RTL for the field if
8952          none already exists, otherwise if the field was declared in a
8953          class found in an external file and hasn't been (and won't
8954          be) accessed for its value, none will be created. */
8955       if (TREE_CODE (where_found) == VAR_DECL && FIELD_STATIC (where_found))
8956         {
8957           build_static_field_ref (where_found);
8958           field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
8959         }
8960     }
8961   /* We might have been trying to resolve field.method(). In which
8962      case, the resolution is over and decl is the answer */
8963   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
8964     field_ref = decl;
8965   else if (JDECL_P (decl))
8966     {
8967       if (!type_found)
8968         type_found = DECL_CONTEXT (decl);
8969       is_static = FIELD_STATIC (decl);
8970       field_ref = build_field_ref ((is_static && !flag_emit_xref? 
8971                                     NULL_TREE : where_found), 
8972                                    type_found, DECL_NAME (decl));
8973       if (field_ref == error_mark_node)
8974         return error_mark_node;
8975       if (is_static)
8976         field_ref = maybe_build_class_init_for_field (decl, field_ref);
8977     }
8978   else
8979     field_ref = decl;
8980
8981   if (field_decl)
8982     *field_decl = decl;
8983   if (field_type)
8984     *field_type = (QUAL_DECL_TYPE (decl) ? 
8985                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
8986   return field_ref;
8987 }
8988
8989 /* If NODE is an access to f static field, strip out the class
8990    initialization part and return the field decl, otherwise, return
8991    NODE. */
8992
8993 static tree
8994 strip_out_static_field_access_decl (node)
8995     tree node;
8996 {
8997   if (TREE_CODE (node) == COMPOUND_EXPR)
8998     {
8999       tree op1 = TREE_OPERAND (node, 1);
9000       if (TREE_CODE (op1) == COMPOUND_EXPR)
9001          {
9002            tree call = TREE_OPERAND (op1, 0);
9003            if (TREE_CODE (call) == CALL_EXPR
9004                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
9005                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
9006                == soft_initclass_node)
9007              return TREE_OPERAND (op1, 1);
9008          }
9009       else if (JDECL_P (op1))
9010         return op1;
9011     }
9012   return node;
9013 }
9014
9015 /* 6.5.5.2: Qualified Expression Names */
9016
9017 static int
9018 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
9019      tree wfl;
9020      tree *found_decl, *type_found, *where_found;
9021 {
9022   int from_type = 0;            /* Field search initiated from a type */
9023   int from_super = 0, from_cast = 0, from_qualified_this = 0;
9024   int previous_call_static = 0;
9025   int is_static;
9026   tree decl = NULL_TREE, type = NULL_TREE, q;
9027   /* For certain for of inner class instantiation */
9028   tree saved_current, saved_this;               
9029 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
9030   { current_class = saved_current; current_this = saved_this;}
9031
9032   *type_found = *where_found = NULL_TREE;
9033
9034   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
9035     {
9036       tree qual_wfl = QUAL_WFL (q);
9037       tree ret_decl;            /* for EH checking */
9038       int location;             /* for EH checking */
9039
9040       /* 15.10.1 Field Access Using a Primary */
9041       switch (TREE_CODE (qual_wfl))
9042         {
9043         case CALL_EXPR:
9044         case NEW_CLASS_EXPR:
9045           /* If the access to the function call is a non static field,
9046              build the code to access it. */
9047           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9048             {
9049               decl = maybe_access_field (decl, *where_found, 
9050                                          DECL_CONTEXT (decl));
9051               if (decl == error_mark_node)
9052                 return 1;
9053             }
9054
9055           /* And code for the function call */
9056           if (complete_function_arguments (qual_wfl))
9057             return 1;
9058
9059           /* We might have to setup a new current class and a new this
9060              for the search of an inner class, relative to the type of
9061              a expression resolved as `decl'. The current values are
9062              saved and restored shortly after */
9063           saved_current = current_class;
9064           saved_this = current_this;
9065           if (decl 
9066               && (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9067                   || from_qualified_this))
9068             {
9069               /* If we still have `from_qualified_this', we have the form
9070                  <T>.this.f() and we need to build <T>.this */
9071               if (from_qualified_this)
9072                 {
9073                   decl = build_access_to_thisn (current_class, type, 0);
9074                   decl = java_complete_tree (decl);
9075                   type = TREE_TYPE (TREE_TYPE (decl));
9076                 }
9077               current_class = type;
9078               current_this = decl;
9079               from_qualified_this = 0;
9080             }
9081
9082           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
9083             CALL_USING_SUPER (qual_wfl) = 1;
9084           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
9085                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
9086           *where_found = patch_method_invocation (qual_wfl, decl, type,
9087                                                   from_super,
9088                                                   &is_static, &ret_decl);
9089           if (*where_found == error_mark_node)
9090             {
9091               RESTORE_THIS_AND_CURRENT_CLASS;
9092               return 1;
9093             }
9094           *type_found = type = QUAL_DECL_TYPE (*where_found);
9095
9096           /* If we're creating an inner class instance, check for that
9097              an enclosing instance is in scope */
9098           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
9099               && INNER_ENCLOSING_SCOPE_CHECK (type))
9100             {
9101               parse_error_context 
9102                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
9103                  lang_printable_name (type, 0),
9104                  (!current_this ? "" :
9105                   "; an explicit one must be provided when creating this inner class"));
9106               RESTORE_THIS_AND_CURRENT_CLASS;
9107               return 1;
9108             }
9109
9110           /* In case we had to change then to resolve a inner class
9111              instantiation using a primary qualified by a `new' */
9112           RESTORE_THIS_AND_CURRENT_CLASS;
9113
9114           /* EH check. No check on access$<n> functions */
9115           if (location 
9116               && !OUTER_FIELD_ACCESS_IDENTIFIER_P 
9117                     (DECL_NAME (current_function_decl)))
9118             check_thrown_exceptions (location, ret_decl);
9119
9120           /* If the previous call was static and this one is too,
9121              build a compound expression to hold the two (because in
9122              that case, previous function calls aren't transported as
9123              forcoming function's argument. */
9124           if (previous_call_static && is_static)
9125             {
9126               decl = build (COMPOUND_EXPR, type, decl, *where_found);
9127               TREE_SIDE_EFFECTS (decl) = 1;
9128             }
9129           else
9130             {
9131               previous_call_static = is_static;
9132               decl = *where_found;
9133             }
9134           from_type = 0;
9135           continue;
9136
9137         case NEW_ARRAY_EXPR:
9138         case NEW_ANONYMOUS_ARRAY_EXPR:
9139           *where_found = decl = java_complete_tree (qual_wfl);
9140           if (decl == error_mark_node)
9141             return 1;
9142           *type_found = type = QUAL_DECL_TYPE (decl);
9143           continue;
9144
9145         case CONVERT_EXPR:
9146           *where_found = decl = java_complete_tree (qual_wfl);
9147           if (decl == error_mark_node)
9148             return 1;
9149           *type_found = type = QUAL_DECL_TYPE (decl);
9150           from_cast = 1;
9151           continue;
9152
9153         case CONDITIONAL_EXPR:
9154         case STRING_CST:
9155         case MODIFY_EXPR:
9156           *where_found = decl = java_complete_tree (qual_wfl);
9157           if (decl == error_mark_node)
9158             return 1;
9159           *type_found = type = QUAL_DECL_TYPE (decl);
9160           continue;
9161
9162         case ARRAY_REF:
9163           /* If the access to the function call is a non static field,
9164              build the code to access it. */
9165           if (JDECL_P (decl) && !FIELD_STATIC (decl))
9166             {
9167               decl = maybe_access_field (decl, *where_found, type);
9168               if (decl == error_mark_node)
9169                 return 1;
9170             }
9171           /* And code for the array reference expression */
9172           decl = java_complete_tree (qual_wfl);
9173           if (decl == error_mark_node)
9174             return 1;
9175           type = QUAL_DECL_TYPE (decl);
9176           continue;
9177
9178         case PLUS_EXPR:
9179           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9180             return 1;
9181           if ((type = patch_string (decl)))
9182             decl = type;
9183           *where_found = QUAL_RESOLUTION (q) = decl;
9184           *type_found = type = TREE_TYPE (decl);
9185           break;
9186
9187         case CLASS_LITERAL:
9188           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9189             return 1;
9190           *where_found = QUAL_RESOLUTION (q) = decl;
9191           *type_found = type = TREE_TYPE (decl);
9192           break;
9193
9194         default:
9195           /* Fix for -Wall Just go to the next statement. Don't
9196              continue */
9197           break;
9198         }
9199
9200       /* If we fall here, we weren't processing a (static) function call. */
9201       previous_call_static = 0;
9202
9203       /* It can be the keyword THIS */
9204       if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
9205         {
9206           if (!current_this)
9207             {
9208               parse_error_context 
9209                 (wfl, "Keyword `this' used outside allowed context");
9210               return 1;
9211             }
9212           if (ctxp->explicit_constructor_p
9213               && type == current_class)
9214             {
9215               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9216               return 1;
9217             }
9218           /* We have to generate code for intermediate acess */
9219           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
9220             {
9221               *where_found = decl = current_this;
9222               *type_found = type = QUAL_DECL_TYPE (decl);
9223             }
9224           /* We're trying to access the this from somewhere else. Make sure
9225              it's allowed before doing so. */
9226           else
9227             {
9228               if (!enclosing_context_p (type, current_class))
9229                 {
9230                   char *p  = xstrdup (lang_printable_name (type, 0));
9231                   parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'", 
9232                                        p, p, 
9233                                        lang_printable_name (current_class, 0));
9234                   free (p);
9235                   return 1;
9236                 }
9237               from_qualified_this = 1;
9238               /* If there's nothing else after that, we need to
9239                  produce something now, otherwise, the section of the
9240                  code that needs to produce <T>.this will generate
9241                  what is necessary. */
9242               if (!TREE_CHAIN (q))
9243                 {
9244                   decl = build_access_to_thisn (current_class, type, 0);
9245                   *where_found = decl = java_complete_tree (decl);
9246                   *type_found = type = TREE_TYPE (decl);
9247                 }
9248             }
9249
9250           from_type = 0;
9251           continue;
9252         }
9253
9254       /* 15.10.2 Accessing Superclass Members using SUPER */
9255       if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
9256         {
9257           tree node;
9258           /* Check on the restricted use of SUPER */
9259           if (METHOD_STATIC (current_function_decl)
9260               || current_class == object_type_node)
9261             {
9262               parse_error_context 
9263                 (wfl, "Keyword `super' used outside allowed context");
9264               return 1;
9265             }
9266           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
9267           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
9268                              CLASSTYPE_SUPER (current_class),
9269                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
9270           *where_found = decl = java_complete_tree (node);
9271           if (decl == error_mark_node)
9272             return 1;
9273           *type_found = type = QUAL_DECL_TYPE (decl);
9274           from_super = from_type = 1;
9275           continue;
9276         }
9277
9278       /* 15.13.1: Can't search for field name in packages, so we
9279          assume a variable/class name was meant. */
9280       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
9281         {
9282           tree name = resolve_package (wfl, &q);
9283           if (name)
9284             {
9285               tree list;
9286               *where_found = decl = resolve_no_layout (name, qual_wfl);
9287               /* We want to be absolutely sure that the class is laid
9288                  out. We're going to search something inside it. */
9289               *type_found = type = TREE_TYPE (decl);
9290               layout_class (type);
9291               from_type = 1;
9292
9293               /* Fix them all the way down, if any are left. */
9294               if (q)
9295                 {
9296                   list = TREE_CHAIN (q);
9297                   while (list)
9298                     {
9299                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
9300                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
9301                       list = TREE_CHAIN (list);
9302                     }
9303                 }
9304             }
9305           else
9306             {
9307               if (from_super || from_cast)
9308                 parse_error_context 
9309                   ((from_cast ? qual_wfl : wfl),
9310                    "No variable `%s' defined in class `%s'",
9311                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9312                    lang_printable_name (type, 0));
9313               else
9314                 parse_error_context
9315                   (qual_wfl, "Undefined variable or class name: `%s'",
9316                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
9317               return 1;
9318             }
9319         }
9320
9321       /* We have a type name. It's been already resolved when the
9322          expression was qualified. */
9323       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
9324         {
9325           if (!(decl = QUAL_RESOLUTION (q)))
9326             return 1;           /* Error reported already */
9327
9328           /* Sneak preview. If next we see a `new', we're facing a
9329              qualification with resulted in a type being selected
9330              instead of a field.  Report the error */
9331           if(TREE_CHAIN (q) 
9332              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
9333             {
9334               parse_error_context (qual_wfl, "Undefined variable `%s'",
9335                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9336               return 1;
9337             }
9338
9339           if (not_accessible_p (TREE_TYPE (decl), decl, type, 0))
9340             {
9341               parse_error_context 
9342                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
9343                  java_accstring_lookup (get_access_flags_from_decl (decl)),
9344                  GET_TYPE_NAME (type),
9345                  IDENTIFIER_POINTER (DECL_NAME (decl)),
9346                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9347               return 1;
9348             }
9349           check_deprecation (qual_wfl, decl);
9350
9351           type = TREE_TYPE (decl);
9352           from_type = 1;
9353         }
9354       /* We resolve and expression name */
9355       else 
9356         {
9357           tree field_decl = NULL_TREE;
9358
9359           /* If there exists an early resolution, use it. That occurs
9360              only once and we know that there are more things to
9361              come. Don't do that when processing something after SUPER
9362              (we need more thing to be put in place below */
9363           if (!from_super && QUAL_RESOLUTION (q))
9364             {
9365               decl = QUAL_RESOLUTION (q);
9366               if (!type)
9367                 {
9368                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
9369                     {
9370                       if (current_this)
9371                         *where_found = current_this;
9372                       else
9373                         {
9374                           static_ref_err (qual_wfl, DECL_NAME (decl),
9375                                           current_class);
9376                           return 1;
9377                         }
9378                       if (outer_field_access_p (current_class, decl))
9379                         decl = build_outer_field_access (qual_wfl, decl);
9380                     }
9381                   else
9382                     {
9383                       *where_found = TREE_TYPE (decl);
9384                       if (TREE_CODE (*where_found) == POINTER_TYPE)
9385                         *where_found = TREE_TYPE (*where_found);
9386                     }
9387                 }
9388             }
9389
9390           /* We have to search for a field, knowing the type of its
9391              container. The flag FROM_TYPE indicates that we resolved
9392              the last member of the expression as a type name, which
9393              means that for the resolution of this field, we'll look
9394              for other errors than if it was resolved as a member of
9395              an other field. */
9396           else
9397             {
9398               int is_static;
9399               tree field_decl_type; /* For layout */
9400
9401               if (!from_type && !JREFERENCE_TYPE_P (type))
9402                 {
9403                   parse_error_context 
9404                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9405                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9406                      lang_printable_name (type, 0),
9407                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9408                   return 1;
9409                 }
9410               
9411               field_decl = lookup_field_wrapper (type,
9412                                                  EXPR_WFL_NODE (qual_wfl));
9413
9414               /* Maybe what we're trying to access to is an inner
9415                  class, only if decl is a TYPE_DECL. */
9416               if (!field_decl && TREE_CODE (decl) == TYPE_DECL)
9417                 {
9418                   tree ptr, inner_decl;
9419
9420                   BUILD_PTR_FROM_NAME (ptr, EXPR_WFL_NODE (qual_wfl));
9421                   inner_decl = resolve_class (decl, ptr, NULL_TREE, qual_wfl);
9422                   if (inner_decl)
9423                     {
9424                       check_inner_class_access (inner_decl, decl, qual_wfl); 
9425                       type = TREE_TYPE (inner_decl);
9426                       decl = inner_decl;
9427                       from_type = 1;
9428                       continue;
9429                     }
9430                 }
9431
9432               if (field_decl == NULL_TREE)
9433                 {
9434                   parse_error_context 
9435                     (qual_wfl, "No variable `%s' defined in type `%s'",
9436                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9437                      GET_TYPE_NAME (type));
9438                   return 1;
9439                 }
9440               if (field_decl == error_mark_node)
9441                 return 1;
9442
9443               /* Layout the type of field_decl, since we may need
9444                  it. Don't do primitive types or loaded classes. The
9445                  situation of non primitive arrays may not handled
9446                  properly here. FIXME */
9447               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9448                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9449               else
9450                 field_decl_type = TREE_TYPE (field_decl);
9451               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9452                   && !CLASS_LOADED_P (field_decl_type)
9453                   && !TYPE_ARRAY_P (field_decl_type))
9454                 resolve_and_layout (field_decl_type, NULL_TREE);
9455               
9456               /* Check on accessibility here */
9457               if (not_accessible_p (current_class, field_decl,
9458                                     DECL_CONTEXT (field_decl), from_super))
9459                 {
9460                   parse_error_context 
9461                     (qual_wfl,
9462                      "Can't access %s field `%s.%s' from `%s'",
9463                      java_accstring_lookup 
9464                        (get_access_flags_from_decl (field_decl)),
9465                      GET_TYPE_NAME (type),
9466                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9467                      IDENTIFIER_POINTER 
9468                        (DECL_NAME (TYPE_NAME (current_class))));
9469                   return 1;
9470                 }
9471               check_deprecation (qual_wfl, field_decl);
9472               
9473               /* There are things to check when fields are accessed
9474                  from type. There are no restrictions on a static
9475                  declaration of the field when it is accessed from an
9476                  interface */
9477               is_static = FIELD_STATIC (field_decl);
9478               if (!from_super && from_type 
9479                   && !TYPE_INTERFACE_P (type) 
9480                   && !is_static 
9481                   && (current_function_decl 
9482                       && METHOD_STATIC (current_function_decl)))
9483                 {
9484                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9485                   return 1;
9486                 }
9487               from_cast = from_super = 0;
9488
9489               /* It's an access from a type but it isn't static, we
9490                  make it relative to `this'. */
9491               if (!is_static && from_type)
9492                 decl = current_this;
9493
9494               /* If we need to generate something to get a proper
9495                  handle on what this field is accessed from, do it
9496                  now. */
9497               if (!is_static)
9498                 {
9499                   decl = maybe_access_field (decl, *where_found, *type_found);
9500                   if (decl == error_mark_node)
9501                     return 1;
9502                 }
9503
9504               /* We want to keep the location were found it, and the type
9505                  we found. */
9506               *where_found = decl;
9507               *type_found = type;
9508
9509               /* Generate the correct expression for field access from
9510                  qualified this */
9511               if (from_qualified_this)
9512                 {
9513                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9514                   from_qualified_this = 0;
9515                 }
9516
9517               /* This is the decl found and eventually the next one to
9518                  search from */
9519               decl = field_decl;
9520             }
9521           from_type = 0;
9522           type = QUAL_DECL_TYPE (decl);
9523
9524           /* Sneak preview. If decl is qualified by a `new', report
9525              the error here to be accurate on the peculiar construct */
9526           if (TREE_CHAIN (q) 
9527               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9528               && !JREFERENCE_TYPE_P (type))
9529             {
9530               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9531                                    lang_printable_name (type, 0));
9532               return 1;
9533             }
9534         }
9535       /* `q' might have changed due to a after package resolution
9536          re-qualification */
9537       if (!q)
9538         break;
9539     }
9540   *found_decl = decl;
9541   return 0;
9542 }
9543
9544 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9545    can't be accessed from REFERENCE (a record type). If MEMBER
9546    features a protected access, we then use WHERE which, if non null,
9547    holds the type of MEMBER's access that is checked against
9548    6.6.2.1. This function should be used when decl is a field or a
9549    method.  */
9550
9551 static int
9552 not_accessible_p (reference, member, where, from_super)
9553      tree reference, member;
9554      tree where;
9555      int from_super;
9556 {
9557   int access_flag = get_access_flags_from_decl (member);
9558
9559   /* Inner classes are processed by check_inner_class_access */
9560   if (INNER_CLASS_TYPE_P (reference))
9561     return 0;
9562
9563   /* Access always granted for members declared public */
9564   if (access_flag & ACC_PUBLIC)
9565     return 0;
9566   
9567   /* Check access on protected members */
9568   if (access_flag & ACC_PROTECTED)
9569     {
9570       /* Access granted if it occurs from within the package
9571          containing the class in which the protected member is
9572          declared */
9573       if (class_in_current_package (DECL_CONTEXT (member)))
9574         return 0;
9575
9576       /* If accessed with the form `super.member', then access is granted */
9577       if (from_super)
9578         return 0;
9579
9580       /* If where is active, access was made through a
9581          qualifier. Access is granted if the type of the qualifier is
9582          or is a sublass of the type the access made from (6.6.2.1.)  */
9583       if (where && !inherits_from_p (reference, where))
9584         return 1;
9585
9586       /* Otherwise, access is granted if occuring from the class where
9587          member is declared or a subclass of it. Find the right
9588          context to perform the check */
9589       if (PURE_INNER_CLASS_TYPE_P (reference))
9590         {
9591           while (INNER_CLASS_TYPE_P (reference))
9592             {
9593               if (inherits_from_p (reference, DECL_CONTEXT (member)))
9594                 return 0;
9595               reference = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (reference)));
9596             }
9597         }
9598       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9599         return 0;
9600       return 1;
9601     }
9602
9603   /* Check access on private members. Access is granted only if it
9604      occurs from within the class in which it is declared -- that does
9605      it for innerclasses too. */
9606   if (access_flag & ACC_PRIVATE)
9607     {
9608       if (reference == DECL_CONTEXT (member))
9609         return 0;
9610       if (enclosing_context_p (reference, DECL_CONTEXT (member)))
9611         return 0;
9612       return 1;
9613     }
9614
9615   /* Default access are permitted only when occuring within the
9616      package in which the type (REFERENCE) is declared. In other words,
9617      REFERENCE is defined in the current package */
9618   if (ctxp->package)
9619     return !class_in_current_package (reference);
9620
9621   /* Otherwise, access is granted */
9622   return 0;
9623 }
9624
9625 /* Test deprecated decl access.  */
9626 static void
9627 check_deprecation (wfl, decl)
9628      tree wfl, decl;
9629 {
9630   const char *file = DECL_SOURCE_FILE (decl);
9631   /* Complain if the field is deprecated and the file it was defined
9632      in isn't compiled at the same time the file which contains its
9633      use is */
9634   if (DECL_DEPRECATED (decl) 
9635       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9636     {
9637       char the [20];
9638       switch (TREE_CODE (decl))
9639         {
9640         case FUNCTION_DECL:
9641           strcpy (the, "method");
9642           break;
9643         case FIELD_DECL:
9644           strcpy (the, "field");
9645           break;
9646         case TYPE_DECL:
9647           strcpy (the, "class");
9648           break;
9649         default:
9650           abort ();
9651         }
9652       parse_warning_context 
9653         (wfl, "The %s `%s' in class `%s' has been deprecated", 
9654          the, lang_printable_name (decl, 0),
9655          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9656     }
9657 }
9658
9659 /* Returns 1 if class was declared in the current package, 0 otherwise */
9660
9661 static int
9662 class_in_current_package (class)
9663      tree class;
9664 {
9665   static tree cache = NULL_TREE;
9666   int qualified_flag;
9667   tree left;
9668
9669   if (cache == class)
9670     return 1;
9671
9672   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9673
9674   /* If the current package is empty and the name of CLASS is
9675      qualified, class isn't in the current package.  If there is a
9676      current package and the name of the CLASS is not qualified, class
9677      isn't in the current package */
9678   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9679     return 0;
9680
9681   /* If there is not package and the name of CLASS isn't qualified,
9682      they belong to the same unnamed package */
9683   if (!ctxp->package && !qualified_flag)
9684     return 1;
9685
9686   /* Compare the left part of the name of CLASS with the package name */
9687   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9688   if (ctxp->package == left)
9689     {
9690       static int initialized_p;
9691       /* Register CACHE with the garbage collector.  */
9692       if (!initialized_p)
9693         {
9694           ggc_add_tree_root (&cache, 1);
9695           initialized_p = 1;
9696         }
9697
9698       cache = class;
9699       return 1;
9700     }
9701   return 0;
9702 }
9703
9704 /* This function may generate code to access DECL from WHERE. This is
9705    done only if certain conditions meet.  */
9706
9707 static tree
9708 maybe_access_field (decl, where, type)
9709   tree decl, where, type;
9710 {
9711   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9712       && !FIELD_STATIC (decl))
9713     decl = build_field_ref (where ? where : current_this, 
9714                             (type ? type : DECL_CONTEXT (decl)),
9715                             DECL_NAME (decl));
9716   return decl;
9717 }
9718
9719 /* Build a method invocation, by patching PATCH. If non NULL
9720    and according to the situation, PRIMARY and WHERE may be
9721    used. IS_STATIC is set to 1 if the invoked function is static. */
9722
9723 static tree
9724 patch_method_invocation (patch, primary, where, from_super,
9725                         is_static, ret_decl)
9726      tree patch, primary, where;
9727      int from_super;
9728      int *is_static;
9729      tree *ret_decl;
9730 {
9731   tree wfl = TREE_OPERAND (patch, 0);
9732   tree args = TREE_OPERAND (patch, 1);
9733   tree name = EXPR_WFL_NODE (wfl);
9734   tree list;
9735   int is_static_flag = 0;
9736   int is_super_init = 0;
9737   tree this_arg = NULL_TREE;
9738   int is_array_clone_call = 0;
9739   
9740   /* Should be overriden if everything goes well. Otherwise, if
9741      something fails, it should keep this value. It stop the
9742      evaluation of a bogus assignment. See java_complete_tree,
9743      MODIFY_EXPR: for the reasons why we sometimes want to keep on
9744      evaluating an assignment */
9745   TREE_TYPE (patch) = error_mark_node;
9746
9747   /* Since lookup functions are messing with line numbers, save the
9748      context now.  */
9749   java_parser_context_save_global ();
9750
9751   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9752
9753   /* Resolution of qualified name, excluding constructors */
9754   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9755     {
9756       tree identifier, identifier_wfl, type, resolved;
9757       /* Extract the last IDENTIFIER of the qualified
9758          expression. This is a wfl and we will use it's location
9759          data during error report. */
9760       identifier_wfl = cut_identifier_in_qualified (wfl);
9761       identifier = EXPR_WFL_NODE (identifier_wfl);
9762       
9763       /* Given the context, IDENTIFIER is syntactically qualified
9764          as a MethodName. We need to qualify what's before */
9765       qualify_ambiguous_name (wfl);
9766       resolved = resolve_field_access (wfl, NULL, NULL);
9767
9768       if (resolved == error_mark_node)
9769         PATCH_METHOD_RETURN_ERROR ();
9770
9771       type = GET_SKIP_TYPE (resolved);
9772       resolve_and_layout (type, NULL_TREE);
9773       
9774       if (JPRIMITIVE_TYPE_P (type))
9775         {
9776           parse_error_context
9777             (identifier_wfl,
9778              "Can't invoke a method on primitive type `%s'",
9779              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9780           PATCH_METHOD_RETURN_ERROR ();         
9781         }
9782
9783       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9784       args = nreverse (args);
9785
9786       /* We're resolving a call from a type */
9787       if (TREE_CODE (resolved) == TYPE_DECL)
9788         {
9789           if (CLASS_INTERFACE (resolved))
9790             {
9791               parse_error_context
9792                 (identifier_wfl,
9793                 "Can't make static reference to method `%s' in interface `%s'",
9794                  IDENTIFIER_POINTER (identifier), 
9795                  IDENTIFIER_POINTER (name));
9796               PATCH_METHOD_RETURN_ERROR ();
9797             }
9798           if (list && !METHOD_STATIC (list))
9799             {
9800               char *fct_name = xstrdup (lang_printable_name (list, 0));
9801               parse_error_context 
9802                 (identifier_wfl,
9803                  "Can't make static reference to method `%s %s' in class `%s'",
9804                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9805                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9806               free (fct_name);
9807               PATCH_METHOD_RETURN_ERROR ();
9808             }
9809         }
9810       else
9811         this_arg = primary = resolved;
9812       
9813       if (TYPE_ARRAY_P (type) && identifier == get_identifier ("clone"))
9814         is_array_clone_call = 1;
9815       
9816       /* IDENTIFIER_WFL will be used to report any problem further */
9817       wfl = identifier_wfl;
9818     }
9819   /* Resolution of simple names, names generated after a primary: or
9820      constructors */
9821   else
9822     {
9823       tree class_to_search = NULL_TREE;
9824       int lc;                   /* Looking for Constructor */
9825       
9826       /* We search constructor in their target class */
9827       if (CALL_CONSTRUCTOR_P (patch))
9828         {
9829           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9830             class_to_search = EXPR_WFL_NODE (wfl);
9831           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
9832                    this_identifier_node)
9833             class_to_search = NULL_TREE;
9834           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9835                    super_identifier_node)
9836             {
9837               is_super_init = 1;
9838               if (CLASSTYPE_SUPER (current_class))
9839                 class_to_search = 
9840                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9841               else
9842                 {
9843                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9844                   PATCH_METHOD_RETURN_ERROR ();
9845                 }
9846             }
9847
9848           /* Class to search is NULL if we're searching the current one */
9849           if (class_to_search)
9850             {
9851               class_to_search = resolve_and_layout (class_to_search, wfl);
9852
9853               if (!class_to_search)
9854                 {
9855                   parse_error_context 
9856                     (wfl, "Class `%s' not found in type declaration",
9857                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9858                   PATCH_METHOD_RETURN_ERROR ();
9859                 }
9860               
9861               /* Can't instantiate an abstract class, but we can
9862                  invoke it's constructor. It's use within the `new'
9863                  context is denied here. */
9864               if (CLASS_ABSTRACT (class_to_search) 
9865                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
9866                 {
9867                   parse_error_context 
9868                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9869                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9870                   PATCH_METHOD_RETURN_ERROR ();
9871                 }
9872
9873               class_to_search = TREE_TYPE (class_to_search);
9874             }
9875           else
9876             class_to_search = current_class;
9877           lc = 1;
9878         }
9879       /* This is a regular search in the local class, unless an
9880          alternate class is specified. */
9881       else
9882         {
9883           if (where != NULL_TREE)
9884             class_to_search = where;
9885           else if (QUALIFIED_P (name))
9886             class_to_search = current_class;
9887           else
9888             {
9889               class_to_search = current_class;
9890
9891               for (;;)
9892                 {
9893                   if (has_method (class_to_search, name))
9894                     break;
9895                   if (! INNER_CLASS_TYPE_P (class_to_search))
9896                     {
9897                       parse_error_context (wfl,
9898                                            "No method named `%s' in scope",
9899                                            IDENTIFIER_POINTER (name));
9900                       PATCH_METHOD_RETURN_ERROR ();
9901                     }
9902                   class_to_search
9903                     = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_to_search)));
9904                 }
9905             }
9906           lc = 0;
9907         }
9908
9909       /* NAME is a simple identifier or comes from a primary. Search
9910          in the class whose declaration contain the method being
9911          invoked. */
9912       resolve_and_layout (class_to_search, NULL_TREE);
9913
9914       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9915       /* Don't continue if no method were found, as the next statement
9916          can't be executed then. */
9917       if (!list)
9918         PATCH_METHOD_RETURN_ERROR ();
9919       
9920       if (TYPE_ARRAY_P (class_to_search)
9921           && DECL_NAME (list) == get_identifier ("clone"))
9922         is_array_clone_call = 1;
9923
9924       /* Check for static reference if non static methods */
9925       if (check_for_static_method_reference (wfl, patch, list, 
9926                                              class_to_search, primary))
9927         PATCH_METHOD_RETURN_ERROR ();
9928
9929       /* Check for inner classes creation from illegal contexts */
9930       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9931                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9932           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9933         {
9934           parse_error_context 
9935             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9936              lang_printable_name (class_to_search, 0),
9937              (!current_this ? "" :
9938               "; an explicit one must be provided when creating this inner class"));
9939           PATCH_METHOD_RETURN_ERROR ();
9940         }
9941
9942       /* Non static methods are called with the current object extra
9943          argument. If patch a `new TYPE()', the argument is the value
9944          returned by the object allocator. If method is resolved as a
9945          primary, use the primary otherwise use the current THIS. */
9946       args = nreverse (args);
9947       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
9948         {
9949           this_arg = primary ? primary : current_this;
9950
9951           /* If we're using an access method, things are different.
9952              There are two familly of cases:
9953
9954              1) We're not generating bytecodes:
9955
9956              - LIST is non static. It's invocation is transformed from
9957                x(a1,...,an) into this$<n>.x(a1,....an).
9958              - LIST is static. It's invocation is transformed from
9959                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
9960
9961              2) We're generating bytecodes:
9962              
9963              - LIST is non static. It's invocation is transformed from
9964                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
9965              - LIST is static. It's invocation is transformed from
9966                x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
9967
9968              Of course, this$<n> can be abitrary complex, ranging from
9969              this$0 (the immediate outer context) to 
9970              access$0(access$0(...(this$0))). 
9971              
9972              maybe_use_access_method returns a non zero value if the
9973              this_arg has to be moved into the (then generated) stub
9974              argument list. In the meantime, the selected function
9975              might have be replaced by a generated stub. */
9976           if (maybe_use_access_method (is_super_init, &list, &this_arg))
9977             {
9978               args = tree_cons (NULL_TREE, this_arg, args);
9979               this_arg = NULL_TREE; /* So it doesn't get chained twice */
9980             }
9981         }
9982     }
9983
9984   /* Merge point of all resolution schemes. If we have nothing, this
9985      is an error, already signaled */
9986   if (!list) 
9987     PATCH_METHOD_RETURN_ERROR ();
9988
9989   /* Check accessibility, position the is_static flag, build and
9990      return the call */
9991   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list,
9992                         (primary ? TREE_TYPE (TREE_TYPE (primary)) : 
9993                          NULL_TREE), from_super)
9994       /* Calls to clone() on array types are permitted as a special-case. */
9995       && !is_array_clone_call)
9996     {
9997       const char *fct_name = IDENTIFIER_POINTER (DECL_NAME (list));
9998       const char *access =
9999         java_accstring_lookup (get_access_flags_from_decl (list));
10000       const char *klass =
10001         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list))));
10002       const char *refklass =
10003         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
10004       const char *what = (DECL_CONSTRUCTOR_P (list)
10005                           ? "constructor" : "method");
10006       /* FIXME: WFL yields the wrong message here but I don't know
10007          what else to use.  */
10008       parse_error_context (wfl,
10009                            "Can't access %s %s `%s.%s' from `%s'",
10010                            access, what, klass, fct_name, refklass);
10011       PATCH_METHOD_RETURN_ERROR ();
10012     }
10013   check_deprecation (wfl, list);
10014
10015   /* If invoking a innerclass constructor, there are hidden parameters
10016      to pass */
10017   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
10018       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10019     {
10020       /* And make sure we add the accessed local variables to be saved
10021          in field aliases. */
10022       args = build_alias_initializer_parameter_list
10023         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
10024
10025       /* Secretly pass the current_this/primary as a second argument */
10026       if (primary || current_this)
10027         {
10028           tree extra_arg;
10029           tree this_type = (current_this ?
10030                             TREE_TYPE (TREE_TYPE (current_this)) : NULL_TREE);
10031           /* Method's (list) enclosing context */
10032           tree mec = DECL_CONTEXT (TYPE_NAME (DECL_CONTEXT (list)));
10033           /* If we have a primary, use it. */
10034           if (primary)
10035             extra_arg = primary;
10036           /* The current `this' is an inner class but isn't a direct
10037              enclosing context for the inner class we're trying to
10038              create. Build an access to the proper enclosing context
10039              and use it. */
10040           else if (current_this && PURE_INNER_CLASS_TYPE_P (this_type)
10041                    && this_type != TREE_TYPE (mec))
10042             {
10043
10044               extra_arg = build_access_to_thisn (current_class,
10045                                                  TREE_TYPE (mec), 0);
10046               extra_arg = java_complete_tree (extra_arg);
10047             }
10048           /* Otherwise, just use the current `this' as an enclosing
10049              context. */
10050           else
10051             extra_arg = current_this;
10052           args = tree_cons (NULL_TREE, extra_arg, args);
10053         }
10054       else
10055         args = tree_cons (NULL_TREE, integer_zero_node, args);
10056     }
10057
10058   /* This handles the situation where a constructor invocation needs
10059      to have an enclosing context passed as a second parameter (the
10060      constructor is one of an inner class. We extract it from the
10061      current function.  */
10062   if (is_super_init && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
10063     {
10064       tree enclosing_decl = DECL_CONTEXT (TYPE_NAME (current_class));
10065       tree extra_arg;
10066
10067       if (ANONYMOUS_CLASS_P (current_class) || !DECL_CONTEXT (enclosing_decl))
10068         {
10069           extra_arg = DECL_FUNCTION_BODY (current_function_decl);
10070           extra_arg = TREE_CHAIN (BLOCK_EXPR_DECLS (extra_arg));
10071         }
10072       else
10073         {
10074           tree dest = TREE_TYPE (DECL_CONTEXT (enclosing_decl));
10075           extra_arg = 
10076             build_access_to_thisn (TREE_TYPE (enclosing_decl), dest, 0);
10077           extra_arg = java_complete_tree (extra_arg);
10078         }
10079       args = tree_cons (NULL_TREE, extra_arg, args);
10080     }
10081
10082   is_static_flag = METHOD_STATIC (list);
10083   if (! is_static_flag && this_arg != NULL_TREE)
10084     args = tree_cons (NULL_TREE, this_arg, args);
10085
10086   /* In the context of an explicit constructor invocation, we can't
10087      invoke any method relying on `this'. Exceptions are: we're
10088      invoking a static function, primary exists and is not the current
10089      this, we're creating a new object. */
10090   if (ctxp->explicit_constructor_p 
10091       && !is_static_flag 
10092       && (!primary || primary == current_this)
10093       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
10094     {
10095       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
10096       PATCH_METHOD_RETURN_ERROR ();
10097     }
10098   java_parser_context_restore_global ();
10099   if (is_static) 
10100     *is_static = is_static_flag;
10101   /* Sometimes, we want the decl of the selected method. Such as for
10102      EH checking */
10103   if (ret_decl)
10104     *ret_decl = list;
10105   patch = patch_invoke (patch, list, args);
10106   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
10107     {
10108       tree finit_parms, finit_call;
10109       
10110       /* Prepare to pass hidden parameters to finit$, if any. */
10111       finit_parms = build_alias_initializer_parameter_list 
10112         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
10113       
10114       finit_call = 
10115         build_method_invocation (build_wfl_node (finit_identifier_node),
10116                                  finit_parms);
10117
10118       /* Generate the code used to initialize fields declared with an
10119          initialization statement and build a compound statement along
10120          with the super constructor invocation. */
10121       patch = build (COMPOUND_EXPR, void_type_node, patch,
10122                      java_complete_tree (finit_call));
10123       CAN_COMPLETE_NORMALLY (patch) = 1;
10124     }
10125   return patch;
10126 }
10127
10128 /* Check that we're not trying to do a static reference to a method in
10129    non static method. Return 1 if it's the case, 0 otherwise. */
10130
10131 static int
10132 check_for_static_method_reference (wfl, node, method, where, primary)
10133      tree wfl, node, method, where, primary;
10134 {
10135   if (METHOD_STATIC (current_function_decl) 
10136       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
10137     {
10138       char *fct_name = xstrdup (lang_printable_name (method, 0));
10139       parse_error_context 
10140         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
10141          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
10142          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
10143       free (fct_name);
10144       return 1;
10145     }
10146   return 0;
10147 }
10148
10149 /* Fix the invocation of *MDECL if necessary in the case of a
10150    invocation from an inner class. *THIS_ARG might be modified
10151    appropriately and an alternative access to *MDECL might be
10152    returned.  */
10153
10154 static int
10155 maybe_use_access_method (is_super_init, mdecl, this_arg)
10156      int is_super_init;
10157      tree *mdecl, *this_arg;
10158 {
10159   tree ctx;
10160   tree md = *mdecl, ta = *this_arg;
10161   int to_return = 0;
10162   int non_static_context = !METHOD_STATIC (md);
10163
10164   if (is_super_init 
10165       || DECL_CONTEXT (md) == current_class
10166       || !PURE_INNER_CLASS_TYPE_P (current_class) 
10167       || DECL_FINIT_P (md))
10168     return 0;
10169   
10170   /* If we're calling a method found in an enclosing class, generate
10171      what it takes to retrieve the right this. Don't do that if we're
10172      invoking a static method. Note that if MD's type is unrelated to
10173      CURRENT_CLASS, then the current this can be used. */
10174
10175   if (non_static_context && DECL_CONTEXT (md) != object_type_node)
10176     {
10177       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
10178       if (inherits_from_p (ctx, DECL_CONTEXT (md)))
10179         {
10180           ta = build_current_thisn (current_class);
10181           ta = build_wfl_node (ta);
10182         }
10183       else
10184         {
10185           tree type = ctx;
10186           while (type)
10187             {
10188               maybe_build_thisn_access_method (type);
10189               if (inherits_from_p (type, DECL_CONTEXT (md)))
10190                 {
10191                   ta = build_access_to_thisn (ctx, type, 0);
10192                   break;
10193                 }
10194               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
10195                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
10196             }
10197         }
10198       ta = java_complete_tree (ta);
10199     }
10200
10201   /* We might have to use an access method to get to MD. We can
10202      break the method access rule as far as we're not generating
10203      bytecode */
10204   if (METHOD_PRIVATE (md) && flag_emit_class_files)
10205     {
10206       md = build_outer_method_access_method (md);
10207       to_return = 1;
10208     }
10209
10210   *mdecl = md;
10211   *this_arg = ta;
10212
10213   /* Returnin a non zero value indicates we were doing a non static
10214      method invokation that is now a static invocation. It will have
10215      callee displace `this' to insert it in the regular argument
10216      list. */
10217   return (non_static_context && to_return);
10218 }
10219
10220 /* Patch an invoke expression METHOD and ARGS, based on its invocation
10221    mode.  */
10222
10223 static tree
10224 patch_invoke (patch, method, args)
10225      tree patch, method, args;
10226 {
10227   tree dtable, func;
10228   tree original_call, t, ta;
10229   tree check = NULL_TREE;
10230
10231   /* Last step for args: convert build-in types. If we're dealing with
10232      a new TYPE() type call, the first argument to the constructor
10233      isn't found in the incoming argument list, but delivered by
10234      `new' */
10235   t = TYPE_ARG_TYPES (TREE_TYPE (method));
10236   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
10237     t = TREE_CHAIN (t);
10238   for (ta = args; t != end_params_node && ta; 
10239        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
10240     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
10241         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
10242       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
10243
10244   /* Resolve unresolved returned type isses */
10245   t = TREE_TYPE (TREE_TYPE (method));
10246   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
10247     resolve_and_layout (TREE_TYPE (t), NULL);
10248
10249   if (flag_emit_class_files || flag_emit_xref)
10250     func = method;
10251   else
10252     {
10253       tree signature = build_java_signature (TREE_TYPE (method));
10254       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
10255         {
10256         case INVOKE_VIRTUAL:
10257           dtable = invoke_build_dtable (0, args);
10258           func = build_invokevirtual (dtable, method);
10259           break;
10260
10261         case INVOKE_NONVIRTUAL:
10262           /* If the object for the method call is null, we throw an
10263              exception.  We don't do this if the object is the current
10264              method's `this'.  In other cases we just rely on an
10265              optimization pass to eliminate redundant checks.  */
10266           if (TREE_VALUE (args) != current_this)
10267             {
10268               /* We use a save_expr here to make sure we only evaluate
10269                  the new `self' expression once.  */
10270               tree save_arg = save_expr (TREE_VALUE (args));
10271               TREE_VALUE (args) = save_arg;
10272               check = java_check_reference (save_arg, 1);
10273             }
10274           /* Fall through.  */
10275
10276         case INVOKE_SUPER:
10277         case INVOKE_STATIC:
10278           func = build_known_method_ref (method, TREE_TYPE (method),
10279                                          DECL_CONTEXT (method),
10280                                          signature, args);
10281           break;
10282
10283         case INVOKE_INTERFACE:
10284           dtable = invoke_build_dtable (1, args);
10285           func = build_invokeinterface (dtable, method);
10286           break;
10287
10288         default:
10289           abort ();
10290         }
10291
10292       /* Ensure self_type is initialized, (invokestatic). FIXME */
10293       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
10294     }
10295
10296   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
10297   TREE_OPERAND (patch, 0) = func;
10298   TREE_OPERAND (patch, 1) = args;
10299   original_call = patch;
10300
10301   /* We're processing a `new TYPE ()' form. New is called and its
10302      returned value is the first argument to the constructor. We build
10303      a COMPOUND_EXPR and use saved expression so that the overall NEW
10304      expression value is a pointer to a newly created and initialized
10305      class. */
10306   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
10307     {
10308       tree class = DECL_CONTEXT (method);
10309       tree c1, saved_new, size, new;
10310       if (flag_emit_class_files || flag_emit_xref)
10311         {
10312           TREE_TYPE (patch) = build_pointer_type (class);
10313           return patch;
10314         }
10315       if (!TYPE_SIZE (class))
10316         safe_layout_class (class);
10317       size = size_in_bytes (class);
10318       new = build (CALL_EXPR, promote_type (class),
10319                    build_address_of (alloc_object_node),
10320                    tree_cons (NULL_TREE, build_class_ref (class),
10321                               build_tree_list (NULL_TREE, 
10322                                                size_in_bytes (class))),
10323                    NULL_TREE);
10324       saved_new = save_expr (new);
10325       c1 = build_tree_list (NULL_TREE, saved_new);
10326       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
10327       TREE_OPERAND (original_call, 1) = c1;
10328       TREE_SET_CODE (original_call, CALL_EXPR);
10329       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
10330     }
10331
10332   /* If CHECK is set, then we are building a check to see if the object
10333      is NULL.  */
10334   if (check != NULL_TREE)
10335     {
10336       patch = build (COMPOUND_EXPR, TREE_TYPE (patch), check, patch);
10337       TREE_SIDE_EFFECTS (patch) = 1;
10338     }
10339
10340   return patch;
10341 }
10342
10343 static int
10344 invocation_mode (method, super)
10345      tree method;
10346      int super;
10347 {
10348   int access = get_access_flags_from_decl (method);
10349
10350   if (super)
10351     return INVOKE_SUPER;
10352
10353   if (access & ACC_STATIC)
10354     return INVOKE_STATIC;
10355
10356   /* We have to look for a constructor before we handle nonvirtual
10357      calls; otherwise the constructor will look nonvirtual.  */
10358   if (DECL_CONSTRUCTOR_P (method))
10359     return INVOKE_STATIC;
10360
10361   if (access & ACC_FINAL || access & ACC_PRIVATE)
10362     return INVOKE_NONVIRTUAL;
10363
10364   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
10365     return INVOKE_NONVIRTUAL;
10366
10367   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
10368     return INVOKE_INTERFACE;
10369
10370   return INVOKE_VIRTUAL;
10371 }
10372
10373 /* Retrieve a refined list of matching methods. It covers the step
10374    15.11.2 (Compile-Time Step 2) */
10375
10376 static tree
10377 lookup_method_invoke (lc, cl, class, name, arg_list)
10378      int lc;
10379      tree cl;
10380      tree class, name, arg_list;
10381 {
10382   tree atl = end_params_node;           /* Arg Type List */
10383   tree method, signature, list, node;
10384   const char *candidates;               /* Used for error report */
10385   char *dup;
10386
10387   /* Fix the arguments */
10388   for (node = arg_list; node; node = TREE_CHAIN (node))
10389     {
10390       tree current_arg = TREE_TYPE (TREE_VALUE (node));
10391       /* Non primitive type may have to be resolved */
10392       if (!JPRIMITIVE_TYPE_P (current_arg))
10393         resolve_and_layout (current_arg, NULL_TREE);
10394       /* And promoted */
10395       if (TREE_CODE (current_arg) == RECORD_TYPE)
10396         current_arg = promote_type (current_arg);
10397       atl = tree_cons (NULL_TREE, current_arg, atl);
10398     }
10399
10400   /* Presto. If we're dealing with an anonymous class and a
10401      constructor call, generate the right constructor now, since we
10402      know the arguments' types. */
10403
10404   if (lc && ANONYMOUS_CLASS_P (class))
10405     craft_constructor (TYPE_NAME (class), atl);
10406
10407   /* Find all candidates and then refine the list, searching for the
10408      most specific method. */
10409   list = find_applicable_accessible_methods_list (lc, class, name, atl);
10410   list = find_most_specific_methods_list (list);
10411   if (list && !TREE_CHAIN (list))
10412     return TREE_VALUE (list);
10413
10414   /* Issue an error. List candidates if any. Candidates are listed
10415      only if accessible (non accessible methods may end-up here for
10416      the sake of a better error report). */
10417   candidates = NULL;
10418   if (list)
10419     {
10420       tree current;
10421       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
10422       for (current = list; current; current = TREE_CHAIN (current))
10423         {
10424           tree cm = TREE_VALUE (current);
10425           char string [4096];
10426           if (!cm || not_accessible_p (class, cm, NULL_TREE, 0))
10427             continue;
10428           sprintf 
10429             (string, "  `%s' in `%s'%s",
10430              get_printable_method_name (cm),
10431              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
10432              (TREE_CHAIN (current) ? "\n" : ""));
10433           obstack_grow (&temporary_obstack, string, strlen (string));
10434         }
10435       obstack_1grow (&temporary_obstack, '\0');
10436       candidates = obstack_finish (&temporary_obstack);
10437     }
10438   /* Issue the error message */
10439   method = make_node (FUNCTION_TYPE);
10440   TYPE_ARG_TYPES (method) = atl;
10441   signature = build_java_argument_signature (method);
10442   dup = xstrdup (lang_printable_name (class, 0));
10443   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
10444                        (lc ? "constructor" : "method"),
10445                        (lc ? dup : IDENTIFIER_POINTER (name)),
10446                        IDENTIFIER_POINTER (signature), dup,
10447                        (candidates ? candidates : ""));
10448   free (dup);
10449   return NULL_TREE;
10450 }
10451
10452 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
10453    when we're looking for a constructor. */
10454
10455 static tree
10456 find_applicable_accessible_methods_list (lc, class, name, arglist)
10457      int lc;
10458      tree class, name, arglist;
10459 {
10460   static struct hash_table t, *searched_classes = NULL;
10461   static int search_not_done = 0;
10462   tree list = NULL_TREE, all_list = NULL_TREE;
10463
10464   /* Check the hash table to determine if this class has been searched 
10465      already. */
10466   if (searched_classes)
10467     {
10468       if (hash_lookup (searched_classes, 
10469                       (const hash_table_key) class, FALSE, NULL))
10470        return NULL;
10471     }
10472   else
10473     {
10474       hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
10475                       java_hash_compare_tree_node);
10476       searched_classes = &t;
10477     }
10478     
10479   search_not_done++;
10480   hash_lookup (searched_classes, 
10481                (const hash_table_key) class, TRUE, NULL);
10482
10483   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
10484     {
10485       load_class (class, 1);
10486       safe_layout_class (class);
10487     }
10488
10489   /* Search interfaces */
10490   if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
10491       && CLASS_INTERFACE (TYPE_NAME (class)))
10492     {
10493       int i, n;
10494       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10495       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10496                                       name, arglist, &list, &all_list);
10497       n = TREE_VEC_LENGTH (basetype_vec);
10498       for (i = 1; i < n; i++)
10499         {
10500           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10501           tree rlist;
10502
10503           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
10504                                                            arglist);
10505           list = chainon (rlist, list);
10506         }
10507     }
10508   /* Search classes */
10509   else
10510     {
10511       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10512                                       name, arglist, &list, &all_list);
10513
10514       /* When looking finit$ or class$, we turn LC to 1 so that we
10515          only search in class. Note that we should have found
10516          something at this point. */
10517       if (ID_FINIT_P (name) || ID_CLASSDOLLAR_P (name))
10518         {
10519           lc = 1;
10520           if (!list)
10521             abort ();
10522         }
10523
10524       /* We must search all interfaces of this class */
10525       if (!lc)
10526       {
10527         tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10528         int n = TREE_VEC_LENGTH (basetype_vec), i;
10529         for (i = 1; i < n; i++)
10530           {
10531             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10532             if (t != object_type_node)
10533               {
10534                 tree rlist
10535                   = find_applicable_accessible_methods_list (lc, t,
10536                                                              name, arglist);
10537                 list = chainon (rlist, list);
10538               }
10539           }
10540       }
10541
10542       /* Search superclass */
10543       if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
10544         {
10545           tree rlist;
10546           class = CLASSTYPE_SUPER (class);
10547           rlist = find_applicable_accessible_methods_list (lc, class, 
10548                                                            name, arglist);
10549           list = chainon (rlist, list);
10550         }
10551     }
10552
10553   search_not_done--;
10554
10555   /* We're done. Reset the searched classes list and finally search
10556      java.lang.Object if it wasn't searched already. */
10557   if (!search_not_done)
10558     {
10559       if (!lc
10560           && TYPE_METHODS (object_type_node)
10561           && !hash_lookup (searched_classes, 
10562                            (const hash_table_key) object_type_node, 
10563                            FALSE, NULL))
10564         {
10565           search_applicable_methods_list (lc, 
10566                                           TYPE_METHODS (object_type_node),
10567                                           name, arglist, &list, &all_list);
10568         }
10569       hash_table_free (searched_classes);
10570       searched_classes = NULL;
10571     }
10572
10573   /* Either return the list obtained or all selected (but
10574      inaccessible) methods for better error report. */
10575   return (!list ? all_list : list);
10576 }
10577
10578 /* Effectively search for the appropriate method in method */
10579
10580 static void 
10581 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10582      int lc;
10583      tree method, name, arglist;
10584      tree *list, *all_list;
10585 {
10586   for (; method; method = TREE_CHAIN (method))
10587     {
10588       /* When dealing with constructor, stop here, otherwise search
10589          other classes */
10590       if (lc && !DECL_CONSTRUCTOR_P (method))
10591         continue;
10592       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10593                        || (DECL_NAME (method) != name)))
10594         continue;
10595
10596       if (argument_types_convertible (method, arglist))
10597         {
10598           /* Retain accessible methods only */
10599           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10600                                  method, NULL_TREE, 0))
10601             *list = tree_cons (NULL_TREE, method, *list);
10602           else
10603             /* Also retain all selected method here */
10604             *all_list = tree_cons (NULL_TREE, method, *list);
10605         }
10606     }
10607 }
10608
10609 /* 15.11.2.2 Choose the Most Specific Method */
10610
10611 static tree
10612 find_most_specific_methods_list (list)
10613      tree list;
10614 {
10615   int max = 0;
10616   int abstract, candidates;
10617   tree current, new_list = NULL_TREE;
10618   for (current = list; current; current = TREE_CHAIN (current))
10619     {
10620       tree method;
10621       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10622
10623       for (method = list; method; method = TREE_CHAIN (method))
10624         {
10625           tree method_v, current_v;
10626           /* Don't test a method against itself */
10627           if (method == current)
10628             continue;
10629
10630           method_v = TREE_VALUE (method);
10631           current_v = TREE_VALUE (current);
10632
10633           /* Compare arguments and location where methods where declared */
10634           if (argument_types_convertible (method_v, current_v))
10635             {
10636               if (valid_method_invocation_conversion_p 
10637                   (DECL_CONTEXT (method_v), DECL_CONTEXT (current_v))
10638                   || (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v))
10639                       && enclosing_context_p (DECL_CONTEXT (method_v),
10640                                               DECL_CONTEXT (current_v))))
10641                 {
10642                   int v = (DECL_SPECIFIC_COUNT (current_v) += 
10643                     (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v)) ? 2 : 1));
10644                   max = (v > max ? v : max);
10645                 }
10646             }
10647         }
10648     }
10649
10650   /* Review the list and select the maximally specific methods */
10651   for (current = list, abstract = -1, candidates = -1;
10652        current; current = TREE_CHAIN (current))
10653     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10654       {
10655         new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10656         abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
10657         candidates++;
10658       }
10659
10660   /* If we have several and they're all abstract, just pick the
10661      closest one. */
10662   if (candidates > 0 && (candidates == abstract))
10663     {
10664       new_list = nreverse (new_list);
10665       TREE_CHAIN (new_list) = NULL_TREE;
10666     }
10667
10668   /* We have several (we couldn't find a most specific), all but one
10669      are abstract, we pick the only non abstract one. */
10670   if (candidates > 0 && (candidates == abstract+1))
10671     {
10672       for (current = new_list; current; current = TREE_CHAIN (current))
10673         if (!METHOD_ABSTRACT (TREE_VALUE (current)))
10674           {
10675             TREE_CHAIN (current) = NULL_TREE;
10676             new_list = current;
10677           }
10678     }
10679
10680   /* If we can't find one, lower expectations and try to gather multiple
10681      maximally specific methods */
10682   while (!new_list && max)
10683     {
10684       while (--max > 0)
10685         {
10686           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10687             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10688         }
10689     }
10690
10691   return new_list;
10692 }
10693
10694 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10695    converted by method invocation conversion (5.3) to the type of the
10696    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10697    to change less often than M1. */
10698
10699 static int
10700 argument_types_convertible (m1, m2_or_arglist)
10701     tree m1, m2_or_arglist;
10702 {
10703   static tree m2_arg_value = NULL_TREE;
10704   static tree m2_arg_cache = NULL_TREE;
10705   static int initialized_p;
10706
10707   register tree m1_arg, m2_arg;
10708
10709   /* Register M2_ARG_VALUE and M2_ARG_CACHE with the garbage
10710      collector.  */
10711   if (!initialized_p)
10712     {
10713       ggc_add_tree_root (&m2_arg_value, 1);
10714       ggc_add_tree_root (&m2_arg_cache, 1);
10715       initialized_p = 1;
10716     }
10717
10718   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10719
10720   if (m2_arg_value == m2_or_arglist)
10721     m2_arg = m2_arg_cache;
10722   else
10723     {
10724       /* M2_OR_ARGLIST can be a function DECL or a raw list of
10725          argument types */
10726       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10727         {
10728           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10729           if (!METHOD_STATIC (m2_or_arglist))
10730             m2_arg = TREE_CHAIN (m2_arg);
10731         }
10732       else
10733         m2_arg = m2_or_arglist;
10734
10735       m2_arg_value = m2_or_arglist;
10736       m2_arg_cache = m2_arg;
10737     }
10738
10739   while (m1_arg != end_params_node && m2_arg != end_params_node)
10740     {
10741       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10742       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10743                                                  TREE_VALUE (m2_arg)))
10744         break;
10745       m1_arg = TREE_CHAIN (m1_arg);
10746       m2_arg = TREE_CHAIN (m2_arg);
10747     }
10748   return m1_arg == end_params_node && m2_arg == end_params_node;
10749 }
10750
10751 /* Qualification routines */
10752
10753 static void
10754 qualify_ambiguous_name (id)
10755      tree id;
10756 {
10757   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10758     saved_current_class;
10759   int again, super_found = 0, this_found = 0, new_array_found = 0;
10760   int code;
10761
10762   /* We first qualify the first element, then derive qualification of
10763      others based on the first one. If the first element is qualified
10764      by a resolution (field or type), this resolution is stored in the
10765      QUAL_RESOLUTION of the qual element being examined. We need to
10766      save the current_class since the use of SUPER might change the
10767      its value. */
10768   saved_current_class = current_class;
10769   qual = EXPR_WFL_QUALIFICATION (id);
10770   do {
10771
10772     /* Simple qualified expression feature a qual_wfl that is a
10773        WFL. Expression derived from a primary feature more complicated
10774        things like a CALL_EXPR. Expression from primary need to be
10775        worked out to extract the part on which the qualification will
10776        take place. */
10777     qual_wfl = QUAL_WFL (qual);
10778     switch (TREE_CODE (qual_wfl))
10779       {
10780       case CALL_EXPR:
10781         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10782         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10783           {
10784             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10785             qual_wfl = QUAL_WFL (qual);
10786           }
10787         break;
10788       case NEW_ARRAY_EXPR:
10789       case NEW_ANONYMOUS_ARRAY_EXPR:
10790         qual = TREE_CHAIN (qual);
10791         again = new_array_found = 1;
10792         continue;
10793       case CONVERT_EXPR:
10794         break;
10795       case NEW_CLASS_EXPR:
10796         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10797         break;
10798       case ARRAY_REF:
10799         while (TREE_CODE (qual_wfl) == ARRAY_REF)
10800           qual_wfl = TREE_OPERAND (qual_wfl, 0);
10801         break;
10802       case STRING_CST:
10803         qual = TREE_CHAIN (qual);
10804         qual_wfl = QUAL_WFL (qual);
10805         break;
10806       case CLASS_LITERAL:
10807         qual = TREE_CHAIN (qual);
10808         qual_wfl = QUAL_WFL (qual);
10809       break;
10810       default:
10811         /* Fix for -Wall. Just break doing nothing */
10812         break;
10813       }
10814
10815     ptr_type = current_class;
10816     again = 0;
10817     code = TREE_CODE (qual_wfl);
10818
10819     /* Pos evaluation: non WFL leading expression nodes */
10820     if (code == CONVERT_EXPR
10821         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10822       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10823
10824     else if (code == INTEGER_CST)
10825       name = qual_wfl;
10826     
10827     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10828              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10829       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10830
10831     else if (code == TREE_LIST)
10832       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10833
10834     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
10835              || code == PLUS_EXPR)
10836       {
10837         qual = TREE_CHAIN (qual);
10838         qual_wfl = QUAL_WFL (qual);
10839         again = 1;
10840       }
10841     else 
10842       {
10843         name = EXPR_WFL_NODE (qual_wfl);
10844         if (!name)
10845           {
10846             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10847             again = 1;
10848           }
10849       }
10850
10851     /* If we have a THIS (from a primary), we set the context accordingly */
10852     if (name == this_identifier_node)
10853       {
10854         /* This isn't really elegant. One more added irregularity
10855            before I start using COMPONENT_REF (hopefully very soon.)  */
10856         if (TREE_CODE (TREE_PURPOSE (qual)) == ARRAY_REF
10857             && TREE_CODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
10858                EXPR_WITH_FILE_LOCATION
10859             && EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) == 
10860                this_identifier_node)
10861             {
10862               qual = TREE_OPERAND (TREE_PURPOSE (qual), 0);
10863               qual = EXPR_WFL_QUALIFICATION (qual);
10864             }
10865         qual = TREE_CHAIN (qual);
10866         qual_wfl = QUAL_WFL (qual);
10867         if (TREE_CODE (qual_wfl) == CALL_EXPR)
10868           again = 1;
10869         else
10870           name = EXPR_WFL_NODE (qual_wfl);
10871         this_found = 1;
10872       }
10873     /* If we have a SUPER, we set the context accordingly */
10874     if (name == super_identifier_node)
10875       {
10876         current_class = CLASSTYPE_SUPER (ptr_type);
10877         /* Check that there is such a thing as a super class. If not,
10878            return.  The error will be caught later on, during the
10879            resolution */
10880         if (!current_class)
10881           {
10882             current_class = saved_current_class;
10883             return;
10884           }
10885         qual = TREE_CHAIN (qual);
10886         /* Do one more interation to set things up */
10887         super_found = again = 1;
10888       }
10889   } while (again);
10890   
10891   /* If name appears within the scope of a local variable declaration
10892      or parameter declaration, then it is an expression name. We don't
10893      carry this test out if we're in the context of the use of SUPER
10894      or THIS */
10895   if (!this_found && !super_found 
10896       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10897       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10898     {
10899       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10900       QUAL_RESOLUTION (qual) = decl;
10901     }
10902
10903   /* If within the class/interface NAME was found to be used there
10904      exists a (possibly inherited) field named NAME, then this is an
10905      expression name. If we saw a NEW_ARRAY_EXPR before and want to
10906      address length, it is OK. */
10907   else if ((decl = lookup_field_wrapper (ptr_type, name))
10908            || name == length_identifier_node)
10909     {
10910       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10911       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10912     }
10913
10914   /* We reclassify NAME as yielding to a type name resolution if:
10915      - NAME is a class/interface declared within the compilation
10916        unit containing NAME,
10917      - NAME is imported via a single-type-import declaration,
10918      - NAME is declared in an another compilation unit of the package
10919        of the compilation unit containing NAME,
10920      - NAME is declared by exactly on type-import-on-demand declaration
10921      of the compilation unit containing NAME. 
10922      - NAME is actually a STRING_CST. */
10923   else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10924            || (decl = resolve_and_layout (name, NULL_TREE)))
10925     {
10926       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10927       QUAL_RESOLUTION (qual) = decl;
10928     }
10929
10930   /* Method call, array references and cast are expression name */
10931   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10932            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
10933            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR
10934            || TREE_CODE (QUAL_WFL (qual)) == MODIFY_EXPR)
10935     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10936
10937   /* Check here that NAME isn't declared by more than one
10938      type-import-on-demand declaration of the compilation unit
10939      containing NAME. FIXME */
10940
10941   /* Otherwise, NAME is reclassified as a package name */
10942   else 
10943     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
10944
10945   /* Propagate the qualification accross other components of the
10946      qualified name */
10947   for (qual = TREE_CHAIN (qual); qual;
10948        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
10949     {
10950       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10951         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
10952       else 
10953         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
10954     }
10955
10956   /* Store the global qualification for the ambiguous part of ID back
10957      into ID fields */
10958   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
10959     RESOLVE_EXPRESSION_NAME_P (id) = 1;
10960   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
10961     RESOLVE_TYPE_NAME_P (id) = 1;
10962   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10963     RESOLVE_PACKAGE_NAME_P (id) = 1;
10964
10965   /* Restore the current class */
10966   current_class = saved_current_class;
10967 }
10968
10969 static int
10970 breakdown_qualified (left, right, source)
10971     tree *left, *right, source;
10972 {
10973   char *p, *base;
10974   int   l = IDENTIFIER_LENGTH (source);
10975
10976   base = alloca (l + 1);
10977   memcpy (base, IDENTIFIER_POINTER (source), l + 1);
10978
10979   /* Breakdown NAME into REMAINDER . IDENTIFIER */
10980   p = base + l - 1;
10981   while (*p != '.' && p != base)
10982     p--;
10983
10984   /* We didn't find a '.'. Return an error */
10985   if (p == base)
10986     return 1;
10987
10988   *p = '\0';
10989   if (right)
10990     *right = get_identifier (p+1);
10991   *left = get_identifier (base);
10992   
10993   return 0;
10994 }
10995
10996 /* Return TRUE if two classes are from the same package. */
10997
10998 static int
10999 in_same_package (name1, name2)
11000   tree name1, name2;
11001 {
11002   tree tmp;
11003   tree pkg1;
11004   tree pkg2;
11005   
11006   if (TREE_CODE (name1) == TYPE_DECL)
11007     name1 = DECL_NAME (name1);
11008   if (TREE_CODE (name2) == TYPE_DECL)
11009     name2 = DECL_NAME (name2);
11010
11011   if (QUALIFIED_P (name1) != QUALIFIED_P (name2))
11012     /* One in empty package. */
11013     return 0;
11014
11015   if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0)
11016     /* Both in empty package. */
11017     return 1;
11018
11019   breakdown_qualified (&pkg1, &tmp, name1);
11020   breakdown_qualified (&pkg2, &tmp, name2);
11021   
11022   return (pkg1 == pkg2);
11023 }
11024
11025 /* Patch tree nodes in a function body. When a BLOCK is found, push
11026    local variable decls if present.
11027    Same as java_complete_lhs, but does resolve static finals to values. */
11028
11029 static tree
11030 java_complete_tree (node)
11031      tree node;
11032 {
11033   node = java_complete_lhs (node);
11034   if (JDECL_P (node) && CLASS_FINAL_VARIABLE_P (node)
11035       && DECL_INITIAL (node) != NULL_TREE
11036       && !flag_emit_xref)
11037     {
11038       tree value = DECL_INITIAL (node);
11039       DECL_INITIAL (node) = NULL_TREE;
11040       value = fold_constant_for_init (value, node);
11041       DECL_INITIAL (node) = value;
11042       if (value != NULL_TREE)
11043         {
11044           /* fold_constant_for_init sometimes widen the original type
11045              of the constant (i.e. byte to int.) It's not desirable,
11046              especially if NODE is a function argument. */
11047           if (TREE_CODE (value) == INTEGER_CST
11048               && TREE_TYPE (node) != TREE_TYPE (value))
11049             return convert (TREE_TYPE (node), value);
11050           else
11051             return value;
11052         }
11053       else
11054         DECL_FIELD_FINAL_IUD (node) = 0;
11055     }
11056   return node;
11057 }
11058
11059 static tree
11060 java_stabilize_reference (node)
11061      tree node;
11062 {
11063   if (TREE_CODE (node) == COMPOUND_EXPR)
11064     {
11065       tree op0 = TREE_OPERAND (node, 0);
11066       tree op1 = TREE_OPERAND (node, 1);
11067       TREE_OPERAND (node, 0) = save_expr (op0);
11068       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
11069       return node;
11070     }
11071   return stabilize_reference (node);
11072 }
11073
11074 /* Patch tree nodes in a function body. When a BLOCK is found, push
11075    local variable decls if present.
11076    Same as java_complete_tree, but does not resolve static finals to values. */
11077
11078 static tree
11079 java_complete_lhs (node)
11080      tree node;
11081 {
11082   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
11083   int flag;
11084
11085   /* CONVERT_EXPR always has its type set, even though it needs to be
11086      worked out. */
11087   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
11088     return node;
11089
11090   /* The switch block implements cases processing container nodes
11091      first.  Contained nodes are always written back. Leaves come
11092      next and return a value. */
11093   switch (TREE_CODE (node))
11094     {
11095     case BLOCK:
11096
11097       /* 1- Block section.
11098          Set the local values on decl names so we can identify them
11099          faster when they're referenced. At that stage, identifiers
11100          are legal so we don't check for declaration errors. */
11101       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11102         {
11103           DECL_CONTEXT (cn) = current_function_decl;
11104           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
11105         }
11106       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
11107           CAN_COMPLETE_NORMALLY (node) = 1;
11108       else
11109         {
11110           tree stmt = BLOCK_EXPR_BODY (node);
11111           tree *ptr;
11112           int error_seen = 0;
11113           if (TREE_CODE (stmt) == COMPOUND_EXPR)
11114             {
11115               /* Re-order from (((A; B); C); ...; Z) to 
11116                  (A; (B; (C ; (...; Z)))).
11117                  This makes it easier to scan the statements left-to-right
11118                  without using recursion (which might overflow the stack
11119                  if the block has many statements. */
11120               for (;;)
11121                 {
11122                   tree left = TREE_OPERAND (stmt, 0);
11123                   if (TREE_CODE (left) != COMPOUND_EXPR)
11124                     break;
11125                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
11126                   TREE_OPERAND (left, 1) = stmt;
11127                   stmt = left;
11128                 }
11129               BLOCK_EXPR_BODY (node) = stmt;
11130             }
11131
11132           /* Now do the actual complete, without deep recursion for
11133              long blocks. */
11134           ptr = &BLOCK_EXPR_BODY (node);
11135           while (TREE_CODE (*ptr) == COMPOUND_EXPR
11136                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
11137             {
11138               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
11139               tree *next = &TREE_OPERAND (*ptr, 1);
11140               TREE_OPERAND (*ptr, 0) = cur;
11141               if (cur == empty_stmt_node)
11142                 {
11143                   /* Optimization;  makes it easier to detect empty bodies.
11144                      Most useful for <clinit> with all-constant initializer. */
11145                   *ptr = *next;
11146                   continue;
11147                 }
11148               if (TREE_CODE (cur) == ERROR_MARK)
11149                 error_seen++;
11150               else if (! CAN_COMPLETE_NORMALLY (cur))
11151                 {
11152                   wfl_op2 = *next;
11153                   for (;;)
11154                     {
11155                       if (TREE_CODE (wfl_op2) == BLOCK)
11156                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
11157                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
11158                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
11159                       else
11160                         break;
11161                     }
11162                   if (TREE_CODE (wfl_op2) != CASE_EXPR
11163                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
11164                     unreachable_stmt_error (*ptr);
11165                 }
11166               ptr = next;
11167             }
11168           *ptr = java_complete_tree (*ptr);
11169
11170           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
11171             return error_mark_node;
11172           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
11173         }
11174       /* Turn local bindings to null */
11175       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
11176         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
11177
11178       TREE_TYPE (node) = void_type_node;
11179       break;
11180
11181       /* 2- They are expressions but ultimately deal with statements */
11182
11183     case THROW_EXPR:
11184       wfl_op1 = TREE_OPERAND (node, 0);
11185       COMPLETE_CHECK_OP_0 (node);
11186       /* 14.19 A throw statement cannot complete normally. */
11187       CAN_COMPLETE_NORMALLY (node) = 0;
11188       return patch_throw_statement (node, wfl_op1);
11189
11190     case SYNCHRONIZED_EXPR:
11191       wfl_op1 = TREE_OPERAND (node, 0);
11192       return patch_synchronized_statement (node, wfl_op1);
11193
11194     case TRY_EXPR:
11195       return patch_try_statement (node);
11196
11197     case TRY_FINALLY_EXPR:
11198       COMPLETE_CHECK_OP_0 (node);
11199       COMPLETE_CHECK_OP_1 (node);
11200       if (TREE_OPERAND (node, 0) == empty_stmt_node)
11201         return TREE_OPERAND (node, 1);
11202       if (TREE_OPERAND (node, 1) == empty_stmt_node)
11203         return TREE_OPERAND (node, 0);
11204       CAN_COMPLETE_NORMALLY (node)
11205         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
11206            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
11207       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
11208       return node;
11209
11210     case CLEANUP_POINT_EXPR:
11211       COMPLETE_CHECK_OP_0 (node);
11212       TREE_TYPE (node) = void_type_node;
11213       CAN_COMPLETE_NORMALLY (node) = 
11214         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
11215       return node;
11216
11217     case WITH_CLEANUP_EXPR:
11218       COMPLETE_CHECK_OP_0 (node);
11219       COMPLETE_CHECK_OP_2 (node);
11220       CAN_COMPLETE_NORMALLY (node) = 
11221         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
11222       TREE_TYPE (node) = void_type_node;
11223       return node;
11224
11225     case LABELED_BLOCK_EXPR:
11226       PUSH_LABELED_BLOCK (node);
11227       if (LABELED_BLOCK_BODY (node))
11228         COMPLETE_CHECK_OP_1 (node);
11229       TREE_TYPE (node) = void_type_node;
11230       POP_LABELED_BLOCK ();
11231
11232       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
11233         {
11234           LABELED_BLOCK_BODY (node) = NULL_TREE;
11235           CAN_COMPLETE_NORMALLY (node) = 1;
11236         }
11237       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
11238         CAN_COMPLETE_NORMALLY (node) = 1;
11239       return node;
11240
11241     case EXIT_BLOCK_EXPR:
11242       /* We don't complete operand 1, because it's the return value of
11243          the EXIT_BLOCK_EXPR which doesn't exist it Java */
11244       return patch_bc_statement (node);
11245
11246     case CASE_EXPR:
11247       cn = java_complete_tree (TREE_OPERAND (node, 0));
11248       if (cn == error_mark_node)
11249         return cn;
11250
11251       /* First, the case expression must be constant. Values of final
11252          fields are accepted. */
11253       cn = fold (cn);
11254       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
11255           && JDECL_P (TREE_OPERAND (cn, 1))
11256           && FIELD_FINAL (TREE_OPERAND (cn, 1))
11257           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
11258         {
11259           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
11260                                        TREE_OPERAND (cn, 1));
11261         }
11262
11263       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
11264         {
11265           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11266           parse_error_context (node, "Constant expression required");
11267           return error_mark_node;
11268         }
11269
11270       nn = ctxp->current_loop;
11271
11272       /* It must be assignable to the type of the switch expression. */
11273       if (!try_builtin_assignconv (NULL_TREE, 
11274                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
11275         {
11276           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11277           parse_error_context 
11278             (wfl_operator,
11279              "Incompatible type for case. Can't convert `%s' to `int'",
11280              lang_printable_name (TREE_TYPE (cn), 0));
11281           return error_mark_node;
11282         }
11283
11284       cn = fold (convert (int_type_node, cn));
11285
11286       /* Multiple instance of a case label bearing the same
11287          value is checked during code generation. The case
11288          expression is allright so far. */
11289       if (TREE_CODE (cn) == VAR_DECL)
11290         cn = DECL_INITIAL (cn);
11291       TREE_OPERAND (node, 0) = cn;
11292       TREE_TYPE (node) = void_type_node;
11293       CAN_COMPLETE_NORMALLY (node) = 1;
11294       TREE_SIDE_EFFECTS (node) = 1;
11295       break;
11296
11297     case DEFAULT_EXPR:
11298       nn = ctxp->current_loop;
11299       /* Only one default label is allowed per switch statement */
11300       if (SWITCH_HAS_DEFAULT (nn))
11301         {
11302           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11303           parse_error_context (wfl_operator, 
11304                                "Duplicate case label: `default'");
11305           return error_mark_node;
11306         }
11307       else
11308         SWITCH_HAS_DEFAULT (nn) = 1;
11309       TREE_TYPE (node) = void_type_node;
11310       TREE_SIDE_EFFECTS (node) = 1;
11311       CAN_COMPLETE_NORMALLY (node) = 1;
11312       break;
11313
11314     case SWITCH_EXPR:
11315     case LOOP_EXPR:
11316       PUSH_LOOP (node);
11317       /* Check whether the loop was enclosed in a labeled
11318          statement. If not, create one, insert the loop in it and
11319          return the node */
11320       nn = patch_loop_statement (node);
11321
11322       /* Anyways, walk the body of the loop */
11323       if (TREE_CODE (node) == LOOP_EXPR)
11324         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11325       /* Switch statement: walk the switch expression and the cases */
11326       else
11327         node = patch_switch_statement (node);
11328
11329       if (node == error_mark_node || TREE_OPERAND (node, 0) == error_mark_node)
11330         nn = error_mark_node;
11331       else
11332         {
11333           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
11334           /* If we returned something different, that's because we
11335              inserted a label. Pop the label too. */
11336           if (nn != node)
11337             {
11338               if (CAN_COMPLETE_NORMALLY (node))
11339                 CAN_COMPLETE_NORMALLY (nn) = 1;
11340               POP_LABELED_BLOCK ();
11341             }
11342         }
11343       POP_LOOP ();
11344       return nn;
11345
11346     case EXIT_EXPR:
11347       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11348       return patch_exit_expr (node);
11349
11350     case COND_EXPR:
11351       /* Condition */
11352       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11353       if (TREE_OPERAND (node, 0) == error_mark_node)
11354         return error_mark_node;
11355       /* then-else branches */
11356       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11357       if (TREE_OPERAND (node, 1) == error_mark_node)
11358         return error_mark_node;
11359       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
11360       if (TREE_OPERAND (node, 2) == error_mark_node)
11361         return error_mark_node;
11362       return patch_if_else_statement (node);
11363       break;
11364
11365     case CONDITIONAL_EXPR:
11366       /* Condition */
11367       wfl_op1 = TREE_OPERAND (node, 0);
11368       COMPLETE_CHECK_OP_0 (node);
11369       wfl_op2 = TREE_OPERAND (node, 1);
11370       COMPLETE_CHECK_OP_1 (node);
11371       wfl_op3 = TREE_OPERAND (node, 2);
11372       COMPLETE_CHECK_OP_2 (node);
11373       return patch_conditional_expr (node, wfl_op1, wfl_op2);
11374
11375       /* 3- Expression section */
11376     case COMPOUND_EXPR:
11377       wfl_op2 = TREE_OPERAND (node, 1);
11378       TREE_OPERAND (node, 0) = nn = 
11379         java_complete_tree (TREE_OPERAND (node, 0));
11380       if (wfl_op2 == empty_stmt_node)
11381         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
11382       else
11383         {
11384           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
11385             {
11386               /* An unreachable condition in a do-while statement
11387                  is *not* (technically) an unreachable statement. */
11388               nn = wfl_op2;
11389               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
11390                 nn = EXPR_WFL_NODE (nn);
11391               if (TREE_CODE (nn) != EXIT_EXPR)
11392                 {
11393                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
11394                   parse_error_context (wfl_operator, "Unreachable statement");
11395                 }
11396             }
11397           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11398           if (TREE_OPERAND (node, 1) == error_mark_node)
11399             return error_mark_node;
11400           CAN_COMPLETE_NORMALLY (node)
11401             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
11402         }
11403       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
11404       break;
11405
11406     case RETURN_EXPR:
11407       /* CAN_COMPLETE_NORMALLY (node) = 0; */
11408       return patch_return (node);
11409
11410     case EXPR_WITH_FILE_LOCATION:
11411       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11412           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11413         {
11414           tree wfl = node;
11415           node = resolve_expression_name (node, NULL);
11416           if (node == error_mark_node)
11417             return node;
11418           /* Keep line number information somewhere were it doesn't
11419              disrupt the completion process. */
11420           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
11421             {
11422               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
11423               TREE_OPERAND (node, 1) = wfl;
11424             }
11425           CAN_COMPLETE_NORMALLY (node) = 1;
11426         }
11427       else
11428         {
11429           tree body;
11430           int save_lineno = lineno;
11431           lineno = EXPR_WFL_LINENO (node);
11432           body = java_complete_tree (EXPR_WFL_NODE (node));
11433           lineno = save_lineno;
11434           EXPR_WFL_NODE (node) = body;
11435           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
11436           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
11437           if (body == empty_stmt_node || TREE_CONSTANT (body))
11438             {
11439               /* Makes it easier to constant fold, detect empty bodies. */
11440               return body;
11441             }
11442           if (body == error_mark_node)
11443             {
11444               /* Its important for the evaluation of assignment that
11445                  this mark on the TREE_TYPE is propagated. */
11446               TREE_TYPE (node) = error_mark_node;
11447               return error_mark_node;
11448             }
11449           else
11450             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
11451           
11452         }
11453       break;
11454
11455     case NEW_ARRAY_EXPR:
11456       /* Patch all the dimensions */
11457       flag = 0;
11458       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11459         {
11460           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
11461           tree dim = convert (int_type_node, 
11462                               java_complete_tree (TREE_VALUE (cn)));
11463           if (dim == error_mark_node)
11464             {
11465               flag = 1;
11466               continue;
11467             }
11468           else
11469             {
11470               TREE_VALUE (cn) = dim;
11471               /* Setup the location of the current dimension, for
11472                  later error report. */
11473               TREE_PURPOSE (cn) = 
11474                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
11475               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
11476             }
11477         }
11478       /* They complete the array creation expression, if no errors
11479          were found. */
11480       CAN_COMPLETE_NORMALLY (node) = 1;
11481       return (flag ? error_mark_node
11482               : force_evaluation_order (patch_newarray (node)));
11483
11484     case NEW_ANONYMOUS_ARRAY_EXPR:
11485       /* Create the array type if necessary. */
11486       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
11487         {
11488           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
11489           if (!(type = resolve_type_during_patch (type)))
11490             return error_mark_node;
11491           type = build_array_from_name (type, NULL_TREE,
11492                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
11493           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
11494         }
11495       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
11496                                    ANONYMOUS_ARRAY_INITIALIZER (node));
11497       if (node == error_mark_node)
11498         return error_mark_node;
11499       CAN_COMPLETE_NORMALLY (node) = 1;
11500       return node;
11501
11502     case NEW_CLASS_EXPR:
11503     case CALL_EXPR:
11504       /* Complete function's argument(s) first */
11505       if (complete_function_arguments (node))
11506         return error_mark_node;
11507       else
11508         {
11509           tree decl, wfl = TREE_OPERAND (node, 0);
11510           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
11511           int from_super = (EXPR_WFL_NODE (TREE_OPERAND (node, 0)) ==
11512                            super_identifier_node);
11513
11514           node = patch_method_invocation (node, NULL_TREE, NULL_TREE,
11515                                           from_super, 0, &decl);
11516           if (node == error_mark_node)
11517             return error_mark_node;
11518
11519           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
11520           /* If we call this(...), register signature and positions */
11521           if (in_this)
11522             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
11523               tree_cons (wfl, decl, 
11524                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
11525           CAN_COMPLETE_NORMALLY (node) = 1;
11526           return force_evaluation_order (node);
11527         }
11528
11529     case MODIFY_EXPR:
11530       /* Save potential wfls */
11531       wfl_op1 = TREE_OPERAND (node, 0);
11532       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
11533       
11534       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
11535           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
11536           && DECL_INITIAL (nn) != NULL_TREE)
11537         {
11538           tree value;
11539           
11540           value = fold_constant_for_init (nn, nn);
11541
11542           if (value != NULL_TREE)
11543             {
11544               tree type = TREE_TYPE (value);
11545               if (JPRIMITIVE_TYPE_P (type) || 
11546                   (type == string_ptr_type_node && ! flag_emit_class_files))
11547                 return empty_stmt_node;
11548             }
11549           if (! flag_emit_class_files)
11550             DECL_INITIAL (nn) = NULL_TREE;
11551           if (CLASS_FINAL_VARIABLE_P (nn))
11552             DECL_FIELD_FINAL_IUD (nn) = 0;
11553         }
11554       wfl_op2 = TREE_OPERAND (node, 1);
11555
11556       if (TREE_OPERAND (node, 0) == error_mark_node)
11557         return error_mark_node;
11558
11559       flag = COMPOUND_ASSIGN_P (wfl_op2);
11560       if (flag)
11561         {
11562           /* This might break when accessing outer field from inner
11563              class. TESTME, FIXME */
11564           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
11565
11566           /* Hand stabilize the lhs on both places */
11567           TREE_OPERAND (node, 0) = lvalue;
11568           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
11569             (flag_emit_class_files ? lvalue : save_expr (lvalue));
11570
11571           /* 15.25.2.a: Left hand is not an array access. FIXME */
11572           /* Now complete the RHS. We write it back later on. */
11573           nn = java_complete_tree (TREE_OPERAND (node, 1));
11574
11575           if ((cn = patch_string (nn)))
11576             nn = cn;
11577
11578           /* The last part of the rewrite for E1 op= E2 is to have 
11579              E1 = (T)(E1 op E2), with T being the type of E1. */
11580           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
11581                                                TREE_TYPE (lvalue), nn));
11582
11583           /* If the assignment is compound and has reference type,
11584              then ensure the LHS has type String and nothing else.  */
11585           if (JREFERENCE_TYPE_P (TREE_TYPE (lvalue))
11586               && ! JSTRING_TYPE_P (TREE_TYPE (lvalue)))
11587             parse_error_context (wfl_op2,
11588                                  "Incompatible type for `+='. Can't convert `%s' to `java.lang.String'",
11589                                  lang_printable_name (TREE_TYPE (lvalue), 0));
11590
11591           /* 15.25.2.b: Left hand is an array access. FIXME */
11592         }
11593
11594       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
11595          function to complete this RHS. Note that a NEW_ARRAY_INIT
11596          might have been already fully expanded if created as a result
11597          of processing an anonymous array initializer. We avoid doing
11598          the operation twice by testing whether the node already bears
11599          a type. */
11600       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
11601         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
11602                                    TREE_OPERAND (node, 1));
11603       /* Otherwise we simply complete the RHS */
11604       else
11605         nn = java_complete_tree (TREE_OPERAND (node, 1));
11606
11607       if (nn == error_mark_node)
11608         return error_mark_node;
11609
11610       /* Write back the RHS as we evaluated it. */
11611       TREE_OPERAND (node, 1) = nn;
11612
11613       /* In case we're handling = with a String as a RHS, we need to
11614          produce a String out of the RHS (it might still be a
11615          STRING_CST or a StringBuffer at this stage */
11616       if ((nn = patch_string (TREE_OPERAND (node, 1))))
11617         TREE_OPERAND (node, 1) = nn;
11618
11619       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
11620                                         TREE_OPERAND (node, 1))))
11621         {
11622           /* We return error_mark_node if outer_field_access_fix
11623              detects we write into a final. */
11624           if (nn == error_mark_node)
11625             return error_mark_node;
11626           node = nn;
11627         }
11628       else
11629         {
11630           node = patch_assignment (node, wfl_op1, wfl_op2);
11631           /* Reorganize the tree if necessary. */
11632           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
11633                        || JSTRING_P (TREE_TYPE (node))))
11634             node = java_refold (node);
11635         }
11636       
11637       CAN_COMPLETE_NORMALLY (node) = 1;
11638       return node;
11639
11640     case MULT_EXPR:
11641     case PLUS_EXPR:
11642     case MINUS_EXPR:
11643     case LSHIFT_EXPR:
11644     case RSHIFT_EXPR:
11645     case URSHIFT_EXPR:
11646     case BIT_AND_EXPR:
11647     case BIT_XOR_EXPR:
11648     case BIT_IOR_EXPR:
11649     case TRUNC_MOD_EXPR:
11650     case TRUNC_DIV_EXPR:
11651     case RDIV_EXPR:
11652     case TRUTH_ANDIF_EXPR:
11653     case TRUTH_ORIF_EXPR:
11654     case EQ_EXPR: 
11655     case NE_EXPR:
11656     case GT_EXPR:
11657     case GE_EXPR:
11658     case LT_EXPR:
11659     case LE_EXPR:
11660       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
11661          knows how to handle those cases. */
11662       wfl_op1 = TREE_OPERAND (node, 0);
11663       wfl_op2 = TREE_OPERAND (node, 1);
11664
11665       CAN_COMPLETE_NORMALLY (node) = 1;
11666       /* Don't complete string nodes if dealing with the PLUS operand. */
11667       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11668         {
11669           nn = java_complete_tree (wfl_op1);
11670           if (nn == error_mark_node)
11671             return error_mark_node;
11672
11673           TREE_OPERAND (node, 0) = nn;
11674         }
11675       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11676         {
11677           nn = java_complete_tree (wfl_op2);
11678           if (nn == error_mark_node)
11679             return error_mark_node;
11680
11681           TREE_OPERAND (node, 1) = nn;
11682         }
11683       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11684
11685     case INSTANCEOF_EXPR:
11686       wfl_op1 = TREE_OPERAND (node, 0);
11687       COMPLETE_CHECK_OP_0 (node);
11688       if (flag_emit_xref)
11689         {
11690           TREE_TYPE (node) = boolean_type_node;
11691           return node;
11692         }
11693       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11694
11695     case UNARY_PLUS_EXPR:
11696     case NEGATE_EXPR:
11697     case TRUTH_NOT_EXPR:
11698     case BIT_NOT_EXPR:
11699     case PREDECREMENT_EXPR:
11700     case PREINCREMENT_EXPR:
11701     case POSTDECREMENT_EXPR:
11702     case POSTINCREMENT_EXPR:
11703     case CONVERT_EXPR:
11704       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11705          how to handle those cases. */
11706       wfl_op1 = TREE_OPERAND (node, 0);
11707       CAN_COMPLETE_NORMALLY (node) = 1;
11708       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11709       if (TREE_OPERAND (node, 0) == error_mark_node)
11710         return error_mark_node;
11711       node = patch_unaryop (node, wfl_op1);
11712       CAN_COMPLETE_NORMALLY (node) = 1;
11713       break;
11714
11715     case ARRAY_REF:
11716       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11717          how to handle those cases. */
11718       wfl_op1 = TREE_OPERAND (node, 0);
11719       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11720       if (TREE_OPERAND (node, 0) == error_mark_node)
11721         return error_mark_node;
11722       if (!flag_emit_class_files && !flag_emit_xref)
11723         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11724       /* The same applies to wfl_op2 */
11725       wfl_op2 = TREE_OPERAND (node, 1);
11726       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11727       if (TREE_OPERAND (node, 1) == error_mark_node)
11728         return error_mark_node;
11729       if (!flag_emit_class_files && !flag_emit_xref)
11730         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11731       return patch_array_ref (node);
11732
11733     case RECORD_TYPE:
11734       return node;;
11735
11736     case COMPONENT_REF:
11737       /* The first step in the re-write of qualified name handling.  FIXME.
11738          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11739       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11740       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11741         {
11742           tree name = TREE_OPERAND (node, 1);
11743           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11744           if (field == NULL_TREE)
11745             {
11746               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11747               return error_mark_node;
11748             }
11749           if (! FIELD_STATIC (field))
11750             {
11751               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11752               return error_mark_node;
11753             }
11754           return field;
11755         }
11756       else
11757         abort ();
11758       break;
11759
11760     case THIS_EXPR:
11761       /* Can't use THIS in a static environment */
11762       if (!current_this)
11763         {
11764           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11765           parse_error_context (wfl_operator,
11766                                "Keyword `this' used outside allowed context");
11767           TREE_TYPE (node) = error_mark_node;
11768           return error_mark_node;
11769         }
11770       if (ctxp->explicit_constructor_p)
11771         {
11772           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11773           parse_error_context 
11774             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11775           TREE_TYPE (node) = error_mark_node;
11776           return error_mark_node;
11777         }
11778       return current_this;
11779       
11780     case CLASS_LITERAL:
11781       CAN_COMPLETE_NORMALLY (node) = 1;
11782       node = patch_incomplete_class_ref (node);
11783       if (node == error_mark_node)
11784         return error_mark_node;
11785       break;
11786
11787     case INSTANCE_INITIALIZERS_EXPR:
11788       in_instance_initializer++;
11789       node = java_complete_tree (TREE_OPERAND (node, 0));
11790       in_instance_initializer--;
11791       if (node != error_mark_node)
11792         TREE_TYPE (node) = void_type_node;
11793       else
11794         return error_mark_node;
11795       break;
11796
11797     default:
11798       CAN_COMPLETE_NORMALLY (node) = 1;
11799       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11800          and it's time to turn it into the appropriate String object */
11801       if ((nn = patch_string (node)))
11802         node = nn;
11803       else
11804         internal_error ("No case for %s", tree_code_name [TREE_CODE (node)]);
11805     }
11806   return node;
11807 }
11808
11809 /* Complete function call's argument. Return a non zero value is an
11810    error was found.  */
11811
11812 static int
11813 complete_function_arguments (node)
11814      tree node;
11815 {
11816   int flag = 0;
11817   tree cn;
11818
11819   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11820   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11821     {
11822       tree wfl = TREE_VALUE (cn), parm, temp;
11823       parm = java_complete_tree (wfl);
11824
11825       if (parm == error_mark_node)
11826         {
11827           flag = 1;
11828           continue;
11829         }
11830       /* If have a string literal that we haven't transformed yet or a
11831          crafted string buffer, as a result of use of the the String
11832          `+' operator. Build `parm.toString()' and expand it. */
11833       if ((temp = patch_string (parm)))
11834         parm = temp;
11835       /* Inline PRIMTYPE.TYPE read access */
11836       parm = maybe_build_primttype_type_ref (parm, wfl);
11837
11838       TREE_VALUE (cn) = parm;
11839     }
11840   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11841   return flag;
11842 }
11843
11844 /* Sometimes (for loops and variable initialized during their
11845    declaration), we want to wrap a statement around a WFL and turn it
11846    debugable.  */
11847
11848 static tree
11849 build_debugable_stmt (location, stmt)
11850     int location;
11851     tree stmt;
11852 {
11853   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11854     {
11855       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11856       EXPR_WFL_LINECOL (stmt) = location;
11857     }
11858   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11859   return stmt;
11860 }
11861
11862 static tree
11863 build_expr_block (body, decls)
11864      tree body, decls;
11865 {
11866   tree node = make_node (BLOCK);
11867   BLOCK_EXPR_DECLS (node) = decls;
11868   BLOCK_EXPR_BODY (node) = body;
11869   if (body)
11870     TREE_TYPE (node) = TREE_TYPE (body);
11871   TREE_SIDE_EFFECTS (node) = 1;
11872   return node;
11873 }
11874
11875 /* Create a new function block and link it approriately to current
11876    function block chain */
11877
11878 static tree
11879 enter_block ()
11880 {
11881   tree b = build_expr_block (NULL_TREE, NULL_TREE);
11882
11883   /* Link block B supercontext to the previous block. The current
11884      function DECL is used as supercontext when enter_a_block is called
11885      for the first time for a given function. The current function body
11886      (DECL_FUNCTION_BODY) is set to be block B.  */
11887
11888   tree fndecl = current_function_decl; 
11889
11890   if (!fndecl) {
11891     BLOCK_SUPERCONTEXT (b) = current_static_block;
11892     current_static_block = b;
11893   }
11894
11895   else if (!DECL_FUNCTION_BODY (fndecl))
11896     {
11897       BLOCK_SUPERCONTEXT (b) = fndecl;
11898       DECL_FUNCTION_BODY (fndecl) = b;
11899     }
11900   else
11901     {
11902       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11903       DECL_FUNCTION_BODY (fndecl) = b;
11904     }
11905   return b;
11906 }
11907
11908 /* Exit a block by changing the current function body
11909    (DECL_FUNCTION_BODY) to the current block super context, only if
11910    the block being exited isn't the method's top level one.  */
11911
11912 static tree
11913 exit_block ()
11914 {
11915   tree b;
11916   if (current_function_decl)
11917     {
11918       b = DECL_FUNCTION_BODY (current_function_decl);
11919       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11920         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11921     }
11922   else
11923     {
11924       b = current_static_block;
11925
11926       if (BLOCK_SUPERCONTEXT (b))
11927         current_static_block = BLOCK_SUPERCONTEXT (b);
11928     }
11929   return b;
11930 }
11931
11932 /* Lookup for NAME in the nested function's blocks, all the way up to
11933    the current toplevel one. It complies with Java's local variable
11934    scoping rules.  */
11935
11936 static tree
11937 lookup_name_in_blocks (name)
11938      tree name;
11939 {
11940   tree b = GET_CURRENT_BLOCK (current_function_decl);
11941
11942   while (b != current_function_decl)
11943     {
11944       tree current;
11945
11946       /* Paranoid sanity check. To be removed */
11947       if (TREE_CODE (b) != BLOCK)
11948         abort ();
11949
11950       for (current = BLOCK_EXPR_DECLS (b); current; 
11951            current = TREE_CHAIN (current))
11952         if (DECL_NAME (current) == name)
11953           return current;
11954       b = BLOCK_SUPERCONTEXT (b);
11955     }
11956   return NULL_TREE;
11957 }
11958
11959 static void
11960 maybe_absorb_scoping_blocks ()
11961 {
11962   while (BLOCK_IS_IMPLICIT (GET_CURRENT_BLOCK (current_function_decl)))
11963     {
11964       tree b = exit_block ();
11965       java_method_add_stmt (current_function_decl, b);
11966       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
11967     }
11968 }
11969
11970 \f
11971 /* This section of the source is reserved to build_* functions that
11972    are building incomplete tree nodes and the patch_* functions that
11973    are completing them.  */
11974
11975 /* Wrap a non WFL node around a WFL.  */
11976
11977 static tree
11978 build_wfl_wrap (node, location)
11979     tree node;
11980     int location;
11981 {
11982   tree wfl, node_to_insert = node;
11983   
11984   /* We want to process THIS . xxx symbolicaly, to keep it consistent
11985      with the way we're processing SUPER. A THIS from a primary as a
11986      different form than a SUPER. Turn THIS into something symbolic */
11987   if (TREE_CODE (node) == THIS_EXPR)
11988     node_to_insert = wfl = build_wfl_node (this_identifier_node);
11989   else
11990     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
11991
11992   EXPR_WFL_LINECOL (wfl) = location;
11993   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
11994   return wfl;
11995 }
11996
11997 /* Build a super() constructor invocation. Returns empty_stmt_node if
11998    we're currently dealing with the class java.lang.Object. */
11999
12000 static tree
12001 build_super_invocation (mdecl)
12002      tree mdecl;
12003 {
12004   if (DECL_CONTEXT (mdecl) == object_type_node)
12005     return empty_stmt_node;
12006   else
12007     {
12008       tree super_wfl = build_wfl_node (super_identifier_node);
12009       tree a = NULL_TREE, t;
12010       /* If we're dealing with an anonymous class, pass the arguments
12011          of the crafted constructor along. */
12012       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
12013         {
12014           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
12015           for (; t != end_params_node; t = TREE_CHAIN (t))
12016             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
12017         }
12018       return build_method_invocation (super_wfl, a);
12019     }
12020 }
12021
12022 /* Build a SUPER/THIS qualified method invocation.  */
12023
12024 static tree
12025 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
12026      int use_this;
12027      tree name, args;
12028      int lloc, rloc;
12029 {
12030   tree invok;
12031   tree wfl = 
12032     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
12033   EXPR_WFL_LINECOL (wfl) = lloc;
12034   invok = build_method_invocation (name, args);
12035   return make_qualified_primary (wfl, invok, rloc);
12036 }
12037
12038 /* Build an incomplete CALL_EXPR node. */
12039
12040 static tree
12041 build_method_invocation (name, args)
12042     tree name;
12043     tree args;
12044 {
12045   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
12046   TREE_SIDE_EFFECTS (call) = 1;
12047   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12048   return call;
12049 }
12050
12051 /* Build an incomplete new xxx(...) node. */
12052
12053 static tree
12054 build_new_invocation (name, args)
12055     tree name, args;
12056 {
12057   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
12058   TREE_SIDE_EFFECTS (call) = 1;
12059   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
12060   return call;
12061 }
12062
12063 /* Build an incomplete assignment expression. */
12064
12065 static tree
12066 build_assignment (op, op_location, lhs, rhs)
12067      int op, op_location;
12068      tree lhs, rhs;
12069 {
12070   tree assignment;
12071   /* Build the corresponding binop if we deal with a Compound
12072      Assignment operator. Mark the binop sub-tree as part of a
12073      Compound Assignment expression */
12074   if (op != ASSIGN_TK)
12075     {
12076       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
12077       COMPOUND_ASSIGN_P (rhs) = 1;
12078     }
12079   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
12080   TREE_SIDE_EFFECTS (assignment) = 1;
12081   EXPR_WFL_LINECOL (assignment) = op_location;
12082   return assignment;
12083 }
12084
12085 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
12086
12087 char *
12088 print_int_node (node)
12089     tree node;
12090 {
12091   static char buffer [80];
12092   if (TREE_CONSTANT_OVERFLOW (node))
12093     sprintf (buffer, "<overflow>");
12094     
12095   if (TREE_INT_CST_HIGH (node) == 0)
12096     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
12097              TREE_INT_CST_LOW (node));
12098   else if (TREE_INT_CST_HIGH (node) == -1
12099            && TREE_INT_CST_LOW (node) != 0)
12100     {
12101       buffer [0] = '-';
12102       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
12103                -TREE_INT_CST_LOW (node));
12104     }
12105   else
12106     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
12107              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
12108
12109   return buffer;
12110 }
12111
12112 \f
12113
12114 /* This section of the code handle assignment check with FINAL
12115    variables.  */
12116
12117 static void
12118 reset_static_final_variable_assignment_flag (class)
12119      tree class;
12120 {
12121   tree field;
12122   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12123     if (CLASS_FINAL_VARIABLE_P (field))
12124       DECL_FIELD_FINAL_LIIC (field) = 0;
12125 }
12126
12127 /* Figure whether all final static variable have been initialized.  */
12128
12129 static void
12130 check_static_final_variable_assignment_flag (class)
12131      tree class;
12132 {
12133   tree field;
12134
12135   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12136     if (CLASS_FINAL_VARIABLE_P (field)
12137         && !DECL_FIELD_FINAL_IUD (field) && !DECL_FIELD_FINAL_LIIC (field))
12138       parse_error_context
12139         (DECL_FIELD_FINAL_WFL (field),
12140          "Blank static final variable `%s' may not have been initialized",
12141          IDENTIFIER_POINTER (DECL_NAME (field)));
12142 }
12143
12144 /* This function marks all final variable locally unassigned.  */
12145
12146 static void
12147 reset_final_variable_local_assignment_flag (class)
12148      tree class;
12149 {
12150   tree field;
12151   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12152     if (FINAL_VARIABLE_P (field))
12153       DECL_FIELD_FINAL_LIIC (field) = 0;
12154 }
12155
12156 /* Figure whether all final variables have beem initialized in MDECL
12157    and mark MDECL accordingly.  */
12158
12159 static void
12160 check_final_variable_local_assignment_flag (class, mdecl)
12161      tree class;
12162      tree mdecl;
12163 {
12164   tree field;
12165   int initialized = 0;
12166   int non_initialized = 0; 
12167
12168   if (DECL_FUNCTION_SYNTHETIC_CTOR (mdecl))
12169     return;
12170
12171   /* First find out whether all final variables or no final variable
12172      are initialized in this ctor. We don't take into account final
12173      variable that have been initialized upon declaration.  */
12174   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12175     if (FINAL_VARIABLE_P (field) && !DECL_FIELD_FINAL_IUD (field))
12176       {
12177         if (DECL_FIELD_FINAL_LIIC (field))
12178           initialized++;
12179         else
12180           non_initialized++;
12181       }
12182
12183   /* There were no non initialized variable and no initialized variable.
12184      This ctor is fine. */
12185   if (!non_initialized && !initialized)
12186     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12187   /* If no variables have been initialized, that fine. We'll check
12188      later whether this ctor calls a constructor which initializes
12189      them. We mark the ctor as not initializing all its finals. */
12190   else if (initialized == 0)
12191     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 0;
12192   /* If we have a mixed bag, then we have a problem. We need to report
12193      all the variables we're not initializing.  */
12194   else if (initialized && non_initialized)
12195     {
12196       DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 0;
12197       for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12198         if (FIELD_FINAL (field)
12199             && !DECL_FIELD_FINAL_IUD (field) && !DECL_FIELD_FINAL_LIIC (field))
12200           {
12201             parse_error_context 
12202               (lookup_cl (mdecl),
12203                "Blank final variable `%s' may not have been initialized in this constructor",
12204                IDENTIFIER_POINTER (DECL_NAME (field)));
12205             DECL_FIELD_FINAL_IERR (field) = 1;
12206           }
12207     }
12208   /* Otherwise we know this ctor is initializing all its final
12209      variable. We mark it so. */
12210   else
12211     DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12212 }
12213
12214 /* This function recurses in a simple what through STMT and stops when
12215    it finds a constructor call. It then verifies that the called
12216    constructor initialized its final properly. Return 1 upon success,
12217    0 or -1 otherwise.  */
12218
12219 static int
12220 check_final_variable_indirect_assignment (stmt)
12221      tree stmt;
12222 {
12223   int res;
12224   switch (TREE_CODE (stmt))
12225     {
12226     case EXPR_WITH_FILE_LOCATION:
12227       return check_final_variable_indirect_assignment (EXPR_WFL_NODE (stmt));
12228     case COMPOUND_EXPR:
12229       res = check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 0));
12230       if (res)
12231         return res;
12232       return check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 1));
12233     case SAVE_EXPR:
12234       return check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 0));
12235     case CALL_EXPR:
12236       {
12237         tree decl = TREE_OPERAND (stmt, 0);
12238         tree fbody;
12239
12240         if (TREE_CODE (decl) != FUNCTION_DECL)
12241           decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
12242         if (TREE_CODE (decl) != FUNCTION_DECL)
12243           abort ();
12244         if (DECL_FUNCTION_ALL_FINAL_INITIALIZED (decl))
12245           return 1;
12246         if (DECL_FINIT_P (decl) || DECL_CONTEXT (decl) != current_class)
12247           return -1;
12248         fbody = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
12249         if (fbody == error_mark_node)
12250           return -1;
12251         fbody = BLOCK_EXPR_BODY (fbody);
12252         return check_final_variable_indirect_assignment (fbody);
12253       }
12254     default:
12255       break;
12256     }
12257   return 0;
12258 }
12259
12260 /* This is the last chance to catch a final variable initialization
12261    problem. This routine will report an error if a final variable was
12262    never (globally) initialized and never reported as not having been
12263    initialized properly. */
12264
12265 static void
12266 check_final_variable_global_assignment_flag (class)
12267      tree class;
12268 {
12269   tree field, mdecl;
12270   int nnctor = 0;
12271
12272   /* We go through all natural ctors and see whether they're
12273      initializing all their final variables or not. */
12274   current_function_decl = NULL_TREE; /* For the error report. */
12275   for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
12276     if (DECL_CONSTRUCTOR_P (mdecl) && ! DECL_FUNCTION_SYNTHETIC_CTOR (mdecl))
12277       {
12278         if (!DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl))
12279           {
12280             /* It doesn't. Maybe it calls a constructor that initializes
12281                them.  find out. */
12282             tree fbody = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl));
12283             if (fbody == error_mark_node)
12284               continue;
12285             fbody = BLOCK_EXPR_BODY (fbody);
12286             if (check_final_variable_indirect_assignment (fbody) == 1)
12287               {
12288                 DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
12289                 nnctor++;
12290               }
12291             else
12292               parse_error_context
12293                 (lookup_cl (mdecl),
12294                  "Final variable initialization error in this constructor");
12295           }
12296         else
12297           nnctor++;
12298       }
12299
12300   /* Finally we catch final variables that never were initialized */
12301   for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
12302     if (FINAL_VARIABLE_P (field)
12303         /* If the field wasn't initialized upon declaration */
12304         && !DECL_FIELD_FINAL_IUD (field)
12305         /* There wasn't natural ctor in which the field could have been
12306            initialized */
12307         && !nnctor
12308         /* If we never reported a problem with this field */
12309         && !DECL_FIELD_FINAL_IERR (field))
12310       {
12311         current_function_decl = NULL;
12312         parse_error_context
12313           (DECL_FIELD_FINAL_WFL (field),
12314            "Final variable `%s' hasn't been initialized upon its declaration",
12315            IDENTIFIER_POINTER (DECL_NAME (field)));
12316       }
12317
12318 }
12319
12320 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
12321    context.  */
12322
12323 static int
12324 check_final_assignment (lvalue, wfl)
12325      tree lvalue, wfl;
12326 {
12327   if (TREE_CODE (lvalue) != COMPONENT_REF && !JDECL_P (lvalue))
12328     return 0;
12329
12330   if (TREE_CODE (lvalue) == COMPONENT_REF
12331       && JDECL_P (TREE_OPERAND (lvalue, 1)))
12332     lvalue = TREE_OPERAND (lvalue, 1);
12333
12334   if (!FIELD_FINAL (lvalue))
12335     return 0;
12336
12337   /* Now the logic. We can modify a final VARIABLE:
12338      1) in finit$, (its declaration was followed by an initialization,)
12339      2) consistently in each natural ctor, if it wasn't initialized in
12340         finit$ or once in <clinit>.  In any other cases, an error should be
12341         reported. */
12342   if (DECL_FINIT_P (current_function_decl))
12343     {
12344       DECL_FIELD_FINAL_IUD (lvalue) = 1;
12345       return 0;
12346     }
12347
12348   if (!DECL_FUNCTION_SYNTHETIC_CTOR (current_function_decl)
12349       /* Only if it wasn't given a value upon initialization */
12350       && DECL_LANG_SPECIFIC (lvalue) && !DECL_FIELD_FINAL_IUD (lvalue)
12351       /* If it was never assigned a value in this constructor */
12352       && !DECL_FIELD_FINAL_LIIC (lvalue))
12353     {
12354       /* Turn the locally assigned flag on, it will be checked later
12355          on to point out at discrepancies. */
12356       DECL_FIELD_FINAL_LIIC (lvalue) = 1;
12357       if (DECL_CLINIT_P (current_function_decl))
12358         DECL_FIELD_FINAL_IUD (lvalue) = 1;
12359       return 0;
12360     }
12361
12362   /* Other problems should be reported right away. */
12363   parse_error_context 
12364     (wfl, "Can't %sassign a value to the final variable `%s'",
12365      (FIELD_STATIC (lvalue) ? "re" : ""),
12366      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
12367
12368   /* Note that static field can be initialized once and only once. */
12369   if (FIELD_STATIC (lvalue))
12370     DECL_FIELD_FINAL_IERR (lvalue) = 1;
12371
12372   return 1;
12373 }
12374
12375 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
12376    read. This is needed to avoid circularities in the implementation
12377    of these fields in libjava. */
12378
12379 static tree
12380 maybe_build_primttype_type_ref (rhs, wfl)
12381     tree rhs, wfl;
12382 {
12383   tree to_return = NULL_TREE;
12384   tree rhs_type = TREE_TYPE (rhs);
12385   if (TREE_CODE (rhs) == COMPOUND_EXPR)
12386     {
12387       tree n = TREE_OPERAND (rhs, 1);
12388       if (TREE_CODE (n) == VAR_DECL 
12389           && DECL_NAME (n) == TYPE_identifier_node
12390           && rhs_type == class_ptr_type
12391           && TREE_CODE (EXPR_WFL_NODE (wfl)) == IDENTIFIER_NODE)
12392         {
12393           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
12394           if (!strncmp (self_name, "java.lang.", 10))
12395             to_return = build_primtype_type_ref (self_name);
12396         }
12397     }
12398   return (to_return ? to_return : rhs );
12399 }
12400
12401 /* 15.25 Assignment operators. */
12402
12403 static tree
12404 patch_assignment (node, wfl_op1, wfl_op2)
12405      tree node;
12406      tree wfl_op1;
12407      tree wfl_op2;
12408 {
12409   tree rhs = TREE_OPERAND (node, 1);
12410   tree lvalue = TREE_OPERAND (node, 0), llvalue;
12411   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
12412   int error_found = 0;
12413   int lvalue_from_array = 0;
12414
12415   /* Can't assign to a (blank) final. */
12416   if (check_final_assignment (lvalue, wfl_op1))
12417     error_found = 1;
12418
12419   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12420
12421   /* Lhs can be a named variable */
12422   if (JDECL_P (lvalue))
12423     {
12424       lhs_type = TREE_TYPE (lvalue);
12425     }
12426   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
12427      comment on reason why */
12428   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
12429     {
12430       lhs_type = TREE_TYPE (lvalue);
12431       lvalue_from_array = 1;
12432     }
12433   /* Or a field access */
12434   else if (TREE_CODE (lvalue) == COMPONENT_REF)
12435     lhs_type = TREE_TYPE (lvalue);
12436   /* Or a function return slot */
12437   else if (TREE_CODE (lvalue) == RESULT_DECL)
12438     lhs_type = TREE_TYPE (lvalue);
12439   /* Otherwise, we might want to try to write into an optimized static
12440      final, this is an of a different nature, reported further on. */
12441   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
12442            && resolve_expression_name (wfl_op1, &llvalue))
12443     {
12444       if (!error_found && check_final_assignment (llvalue, wfl_op1))
12445         {
12446           /* What we should do instead is resetting the all the flags
12447              previously set, exchange lvalue for llvalue and continue. */
12448           error_found = 1;
12449           return error_mark_node;
12450         }
12451       else 
12452         lhs_type = TREE_TYPE (lvalue);
12453     }
12454   else 
12455     {
12456       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
12457       error_found = 1;
12458     }
12459
12460   rhs_type = TREE_TYPE (rhs);
12461   /* 5.1 Try the assignment conversion for builtin type. */
12462   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
12463
12464   /* 5.2 If it failed, try a reference conversion */
12465   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
12466     lhs_type = promote_type (rhs_type);
12467
12468   /* 15.25.2 If we have a compound assignment, convert RHS into the
12469      type of the LHS */
12470   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12471     new_rhs = convert (lhs_type, rhs);
12472
12473   /* Explicit cast required. This is an error */
12474   if (!new_rhs)
12475     {
12476       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
12477       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
12478       tree wfl;
12479       char operation [32];      /* Max size known */
12480
12481       /* If the assignment is part of a declaration, we use the WFL of
12482          the declared variable to point out the error and call it a
12483          declaration problem. If the assignment is a genuine =
12484          operator, we call is a operator `=' problem, otherwise we
12485          call it an assignment problem. In both of these last cases,
12486          we use the WFL of the operator to indicate the error. */
12487
12488       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
12489         {
12490           wfl = wfl_op1;
12491           strcpy (operation, "declaration");
12492         }
12493       else
12494         {
12495           wfl = wfl_operator;
12496           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
12497             strcpy (operation, "assignment");
12498           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
12499             strcpy (operation, "`return'");
12500           else
12501             strcpy (operation, "`='");
12502         }
12503
12504       if (!valid_cast_to_p (rhs_type, lhs_type))
12505         parse_error_context
12506           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
12507            operation, t1, t2);
12508       else
12509         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
12510                              operation, t1, t2);
12511       free (t1); free (t2);
12512       error_found = 1;
12513     }
12514
12515   /* Inline read access to java.lang.PRIMTYPE.TYPE */
12516   if (new_rhs)
12517     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
12518
12519   if (error_found)
12520     return error_mark_node;
12521
12522   /* 10.10: Array Store Exception runtime check */
12523   if (!flag_emit_class_files
12524       && !flag_emit_xref
12525       && lvalue_from_array 
12526       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
12527     {
12528       tree check;
12529       tree base = lvalue;
12530
12531       /* We need to retrieve the right argument for
12532          _Jv_CheckArrayStore.  This is somewhat complicated by bounds
12533          and null pointer checks, both of which wrap the operand in
12534          one layer of COMPOUND_EXPR.  */
12535       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
12536         base = TREE_OPERAND (lvalue, 0);
12537       else
12538         {
12539           base = TREE_OPERAND (base, 0);
12540           if (flag_bounds_check)
12541             base = TREE_OPERAND (base, 1);
12542           if (flag_check_references)
12543             base = TREE_OPERAND (base, 1);
12544           base = TREE_OPERAND (base, 0);        
12545         }
12546
12547       /* Build the invocation of _Jv_CheckArrayStore */
12548       new_rhs = save_expr (new_rhs);
12549       check = build (CALL_EXPR, void_type_node,
12550                      build_address_of (soft_checkarraystore_node),
12551                      tree_cons (NULL_TREE, base,
12552                                 build_tree_list (NULL_TREE, new_rhs)),
12553                      NULL_TREE);
12554       TREE_SIDE_EFFECTS (check) = 1;
12555
12556       /* We have to decide on an insertion point */
12557       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
12558         {
12559           tree t;
12560           if (flag_bounds_check)
12561             {
12562               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
12563               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
12564                 build (COMPOUND_EXPR, void_type_node, t, check);
12565             }
12566           else
12567             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
12568                                               check, TREE_OPERAND (lvalue, 1));
12569         }
12570       else 
12571         {
12572           /* Make sure the bound check will happen before the store check */
12573           if (flag_bounds_check)
12574             TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
12575               build (COMPOUND_EXPR, void_type_node,
12576                      TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
12577           else
12578             lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
12579         }
12580     }
12581
12582   /* Final locals can be used as case values in switch
12583      statement. Prepare them for this eventuality. */
12584   if (TREE_CODE (lvalue) == VAR_DECL 
12585       && LOCAL_FINAL_P (lvalue)
12586       && TREE_CONSTANT (new_rhs)
12587       && IDENTIFIER_LOCAL_VALUE (DECL_NAME (lvalue))
12588       && JINTEGRAL_TYPE_P (TREE_TYPE (lvalue))
12589       )
12590     {
12591       TREE_CONSTANT (lvalue) = 1;
12592       DECL_INITIAL (lvalue) = new_rhs;
12593     }
12594
12595   TREE_OPERAND (node, 0) = lvalue;
12596   TREE_OPERAND (node, 1) = new_rhs;
12597   TREE_TYPE (node) = lhs_type;
12598   return node;
12599 }
12600
12601 /* Check that type SOURCE can be cast into type DEST. If the cast
12602    can't occur at all, return 0 otherwise 1. This function is used to
12603    produce accurate error messages on the reasons why an assignment
12604    failed. */
12605
12606 static tree
12607 try_reference_assignconv (lhs_type, rhs)
12608      tree lhs_type, rhs;
12609 {
12610   tree new_rhs = NULL_TREE;
12611   tree rhs_type = TREE_TYPE (rhs);
12612
12613   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
12614     {
12615       /* `null' may be assigned to any reference type */
12616       if (rhs == null_pointer_node)
12617         new_rhs = null_pointer_node;
12618       /* Try the reference assignment conversion */
12619       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
12620         new_rhs = rhs;
12621       /* This is a magic assignment that we process differently */
12622       else if (TREE_CODE (rhs) == EXC_PTR_EXPR)
12623         new_rhs = rhs;
12624     }
12625   return new_rhs;
12626 }
12627
12628 /* Check that RHS can be converted into LHS_TYPE by the assignment
12629    conversion (5.2), for the cases of RHS being a builtin type. Return
12630    NULL_TREE if the conversion fails or if because RHS isn't of a
12631    builtin type. Return a converted RHS if the conversion is possible.  */
12632
12633 static tree
12634 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
12635      tree wfl_op1, lhs_type, rhs;
12636 {
12637   tree new_rhs = NULL_TREE;
12638   tree rhs_type = TREE_TYPE (rhs);
12639
12640   /* Handle boolean specially.  */
12641   if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
12642       || TREE_CODE (lhs_type) == BOOLEAN_TYPE)
12643     {
12644       if (TREE_CODE (rhs_type) == BOOLEAN_TYPE
12645           && TREE_CODE (lhs_type) == BOOLEAN_TYPE)
12646         new_rhs = rhs;
12647     }
12648
12649   /* Zero accepted everywhere */
12650   else if (TREE_CODE (rhs) == INTEGER_CST 
12651       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
12652       && JPRIMITIVE_TYPE_P (rhs_type))
12653     new_rhs = convert (lhs_type, rhs);
12654
12655   /* 5.1.1 Try Identity Conversion,
12656      5.1.2 Try Widening Primitive Conversion */
12657   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
12658     new_rhs = convert (lhs_type, rhs);
12659
12660   /* Try a narrowing primitive conversion (5.1.3): 
12661        - expression is a constant expression of type int AND
12662        - variable is byte, short or char AND
12663        - The value of the expression is representable in the type of the 
12664          variable */
12665   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
12666            && (lhs_type == byte_type_node || lhs_type == char_type_node
12667                || lhs_type == short_type_node))
12668     {
12669       if (int_fits_type_p (rhs, lhs_type))
12670         new_rhs = convert (lhs_type, rhs);
12671       else if (wfl_op1)         /* Might be called with a NULL */
12672         parse_warning_context 
12673           (wfl_op1, "Constant expression `%s' too wide for narrowing primitive conversion to `%s'", 
12674            print_int_node (rhs), lang_printable_name (lhs_type, 0));
12675       /* Reported a warning that will turn into an error further
12676          down, so we don't return */
12677     }
12678
12679   return new_rhs;
12680 }
12681
12682 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
12683    conversion (5.1.1) or widening primitive conversion (5.1.2).  Return
12684    0 is the conversion test fails.  This implements parts the method
12685    invocation convertion (5.3).  */
12686
12687 static int
12688 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
12689      tree lhs_type, rhs_type;
12690 {
12691   /* 5.1.1: This is the identity conversion part. */
12692   if (lhs_type == rhs_type)
12693     return 1;
12694
12695   /* Reject non primitive types and boolean conversions.  */
12696   if (!JNUMERIC_TYPE_P (lhs_type) || !JNUMERIC_TYPE_P (rhs_type))
12697     return 0;
12698
12699   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
12700      than a char can't be converted into a char. Short can't too, but
12701      the < test below takes care of that */
12702   if (lhs_type == char_type_node && rhs_type == byte_type_node)
12703     return 0;
12704
12705   /* Accept all promoted type here. Note, we can't use <= in the test
12706      below, because we still need to bounce out assignments of short
12707      to char and the likes */
12708   if (lhs_type == int_type_node
12709       && (rhs_type == promoted_byte_type_node
12710           || rhs_type == promoted_short_type_node
12711           || rhs_type == promoted_char_type_node
12712           || rhs_type == promoted_boolean_type_node))
12713     return 1;
12714
12715   /* From here, an integral is widened if its precision is smaller
12716      than the precision of the LHS or if the LHS is a floating point
12717      type, or the RHS is a float and the RHS a double. */
12718   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
12719        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
12720       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
12721       || (rhs_type == float_type_node && lhs_type == double_type_node))
12722     return 1;
12723
12724   return 0;
12725 }
12726
12727 /* Check that something of SOURCE type can be assigned or cast to
12728    something of DEST type at runtime. Return 1 if the operation is
12729    valid, 0 otherwise. If CAST is set to 1, we're treating the case
12730    were SOURCE is cast into DEST, which borrows a lot of the
12731    assignment check. */
12732
12733 static int
12734 valid_ref_assignconv_cast_p (source, dest, cast)
12735      tree source;
12736      tree dest;
12737      int cast;
12738 {
12739   /* SOURCE or DEST might be null if not from a declared entity. */
12740   if (!source || !dest)
12741     return 0;
12742   if (JNULLP_TYPE_P (source))
12743     return 1;
12744   if (TREE_CODE (source) == POINTER_TYPE)
12745     source = TREE_TYPE (source);
12746   if (TREE_CODE (dest) == POINTER_TYPE)
12747     dest = TREE_TYPE (dest);
12748
12749   /* If source and dest are being compiled from bytecode, they may need to
12750      be loaded. */
12751   if (CLASS_P (source) && !CLASS_LOADED_P (source))
12752     {
12753       load_class (source, 1);
12754       safe_layout_class (source);
12755     }
12756   if (CLASS_P (dest) && !CLASS_LOADED_P (dest))
12757     {
12758       load_class (dest, 1);
12759       safe_layout_class (dest);
12760     }
12761
12762   /* Case where SOURCE is a class type */
12763   if (TYPE_CLASS_P (source))
12764     {
12765       if (TYPE_CLASS_P (dest))
12766         return  (source == dest 
12767                  || inherits_from_p (source, dest)
12768                  || (cast && inherits_from_p (dest, source)));
12769       if (TYPE_INTERFACE_P (dest))
12770         {
12771           /* If doing a cast and SOURCE is final, the operation is
12772              always correct a compile time (because even if SOURCE
12773              does not implement DEST, a subclass of SOURCE might). */
12774           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
12775             return 1;
12776           /* Otherwise, SOURCE must implement DEST */
12777           return interface_of_p (dest, source);
12778         }
12779       /* DEST is an array, cast permited if SOURCE is of Object type */
12780       return (cast && source == object_type_node ? 1 : 0);
12781     }
12782   if (TYPE_INTERFACE_P (source))
12783     {
12784       if (TYPE_CLASS_P (dest))
12785         {
12786           /* If not casting, DEST must be the Object type */
12787           if (!cast)
12788             return dest == object_type_node;
12789           /* We're doing a cast. The cast is always valid is class
12790              DEST is not final, otherwise, DEST must implement SOURCE */
12791           else if (!CLASS_FINAL (TYPE_NAME (dest)))
12792             return 1;
12793           else
12794             return interface_of_p (source, dest);
12795         }
12796       if (TYPE_INTERFACE_P (dest))
12797         {
12798           /* If doing a cast, then if SOURCE and DEST contain method
12799              with the same signature but different return type, then
12800              this is a (compile time) error */
12801           if (cast)
12802             {
12803               tree method_source, method_dest;
12804               tree source_type;
12805               tree source_sig;
12806               tree source_name;
12807               for (method_source = TYPE_METHODS (source); method_source; 
12808                    method_source = TREE_CHAIN (method_source))
12809                 {
12810                   source_sig = 
12811                     build_java_argument_signature (TREE_TYPE (method_source));
12812                   source_type = TREE_TYPE (TREE_TYPE (method_source));
12813                   source_name = DECL_NAME (method_source);
12814                   for (method_dest = TYPE_METHODS (dest);
12815                        method_dest; method_dest = TREE_CHAIN (method_dest))
12816                     if (source_sig == 
12817                         build_java_argument_signature (TREE_TYPE (method_dest))
12818                         && source_name == DECL_NAME (method_dest)
12819                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
12820                       return 0;
12821                 }
12822               return 1;
12823             }
12824           else
12825             return source == dest || interface_of_p (dest, source);
12826         }
12827       else
12828         {
12829           /* Array */
12830           return (cast
12831                   && (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable
12832                       || (DECL_NAME (TYPE_NAME (source))
12833                           == java_io_serializable)));
12834         }
12835     }
12836   if (TYPE_ARRAY_P (source))
12837     {
12838       if (TYPE_CLASS_P (dest))
12839         return dest == object_type_node;
12840       /* Can't cast an array to an interface unless the interface is
12841          java.lang.Cloneable or java.io.Serializable.  */
12842       if (TYPE_INTERFACE_P (dest))
12843         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable
12844                 || DECL_NAME (TYPE_NAME (dest)) == java_io_serializable);
12845       else                      /* Arrays */
12846         {
12847           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
12848           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
12849           
12850           /* In case of severe errors, they turn out null */
12851           if (!dest_element_type || !source_element_type)
12852             return 0;
12853           if (source_element_type == dest_element_type)
12854             return 1;
12855           return valid_ref_assignconv_cast_p (source_element_type,
12856                                               dest_element_type, cast);
12857         }
12858       return 0;
12859     }
12860   return 0;
12861 }
12862
12863 static int
12864 valid_cast_to_p (source, dest)
12865      tree source;
12866      tree dest;
12867 {
12868   if (TREE_CODE (source) == POINTER_TYPE)
12869     source = TREE_TYPE (source);
12870   if (TREE_CODE (dest) == POINTER_TYPE)
12871     dest = TREE_TYPE (dest);
12872
12873   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
12874     return valid_ref_assignconv_cast_p (source, dest, 1);
12875
12876   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
12877     return 1;
12878
12879   else if (TREE_CODE (source) == BOOLEAN_TYPE
12880            && TREE_CODE (dest) == BOOLEAN_TYPE)
12881     return 1;
12882
12883   return 0;
12884 }
12885
12886 static tree
12887 do_unary_numeric_promotion (arg)
12888      tree arg;
12889 {
12890   tree type = TREE_TYPE (arg);
12891   if ((TREE_CODE (type) == INTEGER_TYPE && TYPE_PRECISION (type) < 32)
12892       || TREE_CODE (type) == CHAR_TYPE)
12893     arg = convert (int_type_node, arg);
12894   return arg;
12895 }
12896
12897 /* Return a non zero value if SOURCE can be converted into DEST using
12898    the method invocation conversion rule (5.3).  */
12899 static int
12900 valid_method_invocation_conversion_p (dest, source)
12901      tree dest, source;
12902 {
12903   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
12904            && valid_builtin_assignconv_identity_widening_p (dest, source))
12905           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
12906               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
12907               && valid_ref_assignconv_cast_p (source, dest, 0)));
12908 }
12909
12910 /* Build an incomplete binop expression. */
12911
12912 static tree
12913 build_binop (op, op_location, op1, op2)
12914      enum tree_code op;
12915      int op_location;
12916      tree op1, op2;
12917 {
12918   tree binop = build (op, NULL_TREE, op1, op2);
12919   TREE_SIDE_EFFECTS (binop) = 1;
12920   /* Store the location of the operator, for better error report. The
12921      string of the operator will be rebuild based on the OP value. */
12922   EXPR_WFL_LINECOL (binop) = op_location;
12923   return binop;
12924 }
12925
12926 /* Build the string of the operator retained by NODE. If NODE is part
12927    of a compound expression, add an '=' at the end of the string. This
12928    function is called when an error needs to be reported on an
12929    operator. The string is returned as a pointer to a static character
12930    buffer. */
12931
12932 static char *
12933 operator_string (node)
12934      tree node;
12935 {
12936 #define BUILD_OPERATOR_STRING(S)                                        \
12937   {                                                                     \
12938     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
12939     return buffer;                                                      \
12940   }
12941   
12942   static char buffer [10];
12943   switch (TREE_CODE (node))
12944     {
12945     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
12946     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
12947     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
12948     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12949     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
12950     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
12951     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
12952     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
12953     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
12954     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
12955     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
12956     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
12957     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
12958     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
12959     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
12960     case GT_EXPR: BUILD_OPERATOR_STRING (">");
12961     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
12962     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
12963     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
12964     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12965     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
12966     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
12967     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
12968     case PREINCREMENT_EXPR:     /* Fall through */
12969     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
12970     case PREDECREMENT_EXPR:     /* Fall through */
12971     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
12972     default:
12973       internal_error ("unregistered operator %s",
12974                       tree_code_name [TREE_CODE (node)]);
12975     }
12976   return NULL;
12977 #undef BUILD_OPERATOR_STRING
12978 }
12979
12980 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
12981
12982 static int
12983 java_decl_equiv (var_acc1, var_acc2)
12984      tree var_acc1, var_acc2;
12985 {
12986   if (JDECL_P (var_acc1))
12987     return (var_acc1 == var_acc2);
12988   
12989   return (TREE_CODE (var_acc1) == COMPONENT_REF
12990           && TREE_CODE (var_acc2) == COMPONENT_REF
12991           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
12992              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
12993           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
12994 }
12995
12996 /* Return a non zero value if CODE is one of the operators that can be
12997    used in conjunction with the `=' operator in a compound assignment.  */
12998
12999 static int
13000 binop_compound_p (code)
13001     enum tree_code code;
13002 {
13003   int i;
13004   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
13005     if (binop_lookup [i] == code)
13006       break;
13007
13008   return i < BINOP_COMPOUND_CANDIDATES;
13009 }
13010
13011 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
13012
13013 static tree
13014 java_refold (t)
13015      tree t;
13016 {
13017   tree c, b, ns, decl;
13018
13019   if (TREE_CODE (t) != MODIFY_EXPR)
13020     return t;
13021
13022   c = TREE_OPERAND (t, 1);
13023   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
13024          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
13025          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
13026     return t;
13027
13028   /* Now the left branch of the binary operator. */
13029   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
13030   if (! (b && TREE_CODE (b) == NOP_EXPR 
13031          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
13032     return t;
13033
13034   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
13035   if (! (ns && TREE_CODE (ns) == NOP_EXPR
13036          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
13037     return t;
13038
13039   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
13040   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
13041       /* It's got to be the an equivalent decl */
13042       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
13043     {
13044       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
13045       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
13046       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
13047       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
13048       /* Change the right part of the BINOP_EXPR */
13049       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
13050     }
13051
13052   return t;
13053 }
13054
13055 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
13056    errors but we modify NODE so that it contains the type computed
13057    according to the expression, when it's fixed. Otherwise, we write
13058    error_mark_node as the type. It allows us to further the analysis
13059    of remaining nodes and detects more errors in certain cases.  */
13060
13061 static tree
13062 patch_binop (node, wfl_op1, wfl_op2)
13063      tree node;
13064      tree wfl_op1;
13065      tree wfl_op2;
13066 {
13067   tree op1 = TREE_OPERAND (node, 0);
13068   tree op2 = TREE_OPERAND (node, 1);
13069   tree op1_type = TREE_TYPE (op1);
13070   tree op2_type = TREE_TYPE (op2);
13071   tree prom_type = NULL_TREE, cn;
13072   int code = TREE_CODE (node);
13073
13074   /* If 1, tell the routine that we have to return error_mark_node
13075      after checking for the initialization of the RHS */
13076   int error_found = 0;
13077
13078   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13079
13080   /* If either op<n>_type are NULL, this might be early signs of an
13081      error situation, unless it's too early to tell (in case we're
13082      handling a `+', `==', `!=' or `instanceof'.) We want to set op<n>_type
13083      correctly so the error can be later on reported accurately. */
13084   if (! (code == PLUS_EXPR || code == NE_EXPR 
13085          || code == EQ_EXPR || code == INSTANCEOF_EXPR))
13086     {
13087       tree n;
13088       if (! op1_type)
13089         {
13090           n = java_complete_tree (op1);
13091           op1_type = TREE_TYPE (n);
13092         }
13093       if (! op2_type)
13094         {
13095           n = java_complete_tree (op2);
13096           op2_type = TREE_TYPE (n);
13097         }
13098     }
13099
13100   switch (code)
13101     {
13102     /* 15.16 Multiplicative operators */
13103     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
13104     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
13105     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
13106     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
13107       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13108         {
13109           if (!JNUMERIC_TYPE_P (op1_type))
13110             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13111           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13112             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13113           TREE_TYPE (node) = error_mark_node;
13114           error_found = 1;
13115           break;
13116         }
13117       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13118       /* Change the division operator if necessary */
13119       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
13120         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
13121
13122       if (TREE_CODE (prom_type) == INTEGER_TYPE
13123           && flag_use_divide_subroutine
13124           && ! flag_emit_class_files
13125           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
13126         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
13127  
13128       /* This one is more complicated. FLOATs are processed by a
13129          function call to soft_fmod. Duplicate the value of the
13130          COMPOUND_ASSIGN_P flag. */
13131       if (code == TRUNC_MOD_EXPR)
13132         {
13133           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
13134           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
13135           TREE_SIDE_EFFECTS (mod)
13136             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13137           return mod;
13138         }
13139       break;
13140
13141     /* 15.17 Additive Operators */
13142     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
13143
13144       /* Operation is valid if either one argument is a string
13145          constant, a String object or a StringBuffer crafted for the
13146          purpose of the a previous usage of the String concatenation
13147          operator */
13148
13149       if (TREE_CODE (op1) == STRING_CST 
13150           || TREE_CODE (op2) == STRING_CST
13151           || JSTRING_TYPE_P (op1_type)
13152           || JSTRING_TYPE_P (op2_type)
13153           || IS_CRAFTED_STRING_BUFFER_P (op1)
13154           || IS_CRAFTED_STRING_BUFFER_P (op2))
13155         return build_string_concatenation (op1, op2);
13156
13157     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
13158                                    Numeric Types */
13159       if (!JNUMERIC_TYPE_P (op1_type) || !JNUMERIC_TYPE_P (op2_type))
13160         {
13161           if (!JNUMERIC_TYPE_P (op1_type))
13162             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13163           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13164             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13165           TREE_TYPE (node) = error_mark_node;
13166           error_found = 1;
13167           break;
13168         }
13169       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13170       break;
13171
13172     /* 15.18 Shift Operators */
13173     case LSHIFT_EXPR:
13174     case RSHIFT_EXPR:
13175     case URSHIFT_EXPR:
13176       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
13177         {
13178           if (!JINTEGRAL_TYPE_P (op1_type))
13179             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13180           else
13181             {
13182               if (JNUMERIC_TYPE_P (op2_type))
13183                 parse_error_context (wfl_operator,
13184                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
13185                                      operator_string (node),
13186                                      lang_printable_name (op2_type, 0));
13187               else
13188                 parse_error_context (wfl_operator,
13189                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
13190                                      operator_string (node),
13191                                      lang_printable_name (op2_type, 0));
13192             }
13193           TREE_TYPE (node) = error_mark_node;
13194           error_found = 1;
13195           break;
13196         }
13197
13198       /* Unary numeric promotion (5.6.1) is performed on each operand
13199          separatly */
13200       op1 = do_unary_numeric_promotion (op1);
13201       op2 = do_unary_numeric_promotion (op2);
13202
13203       /* The type of the shift expression is the type of the promoted
13204          type of the left-hand operand */
13205       prom_type = TREE_TYPE (op1);
13206
13207       /* Shift int only up to 0x1f and long up to 0x3f */
13208       if (prom_type == int_type_node)
13209         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13210                            build_int_2 (0x1f, 0)));
13211       else
13212         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
13213                            build_int_2 (0x3f, 0)));
13214
13215       /* The >>> operator is a >> operating on unsigned quantities */
13216       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
13217         {
13218           tree to_return;
13219           tree utype = unsigned_type (prom_type);
13220           op1 = convert (utype, op1);
13221           TREE_SET_CODE (node, RSHIFT_EXPR);
13222           TREE_OPERAND (node, 0) = op1;
13223           TREE_OPERAND (node, 1) = op2;
13224           TREE_TYPE (node) = utype;
13225           to_return = convert (prom_type, node);
13226           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
13227           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
13228           TREE_SIDE_EFFECTS (to_return)
13229             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13230           return to_return;
13231         }
13232       break;
13233
13234       /* 15.19.1 Type Comparison Operator instaceof */
13235     case INSTANCEOF_EXPR:
13236
13237       TREE_TYPE (node) = boolean_type_node;
13238
13239       if (!(op2_type = resolve_type_during_patch (op2)))
13240         return error_mark_node;
13241
13242       /* The first operand must be a reference type or the null type */
13243       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
13244         error_found = 1;        /* Error reported further below */
13245
13246       /* The second operand must be a reference type */
13247       if (!JREFERENCE_TYPE_P (op2_type))
13248         {
13249           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
13250           parse_error_context
13251             (wfl_operator, "Invalid argument `%s' for `instanceof'",
13252              lang_printable_name (op2_type, 0));
13253           error_found = 1;
13254         }
13255
13256       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
13257         {
13258           /* If the first operand is null, the result is always false */
13259           if (op1 == null_pointer_node)
13260             return boolean_false_node;
13261           else if (flag_emit_class_files)
13262             {
13263               TREE_OPERAND (node, 1) = op2_type;
13264               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
13265               return node;
13266             }
13267           /* Otherwise we have to invoke instance of to figure it out */
13268           else
13269             return build_instanceof (op1, op2_type);
13270         }
13271       /* There is no way the expression operand can be an instance of
13272          the type operand. This is a compile time error. */
13273       else
13274         {
13275           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
13276           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
13277           parse_error_context 
13278             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
13279              t1, lang_printable_name (op2_type, 0));
13280           free (t1);
13281           error_found = 1;
13282         }
13283       
13284       break;
13285
13286       /* 15.21 Bitwise and Logical Operators */
13287     case BIT_AND_EXPR:
13288     case BIT_XOR_EXPR:
13289     case BIT_IOR_EXPR:
13290       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
13291         /* Binary numeric promotion is performed on both operand and the
13292            expression retain that type */
13293         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13294
13295       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
13296                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
13297         /* The type of the bitwise operator expression is BOOLEAN */
13298         prom_type = boolean_type_node;
13299       else
13300         {
13301           if (!JINTEGRAL_TYPE_P (op1_type))
13302             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
13303           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
13304             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
13305           TREE_TYPE (node) = error_mark_node;
13306           error_found = 1;
13307           /* Insert a break here if adding thing before the switch's
13308              break for this case */
13309         }
13310       break;
13311
13312       /* 15.22 Conditional-And Operator */
13313     case TRUTH_ANDIF_EXPR:
13314       /* 15.23 Conditional-Or Operator */
13315     case TRUTH_ORIF_EXPR:
13316       /* Operands must be of BOOLEAN type */
13317       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
13318           TREE_CODE (op2_type) != BOOLEAN_TYPE)
13319         {
13320           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
13321             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
13322           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
13323             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
13324           TREE_TYPE (node) = boolean_type_node;
13325           error_found = 1;
13326           break;
13327         }
13328       /* The type of the conditional operators is BOOLEAN */
13329       prom_type = boolean_type_node;
13330       break;
13331
13332       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
13333     case LT_EXPR:
13334     case GT_EXPR:
13335     case LE_EXPR:
13336     case GE_EXPR:
13337       /* The type of each of the operands must be a primitive numeric
13338          type */
13339       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
13340         {
13341           if (!JNUMERIC_TYPE_P (op1_type))
13342             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
13343           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
13344             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
13345           TREE_TYPE (node) = boolean_type_node;
13346           error_found = 1;
13347           break;
13348         }
13349       /* Binary numeric promotion is performed on the operands */
13350       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13351       /* The type of the relation expression is always BOOLEAN */
13352       prom_type = boolean_type_node;
13353       break;
13354
13355       /* 15.20 Equality Operator */
13356     case EQ_EXPR:
13357     case NE_EXPR:
13358       /* It's time for us to patch the strings. */
13359       if ((cn = patch_string (op1))) 
13360        {
13361          op1 = cn;
13362          op1_type = TREE_TYPE (op1);
13363        }
13364       if ((cn = patch_string (op2))) 
13365        {
13366          op2 = cn;
13367          op2_type = TREE_TYPE (op2);
13368        }
13369       
13370       /* 15.20.1 Numerical Equality Operators == and != */
13371       /* Binary numeric promotion is performed on the operands */
13372       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
13373         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
13374       
13375       /* 15.20.2 Boolean Equality Operators == and != */
13376       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
13377           TREE_CODE (op2_type) == BOOLEAN_TYPE)
13378         ;                       /* Nothing to do here */
13379       
13380       /* 15.20.3 Reference Equality Operators == and != */
13381       /* Types have to be either references or the null type. If
13382          they're references, it must be possible to convert either
13383          type to the other by casting conversion. */
13384       else if (op1 == null_pointer_node || op2 == null_pointer_node 
13385                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
13386                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
13387                        || valid_ref_assignconv_cast_p (op2_type, 
13388                                                        op1_type, 1))))
13389         ;                       /* Nothing to do here */
13390           
13391       /* Else we have an error figure what can't be converted into
13392          what and report the error */
13393       else
13394         {
13395           char *t1;
13396           t1 = xstrdup (lang_printable_name (op1_type, 0));
13397           parse_error_context 
13398             (wfl_operator,
13399              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
13400              operator_string (node), t1, 
13401              lang_printable_name (op2_type, 0));
13402           free (t1);
13403           TREE_TYPE (node) = boolean_type_node;
13404           error_found = 1;
13405           break;
13406         }
13407       prom_type = boolean_type_node;
13408       break;
13409     }
13410
13411   if (error_found)
13412     return error_mark_node;
13413
13414   TREE_OPERAND (node, 0) = op1;
13415   TREE_OPERAND (node, 1) = op2;
13416   TREE_TYPE (node) = prom_type;
13417   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13418   
13419   if (flag_emit_xref)
13420     return node;
13421
13422   /* fold does not respect side-effect order as required for Java but not C.
13423    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
13424    * bytecode.
13425    */
13426   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
13427       : ! TREE_SIDE_EFFECTS (node))
13428     node = fold (node);
13429   return node;
13430 }
13431
13432 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
13433    zero value, the value of CSTE comes after the valude of STRING */
13434
13435 static tree
13436 do_merge_string_cste (cste, string, string_len, after)
13437      tree cste;
13438      const char *string;
13439      int string_len, after;
13440 {
13441   const char *old = TREE_STRING_POINTER (cste);
13442   int old_len = TREE_STRING_LENGTH (cste);
13443   int len = old_len + string_len;
13444   char *new = alloca (len+1);
13445
13446   if (after)
13447     {
13448       memcpy (new, string, string_len);
13449       memcpy (&new [string_len], old, old_len);
13450     }
13451   else
13452     {
13453       memcpy (new, old, old_len);
13454       memcpy (&new [old_len], string, string_len);
13455     }
13456   new [len] = '\0';
13457   return build_string (len, new);
13458 }
13459
13460 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
13461    new STRING_CST on success, NULL_TREE on failure */
13462
13463 static tree
13464 merge_string_cste (op1, op2, after)
13465      tree op1, op2;
13466      int after;
13467 {
13468   /* Handle two string constants right away */
13469   if (TREE_CODE (op2) == STRING_CST)
13470     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
13471                                  TREE_STRING_LENGTH (op2), after);
13472   
13473   /* Reasonable integer constant can be treated right away */
13474   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
13475     {
13476       static const char *boolean_true = "true";
13477       static const char *boolean_false = "false";
13478       static const char *null_pointer = "null";
13479       char ch[3];
13480       const char *string;
13481       
13482       if (op2 == boolean_true_node)
13483         string = boolean_true;
13484       else if (op2 == boolean_false_node)
13485         string = boolean_false;
13486       else if (op2 == null_pointer_node)
13487         string = null_pointer;
13488       else if (TREE_TYPE (op2) == char_type_node)
13489         {
13490           ch[0] = (char )TREE_INT_CST_LOW (op2);
13491           ch[1] = '\0';
13492           string = ch;
13493         }
13494       else
13495           string = print_int_node (op2);
13496       
13497       return do_merge_string_cste (op1, string, strlen (string), after);
13498     }
13499   return NULL_TREE;
13500 }
13501
13502 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
13503    has to be a STRING_CST and the other part must be a STRING_CST or a
13504    INTEGRAL constant. Return a new STRING_CST if the operation
13505    succeed, NULL_TREE otherwise.
13506
13507    If the case we want to optimize for space, we might want to return
13508    NULL_TREE for each invocation of this routine. FIXME */
13509
13510 static tree
13511 string_constant_concatenation (op1, op2)
13512      tree op1, op2;
13513 {
13514   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
13515     {
13516       tree string, rest;
13517       int invert;
13518       
13519       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
13520       rest   = (string == op1 ? op2 : op1);
13521       invert = (string == op1 ? 0 : 1 );
13522       
13523       /* Walk REST, only if it looks reasonable */
13524       if (TREE_CODE (rest) != STRING_CST
13525           && !IS_CRAFTED_STRING_BUFFER_P (rest)
13526           && !JSTRING_TYPE_P (TREE_TYPE (rest))
13527           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
13528         {
13529           rest = java_complete_tree (rest);
13530           if (rest == error_mark_node)
13531             return error_mark_node;
13532           rest = fold (rest);
13533         }
13534       return merge_string_cste (string, rest, invert);
13535     }
13536   return NULL_TREE;
13537 }
13538
13539 /* Implement the `+' operator. Does static optimization if possible,
13540    otherwise create (if necessary) and append elements to a
13541    StringBuffer. The StringBuffer will be carried around until it is
13542    used for a function call or an assignment. Then toString() will be
13543    called on it to turn it into a String object. */
13544
13545 static tree
13546 build_string_concatenation (op1, op2)
13547      tree op1, op2;
13548 {
13549   tree result;
13550   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
13551
13552   if (flag_emit_xref)
13553     return build (PLUS_EXPR, string_type_node, op1, op2);
13554   
13555   /* Try to do some static optimization */
13556   if ((result = string_constant_concatenation (op1, op2)))
13557     return result;
13558
13559   /* Discard empty strings on either side of the expression */
13560   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
13561     {
13562       op1 = op2;
13563       op2 = NULL_TREE;
13564     }
13565   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
13566     op2 = NULL_TREE;
13567
13568   /* If operands are string constant, turn then into object references */
13569   if (TREE_CODE (op1) == STRING_CST)
13570     op1 = patch_string_cst (op1);
13571   if (op2 && TREE_CODE (op2) == STRING_CST)
13572     op2 = patch_string_cst (op2);
13573
13574   /* If either one of the constant is null and the other non null
13575      operand is a String object, return it. */
13576   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
13577     return op1;
13578
13579   /* If OP1 isn't already a StringBuffer, create and
13580      initialize a new one */
13581   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
13582     {
13583       /* Two solutions here: 
13584          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
13585          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
13586       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
13587         op1 = BUILD_STRING_BUFFER (op1);
13588       else
13589         {
13590           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
13591           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
13592         }
13593     }
13594
13595   if (op2)
13596     {
13597       /* OP1 is no longer the last node holding a crafted StringBuffer */
13598       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
13599       /* Create a node for `{new...,xxx}.append (op2)' */
13600       if (op2)
13601         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
13602     }
13603
13604   /* Mark the last node holding a crafted StringBuffer */
13605   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
13606
13607   TREE_SIDE_EFFECTS (op1) = side_effects;
13608   return op1;
13609 }
13610
13611 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
13612    StringBuffer. If no string were found to be patched, return
13613    NULL. */
13614
13615 static tree
13616 patch_string (node)
13617     tree node;
13618 {
13619   if (node == error_mark_node)
13620     return error_mark_node;
13621   if (TREE_CODE (node) == STRING_CST)
13622     return patch_string_cst (node);
13623   else if (IS_CRAFTED_STRING_BUFFER_P (node))
13624     {
13625       int saved = ctxp->explicit_constructor_p;
13626       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
13627       tree ret;
13628       /* Temporary disable forbid the use of `this'. */
13629       ctxp->explicit_constructor_p = 0;
13630       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
13631       /* String concatenation arguments must be evaluated in order too. */
13632       ret = force_evaluation_order (ret);
13633       /* Restore it at its previous value */
13634       ctxp->explicit_constructor_p = saved;
13635       return ret;
13636     }
13637   return NULL_TREE;
13638 }
13639
13640 /* Build the internal representation of a string constant.  */
13641
13642 static tree
13643 patch_string_cst (node)
13644      tree node;
13645 {
13646   int location;
13647   if (! flag_emit_class_files)
13648     {
13649       node = get_identifier (TREE_STRING_POINTER (node));
13650       location = alloc_name_constant (CONSTANT_String, node);
13651       node = build_ref_from_constant_pool (location);
13652     }
13653   TREE_TYPE (node) = string_ptr_type_node;
13654   TREE_CONSTANT (node) = 1;
13655   return node;
13656 }
13657
13658 /* Build an incomplete unary operator expression. */
13659
13660 static tree
13661 build_unaryop (op_token, op_location, op1)
13662      int op_token, op_location;
13663      tree op1;
13664 {
13665   enum tree_code op;
13666   tree unaryop;
13667   switch (op_token)
13668     {
13669     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
13670     case MINUS_TK: op = NEGATE_EXPR; break;
13671     case NEG_TK: op = TRUTH_NOT_EXPR; break;
13672     case NOT_TK: op = BIT_NOT_EXPR; break;
13673     default: abort ();
13674     }
13675
13676   unaryop = build1 (op, NULL_TREE, op1);
13677   TREE_SIDE_EFFECTS (unaryop) = 1;
13678   /* Store the location of the operator, for better error report. The
13679      string of the operator will be rebuild based on the OP value. */
13680   EXPR_WFL_LINECOL (unaryop) = op_location;
13681   return unaryop;
13682 }
13683
13684 /* Special case for the ++/-- operators, since they require an extra
13685    argument to build, which is set to NULL and patched
13686    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
13687
13688 static tree
13689 build_incdec (op_token, op_location, op1, is_post_p)
13690      int op_token, op_location;
13691      tree op1;
13692      int is_post_p;
13693 {
13694   static enum tree_code lookup [2][2] = 
13695     {
13696       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
13697       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
13698     };
13699   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
13700                      NULL_TREE, op1, NULL_TREE);
13701   TREE_SIDE_EFFECTS (node) = 1;
13702   /* Store the location of the operator, for better error report. The
13703      string of the operator will be rebuild based on the OP value. */
13704   EXPR_WFL_LINECOL (node) = op_location;
13705   return node;
13706 }     
13707
13708 /* Build an incomplete cast operator, based on the use of the
13709    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
13710    set. java_complete_tree is trained to walk a CONVERT_EXPR even
13711    though its type is already set.  */
13712
13713 static tree
13714 build_cast (location, type, exp)
13715      int location;
13716      tree type, exp;
13717 {
13718   tree node = build1 (CONVERT_EXPR, type, exp);
13719   EXPR_WFL_LINECOL (node) = location;
13720   return node;
13721 }
13722
13723 /* Build an incomplete class reference operator.  */
13724 static tree
13725 build_incomplete_class_ref (location, class_name)
13726     int location;
13727     tree class_name;
13728 {
13729   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
13730   EXPR_WFL_LINECOL (node) = location;
13731   return node;
13732 }
13733
13734 /* Complete an incomplete class reference operator.  */
13735 static tree
13736 patch_incomplete_class_ref (node)
13737     tree node;
13738 {
13739   tree type = TREE_OPERAND (node, 0);
13740   tree ref_type;
13741
13742   if (!(ref_type = resolve_type_during_patch (type)))
13743     return error_mark_node;
13744
13745   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
13746     {
13747       /* A class referenced by `foo.class' is initialized.  */
13748       return build_class_init (ref_type, build_class_ref (ref_type));
13749     }
13750
13751   /* If we're emitting class files and we have to deal with non
13752      primitive types, we invoke (and consider generating) the
13753      synthetic static method `class$'. */
13754   if (!TYPE_DOT_CLASS (current_class))
13755       build_dot_class_method (current_class);
13756   ref_type = build_dot_class_method_invocation (ref_type);
13757   return java_complete_tree (ref_type);
13758 }
13759
13760 /* 15.14 Unary operators. We return error_mark_node in case of error,
13761    but preserve the type of NODE if the type is fixed.  */
13762
13763 static tree
13764 patch_unaryop (node, wfl_op)
13765      tree node;
13766      tree wfl_op;
13767 {
13768   tree op = TREE_OPERAND (node, 0);
13769   tree op_type = TREE_TYPE (op);
13770   tree prom_type = NULL_TREE, value, decl;
13771   int outer_field_flag = 0;
13772   int code = TREE_CODE (node);
13773   int error_found = 0;
13774
13775   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13776
13777   switch (code)
13778     {
13779       /* 15.13.2 Postfix Increment Operator ++ */
13780     case POSTINCREMENT_EXPR:
13781       /* 15.13.3 Postfix Increment Operator -- */
13782     case POSTDECREMENT_EXPR:
13783       /* 15.14.1 Prefix Increment Operator ++ */
13784     case PREINCREMENT_EXPR:
13785       /* 15.14.2 Prefix Decrement Operator -- */
13786     case PREDECREMENT_EXPR:
13787       op = decl = strip_out_static_field_access_decl (op);
13788       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
13789       /* We might be trying to change an outer field accessed using
13790          access method. */
13791       if (outer_field_flag)
13792         {
13793           /* Retrieve the decl of the field we're trying to access. We
13794              do that by first retrieving the function we would call to
13795              access the field. It has been already verified that this
13796              field isn't final */
13797           if (flag_emit_class_files)
13798             decl = TREE_OPERAND (op, 0);
13799           else
13800             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
13801           decl = DECL_FUNCTION_ACCESS_DECL (decl);
13802         }
13803       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
13804       else if (!JDECL_P (decl) 
13805           && TREE_CODE (decl) != COMPONENT_REF
13806           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
13807           && TREE_CODE (decl) != INDIRECT_REF
13808           && !(TREE_CODE (decl) == COMPOUND_EXPR
13809                && TREE_OPERAND (decl, 1)
13810                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
13811         {
13812           tree lvalue;
13813           /* Before screaming, check that we're not in fact trying to
13814              increment a optimized static final access, in which case
13815              we issue an different error message. */
13816           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
13817                 && resolve_expression_name (wfl_op, &lvalue)
13818                 && check_final_assignment (lvalue, wfl_op)))
13819             parse_error_context (wfl_operator, "Invalid argument to `%s'",
13820                                  operator_string (node));
13821           TREE_TYPE (node) = error_mark_node;
13822           error_found = 1;
13823         }
13824       
13825       if (check_final_assignment (op, wfl_op))
13826         error_found = 1;
13827
13828       /* From now on, we know that op if a variable and that it has a
13829          valid wfl. We use wfl_op to locate errors related to the
13830          ++/-- operand. */
13831       else if (!JNUMERIC_TYPE_P (op_type))
13832         {
13833           parse_error_context
13834             (wfl_op, "Invalid argument type `%s' to `%s'",
13835              lang_printable_name (op_type, 0), operator_string (node));
13836           TREE_TYPE (node) = error_mark_node;
13837           error_found = 1;
13838         }
13839       else
13840         {
13841           /* Before the addition, binary numeric promotion is performed on
13842              both operands, if really necessary */
13843           if (JINTEGRAL_TYPE_P (op_type))
13844             {
13845               value = build_int_2 (1, 0);
13846               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
13847             }
13848           else
13849             {
13850               value = build_int_2 (1, 0);
13851               TREE_TYPE (node) = 
13852                 binary_numeric_promotion (op_type, 
13853                                           TREE_TYPE (value), &op, &value);
13854             }
13855
13856           /* We remember we might be accessing an outer field */
13857           if (outer_field_flag)
13858             {
13859               /* We re-generate an access to the field */
13860               value = build (PLUS_EXPR, TREE_TYPE (op), 
13861                              build_outer_field_access (wfl_op, decl), value);
13862                                                     
13863               /* And we patch the original access$() into a write 
13864                  with plus_op as a rhs */
13865               return outer_field_access_fix (node, op, value);
13866             }
13867
13868           /* And write back into the node. */
13869           TREE_OPERAND (node, 0) = op;
13870           TREE_OPERAND (node, 1) = value;
13871           /* Convert the overall back into its original type, if
13872              necessary, and return */
13873           if (JINTEGRAL_TYPE_P (op_type))
13874             return fold (node);
13875           else
13876             return fold (convert (op_type, node));
13877         }
13878       break;
13879
13880       /* 15.14.3 Unary Plus Operator + */
13881     case UNARY_PLUS_EXPR:
13882       /* 15.14.4 Unary Minus Operator - */
13883     case NEGATE_EXPR:
13884       if (!JNUMERIC_TYPE_P (op_type))
13885         {
13886           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
13887           TREE_TYPE (node) = error_mark_node;
13888           error_found = 1;
13889         }
13890       /* Unary numeric promotion is performed on operand */
13891       else
13892         {
13893           op = do_unary_numeric_promotion (op);
13894           prom_type = TREE_TYPE (op);
13895           if (code == UNARY_PLUS_EXPR)
13896             return fold (op);
13897         }
13898       break;
13899
13900       /* 15.14.5 Bitwise Complement Operator ~ */
13901     case BIT_NOT_EXPR:
13902       if (!JINTEGRAL_TYPE_P (op_type))
13903         {
13904           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
13905           TREE_TYPE (node) = error_mark_node;
13906           error_found = 1;
13907         }
13908       else
13909         {
13910           op = do_unary_numeric_promotion (op);
13911           prom_type = TREE_TYPE (op);
13912         }
13913       break;
13914
13915       /* 15.14.6 Logical Complement Operator ! */
13916     case TRUTH_NOT_EXPR:
13917       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
13918         {
13919           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
13920           /* But the type is known. We will report an error if further
13921              attempt of a assignment is made with this rhs */
13922           TREE_TYPE (node) = boolean_type_node;
13923           error_found = 1;
13924         }
13925       else
13926         prom_type = boolean_type_node;
13927       break;
13928
13929       /* 15.15 Cast Expression */
13930     case CONVERT_EXPR:
13931       value = patch_cast (node, wfl_operator);
13932       if (value == error_mark_node)
13933         {
13934           /* If this cast is part of an assignment, we tell the code
13935              that deals with it not to complain about a mismatch,
13936              because things have been cast, anyways */
13937           TREE_TYPE (node) = error_mark_node;
13938           error_found = 1;
13939         }
13940       else
13941         {
13942           value = fold (value);
13943           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
13944           return value;
13945         }
13946       break;
13947     }
13948   
13949   if (error_found)
13950     return error_mark_node;
13951
13952   /* There are cases where node has been replaced by something else
13953      and we don't end up returning here: UNARY_PLUS_EXPR,
13954      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
13955   TREE_OPERAND (node, 0) = fold (op);
13956   TREE_TYPE (node) = prom_type;
13957   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
13958   return fold (node);
13959 }
13960
13961 /* Generic type resolution that sometimes takes place during node
13962    patching. Returned the resolved type or generate an error
13963    message. Return the resolved type or NULL_TREE.  */
13964
13965 static tree
13966 resolve_type_during_patch (type)
13967      tree type;
13968 {
13969   if (unresolved_type_p (type, NULL))
13970     {
13971       tree type_decl = resolve_and_layout (EXPR_WFL_NODE (type), type);
13972       if (!type_decl)
13973         {
13974           parse_error_context (type, 
13975                                "Class `%s' not found in type declaration",
13976                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
13977           return NULL_TREE;
13978         }
13979       return TREE_TYPE (type_decl);
13980     }
13981   return type;
13982 }
13983 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
13984    found. Otherwise NODE or something meant to replace it is returned.  */
13985
13986 static tree
13987 patch_cast (node, wfl_op)
13988      tree node;
13989      tree wfl_op;
13990 {
13991   tree op = TREE_OPERAND (node, 0);
13992   tree op_type = TREE_TYPE (op);
13993   tree cast_type = TREE_TYPE (node);
13994   char *t1;
13995
13996   /* First resolve OP_TYPE if unresolved */
13997   if (!(cast_type = resolve_type_during_patch (cast_type)))
13998     return error_mark_node;
13999
14000   /* Check on cast that are proven correct at compile time */
14001   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
14002     {
14003       /* Same type */
14004       if (cast_type == op_type)
14005         return node;
14006
14007       /* float and double type are converted to the original type main
14008          variant and then to the target type. */
14009       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
14010         op = convert (integer_type_node, op);
14011
14012       /* Try widening/narowwing convertion. Potentially, things need
14013          to be worked out in gcc so we implement the extreme cases
14014          correctly. fold_convert() needs to be fixed. */
14015       return convert (cast_type, op);
14016     }
14017
14018   /* It's also valid to cast a boolean into a boolean */
14019   if (op_type == boolean_type_node && cast_type == boolean_type_node)
14020     return node;
14021
14022   /* null can be casted to references */
14023   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
14024     return build_null_of_type (cast_type);
14025
14026   /* The remaining legal casts involve conversion between reference
14027      types. Check for their compile time correctness. */
14028   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
14029       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
14030     {
14031       TREE_TYPE (node) = promote_type (cast_type);
14032       /* Now, the case can be determined correct at compile time if
14033          OP_TYPE can be converted into CAST_TYPE by assignment
14034          conversion (5.2) */
14035
14036       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
14037         {
14038           TREE_SET_CODE (node, NOP_EXPR);
14039           return node;
14040         }
14041
14042       if (flag_emit_class_files)
14043         {
14044           TREE_SET_CODE (node, CONVERT_EXPR);
14045           return node;
14046         }
14047
14048       /* The cast requires a run-time check */
14049       return build (CALL_EXPR, promote_type (cast_type),
14050                     build_address_of (soft_checkcast_node),
14051                     tree_cons (NULL_TREE, build_class_ref (cast_type),
14052                                build_tree_list (NULL_TREE, op)),
14053                     NULL_TREE);
14054     }
14055
14056   /* Any other casts are proven incorrect at compile time */
14057   t1 = xstrdup (lang_printable_name (op_type, 0));
14058   parse_error_context (wfl_op, "Invalid cast from `%s' to `%s'",
14059                        t1, lang_printable_name (cast_type, 0));
14060   free (t1);
14061   return error_mark_node;
14062 }
14063
14064 /* Build a null constant and give it the type TYPE.  */
14065
14066 static tree
14067 build_null_of_type (type)
14068      tree type;
14069 {
14070   tree node = build_int_2 (0, 0);
14071   TREE_TYPE (node) = promote_type (type);
14072   return node;
14073 }
14074
14075 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
14076    a list of indices. */
14077 static tree
14078 build_array_ref (location, array, index)
14079      int location;
14080      tree array, index;
14081 {
14082   tree node = build (ARRAY_REF, NULL_TREE, array, index);
14083   EXPR_WFL_LINECOL (node) = location;
14084   return node;
14085 }
14086
14087 /* 15.12 Array Access Expression */
14088
14089 static tree
14090 patch_array_ref (node)
14091      tree node;
14092 {
14093   tree array = TREE_OPERAND (node, 0);
14094   tree array_type  = TREE_TYPE (array);
14095   tree index = TREE_OPERAND (node, 1);
14096   tree index_type = TREE_TYPE (index);
14097   int error_found = 0;
14098
14099   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14100
14101   if (TREE_CODE (array_type) == POINTER_TYPE)
14102     array_type = TREE_TYPE (array_type);
14103
14104   /* The array reference must be an array */
14105   if (!TYPE_ARRAY_P (array_type))
14106     {
14107       parse_error_context 
14108         (wfl_operator,
14109          "`[]' can only be applied to arrays. It can't be applied to `%s'",
14110          lang_printable_name (array_type, 0));
14111       TREE_TYPE (node) = error_mark_node;
14112       error_found = 1;
14113     }
14114
14115   /* The array index undergoes unary numeric promotion. The promoted
14116      type must be int */
14117   index = do_unary_numeric_promotion (index);
14118   if (TREE_TYPE (index) != int_type_node)
14119     {
14120       if (valid_cast_to_p (index_type, int_type_node))
14121         parse_error_context (wfl_operator,
14122    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
14123                              lang_printable_name (index_type, 0));
14124       else
14125         parse_error_context (wfl_operator,
14126           "Incompatible type for `[]'. Can't convert `%s' to `int'",
14127                              lang_printable_name (index_type, 0));
14128       TREE_TYPE (node) = error_mark_node;
14129       error_found = 1;
14130     }
14131
14132   if (error_found)
14133     return error_mark_node;
14134
14135   array_type = TYPE_ARRAY_ELEMENT (array_type);
14136
14137   if (flag_emit_class_files || flag_emit_xref)
14138     {
14139       TREE_OPERAND (node, 0) = array;
14140       TREE_OPERAND (node, 1) = index;
14141     }
14142   else
14143     {
14144       /* The save_expr is for correct evaluation order.  It would be cleaner
14145          to use force_evaluation_order (see comment there), but that is
14146          difficult when we also have to deal with bounds checking. */
14147       if (TREE_SIDE_EFFECTS (index))
14148         array = save_expr (array);
14149       node = build_java_arrayaccess (array, array_type, index);
14150       if (TREE_SIDE_EFFECTS (index))
14151         node = build (COMPOUND_EXPR, array_type, array, node);
14152     }
14153   TREE_TYPE (node) = array_type;
14154   return node;
14155 }
14156
14157 /* 15.9 Array Creation Expressions */
14158
14159 static tree
14160 build_newarray_node (type, dims, extra_dims)
14161      tree type;
14162      tree dims;
14163      int extra_dims;
14164 {
14165   tree node =
14166     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
14167            build_int_2 (extra_dims, 0));
14168   return node;
14169 }
14170
14171 static tree
14172 patch_newarray (node)
14173      tree node;
14174 {
14175   tree type = TREE_OPERAND (node, 0);
14176   tree dims = TREE_OPERAND (node, 1);
14177   tree cdim, array_type;
14178   int error_found = 0;
14179   int ndims = 0;
14180   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
14181
14182   /* Dimension types are verified. It's better for the types to be
14183      verified in order. */
14184   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
14185     {
14186       int dim_error = 0;
14187       tree dim = TREE_VALUE (cdim);
14188
14189       /* Dim might have been saved during its evaluation */
14190       dim = (TREE_CODE (dim) == SAVE_EXPR ? TREE_OPERAND (dim, 0) : dim);
14191
14192       /* The type of each specified dimension must be an integral type. */
14193       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
14194         dim_error = 1;
14195
14196       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
14197          promoted type must be int. */
14198       else
14199         {
14200           dim = do_unary_numeric_promotion (dim);
14201           if (TREE_TYPE (dim) != int_type_node)
14202             dim_error = 1;
14203         }
14204
14205       /* Report errors on types here */
14206       if (dim_error)
14207         {
14208           parse_error_context 
14209             (TREE_PURPOSE (cdim), 
14210              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
14211              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
14212               "Explicit cast needed to" : "Can't"),
14213              lang_printable_name (TREE_TYPE (dim), 0));
14214           error_found = 1;
14215         }
14216
14217       TREE_PURPOSE (cdim) = NULL_TREE;
14218     }
14219
14220   /* Resolve array base type if unresolved */
14221   if (!(type = resolve_type_during_patch (type)))
14222     error_found = 1;
14223
14224   if (error_found)
14225     {
14226       /* We don't want further evaluation of this bogus array creation
14227          operation */
14228       TREE_TYPE (node) = error_mark_node;
14229       return error_mark_node;
14230     }
14231
14232   /* Set array_type to the actual (promoted) array type of the result. */
14233   if (TREE_CODE (type) == RECORD_TYPE)
14234     type = build_pointer_type (type);
14235   while (--xdims >= 0)
14236     {
14237       type = promote_type (build_java_array_type (type, -1));
14238     }
14239   dims = nreverse (dims);
14240   array_type = type;
14241   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
14242     {
14243       type = array_type;
14244       array_type
14245         = build_java_array_type (type,
14246                                  TREE_CODE (cdim) == INTEGER_CST
14247                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
14248                                  : -1);
14249       array_type = promote_type (array_type);
14250     }
14251   dims = nreverse (dims);
14252
14253   /* The node is transformed into a function call. Things are done
14254      differently according to the number of dimensions. If the number
14255      of dimension is equal to 1, then the nature of the base type
14256      (primitive or not) matters. */
14257   if (ndims == 1)
14258     return build_new_array (type, TREE_VALUE (dims));
14259   
14260   /* Can't reuse what's already written in expr.c because it uses the
14261      JVM stack representation. Provide a build_multianewarray. FIXME */
14262   return build (CALL_EXPR, array_type,
14263                 build_address_of (soft_multianewarray_node),
14264                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
14265                            tree_cons (NULL_TREE, 
14266                                       build_int_2 (ndims, 0), dims )),
14267                 NULL_TREE);
14268 }
14269
14270 /* 10.6 Array initializer.  */
14271
14272 /* Build a wfl for array element that don't have one, so we can
14273    pin-point errors.  */
14274
14275 static tree
14276 maybe_build_array_element_wfl (node)
14277      tree node;
14278 {
14279   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
14280     return build_expr_wfl (NULL_TREE, ctxp->filename,
14281                            ctxp->elc.line, ctxp->elc.prev_col);
14282   else
14283     return NULL_TREE;
14284 }
14285
14286 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
14287    identification of initialized arrays easier to detect during walk
14288    and expansion.  */
14289
14290 static tree
14291 build_new_array_init (location, values)
14292      int location;
14293      tree values;
14294 {
14295   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
14296   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
14297   EXPR_WFL_LINECOL (to_return) = location;
14298   return to_return;
14299 }
14300
14301 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
14302    occurred.  Otherwise return NODE after having set its type
14303    appropriately.  */
14304
14305 static tree
14306 patch_new_array_init (type, node)
14307      tree type, node;
14308 {
14309   int error_seen = 0;
14310   tree current, element_type;
14311   HOST_WIDE_INT length;
14312   int all_constant = 1;
14313   tree init = TREE_OPERAND (node, 0);
14314
14315   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
14316     {
14317       parse_error_context (node,
14318                            "Invalid array initializer for non-array type `%s'",
14319                            lang_printable_name (type, 1));
14320       return error_mark_node;
14321     }
14322   type = TREE_TYPE (type);
14323   element_type = TYPE_ARRAY_ELEMENT (type);
14324
14325   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
14326
14327   for (length = 0, current = CONSTRUCTOR_ELTS (init);
14328        current;  length++, current = TREE_CHAIN (current))
14329     {
14330       tree elt = TREE_VALUE (current);
14331       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
14332         {
14333           error_seen |= array_constructor_check_entry (element_type, current);
14334           elt = TREE_VALUE (current);
14335           /* When compiling to native code, STRING_CST is converted to
14336              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
14337           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
14338             all_constant = 0;
14339         }
14340       else
14341         {
14342           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
14343           TREE_PURPOSE (current) = NULL_TREE;
14344           all_constant = 0;
14345         }
14346       if (elt && TREE_CODE (elt) == TREE_LIST 
14347           && TREE_VALUE (elt) == error_mark_node)
14348         error_seen = 1;
14349     }
14350
14351   if (error_seen)
14352     return error_mark_node;
14353
14354   /* Create a new type. We can't reuse the one we have here by
14355      patching its dimension because it originally is of dimension -1
14356      hence reused by gcc. This would prevent triangular arrays. */
14357   type = build_java_array_type (element_type, length);
14358   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
14359   TREE_TYPE (node) = promote_type (type);
14360   TREE_CONSTANT (init) = all_constant;
14361   TREE_CONSTANT (node) = all_constant;
14362   return node;
14363 }
14364
14365 /* Verify that one entry of the initializer element list can be
14366    assigned to the array base type. Report 1 if an error occurred, 0
14367    otherwise.  */
14368
14369 static int
14370 array_constructor_check_entry (type, entry)
14371      tree type, entry;
14372 {
14373   char *array_type_string = NULL;       /* For error reports */
14374   tree value, type_value, new_value, wfl_value, patched;
14375   int error_seen = 0;
14376
14377   new_value = NULL_TREE;
14378   wfl_value = TREE_VALUE (entry);
14379
14380   value = java_complete_tree (TREE_VALUE (entry));
14381   /* patch_string return error_mark_node if arg is error_mark_node */
14382   if ((patched = patch_string (value)))
14383     value = patched;
14384   if (value == error_mark_node)
14385     return 1;
14386   
14387   type_value = TREE_TYPE (value);
14388   
14389   /* At anytime, try_builtin_assignconv can report a warning on
14390      constant overflow during narrowing. */
14391   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
14392   new_value = try_builtin_assignconv (wfl_operator, type, value);
14393   if (!new_value && (new_value = try_reference_assignconv (type, value)))
14394     type_value = promote_type (type);
14395
14396   /* Check and report errors */
14397   if (!new_value)
14398     {
14399       const char *msg = (!valid_cast_to_p (type_value, type) ?
14400                    "Can't" : "Explicit cast needed to");
14401       if (!array_type_string)
14402         array_type_string = xstrdup (lang_printable_name (type, 1));
14403       parse_error_context 
14404         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
14405          msg, lang_printable_name (type_value, 1), array_type_string);
14406       error_seen = 1;
14407     }
14408   
14409   if (new_value)
14410     {
14411       new_value = maybe_build_primttype_type_ref (new_value, wfl_value);
14412       TREE_VALUE (entry) = new_value;
14413     }
14414
14415   if (array_type_string)
14416     free (array_type_string);
14417
14418   TREE_PURPOSE (entry) = NULL_TREE;
14419   return error_seen;
14420 }
14421
14422 static tree
14423 build_this (location)
14424      int location;
14425 {
14426   tree node = build_wfl_node (this_identifier_node);
14427   TREE_SET_CODE (node, THIS_EXPR);
14428   EXPR_WFL_LINECOL (node) = location;
14429   return node;
14430 }
14431
14432 /* 14.15 The return statement. It builds a modify expression that
14433    assigns the returned value to the RESULT_DECL that hold the value
14434    to be returned. */
14435
14436 static tree
14437 build_return (location, op)
14438      int location;
14439      tree op;
14440 {
14441   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
14442   EXPR_WFL_LINECOL (node) = location;
14443   node = build_debugable_stmt (location, node);
14444   return node;
14445 }
14446
14447 static tree
14448 patch_return (node)
14449      tree node;
14450 {
14451   tree return_exp = TREE_OPERAND (node, 0);
14452   tree meth = current_function_decl;
14453   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
14454   int error_found = 0;
14455
14456   TREE_TYPE (node) = error_mark_node;
14457   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14458
14459   /* It's invalid to have a return value within a function that is
14460      declared with the keyword void or that is a constructor */
14461   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
14462     error_found = 1;
14463
14464   /* It's invalid to use a return statement in a static block */
14465   if (DECL_CLINIT_P (current_function_decl))
14466     error_found = 1;
14467
14468   /* It's invalid to have a no return value within a function that
14469      isn't declared with the keyword `void' */
14470   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
14471     error_found = 2;
14472   
14473   if (in_instance_initializer)
14474     error_found = 1;
14475
14476   if (error_found)
14477     {
14478       if (in_instance_initializer)
14479         parse_error_context (wfl_operator,
14480                              "`return' inside instance initializer");
14481         
14482       else if (DECL_CLINIT_P (current_function_decl))
14483         parse_error_context (wfl_operator,
14484                              "`return' inside static initializer");
14485
14486       else if (!DECL_CONSTRUCTOR_P (meth))
14487         {
14488           char *t = xstrdup (lang_printable_name (mtype, 0));
14489           parse_error_context (wfl_operator, 
14490                                "`return' with%s value from `%s %s'",
14491                                (error_found == 1 ? "" : "out"), 
14492                                t, lang_printable_name (meth, 0));
14493           free (t);
14494         }
14495       else
14496         parse_error_context (wfl_operator, 
14497                              "`return' with value from constructor `%s'",
14498                              lang_printable_name (meth, 0));
14499       return error_mark_node;
14500     }
14501
14502   /* If we have a return_exp, build a modify expression and expand
14503      it. Note: at that point, the assignment is declared valid, but we
14504      may want to carry some more hacks */
14505   if (return_exp)
14506     {
14507       tree exp = java_complete_tree (return_exp);
14508       tree modify, patched;
14509
14510       /* If the function returned value and EXP are booleans, EXP has
14511       to be converted into the type of DECL_RESULT, which is integer
14512       (see complete_start_java_method) */
14513       if (TREE_TYPE (exp) == boolean_type_node &&
14514           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
14515         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
14516
14517       /* `null' can be assigned to a function returning a reference */
14518       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
14519           exp == null_pointer_node)
14520         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
14521
14522       if ((patched = patch_string (exp)))
14523         exp = patched;
14524       
14525       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
14526       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
14527       modify = java_complete_tree (modify);
14528
14529       if (modify != error_mark_node)
14530         {
14531           TREE_SIDE_EFFECTS (modify) = 1;
14532           TREE_OPERAND (node, 0) = modify;
14533         }
14534       else
14535         return error_mark_node;
14536     }
14537   TREE_TYPE (node) = void_type_node;
14538   TREE_SIDE_EFFECTS (node) = 1;
14539   return node;
14540 }
14541
14542 /* 14.8 The if Statement */
14543
14544 static tree
14545 build_if_else_statement (location, expression, if_body, else_body)
14546      int location;
14547      tree expression, if_body, else_body;
14548 {
14549   tree node;
14550   if (!else_body)
14551     else_body = empty_stmt_node;
14552   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
14553   EXPR_WFL_LINECOL (node) = location;
14554   node = build_debugable_stmt (location, node);
14555   return node;
14556 }
14557
14558 static tree
14559 patch_if_else_statement (node)
14560      tree node;
14561 {
14562   tree expression = TREE_OPERAND (node, 0);
14563
14564   TREE_TYPE (node) = error_mark_node;
14565   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14566
14567   /* The type of expression must be boolean */
14568   if (TREE_TYPE (expression) != boolean_type_node
14569       && TREE_TYPE (expression) != promoted_boolean_type_node)
14570     {
14571       parse_error_context 
14572         (wfl_operator, 
14573          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
14574          lang_printable_name (TREE_TYPE (expression), 0));
14575       return error_mark_node;
14576     }
14577   
14578   TREE_TYPE (node) = void_type_node;
14579   TREE_SIDE_EFFECTS (node) = 1;
14580   CAN_COMPLETE_NORMALLY (node)
14581     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
14582     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
14583   return node;
14584 }
14585
14586 /* 14.6 Labeled Statements */
14587
14588 /* Action taken when a lableled statement is parsed. a new
14589    LABELED_BLOCK_EXPR is created. No statement is attached to the
14590    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
14591
14592 static tree
14593 build_labeled_block (location, label)
14594      int location;
14595      tree label;
14596 {
14597   tree label_name ;
14598   tree label_decl, node;
14599   if (label == NULL_TREE || label == continue_identifier_node)
14600     label_name = label;
14601   else
14602     {
14603       label_name = merge_qualified_name (label_id, label);
14604       /* Issue an error if we try to reuse a label that was previously
14605          declared */
14606       if (IDENTIFIER_LOCAL_VALUE (label_name))
14607         {
14608           EXPR_WFL_LINECOL (wfl_operator) = location;
14609           parse_error_context (wfl_operator,
14610             "Declaration of `%s' shadows a previous label declaration",
14611                                IDENTIFIER_POINTER (label));
14612           EXPR_WFL_LINECOL (wfl_operator) = 
14613             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
14614           parse_error_context (wfl_operator,
14615             "This is the location of the previous declaration of label `%s'",
14616                                IDENTIFIER_POINTER (label));
14617           java_error_count--;
14618         }
14619     }
14620
14621   label_decl = create_label_decl (label_name);
14622   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
14623   EXPR_WFL_LINECOL (node) = location;
14624   TREE_SIDE_EFFECTS (node) = 1;
14625   return node;
14626 }
14627
14628 /* A labeled statement LBE is attached a statement.  */
14629
14630 static tree
14631 finish_labeled_statement (lbe, statement)
14632      tree lbe;                  /* Labeled block expr */
14633      tree statement;
14634 {
14635   /* In anyways, tie the loop to its statement */
14636   LABELED_BLOCK_BODY (lbe) = statement;
14637   pop_labeled_block ();
14638   POP_LABELED_BLOCK ();
14639   return lbe;
14640 }
14641
14642 /* 14.10, 14.11, 14.12 Loop Statements */
14643
14644 /* Create an empty LOOP_EXPR and make it the last in the nested loop
14645    list. */
14646
14647 static tree
14648 build_new_loop (loop_body)
14649      tree loop_body;
14650 {
14651   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
14652   TREE_SIDE_EFFECTS (loop) = 1;
14653   PUSH_LOOP (loop);
14654   return loop;
14655 }
14656
14657 /* Create a loop body according to the following structure:
14658      COMPOUND_EXPR
14659        COMPOUND_EXPR            (loop main body)
14660          EXIT_EXPR              (this order is for while/for loops.
14661          LABELED_BLOCK_EXPR      the order is reversed for do loops)
14662            LABEL_DECL           (a continue occuring here branches at the 
14663            BODY                  end of this labeled block)
14664        INCREMENT                (if any)
14665
14666   REVERSED, if non zero, tells that the loop condition expr comes
14667   after the body, like in the do-while loop.
14668
14669   To obtain a loop, the loop body structure described above is
14670   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
14671
14672    LABELED_BLOCK_EXPR
14673      LABEL_DECL                   (use this label to exit the loop)
14674      LOOP_EXPR
14675        <structure described above> */
14676
14677 static tree
14678 build_loop_body (location, condition, reversed)
14679      int location;
14680      tree condition;
14681      int reversed;
14682 {
14683   tree first, second, body;
14684
14685   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
14686   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
14687   condition = build_debugable_stmt (location, condition);
14688   TREE_SIDE_EFFECTS (condition) = 1;
14689
14690   body = build_labeled_block (0, continue_identifier_node);
14691   first = (reversed ? body : condition);
14692   second = (reversed ? condition : body);
14693   return 
14694     build (COMPOUND_EXPR, NULL_TREE, 
14695            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
14696 }
14697
14698 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
14699    their order) on the current loop. Unlink the current loop from the
14700    loop list.  */
14701
14702 static tree
14703 finish_loop_body (location, condition, body, reversed)
14704      int location;
14705      tree condition, body;
14706      int reversed;
14707 {
14708   tree to_return = ctxp->current_loop;
14709   tree loop_body = LOOP_EXPR_BODY (to_return);
14710   if (condition)
14711     {
14712       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
14713       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
14714          The real EXIT_EXPR is one operand further. */
14715       EXPR_WFL_LINECOL (cnode) = location;
14716       /* This one is for accurate error reports */
14717       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
14718       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
14719     }
14720   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
14721   POP_LOOP ();
14722   return to_return;
14723 }
14724
14725 /* Tailored version of finish_loop_body for FOR loops, when FOR
14726    loops feature the condition part */
14727
14728 static tree
14729 finish_for_loop (location, condition, update, body)
14730     int location;
14731     tree condition, update, body;
14732 {
14733   /* Put the condition and the loop body in place */
14734   tree loop = finish_loop_body (location, condition, body, 0);
14735   /* LOOP is the current loop which has been now popped of the loop
14736      stack. Install the update block */
14737   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
14738   return loop;
14739 }
14740
14741 /* Try to find the loop a block might be related to. This comprises
14742    the case where the LOOP_EXPR is found as the second operand of a
14743    COMPOUND_EXPR, because the loop happens to have an initialization
14744    part, then expressed as the first operand of the COMPOUND_EXPR. If
14745    the search finds something, 1 is returned. Otherwise, 0 is
14746    returned. The search is assumed to start from a
14747    LABELED_BLOCK_EXPR's block.  */
14748
14749 static tree
14750 search_loop (statement)
14751     tree statement;
14752 {
14753   if (TREE_CODE (statement) == LOOP_EXPR)
14754     return statement;
14755
14756   if (TREE_CODE (statement) == BLOCK)
14757     statement = BLOCK_SUBBLOCKS (statement);
14758   else
14759     return NULL_TREE;
14760
14761   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14762     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14763       statement = TREE_OPERAND (statement, 1);
14764
14765   return (TREE_CODE (statement) == LOOP_EXPR
14766           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
14767 }
14768
14769 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
14770    returned otherwise.  */
14771
14772 static int
14773 labeled_block_contains_loop_p (block, loop)
14774     tree block, loop;
14775 {
14776   if (!block)
14777     return 0;
14778
14779   if (LABELED_BLOCK_BODY (block) == loop)
14780     return 1;
14781
14782   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
14783     return 1;
14784
14785   return 0;
14786 }
14787
14788 /* If the loop isn't surrounded by a labeled statement, create one and
14789    insert LOOP as its body.  */
14790
14791 static tree
14792 patch_loop_statement (loop)
14793      tree loop;
14794 {
14795   tree loop_label;
14796
14797   TREE_TYPE (loop) = void_type_node;
14798   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
14799     return loop;
14800
14801   loop_label = build_labeled_block (0, NULL_TREE);
14802   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
14803      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
14804   LABELED_BLOCK_BODY (loop_label) = loop;
14805   PUSH_LABELED_BLOCK (loop_label);
14806   return loop_label;
14807 }
14808
14809 /* 14.13, 14.14: break and continue Statements */
14810
14811 /* Build a break or a continue statement. a null NAME indicates an
14812    unlabeled break/continue statement.  */
14813
14814 static tree
14815 build_bc_statement (location, is_break, name)
14816      int location, is_break;
14817      tree name;
14818 {
14819   tree break_continue, label_block_expr = NULL_TREE;
14820
14821   if (name)
14822     {
14823       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
14824             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
14825         /* Null means that we don't have a target for this named
14826            break/continue. In this case, we make the target to be the
14827            label name, so that the error can be reported accuratly in
14828            patch_bc_statement. */
14829         label_block_expr = EXPR_WFL_NODE (name);
14830     }
14831   /* Unlabeled break/continue will be handled during the
14832      break/continue patch operation */
14833   break_continue 
14834     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
14835
14836   IS_BREAK_STMT_P (break_continue) = is_break;
14837   TREE_SIDE_EFFECTS (break_continue) = 1;
14838   EXPR_WFL_LINECOL (break_continue) = location;
14839   break_continue = build_debugable_stmt (location, break_continue);
14840   return break_continue;
14841 }
14842
14843 /* Verification of a break/continue statement. */
14844
14845 static tree
14846 patch_bc_statement (node)
14847      tree node;
14848 {
14849   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
14850   tree labeled_block = ctxp->current_labeled_block;
14851   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14852  
14853   /* Having an identifier here means that the target is unknown. */
14854   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
14855     {
14856       parse_error_context (wfl_operator, "No label definition found for `%s'",
14857                            IDENTIFIER_POINTER (bc_label));
14858       return error_mark_node;
14859     }
14860   if (! IS_BREAK_STMT_P (node))
14861     {
14862       /* It's a continue statement. */
14863       for (;; labeled_block = TREE_CHAIN (labeled_block))
14864         {
14865           if (labeled_block == NULL_TREE)
14866             {
14867               if (bc_label == NULL_TREE)
14868                 parse_error_context (wfl_operator,
14869                                      "`continue' must be in loop");
14870               else
14871                 parse_error_context 
14872                   (wfl_operator, "continue label `%s' does not name a loop",
14873                    IDENTIFIER_POINTER (bc_label));
14874               return error_mark_node;
14875             }
14876           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
14877                == continue_identifier_node)
14878               && (bc_label == NULL_TREE
14879                   || TREE_CHAIN (labeled_block) == bc_label))
14880             {
14881               bc_label = labeled_block;
14882               break;
14883             }
14884         }
14885     }
14886   else if (!bc_label)
14887     { 
14888       for (;; labeled_block = TREE_CHAIN (labeled_block))
14889         {
14890           if (labeled_block == NULL_TREE)
14891             {
14892               parse_error_context (wfl_operator,
14893                                      "`break' must be in loop or switch");
14894               return error_mark_node;
14895             }
14896           target_stmt = LABELED_BLOCK_BODY (labeled_block);
14897           if (TREE_CODE (target_stmt) == SWITCH_EXPR
14898               || search_loop (target_stmt))
14899             {
14900               bc_label = labeled_block;
14901               break;
14902             }
14903         }
14904     }
14905
14906   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
14907   CAN_COMPLETE_NORMALLY (bc_label) = 1;
14908
14909   /* Our break/continue don't return values. */
14910   TREE_TYPE (node) = void_type_node;
14911   /* Encapsulate the break within a compound statement so that it's
14912      expanded all the times by expand_expr (and not clobbered
14913      sometimes, like after a if statement) */
14914   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
14915   TREE_SIDE_EFFECTS (node) = 1;
14916   return node;
14917 }
14918
14919 /* Process the exit expression belonging to a loop. Its type must be
14920    boolean.  */
14921
14922 static tree
14923 patch_exit_expr (node)
14924      tree node;
14925 {
14926   tree expression = TREE_OPERAND (node, 0);
14927   TREE_TYPE (node) = error_mark_node;
14928   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14929
14930   /* The type of expression must be boolean */
14931   if (TREE_TYPE (expression) != boolean_type_node)
14932     {
14933       parse_error_context 
14934         (wfl_operator, 
14935     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
14936          lang_printable_name (TREE_TYPE (expression), 0));
14937       return error_mark_node;
14938     }
14939   /* Now we know things are allright, invert the condition, fold and
14940      return */
14941   TREE_OPERAND (node, 0) = 
14942     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
14943
14944   if (! integer_zerop (TREE_OPERAND (node, 0))
14945       && ctxp->current_loop != NULL_TREE
14946       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
14947     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
14948   if (! integer_onep (TREE_OPERAND (node, 0)))
14949     CAN_COMPLETE_NORMALLY (node) = 1;
14950
14951
14952   TREE_TYPE (node) = void_type_node;
14953   return node;
14954 }
14955
14956 /* 14.9 Switch statement */
14957
14958 static tree
14959 patch_switch_statement (node)
14960      tree node;
14961 {
14962   tree se = TREE_OPERAND (node, 0), se_type;
14963
14964   /* Complete the switch expression */
14965   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
14966   se_type = TREE_TYPE (se);
14967   /* The type of the switch expression must be char, byte, short or
14968      int */
14969   if (! JINTEGRAL_TYPE_P (se_type) || se_type == long_type_node)
14970     {
14971       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14972       parse_error_context (wfl_operator,
14973           "Incompatible type for `switch'. Can't convert `%s' to `int'",
14974                            lang_printable_name (se_type, 0));
14975       /* This is what java_complete_tree will check */
14976       TREE_OPERAND (node, 0) = error_mark_node;
14977       return error_mark_node;
14978     }
14979
14980   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
14981
14982   /* Ready to return */
14983   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
14984     {
14985       TREE_TYPE (node) = error_mark_node;
14986       return error_mark_node;
14987     }
14988   TREE_TYPE (node) = void_type_node;
14989   TREE_SIDE_EFFECTS (node) = 1;
14990   CAN_COMPLETE_NORMALLY (node)
14991     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
14992       || ! SWITCH_HAS_DEFAULT (node);
14993   return node;
14994 }
14995
14996 /* 14.18 The try/catch statements */
14997
14998 static tree
14999 build_try_statement (location, try_block, catches)
15000      int location;
15001      tree try_block, catches;
15002 {
15003   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
15004   EXPR_WFL_LINECOL (node) = location;
15005   return node;
15006 }
15007
15008 static tree
15009 build_try_finally_statement (location, try_block, finally)
15010      int location;
15011      tree try_block, finally;
15012 {
15013   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
15014   EXPR_WFL_LINECOL (node) = location;
15015   return node;
15016 }
15017
15018 static tree
15019 patch_try_statement (node)
15020      tree node;
15021 {
15022   int error_found = 0;
15023   tree try = TREE_OPERAND (node, 0);
15024   /* Exception handlers are considered in left to right order */
15025   tree catch = nreverse (TREE_OPERAND (node, 1));
15026   tree current, caught_type_list = NULL_TREE;
15027
15028   /* Check catch clauses, if any. Every time we find an error, we try
15029      to process the next catch clause. We process the catch clause before
15030      the try block so that when processing the try block we can check thrown
15031      exceptions againts the caught type list. */
15032   for (current = catch; current; current = TREE_CHAIN (current))
15033     {
15034       tree carg_decl, carg_type;
15035       tree sub_current, catch_block, catch_clause;
15036       int unreachable;
15037
15038       /* At this point, the structure of the catch clause is
15039            CATCH_EXPR           (catch node)
15040              BLOCK              (with the decl of the parameter)
15041                COMPOUND_EXPR
15042                  MODIFY_EXPR   (assignment of the catch parameter)
15043                  BLOCK          (catch clause block)
15044        */
15045       catch_clause = TREE_OPERAND (current, 0);
15046       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
15047       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
15048
15049       /* Catch clauses can't have more than one parameter declared,
15050          but it's already enforced by the grammar. Make sure that the
15051          only parameter of the clause statement in of class Throwable
15052          or a subclass of Throwable, but that was done earlier. The
15053          catch clause parameter type has also been resolved. */
15054       
15055       /* Just make sure that the catch clause parameter type inherits
15056          from java.lang.Throwable */
15057       if (!inherits_from_p (carg_type, throwable_type_node))
15058         {
15059           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15060           parse_error_context (wfl_operator,
15061                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
15062                                lang_printable_name (carg_type, 0));
15063           error_found = 1;
15064           continue;
15065         }
15066       
15067       /* Partial check for unreachable catch statement: The catch
15068          clause is reachable iff is no earlier catch block A in
15069          the try statement such that the type of the catch
15070          clause's parameter is the same as or a subclass of the
15071          type of A's parameter */
15072       unreachable = 0;
15073       for (sub_current = catch;
15074            sub_current != current; sub_current = TREE_CHAIN (sub_current))
15075         {
15076           tree sub_catch_clause, decl;
15077           sub_catch_clause = TREE_OPERAND (sub_current, 0);
15078           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
15079
15080           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
15081             {
15082               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
15083               parse_error_context 
15084                 (wfl_operator,
15085                  "`catch' not reached because of the catch clause at line %d",
15086                  EXPR_WFL_LINENO (sub_current));
15087               unreachable = error_found = 1;
15088               break;
15089             }
15090         }
15091       /* Complete the catch clause block */
15092       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
15093       if (catch_block == error_mark_node)
15094         {
15095           error_found = 1;
15096           continue;
15097         }
15098       if (CAN_COMPLETE_NORMALLY (catch_block))
15099         CAN_COMPLETE_NORMALLY (node) = 1;
15100       TREE_OPERAND (current, 0) = catch_block;
15101
15102       if (unreachable)
15103         continue;
15104
15105       /* Things to do here: the exception must be thrown */
15106
15107       /* Link this type to the caught type list */
15108       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
15109     }
15110
15111   PUSH_EXCEPTIONS (caught_type_list);
15112   if ((try = java_complete_tree (try)) == error_mark_node)
15113     error_found = 1;
15114   if (CAN_COMPLETE_NORMALLY (try))
15115     CAN_COMPLETE_NORMALLY (node) = 1;
15116   POP_EXCEPTIONS ();
15117
15118   /* Verification ends here */
15119   if (error_found) 
15120     return error_mark_node;
15121
15122   TREE_OPERAND (node, 0) = try;
15123   TREE_OPERAND (node, 1) = catch;
15124   TREE_TYPE (node) = void_type_node;
15125   return node;
15126 }
15127
15128 /* 14.17 The synchronized Statement */
15129
15130 static tree
15131 patch_synchronized_statement (node, wfl_op1)
15132     tree node, wfl_op1;
15133 {
15134   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
15135   tree block = TREE_OPERAND (node, 1);
15136
15137   tree tmp, enter, exit, expr_decl, assignment;
15138
15139   if (expr == error_mark_node)
15140     {
15141       block = java_complete_tree (block);
15142       return expr;
15143     }
15144
15145   /* We might be trying to synchronize on a STRING_CST */
15146   if ((tmp = patch_string (expr)))
15147     expr = tmp;
15148
15149   /* The TYPE of expr must be a reference type */
15150   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
15151     {
15152       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15153       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
15154                            lang_printable_name (TREE_TYPE (expr), 0));
15155       return error_mark_node;
15156     }
15157
15158   if (flag_emit_xref)
15159     {
15160       TREE_OPERAND (node, 0) = expr;
15161       TREE_OPERAND (node, 1) = java_complete_tree (block);
15162       CAN_COMPLETE_NORMALLY (node) = 1;
15163       return node;
15164     }
15165
15166   /* Generate a try-finally for the synchronized statement, except
15167      that the handler that catches all throw exception calls
15168      _Jv_MonitorExit and then rethrow the exception.
15169      The synchronized statement is then implemented as:
15170      TRY 
15171        {
15172          _Jv_MonitorEnter (expression)
15173          synchronized_block
15174          _Jv_MonitorExit (expression)
15175        }
15176      CATCH_ALL
15177        {
15178          e = _Jv_exception_info ();
15179          _Jv_MonitorExit (expression)
15180          Throw (e);
15181        } */
15182
15183   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
15184   BUILD_MONITOR_ENTER (enter, expr_decl);
15185   BUILD_MONITOR_EXIT (exit, expr_decl);
15186   CAN_COMPLETE_NORMALLY (enter) = 1;
15187   CAN_COMPLETE_NORMALLY (exit) = 1;
15188   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
15189   TREE_SIDE_EFFECTS (assignment) = 1;
15190   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
15191                  build (COMPOUND_EXPR, NULL_TREE,
15192                         build (WITH_CLEANUP_EXPR, NULL_TREE,
15193                                build (COMPOUND_EXPR, NULL_TREE,
15194                                       assignment, enter),
15195                                NULL_TREE, exit),
15196                         block));
15197   node = build_expr_block (node, expr_decl);
15198
15199   return java_complete_tree (node);
15200 }
15201
15202 /* 14.16 The throw Statement */
15203
15204 static tree
15205 patch_throw_statement (node, wfl_op1)
15206     tree node, wfl_op1;
15207 {
15208   tree expr = TREE_OPERAND (node, 0);
15209   tree type = TREE_TYPE (expr);
15210   int unchecked_ok = 0, tryblock_throws_ok = 0;
15211
15212   /* Thrown expression must be assignable to java.lang.Throwable */
15213   if (!try_reference_assignconv (throwable_type_node, expr))
15214     {
15215       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15216       parse_error_context (wfl_operator,
15217     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
15218                            lang_printable_name (type, 0));
15219       /* If the thrown expression was a reference, we further the
15220          compile-time check. */
15221       if (!JREFERENCE_TYPE_P (type))
15222         return error_mark_node;
15223     }
15224
15225   /* At least one of the following must be true */
15226
15227   /* The type of the throw expression is a not checked exception,
15228      i.e. is a unchecked expression. */
15229   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
15230
15231   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15232   /* An instance can't throw a checked excetion unless that exception
15233      is explicitely declared in the `throws' clause of each
15234      constructor. This doesn't apply to anonymous classes, since they
15235      don't have declared constructors. */
15236   if (!unchecked_ok 
15237       && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
15238     {
15239       tree current;
15240       for (current = TYPE_METHODS (current_class); current; 
15241            current = TREE_CHAIN (current))
15242         if (DECL_CONSTRUCTOR_P (current) 
15243             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
15244           {
15245             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)", 
15246                                  lang_printable_name (TREE_TYPE (expr), 0));
15247             return error_mark_node;
15248           }
15249     }
15250
15251   /* Throw is contained in a try statement and at least one catch
15252      clause can receive the thrown expression or the current method is
15253      declared to throw such an exception. Or, the throw statement is
15254      contained in a method or constructor declaration and the type of
15255      the Expression is assignable to at least one type listed in the
15256      throws clause the declaration. */
15257   if (!unchecked_ok)
15258     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
15259   if (!(unchecked_ok || tryblock_throws_ok))
15260     {
15261       /* If there is a surrounding try block that has no matching
15262          clatch clause, report it first. A surrounding try block exits
15263          only if there is something after the list of checked
15264          exception thrown by the current function (if any). */
15265       if (IN_TRY_BLOCK_P ())
15266         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
15267                              lang_printable_name (type, 0));
15268       /* If we have no surrounding try statement and the method doesn't have
15269          any throws, report it now. FIXME */
15270
15271       /* We report that the exception can't be throw from a try block
15272          in all circumstances but when the `throw' is inside a static
15273          block. */
15274       else if (!EXCEPTIONS_P (currently_caught_type_list) 
15275                && !tryblock_throws_ok)
15276         {
15277           if (DECL_CLINIT_P (current_function_decl))
15278             parse_error_context (wfl_operator,
15279                    "Checked exception `%s' can't be thrown in initializer",
15280                                  lang_printable_name (type, 0));
15281           else
15282             parse_error_context (wfl_operator,
15283                    "Checked exception `%s' isn't thrown from a `try' block", 
15284                                  lang_printable_name (type, 0));
15285         }
15286       /* Otherwise, the current method doesn't have the appropriate
15287          throws declaration */
15288       else
15289         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
15290                              lang_printable_name (type, 0));
15291       return error_mark_node;
15292     }
15293
15294   if (! flag_emit_class_files && ! flag_emit_xref)
15295     BUILD_THROW (node, expr);
15296
15297   /* If doing xrefs, keep the location where the `throw' was seen. */
15298   if (flag_emit_xref)
15299     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
15300   return node;
15301 }
15302
15303 /* Check that exception said to be thrown by method DECL can be
15304    effectively caught from where DECL is invoked.  */
15305
15306 static void
15307 check_thrown_exceptions (location, decl)
15308      int location;
15309      tree decl;
15310 {
15311   tree throws;
15312   /* For all the unchecked exceptions thrown by DECL */
15313   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
15314        throws = TREE_CHAIN (throws)) 
15315     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
15316       {
15317 #if 1
15318         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
15319         if (DECL_NAME (decl) == get_identifier ("clone"))
15320           continue;
15321 #endif
15322         EXPR_WFL_LINECOL (wfl_operator) = location;
15323         if (DECL_FINIT_P (current_function_decl))
15324           parse_error_context
15325             (wfl_operator, "Exception `%s' can't be thrown in initializer",
15326              lang_printable_name (TREE_VALUE (throws), 0));
15327         else 
15328           {
15329             parse_error_context 
15330               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
15331                lang_printable_name (TREE_VALUE (throws), 0),
15332                (DECL_INIT_P (current_function_decl) ?
15333                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
15334                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
15335           }
15336       }
15337 }
15338
15339 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
15340    try-catch blocks, OR is listed in the `throws' clause of the
15341    current method.  */
15342
15343 static int
15344 check_thrown_exceptions_do (exception)
15345      tree exception;
15346 {
15347   tree list = currently_caught_type_list;
15348   resolve_and_layout (exception, NULL_TREE);
15349   /* First, all the nested try-catch-finally at that stage. The
15350      last element contains `throws' clause exceptions, if any. */
15351   if (IS_UNCHECKED_EXCEPTION_P (exception))
15352     return 1;
15353   while (list)
15354     {
15355       tree caught;
15356       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
15357         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
15358           return 1;
15359       list = TREE_CHAIN (list);
15360     }
15361   return 0;
15362 }
15363
15364 static void
15365 purge_unchecked_exceptions (mdecl)
15366      tree mdecl;
15367 {
15368   tree throws = DECL_FUNCTION_THROWS (mdecl);
15369   tree new = NULL_TREE;
15370
15371   while (throws)
15372     {
15373       tree next = TREE_CHAIN (throws);
15374       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
15375         {
15376           TREE_CHAIN (throws) = new;
15377           new = throws;
15378         }
15379       throws = next;
15380     }
15381   /* List is inverted here, but it doesn't matter */
15382   DECL_FUNCTION_THROWS (mdecl) = new;
15383 }
15384
15385 /* 15.24 Conditional Operator ?: */
15386
15387 static tree
15388 patch_conditional_expr (node, wfl_cond, wfl_op1)
15389      tree node, wfl_cond, wfl_op1;
15390 {
15391   tree cond = TREE_OPERAND (node, 0);
15392   tree op1 = TREE_OPERAND (node, 1);
15393   tree op2 = TREE_OPERAND (node, 2);
15394   tree resulting_type = NULL_TREE;
15395   tree t1, t2, patched;
15396   int error_found = 0;
15397
15398   /* Operands of ?: might be StringBuffers crafted as a result of a
15399      string concatenation. Obtain a descent operand here.  */
15400   if ((patched = patch_string (op1)))
15401     TREE_OPERAND (node, 1) = op1 = patched;
15402   if ((patched = patch_string (op2)))
15403     TREE_OPERAND (node, 2) = op2 = patched;
15404
15405   t1 = TREE_TYPE (op1);
15406   t2 = TREE_TYPE (op2);
15407
15408   /* The first expression must be a boolean */
15409   if (TREE_TYPE (cond) != boolean_type_node)
15410     {
15411       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
15412       parse_error_context (wfl_operator,
15413                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
15414                            lang_printable_name (TREE_TYPE (cond), 0));
15415       error_found = 1;
15416     }
15417
15418   /* Second and third can be numeric, boolean (i.e. primitive),
15419      references or null. Anything else results in an error */
15420   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
15421         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
15422             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
15423         || (t1 == boolean_type_node && t2 == boolean_type_node)))
15424     error_found = 1;
15425
15426   /* Determine the type of the conditional expression. Same types are
15427      easy to deal with */
15428   else if (t1 == t2)
15429     resulting_type = t1;
15430
15431   /* There are different rules for numeric types */
15432   else if (JNUMERIC_TYPE_P (t1))
15433     {
15434       /* if byte/short found, the resulting type is short */
15435       if ((t1 == byte_type_node && t2 == short_type_node)
15436           || (t1 == short_type_node && t2 == byte_type_node))
15437         resulting_type = short_type_node;
15438
15439       /* If t1 is a constant int and t2 is of type byte, short or char
15440          and t1's value fits in t2, then the resulting type is t2 */
15441       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
15442           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
15443         resulting_type = t2;
15444
15445       /* If t2 is a constant int and t1 is of type byte, short or char
15446          and t2's value fits in t1, then the resulting type is t1 */
15447       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
15448           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
15449         resulting_type = t1;
15450
15451       /* Otherwise, binary numeric promotion is applied and the
15452          resulting type is the promoted type of operand 1 and 2 */
15453       else 
15454         resulting_type = binary_numeric_promotion (t1, t2, 
15455                                                    &TREE_OPERAND (node, 1), 
15456                                                    &TREE_OPERAND (node, 2));
15457     }
15458
15459   /* Cases of a reference and a null type */
15460   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
15461     resulting_type = t1;
15462
15463   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
15464     resulting_type = t2;
15465
15466   /* Last case: different reference types. If a type can be converted
15467      into the other one by assignment conversion, the latter
15468      determines the type of the expression */
15469   else if ((resulting_type = try_reference_assignconv (t1, op2)))
15470     resulting_type = promote_type (t1);
15471
15472   else if ((resulting_type = try_reference_assignconv (t2, op1)))
15473     resulting_type = promote_type (t2);
15474
15475   /* If we don't have any resulting type, we're in trouble */
15476   if (!resulting_type)
15477     {
15478       char *t = xstrdup (lang_printable_name (t1, 0));
15479       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
15480       parse_error_context (wfl_operator,
15481                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
15482                            t, lang_printable_name (t2, 0));
15483       free (t);
15484       error_found = 1;
15485     }
15486
15487   if (error_found)
15488     {
15489       TREE_TYPE (node) = error_mark_node;
15490       return error_mark_node;
15491     }
15492
15493   TREE_TYPE (node) = resulting_type;
15494   TREE_SET_CODE (node, COND_EXPR);
15495   CAN_COMPLETE_NORMALLY (node) = 1;
15496   return node;
15497 }
15498
15499 /* Wrap EXPR with code to initialize DECL's class, if appropriate. */
15500
15501 static tree
15502 maybe_build_class_init_for_field (decl, expr)
15503     tree decl, expr;
15504 {
15505   tree clas = DECL_CONTEXT (decl);
15506   if (flag_emit_class_files || flag_emit_xref)
15507     return expr;
15508
15509   if (TREE_CODE (decl) == VAR_DECL && FIELD_STATIC (decl)
15510       && FIELD_FINAL (decl))
15511     {
15512       tree init = DECL_INITIAL (decl);
15513       if (init != NULL_TREE)
15514         init = fold_constant_for_init (init, decl);
15515       if (init != NULL_TREE && CONSTANT_VALUE_P (init))
15516         return expr;
15517     }
15518
15519   return build_class_init (clas, expr);
15520 }
15521
15522 /* Try to constant fold NODE.
15523    If NODE is not a constant expression, return NULL_EXPR.
15524    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
15525
15526 static tree
15527 fold_constant_for_init (node, context)
15528      tree node;
15529      tree context;
15530 {
15531   tree op0, op1, val;
15532   enum tree_code code = TREE_CODE (node);
15533
15534   switch (code)
15535     {
15536     case STRING_CST:
15537     case INTEGER_CST:
15538     case REAL_CST:
15539       return node;
15540
15541     case PLUS_EXPR:
15542     case MINUS_EXPR:
15543     case MULT_EXPR:
15544     case TRUNC_MOD_EXPR:
15545     case RDIV_EXPR:
15546     case LSHIFT_EXPR:
15547     case RSHIFT_EXPR:
15548     case URSHIFT_EXPR:
15549     case BIT_AND_EXPR:
15550     case BIT_XOR_EXPR:
15551     case BIT_IOR_EXPR:
15552     case TRUTH_ANDIF_EXPR:
15553     case TRUTH_ORIF_EXPR:
15554     case EQ_EXPR: 
15555     case NE_EXPR:
15556     case GT_EXPR:
15557     case GE_EXPR:
15558     case LT_EXPR:
15559     case LE_EXPR:
15560       op0 = TREE_OPERAND (node, 0);
15561       op1 = TREE_OPERAND (node, 1);
15562       val = fold_constant_for_init (op0, context);
15563       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15564         return NULL_TREE;
15565       TREE_OPERAND (node, 0) = val;
15566       val = fold_constant_for_init (op1, context);
15567       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15568         return NULL_TREE;
15569       TREE_OPERAND (node, 1) = val;
15570       return patch_binop (node, op0, op1);
15571
15572     case UNARY_PLUS_EXPR:
15573     case NEGATE_EXPR:
15574     case TRUTH_NOT_EXPR:
15575     case BIT_NOT_EXPR:
15576     case CONVERT_EXPR:
15577       op0 = TREE_OPERAND (node, 0);
15578       val = fold_constant_for_init (op0, context);
15579       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15580         return NULL_TREE;
15581       TREE_OPERAND (node, 0) = val;
15582       return patch_unaryop (node, op0);
15583       break;
15584
15585     case COND_EXPR:
15586       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
15587       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15588         return NULL_TREE;
15589       TREE_OPERAND (node, 0) = val;
15590       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
15591       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15592         return NULL_TREE;
15593       TREE_OPERAND (node, 1) = val;
15594       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
15595       if (val == NULL_TREE || ! TREE_CONSTANT (val))
15596         return NULL_TREE;
15597       TREE_OPERAND (node, 2) = val;
15598       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
15599         : TREE_OPERAND (node, 2);
15600
15601     case VAR_DECL:
15602     case FIELD_DECL:
15603       if (! FIELD_FINAL (node)
15604           || DECL_INITIAL (node) == NULL_TREE)
15605         return NULL_TREE;
15606       val = DECL_INITIAL (node);
15607       /* Guard against infinite recursion. */
15608       DECL_INITIAL (node) = NULL_TREE;
15609       val = fold_constant_for_init (val, node);
15610       DECL_INITIAL (node) = val;
15611       if (!val && CLASS_FINAL_VARIABLE_P (node))
15612         DECL_FIELD_FINAL_IUD (node) = 0;
15613       return val;
15614
15615     case EXPR_WITH_FILE_LOCATION:
15616       /* Compare java_complete_tree and resolve_expression_name. */
15617       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
15618           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
15619         {
15620           tree name = EXPR_WFL_NODE (node);
15621           tree decl;
15622           if (PRIMARY_P (node))
15623             return NULL_TREE;
15624           else if (! QUALIFIED_P (name))
15625             {
15626               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
15627               if (decl == NULL_TREE 
15628                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
15629                 return NULL_TREE;
15630               return fold_constant_for_init (decl, decl);
15631             }
15632           else
15633             {
15634               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
15635               qualify_ambiguous_name (node);
15636               if (resolve_field_access (node, &decl, NULL)
15637                   && decl != NULL_TREE)
15638                 return fold_constant_for_init (decl, decl);
15639               return NULL_TREE;
15640             }
15641         }
15642       else
15643         {
15644           op0 = TREE_OPERAND (node, 0);
15645           val = fold_constant_for_init (op0, context);
15646           if (val == NULL_TREE || ! TREE_CONSTANT (val))
15647             return NULL_TREE;
15648           TREE_OPERAND (node, 0) = val;
15649           return val;
15650         }
15651
15652 #ifdef USE_COMPONENT_REF
15653     case IDENTIFIER:
15654     case COMPONENT_REF:
15655       ?;
15656 #endif
15657
15658     default:
15659       return NULL_TREE;
15660     }
15661 }
15662
15663 #ifdef USE_COMPONENT_REF
15664 /* Context is 'T' for TypeName, 'P' for PackageName,
15665    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
15666
15667 tree
15668 resolve_simple_name (name, context)
15669      tree name;
15670      int context;
15671 {
15672 }
15673
15674 tree
15675 resolve_qualified_name (name, context)
15676      tree name;
15677      int context;
15678 {
15679 }
15680 #endif
15681
15682 /* Mark P, which is really a `struct parser_ctxt **' for GC.  */
15683
15684 static void
15685 mark_parser_ctxt (p)
15686      void *p;
15687 {
15688   struct parser_ctxt *pc = *((struct parser_ctxt **) p);
15689   int i;
15690
15691   if (!pc)
15692     return;
15693
15694 #ifndef JC1_LITE
15695   for (i = 0; i < 11; ++i)
15696     ggc_mark_tree (pc->modifier_ctx[i]);
15697   ggc_mark_tree (pc->class_type);
15698   ggc_mark_tree (pc->function_decl);
15699   ggc_mark_tree (pc->package);
15700   ggc_mark_tree (pc->class_list);
15701   ggc_mark_tree (pc->current_parsed_class);
15702   ggc_mark_tree (pc->current_parsed_class_un);
15703   ggc_mark_tree (pc->non_static_initialized);
15704   ggc_mark_tree (pc->static_initialized);
15705   ggc_mark_tree (pc->instance_initializers);
15706   ggc_mark_tree (pc->import_list);
15707   ggc_mark_tree (pc->import_demand_list);
15708   ggc_mark_tree (pc->current_loop);
15709   ggc_mark_tree (pc->current_labeled_block);
15710 #endif /* JC1_LITE */
15711
15712   if (pc->next)
15713     mark_parser_ctxt (&pc->next);
15714 }
15715
15716 void
15717 init_src_parse ()
15718 {
15719   /* Register roots with the garbage collector.  */
15720   ggc_add_tree_root (src_parse_roots, sizeof (src_parse_roots) / sizeof(tree));
15721 }